diff options
Diffstat (limited to 'src/uqm/globdata.c')
-rw-r--r-- | src/uqm/globdata.c | 511 |
1 files changed, 511 insertions, 0 deletions
diff --git a/src/uqm/globdata.c b/src/uqm/globdata.c new file mode 100644 index 0000000..ff9edc2 --- /dev/null +++ b/src/uqm/globdata.c @@ -0,0 +1,511 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "globdata.h" + +#include "coderes.h" +#include "encount.h" +#include "starmap.h" +#include "master.h" +#include "setup.h" +#include "units.h" +#include "hyper.h" +#include "resinst.h" +#include "nameref.h" +#include "build.h" +#include "state.h" +#include "grpinfo.h" +#include "gamestr.h" + +#include <assert.h> +#include <stdlib.h> +#ifdef STATE_DEBUG +# include "libs/log.h" +#endif + + +static void CreateRadar (void); + +CONTEXT RadarContext; +FRAME PlayFrame; + +GLOBDATA GlobData; + + +BYTE +getGameState (BYTE *state, int startBit, int endBit) +{ + return (BYTE) (((startBit >> 3) == (endBit >> 3) + ? (state[startBit >> 3] >> (startBit & 7)) + : ((state[startBit >> 3] >> (startBit & 7)) + | (state[endBit >> 3] + << (endBit - startBit - (endBit & 7))))) + & ((1 << (endBit - startBit + 1)) - 1)); +} + +void +setGameState (BYTE *state, int startBit, int endBit, BYTE val +#ifdef STATE_DEBUG + , const char *name +#endif +) +{ + state[startBit >> 3] = + (state[startBit >> 3] + & (BYTE) ~(((1 << (endBit - startBit + 1)) - 1) << (startBit & 7))) + | (BYTE)((val) << (startBit & 7)); + + if ((startBit >> 3) < (endBit >> 3)) { + state[endBit >> 3] = + (state[endBit >> 3] + & (BYTE)~((1 << ((endBit & 7) + 1)) - 1)) + | (BYTE)((val) >> (endBit - startBit - (endBit & 7))); + } +#ifdef STATE_DEBUG + log_add (log_Debug, "State '%s' set to %d.", name, (int)val); +#endif +} + +DWORD +getGameState32 (BYTE *state, int startBit) +{ + DWORD v; + int shift; + + for (v = 0, shift = 0; shift < 32; shift += 8, startBit += 8) + { + v |= getGameState (state, startBit, startBit + 7) << shift; + } + + return v; +} + +void +setGameState32 (BYTE *state, int startBit, DWORD val +#ifdef STATE_DEBUG + , const char *name +#endif +) +{ + DWORD v = val; + int i; + + for (i = 0; i < 4; ++i, v >>= 8, startBit += 8) + { + setGameState (state, startBit, startBit + 7, v & 0xff +#ifdef STATE_DEBUG + , "(ignored)" +#endif + ); + } + +#ifdef STATE_DEBUG + log_add (log_Debug, "State '%s' set to %u.", name, (unsigned)val); +#endif +} + +void +copyGameState (BYTE *dest, DWORD target, BYTE *src, DWORD begin, DWORD end) +{ + while (begin < end) + { + BYTE b; + DWORD delta = 7; + if (begin + delta > end) + delta = end - begin; + b = getGameState (src, begin, begin + delta); + setGameState (dest, target, target + delta, b); + begin += 8; + target += 8; + } +} + +static void +CreateRadar (void) +{ + if (RadarContext == 0) + { + RECT r; + CONTEXT OldContext; + + RadarContext = CreateContext ("RadarContext"); + OldContext = SetContext (RadarContext); + SetContextFGFrame (Screen); + r.corner.x = RADAR_X; + r.corner.y = RADAR_Y; + r.extent.width = RADAR_WIDTH; + r.extent.height = RADAR_HEIGHT; + SetContextClipRect (&r); + SetContext (OldContext); + } +} + +BOOLEAN +LoadSC2Data (void) +{ + if (FlagStatFrame == 0) + { + FlagStatFrame = CaptureDrawable ( + LoadGraphic (FLAGSTAT_MASK_PMAP_ANIM)); + if (FlagStatFrame == NULL) + return FALSE; + + MiscDataFrame = CaptureDrawable ( + LoadGraphic (MISCDATA_MASK_PMAP_ANIM)); + if (MiscDataFrame == NULL) + return FALSE; + + FontGradFrame = CaptureDrawable ( + LoadGraphic (FONTGRAD_PMAP_ANIM)); + } + + CreateRadar (); + + if (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) + { + GLOBAL (ShipStamp.origin.x) = + GLOBAL (ShipStamp.origin.y) = -1; + } + + return TRUE; +} + +static void +copyFleetInfo (FLEET_INFO *dst, SHIP_INFO *src, FLEET_STUFF *fleet) +{ + // other leading fields are irrelevant + dst->crew_level = src->crew_level; + dst->max_crew = src->max_crew; + dst->max_energy = src->max_energy; + + dst->race_strings = src->race_strings; + dst->icons = src->icons; + dst->melee_icon = src->melee_icon; + + dst->actual_strength = fleet->strength; + dst->known_loc = fleet->known_loc; +} + +BOOLEAN +InitGameStructures (void) +{ + COUNT i; + + InitGlobData (); + + PlayFrame = CaptureDrawable (LoadGraphic (PLAYMENU_ANIM)); + + { + COUNT num_ships; + SPECIES_ID s_id = ARILOU_ID; + + num_ships = KOHR_AH_ID - s_id + 1 + + 2; /* Yehat Rebels and Ur-Quan probe */ + + InitQueue (&GLOBAL (avail_race_q), num_ships, sizeof (FLEET_INFO)); + for (i = 0; i < num_ships; ++i) + { + SPECIES_ID ship_ref; + HFLEETINFO hFleet; + FLEET_INFO *FleetPtr; + + if (i < num_ships - 2) + ship_ref = s_id++; + else if (i == num_ships - 2) + ship_ref = YEHAT_ID; + else /* (i == num_ships - 1) */ + ship_ref = UR_QUAN_PROBE_ID; + + hFleet = AllocLink (&GLOBAL (avail_race_q)); + if (!hFleet) + continue; + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hFleet); + FleetPtr->SpeciesID = ship_ref; + + if (i < num_ships - 1) + { + HMASTERSHIP hMasterShip; + MASTER_SHIP_INFO *MasterPtr; + + hMasterShip = FindMasterShip (ship_ref); + MasterPtr = LockMasterShip (&master_q, hMasterShip); + // Grab a copy of loaded icons and strings (not owned) + copyFleetInfo (FleetPtr, &MasterPtr->ShipInfo, + &MasterPtr->Fleet); + UnlockMasterShip (&master_q, hMasterShip); + } + else + { + // Ur-Quan probe. + RACE_DESC *RDPtr = load_ship (FleetPtr->SpeciesID, + FALSE); + if (RDPtr) + { // Grab a copy of loaded icons and strings + copyFleetInfo (FleetPtr, &RDPtr->ship_info, + &RDPtr->fleet); + // avail_race_q owns these resources now + free_ship (RDPtr, FALSE, FALSE); + } + } + + FleetPtr->allied_state = BAD_GUY; + FleetPtr->known_strength = 0; + FleetPtr->loc = FleetPtr->known_loc; + // XXX: Hack: Rebel special case + if (i == YEHAT_REBEL_SHIP) + FleetPtr->actual_strength = 0; + FleetPtr->growth = 0; + FleetPtr->growth_fract = 0; + FleetPtr->growth_err_term = 255 >> 1; + FleetPtr->days_left = 0; + FleetPtr->func_index = ~0; + + UnlockFleetInfo (&GLOBAL (avail_race_q), hFleet); + PutQueue (&GLOBAL (avail_race_q), hFleet); + } + } + + InitSISContexts (); + LoadSC2Data (); + + InitPlanetInfo (); + InitGroupInfo (TRUE); + + GLOBAL (glob_flags) = 0; + + GLOBAL (ElementWorth[COMMON]) = 1; + GLOBAL_SIS (ElementAmounts[COMMON]) = 0; + GLOBAL (ElementWorth[CORROSIVE]) = 2; + GLOBAL_SIS (ElementAmounts[CORROSIVE]) = 0; + GLOBAL (ElementWorth[BASE_METAL]) = 3; + GLOBAL_SIS (ElementAmounts[BASE_METAL]) = 0; + GLOBAL (ElementWorth[NOBLE]) = 4; + GLOBAL_SIS (ElementAmounts[NOBLE]) = 0; + GLOBAL (ElementWorth[RARE_EARTH]) = 5; + GLOBAL_SIS (ElementAmounts[RARE_EARTH]) = 0; + GLOBAL (ElementWorth[PRECIOUS]) = 6; + GLOBAL_SIS (ElementAmounts[PRECIOUS]) = 0; + GLOBAL (ElementWorth[RADIOACTIVE]) = 8; + GLOBAL_SIS (ElementAmounts[RADIOACTIVE]) = 0; + GLOBAL (ElementWorth[EXOTIC]) = 25; + GLOBAL_SIS (ElementAmounts[EXOTIC]) = 0; + + for (i = 0; i < NUM_DRIVE_SLOTS; ++i) + GLOBAL_SIS (DriveSlots[i]) = EMPTY_SLOT + 0; + GLOBAL_SIS (DriveSlots[5]) = + GLOBAL_SIS (DriveSlots[6]) = FUSION_THRUSTER; + for (i = 0; i < NUM_JET_SLOTS; ++i) + GLOBAL_SIS (JetSlots[i]) = EMPTY_SLOT + 1; + GLOBAL_SIS (JetSlots[0]) = + GLOBAL_SIS (JetSlots[6]) = TURNING_JETS; + for (i = 0; i < NUM_MODULE_SLOTS; ++i) + GLOBAL_SIS (ModuleSlots[i]) = EMPTY_SLOT + 2; + GLOBAL_SIS (ModuleSlots[15]) = GUN_WEAPON; + GLOBAL_SIS (ModuleSlots[2]) = CREW_POD; + GLOBAL_SIS (CrewEnlisted) = CREW_POD_CAPACITY; + GLOBAL_SIS (ModuleSlots[8]) = STORAGE_BAY; + GLOBAL_SIS (ModuleSlots[1]) = FUEL_TANK; + GLOBAL_SIS (FuelOnBoard) = 10 * FUEL_TANK_SCALE; + + InitQueue (&GLOBAL (built_ship_q), + MAX_BUILT_SHIPS, sizeof (SHIP_FRAGMENT)); + InitQueue (&GLOBAL (npc_built_ship_q), MAX_SHIPS_PER_SIDE, + sizeof (SHIP_FRAGMENT)); + InitQueue (&GLOBAL (ip_group_q), MAX_BATTLE_GROUPS, + sizeof (IP_GROUP)); + InitQueue (&GLOBAL (encounter_q), MAX_ENCOUNTERS, sizeof (ENCOUNTER)); + + GLOBAL (CurrentActivity) = IN_INTERPLANETARY | START_INTERPLANETARY; + + GLOBAL_SIS (ResUnits) = 0; + GLOBAL (CrewCost) = 3; + GLOBAL (FuelCost) = 20; + GLOBAL (ModuleCost[PLANET_LANDER]) = 500 / MODULE_COST_SCALE; + GLOBAL (ModuleCost[FUSION_THRUSTER]) = 500 / MODULE_COST_SCALE; + GLOBAL (ModuleCost[TURNING_JETS]) = 500 / MODULE_COST_SCALE; + GLOBAL (ModuleCost[CREW_POD]) = 2000 / MODULE_COST_SCALE; + GLOBAL (ModuleCost[STORAGE_BAY]) = 750 / MODULE_COST_SCALE; + GLOBAL (ModuleCost[FUEL_TANK]) = 500 / MODULE_COST_SCALE; + GLOBAL (ModuleCost[DYNAMO_UNIT]) = 2000 / MODULE_COST_SCALE; + GLOBAL (ModuleCost[GUN_WEAPON]) = 2000 / MODULE_COST_SCALE; + + GLOBAL_SIS (NumLanders) = 1; + + utf8StringCopy (GLOBAL_SIS (ShipName), sizeof (GLOBAL_SIS (ShipName)), + GAME_STRING (NAMING_STRING_BASE + 2)); + utf8StringCopy (GLOBAL_SIS (CommanderName), + sizeof (GLOBAL_SIS (CommanderName)), + GAME_STRING (NAMING_STRING_BASE + 3)); + + SetRaceAllied (HUMAN_SHIP, TRUE); + CloneShipFragment (HUMAN_SHIP, &GLOBAL (built_ship_q), 0); + + GLOBAL_SIS (log_x) = UNIVERSE_TO_LOGX (SOL_X); + GLOBAL_SIS (log_y) = UNIVERSE_TO_LOGY (SOL_Y); + CurStarDescPtr = 0; + GLOBAL (autopilot.x) = ~0; + GLOBAL (autopilot.y) = ~0; + + return (TRUE); +} + +void +FreeSC2Data (void) +{ + DestroyContext (RadarContext); + RadarContext = 0; + DestroyDrawable (ReleaseDrawable (FontGradFrame)); + FontGradFrame = 0; + DestroyDrawable (ReleaseDrawable (MiscDataFrame)); + MiscDataFrame = 0; + DestroyDrawable (ReleaseDrawable (FlagStatFrame)); + FlagStatFrame = 0; +} + +void +UninitGameStructures (void) +{ + HFLEETINFO hStarShip; + + UninitQueue (&GLOBAL (encounter_q)); + UninitQueue (&GLOBAL (ip_group_q)); + UninitQueue (&GLOBAL (npc_built_ship_q)); + UninitQueue (&GLOBAL (built_ship_q)); + UninitGroupInfo (); + UninitPlanetInfo (); + +// FreeSC2Data (); + + // The only resources avail_race_q owns are the Ur-Quan probe's + // so free them now + hStarShip = GetTailLink (&GLOBAL (avail_race_q)); + if (hStarShip) + { + FLEET_INFO *FleetPtr; + + FleetPtr = LockFleetInfo (&GLOBAL (avail_race_q), hStarShip); + DestroyDrawable (ReleaseDrawable (FleetPtr->melee_icon)); + DestroyDrawable (ReleaseDrawable (FleetPtr->icons)); + DestroyStringTable (ReleaseStringTable (FleetPtr->race_strings)); + UnlockFleetInfo (&GLOBAL (avail_race_q), hStarShip); + } + + UninitQueue (&GLOBAL (avail_race_q)); + + DestroyDrawable (ReleaseDrawable (PlayFrame)); + PlayFrame = 0; +} + +void +InitGlobData (void) +{ + COUNT i; + + i = GLOBAL (glob_flags); + memset (&GlobData, 0, sizeof (GlobData)); + GLOBAL (glob_flags) = (BYTE)i; + + GLOBAL (DisplayArray) = DisplayArray; +} + + +BOOLEAN +inFullGame (void) +{ + ACTIVITY act = LOBYTE (GLOBAL (CurrentActivity)); + return (act == IN_LAST_BATTLE || act == IN_ENCOUNTER || + act == IN_HYPERSPACE || act == IN_INTERPLANETARY || + act == WON_LAST_BATTLE); +} + +BOOLEAN +inSuperMelee (void) +{ + return (LOBYTE (GLOBAL (CurrentActivity)) == SUPER_MELEE); + // TODO: && !inMainMenu () +} + +#if 0 +BOOLEAN +inBattle (void) +{ + // TODO: IN_BATTLE is also set while in HyperSpace/QuasiSpace. + return ((GLOBAL (CurrentActivity) & IN_BATTLE) != 0); +} +#endif + +#if 0 +// Disabled for now as there are similar functions in uqm/planets/planets.h +// Pre: inFullGame() +BOOLEAN +inInterPlanetary (void) +{ + assert (inFullGame ()); + return (pSolarSysState != NULL); +} + +// Pre: inFullGame() +BOOLEAN +inSolarSystem (void) +{ + assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_INTERPLANETARY); +} + +// Pre: inFullGame() +BOOLEAN +inOrbit (void) +{ + assert (inFullGame ()); + return (pSolarSysState != NULL) && + (pSolarSysState->pOrbitalDesc != NULL); +} +#endif + +// In HyperSpace or QuasiSpace +// Pre: inFullGame() +BOOLEAN +inHQSpace (void) +{ + //assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE); + // IN_HYPERSPACE is also set for QuasiSpace +} + +// In HyperSpace +// Pre: inFullGame() +BOOLEAN +inHyperSpace (void) +{ + //assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) && + (GET_GAME_STATE (ARILOU_SPACE_SIDE) <= 1); + // IN_HYPERSPACE is also set for QuasiSpace +} + +// In QuasiSpace +// Pre: inFullGame() +BOOLEAN +inQuasiSpace (void) +{ + //assert (inFullGame ()); + return (LOBYTE (GLOBAL (CurrentActivity)) == IN_HYPERSPACE) && + (GET_GAME_STATE (ARILOU_SPACE_SIDE) > 1); + // IN_HYPERSPACE is also set for QuasiSpace +} + |