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:
avolkov
2009-12-05 02:26:29 +00:00
parent b98aff0d7f
commit 240dc2d78d
4 changed files with 222 additions and 241 deletions
+163 -69
View File
@@ -21,7 +21,9 @@
#include "../setup.h"
#include "libs/graphics/gfx_common.h"
#include "libs/graphics/drawable.h"
#include "libs/mathlib.h"
#include "scan.h"
#include "options.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,
FRAME dstFrame, const RECT *rdst, int num, int denom);
static int rotFrameIndex;
static int rotDirection;
static bool throbShield;
static int rotPointIndex;
// RotatePlanet
// This will take care of zooming into a planet on orbit, generating the planet frames
// And applying the shield.
// 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)
// Draw the planet sphere and any extra graphic (like a shield) if present
void
DrawPlanetSphere (int x, int y)
{
STAMP s;
FRAME pFrame[2];
COUNT i, num_frames;
int old_scale, old_mode;
RECT *rp = NULL;
CONTEXT OldContext;
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
int base = GSCALE_IDENTITY;
num_frames = 1;
pFrame[0] = Orbit->PlanetFrameArray;
s.origin.x = x;
s.origin.y = y;
BatchGraphics ();
s.frame = Orbit->SphereFrame;
DrawStamp (&s);
if (Orbit->ObjectFrame)
{
pFrame[1] = Orbit->ObjectFrame;
num_frames++;
}
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);
// PauseRotate needs to be checked twice. It is first checked
// at the rotate_planet_task function to bypass rendering the
// planet (and thus slowinng down other parts of te code. It
// 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)
{
OldContext = SetContext (SpaceContext);
BatchGraphics ();
if (rp)
RepairBackRect (rp);
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];
s.frame = Orbit->ObjectFrame;
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
void
InitSphereRotation (int direction, BOOLEAN shielded)
{
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
rotDirection = direction;
rotPointIndex = 0;
throbShield = shielded && optWhichShield == OPT_3DO;
if (throbShield)
{
// 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 ();
if (i > 0)
RepairBackRect (&repairRect);
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
+16 -9
View File
@@ -69,7 +69,6 @@ DrawScannedObjects (BOOLEAN Reversed)
void
DrawPlanetSurfaceBorder (void)
{
#define BORDER_HEIGHT 5
CONTEXT oldContext;
RECT oldClipRect;
RECT clipRect;
@@ -91,9 +90,9 @@ DrawPlanetSurfaceBorder (void)
SetContextForeGroundColor (
BUILD_COLOR (MAKE_RGB15 (0x0A, 0x0A, 0x0A), 0x08));
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.height = BORDER_HEIGHT - 2;
r.extent.height = MAP_BORDER_HEIGHT - 2;
DrawFilledRectangle (&r);
SetContextForeGroundColor (SIS_BOTTOM_RIGHT_BORDER_COLOR);
@@ -110,7 +109,7 @@ DrawPlanetSurfaceBorder (void)
// Right shadow line
r.extent.width = 1;
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;
DrawFilledRectangle (&r);
@@ -248,12 +247,18 @@ LoadPlanet (FRAME SurfDefFrame)
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 =
AssignTask (rotate_planet_task, 4096,
"rotate planets");
while (pSolarSysState->MenuState.Initialized == 2)
TaskSwitch ();
}
}
@@ -270,6 +275,8 @@ FreePlanet (void)
pSolarSysState->MenuState.flash_task = 0;
}
UninitSphereRotation ();
StopMusic ();
LockMutex (GraphicsLock);
@@ -293,8 +300,8 @@ FreePlanet (void)
Orbit->lpTopoData = 0;
DestroyDrawable (ReleaseDrawable (Orbit->TopoZoomFrame));
Orbit->TopoZoomFrame = 0;
DestroyDrawable (ReleaseDrawable (Orbit->PlanetFrameArray));
Orbit->PlanetFrameArray = 0;
DestroyDrawable (ReleaseDrawable (Orbit->SphereFrame));
Orbit->SphereFrame = NULL;
DestroyDrawable (ReleaseDrawable (Orbit->TintFrame));
Orbit->TintFrame = 0;
+17 -4
View File
@@ -88,6 +88,13 @@ enum
#define MAX_PLANETS 16
#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 star_desc STAR_DESC;
@@ -141,7 +148,7 @@ struct planet_orbit
// normal topo data; expressed in elevation levels
// data is signed for planets other than gas giants
// transformed to light variance map for 3d planet
FRAME PlanetFrameArray;
FRAME SphereFrame;
// rotating 3d planet frames (current and next)
FRAME ObjectFrame;
// any extra planetary object (shield, atmo, rings)
@@ -258,9 +265,15 @@ extern void FillOrbits (SOLARSYS_STATE *system, BYTE NumPlanets,
PLANET_DESC *pBaseDesc, BOOLEAN TypesDefined);
extern void InitLander (BYTE LanderFlags);
extern RECT* RotatePlanet (int x, int dx, int dy, COUNT scale_amt,
UBYTE zoom_from, RECT *r);
extern void SetPlanetTilt (int da);
extern void InitSphereRotation (int direction, BOOLEAN shielded);
extern void UninitSphereRotation (void);
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 GeneratePlanetSurface (PLANET_DESC *pPlanetDesc,
FRAME SurfDefFrame);
+28 -161
View File
@@ -32,10 +32,6 @@
#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
// 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 NUM_BATCH_POINTS 64
#define USE_3D_PLANET 1
#define RADIUS 37
//2*RADIUS
#define TWORADIUS (RADIUS << 1)
@@ -117,15 +112,9 @@ RenderTopography (FRAME DstFrame, BYTE *pTopoData, int w, int h)
if (pSolarSysState->XlatRef == 0)
{
STAMP s;
s.origin.x = s.origin.y = 0;
#if 0
s.frame = SetAbsFrameIndex (
pSolarSysState->PlanetFrameArray[2], 1
);
DrawStamp (&s);
#endif
// There is currently nothing we can do w/o an xlat table
// This is still called for Earth for 4x scaled topo, but we
// do not need it because we cannot land on Earth.
}
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
// for a tilted planet. It also does the sphere->plane mapping
void
static void
CreateSphereTiltMap (int angle)
{
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
// The shield is created in two parts. This routine creates the Halo.
// The red tint of the planet is currently applied in RenderPlanetSphere
@@ -641,7 +604,7 @@ shield_level (int offset)
// See description above
// offset is effectively the angle of rotation around the planet's axis
static void
void
SetShieldThrobEffect (FRAME ShieldFrame, int offset, FRAME ThrobFrame)
{
int i;
@@ -1333,12 +1296,12 @@ ValidateMap (SBYTE *DepthArray)
} while (--i);
}
void
static void
planet_orbit_init (void)
{
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
Orbit->PlanetFrameArray = CaptureDrawable (CreateDrawable (
Orbit->SphereFrame = CaptureDrawable (CreateDrawable (
WANT_PIXMAP | WANT_ALPHA, DIAMETER, DIAMETER, 2));
Orbit->TintFrame = CaptureDrawable (CreateDrawable (
WANT_PIXMAP | WANT_ALPHA, MAP_WIDTH, MAP_HEIGHT, 2));
@@ -1767,11 +1730,13 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
RECT r;
DWORD old_seed;
const PlanetFrame *PlanDataPtr;
PLANET_INFO *PlanetInfo = &pSolarSysState->SysInfo.PlanetInfo;
COUNT i, y;
POINT loc;
CONTEXT OldContext;
PLANET_ORBIT *Orbit = &pSolarSysState->Orbit;
BYTE *pScaledTopo = 0;
BOOLEAN shielded = (pPlanetDesc->data_index & PLANET_SHIELDED) != 0;
old_seed = TFB_SeedRandom (pPlanetDesc->rand_seed);
@@ -1906,16 +1871,14 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
pSolarSysState->XlatRef = CaptureStringTable (
LoadStringTable (PlanDataPtr->XlatTabInstance));
if (pSolarSysState->SysInfo.PlanetInfo.SurfaceTemperature >
HOT_THRESHOLD)
if (PlanetInfo->SurfaceTemperature > HOT_THRESHOLD)
{
pSolarSysState->OrbitalCMap = SetAbsColorMapIndex (
pSolarSysState->OrbitalCMap, 2);
pSolarSysState->XlatRef = SetAbsStringTableIndex (
pSolarSysState->XlatRef, 2);
}
else if (pSolarSysState->SysInfo.PlanetInfo.SurfaceTemperature >
COLD_THRESHOLD)
else if (PlanetInfo->SurfaceTemperature > COLD_THRESHOLD)
{
pSolarSysState->OrbitalCMap = SetAbsColorMapIndex (
pSolarSysState->OrbitalCMap, 1);
@@ -1928,10 +1891,8 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
}
if (!(pPlanetDesc->data_index & PLANET_SHIELDED)
&& pSolarSysState->SysInfo.PlanetInfo.AtmoDensity
!= GAS_GIANT_ATMOSPHERE)
{ // produce 4x scaled topo image for IP
if (!shielded && PlanetInfo->AtmoDensity != GAS_GIANT_ATMOSPHERE)
{ // produce 4x scaled topo image for Planetside
// for the planets that we can land on
pScaledTopo = HMalloc (MAP_WIDTH * 4 * MAP_HEIGHT * 4);
if (pScaledTopo)
@@ -1979,12 +1940,16 @@ GeneratePlanetSurface (PLANET_DESC *pPlanetDesc, FRAME SurfDefFrame)
loc = pSolarSysState->pOrbitalDesc->pPrevDesc->location;
}
// Rotating planet sphere initialization
GenerateSphereMask (loc);
CreateSphereTiltMap (pSolarSysState->SysInfo.PlanetInfo.AxialTilt);
if (pPlanetDesc->data_index & PLANET_SHIELDED)
{
CreateSphereTiltMap (PlanetInfo->AxialTilt);
if (shielded)
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 ();
}
@@ -1997,69 +1962,16 @@ int
rotate_planet_task (void *data)
{
Task task = (Task) data;
SIZE spin_dir;
COORD init_x;
DWORD TimeIn;
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;
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 ();
while (!Task_ReadState (task, TASK_EXIT))
{
BYTE view_index;
COORD x;
CONTEXT oldContext;
x = init_x;
view_index = MAP_WIDTH;
do
{
// This lock was placed before the RotatePlanet call
// 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 acquire the graphics lock
LockMutex (GraphicsLock);
if (*(volatile UBYTE *)&pSS->PauseRotate != 1
&& !(GLOBAL (CurrentActivity) & CHECK_ABORT))
{
@@ -2076,64 +1989,18 @@ rotate_planet_task (void *data)
if (*(volatile UBYTE *)&pSS->PauseRotate == 2)
pSS->PauseRotate = 1;
// go to the next frame
Orbit->PlanetFrameArray = SetAbsFrameIndex (
Orbit->PlanetFrameArray, altfi);
if (doThrob)
{
Orbit->ObjectFrame = SetAbsFrameIndex (
ShieldFrame, altfi);
}
oldContext = SetContext (SpaceContext);
DrawPlanetSphere (SIS_SCREEN_WIDTH / 2, PLANET_ORG_Y);
SetContext (oldContext);
repair = RotatePlanet (x, SIS_SCREEN_WIDTH >> 1,
(148 - SIS_ORG_Y) >> 1, zoom_amt, zoom_from, repair);
if (!repair && zooming)
{
zooming = FALSE;
zoom_amt = 0;
++pSS->MenuState.Initialized;
PrepareNextRotationFrame ();
}
x += spin_dir;
}
else
view_index++;
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 + (ONE_SECOND * ROTATION_TIME) /
(MAP_WIDTH));
SleepThreadUntil (TimeIn + PLANET_ROTATION_RATE);
TimeIn = GetTimeCounter ();
} while (--view_index && !Task_ReadState (task, TASK_EXIT));
}
if (OldShieldFrame)
{
Orbit->ObjectFrame = OldShieldFrame;
DestroyDrawable (ReleaseDrawable (ShieldFrame));
}
FinishTask (task);