diff --git a/sc2/src/uqm/planets/lander.c b/sc2/src/uqm/planets/lander.c index e9937d88a..191432a40 100644 --- a/sc2/src/uqm/planets/lander.c +++ b/sc2/src/uqm/planets/lander.c @@ -50,14 +50,17 @@ LanderInputState *pLanderInputState; // Temporary, to replace the references to pMenuState. - // Eventually, this should become a parameter to everything which - // needs it. + // TODO: Many functions depend on pLanderInputState. In particular, + // the ELEMENT property functions. Fields in LanderInputState + // should either be made static vars, or ELEMENT should carry + // something like an 'intptr_t private' field FRAME LanderFrame[8]; static SOUND LanderSounds; MUSIC_REF LanderMusic; #define NUM_ORBIT_THEMES 5 static MUSIC_REF OrbitMusic[NUM_ORBIT_THEMES]; + const LIFEFORM_DESC CreatureData[] = { {SPEED_MOTIONLESS | DANGER_HARMLESS, MAKE_BYTE (1, 1)}, @@ -139,6 +142,7 @@ extern PRIM_LINKS DisplayLinks; #define LANDER_SPEED_DENOM 10 static BYTE lander_flags; +static POINT curLanderLoc; #define NUM_LANDING_DELTAS 11 #define ON_THE_GROUND -1 @@ -187,8 +191,8 @@ DamageColorCycle (COLOR c, COUNT i) return (c); } -#define MAGNIFICATION (1 << MAG_SHIFT) - +// XXX: This function used to erase a moving object by drawing a piece +// of surface over its previous location. Now it just moves the object static BOOLEAN RepairTopography (ELEMENT *ElementPtr) { @@ -339,14 +343,12 @@ object_animation (ELEMENT *ElementPtr) SIZE dx, dy; COUNT old_angle; - dx = pSolarSysState->MenuState.first_item.x - - ElementPtr->next.location.x; + dx = curLanderLoc.x - ElementPtr->next.location.x; if (dx < 0 && dx < -(MAP_WIDTH << (MAG_SHIFT - 1))) dx += MAP_WIDTH << MAG_SHIFT; else if (dx > (MAP_WIDTH << (MAG_SHIFT - 1))) dx -= MAP_WIDTH << MAG_SHIFT; - dy = pSolarSysState->MenuState.first_item.y - - ElementPtr->next.location.y; + dy = curLanderLoc.y - ElementPtr->next.location.y; angle = ARCTAN (dx, dy); if (dx < 0) dx = -dx; @@ -942,8 +944,7 @@ lightning_process (ELEMENT *ElementPtr) && !pPSD->InTransit) lander_flags |= KILL_CREW; - ElementPtr->next.location = - pSolarSysState->MenuState.first_item; + ElementPtr->next.location = curLanderLoc; } pPrim->Object.Stamp.frame = @@ -981,13 +982,11 @@ AddLightning (void) rand_val = TFB_Random (); LightningElementPtr->life_span = 10 + (HIWORD (rand_val) % 10) + 1; - LightningElementPtr->next.location.x = ( - pSolarSysState->MenuState.first_item.x + LightningElementPtr->next.location.x = (curLanderLoc.x + ((MAP_WIDTH << MAG_SHIFT) - ((SURFACE_WIDTH >> 1) - 6)) + (LOBYTE (rand_val) % (SURFACE_WIDTH - 12)) ) % (MAP_WIDTH << MAG_SHIFT); - LightningElementPtr->next.location.y = ( - pSolarSysState->MenuState.first_item.y + LightningElementPtr->next.location.y = (curLanderLoc.y + ((MAP_HEIGHT << MAG_SHIFT) - ((SURFACE_HEIGHT >> 1) - 6)) + (HIBYTE (rand_val) % (SURFACE_HEIGHT - 12)) ) % (MAP_HEIGHT << MAG_SHIFT); @@ -1029,13 +1028,11 @@ AddGroundDisaster (COUNT which_disaster) GroundDisasterElementPtr->preprocess_func = object_animation; rand_val = TFB_Random (); - GroundDisasterElementPtr->next.location.x = ( - pSolarSysState->MenuState.first_item.x + GroundDisasterElementPtr->next.location.x = (curLanderLoc.x + ((MAP_WIDTH << MAG_SHIFT) - (SURFACE_WIDTH * 3 / 8)) + (LOWORD (rand_val) % (SURFACE_WIDTH * 3 / 4)) ) % (MAP_WIDTH << MAG_SHIFT); - GroundDisasterElementPtr->next.location.y = ( - pSolarSysState->MenuState.first_item.y + GroundDisasterElementPtr->next.location.y = (curLanderLoc.y + ((MAP_HEIGHT << MAG_SHIFT) - (SURFACE_HEIGHT * 3 / 8)) + (HIWORD (rand_val) % (SURFACE_HEIGHT * 3 / 4)) ) % (MAP_HEIGHT << MAG_SHIFT); @@ -1067,6 +1064,10 @@ AddGroundDisaster (COUNT which_disaster) return (hGroundDisasterElement); } +// This function replaces the ELEMENT manipulations typically done by +// PreProcess() and PostProcess() in process.c. Lander code does not +// call RedrawQueue() & Co and thus does not reap the benefits (or curses, +// depending how you look at it) of automatic flags processing. static void BuildObjectList (void) { @@ -1094,7 +1095,7 @@ BuildObjectList (void) if (LOBYTE (LOWORD (rand_val)) < pPSD->WeatherChance) AddLightning (); - org = pSolarSysState->MenuState.first_item; + org = curLanderLoc; for (hElement = GetHeadElement (); hElement; hElement = hNextElement) { @@ -1109,8 +1110,10 @@ BuildObjectList (void) hNextElement = GetSuccElement (ElementPtr); UnlockElement (hElement); + // XXX: Hack: APPEARING flag is set by scan.c for scanned blips if (ElementPtr->state_flags & APPEARING) { + // XXX: Hack: defer deletion of the element ElementPtr->current.location.x |= 0x8000; ElementPtr->current.location.y |= 0x8000; } @@ -1130,9 +1133,7 @@ BuildObjectList (void) if (ElementPtr->preprocess_func) (*ElementPtr->preprocess_func) (ElementPtr); - GetNextVelocityComponents ( - &ElementPtr->velocity, &dx, &dy, 1 - ); + GetNextVelocityComponents (&ElementPtr->velocity, &dx, &dy, 1); if (dx || dy) { ElementPtr->next.location.x += dx; @@ -1145,8 +1146,11 @@ BuildObjectList (void) else if (ElementPtr->next.location.y >= (MAP_HEIGHT << MAG_SHIFT)) ElementPtr->next.location.y = (MAP_HEIGHT << MAG_SHIFT) - 1; } + // XXX: Hack: APPEARING flag is set by scan.c for scanned blips if (ElementPtr->state_flags & APPEARING) + { // XXX: Hack: remove the element from display ElementPtr->current.location.x |= 0x8000; + } if (ElementPtr->next.location.x < 0) ElementPtr->next.location.x += MAP_WIDTH << MAG_SHIFT; else @@ -1183,99 +1187,72 @@ BuildObjectList (void) } static void -RepairScan (void) +RepairScan (POINT newPlanetLoc) { - CONTEXT OldContext; HELEMENT hElement, hNextElement; - OldContext = SetContext (ScanContext); - for (hElement = GetHeadElement (); hElement; hElement = hNextElement) { ELEMENT *ElementPtr; + BOOLEAN remove = FALSE; LockElement (hElement, &ElementPtr); hNextElement = GetSuccElement (ElementPtr); if (ElementPtr->current.location.x & 0x8000) - { - BOOLEAN remove; - + { // XXX: element removed from display ElementPtr->current.location.x &= ~0x8000; if (ElementPtr->current.location.y & 0x8000) - { + { // XXX: deletion of this element was defered remove = TRUE; ElementPtr->current.location.y &= ~0x8000; } - else - remove = FALSE; + RepairTopography (ElementPtr); - if (remove) - { - UnlockElement (hElement); - RemoveElement (hElement); - FreeElement (hElement); - continue; - } } UnlockElement (hElement); + + if (remove) + { + RemoveElement (hElement); + FreeElement (hElement); + } } - BatchGraphics (); -#if 1 - DrawPlanet (0, 0, 0, 0); -#endif - DrawScannedObjects (TRUE); - drawPlanetCursor (pLanderInputState->scanInputState, FALSE); - UnbatchGraphics (); - - SetContext (OldContext); + RedrawSurfaceScan (&newPlanetLoc); } static void ScrollPlanetSide (SIZE dx, SIZE dy, int landingIndex) { - POINT old_pt, new_pt; + POINT new_pt; STAMP lander_s, shadow_s, shield_s; CONTEXT OldContext; - MENU_STATE *scanInputState = &pSolarSysState->MenuState; - // TODO: Make a new structure ScanInputState, like - // LanderInputState, instead of using MENU_STATE. - old_pt.x = scanInputState->first_item.x - (SURFACE_WIDTH >> 1); - old_pt.y = scanInputState->first_item.y - (SURFACE_HEIGHT >> 1); - - new_pt.y = old_pt.y + dy; - if (new_pt.y < -(SURFACE_HEIGHT >> 1)) + new_pt.y = curLanderLoc.y + dy; + if (new_pt.y < 0) { - new_pt.y = -(SURFACE_HEIGHT >> 1); - dy = new_pt.y - old_pt.y; + new_pt.y = 0; + dy = new_pt.y - curLanderLoc.y; dx = 0; ZeroVelocityComponents (&GLOBAL (velocity)); } - else if (new_pt.y > (MAP_HEIGHT << MAG_SHIFT) - (SURFACE_HEIGHT >> 1)) + else if (new_pt.y > (MAP_HEIGHT << MAG_SHIFT) - 1) { - new_pt.y = (MAP_HEIGHT << MAG_SHIFT) - (SURFACE_HEIGHT >> 1); - dy = new_pt.y - old_pt.y; + new_pt.y = (MAP_HEIGHT << MAG_SHIFT) - 1; + dy = new_pt.y - curLanderLoc.y; dx = 0; ZeroVelocityComponents (&GLOBAL (velocity)); } - new_pt.x = old_pt.x + dx; + new_pt.x = curLanderLoc.x + dx; if (new_pt.x < 0) new_pt.x += MAP_WIDTH << MAG_SHIFT; else if (new_pt.x >= MAP_WIDTH << MAG_SHIFT) new_pt.x -= MAP_WIDTH << MAG_SHIFT; - - new_pt.x = scanInputState->first_item.x + dx; - if (new_pt.x < 0) - new_pt.x += MAP_WIDTH << MAG_SHIFT; - else if (new_pt.x >= MAP_WIDTH << MAG_SHIFT) - new_pt.x -= MAP_WIDTH << MAG_SHIFT; - new_pt.y = scanInputState->first_item.y + dy; - - scanInputState->first_item = new_pt; + + curLanderLoc = new_pt; LockMutex (GraphicsLock); OldContext = SetContext (SpaceContext); @@ -1384,8 +1361,7 @@ ScrollPlanetSide (SIZE dx, SIZE dy, int landingIndex) } } - setPlanetCursorLoc (pLanderInputState->scanInputState, new_pt); - RepairScan (); + RepairScan (new_pt); if (lander_flags & KILL_CREW) DeltaLanderCrew (-1, LIGHTNING_DISASTER); @@ -1430,10 +1406,9 @@ AnimateLaunch (FRAME farray) } static void -InitPlanetSide (void) +InitPlanetSide (POINT pt) { SIZE num_crew; - POINT pt; STAMP s; CONTEXT OldContext; DWORD Time; @@ -1527,10 +1502,9 @@ InitPlanetSide (void) TaskSwitch (); LockMutex (GraphicsLock); #endif - // Adjust pSolarSysState->MenuState.first_item by a random jitter. -#define RANDOM_MISS 64 - pt = pSolarSysState->MenuState.first_item; + // Adjust landing location by a random jitter. +#define RANDOM_MISS 64 // Jitter the X landing point. pt.x -= RANDOM_MISS - (SIZE)(LOWORD (TFB_Random ()) % (RANDOM_MISS << 1)); if (pt.x < 0) @@ -1545,8 +1519,8 @@ InitPlanetSide (void) else if (pt.y >= (MAP_HEIGHT << MAG_SHIFT)) pt.y = (MAP_HEIGHT << MAG_SHIFT) - 1; - // Set the planet location - pSolarSysState->MenuState.first_item = pt; + curLanderLoc = pt; + SetContext (SpaceContext); SetContextFont (TinyFont); @@ -1594,7 +1568,8 @@ InitPlanetSide (void) } static void -LanderFire (LanderInputState *inputState, SIZE index) { +LanderFire (LanderInputState *inputState, SIZE index) +{ #define SHUTTLE_FIRE_WAIT 15 HELEMENT hWeaponElement; SIZE wdx, wdy; @@ -1610,8 +1585,7 @@ LanderFire (LanderInputState *inputState, SIZE index) { WeaponElementPtr->mass_points = 1; WeaponElementPtr->life_span = 12; WeaponElementPtr->state_flags = FINITE_LIFE; - WeaponElementPtr->next.location = - pSolarSysState->MenuState.first_item; + WeaponElementPtr->next.location = curLanderLoc; WeaponElementPtr->current.location.x = WeaponElementPtr->next.location.x >> MAG_SHIFT; WeaponElementPtr->current.location.y = @@ -1714,12 +1688,10 @@ landerSpeedNumer = WORLD_TO_VELOCITY (48); ExplosionElementPtr->playerNr = PS_HUMAN_PLAYER; ExplosionElementPtr->mass_points = DEATH_EXPLOSION; ExplosionElementPtr->state_flags = FINITE_LIFE; - ExplosionElementPtr->next.location = - pSolarSysState->MenuState.first_item; + ExplosionElementPtr->next.location = curLanderLoc; ExplosionElementPtr->preprocess_func = object_animation; ExplosionElementPtr->turn_wait = MAKE_BYTE (2, 2); - ExplosionElementPtr->life_span = - EXPLOSION_LIFE + ExplosionElementPtr->life_span = EXPLOSION_LIFE * (LONIBBLE (ExplosionElementPtr->turn_wait) + 1); SetPrimType (&DisplayArray[ExplosionElementPtr->PrimIndex], @@ -1883,9 +1855,7 @@ ReturnToOrbit (RECT *pRect) SetTransitionSource (pRect); BatchGraphics (); DrawStarBackGround (TRUE); - SetContext (ScanContext); - DrawPlanet (0, 0, 0, 0); - DrawScannedObjects (TRUE); + RedrawSurfaceScan (NULL); ScreenTransition (3, pRect); UnbatchGraphics (); @@ -1944,7 +1914,7 @@ LandingTakeoffSequence (LanderInputState *inputState, BOOLEAN landing) } void -PlanetSide (MENU_STATE *pMS) +PlanetSide (POINT planetLoc) { SIZE index; LanderInputState landerInputState; @@ -2011,16 +1981,18 @@ PlanetSide (MENU_STATE *pMS) BUILD_COLOR (MAKE_RGB15 (0x1F, 0x03, 0x00), 0x7F); landerInputState.planetSideDesc = &PSD; - // ScrollPlanetSide depends on this. Not just DoPlanetSide(). + // TODO: Many functions depend on pLanderInputState. In particular, + // the ELEMENT property functions. Fields in LanderInputState + // should either be made static vars, or ELEMENT should carry + // something like an 'intptr_t private' field pLanderInputState = &landerInputState; - landerInputState.scanInputState = pMS; index = NORMALIZE_FACING ((COUNT)TFB_Random ()); LanderFrame[0] = SetAbsFrameIndex (LanderFrame[0], index); landerInputState.delta_item = 0; pSolarSysState->MenuState.Initialized += 4; - InitPlanetSide (); + InitPlanetSide (planetLoc); landerInputState.NextTime = GetTimeCounter () + PLANET_SIDE_RATE; LandingTakeoffSequence (&landerInputState, TRUE); diff --git a/sc2/src/uqm/planets/lander.h b/sc2/src/uqm/planets/lander.h index d1fbc8355..6a3cc3c84 100644 --- a/sc2/src/uqm/planets/lander.h +++ b/sc2/src/uqm/planets/lander.h @@ -23,7 +23,7 @@ #include "libs/compiler.h" #include "libs/gfxlib.h" #include "libs/sndlib.h" -#include "../menustat.h" +#include "libs/timelib.h" #include "../element.h" @@ -66,7 +66,6 @@ struct LanderInputState { PLANETSIDE_DESC *planetSideDesc; SIZE Initialized; - MENU_STATE *scanInputState; TimeCount NextTime; // Frame rate control @@ -82,14 +81,19 @@ struct LanderInputState { extern LanderInputState *pLanderInputState; // Temporary, to replace the references to pMenuState. - // Eventually, this should become a parameter to everything which - // needs it. + // TODO: Many functions depend on pLanderInputState. In particular, + // the ELEMENT property functions. Fields in LanderInputState + // should either be made static vars, or ELEMENT should carry + // something like an 'intptr_t private' field + // TODO: Generation functions use pLanderInputState to locate + // the PLANETSIDE_DESC.InTransit. Make those instances into + // a function call instead. extern CONTEXT ScanContext; extern MUSIC_REF LanderMusic; -extern void PlanetSide (MENU_STATE *pMS); +extern void PlanetSide (POINT planetLoc); extern void DoDiscoveryReport (SOUND ReadOutSounds); extern void SetPlanetMusic (BYTE planet_type); extern void LoadLanderData (void); diff --git a/sc2/src/uqm/planets/scan.c b/sc2/src/uqm/planets/scan.c index 04c1ba486..b4205d27c 100644 --- a/sc2/src/uqm/planets/scan.c +++ b/sc2/src/uqm/planets/scan.c @@ -45,11 +45,12 @@ extern FRAME SpaceJunkFrame; #undef SPIN_ON_SCAN #define FLASH_INDEX 105 -#define FLASH_WIDTH 9 -#define FLASH_HEIGHT 9 +// TODO: this will become static once genchmmr.c declares its own CONTEXT CONTEXT ScanContext; +static POINT planetLoc; + void RepairBackRect (RECT *pRect) { @@ -537,7 +538,7 @@ restorePlanetLocationImage (MENU_STATE *pMS) DrawStamp (&s); } -void +static void drawPlanetCursor (MENU_STATE *pMS, BOOLEAN filled) { STAMP s; @@ -559,9 +560,9 @@ setPlanetCursorLoc (MENU_STATE *pMS, POINT new_pt) } static void -SetPlanetLoc (MENU_STATE *pMS, POINT new_pt) +setPlanetLoc (MENU_STATE *pMS, POINT new_pt) { - pSolarSysState->MenuState.first_item = new_pt; + planetLoc = new_pt; // Set the new flash location setPlanetCursorLoc (pMS, new_pt); @@ -613,6 +614,27 @@ flashPlanetLocation (MENU_STATE *pMS) drawPlanetCursor (pMS, TRUE); } +void +RedrawSurfaceScan (const POINT *newLoc) +{ + CONTEXT OldContext; + + OldContext = SetContext (ScanContext); + + BatchGraphics (); + DrawPlanet (0, 0, 0, 0); + DrawScannedObjects (TRUE); + if (newLoc) + { + // TODO: Give scan its own STATE struct and pScanState (if needed) + setPlanetLoc (pMenuState, *newLoc); + drawPlanetCursor (pMenuState, FALSE); + } + UnbatchGraphics (); + + SetContext (OldContext); +} + static BOOLEAN DoScan (MENU_STATE *pMS); static BOOLEAN @@ -640,7 +662,7 @@ PickPlanetSide (MENU_STATE *pMS) LockMutex (GraphicsLock); SetContext (ScanContext); // Set the current flash location - setPlanetCursorLoc (pMS, pSolarSysState->MenuState.first_item); + setPlanetCursorLoc (pMS, planetLoc); savePlanetLocationImage (pMS); SetFlashRect (NULL); @@ -662,7 +684,7 @@ PickPlanetSide (MENU_STATE *pMS) if (!select) { // Bailing out LockMutex (GraphicsLock); - SetPlanetLoc (pMS, pSolarSysState->MenuState.first_item); + restorePlanetLocationImage (pMS); UnlockMutex (GraphicsLock); } else @@ -682,7 +704,7 @@ PickPlanetSide (MENU_STATE *pMS) drawPlanetCursor (pMS, FALSE); UnlockMutex (GraphicsLock); - PlanetSide (pMS); + PlanetSide (planetLoc); if (GLOBAL (CurrentActivity) & CHECK_ABORT) goto ExitPlanetSide; @@ -741,7 +763,7 @@ ExitPlanetSide: SIZE dy = 0; POINT new_pt; - new_pt = pSolarSysState->MenuState.first_item; + new_pt = planetLoc; if (PulsedInputState.menu[KEY_MENU_LEFT]) dx = -1; @@ -769,13 +791,13 @@ ExitPlanetSide: { new_pt.y += dy; if (new_pt.y < 0 || new_pt.y >= (MAP_HEIGHT << MAG_SHIFT)) - new_pt.y = pSolarSysState->MenuState.first_item.y; + new_pt.y = planetLoc.y; } - if (new_pt.x != pSolarSysState->MenuState.first_item.x - || new_pt.y != pSolarSysState->MenuState.first_item.y) + if (new_pt.x != planetLoc.x + || new_pt.y != planetLoc.y) { - SetPlanetLoc (pMS, new_pt); + setPlanetLoc (pMS, new_pt); } flashPlanetLocation (pMS); @@ -816,6 +838,7 @@ DrawScannedStuff (COUNT y, BYTE CurState) //DWORD Time; STAMP s; + // XXX: Hack: flag this as surface scan element ElementPtr->state_flags |= APPEARING; s.origin = ElementPtr->current.location; @@ -1152,15 +1175,13 @@ ScanSystem (void) GAS_GIANT_ATMOSPHERE)) { MenuState.CurState = EXIT_SCAN; - ScanContext = 0; + ScanContext = NULL; } else { MenuState.CurState = AUTO_SCAN; - pSolarSysState->MenuState.first_item.x = - (MAP_WIDTH >> 1) << MAG_SHIFT; - pSolarSysState->MenuState.first_item.y = - (MAP_HEIGHT >> 1) << MAG_SHIFT; + planetLoc.x = (MAP_WIDTH >> 1) << MAG_SHIFT; + planetLoc.y = (MAP_HEIGHT >> 1) << MAG_SHIFT; LockMutex (GraphicsLock); ScanContext = CreateContext ("ScanContext"); @@ -1196,7 +1217,7 @@ ScanSystem (void) SetContext (SpaceContext); DestroyDrawable (ReleaseDrawable (MenuState.flash_frame1)); DestroyContext (ScanContext); - ScanContext = 0; + ScanContext = NULL; UnlockMutex (GraphicsLock); } } diff --git a/sc2/src/uqm/planets/scan.h b/sc2/src/uqm/planets/scan.h index a4eec0a10..4880b979f 100644 --- a/sc2/src/uqm/planets/scan.h +++ b/sc2/src/uqm/planets/scan.h @@ -46,8 +46,7 @@ typedef struct extern void RepairBackRect (RECT *pRect); extern void GeneratePlanetSide (void); -extern void drawPlanetCursor (MENU_STATE *pMS, BOOLEAN filled); -extern void setPlanetCursorLoc (MENU_STATE *pMS, POINT new_pt); +extern void RedrawSurfaceScan (const POINT *newLoc); #endif /* _SCAN_H */