aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2019-05-15 15:47:15 -1000
committerPaul Gilbert2019-05-15 15:47:15 -1000
commit84bd8c6b46b405c3c14e8be6868d3a1534879d52 (patch)
tree5eacfa5d05d6867ba3149a487cf14acc1bae53de
parent120ea78e135e501f640a430484069a11437783cc (diff)
downloadscummvm-rg350-84bd8c6b46b405c3c14e8be6868d3a1534879d52.tar.gz
scummvm-rg350-84bd8c6b46b405c3c14e8be6868d3a1534879d52.tar.bz2
scummvm-rg350-84bd8c6b46b405c3c14e8be6868d3a1534879d52.zip
GLK: HUGO: Move savegame code
-rw-r--r--engines/glk/hugo/herun.cpp248
-rw-r--r--engines/glk/hugo/hugo.cpp177
-rw-r--r--engines/glk/hugo/hugo.h16
-rw-r--r--engines/glk/hugo/hugo_defines.h2
4 files changed, 201 insertions, 242 deletions
diff --git a/engines/glk/hugo/herun.cpp b/engines/glk/hugo/herun.cpp
index dca7ac2333..8659544d2e 100644
--- a/engines/glk/hugo/herun.cpp
+++ b/engines/glk/hugo/herun.cpp
@@ -1151,112 +1151,6 @@ RestartError:
return 0;
}
-#ifndef RESTOREGAMEDATA_REPLACED
-
-int Hugo::RestoreGameData() {
- char testid[3], testserial[9];
- int lbyte, hbyte;
- int j;
- unsigned int k, undosize;
- long i;
-
- /* Check ID */
- testid[0] = (char)hugo_fgetc(save);
- testid[1] = (char)hugo_fgetc(save);
- testid[2] = '\0';
- if (hugo_ferror(save)) goto RestoreError;
-
- if (strcmp(testid, id))
- {
- AP("Incorrect save file.");
- if (hugo_fclose(save)) FatalError(READ_E);
- save = nullptr;
- return 0;
- }
-
- /* Check serial number */
- if (!hugo_fgets(testserial, 9, save)) goto RestoreError;
- if (strcmp(testserial, serial))
- {
- AP("Save file created by different version.");
- if (hugo_fclose(save)) FatalError(READ_E);
- save = nullptr;
- return 0;
- }
-
- /* Restore variables */
- for (k=0; k<MAXGLOBALS+MAXLOCALS; k++)
- {
- if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
- goto RestoreError;
- var[k] = lbyte + hbyte * 256;
- }
-
- /* Restore objtable and above */
-
- if (hugo_fseek(game, objtable*16L, SEEK_SET)) goto RestoreError;
- i = 0;
-
- while (i<codeend-(long)(objtable*16L))
- {
- if ((hbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError;
-
- if (hbyte==0)
- {
- if ((lbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError;
- SETMEM(objtable*16L+i, (unsigned char)lbyte);
- i++;
-
- /* Skip byte in game file */
- if (hugo_fgetc(game)==EOF) goto RestoreError;
- }
- else
- {
- while (hbyte--)
- {
- /* Get unchanged game file byte */
- if ((lbyte = hugo_fgetc(game))==EOF) goto RestoreError;
- SETMEM(objtable*16L+i, (unsigned char)lbyte);
- i++;
- }
- }
- }
-
- /* Restore undo data */
- if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
- goto RestoreError;
- undosize = lbyte + hbyte*256;
-
- /* We can only restore undo data if it was saved by a port with
- the same MAXUNDO as us */
- if (undosize==MAXUNDO)
- {
- for (k=0; k<MAXUNDO; k++)
- {
- for (j=0; j<5; j++)
- {
- if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
- goto RestoreError;
- undostack[k][j] = lbyte + hbyte*256;
- }
- }
- if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
- undoptr = lbyte + hbyte*256;
- if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
- undoturn = lbyte + hbyte*256;
- if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
- undoinvalid = (unsigned char)lbyte, undorecord = (unsigned char)hbyte;
- }
- else undoinvalid = true;
-
- return true;
-
-RestoreError:
- return false;
-}
-
-#endif // RESTOREGAMEDATA_REPLACED
-
int Hugo::RunRestore() {
#if !defined (GLK)
save = nullptr;
@@ -1270,40 +1164,28 @@ int Hugo::RunRestore() {
if (!strcmp(line, "")) return 0;
if (!(save = HUGO_FOPEN(line, "r+b"))) return 0;
-#else
- /* Glk implementation */
- frefid_t savefile;
-
- save = nullptr;
-
- savefile = glk_fileref_create_by_prompt(fileusage_SavedGame | fileusage_BinaryMode,
- filemode_Read, 0);
- if (!savefile) return 0;
- if (glk_fileref_does_file_exist(savefile))
- save = glk_stream_open_file(savefile, filemode_Read, 0);
- else
- save = nullptr;
- glk_fileref_destroy(savefile);
- if (!save) return 0;
-
-#endif /* GLK */
-
if (!RestoreGameData()) goto RestoreError;
if (hugo_fclose(save)) FatalError(READ_E);
save = nullptr;
-#if !defined (GLK)
strcpy(savefile, line);
-#endif
+#else
+ /* Glk implementation */
+ if (loadGame().getCode() != Common::kNoError)
+ goto RestoreError;
+
+#endif /* GLK */
game_reset = true;
- return (1);
+ return 1;
RestoreError:
+#if !defined (GLK)
if ((save) && hugo_fclose(save)) FatalError(READ_E);
save = nullptr;
+#endif
game_reset = false;
return 0;
}
@@ -2212,90 +2094,6 @@ ReturnfromRoutine:
return;
}
-#ifndef SAVEGAMEDATA_REPLACED
-
-int Hugo::SaveGameData() {
- int c, j;
- int lbyte, hbyte;
- long i;
- int samecount = 0;
-
- /* Write ID */
- if (hugo_fputc(id[0], save)==EOF || hugo_fputc(id[1], save)==EOF) goto SaveError;
-
- /* Write serial number */
- if (hugo_fputs(serial, save)==EOF) goto SaveError;
-
- /* Save variables */
- for (c=0; c<MAXGLOBALS+MAXLOCALS; c++)
- {
- hbyte = (unsigned int)var[c] / 256;
- lbyte = (unsigned int)var[c] - hbyte * 256;
- if (hugo_fputc(lbyte, save)==EOF || hugo_fputc(hbyte, save)==EOF) goto SaveError;
- }
-
- /* Save objtable to end of code space */
-
- if (hugo_fseek(game, objtable*16L, SEEK_SET)) goto SaveError;
-
- for (i=0; i<=codeend-(long)(objtable*16L); i++)
- {
- if ((lbyte = hugo_fgetc(game))==EOF) goto SaveError;
- hbyte = MEM(objtable*16L+i);
-
- /* If memory same as original game file */
- if (lbyte==hbyte && samecount<255) samecount++;
-
- /* If memory differs (or samecount exceeds 1 byte) */
- else
- {
- if (samecount)
- if (hugo_fputc(samecount, save)==EOF) goto SaveError;
-
- if (lbyte!=hbyte)
- {
- if (hugo_fputc(0, save)==EOF) goto SaveError;
- if (hugo_fputc(hbyte, save)==EOF) goto SaveError;
- samecount = 0;
- }
- else samecount = 1;
- }
- }
- if (samecount)
- if (hugo_fputc(samecount, save)==EOF) goto SaveError;
-
- /* Save undo data */
-
- /* Save the number of turns in this port's undo stack */
- hbyte = (unsigned int)MAXUNDO / 256;
- lbyte = (unsigned int)MAXUNDO - hbyte*256;
- if (hugo_fputc(lbyte, save)==EOF || hugo_fputc(hbyte, save)==EOF)
- goto SaveError;
- for (c=0; c<MAXUNDO; c++)
- {
- for (j=0; j<5; j++)
- {
- hbyte = (unsigned int)undostack[c][j] / 256;
- lbyte = (unsigned int)undostack[c][j] - hbyte*256;
- if (hugo_fputc(lbyte, save)==EOF || hugo_fputc(hbyte, save)==EOF)
- goto SaveError;
- }
- }
- if (hugo_fputc(undoptr-(undoptr/256)*256, save)==EOF || hugo_fputc(undoptr/256, save)==EOF)
- goto SaveError;
- if (hugo_fputc(undoturn-(undoturn/256)*256, save)==EOF || hugo_fputc(undoturn/256, save)==EOF)
- goto SaveError;
- if (hugo_fputc(undoinvalid, save)==EOF || hugo_fputc(undorecord, save)==EOF)
- goto SaveError;
-
- return true;
-
-SaveError:
- return false;
-}
-
-#endif // SAVEGAMEDATA_REPLACED
-
int Hugo::RunSave() {
#ifdef PALMOS
/* Prevent simultaneous access to the same db record */
@@ -2316,35 +2114,25 @@ int Hugo::RunSave() {
if (!hugo_overwrite(line)) return 0;
if (!(save = HUGO_FOPEN(line, "w+b"))) return 0;
-#else
- /* Glk implementation */
- frefid_t savefile;
-
- save = nullptr;
-
- savefile = glk_fileref_create_by_prompt(fileusage_SavedGame | fileusage_BinaryMode,
- filemode_Write, 0);
- if (!savefile) return 0;
- save = glk_stream_open_file(savefile, filemode_Write, 0);
- glk_fileref_destroy(savefile);
- if (!save) return 0;
-
-#endif /* GLK */
-
if (!SaveGameData()) goto SaveError;
-
+
if (hugo_fclose(save)) FatalError(WRITE_E);
save = nullptr;
-#if !defined (GLK)
strcpy(savefile, line);
-#endif
+#else
+ /* Glk implementation */
+ if (saveGame().getCode() != Common::kNoError)
+ goto SaveError;
+#endif /* GLK */
- return(1);
+ return 1;
SaveError:
+#if !defined (GLK)
if ((save) && hugo_fclose(save)) FatalError(WRITE_E);
save = nullptr;
+#endif
return 0;
}
diff --git a/engines/glk/hugo/hugo.cpp b/engines/glk/hugo/hugo.cpp
index 543da72a14..c15a843fbf 100644
--- a/engines/glk/hugo/hugo.cpp
+++ b/engines/glk/hugo/hugo.cpp
@@ -34,7 +34,7 @@ Hugo::Hugo(OSystem *syst, const GlkGameDescription &gameDesc) : GlkAPI(syst, gam
// hemedia
mchannel(nullptr), schannel(nullptr),
// hemisc
- game_version(0), object_size(24), game(nullptr), script(nullptr), save(nullptr),
+ game_version(0), object_size(24), game(nullptr), script(nullptr),
playback(nullptr), record(nullptr), io(nullptr), ioblock('\0'), ioerror('\0'),
codestart(0), objtable(0), eventtable(0), proptable(0), arraytable(0), dicttable(0),
syntable(0), initaddr(0), mainaddr(0), parseaddr(0), parseerroraddr(0),
@@ -148,14 +148,181 @@ void Hugo::runGame() {
hugo_closefiles();
}
-Common::Error Hugo::loadGameData(strid_t file) {
- // TODO
+Common::Error Hugo::loadGameData(strid_t save) {
+ char testid[3], testserial[9];
+ int lbyte, hbyte;
+ int j;
+ unsigned int k, undosize;
+ long i;
+
+ /* Check ID */
+ testid[0] = (char)hugo_fgetc(save);
+ testid[1] = (char)hugo_fgetc(save);
+ testid[2] = '\0';
+ if (hugo_ferror(save)) goto RestoreError;
+
+ if (strcmp(testid, id)) {
+ GUIErrorMessage("Incorrect save file.");
+ goto RestoreError;
+ }
+
+ /* Check serial number */
+ if (!hugo_fgets(testserial, 9, save)) goto RestoreError;
+ if (strcmp(testserial, serial))
+ {
+ GUIErrorMessage("Save file created by different version.");
+ goto RestoreError;
+ }
+
+ /* Restore variables */
+ for (k=0; k<MAXGLOBALS+MAXLOCALS; k++)
+ {
+ if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
+ goto RestoreError;
+ var[k] = lbyte + hbyte * 256;
+ }
+
+ /* Restore objtable and above */
+
+ if (hugo_fseek(game, objtable*16L, SEEK_SET)) goto RestoreError;
+ i = 0;
+
+ while (i<codeend-(long)(objtable*16L))
+ {
+ if ((hbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError;
+
+ if (hbyte==0)
+ {
+ if ((lbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError;
+ SETMEM(objtable*16L+i, (unsigned char)lbyte);
+ i++;
+
+ /* Skip byte in game file */
+ if (hugo_fgetc(game)==EOF) goto RestoreError;
+ }
+ else
+ {
+ while (hbyte--)
+ {
+ /* Get unchanged game file byte */
+ if ((lbyte = hugo_fgetc(game))==EOF) goto RestoreError;
+ SETMEM(objtable*16L+i, (unsigned char)lbyte);
+ i++;
+ }
+ }
+ }
+
+ /* Restore undo data */
+ if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
+ goto RestoreError;
+ undosize = lbyte + hbyte*256;
+
+ /* We can only restore undo data if it was saved by a port with
+ the same MAXUNDO as us */
+ if (undosize==MAXUNDO)
+ {
+ for (k=0; k<MAXUNDO; k++)
+ {
+ for (j=0; j<5; j++)
+ {
+ if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
+ goto RestoreError;
+ undostack[k][j] = lbyte + hbyte*256;
+ }
+ }
+ if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
+ undoptr = lbyte + hbyte*256;
+ if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
+ undoturn = lbyte + hbyte*256;
+ if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
+ undoinvalid = (unsigned char)lbyte, undorecord = (unsigned char)hbyte;
+ }
+ else undoinvalid = true;
+
return Common::kNoError;
+
+RestoreError:
+ return Common::kReadingFailed;
}
-Common::Error Hugo::saveGameData(strid_t file, const Common::String &desc) {
- // TODO
+Common::Error Hugo::saveGameData(strid_t save, const Common::String &desc) {
+ int c, j;
+ int lbyte, hbyte;
+ long i;
+ int samecount = 0;
+
+ /* Write ID */
+ if (hugo_fputc(id[0], save) == EOF || hugo_fputc(id[1], save) == EOF) goto SaveError;
+
+ /* Write serial number */
+ if (hugo_fputs(serial, save) == EOF) goto SaveError;
+
+ /* Save variables */
+ for (c = 0; c<MAXGLOBALS + MAXLOCALS; c++)
+ {
+ hbyte = (unsigned int)var[c] / 256;
+ lbyte = (unsigned int)var[c] - hbyte * 256;
+ if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF) goto SaveError;
+ }
+
+ /* Save objtable to end of code space */
+
+ if (hugo_fseek(game, objtable * 16L, SEEK_SET)) goto SaveError;
+
+ for (i = 0; i <= codeend - (long)(objtable * 16L); i++)
+ {
+ if ((lbyte = hugo_fgetc(game)) == EOF) goto SaveError;
+ hbyte = MEM(objtable * 16L + i);
+
+ /* If memory same as original game file */
+ if (lbyte == hbyte && samecount<255) samecount++;
+
+ /* If memory differs (or samecount exceeds 1 byte) */
+ else
+ {
+ if (samecount)
+ if (hugo_fputc(samecount, save) == EOF) goto SaveError;
+
+ if (lbyte != hbyte)
+ {
+ if (hugo_fputc(0, save) == EOF) goto SaveError;
+ if (hugo_fputc(hbyte, save) == EOF) goto SaveError;
+ samecount = 0;
+ }
+ else samecount = 1;
+ }
+ }
+ if (samecount)
+ if (hugo_fputc(samecount, save) == EOF) goto SaveError;
+
+ /* Save undo data */
+
+ /* Save the number of turns in this port's undo stack */
+ hbyte = (unsigned int)MAXUNDO / 256;
+ lbyte = (unsigned int)MAXUNDO - hbyte * 256;
+ if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF)
+ goto SaveError;
+ for (c = 0; c<MAXUNDO; c++)
+ {
+ for (j = 0; j<5; j++)
+ {
+ hbyte = (unsigned int)undostack[c][j] / 256;
+ lbyte = (unsigned int)undostack[c][j] - hbyte * 256;
+ if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF)
+ goto SaveError;
+ }
+ }
+ if (hugo_fputc(undoptr - (undoptr / 256) * 256, save) == EOF || hugo_fputc(undoptr / 256, save) == EOF)
+ goto SaveError;
+ if (hugo_fputc(undoturn - (undoturn / 256) * 256, save) == EOF || hugo_fputc(undoturn / 256, save) == EOF)
+ goto SaveError;
+ if (hugo_fputc(undoinvalid, save) == EOF || hugo_fputc(undorecord, save) == EOF)
+ goto SaveError;
+
return Common::kNoError;
+
+SaveError:
+ return Common::kWritingFailed;
}
} // End of namespace Hugo
diff --git a/engines/glk/hugo/hugo.h b/engines/glk/hugo/hugo.h
index c09e318633..2be3bfd680 100644
--- a/engines/glk/hugo/hugo.h
+++ b/engines/glk/hugo/hugo.h
@@ -73,7 +73,6 @@ private:
int object_size;
Common::SeekableReadStream *game;
HUGO_FILE script;
- HUGO_FILE save;
HUGO_FILE playback;
HUGO_FILE record;
HUGO_FILE io; char ioblock; char ioerror;
@@ -972,8 +971,6 @@ private:
*/
void RunRoutine(long addr);
- int SaveGameData();
-
int RunSave();
int RunScriptSet();
@@ -1043,9 +1040,14 @@ private:
char *hugo_fgets(char *buf, int max, Common::SeekableReadStream *s) {
char *ptr = buf;
char c;
- while (s->pos() < s->size() && (c = hugo_fgetc(s)) != '\n')
+ while (s->pos() < s->size()) {
+ c = hugo_fgetc(s);
+ if (c == '\n' || c == '\0' || (max-- == 0))
+ break;
*ptr++ = c;
- return buffer;
+ }
+ *ptr++ = '\0';
+ return buf;
}
char *hugo_fgets(char *buf, int max, strid_t s) {
Common::SeekableReadStream *rs = *s;
@@ -1190,12 +1192,12 @@ public:
/**
* Load a savegame from the passed stream
*/
- virtual Common::Error loadGameData(strid_t file) override;
+ virtual Common::Error loadGameData(strid_t save) override;
/**
* Save the game to the passed stream
*/
- virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override;
+ virtual Common::Error saveGameData(strid_t save, const Common::String &desc) override;
};
} // End of namespace Hugo
diff --git a/engines/glk/hugo/hugo_defines.h b/engines/glk/hugo/hugo_defines.h
index b9ed1379cf..8d5b41b49e 100644
--- a/engines/glk/hugo/hugo_defines.h
+++ b/engines/glk/hugo/hugo_defines.h
@@ -36,6 +36,8 @@ namespace Hugo {
#define GRAPHICS_SUPPORTED
#define SOUND_SUPPORTED
#define SETTITLE_SUPPORTED
+#define SAVEGAMEDATA_REPLACED
+#define RESTOREGAMEDATA_REPLACED
// There's a bunch of debugging code in the original Hugo sources behind DEBUGGER defines,
// but doesn't actually have any implementation of them. I've put in some stub methods,