mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-14 13:50:13 +00:00
GLK: Further changeover of sub-engines to use new savegame code
This commit is contained in:
parent
3876fb6710
commit
553bb74f8c
@ -5,6 +5,7 @@ engines/glk/advsys/advsys.cpp
|
|||||||
engines/glk/advsys/vm.cpp
|
engines/glk/advsys/vm.cpp
|
||||||
engines/glk/alan2/alan2.cpp
|
engines/glk/alan2/alan2.cpp
|
||||||
engines/glk/frotz/detection.cpp
|
engines/glk/frotz/detection.cpp
|
||||||
|
engines/glk/frotz/frotz.cpp
|
||||||
engines/glk/glulxe/glulxe.cpp
|
engines/glk/glulxe/glulxe.cpp
|
||||||
engines/glk/magnetic/magnetic.cpp
|
engines/glk/magnetic/magnetic.cpp
|
||||||
engines/glk/scott/scott.cpp
|
engines/glk/scott/scott.cpp
|
||||||
|
@ -102,11 +102,13 @@ bool AdvSys::singleAction() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error AdvSys::loadGameData(strid_t save) {
|
Common::Error AdvSys::readSaveData(Common::SeekableReadStream *rs) {
|
||||||
|
rs->read(_saveArea, rs->size());
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error AdvSys::saveGameData(strid_t save, const Common::String &desc) {
|
Common::Error AdvSys::writeGameData(Common::WriteStream *ws) {
|
||||||
|
ws->write(_saveArea, _saveSize);
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,14 +67,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t save) override;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t save, const Common::String &desc) override;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace AdvSys
|
} // End of namespace AdvSys
|
||||||
|
@ -61,14 +61,14 @@ void Alan2::runGame() {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Alan2::loadGameData(strid_t file) {
|
Common::Error Alan2::readSaveData(Common::SeekableReadStream *rs) {
|
||||||
// TODO
|
// TODO
|
||||||
return Common::kNoError;
|
return Common::kReadingFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Alan2::saveGameData(strid_t file, const Common::String &desc) {
|
Common::Error Alan2::writeGameData(Common::WriteStream *ws) {
|
||||||
// TODO
|
// TODO
|
||||||
return Common::kNoError;
|
return Common::kWritingFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Alan2::is_gamefile_valid() {
|
bool Alan2::is_gamefile_valid() {
|
||||||
|
@ -68,14 +68,15 @@ public:
|
|||||||
virtual InterpreterType getInterpreterType() const override { return INTERPRETER_ALAN2; }
|
virtual InterpreterType getInterpreterType() const override { return INTERPRETER_ALAN2; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t file) override;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Output a string to the screen
|
* Output a string to the screen
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "glk/frotz/quetzal.h"
|
#include "glk/frotz/quetzal.h"
|
||||||
#include "engines/util.h"
|
#include "engines/util.h"
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
|
#include "common/translation.h"
|
||||||
|
|
||||||
namespace Glk {
|
namespace Glk {
|
||||||
namespace Frotz {
|
namespace Frotz {
|
||||||
@ -90,17 +91,13 @@ void Frotz::initialize() {
|
|||||||
z_restart();
|
z_restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Frotz::saveGameData(strid_t file, const Common::String &desc) {
|
Common::Error Frotz::loadGameState(int slot) {
|
||||||
Quetzal q(story_fp);
|
FileReference ref(slot, "", fileusage_SavedGame | fileusage_TextMode);
|
||||||
bool success = q.save(*file, this, desc);
|
|
||||||
|
|
||||||
if (!success)
|
strid_t file = _streams->openFileStream(&ref, filemode_Read);
|
||||||
print_string("Error writing save file\n");
|
if (file == nullptr)
|
||||||
|
return Common::kReadingFailed;
|
||||||
|
|
||||||
return Common::kNoError;
|
|
||||||
}
|
|
||||||
|
|
||||||
Common::Error Frotz::loadGameData(strid_t file) {
|
|
||||||
Quetzal q(story_fp);
|
Quetzal q(story_fp);
|
||||||
bool success = q.restore(*file, this) == 2;
|
bool success = q.restore(*file, this) == 2;
|
||||||
|
|
||||||
@ -123,14 +120,32 @@ Common::Error Frotz::loadGameData(strid_t file) {
|
|||||||
* seems to cover up most of the resulting badness.
|
* seems to cover up most of the resulting badness.
|
||||||
*/
|
*/
|
||||||
if (h_version > V3 && h_version != V6 && (h_screen_rows != old_screen_rows
|
if (h_version > V3 && h_version != V6 && (h_screen_rows != old_screen_rows
|
||||||
|| h_screen_cols != old_screen_cols))
|
|| h_screen_cols != old_screen_cols))
|
||||||
erase_window(1);
|
erase_window(1);
|
||||||
} else {
|
} else {
|
||||||
error("Error reading save file");
|
error(_("Error reading save file"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::Error Frotz::saveGameState(int slot, const Common::String &desc) {
|
||||||
|
Common::String msg;
|
||||||
|
FileReference ref(slot, desc, fileusage_BinaryMode | fileusage_SavedGame);
|
||||||
|
|
||||||
|
strid_t file = _streams->openFileStream(&ref, filemode_Write);
|
||||||
|
if (file == nullptr)
|
||||||
|
return Common::kWritingFailed;
|
||||||
|
|
||||||
|
Quetzal q(story_fp);
|
||||||
|
bool success = q.save(*file, this, desc);
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
print_string(_("Error writing save file\n"));
|
||||||
|
|
||||||
|
return Common::kNoError;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Frotz
|
} // End of namespace Frotz
|
||||||
} // End of namespace Glk
|
} // End of namespace Glk
|
||||||
|
@ -72,14 +72,25 @@ public:
|
|||||||
virtual void runGame() override;
|
virtual void runGame() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from a given slot
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t file) override;
|
virtual Common::Error loadGameState(int slot) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game to a given slot
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override;
|
virtual Common::Error saveGameState(int slot, const Common::String &desc) override;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loading method not used for Frotz sub-engine
|
||||||
|
*/
|
||||||
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override { return Common::kReadingFailed; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saving method not used for Frotz sub-engine
|
||||||
|
*/
|
||||||
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override { return Common::kWritingFailed; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Frotz *g_vm;
|
extern Frotz *g_vm;
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include "glk/conf.h"
|
#include "glk/conf.h"
|
||||||
#include "glk/events.h"
|
#include "glk/events.h"
|
||||||
#include "glk/picture.h"
|
#include "glk/picture.h"
|
||||||
|
#include "glk/quetzal.h"
|
||||||
#include "glk/screen.h"
|
#include "glk/screen.h"
|
||||||
#include "glk/selection.h"
|
#include "glk/selection.h"
|
||||||
#include "glk/sound.h"
|
#include "glk/sound.h"
|
||||||
@ -182,10 +183,32 @@ Common::Error GlkEngine::loadGameState(int slot) {
|
|||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
return Common::kReadingFailed;
|
return Common::kReadingFailed;
|
||||||
|
|
||||||
Common::Error result = loadGameData(file);
|
Common::ErrorCode errCode = Common::kNoError;
|
||||||
|
QuetzalReader r;
|
||||||
|
if (r.open(*file, ID_IFSF)) {
|
||||||
|
// First scan for a SCVM chunk. It has information of the game the save is for,
|
||||||
|
// so if present we can validate the save is for this game
|
||||||
|
for (QuetzalReader::Iterator it = r.begin(); it != r.end(); ++it) {
|
||||||
|
if ((*it)._id == ID_SCVM) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errCode != Common::kNoError) {
|
||||||
|
// Scan for an uncompressed memory chunk
|
||||||
|
errCode = Common::kReadingFailed; // Presume we won't find chunk
|
||||||
|
for (QuetzalReader::Iterator it = r.begin(); it != r.end(); ++it) {
|
||||||
|
if ((*it)._id == ID_UMem) {
|
||||||
|
Common::SeekableReadStream *rs = it.getStream();
|
||||||
|
errCode = readSaveData(rs).getCode();
|
||||||
|
delete rs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
file->close();
|
file->close();
|
||||||
return result;
|
return errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error GlkEngine::saveGameState(int slot, const Common::String &desc) {
|
Common::Error GlkEngine::saveGameState(int slot, const Common::String &desc) {
|
||||||
@ -196,10 +219,21 @@ Common::Error GlkEngine::saveGameState(int slot, const Common::String &desc) {
|
|||||||
if (file == nullptr)
|
if (file == nullptr)
|
||||||
return Common::kWritingFailed;
|
return Common::kWritingFailed;
|
||||||
|
|
||||||
Common::Error result = saveGameData(file, desc);
|
Common::ErrorCode errCode = Common::kNoError;
|
||||||
|
QuetzalWriter w;
|
||||||
|
|
||||||
|
// Add the uncompressed memory chunk with the game's save data
|
||||||
|
{
|
||||||
|
Common::WriteStream &ws = w.add(ID_UMem);
|
||||||
|
errCode = writeGameData(&ws).getCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (errCode != Common::kNoError) {
|
||||||
|
w.save(*file, desc);
|
||||||
|
}
|
||||||
|
|
||||||
file->close();
|
file->close();
|
||||||
return result;
|
return errCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlkEngine::beep() {
|
void GlkEngine::beep() {
|
||||||
|
@ -198,14 +198,15 @@ public:
|
|||||||
virtual Common::Error saveGameState(int slot, const Common::String &desc) override;
|
virtual Common::Error saveGameState(int slot, const Common::String &desc) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed file
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t file) = 0;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed file
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t file, const Common::String &desc) = 0;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a beep
|
* Generate a beep
|
||||||
|
@ -681,12 +681,20 @@ PerformJump: /* goto label for successful jumping... ironic, no? */
|
|||||||
|
|
||||||
case op_save:
|
case op_save:
|
||||||
push_callstub(inst[1].desttype, inst[1].value);
|
push_callstub(inst[1].desttype, inst[1].value);
|
||||||
|
#ifdef TODO
|
||||||
value = saveGameData(find_stream_by_id(inst[0].value), "Savegame").getCode() == Common::kNoError ? 0 : 1;
|
value = saveGameData(find_stream_by_id(inst[0].value), "Savegame").getCode() == Common::kNoError ? 0 : 1;
|
||||||
|
#else
|
||||||
|
error("TODO");
|
||||||
|
#endif
|
||||||
pop_callstub(value);
|
pop_callstub(value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case op_restore:
|
case op_restore:
|
||||||
|
#ifdef TODO
|
||||||
value = loadGameData(find_stream_by_id(inst[0].value)).getCode() == Common::kNoError ? 0 : 1;
|
value = loadGameData(find_stream_by_id(inst[0].value)).getCode() == Common::kNoError ? 0 : 1;
|
||||||
|
#else
|
||||||
|
error("TODO");
|
||||||
|
#endif
|
||||||
if (value == 0) {
|
if (value == 0) {
|
||||||
/* We've succeeded, and the stack now contains the callstub
|
/* We've succeeded, and the stack now contains the callstub
|
||||||
saved during saveundo. Ignore this opcode's operand. */
|
saved during saveundo. Ignore this opcode's operand. */
|
||||||
|
@ -407,14 +407,15 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t str) override;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t str, const Common::String &desc) override;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup Main access methods
|
* \defgroup Main access methods
|
||||||
|
@ -232,13 +232,13 @@ uint Glulxe::perform_restoreundo() {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Glulxe::saveGameData(strid_t str, const Common::String &desc) {
|
Common::Error Glulxe::writeGameData(Common::WriteStream *ws) {
|
||||||
dest_t dest;
|
dest_t dest;
|
||||||
int ix;
|
int ix;
|
||||||
uint res, lx, val;
|
uint res = 0, lx, val;
|
||||||
uint memstart = 0, memlen = 0, stackstart = 0, stacklen = 0;
|
uint memstart = 0, memlen = 0, stackstart = 0, stacklen = 0;
|
||||||
uint heapstart = 0, heaplen = 0, filestart = 0, filelen = 0;
|
uint heapstart = 0, heaplen = 0, filestart = 0, filelen = 0;
|
||||||
|
#ifdef TODO
|
||||||
stream_get_iosys(&val, &lx);
|
stream_get_iosys(&val, &lx);
|
||||||
if (val != 2) {
|
if (val != 2) {
|
||||||
/* Not using the Glk I/O system, so bail. This function only
|
/* Not using the Glk I/O system, so bail. This function only
|
||||||
@ -246,14 +246,14 @@ Common::Error Glulxe::saveGameData(strid_t str, const Common::String &desc) {
|
|||||||
fatal_error("Streams are only available in Glk I/O system.");
|
fatal_error("Streams are only available in Glk I/O system.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (str == nullptr)
|
if (ws == nullptr)
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
|
|
||||||
dest.ismem = false;
|
dest.ismem = false;
|
||||||
dest.size = 0;
|
dest.size = 0;
|
||||||
dest.pos = 0;
|
dest.pos = 0;
|
||||||
dest.ptr = nullptr;
|
dest.ptr = nullptr;
|
||||||
dest.str = str;
|
dest.str = ws;
|
||||||
|
|
||||||
res = 0;
|
res = 0;
|
||||||
|
|
||||||
@ -357,11 +357,11 @@ Common::Error Glulxe::saveGameData(strid_t str, const Common::String &desc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* All done. */
|
/* All done. */
|
||||||
|
#endif
|
||||||
return res ? Common::kUnknownError : Common::kNoError;
|
return res ? Common::kUnknownError : Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Glulxe::loadGameData(strid_t str) {
|
Common::Error Glulxe::readSaveData(Common::SeekableReadStream *rs) {
|
||||||
dest_t dest;
|
dest_t dest;
|
||||||
int ix;
|
int ix;
|
||||||
uint lx, res, val;
|
uint lx, res, val;
|
||||||
@ -369,7 +369,7 @@ Common::Error Glulxe::loadGameData(strid_t str) {
|
|||||||
uint heapsumlen = 0;
|
uint heapsumlen = 0;
|
||||||
uint *heapsumarr = nullptr;
|
uint *heapsumarr = nullptr;
|
||||||
bool fromshell = false;
|
bool fromshell = false;
|
||||||
|
#ifdef TODO
|
||||||
/* If profiling is enabled and active then fail. */
|
/* If profiling is enabled and active then fail. */
|
||||||
#if VM_PROFILING
|
#if VM_PROFILING
|
||||||
if (profile_profiling_active())
|
if (profile_profiling_active())
|
||||||
@ -475,7 +475,7 @@ Common::Error Glulxe::loadGameData(strid_t str) {
|
|||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
return Common::kUnknownError;
|
return Common::kUnknownError;
|
||||||
|
#endif
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ void Hugo::runGame() {
|
|||||||
hugo_closefiles();
|
hugo_closefiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Hugo::loadGameData(strid_t save) {
|
Common::Error Hugo::readSaveData(Common::SeekableReadStream *rs) {
|
||||||
char testid[3], testserial[9];
|
char testid[3], testserial[9];
|
||||||
int lbyte, hbyte;
|
int lbyte, hbyte;
|
||||||
int j;
|
int j;
|
||||||
@ -160,18 +160,18 @@ Common::Error Hugo::loadGameData(strid_t save) {
|
|||||||
long i;
|
long i;
|
||||||
|
|
||||||
/* Check ID */
|
/* Check ID */
|
||||||
testid[0] = (char)hugo_fgetc(save);
|
testid[0] = (char)hugo_fgetc(rs);
|
||||||
testid[1] = (char)hugo_fgetc(save);
|
testid[1] = (char)hugo_fgetc(rs);
|
||||||
testid[2] = '\0';
|
testid[2] = '\0';
|
||||||
if (hugo_ferror(save)) goto RestoreError;
|
if (hugo_ferror(rs)) goto RestoreError;
|
||||||
|
|
||||||
if (strcmp(testid, id)) {
|
if (strcmp(testid, id)) {
|
||||||
GUIErrorMessage("Incorrect save file.");
|
GUIErrorMessage("Incorrect rs file.");
|
||||||
goto RestoreError;
|
goto RestoreError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check serial number */
|
/* Check serial number */
|
||||||
if (!hugo_fgets(testserial, 9, save)) goto RestoreError;
|
if (!hugo_fgets(testserial, 9, rs)) goto RestoreError;
|
||||||
if (strcmp(testserial, serial))
|
if (strcmp(testserial, serial))
|
||||||
{
|
{
|
||||||
GUIErrorMessage("Save file created by different version.");
|
GUIErrorMessage("Save file created by different version.");
|
||||||
@ -181,7 +181,7 @@ Common::Error Hugo::loadGameData(strid_t save) {
|
|||||||
/* Restore variables */
|
/* Restore variables */
|
||||||
for (k=0; k<MAXGLOBALS+MAXLOCALS; k++)
|
for (k=0; k<MAXGLOBALS+MAXLOCALS; k++)
|
||||||
{
|
{
|
||||||
if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
|
if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF)
|
||||||
goto RestoreError;
|
goto RestoreError;
|
||||||
var[k] = lbyte + hbyte * 256;
|
var[k] = lbyte + hbyte * 256;
|
||||||
}
|
}
|
||||||
@ -193,11 +193,11 @@ Common::Error Hugo::loadGameData(strid_t save) {
|
|||||||
|
|
||||||
while (i<codeend-(long)(objtable*16L))
|
while (i<codeend-(long)(objtable*16L))
|
||||||
{
|
{
|
||||||
if ((hbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError;
|
if ((hbyte = hugo_fgetc(rs))==EOF && hugo_ferror(rs)) goto RestoreError;
|
||||||
|
|
||||||
if (hbyte==0)
|
if (hbyte==0)
|
||||||
{
|
{
|
||||||
if ((lbyte = hugo_fgetc(save))==EOF && hugo_ferror(save)) goto RestoreError;
|
if ((lbyte = hugo_fgetc(rs))==EOF && hugo_ferror(rs)) goto RestoreError;
|
||||||
SETMEM(objtable*16L+i, (unsigned char)lbyte);
|
SETMEM(objtable*16L+i, (unsigned char)lbyte);
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
@ -217,28 +217,25 @@ Common::Error Hugo::loadGameData(strid_t save) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Restore undo data */
|
/* Restore undo data */
|
||||||
if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
|
if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF)
|
||||||
goto RestoreError;
|
goto RestoreError;
|
||||||
undosize = lbyte + hbyte*256;
|
undosize = lbyte + hbyte*256;
|
||||||
|
|
||||||
/* We can only restore undo data if it was saved by a port with
|
/* We can only restore undo data if it was saved by a port with
|
||||||
the same MAXUNDO as us */
|
the same MAXUNDO as us */
|
||||||
if (undosize==MAXUNDO)
|
if (undosize == MAXUNDO) {
|
||||||
{
|
for (k = 0; k < MAXUNDO; k++) {
|
||||||
for (k=0; k<MAXUNDO; k++)
|
for (j=0; j<5; j++) {
|
||||||
{
|
if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF)
|
||||||
for (j=0; j<5; j++)
|
|
||||||
{
|
|
||||||
if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF)
|
|
||||||
goto RestoreError;
|
goto RestoreError;
|
||||||
undostack[k][j] = lbyte + hbyte*256;
|
undostack[k][j] = lbyte + hbyte*256;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
|
if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF) goto RestoreError;
|
||||||
undoptr = lbyte + hbyte*256;
|
undoptr = lbyte + hbyte*256;
|
||||||
if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
|
if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF) goto RestoreError;
|
||||||
undoturn = lbyte + hbyte*256;
|
undoturn = lbyte + hbyte*256;
|
||||||
if ((lbyte = hugo_fgetc(save))==EOF || (hbyte = hugo_fgetc(save))==EOF) goto RestoreError;
|
if ((lbyte = hugo_fgetc(rs))==EOF || (hbyte = hugo_fgetc(rs))==EOF) goto RestoreError;
|
||||||
undoinvalid = (unsigned char)lbyte, undorecord = (unsigned char)hbyte;
|
undoinvalid = (unsigned char)lbyte, undorecord = (unsigned char)hbyte;
|
||||||
}
|
}
|
||||||
else undoinvalid = true;
|
else undoinvalid = true;
|
||||||
@ -249,32 +246,31 @@ RestoreError:
|
|||||||
return Common::kReadingFailed;
|
return Common::kReadingFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Hugo::saveGameData(strid_t save, const Common::String &desc) {
|
Common::Error Hugo::writeGameData(Common::WriteStream *ws) {
|
||||||
int c, j;
|
int c, j;
|
||||||
int lbyte, hbyte;
|
int lbyte, hbyte;
|
||||||
long i;
|
long i;
|
||||||
int samecount = 0;
|
int samecount = 0;
|
||||||
|
|
||||||
/* Write ID */
|
/* Write ID */
|
||||||
if (hugo_fputc(id[0], save) == EOF || hugo_fputc(id[1], save) == EOF) goto SaveError;
|
if (hugo_fputc(id[0], ws) == EOF || hugo_fputc(id[1], ws) == EOF) goto SaveError;
|
||||||
|
|
||||||
/* Write serial number */
|
/* Write serial number */
|
||||||
if (hugo_fputs(serial, save) == EOF) goto SaveError;
|
if (hugo_fputs(serial, ws) == EOF) goto SaveError;
|
||||||
|
|
||||||
/* Save variables */
|
/* Save variables */
|
||||||
for (c = 0; c<MAXGLOBALS + MAXLOCALS; c++)
|
for (c = 0; c<MAXGLOBALS + MAXLOCALS; c++)
|
||||||
{
|
{
|
||||||
hbyte = (unsigned int)var[c] / 256;
|
hbyte = (unsigned int)var[c] / 256;
|
||||||
lbyte = (unsigned int)var[c] - hbyte * 256;
|
lbyte = (unsigned int)var[c] - hbyte * 256;
|
||||||
if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF) goto SaveError;
|
if (hugo_fputc(lbyte, ws) == EOF || hugo_fputc(hbyte, ws) == EOF) goto SaveError;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save objtable to end of code space */
|
/* Save objtable to end of code space */
|
||||||
|
|
||||||
if (hugo_fseek(game, objtable * 16L, SEEK_SET)) goto SaveError;
|
if (hugo_fseek(game, objtable * 16L, SEEK_SET)) goto SaveError;
|
||||||
|
|
||||||
for (i = 0; i <= codeend - (long)(objtable * 16L); i++)
|
for (i = 0; i <= codeend - (long)(objtable * 16L); i++) {
|
||||||
{
|
|
||||||
if ((lbyte = hugo_fgetc(game)) == EOF) goto SaveError;
|
if ((lbyte = hugo_fgetc(game)) == EOF) goto SaveError;
|
||||||
hbyte = MEM(objtable * 16L + i);
|
hbyte = MEM(objtable * 16L + i);
|
||||||
|
|
||||||
@ -282,45 +278,42 @@ Common::Error Hugo::saveGameData(strid_t save, const Common::String &desc) {
|
|||||||
if (lbyte == hbyte && samecount<255) samecount++;
|
if (lbyte == hbyte && samecount<255) samecount++;
|
||||||
|
|
||||||
/* If memory differs (or samecount exceeds 1 byte) */
|
/* If memory differs (or samecount exceeds 1 byte) */
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if (samecount)
|
if (samecount)
|
||||||
if (hugo_fputc(samecount, save) == EOF) goto SaveError;
|
if (hugo_fputc(samecount, ws) == EOF) goto SaveError;
|
||||||
|
|
||||||
if (lbyte != hbyte)
|
if (lbyte != hbyte)
|
||||||
{
|
{
|
||||||
if (hugo_fputc(0, save) == EOF) goto SaveError;
|
if (hugo_fputc(0, ws) == EOF) goto SaveError;
|
||||||
if (hugo_fputc(hbyte, save) == EOF) goto SaveError;
|
if (hugo_fputc(hbyte, ws) == EOF) goto SaveError;
|
||||||
samecount = 0;
|
samecount = 0;
|
||||||
}
|
}
|
||||||
else samecount = 1;
|
else samecount = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (samecount)
|
if (samecount)
|
||||||
if (hugo_fputc(samecount, save) == EOF) goto SaveError;
|
if (hugo_fputc(samecount, ws) == EOF) goto SaveError;
|
||||||
|
|
||||||
/* Save undo data */
|
/* Save undo data */
|
||||||
|
|
||||||
/* Save the number of turns in this port's undo stack */
|
/* Save the number of turns in this port's undo stack */
|
||||||
hbyte = (unsigned int)MAXUNDO / 256;
|
hbyte = (unsigned int)MAXUNDO / 256;
|
||||||
lbyte = (unsigned int)MAXUNDO - hbyte * 256;
|
lbyte = (unsigned int)MAXUNDO - hbyte * 256;
|
||||||
if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF)
|
if (hugo_fputc(lbyte, ws) == EOF || hugo_fputc(hbyte, ws) == EOF)
|
||||||
goto SaveError;
|
goto SaveError;
|
||||||
for (c = 0; c<MAXUNDO; c++)
|
for (c = 0; c < MAXUNDO; c++) {
|
||||||
{
|
for (j = 0; j < 5; j++) {
|
||||||
for (j = 0; j<5; j++)
|
|
||||||
{
|
|
||||||
hbyte = (unsigned int)undostack[c][j] / 256;
|
hbyte = (unsigned int)undostack[c][j] / 256;
|
||||||
lbyte = (unsigned int)undostack[c][j] - hbyte * 256;
|
lbyte = (unsigned int)undostack[c][j] - hbyte * 256;
|
||||||
if (hugo_fputc(lbyte, save) == EOF || hugo_fputc(hbyte, save) == EOF)
|
if (hugo_fputc(lbyte, ws) == EOF || hugo_fputc(hbyte, ws) == EOF)
|
||||||
goto SaveError;
|
goto SaveError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hugo_fputc(undoptr - (undoptr / 256) * 256, save) == EOF || hugo_fputc(undoptr / 256, save) == EOF)
|
if (hugo_fputc(undoptr - (undoptr / 256) * 256, ws) == EOF || hugo_fputc(undoptr / 256, ws) == EOF)
|
||||||
goto SaveError;
|
goto SaveError;
|
||||||
if (hugo_fputc(undoturn - (undoturn / 256) * 256, save) == EOF || hugo_fputc(undoturn / 256, save) == EOF)
|
if (hugo_fputc(undoturn - (undoturn / 256) * 256, ws) == EOF || hugo_fputc(undoturn / 256, ws) == EOF)
|
||||||
goto SaveError;
|
goto SaveError;
|
||||||
if (hugo_fputc(undoinvalid, save) == EOF || hugo_fputc(undorecord, save) == EOF)
|
if (hugo_fputc(undoinvalid, ws) == EOF || hugo_fputc(undorecord, ws) == EOF)
|
||||||
goto SaveError;
|
goto SaveError;
|
||||||
|
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
|
@ -1191,14 +1191,15 @@ public:
|
|||||||
virtual InterpreterType getInterpreterType() const override { return INTERPRETER_HUGO; }
|
virtual InterpreterType getInterpreterType() const override { return INTERPRETER_HUGO; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t save) override;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t save, const Common::String &desc) override;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
@ -58,14 +58,14 @@ void Magnetic::runGame() {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Magnetic::loadGameData(strid_t file) {
|
Common::Error Magnetic::readSaveData(Common::SeekableReadStream *rs) {
|
||||||
// TODO
|
// TODO
|
||||||
return Common::kNoError;
|
return Common::kReadingFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Magnetic::saveGameData(strid_t file, const Common::String &desc) {
|
Common::Error Magnetic::writeGameData(Common::WriteStream *ws) {
|
||||||
// TODO
|
// TODO
|
||||||
return Common::kNoError;
|
return Common::kWritingFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Magnetic::is_gamefile_valid() {
|
bool Magnetic::is_gamefile_valid() {
|
||||||
|
@ -191,14 +191,15 @@ public:
|
|||||||
virtual InterpreterType getInterpreterType() const override { return INTERPRETER_MAGNETIC; }
|
virtual InterpreterType getInterpreterType() const override { return INTERPRETER_MAGNETIC; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t file) override;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Magnetic
|
} // End of namespace Magnetic
|
||||||
|
@ -29,15 +29,6 @@
|
|||||||
|
|
||||||
namespace Glk {
|
namespace Glk {
|
||||||
|
|
||||||
static Common::String readString(Common::ReadStream *src) {
|
|
||||||
char c;
|
|
||||||
Common::String result;
|
|
||||||
while ((c = src->readByte()) != 0)
|
|
||||||
result += c;
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void QuetzalReader::clear() {
|
void QuetzalReader::clear() {
|
||||||
_chunks.clear();
|
_chunks.clear();
|
||||||
_stream = nullptr;
|
_stream = nullptr;
|
||||||
@ -141,6 +132,15 @@ bool QuetzalReader::getSavegameMetaInfo(Common::SeekableReadStream *rs, SaveStat
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Common::String QuetzalReader::readString(Common::ReadStream *src) {
|
||||||
|
char c;
|
||||||
|
Common::String result;
|
||||||
|
while ((c = src->readByte()) != 0)
|
||||||
|
result += c;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
Common::WriteStream &QuetzalWriter::add(uint32 chunkId) {
|
Common::WriteStream &QuetzalWriter::add(uint32 chunkId) {
|
||||||
|
@ -143,6 +143,11 @@ public:
|
|||||||
* Loads a Quetzal save and extract's it's description and meta info
|
* Loads a Quetzal save and extract's it's description and meta info
|
||||||
*/
|
*/
|
||||||
static bool getSavegameMetaInfo(Common::SeekableReadStream *rs, SaveStateDescriptor &ssd);
|
static bool getSavegameMetaInfo(Common::SeekableReadStream *rs, SaveStateDescriptor &ssd);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Support method for reading a string from a stream
|
||||||
|
*/
|
||||||
|
static Common::String readString(Common::ReadStream *src);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "glk/scott/scott.h"
|
#include "glk/scott/scott.h"
|
||||||
|
#include "glk/quetzal.h"
|
||||||
#include "common/config-manager.h"
|
#include "common/config-manager.h"
|
||||||
#include "common/translation.h"
|
#include "common/translation.h"
|
||||||
|
|
||||||
@ -508,41 +509,44 @@ void Scott::lineInput(char *buf, size_t n) {
|
|||||||
buf[ev.val1] = 0;
|
buf[ev.val1] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Scott::saveGameData(strid_t file, const Common::String &desc) {
|
Common::Error Scott::writeGameData(Common::WriteStream *ws) {
|
||||||
Common::String msg;
|
Common::String msg;
|
||||||
|
|
||||||
for (int ct = 0; ct < 16; ct++) {
|
for (int ct = 0; ct < 16; ct++) {
|
||||||
msg = Common::String::format("%d %d\n", _counters[ct], _roomSaved[ct]);
|
msg = Common::String::format("%d %d\n", _counters[ct], _roomSaved[ct]);
|
||||||
glk_put_string_stream(file, msg.c_str());
|
ws->write(msg.c_str(), msg.size());
|
||||||
|
ws->writeByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
msg = Common::String::format("%u %d %d %d %d %d\n",
|
msg = Common::String::format("%u %d %d %d %d %d\n",
|
||||||
_bitFlags, (_bitFlags & (1 << DARKBIT)) ? 1 : 0,
|
_bitFlags, (_bitFlags & (1 << DARKBIT)) ? 1 : 0,
|
||||||
MY_LOC, _currentCounter, _savedRoom, _gameHeader._lightTime);
|
MY_LOC, _currentCounter, _savedRoom, _gameHeader._lightTime);
|
||||||
glk_put_string_stream(file, msg.c_str());
|
ws->write(msg.c_str(), msg.size());
|
||||||
|
ws->writeByte(0);
|
||||||
|
|
||||||
for (int ct = 0; ct <= _gameHeader._numItems; ct++) {
|
for (int ct = 0; ct <= _gameHeader._numItems; ct++) {
|
||||||
msg = Common::String::format("%hd\n", (short)_items[ct]._location);
|
msg = Common::String::format("%hd\n", (short)_items[ct]._location);
|
||||||
glk_put_string_stream(file, msg.c_str());
|
ws->write(msg.c_str(), msg.size());
|
||||||
|
ws->writeByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
output(_("Saved.\n"));
|
output(_("Saved.\n"));
|
||||||
return Common::kNoError;
|
return Common::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error Scott::loadGameData(strid_t file) {
|
Common::Error Scott::readSaveData(Common::SeekableReadStream *rs) {
|
||||||
char buf[128];
|
Common::String line;
|
||||||
int ct = 0;
|
int ct = 0;
|
||||||
short lo;
|
short lo;
|
||||||
short darkFlag;
|
short darkFlag;
|
||||||
|
|
||||||
for (ct = 0; ct < 16; ct++) {
|
for (ct = 0; ct < 16; ct++) {
|
||||||
glk_get_line_stream(file, buf, sizeof buf);
|
line = QuetzalReader::readString(rs);
|
||||||
sscanf(buf, "%d %d", &_counters[ct], &_roomSaved[ct]);
|
sscanf(line.c_str(), "%d %d", &_counters[ct], &_roomSaved[ct]);
|
||||||
}
|
}
|
||||||
|
|
||||||
glk_get_line_stream(file, buf, sizeof buf);
|
line = QuetzalReader::readString(rs);
|
||||||
sscanf(buf, "%u %hd %d %d %d %d\n",
|
sscanf(line.c_str(), "%u %hd %d %d %d %d\n",
|
||||||
&_bitFlags, &darkFlag, &MY_LOC, &_currentCounter, &_savedRoom,
|
&_bitFlags, &darkFlag, &MY_LOC, &_currentCounter, &_savedRoom,
|
||||||
&_gameHeader._lightTime);
|
&_gameHeader._lightTime);
|
||||||
|
|
||||||
@ -550,8 +554,8 @@ Common::Error Scott::loadGameData(strid_t file) {
|
|||||||
if (darkFlag)
|
if (darkFlag)
|
||||||
_bitFlags |= (1 << 15);
|
_bitFlags |= (1 << 15);
|
||||||
for (ct = 0; ct <= _gameHeader._numItems; ct++) {
|
for (ct = 0; ct <= _gameHeader._numItems; ct++) {
|
||||||
glk_get_line_stream(file, buf, sizeof buf);
|
line = QuetzalReader::readString(rs);
|
||||||
sscanf(buf, "%hd\n", &lo);
|
sscanf(line.c_str(), "%hd\n", &lo);
|
||||||
_items[ct]._location = (unsigned char)lo;
|
_items[ct]._location = (unsigned char)lo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,14 +177,15 @@ public:
|
|||||||
virtual void runGame() override;
|
virtual void runGame() override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t file) override;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Scott
|
} // End of namespace Scott
|
||||||
|
@ -42,14 +42,14 @@ bool TADS::hasFeature(EngineFeature f) const {
|
|||||||
return GlkAPI::hasFeature(f);
|
return GlkAPI::hasFeature(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error TADS::loadGameData(strid_t file) {
|
Common::Error TADS::readSaveData(Common::SeekableReadStream *rs) {
|
||||||
// TODO
|
// TODO
|
||||||
return Common::kNoError;
|
return Common::kReadingFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Error TADS::saveGameData(strid_t file, const Common::String &desc) {
|
Common::Error TADS::writeGameData(Common::WriteStream *ws) {
|
||||||
// TODO
|
// TODO
|
||||||
return Common::kNoError;
|
return Common::kWritingFailed;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace TADS
|
} // End of namespace TADS
|
||||||
|
@ -54,14 +54,15 @@ public:
|
|||||||
virtual bool hasFeature(EngineFeature f) const override;
|
virtual bool hasFeature(EngineFeature f) const override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load a savegame from the passed stream
|
* Load a savegame from the passed Quetzal file chunk stream
|
||||||
*/
|
*/
|
||||||
virtual Common::Error loadGameData(strid_t file) override;
|
virtual Common::Error readSaveData(Common::SeekableReadStream *rs) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the game to the passed stream
|
* Save the game. The passed write stream represents access to the UMem chunk
|
||||||
|
* in the Quetzal save file that will be created
|
||||||
*/
|
*/
|
||||||
virtual Common::Error saveGameData(strid_t file, const Common::String &desc) override;
|
virtual Common::Error writeGameData(Common::WriteStream *ws) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TADS *g_vm;
|
extern TADS *g_vm;
|
||||||
|
Loading…
Reference in New Issue
Block a user