First draft of namable savegames.
This code is loosely adapted from JMS's code in UQM-HD, but very little remains beyond the text input loop internals. Fully backwards compatible, but this format shouldn't survive to the final merge.
This commit is contained in:
+213
-29
@@ -34,6 +34,7 @@
|
||||
#include "sounds.h"
|
||||
#include "util.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/log.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@@ -253,7 +254,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
// disallow the change
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
|
||||
PreUpdateFlashRect ();
|
||||
|
||||
SetContextForeGroundColor (BackGround);
|
||||
@@ -264,7 +265,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
text_r.corner.x += *pchar_deltas++;
|
||||
if (CursorPos < lf.CharCount) /* end of line */
|
||||
--text_r.corner.x;
|
||||
|
||||
|
||||
if (state & DDSHS_BLOCKCUR)
|
||||
{ // Use block cursor for keyboardless systems
|
||||
if (CursorPos == lf.CharCount)
|
||||
@@ -284,7 +285,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
{ // Insertion point cursor
|
||||
text_r.extent.width = 1;
|
||||
}
|
||||
|
||||
|
||||
text_r.corner.y = r.corner.y;
|
||||
text_r.extent.height = r.extent.height;
|
||||
SetContextForeGroundColor (BLACK_COLOR);
|
||||
@@ -292,7 +293,7 @@ DrawNameString (bool nameCaptain, UNICODE *Str, COUNT CursorPos,
|
||||
|
||||
SetContextForeGroundColor (ForeGround);
|
||||
font_DrawText (&lf);
|
||||
|
||||
|
||||
PostUpdateFlashRect ();
|
||||
}
|
||||
|
||||
@@ -347,15 +348,183 @@ NameCaptainOrShip (bool nameCaptain)
|
||||
utf8StringCopy (Setting, tes.MaxSize, buf);
|
||||
else
|
||||
utf8StringCopy (buf, sizeof (buf), Setting);
|
||||
|
||||
|
||||
SetFlashRect (SFR_MENU_3DO);
|
||||
|
||||
|
||||
DrawNameString (nameCaptain, buf, 0, DDSHS_NORMAL);
|
||||
|
||||
if (namingCB)
|
||||
namingCB ();
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
DrawSaveNameString (UNICODE *Str, COUNT CursorPos, COUNT state, COUNT gameIndex)
|
||||
{
|
||||
RECT r;
|
||||
TEXT lf;
|
||||
Color BackGround, ForeGround;
|
||||
FONT Font;
|
||||
|
||||
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x1B, 0x00, 0x1B), 0x33));
|
||||
r.extent.width = 15;
|
||||
if (MAX_SAVED_GAMES > 99)
|
||||
r.extent.width += 5;
|
||||
r.extent.height = 11;
|
||||
r.corner.x = 8;
|
||||
r.corner.y = (160 + ((gameIndex % SAVES_PER_PAGE) * 13));
|
||||
DrawRectangle (&r);
|
||||
|
||||
r.extent.width = (204 - SAFE_X);
|
||||
r.corner.x = (30 + SAFE_X);
|
||||
DrawRectangle (&r);
|
||||
|
||||
Font = TinyFont;
|
||||
lf.baseline.x = r.corner.x + 3;
|
||||
lf.baseline.y = r.corner.y + 8;
|
||||
|
||||
BackGround = BUILD_COLOR (MAKE_RGB15 (0x1B, 0x00, 0x1B), 0x33);
|
||||
ForeGround = BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01);
|
||||
|
||||
lf.align = ALIGN_LEFT;
|
||||
|
||||
SetContextFont (Font);
|
||||
lf.pStr = Str;
|
||||
lf.CharCount = (COUNT)~0;
|
||||
|
||||
if (!(state & DDSHS_EDIT))
|
||||
{
|
||||
//RECT r;
|
||||
TEXT t;
|
||||
|
||||
SetContextForeGroundColor (BLACK_COLOR);
|
||||
DrawFilledRectangle (&r);
|
||||
|
||||
t.baseline.x = r.corner.x + 3;
|
||||
t.baseline.y = r.corner.y + 8;
|
||||
t.align = ALIGN_LEFT;
|
||||
t.pStr = Str;
|
||||
t.CharCount = (COUNT)~0;
|
||||
SetContextForeGroundColor (CAPTAIN_NAME_TEXT_COLOR);
|
||||
font_DrawText (&t);
|
||||
}
|
||||
else
|
||||
{ // editing state
|
||||
COUNT i;
|
||||
RECT text_r;
|
||||
BYTE char_deltas[SAVE_NAME_SIZE];
|
||||
BYTE *pchar_deltas;
|
||||
|
||||
TextRect (&lf, &text_r, char_deltas);
|
||||
if ((text_r.extent.width + 2) >= r.extent.width)
|
||||
{ // the text does not fit the input box size and so
|
||||
// will not fit when displayed later
|
||||
// disallow the change
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
PreUpdateFlashRect ();
|
||||
|
||||
SetContextForeGroundColor (BackGround);
|
||||
DrawFilledRectangle (&r);
|
||||
|
||||
pchar_deltas = char_deltas;
|
||||
|
||||
for (i = CursorPos; i > 0; --i)
|
||||
text_r.corner.x += *pchar_deltas++;
|
||||
if (CursorPos < lf.CharCount) /* end of line */
|
||||
--text_r.corner.x;
|
||||
|
||||
if (state & DDSHS_BLOCKCUR)
|
||||
{ // Use block cursor for keyboardless systems
|
||||
if (CursorPos == lf.CharCount)
|
||||
{ // cursor at end-line -- use insertion point
|
||||
text_r.extent.width = 1;
|
||||
}
|
||||
else if (CursorPos + 1 == lf.CharCount)
|
||||
{ // extra pixel for last char margin
|
||||
text_r.extent.width = (SIZE)*pchar_deltas + 2;
|
||||
}
|
||||
else
|
||||
{ // normal mid-line char
|
||||
text_r.extent.width = (SIZE)*pchar_deltas + 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Insertion point cursor
|
||||
text_r.extent.width = 1;
|
||||
}
|
||||
|
||||
text_r.corner.y = r.corner.y;
|
||||
text_r.extent.height = r.extent.height;
|
||||
SetContextForeGroundColor (BLACK_COLOR);
|
||||
DrawFilledRectangle (&text_r);
|
||||
|
||||
SetContextForeGroundColor (ForeGround);
|
||||
font_DrawText (&lf);
|
||||
PostUpdateFlashRect ();
|
||||
}
|
||||
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
OnSaveNameChange (TEXTENTRY_STATE *pTES)
|
||||
{
|
||||
COUNT hl = DDSHS_EDIT;
|
||||
COUNT *gameIndex = pTES->CbParam;
|
||||
|
||||
if (pTES->JoystickMode)
|
||||
hl |= DDSHS_BLOCKCUR;
|
||||
|
||||
return DrawSaveNameString (pTES->BaseStr, pTES->CursorPos, hl, *gameIndex);
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
NameSaveGame (COUNT gameIndex, UNICODE *buf)
|
||||
{
|
||||
TEXTENTRY_STATE tes;
|
||||
COUNT CursPos = 0;
|
||||
COUNT *gIndex = HMalloc (sizeof (COUNT));
|
||||
RECT r;
|
||||
*gIndex = gameIndex;
|
||||
|
||||
DrawSaveNameString (buf, CursPos, DDSHS_EDIT, gameIndex);
|
||||
|
||||
tes.MaxSize = SAVE_NAME_SIZE;
|
||||
|
||||
// text entry setup
|
||||
tes.Initialized = FALSE;
|
||||
tes.BaseStr = buf;
|
||||
tes.CursorPos = CursPos;
|
||||
tes.CbParam = gIndex;
|
||||
tes.ChangeCallback = OnSaveNameChange;
|
||||
tes.FrameCallback = 0;
|
||||
r.extent.width = (204 - SAFE_X);
|
||||
r.extent.height = 11;
|
||||
r.corner.x = (30 + SAFE_X);
|
||||
r.corner.y = (160 + ((gameIndex % SAVES_PER_PAGE) * 13));
|
||||
SetFlashRect (&r);
|
||||
|
||||
if (!DoTextEntry (&tes))
|
||||
buf[0] = 0;
|
||||
|
||||
SetFlashRect(NULL);
|
||||
|
||||
DrawSaveNameString (buf, CursPos, DDSHS_NORMAL, gameIndex);
|
||||
|
||||
if (namingCB)
|
||||
namingCB ();
|
||||
|
||||
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
|
||||
|
||||
HFree (gIndex);
|
||||
|
||||
SetFlashRect (NULL);
|
||||
|
||||
if (tes.Success)
|
||||
return (TRUE);
|
||||
else
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -611,7 +780,7 @@ DrawSavegameSummary (PICK_GAME_STATE *pickState, COUNT gameIndex)
|
||||
UninitQueue (&GLOBAL (built_ship_q));
|
||||
|
||||
SetContextClipRect (&OldRect);
|
||||
|
||||
|
||||
SetContext (SpaceContext);
|
||||
// draw devices
|
||||
s.origin.y = 13;
|
||||
@@ -680,7 +849,7 @@ DrawSavegameSummary (PICK_GAME_STATE *pickState, COUNT gameIndex)
|
||||
SetContextForeGroundColor (
|
||||
BUILD_COLOR (MAKE_RGB15 (0x10, 0x00, 0x10), 0x01));
|
||||
font_DrawText (&t);
|
||||
|
||||
|
||||
// print the location
|
||||
t.baseline.x = 6;
|
||||
t.baseline.y = 139 + 6;
|
||||
@@ -697,7 +866,7 @@ DrawSavegameSummary (PICK_GAME_STATE *pickState, COUNT gameIndex)
|
||||
{
|
||||
BYTE QuasiState;
|
||||
STAR_DESC *SDPtr;
|
||||
|
||||
|
||||
QuasiState = GET_GAME_STATE (ARILOU_SPACE_SIDE);
|
||||
SET_GAME_STATE (ARILOU_SPACE_SIDE, 0);
|
||||
SDPtr = FindStar (NULL, &starPt, 1, 1);
|
||||
@@ -770,11 +939,11 @@ DrawGameSelection (PICK_GAME_STATE *pickState, COUNT selSlot)
|
||||
COUNT curSlot;
|
||||
UNICODE buf[256];
|
||||
UNICODE buf2[80];
|
||||
|
||||
|
||||
BatchGraphics ();
|
||||
|
||||
SetContextFont (TinyFont);
|
||||
|
||||
|
||||
// Erase the selection menu
|
||||
r.extent.width = 240;
|
||||
r.extent.height = 65;
|
||||
@@ -825,9 +994,10 @@ DrawGameSelection (PICK_GAME_STATE *pickState, COUNT selSlot)
|
||||
{
|
||||
DateToString (buf2, sizeof buf2, desc->month_index,
|
||||
desc->day_index, desc->year_index);
|
||||
snprintf (buf, sizeof buf, "%s %s",
|
||||
GAME_STRING (SAVEGAME_STRING_BASE + 4), buf2);
|
||||
// "Saved Game - Date:"
|
||||
if (desc->SaveName[0])
|
||||
snprintf (buf, sizeof buf, "%s: %s", buf2, desc->SaveName);
|
||||
else
|
||||
snprintf (buf, sizeof buf, "%s", buf2);
|
||||
}
|
||||
font_DrawText (&t);
|
||||
}
|
||||
@@ -928,7 +1098,7 @@ DoPickGame (MENU_STATE *pMS)
|
||||
SetContext (SpaceContext);
|
||||
RedrawPickDisplay (pickState, pMS->CurState);
|
||||
}
|
||||
|
||||
|
||||
SleepThreadUntil (TimeIn + ONE_SECOND / 30);
|
||||
}
|
||||
|
||||
@@ -936,22 +1106,35 @@ DoPickGame (MENU_STATE *pMS)
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
SaveLoadGame (PICK_GAME_STATE *pickState, COUNT gameIndex)
|
||||
SaveLoadGame (PICK_GAME_STATE *pickState, COUNT gameIndex, BOOLEAN *canceled_by_user)
|
||||
{
|
||||
SUMMARY_DESC *desc = pickState->summary + gameIndex;
|
||||
UNICODE nameBuf[SAVE_NAME_SIZE];
|
||||
STAMP saveStamp;
|
||||
BOOLEAN success;
|
||||
|
||||
saveStamp.frame = NULL;
|
||||
|
||||
// TODO: fix ConfirmSaveLoad() interface so it does not rely on
|
||||
// MsgStamp != NULL parameter.
|
||||
ConfirmSaveLoad (pickState->saving ? &saveStamp : NULL);
|
||||
|
||||
if (pickState->saving)
|
||||
success = SaveGame (gameIndex, desc);
|
||||
{
|
||||
nameBuf[0] = 0;
|
||||
if (NameSaveGame (gameIndex, nameBuf))
|
||||
{
|
||||
PlayMenuSound (MENU_SOUND_SUCCESS);
|
||||
ConfirmSaveLoad (pickState->saving ? &saveStamp : NULL);
|
||||
success = SaveGame (gameIndex, desc, nameBuf);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
*canceled_by_user = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfirmSaveLoad (pickState->saving ? &saveStamp : NULL);
|
||||
success = LoadGame (gameIndex, NULL);
|
||||
}
|
||||
|
||||
// TODO: the same should be done for both save and load if we also
|
||||
// display a load problem message
|
||||
@@ -1005,12 +1188,12 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu)
|
||||
// draw the current savegame and fade in
|
||||
SetTransitionSource (NULL);
|
||||
BatchGraphics ();
|
||||
|
||||
|
||||
SetContextBackGroundColor (BLACK_COLOR);
|
||||
ClearDrawable ();
|
||||
RedrawPickDisplay (&pickState, MenuState.CurState);
|
||||
DrawSaveLoad (&pickState);
|
||||
|
||||
|
||||
if (fromMainMenu)
|
||||
{
|
||||
UnbatchGraphics ();
|
||||
@@ -1028,10 +1211,12 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu)
|
||||
SetMenuSounds (MENU_SOUND_ARROWS | MENU_SOUND_PAGEUP | MENU_SOUND_PAGEDOWN,
|
||||
0);
|
||||
MenuState.InputFunc = DoPickGame;
|
||||
|
||||
|
||||
// Save/load retry loop
|
||||
while (1)
|
||||
{
|
||||
BOOLEAN canceled_by_user = FALSE;
|
||||
|
||||
pickState.success = FALSE;
|
||||
DoInput (&MenuState, TRUE);
|
||||
if (!pickState.success)
|
||||
@@ -1039,11 +1224,11 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu)
|
||||
|
||||
lastUsedSlot = MenuState.CurState;
|
||||
|
||||
if (SaveLoadGame (&pickState, MenuState.CurState))
|
||||
if (SaveLoadGame (&pickState, MenuState.CurState, &canceled_by_user))
|
||||
break; // all good
|
||||
|
||||
// something broke
|
||||
if (saving)
|
||||
if (saving && !canceled_by_user)
|
||||
SaveProblem ();
|
||||
// TODO: Shouldn't we have a Problem() equivalent for Load too?
|
||||
|
||||
@@ -1058,7 +1243,7 @@ PickGame (BOOLEAN saving, BOOLEAN fromMainMenu)
|
||||
{ // Load succeeded, signal up the chain
|
||||
GLOBAL (CurrentActivity) |= CHECK_LOAD;
|
||||
}
|
||||
|
||||
|
||||
if (!(GLOBAL (CurrentActivity) & CHECK_ABORT) &&
|
||||
(saving || (!pickState.success && !fromMainMenu)))
|
||||
{ // Restore previous screen
|
||||
@@ -1145,7 +1330,7 @@ GameOptions (void)
|
||||
DrawMenuStateStrings (PM_SAVE_GAME, MenuState.CurState);
|
||||
|
||||
SetFlashRect (SFR_MENU_3DO);
|
||||
|
||||
|
||||
SetMenuSounds (MENU_SOUND_ARROWS, MENU_SOUND_SELECT);
|
||||
MenuState.InputFunc = DoGameOptions;
|
||||
DoInput (&MenuState, TRUE);
|
||||
@@ -1154,4 +1339,3 @@ GameOptions (void)
|
||||
|
||||
return !(GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_LOAD));
|
||||
}
|
||||
|
||||
|
||||
+33
-12
@@ -368,7 +368,7 @@ LoadEncounter (ENCOUNTER *EncounterPtr, DECODE_REF fh)
|
||||
cread_ptr (fh); /* useless ptr; FRAME icons */
|
||||
cread_ptr (fh); /* useless ptr; FRAME melee_icon */
|
||||
}
|
||||
|
||||
|
||||
// Load the stuff after the BRIEF_SHIP_INFO array
|
||||
cread_32s (fh, &EncounterPtr->log_x);
|
||||
cread_32s (fh, &EncounterPtr->log_y);
|
||||
@@ -405,7 +405,7 @@ DummyLoadQueue (QUEUE *QueuePtr, DECODE_REF fh)
|
||||
cread_16 (fh, NULL); /* MEM_HANDLE hq_tab */
|
||||
cread_16 (fh, NULL); /* COUNT object_size */
|
||||
cread_8 (fh, NULL); /* BYTE num_objects */
|
||||
|
||||
|
||||
cread_8 (fh, NULL); /* padding */
|
||||
cread_16 (fh, NULL); /* padding */
|
||||
}
|
||||
@@ -438,7 +438,7 @@ LoadGameState (GAME_STATE *GSPtr, DECODE_REF fh)
|
||||
cread_a8 (fh, GSPtr->ElementWorth, NUM_ELEMENT_CATEGORIES);
|
||||
cread_ptr (fh); /* not loading ptr; PRIMITIVE *DisplayArray */
|
||||
cread_16 (fh, &GSPtr->CurrentActivity);
|
||||
|
||||
|
||||
cread_16 (fh, NULL); /* CLOCK_STATE alignment padding */
|
||||
LoadClockState (&GSPtr->GameClock, fh);
|
||||
|
||||
@@ -466,7 +466,7 @@ LoadGameState (GAME_STATE *GSPtr, DECODE_REF fh)
|
||||
cread_16 (fh, NULL); /* VELOCITY_DESC padding */
|
||||
|
||||
cread_32 (fh, &GSPtr->BattleGroupRef);
|
||||
|
||||
|
||||
DummyLoadQueue (&GSPtr->avail_race_q, fh);
|
||||
DummyLoadQueue (&GSPtr->npc_built_ship_q, fh);
|
||||
// Not loading ip_group_q, was not there originally
|
||||
@@ -480,10 +480,10 @@ LoadGameState (GAME_STATE *GSPtr, DECODE_REF fh)
|
||||
}
|
||||
|
||||
static BOOLEAN
|
||||
LoadSisState (SIS_STATE *SSPtr, void *fp)
|
||||
LoadSisState (SIS_STATE *SSPtr, void *fp, SDWORD first)
|
||||
{
|
||||
SSPtr->log_x = first;
|
||||
if (
|
||||
read_32s (fp, &SSPtr->log_x) != 1 ||
|
||||
read_32s (fp, &SSPtr->log_y) != 1 ||
|
||||
read_32 (fp, &SSPtr->ResUnits) != 1 ||
|
||||
read_32 (fp, &SSPtr->FuelOnBoard) != 1 ||
|
||||
@@ -510,7 +510,26 @@ LoadSisState (SIS_STATE *SSPtr, void *fp)
|
||||
static BOOLEAN
|
||||
LoadSummary (SUMMARY_DESC *SummPtr, void *fp)
|
||||
{
|
||||
if (!LoadSisState (&SummPtr->SS, fp))
|
||||
SDWORD magic;
|
||||
BOOLEAN legacy;
|
||||
SummPtr->SaveName[0] = 0;
|
||||
if (!read_32s (fp, &magic))
|
||||
return FALSE;
|
||||
if (magic == SAVE_MAGIC)
|
||||
{
|
||||
legacy = FALSE;
|
||||
// Read in the real first value for LoadSisState
|
||||
if (read_32 (fp, &magic) != 1)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Otherwise, we're legacy and the "magic" number was
|
||||
// really LoadSisState's first value
|
||||
legacy = TRUE;
|
||||
}
|
||||
|
||||
if (!LoadSisState (&SummPtr->SS, fp, magic))
|
||||
return FALSE;
|
||||
|
||||
if (
|
||||
@@ -524,11 +543,15 @@ LoadSummary (SUMMARY_DESC *SummPtr, void *fp)
|
||||
read_8 (fp, &SummPtr->NumShips) != 1 ||
|
||||
read_8 (fp, &SummPtr->NumDevices) != 1 ||
|
||||
read_a8 (fp, SummPtr->ShipList, MAX_BUILT_SHIPS) != 1 ||
|
||||
read_a8 (fp, SummPtr->DeviceList, MAX_EXCLUSIVE_DEVICES) != 1 ||
|
||||
|
||||
read_16 (fp, NULL) != 1 /* padding */
|
||||
read_a8 (fp, SummPtr->DeviceList, MAX_EXCLUSIVE_DEVICES) != 1
|
||||
)
|
||||
return FALSE;
|
||||
if (!legacy && (read_a8 (fp, SummPtr->SaveName, SAVE_NAME_SIZE) != 1))
|
||||
return FALSE;
|
||||
// Don't trust the savefile to properly null-terminate!
|
||||
SummPtr->SaveName[SAVE_NAME_SIZE-1] = 0;
|
||||
if (read_16 (fp, NULL) != 1) /* padding */
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
@@ -760,5 +783,3 @@ LoadGame (COUNT which_game, SUMMARY_DESC *SummPtr)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+17
-12
@@ -305,7 +305,7 @@ SaveEncounter (const ENCOUNTER *EncounterPtr, DECODE_REF fh)
|
||||
cwrite_ptr (fh); /* useless ptr; FRAME icons */
|
||||
cwrite_ptr (fh); /* useless ptr; FRAME melee_icon */
|
||||
}
|
||||
|
||||
|
||||
// Save the stuff after the BRIEF_SHIP_INFO array
|
||||
cwrite_32 (fh, EncounterPtr->log_x);
|
||||
cwrite_32 (fh, EncounterPtr->log_y);
|
||||
@@ -340,7 +340,7 @@ DummySaveQueue (const QUEUE *QueuePtr, DECODE_REF fh)
|
||||
cwrite_16 (fh, 0); /* MEM_HANDLE hq_tab */
|
||||
cwrite_16 (fh, 0); /* COUNT object_size */
|
||||
cwrite_8 (fh, 0); /* BYTE num_objects */
|
||||
|
||||
|
||||
cwrite_8 (fh, 0); /* padding */
|
||||
cwrite_16 (fh, 0); /* padding */
|
||||
}
|
||||
@@ -371,7 +371,7 @@ SaveGameState (const GAME_STATE *GSPtr, DECODE_REF fh)
|
||||
cwrite_a8 (fh, GSPtr->ElementWorth, NUM_ELEMENT_CATEGORIES);
|
||||
cwrite_ptr (fh); /* useless ptr; PRIMITIVE *DisplayArray */
|
||||
cwrite_16 (fh, GSPtr->CurrentActivity);
|
||||
|
||||
|
||||
cwrite_16 (fh, 0); /* CLOCK_STATE alignment padding */
|
||||
SaveClockState (&GSPtr->GameClock, fh);
|
||||
|
||||
@@ -399,7 +399,7 @@ SaveGameState (const GAME_STATE *GSPtr, DECODE_REF fh)
|
||||
cwrite_16 (fh, 0); /* VELOCITY_DESC padding */
|
||||
|
||||
cwrite_32 (fh, GSPtr->BattleGroupRef);
|
||||
|
||||
|
||||
DummySaveQueue (&GSPtr->avail_race_q, fh);
|
||||
DummySaveQueue (&GSPtr->npc_built_ship_q, fh);
|
||||
// Not saving ip_group_q, was not there originally
|
||||
@@ -443,6 +443,8 @@ SaveSisState (const SIS_STATE *SSPtr, void *fp)
|
||||
static BOOLEAN
|
||||
SaveSummary (const SUMMARY_DESC *SummPtr, void *fp)
|
||||
{
|
||||
if (write_32 (fp, SAVE_MAGIC) != 1)
|
||||
return FALSE;
|
||||
if (!SaveSisState (&SummPtr->SS, fp))
|
||||
return FALSE;
|
||||
|
||||
@@ -458,6 +460,7 @@ SaveSummary (const SUMMARY_DESC *SummPtr, void *fp)
|
||||
write_8 (fp, SummPtr->NumDevices) != 1 ||
|
||||
write_a8 (fp, SummPtr->ShipList, MAX_BUILT_SHIPS) != 1 ||
|
||||
write_a8 (fp, SummPtr->DeviceList, MAX_EXCLUSIVE_DEVICES) != 1 ||
|
||||
write_a8 (fp, SummPtr->SaveName, SAVE_NAME_SIZE) != 1 ||
|
||||
|
||||
write_16 (fp, 0) != 1 /* padding */
|
||||
)
|
||||
@@ -478,8 +481,9 @@ SaveStarDesc (const STAR_DESC *SDPtr, DECODE_REF fh)
|
||||
}
|
||||
|
||||
static void
|
||||
PrepareSummary (SUMMARY_DESC *SummPtr)
|
||||
PrepareSummary (SUMMARY_DESC *SummPtr, const char *name)
|
||||
{
|
||||
int i;
|
||||
SummPtr->SS = GlobData.SIS_state;
|
||||
|
||||
SummPtr->Activity = LOBYTE (GLOBAL (CurrentActivity));
|
||||
@@ -535,6 +539,8 @@ PrepareSummary (SUMMARY_DESC *SummPtr)
|
||||
SummPtr->day_index = GLOBAL (GameClock.day_index);
|
||||
SummPtr->month_index = GLOBAL (GameClock.month_index);
|
||||
SummPtr->year_index = GLOBAL (GameClock.year_index);
|
||||
SummPtr->SaveName[SAVE_NAME_SIZE-1] = 0;
|
||||
strncpy (SummPtr->SaveName, name, SAVE_NAME_SIZE-1);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -549,7 +555,7 @@ SaveProblemMessage (STAMP *MsgStamp)
|
||||
// TODO: This should probably just use DoPopupWindow()
|
||||
|
||||
ppStr[0] = GAME_STRING (SAVEGAME_STRING_BASE + 2);
|
||||
|
||||
|
||||
SetContextFont (StarConFont);
|
||||
|
||||
t.baseline.x = t.baseline.y = 0;
|
||||
@@ -579,7 +585,7 @@ SaveProblemMessage (STAMP *MsgStamp)
|
||||
r.extent.height += 8;
|
||||
|
||||
*MsgStamp = SaveContextFrame (&r);
|
||||
|
||||
|
||||
BatchGraphics ();
|
||||
DrawStarConBox (&r, 2,
|
||||
BUILD_COLOR (MAKE_RGB15 (0x10, 0x10, 0x10), 0x19),
|
||||
@@ -605,7 +611,7 @@ SaveProblem (void)
|
||||
{
|
||||
STAMP s;
|
||||
CONTEXT OldContext;
|
||||
|
||||
|
||||
OldContext = SetContext (SpaceContext);
|
||||
SaveProblemMessage (&s);
|
||||
FlushGraphics ();
|
||||
@@ -635,7 +641,7 @@ SaveFlagshipState (void)
|
||||
// This function first writes to a memory file, and then writes the whole
|
||||
// lot to the actual save file at once.
|
||||
BOOLEAN
|
||||
SaveGame (COUNT which_game, SUMMARY_DESC *SummPtr)
|
||||
SaveGame (COUNT which_game, SUMMARY_DESC *SummPtr, const char *name)
|
||||
{
|
||||
BOOLEAN success, made_room;
|
||||
void *out_fp, *h;
|
||||
@@ -833,7 +839,7 @@ RetrySave:
|
||||
flen + sizeof (*SummPtr));
|
||||
if (flen && (out_fp = res_OpenResFile (saveDir, file, "wb")))
|
||||
{
|
||||
PrepareSummary (SummPtr);
|
||||
PrepareSummary (SummPtr, name);
|
||||
|
||||
success = SaveSummary (SummPtr, out_fp);
|
||||
// Then write the rest of the data.
|
||||
@@ -846,7 +852,7 @@ RetrySave:
|
||||
}
|
||||
else
|
||||
success = FALSE;
|
||||
|
||||
|
||||
if (!success)
|
||||
DeleteResFile (saveDir, file);
|
||||
}
|
||||
@@ -858,4 +864,3 @@ RetrySave:
|
||||
|
||||
return (success);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern void SaveProblem (void);
|
||||
extern BOOLEAN SaveGame (COUNT which_game, SUMMARY_DESC *summary_desc);
|
||||
extern BOOLEAN SaveGame (COUNT which_game, SUMMARY_DESC *summary_desc, const char *name);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
||||
+4
-1
@@ -76,7 +76,7 @@ enum
|
||||
CANNON_WEAPON,
|
||||
TRACKING_SYSTEM,
|
||||
ANTIMISSILE_DEFENSE,
|
||||
|
||||
|
||||
NUM_PURCHASE_MODULES,
|
||||
|
||||
BOMB_MODULE_0 = NUM_PURCHASE_MODULES,
|
||||
@@ -160,6 +160,8 @@ typedef struct
|
||||
// is only used for displaying savegame summaries. There is also
|
||||
// room for only 16 devices on screen.
|
||||
#define MAX_EXCLUSIVE_DEVICES 16
|
||||
#define SAVE_MAGIC 0x01534d55
|
||||
#define SAVE_NAME_SIZE 24
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -172,6 +174,7 @@ typedef struct
|
||||
BYTE NumShips, NumDevices;
|
||||
BYTE ShipList[MAX_BUILT_SHIPS];
|
||||
BYTE DeviceList[MAX_EXCLUSIVE_DEVICES];
|
||||
UNICODE SaveName[SAVE_NAME_SIZE];
|
||||
} SUMMARY_DESC;
|
||||
|
||||
#define OVERRIDE_LANDER_FLAGS (1 << 7)
|
||||
|
||||
Reference in New Issue
Block a user