Added 3DO-style throbbing slave shield; --shield option

git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2083 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
avolkov
2005-12-16 20:35:12 +00:00
parent 41e6c9deec
commit 078459d6e2
4 changed files with 132 additions and 6 deletions
+1
View File
@@ -41,6 +41,7 @@ int optWhichCoarseScan;
int optWhichMenu;
int optWhichFonts;
int optWhichIntro;
int optWhichShield;
int optSmoothScroll;
int optMeleeScale;
+1
View File
@@ -35,6 +35,7 @@ extern int optWhichCoarseScan;
extern int optWhichMenu;
extern int optWhichFonts;
extern int optWhichIntro;
extern int optWhichShield;
extern int optSmoothScroll;
extern int optMeleeScale;
+116 -6
View File
@@ -19,6 +19,7 @@
#include "nameref.h"
#include "resinst.h"
#include "setup.h"
#include "options.h"
#include "planets/planets.h"
#include "planets/scan.h"
#include "libs/graphics/gfx_common.h"
@@ -612,7 +613,75 @@ CreateShieldMask (void)
return ShieldFrame;
}
// Apply the shield to the topo data
// SetShieldThrobEffect adjusts the red levels in the shield glow graphic
// the throbbing cycle MUST be == 0 (mod MAP_WIDTH), or it will go
// out of sync with RenderLevelMasks()
#define SHIELD_THROBS 6
// throb cycles per revolution
#define THROB_CYCLE ((MAP_WIDTH << 8) / SHIELD_THROBS)
#define THROB_HALF_CYCLE (THROB_CYCLE >> 1)
#define THROB_MAX_LEVEL 256
#define THROB_MIN_LEVEL 100
#define THROB_D_LEVEL (THROB_MAX_LEVEL - THROB_MIN_LEVEL)
static inline int
shield_level (int offset)
{
int level;
offset = (offset << 8) % THROB_CYCLE;
level = abs (offset - THROB_HALF_CYCLE);
level = THROB_MIN_LEVEL + level * THROB_D_LEVEL / THROB_HALF_CYCLE;
return level;
}
// See description above
// offset is effectively the angle of rotation around the planet's axis
static void
SetShieldThrobEffect (FRAME ShieldFrame, int offset, FRAME ThrobFrame)
{
int i;
int width, height;
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
DWORD *rgba;
int level;
level = shield_level (offset);
width = GetFrameWidth (ShieldFrame);
height = GetFrameHeight (ShieldFrame);
getpixelarray (Orbit->ScratchArray, 4, ShieldFrame, width, height);
for (i = 0, rgba = Orbit->ScratchArray; i < width * height; ++i, ++rgba)
{
DWORD p = *rgba;
int r, g, b, a;
r = (UBYTE)(p >> 24);
g = (UBYTE)(p >> 16);
b = (UBYTE)(p >> 8);
a = (UBYTE)(p);
if (a == 255)
{ // adjust color data for full-alpha pixels
r = r * level / THROB_MAX_LEVEL;
g = g * level / THROB_MAX_LEVEL;
b = b * level / THROB_MAX_LEVEL;
}
else if (a > 0)
{ // adjust alpha for translucent pixels
a = a * level / THROB_MAX_LEVEL;
}
*rgba = frame_mapRGBA (ThrobFrame, r, g, b, a);
}
process_rgb_bmp (ThrobFrame, Orbit->ScratchArray, width, height);
}
// Apply the shield to the topo image
static void
ApplyShieldTint (void)
{
@@ -669,7 +738,7 @@ get_map_elev (SBYTE *elevs, int x, int y, int offset)
// offset is effectively the angle of rotation around the planet's axis
// We use the SDL routines to directly write to the SDL_Surface to improve performance
void
RenderLevelMasks (int offset)
RenderLevelMasks (int offset, BOOLEAN doThrob)
{
POINT pt;
DWORD *rgba, *p_rgba;
@@ -678,6 +747,7 @@ RenderLevelMasks (int offset)
DWORD *pixels;
SBYTE *elevs;
FRAME MaskFrame;
int shLevel;
#if PROFILE
static clock_t t = 0;
@@ -686,6 +756,9 @@ RenderLevelMasks (int offset)
t1 = clock ();
#endif
shLevel = shield_level (offset);
rgba = pSolarSysState->Orbit.ScratchArray;
p_rgba = rgba;
// Choose the correct Frame to write to
@@ -755,7 +828,14 @@ RenderLevelMasks (int offset)
// The shield is glow + reflect (+ filter for others)
r = calc_map_light (SHIELD_REFLECT_COMP, diffus, 0);
r = r + SHIELD_GLOW_COMP + c[2];
r += SHIELD_GLOW_COMP;
if (doThrob)
{ // adjust red level for throbbing shield
r = r * shLevel / THROB_MAX_LEVEL;
}
r += c[2];
if (r > 255)
r = 255;
c[2] = r;
@@ -1935,6 +2015,9 @@ rotate_planet_task (void *data)
COUNT zoom_arr[50];
COUNT zoom_amt, frame_num = 0, zoom_frames;
PLANET_ORBIT *Orbit;
FRAME OldShieldFrame = 0;
FRAME ShieldFrame = 0;
BOOLEAN doThrob = FALSE;
r.extent.width = 0;
zooming = TRUE;
@@ -1949,8 +2032,25 @@ rotate_planet_task (void *data)
i = 1 - ((pSS->SysInfo.PlanetInfo.AxialTilt & 1) << 1);
init_x = (i == 1) ? (0) : (MAP_WIDTH - 1);
if (optWhichShield == OPT_3DO &&
pSolarSysState->pOrbitalDesc->data_index & PLANET_SHIELDED)
{ // prepare the shield throb effect
doThrob = TRUE;
OldShieldFrame = Orbit->ObjectFrame;
ShieldFrame = CaptureDrawable (
CreateDrawable (WANT_PIXMAP | WANT_ALPHA,
GetFrameWidth (OldShieldFrame),
GetFrameHeight (OldShieldFrame), 1));
SetFrameHot (ShieldFrame, GetFrameHot (OldShieldFrame));
Orbit->ObjectFrame = ShieldFrame;
SetShieldThrobEffect (OldShieldFrame, init_x, ShieldFrame);
}
// Render the first planet frame
RenderLevelMasks (init_x);
RenderLevelMasks (init_x, doThrob);
pSolarSysState->Orbit.isPFADefined[init_x] = 1;
zoom_from = (UBYTE)TFB_Random () & 0x03;
@@ -2006,9 +2106,13 @@ rotate_planet_task (void *data)
// If this frame hasn't been generted, generate it
if (!Orbit->isPFADefined[x])
{
RenderLevelMasks (x);
RenderLevelMasks (x, doThrob);
Orbit->isPFADefined[x] = 1;
}
if (doThrob)
{ // prepare next throb frame
SetShieldThrobEffect (OldShieldFrame, x, ShieldFrame);
}
if (zooming)
{
@@ -2028,7 +2132,13 @@ rotate_planet_task (void *data)
TimeIn = GetTimeCounter ();
} while (--view_index && !Task_ReadState (task, TASK_EXIT));
}
if (OldShieldFrame)
{
Orbit->ObjectFrame = OldShieldFrame;
DestroyDrawable (ReleaseDrawable (ShieldFrame));
}
FinishTask (task);
return 0;
+14
View File
@@ -70,6 +70,7 @@ struct options_struct {
int whichMenu;
int whichFonts;
int whichIntro;
int whichShield;
int smoothScroll;
int meleeScale;
BOOLEAN subTitles;
@@ -118,6 +119,7 @@ main (int argc, char *argv[])
/* .whichMenu = */ OPT_PC,
/* .whichFont = */ OPT_PC,
/* .whichIntro = */ OPT_3DO,
/* .whichShield = */ OPT_PC,
/* .smoothScroll = */ OPT_PC,
/* .meleeScale = */ TFB_SCALE_TRILINEAR,
/* .subtitles = */ TRUE,
@@ -317,6 +319,7 @@ main (int argc, char *argv[])
optWhichMenu = options.whichMenu;
optWhichFonts = options.whichFonts;
optWhichIntro = options.whichIntro;
optWhichShield = options.whichShield;
optSmoothScroll = options.smoothScroll;
optMeleeScale = options.meleeScale;
optSubtitles = options.subTitles;
@@ -370,6 +373,7 @@ enum
CSCAN_OPT = 1000,
MENU_OPT,
FONT_OPT,
SHIELD_OPT,
SCROLL_OPT,
SOUND_OPT,
STEREOSFX_OPT,
@@ -406,6 +410,7 @@ static struct option longOptions[] =
{"cscan", 1, NULL, CSCAN_OPT},
{"menu", 1, NULL, MENU_OPT},
{"font", 1, NULL, FONT_OPT},
{"shield", 1, NULL, SHIELD_OPT},
{"scroll", 1, NULL, SCROLL_OPT},
{"sound", 1, NULL, SOUND_OPT},
{"stereosfx", 0, NULL, STEREOSFX_OPT},
@@ -656,6 +661,12 @@ parseOptions(int argc, char *argv[], struct options_struct *options)
&options->whichFonts) == -1)
badArg = TRUE;
break;
case SHIELD_OPT:
if (Check_PC_3DO_opt (optarg, OPT_PC | OPT_3DO,
longOptions[optionIndex].name,
&options->whichShield) == -1)
badArg = TRUE;
break;
case SCROLL_OPT:
if (Check_PC_3DO_opt (optarg, OPT_PC | OPT_3DO,
longOptions[optionIndex].name,
@@ -856,6 +867,9 @@ usage (FILE *out, const struct options_struct *defaultOptions)
"(default %s)\n", PC_3DO_optString(defaultOptions->whichMenu));
fprintf (out, " --font : font types and colors (default %s)\n",
PC_3DO_optString(defaultOptions->whichFonts));
fprintf (out, " --shield : slave shield type; pc=static, "
"3do=throbbing (default %s)\n",
PC_3DO_optString(defaultOptions->whichShield));
fprintf (out, " --scroll : ff/frev during comm. pc=per-page, "
"3do=smooth (default %s)\n",
PC_3DO_optString(defaultOptions->smoothScroll));