diff options
author | Paul Gilbert | 2019-05-15 15:47:15 -1000 |
---|---|---|
committer | Paul Gilbert | 2019-05-15 15:47:15 -1000 |
commit | 84bd8c6b46b405c3c14e8be6868d3a1534879d52 (patch) | |
tree | 5eacfa5d05d6867ba3149a487cf14acc1bae53de | |
parent | 120ea78e135e501f640a430484069a11437783cc (diff) | |
download | scummvm-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.cpp | 248 | ||||
-rw-r--r-- | engines/glk/hugo/hugo.cpp | 177 | ||||
-rw-r--r-- | engines/glk/hugo/hugo.h | 16 | ||||
-rw-r--r-- | engines/glk/hugo/hugo_defines.h | 2 |
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, |