void free_ship (RACE_DESC *raceDescPtr, BOOLEAN FreeIconData, BOOLEAN FreeBattleData) { if (raceDescPtr->uninit_func != NULL) (*raceDescPtr->uninit_func) (raceDescPtr); if (FreeBattleData) { DATA_STUFF *shipData = &raceDescPtr->ship_data; free_image (shipData->special); free_image (shipData->weapon); free_image (shipData->ship); DestroyDrawable ( ReleaseDrawable (shipData->captain_control.background)); DestroyMusic (shipData->victory_ditty); DestroySound (ReleaseSound (shipData->ship_sounds)); } if (FreeIconData) { SHIP_INFO *shipInfo = &raceDescPtr->ship_info; DestroyDrawable (ReleaseDrawable (shipInfo->melee_icon)); DestroyDrawable (ReleaseDrawable (shipInfo->icons)); DestroyStringTable (ReleaseStringTable (shipInfo->race_strings)); } DestroyCodeRes (ReleaseCodeRes (raceDescPtr->CodeRef)); }
static bool GenerateAndrosynth_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 1, MATCH_PLANET)) { COUNT i; COUNT visits = 0; LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); solarSys->PlanetSideFrame[1] = CaptureDrawable (LoadGraphic (RUINS_MASK_PMAP_ANIM)); solarSys->SysInfo.PlanetInfo.DiscoveryString = CaptureStringTable ( LoadStringTable (ANDROSYNTH_RUINS_STRTAB)); // Androsynth ruins are a special case. The DiscoveryString contains // several lander reports which form a story. Each report is given // when the player collides with a new city ruin. Ruins previously // visited are marked in the upper 16 bits of ScanRetrieveMask, and // the lower bits are cleared to keep the ruin nodes on the map. for (i = 16; i < 32; ++i) { if (isNodeRetrieved (&solarSys->SysInfo.PlanetInfo, ENERGY_SCAN, i)) ++visits; } if (visits >= GetStringTableCount ( solarSys->SysInfo.PlanetInfo.DiscoveryString)) { // All the reports were already given DestroyStringTable (ReleaseStringTable ( solarSys->SysInfo.PlanetInfo.DiscoveryString)); solarSys->SysInfo.PlanetInfo.DiscoveryString = 0; } else { // Advance the report sequence to the first unread solarSys->SysInfo.PlanetInfo.DiscoveryString = SetRelStringTableIndex ( solarSys->SysInfo.PlanetInfo.DiscoveryString, visits); } } GenerateDefault_generateOrbital (solarSys, world); if (matchWorld (solarSys, world, 1, MATCH_PLANET)) { solarSys->SysInfo.PlanetInfo.AtmoDensity = EARTH_ATMOSPHERE * 144 / 100; solarSys->SysInfo.PlanetInfo.SurfaceTemperature = 28; solarSys->SysInfo.PlanetInfo.Weather = 1; solarSys->SysInfo.PlanetInfo.Tectonics = 1; } return true; }
static void UninitKernel (BOOLEAN ships) { UninitSpace (); DestroySound (ReleaseSound (MenuSounds)); DestroyFont (MicroFont); DestroyStringTable (ReleaseStringTable (GameStrings)); DestroyDrawable (ReleaseDrawable (StatusFrame)); DestroyDrawable (ReleaseDrawable (ActivityFrame)); DestroyFont (TinyFont); DestroyFont (StarConFont); UninitQueue (&race_q[0]); UninitQueue (&race_q[1]); if (ships) FreeMasterShipList (); ActivityFrame = 0; }
void FreePlanet (void) { COUNT i, j; PLANET_ORBIT *Orbit = &pSolarSysState->Orbit; UninitSphereRotation (); StopMusic (); LockMutex (GraphicsLock); for (i = 0; i < sizeof (pSolarSysState->PlanetSideFrame) / sizeof (pSolarSysState->PlanetSideFrame[0]); ++i) { DestroyDrawable (ReleaseDrawable (pSolarSysState->PlanetSideFrame[i])); pSolarSysState->PlanetSideFrame[i] = 0; } // FreeLanderData (); DestroyStringTable (ReleaseStringTable (pSolarSysState->XlatRef)); pSolarSysState->XlatRef = 0; DestroyDrawable (ReleaseDrawable (pSolarSysState->TopoFrame)); pSolarSysState->TopoFrame = 0; DestroyColorMap (ReleaseColorMap (pSolarSysState->OrbitalCMap)); pSolarSysState->OrbitalCMap = 0; HFree (Orbit->lpTopoData); Orbit->lpTopoData = 0; DestroyDrawable (ReleaseDrawable (Orbit->TopoZoomFrame)); Orbit->TopoZoomFrame = 0; DestroyDrawable (ReleaseDrawable (Orbit->SphereFrame)); Orbit->SphereFrame = NULL; DestroyDrawable (ReleaseDrawable (Orbit->TintFrame)); Orbit->TintFrame = 0; Orbit->TintColor = BLACK_COLOR; DestroyDrawable (ReleaseDrawable (Orbit->ObjectFrame)); Orbit->ObjectFrame = 0; DestroyDrawable (ReleaseDrawable (Orbit->WorkFrame)); Orbit->WorkFrame = 0; HFree (Orbit->TopoColors); Orbit->TopoColors = NULL; HFree (Orbit->ScratchArray); Orbit->ScratchArray = NULL; if (Orbit->map_rotate && Orbit->light_diff) { for (j=0 ; j < MAP_HEIGHT+1 ; j++) { HFree (Orbit->map_rotate[j]); HFree (Orbit->light_diff[j]); } } HFree (Orbit->map_rotate); Orbit->map_rotate = NULL; HFree (Orbit->light_diff); Orbit->light_diff = NULL; DestroyStringTable (ReleaseStringTable ( pSolarSysState->SysInfo.PlanetInfo.DiscoveryString )); pSolarSysState->SysInfo.PlanetInfo.DiscoveryString = 0; FreeLanderFont (&pSolarSysState->SysInfo.PlanetInfo); // Need to make sure our own CONTEXTs are not active because // we will destroy them now SetContext (SpaceContext); DestroyPlanetContext (); DestroyScanContext (); UnlockMutex (GraphicsLock); }
static bool GenerateChmmr_generateOrbital (SOLARSYS_STATE *solarSys, PLANET_DESC *world) { if (matchWorld (solarSys, world, 1, MATCH_PLANET)) { if (GET_GAME_STATE (CHMMR_UNLEASHED)) { SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 7); InitCommunication (CHMMR_CONVERSATION); if (GET_GAME_STATE (CHMMR_BOMB_STATE) == 2) { GLOBAL (CurrentActivity) |= END_INTERPLANETARY; } return true; } else if (GET_GAME_STATE (SUN_DEVICE_ON_SHIP) && !GET_GAME_STATE (ILWRATH_DECEIVED) && ActivateStarShip (ILWRATH_SHIP, SPHERE_TRACKING)) { PutGroupInfo (GROUPS_RANDOM, GROUP_SAVE_IP); ReinitQueue (&GLOBAL (ip_group_q)); assert (CountLinks (&GLOBAL (npc_built_ship_q)) == 0); CloneShipFragment (ILWRATH_SHIP, &GLOBAL (npc_built_ship_q), INFINITE_FLEET); SET_GAME_STATE (GLOBAL_FLAGS_AND_DATA, 1 << 6); GLOBAL (CurrentActivity) |= START_INTERPLANETARY; InitCommunication (ILWRATH_CONVERSATION); if (!(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD))) { GLOBAL (CurrentActivity) &= ~START_INTERPLANETARY; ReinitQueue (&GLOBAL (npc_built_ship_q)); GetGroupInfo (GROUPS_RANDOM, GROUP_LOAD_IP); } return true; } } else if (matchWorld (solarSys, world, 1, 0)) { /* Starbase */ LockMutex (GraphicsLock); LoadStdLanderFont (&solarSys->SysInfo.PlanetInfo); solarSys->SysInfo.PlanetInfo.DiscoveryString = CaptureStringTable (LoadStringTable (CHMMR_BASE_STRTAB)); DoDiscoveryReport (MenuSounds); DestroyStringTable (ReleaseStringTable ( solarSys->SysInfo.PlanetInfo.DiscoveryString)); solarSys->SysInfo.PlanetInfo.DiscoveryString = 0; FreeLanderFont (&solarSys->SysInfo.PlanetInfo); UnlockMutex (GraphicsLock); return true; } GenerateDefault_generateOrbital (solarSys, world); return true; }
BOOLEAN DoTextEntry (PTEXTENTRY_STATE pTES) { wchar_t ch; UNICODE *pStr; UNICODE *CacheInsPt; int CacheCursorPos; int len; BOOLEAN changed = FALSE; if (GLOBAL (CurrentActivity) & CHECK_ABORT) return (FALSE); if (!pTES->Initialized) { // init basic vars int lwlen; pTES->InputFunc = DoTextEntry; pTES->Success = FALSE; pTES->Initialized = TRUE; pTES->JoystickMode = FALSE; pTES->UpperRegister = TRUE; // init insertion point if ((size_t)pTES->CursorPos > utf8StringCount (pTES->BaseStr)) pTES->CursorPos = utf8StringCount (pTES->BaseStr); pTES->InsPt = skipUTF8Chars (pTES->BaseStr, pTES->CursorPos); // load joystick alphabet pTES->JoyAlphaString = CaptureStringTable ( LoadStringTable (JOYSTICK_ALPHA_STRTAB)); pTES->JoyAlpha = LoadJoystickAlpha ( SetAbsStringTableIndex (pTES->JoyAlphaString, 0), &pTES->JoyAlphaLength); pTES->JoyUpper = LoadJoystickAlpha ( SetAbsStringTableIndex (pTES->JoyAlphaString, 1), &pTES->JoyRegLength); pTES->JoyLower = LoadJoystickAlpha ( SetAbsStringTableIndex (pTES->JoyAlphaString, 2), &lwlen); if (lwlen != pTES->JoyRegLength) { if (lwlen < pTES->JoyRegLength) pTES->JoyRegLength = lwlen; log_add (log_Warning, "Warning: Joystick upper-lower registers" " size mismatch; using the smallest subset (%d)", pTES->JoyRegLength); } pTES->CacheStr = HMalloc (pTES->MaxSize * sizeof (*pTES->CacheStr)); DoInput (pTES, TRUE); if (pTES->CacheStr) HFree (pTES->CacheStr); if (pTES->JoyLower) HFree (pTES->JoyLower); if (pTES->JoyUpper) HFree (pTES->JoyUpper); if (pTES->JoyAlpha) HFree (pTES->JoyAlpha); DestroyStringTable ( ReleaseStringTable (pTES->JoyAlphaString)); return pTES->Success; } pStr = pTES->InsPt; len = strlen (pStr); // save a copy of string CacheInsPt = pTES->InsPt; CacheCursorPos = pTES->CursorPos; memcpy (pTES->CacheStr, pTES->BaseStr, pTES->MaxSize); // process the pending character buffer ch = GetNextCharacter (); if (!ch && PulsedInputState.menu[KEY_MENU_ANY]) { // keyboard repeat, but only when buffer empty ch = GetLastCharacter (); } while (ch) { UNICODE chbuf[8]; int chsize; pTES->JoystickMode = FALSE; chsize = getStringFromChar (chbuf, sizeof (chbuf), ch); if (isWidePrintChar (ch) && chsize > 0) { if (pStr + len - pTES->BaseStr + chsize < pTES->MaxSize) { // insert character, when fits memmove (pStr + chsize, pStr, len + 1); memcpy (pStr, chbuf, chsize); pStr += chsize; ++pTES->CursorPos; changed = TRUE; } else { // does not fit PlayMenuSound (MENU_SOUND_FAILURE); } } ch = GetNextCharacter (); } if (PulsedInputState.menu[KEY_MENU_DELETE]) { if (len) { joy_char_t ch; ReadOneChar (&ch, pStr); memmove (pStr, pStr + ch.len, len - ch.len + 1); len -= ch.len; changed = TRUE; } } else if (PulsedInputState.menu[KEY_MENU_BACKSPACE]) { if (pStr > pTES->BaseStr) { UNICODE *prev = skipUTF8Chars (pTES->BaseStr, pTES->CursorPos - 1); memmove (prev, pStr, len + 1); pStr = prev; --pTES->CursorPos; changed = TRUE; } } else if (PulsedInputState.menu[KEY_MENU_LEFT]) { if (pStr > pTES->BaseStr) { UNICODE *prev = skipUTF8Chars (pTES->BaseStr, pTES->CursorPos - 1); pStr = prev; len += (prev - pStr); --pTES->CursorPos; changed = TRUE; } } else if (PulsedInputState.menu[KEY_MENU_RIGHT]) { if (len > 0) { joy_char_t ch; ReadOneChar (&ch, pStr); pStr += ch.len; len -= ch.len; ++pTES->CursorPos; changed = TRUE; } } else if (PulsedInputState.menu[KEY_MENU_HOME]) { if (pStr > pTES->BaseStr) { pStr = pTES->BaseStr; len = strlen (pStr); pTES->CursorPos = 0; changed = TRUE; } } else if (PulsedInputState.menu[KEY_MENU_END]) { if (len > 0) { pTES->CursorPos += utf8StringCount (pStr); pStr += len; len = 0; changed = TRUE; } } if (pTES->JoyAlpha && ( PulsedInputState.menu[KEY_MENU_UP] || PulsedInputState.menu[KEY_MENU_DOWN] || PulsedInputState.menu[KEY_MENU_PAGE_UP] || PulsedInputState.menu[KEY_MENU_PAGE_DOWN]) ) { // do joystick text joy_char_t ch; joy_char_t newch; joy_char_t cmpch; int i; pTES->JoystickMode = TRUE; if (len) ReadOneChar (&ch, pStr); else ch = pTES->JoyAlpha[0]; newch = ch; JoyCharToUpper (&cmpch, &ch, pTES); // find current char in the alphabet i = JoyCharFindIn (&cmpch, pTES->JoyAlpha, pTES->JoyAlphaLength); if (PulsedInputState.menu[KEY_MENU_UP]) { --i; if (i < 0) i = pTES->JoyAlphaLength - 1; newch = pTES->JoyAlpha[i]; } else if (PulsedInputState.menu[KEY_MENU_DOWN]) { ++i; if (i >= pTES->JoyAlphaLength) i = 0; newch = pTES->JoyAlpha[i]; } if (PulsedInputState.menu[KEY_MENU_PAGE_UP] || PulsedInputState.menu[KEY_MENU_PAGE_DOWN]) { if (len) { // single char change if (JoyCharIsLower (&newch, pTES)) JoyCharToUpper (&newch, &newch, pTES); else JoyCharToLower (&newch, &newch, pTES); } else { // register change pTES->UpperRegister = !pTES->UpperRegister; } } else { // check register if (pTES->UpperRegister) JoyCharToUpper (&newch, &newch, pTES); else JoyCharToLower (&newch, &newch, pTES); } if (strcmp (newch.enc, ch.enc) != 0) { // new char is different, put it in if (len) { // change current -- this is messy with utf8 int l = len - ch.len; if (pStr + l - pTES->BaseStr + newch.len < pTES->MaxSize) { // adjust other chars if necessary if (newch.len != ch.len) memmove (pStr + newch.len, pStr + ch.len, l + 1); memcpy (pStr, newch.enc, newch.len); len = l + newch.len; changed = TRUE; } } else { // append if (pStr + len - pTES->BaseStr + newch.len < pTES->MaxSize) { memcpy (pStr, newch.enc, newch.len); pStr[newch.len] = '\0'; len += newch.len; changed = TRUE; } else { // does not fit PlayMenuSound (MENU_SOUND_FAILURE); } } } } if (PulsedInputState.menu[KEY_MENU_SELECT]) { // done entering pTES->Success = TRUE; return FALSE; } else if (PulsedInputState.menu[KEY_MENU_EDIT_CANCEL]) { // canceled entering pTES->Success = FALSE; return FALSE; } pTES->InsPt = pStr; if (changed && pTES->ChangeCallback) { if (!pTES->ChangeCallback (pTES)) { // changes not accepted - revert memcpy (pTES->BaseStr, pTES->CacheStr, pTES->MaxSize); pTES->InsPt = CacheInsPt; pTES->CursorPos = CacheCursorPos; PlayMenuSound (MENU_SOUND_FAILURE); } } if (pTES->FrameCallback) return pTES->FrameCallback (pTES); return TRUE; }