Split planet rotation code into sensible functions in preparation for dethreading; some cleanups
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@3391 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
+160
-66
@@ -21,7 +21,9 @@
|
|||||||
#include "../setup.h"
|
#include "../setup.h"
|
||||||
#include "libs/graphics/gfx_common.h"
|
#include "libs/graphics/gfx_common.h"
|
||||||
#include "libs/graphics/drawable.h"
|
#include "libs/graphics/drawable.h"
|
||||||
|
#include "libs/mathlib.h"
|
||||||
#include "scan.h"
|
#include "scan.h"
|
||||||
|
#include "options.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@@ -41,87 +43,179 @@ extern void fill_frame_rgb (FRAME FramePtr, DWORD color, int x0, int y0,
|
|||||||
extern void arith_frame_blit (FRAME srcFrame, const RECT *rsrc,
|
extern void arith_frame_blit (FRAME srcFrame, const RECT *rsrc,
|
||||||
FRAME dstFrame, const RECT *rdst, int num, int denom);
|
FRAME dstFrame, const RECT *rdst, int num, int denom);
|
||||||
|
|
||||||
|
static int rotFrameIndex;
|
||||||
|
static int rotDirection;
|
||||||
|
static bool throbShield;
|
||||||
|
static int rotPointIndex;
|
||||||
|
|
||||||
// RotatePlanet
|
// Draw the planet sphere and any extra graphic (like a shield) if present
|
||||||
// This will take care of zooming into a planet on orbit, generating the planet frames
|
void
|
||||||
// And applying the shield.
|
DrawPlanetSphere (int x, int y)
|
||||||
|
|
||||||
// The speed to zoom in.
|
|
||||||
#define PLANET_ZOOM_SPEED 2
|
|
||||||
|
|
||||||
RECT*
|
|
||||||
RotatePlanet (int x, int dx, int dy, COUNT scale_amt, UBYTE zoom_from,
|
|
||||||
RECT *zoomr)
|
|
||||||
{
|
{
|
||||||
STAMP s;
|
STAMP s;
|
||||||
FRAME pFrame[2];
|
|
||||||
COUNT i, num_frames;
|
|
||||||
int old_scale, old_mode;
|
|
||||||
RECT *rp = NULL;
|
|
||||||
CONTEXT OldContext;
|
|
||||||
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
||||||
int base = GSCALE_IDENTITY;
|
|
||||||
|
|
||||||
num_frames = 1;
|
s.origin.x = x;
|
||||||
pFrame[0] = Orbit->PlanetFrameArray;
|
s.origin.y = y;
|
||||||
|
|
||||||
|
BatchGraphics ();
|
||||||
|
s.frame = Orbit->SphereFrame;
|
||||||
|
DrawStamp (&s);
|
||||||
if (Orbit->ObjectFrame)
|
if (Orbit->ObjectFrame)
|
||||||
{
|
{
|
||||||
pFrame[1] = Orbit->ObjectFrame;
|
s.frame = Orbit->ObjectFrame;
|
||||||
num_frames++;
|
DrawStamp (&s);
|
||||||
}
|
}
|
||||||
|
UnbatchGraphics ();
|
||||||
|
}
|
||||||
|
|
||||||
if (scale_amt)
|
|
||||||
{
|
|
||||||
if (zoomr->extent.width)
|
|
||||||
rp = zoomr;
|
|
||||||
// we're zooming in, take care of scaling the frames
|
|
||||||
//Translate the planet so it comes from the bottom right corner
|
|
||||||
dx += ((zoom_from & 0x01) ? 1 : -1) * dx * (base - scale_amt) / base;
|
|
||||||
dy += ((zoom_from & 0x02) ? 1 : -1) * dy * (base - scale_amt) / base;
|
|
||||||
}
|
|
||||||
|
|
||||||
//LockMutex (GraphicsLock);
|
void
|
||||||
|
InitSphereRotation (int direction, BOOLEAN shielded)
|
||||||
|
{
|
||||||
|
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
||||||
|
|
||||||
// PauseRotate needs to be checked twice. It is first checked
|
rotDirection = direction;
|
||||||
// at the rotate_planet_task function to bypass rendering the
|
rotPointIndex = 0;
|
||||||
// planet (and thus slowinng down other parts of te code. It
|
throbShield = shielded && optWhichShield == OPT_3DO;
|
||||||
// is checked here because it is possile that PauseRotate was
|
|
||||||
// set between then and now, and we don't want too push
|
|
||||||
// anything onto the DrawQueue in that case. If the locking
|
|
||||||
// operation is moved before the RenderPlanetSphere call, one of
|
|
||||||
// the two PauseRotate checks can be removed.
|
|
||||||
|
|
||||||
//if (((SOLARSYS_STATE *volatile)pSolarSysState)->PauseRotate !=1)
|
if (throbShield)
|
||||||
{
|
{
|
||||||
OldContext = SetContext (SpaceContext);
|
// ObjectFrame must contain the shield graphic
|
||||||
|
Orbit->WorkFrame = Orbit->ObjectFrame;
|
||||||
|
// We need a scratch frame so that we can apply throbbing
|
||||||
|
// to the shield, so create one
|
||||||
|
Orbit->ObjectFrame = CaptureDrawable (CreateDrawable (
|
||||||
|
WANT_PIXMAP | WANT_ALPHA,
|
||||||
|
GetFrameWidth (Orbit->ObjectFrame),
|
||||||
|
GetFrameHeight (Orbit->ObjectFrame), 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render the first sphere/shield frame
|
||||||
|
// Prepare will set the next one
|
||||||
|
rotFrameIndex = 1;
|
||||||
|
PrepareNextRotationFrame ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UninitSphereRotation (void)
|
||||||
|
{
|
||||||
|
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
||||||
|
|
||||||
|
if (Orbit->WorkFrame)
|
||||||
|
{
|
||||||
|
DestroyDrawable (ReleaseDrawable (Orbit->ObjectFrame));
|
||||||
|
Orbit->ObjectFrame = Orbit->WorkFrame;
|
||||||
|
Orbit->WorkFrame = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PrepareNextRotationFrame (void)
|
||||||
|
{
|
||||||
|
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
||||||
|
|
||||||
|
// Generate the next rotation frame
|
||||||
|
// We alternate between the frames because we do not call FlushGraphics()
|
||||||
|
// The frame we just drew may not have made it to the screen yet
|
||||||
|
rotFrameIndex ^= 1;
|
||||||
|
|
||||||
|
// Go to next point, taking care of wraparounds
|
||||||
|
rotPointIndex += rotDirection;
|
||||||
|
if (rotPointIndex < 0)
|
||||||
|
rotPointIndex = MAP_WIDTH - 1;
|
||||||
|
else if (rotPointIndex >= MAP_WIDTH)
|
||||||
|
rotPointIndex = 0;
|
||||||
|
|
||||||
|
// prepare the next sphere frame
|
||||||
|
Orbit->SphereFrame = SetAbsFrameIndex (Orbit->SphereFrame, rotFrameIndex);
|
||||||
|
RenderPlanetSphere (Orbit->SphereFrame, rotPointIndex, throbShield);
|
||||||
|
|
||||||
|
if (throbShield)
|
||||||
|
{ // prepare the next shield throb frame
|
||||||
|
Orbit->ObjectFrame = SetAbsFrameIndex (Orbit->ObjectFrame,
|
||||||
|
rotFrameIndex);
|
||||||
|
SetShieldThrobEffect (Orbit->WorkFrame, rotPointIndex,
|
||||||
|
Orbit->ObjectFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZOOM_RATE 24
|
||||||
|
#define ZOOM_TIME (ONE_SECOND * 6 / 5)
|
||||||
|
|
||||||
|
// This takes care of zooming the planet sphere into place
|
||||||
|
// when entering orbit
|
||||||
|
void
|
||||||
|
ZoomInPlanetSphere (void)
|
||||||
|
{
|
||||||
|
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
||||||
|
const int base = GSCALE_IDENTITY;
|
||||||
|
int dx, dy;
|
||||||
|
int oldScale;
|
||||||
|
int oldMode;
|
||||||
|
int i;
|
||||||
|
int frameCount;
|
||||||
|
int zoomCorner;
|
||||||
|
RECT frameRect;
|
||||||
|
RECT repairRect;
|
||||||
|
TimeCount NextTime;
|
||||||
|
|
||||||
|
frameCount = ZOOM_TIME / (ONE_SECOND / ZOOM_RATE);
|
||||||
|
|
||||||
|
// Planet zoom in from a randomly chosen corner
|
||||||
|
zoomCorner = TFB_Random ();
|
||||||
|
dx = 1 - (zoomCorner & 1) * 2;
|
||||||
|
dy = 1 - (zoomCorner & 2);
|
||||||
|
|
||||||
|
if (Orbit->ObjectFrame)
|
||||||
|
GetFrameRect (Orbit->ObjectFrame, &frameRect);
|
||||||
|
else
|
||||||
|
GetFrameRect (Orbit->SphereFrame, &frameRect);
|
||||||
|
repairRect = frameRect;
|
||||||
|
|
||||||
|
for (i = 0; i <= frameCount; ++i)
|
||||||
|
{
|
||||||
|
double scale;
|
||||||
|
POINT pt;
|
||||||
|
|
||||||
|
NextTime = GetTimeCounter () + (ONE_SECOND / ZOOM_RATE);
|
||||||
|
|
||||||
|
// Use 1 + e^-2 - e^(-2x / frameCount)) function to get a decelerating
|
||||||
|
// zoom like the one 3DO does (supposedly)
|
||||||
|
if (i < frameCount)
|
||||||
|
scale = 1.134 - exp (-2.0 * i / frameCount);
|
||||||
|
else
|
||||||
|
scale = 1.0; // final frame
|
||||||
|
|
||||||
|
// start from beyond the screen
|
||||||
|
pt.x = SIS_SCREEN_WIDTH / 2 + (int) (dx * (1.0 - scale)
|
||||||
|
* (SIS_SCREEN_WIDTH * 6 / 10) + 0.5);
|
||||||
|
pt.y = PLANET_ORG_Y + (int) (dy * (1.0 - scale)
|
||||||
|
* (SCAN_SCREEN_HEIGHT * 6 / 10) + 0.5);
|
||||||
|
|
||||||
|
LockMutex (GraphicsLock);
|
||||||
|
SetContext (SpaceContext);
|
||||||
|
|
||||||
BatchGraphics ();
|
BatchGraphics ();
|
||||||
if (rp)
|
if (i > 0)
|
||||||
RepairBackRect (rp);
|
RepairBackRect (&repairRect);
|
||||||
s.origin.x = dx;
|
|
||||||
s.origin.y = dy;
|
|
||||||
old_mode = SetGraphicScaleMode (TFB_SCALE_BILINEAR);
|
|
||||||
old_scale = SetGraphicScale (scale_amt);
|
|
||||||
for (i = 0; i < num_frames; i++)
|
|
||||||
{
|
|
||||||
s.frame = pFrame[i];
|
|
||||||
DrawStamp (&s);
|
|
||||||
}
|
|
||||||
SetGraphicScale (old_scale);
|
|
||||||
SetGraphicScaleMode (old_mode);
|
|
||||||
UnbatchGraphics ();
|
|
||||||
SetContext (OldContext);
|
|
||||||
}
|
|
||||||
//UnlockMutex (GraphicsLock);
|
|
||||||
if (scale_amt && scale_amt != base)
|
|
||||||
{
|
|
||||||
GetFrameRect (pFrame[num_frames - 1], zoomr);
|
|
||||||
zoomr->corner.x += dx;
|
|
||||||
zoomr->corner.y += dy;
|
|
||||||
return zoomr;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
(void)x; // unused param
|
oldMode = SetGraphicScaleMode (TFB_SCALE_BILINEAR);
|
||||||
|
oldScale = SetGraphicScale ((int)(base * scale + 0.5));
|
||||||
|
DrawPlanetSphere (pt.x, pt.y);
|
||||||
|
SetGraphicScale (oldScale);
|
||||||
|
SetGraphicScaleMode (oldMode);
|
||||||
|
|
||||||
|
UnbatchGraphics ();
|
||||||
|
UnlockMutex (GraphicsLock);
|
||||||
|
|
||||||
|
repairRect.corner.x = pt.x + frameRect.corner.x;
|
||||||
|
repairRect.corner.y = pt.y + frameRect.corner.y;
|
||||||
|
|
||||||
|
PrepareNextRotationFrame ();
|
||||||
|
|
||||||
|
SleepThreadUntil (NextTime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// rgb.a is ignored
|
// rgb.a is ignored
|
||||||
|
|||||||
@@ -69,7 +69,6 @@ DrawScannedObjects (BOOLEAN Reversed)
|
|||||||
void
|
void
|
||||||
DrawPlanetSurfaceBorder (void)
|
DrawPlanetSurfaceBorder (void)
|
||||||
{
|
{
|
||||||
#define BORDER_HEIGHT 5
|
|
||||||
CONTEXT oldContext;
|
CONTEXT oldContext;
|
||||||
RECT oldClipRect;
|
RECT oldClipRect;
|
||||||
RECT clipRect;
|
RECT clipRect;
|
||||||
@@ -91,9 +90,9 @@ DrawPlanetSurfaceBorder (void)
|
|||||||
SetContextForeGroundColor (
|
SetContextForeGroundColor (
|
||||||
BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x0A), 0x08));
|
BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x0A), 0x08));
|
||||||
r.corner.x = 0;
|
r.corner.x = 0;
|
||||||
r.corner.y = clipRect.extent.height - MAP_HEIGHT - BORDER_HEIGHT;
|
r.corner.y = clipRect.extent.height - MAP_HEIGHT - MAP_BORDER_HEIGHT;
|
||||||
r.extent.width = clipRect.extent.width;
|
r.extent.width = clipRect.extent.width;
|
||||||
r.extent.height = BORDER_HEIGHT - 2;
|
r.extent.height = MAP_BORDER_HEIGHT - 2;
|
||||||
DrawFilledRectangle (&r);
|
DrawFilledRectangle (&r);
|
||||||
|
|
||||||
SetContextForeGroundColor (SIS_BOTTOM_RIGHT_BORDER_COLOR);
|
SetContextForeGroundColor (SIS_BOTTOM_RIGHT_BORDER_COLOR);
|
||||||
@@ -110,7 +109,7 @@ DrawPlanetSurfaceBorder (void)
|
|||||||
// Right shadow line
|
// Right shadow line
|
||||||
r.extent.width = 1;
|
r.extent.width = 1;
|
||||||
r.extent.height = MAP_HEIGHT + 2;
|
r.extent.height = MAP_HEIGHT + 2;
|
||||||
r.corner.y += BORDER_HEIGHT - 1;
|
r.corner.y += MAP_BORDER_HEIGHT - 1;
|
||||||
r.corner.x = clipRect.extent.width - 1;
|
r.corner.x = clipRect.extent.width - 1;
|
||||||
DrawFilledRectangle (&r);
|
DrawFilledRectangle (&r);
|
||||||
|
|
||||||
@@ -248,12 +247,18 @@ LoadPlanet (FRAME SurfDefFrame)
|
|||||||
|
|
||||||
if (pSolarSysState->MenuState.flash_task == 0)
|
if (pSolarSysState->MenuState.flash_task == 0)
|
||||||
{
|
{
|
||||||
|
assert (pSolarSysState->MenuState.Initialized == 2);
|
||||||
|
|
||||||
|
// Only zoom when not already in orbit
|
||||||
|
if (!(LastActivity & CHECK_LOAD))
|
||||||
|
ZoomInPlanetSphere ();
|
||||||
|
|
||||||
|
// XXX: Mark as in-orbit. This should go away eventually
|
||||||
|
pSolarSysState->MenuState.Initialized = 3;
|
||||||
|
|
||||||
pSolarSysState->MenuState.flash_task =
|
pSolarSysState->MenuState.flash_task =
|
||||||
AssignTask (rotate_planet_task, 4096,
|
AssignTask (rotate_planet_task, 4096,
|
||||||
"rotate planets");
|
"rotate planets");
|
||||||
|
|
||||||
while (pSolarSysState->MenuState.Initialized == 2)
|
|
||||||
TaskSwitch ();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +275,8 @@ FreePlanet (void)
|
|||||||
pSolarSysState->MenuState.flash_task = 0;
|
pSolarSysState->MenuState.flash_task = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UninitSphereRotation ();
|
||||||
|
|
||||||
StopMusic ();
|
StopMusic ();
|
||||||
LockMutex (GraphicsLock);
|
LockMutex (GraphicsLock);
|
||||||
|
|
||||||
@@ -293,8 +300,8 @@ FreePlanet (void)
|
|||||||
Orbit->lpTopoData = 0;
|
Orbit->lpTopoData = 0;
|
||||||
DestroyDrawable (ReleaseDrawable (Orbit->TopoZoomFrame));
|
DestroyDrawable (ReleaseDrawable (Orbit->TopoZoomFrame));
|
||||||
Orbit->TopoZoomFrame = 0;
|
Orbit->TopoZoomFrame = 0;
|
||||||
DestroyDrawable (ReleaseDrawable (Orbit->PlanetFrameArray));
|
DestroyDrawable (ReleaseDrawable (Orbit->SphereFrame));
|
||||||
Orbit->PlanetFrameArray = 0;
|
Orbit->SphereFrame = NULL;
|
||||||
|
|
||||||
DestroyDrawable (ReleaseDrawable (Orbit->TintFrame));
|
DestroyDrawable (ReleaseDrawable (Orbit->TintFrame));
|
||||||
Orbit->TintFrame = 0;
|
Orbit->TintFrame = 0;
|
||||||
|
|||||||
@@ -88,6 +88,13 @@ enum
|
|||||||
#define MAX_PLANETS 16
|
#define MAX_PLANETS 16
|
||||||
#define MAX_MOONS 4
|
#define MAX_MOONS 4
|
||||||
|
|
||||||
|
#define MAP_BORDER_HEIGHT 5
|
||||||
|
#define SCAN_SCREEN_HEIGHT (SIS_SCREEN_HEIGHT - MAP_HEIGHT - MAP_BORDER_HEIGHT)
|
||||||
|
|
||||||
|
#define PLANET_ROTATION_TIME (ONE_SECOND * 12)
|
||||||
|
#define PLANET_ROTATION_RATE (PLANET_ROTATION_TIME / MAP_WIDTH)
|
||||||
|
// XXX: -9 to match the original, but why? I have no idea
|
||||||
|
#define PLANET_ORG_Y ((SCAN_SCREEN_HEIGHT - 9) / 2)
|
||||||
|
|
||||||
typedef struct planet_desc PLANET_DESC;
|
typedef struct planet_desc PLANET_DESC;
|
||||||
typedef struct star_desc STAR_DESC;
|
typedef struct star_desc STAR_DESC;
|
||||||
@@ -141,7 +148,7 @@ struct planet_orbit
|
|||||||
// normal topo data; expressed in elevation levels
|
// normal topo data; expressed in elevation levels
|
||||||
// data is signed for planets other than gas giants
|
// data is signed for planets other than gas giants
|
||||||
// transformed to light variance map for 3d planet
|
// transformed to light variance map for 3d planet
|
||||||
FRAME PlanetFrameArray;
|
FRAME SphereFrame;
|
||||||
// rotating 3d planet frames (current and next)
|
// rotating 3d planet frames (current and next)
|
||||||
FRAME ObjectFrame;
|
FRAME ObjectFrame;
|
||||||
// any extra planetary object (shield, atmo, rings)
|
// any extra planetary object (shield, atmo, rings)
|
||||||
@@ -258,9 +265,15 @@ extern void FillOrbits (SOLARSYS_STATE *system, BYTE NumPlanets,
|
|||||||
PLANET_DESC *pBaseDesc, BOOLEAN TypesDefined);
|
PLANET_DESC *pBaseDesc, BOOLEAN TypesDefined);
|
||||||
extern void InitLander (BYTE LanderFlags);
|
extern void InitLander (BYTE LanderFlags);
|
||||||
|
|
||||||
extern RECT* RotatePlanet (int x, int dx, int dy, COUNT scale_amt,
|
extern void InitSphereRotation (int direction, BOOLEAN shielded);
|
||||||
UBYTE zoom_from, RECT *r);
|
extern void UninitSphereRotation (void);
|
||||||
extern void SetPlanetTilt (int da);
|
extern void PrepareNextRotationFrame (void);
|
||||||
|
extern void DrawPlanetSphere (int x, int y);
|
||||||
|
extern void RenderPlanetSphere (FRAME Frame, int offset, BOOLEAN doThrob);
|
||||||
|
extern void SetShieldThrobEffect (FRAME FromFrame, int offset, FRAME ToFrame);
|
||||||
|
|
||||||
|
extern void ZoomInPlanetSphere (void);
|
||||||
|
|
||||||
extern void DrawScannedObjects (BOOLEAN Reversed);
|
extern void DrawScannedObjects (BOOLEAN Reversed);
|
||||||
extern void GeneratePlanetSurface (PLANET_DESC *pPlanetDesc,
|
extern void GeneratePlanetSurface (PLANET_DESC *pPlanetDesc,
|
||||||
FRAME SurfDefFrame);
|
FRAME SurfDefFrame);
|
||||||
|
|||||||
+29
-162
@@ -32,10 +32,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#undef PROFILE_ROTATION
|
#undef PROFILE_ROTATION
|
||||||
#define ROTATION_TIME 12
|
|
||||||
|
|
||||||
// The initial size of the planet when zooming. MUST BE ODD
|
|
||||||
#define PLANET_INIT_ZOOM_SIZE 3
|
|
||||||
|
|
||||||
// define USE_ALPHA_SHIELD to use an aloha overlay instead of
|
// define USE_ALPHA_SHIELD to use an aloha overlay instead of
|
||||||
// an additive overlay for the shield effect
|
// an additive overlay for the shield effect
|
||||||
@@ -59,7 +55,6 @@ extern void getpixelarray (void *map, int Bpp, FRAME FramePtr,
|
|||||||
#define SHIELD_REFLECT_COMP 100
|
#define SHIELD_REFLECT_COMP 100
|
||||||
|
|
||||||
#define NUM_BATCH_POINTS 64
|
#define NUM_BATCH_POINTS 64
|
||||||
#define USE_3D_PLANET 1
|
|
||||||
#define RADIUS 37
|
#define RADIUS 37
|
||||||
//2*RADIUS
|
//2*RADIUS
|
||||||
#define TWORADIUS (RADIUS << 1)
|
#define TWORADIUS (RADIUS << 1)
|
||||||
@@ -117,15 +112,9 @@ RenderTopography (FRAME DstFrame, BYTE *pTopoData, int w, int h)
|
|||||||
|
|
||||||
if (pSolarSysState->XlatRef == 0)
|
if (pSolarSysState->XlatRef == 0)
|
||||||
{
|
{
|
||||||
STAMP s;
|
// There is currently nothing we can do w/o an xlat table
|
||||||
|
// This is still called for Earth for 4x scaled topo, but we
|
||||||
s.origin.x = s.origin.y = 0;
|
// do not need it because we cannot land on Earth.
|
||||||
#if 0
|
|
||||||
s.frame = SetAbsFrameIndex (
|
|
||||||
pSolarSysState->PlanetFrameArray[2], 1
|
|
||||||
);
|
|
||||||
DrawStamp (&s);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -450,7 +439,7 @@ get_avg_rgb (DWORD p1[4], DWORD mult[4], COUNT offset)
|
|||||||
|
|
||||||
// CreateSphereTiltMap creates 'map_rotate' to map the topo data
|
// CreateSphereTiltMap creates 'map_rotate' to map the topo data
|
||||||
// for a tilted planet. It also does the sphere->plane mapping
|
// for a tilted planet. It also does the sphere->plane mapping
|
||||||
void
|
static void
|
||||||
CreateSphereTiltMap (int angle)
|
CreateSphereTiltMap (int angle)
|
||||||
{
|
{
|
||||||
int x, y;
|
int x, y;
|
||||||
@@ -507,32 +496,6 @@ CreateSphereTiltMap (int angle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//init_zoom_array
|
|
||||||
// evaluate the function 5/6*(1-e^(-x/14)) to get a decelerating zoom
|
|
||||||
// on entering planet orbit. This gives us nearly equivalent to what
|
|
||||||
// the 3DO does.
|
|
||||||
#define ZOOM_TIME (1.13)
|
|
||||||
#define ZOOM_FACT1 (6.0 / 5)
|
|
||||||
#define ZOOM_FACT2 (14.0 / 25)
|
|
||||||
COUNT
|
|
||||||
init_zoom_array (COUNT *zoom_arr)
|
|
||||||
{
|
|
||||||
float frames_per_sec;
|
|
||||||
int num_frames, i;
|
|
||||||
int base = GSCALE_IDENTITY;
|
|
||||||
|
|
||||||
frames_per_sec = (float)MAP_WIDTH / ROTATION_TIME;
|
|
||||||
num_frames = (int)((frames_per_sec * ZOOM_TIME) + 0.5);
|
|
||||||
for (i = 0; i < num_frames; i++)
|
|
||||||
{
|
|
||||||
zoom_arr[i] = (COUNT) (base * ZOOM_FACT1 *
|
|
||||||
(1 - exp (-(i + 1) / (ZOOM_FACT2 * num_frames))));
|
|
||||||
}
|
|
||||||
zoom_arr[i] = base;
|
|
||||||
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
//CreateShieldMask
|
//CreateShieldMask
|
||||||
// The shield is created in two parts. This routine creates the Halo.
|
// The shield is created in two parts. This routine creates the Halo.
|
||||||
// The red tint of the planet is currently applied in RenderPlanetSphere
|
// The red tint of the planet is currently applied in RenderPlanetSphere
|
||||||
@@ -641,7 +604,7 @@ shield_level (int offset)
|
|||||||
|
|
||||||
// See description above
|
// See description above
|
||||||
// offset is effectively the angle of rotation around the planet's axis
|
// offset is effectively the angle of rotation around the planet's axis
|
||||||
static void
|
void
|
||||||
SetShieldThrobEffect (FRAME ShieldFrame, int offset, FRAME ThrobFrame)
|
SetShieldThrobEffect (FRAME ShieldFrame, int offset, FRAME ThrobFrame)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
@@ -1333,12 +1296,12 @@ ValidateMap (SBYTE *DepthArray)
|
|||||||
} while (--i);
|
} while (--i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
planet_orbit_init (void)
|
planet_orbit_init (void)
|
||||||
{
|
{
|
||||||
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
||||||
|
|
||||||
Orbit->PlanetFrameArray = CaptureDrawable (CreateDrawable (
|
Orbit->SphereFrame = CaptureDrawable (CreateDrawable (
|
||||||
WANT_PIXMAP | WANT_ALPHA, DIAMETER, DIAMETER, 2));
|
WANT_PIXMAP | WANT_ALPHA, DIAMETER, DIAMETER, 2));
|
||||||
Orbit->TintFrame = CaptureDrawable (CreateDrawable (
|
Orbit->TintFrame = CaptureDrawable (CreateDrawable (
|
||||||
WANT_PIXMAP | WANT_ALPHA, MAP_WIDTH, MAP_HEIGHT, 2));
|
WANT_PIXMAP | WANT_ALPHA, MAP_WIDTH, MAP_HEIGHT, 2));
|
||||||
@@ -1767,11 +1730,13 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
|
|||||||
RECT r;
|
RECT r;
|
||||||
DWORD old_seed;
|
DWORD old_seed;
|
||||||
const PlanetFrame *PlanDataPtr;
|
const PlanetFrame *PlanDataPtr;
|
||||||
|
PLANET_INFO *PlanetInfo = &pSolarSysState->SysInfo.PlanetInfo;
|
||||||
COUNT i, y;
|
COUNT i, y;
|
||||||
POINT loc;
|
POINT loc;
|
||||||
CONTEXT OldContext;
|
CONTEXT OldContext;
|
||||||
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
|
||||||
BYTE *pScaledTopo = 0;
|
BYTE *pScaledTopo = 0;
|
||||||
|
BOOLEAN shielded = (pPlanetDesc->data_index & PLANET_SHIELDED) != 0;
|
||||||
|
|
||||||
old_seed = TFB_SeedRandom (pPlanetDesc->rand_seed);
|
old_seed = TFB_SeedRandom (pPlanetDesc->rand_seed);
|
||||||
|
|
||||||
@@ -1906,16 +1871,14 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
|
|||||||
pSolarSysState->XlatRef = CaptureStringTable (
|
pSolarSysState->XlatRef = CaptureStringTable (
|
||||||
LoadStringTable (PlanDataPtr->XlatTabInstance));
|
LoadStringTable (PlanDataPtr->XlatTabInstance));
|
||||||
|
|
||||||
if (pSolarSysState->SysInfo.PlanetInfo.SurfaceTemperature >
|
if (PlanetInfo->SurfaceTemperature > HOT_THRESHOLD)
|
||||||
HOT_THRESHOLD)
|
|
||||||
{
|
{
|
||||||
pSolarSysState->OrbitalCMap = SetAbsColorMapIndex (
|
pSolarSysState->OrbitalCMap = SetAbsColorMapIndex (
|
||||||
pSolarSysState->OrbitalCMap, 2);
|
pSolarSysState->OrbitalCMap, 2);
|
||||||
pSolarSysState->XlatRef = SetAbsStringTableIndex (
|
pSolarSysState->XlatRef = SetAbsStringTableIndex (
|
||||||
pSolarSysState->XlatRef, 2);
|
pSolarSysState->XlatRef, 2);
|
||||||
}
|
}
|
||||||
else if (pSolarSysState->SysInfo.PlanetInfo.SurfaceTemperature >
|
else if (PlanetInfo->SurfaceTemperature > COLD_THRESHOLD)
|
||||||
COLD_THRESHOLD)
|
|
||||||
{
|
{
|
||||||
pSolarSysState->OrbitalCMap = SetAbsColorMapIndex (
|
pSolarSysState->OrbitalCMap = SetAbsColorMapIndex (
|
||||||
pSolarSysState->OrbitalCMap, 1);
|
pSolarSysState->OrbitalCMap, 1);
|
||||||
@@ -1928,10 +1891,8 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pPlanetDesc->data_index & PLANET_SHIELDED)
|
if (!shielded && PlanetInfo->AtmoDensity != GAS_GIANT_ATMOSPHERE)
|
||||||
&& pSolarSysState->SysInfo.PlanetInfo.AtmoDensity
|
{ // produce 4x scaled topo image for Planetside
|
||||||
!= GAS_GIANT_ATMOSPHERE)
|
|
||||||
{ // produce 4x scaled topo image for IP
|
|
||||||
// for the planets that we can land on
|
// for the planets that we can land on
|
||||||
pScaledTopo = HMalloc (MAP_WIDTH * 4 * MAP_HEIGHT * 4);
|
pScaledTopo = HMalloc (MAP_WIDTH * 4 * MAP_HEIGHT * 4);
|
||||||
if (pScaledTopo)
|
if (pScaledTopo)
|
||||||
@@ -1979,12 +1940,16 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
|
|||||||
loc = pSolarSysState->pOrbitalDesc->pPrevDesc->location;
|
loc = pSolarSysState->pOrbitalDesc->pPrevDesc->location;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rotating planet sphere initialization
|
||||||
GenerateSphereMask (loc);
|
GenerateSphereMask (loc);
|
||||||
CreateSphereTiltMap (pSolarSysState->SysInfo.PlanetInfo.AxialTilt);
|
CreateSphereTiltMap (PlanetInfo->AxialTilt);
|
||||||
|
if (shielded)
|
||||||
if (pPlanetDesc->data_index & PLANET_SHIELDED)
|
|
||||||
{
|
|
||||||
Orbit->ObjectFrame = CreateShieldMask ();
|
Orbit->ObjectFrame = CreateShieldMask ();
|
||||||
|
InitSphereRotation (1 - 2 * (PlanetInfo->AxialTilt & 1), shielded);
|
||||||
|
|
||||||
|
if (shielded)
|
||||||
|
{ // This overwrites pSolarSysState->TopoFrame, so everything that
|
||||||
|
// needs it has to come before
|
||||||
ApplyShieldTint ();
|
ApplyShieldTint ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1997,69 +1962,16 @@ int
|
|||||||
rotate_planet_task (void *data)
|
rotate_planet_task (void *data)
|
||||||
{
|
{
|
||||||
Task task = (Task) data;
|
Task task = (Task) data;
|
||||||
SIZE spin_dir;
|
|
||||||
COORD init_x;
|
|
||||||
DWORD TimeIn;
|
DWORD TimeIn;
|
||||||
SOLARSYS_STATE *pSS;
|
SOLARSYS_STATE *pSS;
|
||||||
BOOLEAN zooming;
|
|
||||||
RECT r, *repair = &r;
|
|
||||||
UBYTE zoom_from;
|
|
||||||
COUNT zoom_arr[50];
|
|
||||||
COUNT zoom_amt, frame_num = 0, zoom_frames;
|
|
||||||
PLANET_ORBIT *Orbit;
|
|
||||||
FRAME OldShieldFrame = 0;
|
|
||||||
FRAME ShieldFrame = 0;
|
|
||||||
BOOLEAN doThrob = FALSE;
|
|
||||||
COUNT altfi; // alternating frame index
|
|
||||||
|
|
||||||
r.extent.width = 0;
|
|
||||||
zooming = TRUE;
|
|
||||||
|
|
||||||
pSS = pSolarSysState;
|
pSS = pSolarSysState;
|
||||||
while (*(volatile SIZE *)&pSS->MenuState.Initialized < 2 &&
|
|
||||||
!Task_ReadState (task, TASK_EXIT))
|
|
||||||
TaskSwitch ();
|
|
||||||
|
|
||||||
Orbit = &pSolarSysState->Orbit;
|
|
||||||
|
|
||||||
spin_dir = 1 - ((pSS->SysInfo.PlanetInfo.AxialTilt & 1) << 1);
|
|
||||||
init_x = (spin_dir == 1) ? (0) : (MAP_WIDTH - 1);
|
|
||||||
altfi = 0;
|
|
||||||
|
|
||||||
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), 2));
|
|
||||||
|
|
||||||
SetShieldThrobEffect (OldShieldFrame, init_x, ShieldFrame);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render the first planet frame
|
|
||||||
RenderPlanetSphere (Orbit->PlanetFrameArray, init_x, doThrob);
|
|
||||||
|
|
||||||
zoom_from = TFB_Random () & 0x03;
|
|
||||||
zoom_frames = init_zoom_array (zoom_arr);
|
|
||||||
zoom_amt = zoom_arr[frame_num];
|
|
||||||
|
|
||||||
// Disable zooming when already in orbit
|
|
||||||
if (LastActivity & CHECK_LOAD)
|
|
||||||
zoom_amt = 0;
|
|
||||||
|
|
||||||
TimeIn = GetTimeCounter ();
|
TimeIn = GetTimeCounter ();
|
||||||
while (!Task_ReadState (task, TASK_EXIT))
|
while (!Task_ReadState (task, TASK_EXIT))
|
||||||
{
|
{
|
||||||
BYTE view_index;
|
CONTEXT oldContext;
|
||||||
COORD x;
|
|
||||||
|
|
||||||
x = init_x;
|
|
||||||
view_index = MAP_WIDTH;
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
// This lock was placed before the RotatePlanet call
|
// This lock was placed before the RotatePlanet call
|
||||||
// To prevent the thread from being interrupted by the flash
|
// To prevent the thread from being interrupted by the flash
|
||||||
@@ -2069,6 +1981,7 @@ rotate_planet_task (void *data)
|
|||||||
// to guarantee that PauseRotate doesn't change while waiting
|
// to guarantee that PauseRotate doesn't change while waiting
|
||||||
// to acquire the graphics lock
|
// to acquire the graphics lock
|
||||||
LockMutex (GraphicsLock);
|
LockMutex (GraphicsLock);
|
||||||
|
|
||||||
if (*(volatile UBYTE *)&pSS->PauseRotate != 1
|
if (*(volatile UBYTE *)&pSS->PauseRotate != 1
|
||||||
&& !(GLOBAL (CurrentActivity) & CHECK_ABORT))
|
&& !(GLOBAL (CurrentActivity) & CHECK_ABORT))
|
||||||
{
|
{
|
||||||
@@ -2076,64 +1989,18 @@ rotate_planet_task (void *data)
|
|||||||
if (*(volatile UBYTE *)&pSS->PauseRotate == 2)
|
if (*(volatile UBYTE *)&pSS->PauseRotate == 2)
|
||||||
pSS->PauseRotate = 1;
|
pSS->PauseRotate = 1;
|
||||||
|
|
||||||
// go to the next frame
|
oldContext = SetContext (SpaceContext);
|
||||||
Orbit->PlanetFrameArray = SetAbsFrameIndex (
|
DrawPlanetSphere (SIS_SCREEN_WIDTH / 2, PLANET_ORG_Y);
|
||||||
Orbit->PlanetFrameArray, altfi);
|
SetContext (oldContext);
|
||||||
if (doThrob)
|
|
||||||
{
|
|
||||||
Orbit->ObjectFrame = SetAbsFrameIndex (
|
|
||||||
ShieldFrame, altfi);
|
|
||||||
}
|
|
||||||
|
|
||||||
repair = RotatePlanet (x, SIS_SCREEN_WIDTH >> 1,
|
PrepareNextRotationFrame ();
|
||||||
(148 - SIS_ORG_Y) >> 1, zoom_amt, zoom_from, repair);
|
|
||||||
|
|
||||||
if (!repair && zooming)
|
|
||||||
{
|
|
||||||
zooming = FALSE;
|
|
||||||
zoom_amt = 0;
|
|
||||||
++pSS->MenuState.Initialized;
|
|
||||||
}
|
|
||||||
x += spin_dir;
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
view_index++;
|
|
||||||
|
|
||||||
UnlockMutex (GraphicsLock);
|
UnlockMutex (GraphicsLock);
|
||||||
|
|
||||||
// Generate the next rotation frame
|
|
||||||
altfi ^= 1;
|
|
||||||
RenderPlanetSphere (SetAbsFrameIndex (Orbit->PlanetFrameArray,
|
|
||||||
altfi), x, doThrob);
|
|
||||||
if (doThrob)
|
|
||||||
{ // prepare next throb frame
|
|
||||||
SetShieldThrobEffect (OldShieldFrame, x,
|
|
||||||
SetAbsFrameIndex (ShieldFrame, altfi));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (zooming)
|
|
||||||
{
|
|
||||||
frame_num++;
|
|
||||||
if (frame_num > zoom_frames)
|
|
||||||
{
|
|
||||||
log_add (log_Warning, "rotate_planet_task() : zoom frame"
|
|
||||||
" out of bounds!");
|
|
||||||
frame_num = zoom_frames;
|
|
||||||
}
|
|
||||||
zoom_amt = zoom_arr[frame_num];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
SleepThreadUntil (TimeIn + PLANET_ROTATION_RATE);
|
||||||
SleepThreadUntil (TimeIn + (ONE_SECOND * ROTATION_TIME) /
|
|
||||||
(MAP_WIDTH));
|
|
||||||
TimeIn = GetTimeCounter ();
|
TimeIn = GetTimeCounter ();
|
||||||
} while (--view_index && !Task_ReadState (task, TASK_EXIT));
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (OldShieldFrame)
|
|
||||||
{
|
|
||||||
Orbit->ObjectFrame = OldShieldFrame;
|
|
||||||
DestroyDrawable (ReleaseDrawable (ShieldFrame));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FinishTask (task);
|
FinishTask (task);
|
||||||
|
|||||||
Reference in New Issue
Block a user