SCI32: Implement kSave for standard-save SCI32 games
Games with custom save code (KQ7, MGDX, PQ:SWAT, Shivers) are not fully supported yet.
This commit is contained in:
parent
a22bfb0db2
commit
10f450917c
3 changed files with 39 additions and 29 deletions
|
@ -484,11 +484,12 @@ reg_t kShowMovieWinPlayUntilEvent(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kShowMovieWinInitDouble(EngineState *s, int argc, reg_t *argv);
|
reg_t kShowMovieWinInitDouble(EngineState *s, int argc, reg_t *argv);
|
||||||
|
|
||||||
reg_t kSave(EngineState *s, int argc, reg_t *argv);
|
reg_t kSave(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kSaveSave32(EngineState *s, int argc, reg_t *argv);
|
reg_t kSaveGame32(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kSaveRestore32(EngineState *s, int argc, reg_t *argv);
|
reg_t kRestoreGame32(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kSaveList32(EngineState *s, int argc, reg_t *argv);
|
reg_t kGetSaveFiles32(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kSaveCheck32(EngineState *s, int argc, reg_t *argv);
|
reg_t kCheckSaveGame32(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kSaveMakeFileName32(EngineState *s, int argc, reg_t *argv);
|
reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv);
|
||||||
|
reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv);
|
||||||
|
|
||||||
reg_t kSetHotRectangles(EngineState *s, int argc, reg_t *argv);
|
reg_t kSetHotRectangles(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv);
|
reg_t kIsHiRes(EngineState *s, int argc, reg_t *argv);
|
||||||
|
@ -591,8 +592,6 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv);
|
reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv);
|
||||||
|
|
||||||
reg_t kEditText(EngineState *s, int argc, reg_t *argv);
|
reg_t kEditText(EngineState *s, int argc, reg_t *argv);
|
||||||
reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv);
|
|
||||||
reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv);
|
|
||||||
reg_t kSetScroll(EngineState *s, int argc, reg_t *argv);
|
reg_t kSetScroll(EngineState *s, int argc, reg_t *argv);
|
||||||
|
|
||||||
reg_t kPaletteSetFromResource32(EngineState *s, int argc, reg_t *argv);
|
reg_t kPaletteSetFromResource32(EngineState *s, int argc, reg_t *argv);
|
||||||
|
|
|
@ -351,18 +351,18 @@ static const SciKernelMapSubEntry kPalCycle_subops[] = {
|
||||||
|
|
||||||
// version, subId, function-mapping, signature, workarounds
|
// version, subId, function-mapping, signature, workarounds
|
||||||
static const SciKernelMapSubEntry kSave_subops[] = {
|
static const SciKernelMapSubEntry kSave_subops[] = {
|
||||||
{ SIG_SCI32, 0, MAP_CALL(SaveSave32), "rir[r0]", NULL },
|
{ SIG_SCI32, 0, MAP_CALL(SaveGame32), "rir[r0]", NULL },
|
||||||
{ SIG_SCI32, 1, MAP_CALL(SaveRestore32), "ri[r0]", NULL },
|
{ SIG_SCI32, 1, MAP_CALL(RestoreGame32), "ri[r0]", NULL },
|
||||||
// System script 64994 in several SCI2.1mid games (KQ7 2.00b, Phant1,
|
// System script 64994 in several SCI2.1mid games (KQ7 2.00b, Phant1,
|
||||||
// PQ:SWAT, SQ6, Torin) calls GetSaveDir with an extra unused argument, and
|
// PQ:SWAT, SQ6, Torin) calls GetSaveDir with an extra unused argument, and
|
||||||
// it is easier to just handle it here than to bother with creating
|
// it is easier to just handle it here than to bother with creating
|
||||||
// workarounds
|
// workarounds
|
||||||
{ SIG_SCI32, 2, MAP_CALL(GetSaveDir), "(r)", NULL },
|
{ SIG_SCI32, 2, MAP_CALL(GetSaveDir), "(r)", NULL },
|
||||||
{ SIG_SCI32, 3, MAP_CALL(SaveCheck32), "ri[r0]", NULL },
|
{ SIG_SCI32, 3, MAP_CALL(CheckSaveGame32), "ri[r0]", NULL },
|
||||||
// Subop 4 hasn't been encountered yet
|
// Subop 4 hasn't been encountered yet
|
||||||
{ SIG_SCI32, 5, MAP_CALL(SaveList32), "rrr", NULL },
|
{ SIG_SCI32, 5, MAP_CALL(GetSaveFiles32), "rrr", NULL },
|
||||||
{ SIG_SCI32, 6, MAP_CALL(MakeSaveCatName), "rr", NULL },
|
{ SIG_SCI32, 6, MAP_CALL(MakeSaveCatName), "rr", NULL },
|
||||||
{ SIG_SCI32, 7, MAP_CALL(SaveMakeFileName32), "rri", NULL },
|
{ SIG_SCI32, 7, MAP_CALL(MakeSaveFileName), "rri", NULL },
|
||||||
{ SIG_SCI32, 8, MAP_EMPTY(GameIsRestarting), ".*", NULL },
|
{ SIG_SCI32, 8, MAP_EMPTY(GameIsRestarting), ".*", NULL },
|
||||||
SCI_SUBOPENTRY_TERMINATOR
|
SCI_SUBOPENTRY_TERMINATOR
|
||||||
};
|
};
|
||||||
|
@ -633,7 +633,7 @@ static SciKernelMapEntry s_kernelMap[] = {
|
||||||
{ MAP_CALL(CheckFreeSpace), SIG_SCI11, SIGFOR_ALL, "r(i)", NULL, NULL },
|
{ MAP_CALL(CheckFreeSpace), SIG_SCI11, SIGFOR_ALL, "r(i)", NULL, NULL },
|
||||||
{ MAP_CALL(CheckFreeSpace), SIG_SCI16, SIGFOR_ALL, "r", NULL, NULL },
|
{ MAP_CALL(CheckFreeSpace), SIG_SCI16, SIGFOR_ALL, "r", NULL, NULL },
|
||||||
#ifdef ENABLE_SCI32
|
#ifdef ENABLE_SCI32
|
||||||
{ "CheckSaveGame", kSaveCheck32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "ri[r0]", NULL, NULL },
|
{ "CheckSaveGame", kCheckSaveGame32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "ri[r0]", NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
{ MAP_CALL(CheckSaveGame), SIG_SCI16, SIGFOR_ALL, ".*", NULL, NULL },
|
{ MAP_CALL(CheckSaveGame), SIG_SCI16, SIGFOR_ALL, ".*", NULL, NULL },
|
||||||
{ MAP_CALL(Clone), SIG_EVERYWHERE, "o", NULL, NULL },
|
{ MAP_CALL(Clone), SIG_EVERYWHERE, "o", NULL, NULL },
|
||||||
|
@ -690,7 +690,7 @@ static SciKernelMapEntry s_kernelMap[] = {
|
||||||
#endif
|
#endif
|
||||||
{ MAP_CALL(GetSaveDir), SIG_SCI16, SIGFOR_ALL, "", NULL, NULL },
|
{ MAP_CALL(GetSaveDir), SIG_SCI16, SIGFOR_ALL, "", NULL, NULL },
|
||||||
#ifdef ENABLE_SCI32
|
#ifdef ENABLE_SCI32
|
||||||
{ "GetSaveFiles", kSaveList32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "rrr", NULL, NULL },
|
{ "GetSaveFiles", kGetSaveFiles32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "rrr", NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
{ MAP_CALL(GetSaveFiles), SIG_EVERYWHERE, "rrr", NULL, NULL },
|
{ MAP_CALL(GetSaveFiles), SIG_EVERYWHERE, "rrr", NULL, NULL },
|
||||||
{ MAP_CALL(GetTime), SIG_EVERYWHERE, "(i)", NULL, NULL },
|
{ MAP_CALL(GetTime), SIG_EVERYWHERE, "(i)", NULL, NULL },
|
||||||
|
@ -754,12 +754,12 @@ static SciKernelMapEntry s_kernelMap[] = {
|
||||||
{ MAP_CALL(RespondsTo), SIG_EVERYWHERE, ".i", NULL, NULL },
|
{ MAP_CALL(RespondsTo), SIG_EVERYWHERE, ".i", NULL, NULL },
|
||||||
{ MAP_CALL(RestartGame), SIG_EVERYWHERE, "", NULL, NULL },
|
{ MAP_CALL(RestartGame), SIG_EVERYWHERE, "", NULL, NULL },
|
||||||
#ifdef ENABLE_SCI32
|
#ifdef ENABLE_SCI32
|
||||||
{ "RestoreGame", kSaveRestore32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "ri[r0]", NULL, NULL },
|
{ "RestoreGame", kRestoreGame32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "ri[r0]", NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
{ MAP_CALL(RestoreGame), SIG_EVERYWHERE, "[r0]i[r0]", NULL, NULL },
|
{ MAP_CALL(RestoreGame), SIG_EVERYWHERE, "[r0]i[r0]", NULL, NULL },
|
||||||
{ MAP_CALL(Said), SIG_EVERYWHERE, "[r0]", NULL, NULL },
|
{ MAP_CALL(Said), SIG_EVERYWHERE, "[r0]", NULL, NULL },
|
||||||
#ifdef ENABLE_SCI32
|
#ifdef ENABLE_SCI32
|
||||||
{ "SaveGame", kSaveSave32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "rir[r0]", NULL, NULL },
|
{ "SaveGame", kSaveGame32, SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "rir[r0]", NULL, NULL },
|
||||||
#endif
|
#endif
|
||||||
{ MAP_CALL(SaveGame), SIG_SCI16, SIGFOR_ALL, "[r0]i[r0](r0)", NULL, NULL },
|
{ MAP_CALL(SaveGame), SIG_SCI16, SIGFOR_ALL, "[r0]i[r0](r0)", NULL, NULL },
|
||||||
{ MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL },
|
{ MAP_CALL(ScriptID), SIG_EVERYWHERE, "[io](i)", NULL, NULL },
|
||||||
|
@ -870,8 +870,8 @@ static SciKernelMapEntry s_kernelMap[] = {
|
||||||
{ MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
|
{ MAP_CALL(UpdateScreenItem), SIG_EVERYWHERE, "o", NULL, NULL },
|
||||||
{ MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL },
|
{ MAP_CALL(ObjectIntersect), SIG_EVERYWHERE, "oo", NULL, NULL },
|
||||||
{ MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL },
|
{ MAP_CALL(EditText), SIG_EVERYWHERE, "o", NULL, NULL },
|
||||||
{ MAP_CALL(MakeSaveCatName), SIG_EVERYWHERE, "rr", NULL, NULL },
|
{ MAP_CALL(MakeSaveCatName), SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "rr", NULL, NULL },
|
||||||
{ "MakeSaveFileName", kSaveMakeFileName32, SIG_UNTIL_SCI21MID, SIGFOR_ALL, "rri", NULL, NULL },
|
{ MAP_CALL(MakeSaveFileName), SIG_UNTIL_SCI21EARLY, SIGFOR_ALL, "rri", NULL, NULL },
|
||||||
{ MAP_CALL(SetScroll), SIG_EVERYWHERE, "oiiii(i)(i)", NULL, NULL },
|
{ MAP_CALL(SetScroll), SIG_EVERYWHERE, "oiiii(i)(i)", NULL, NULL },
|
||||||
{ MAP_CALL(PalCycle), SIG_EVERYWHERE, "(.*)", kPalCycle_subops, NULL },
|
{ MAP_CALL(PalCycle), SIG_EVERYWHERE, "(.*)", kPalCycle_subops, NULL },
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,12 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
|
||||||
return SIGNAL_REG;
|
return SIGNAL_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SCI32
|
||||||
|
// See kMakeSaveCatName
|
||||||
|
if (name == "fake.cat") {
|
||||||
|
return make_reg(0, VIRTUALFILE_HANDLE_SCI32SAVE);
|
||||||
|
}
|
||||||
|
|
||||||
// Torin's autosave system checks for the presence of autosave.cat
|
// Torin's autosave system checks for the presence of autosave.cat
|
||||||
// by opening it. Since we don't use .cat files, we instead check
|
// by opening it. Since we don't use .cat files, we instead check
|
||||||
// for the autosave game.
|
// for the autosave game.
|
||||||
|
@ -285,6 +291,7 @@ reg_t kFileIOOpen(EngineState *s, int argc, reg_t *argv) {
|
||||||
return SIGNAL_REG;
|
return SIGNAL_REG;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
// Happens many times during KQ1 (e.g. when typing something)
|
// Happens many times during KQ1 (e.g. when typing something)
|
||||||
|
@ -1039,7 +1046,7 @@ reg_t kGetSaveFiles(EngineState *s, int argc, reg_t *argv) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_SCI32
|
#ifdef ENABLE_SCI32
|
||||||
reg_t kSaveSave32(EngineState *s, int argc, reg_t *argv) {
|
reg_t kSaveGame32(EngineState *s, int argc, reg_t *argv) {
|
||||||
const Common::String gameName = s->_segMan->getString(argv[0]);
|
const Common::String gameName = s->_segMan->getString(argv[0]);
|
||||||
int16 saveNo = argv[1].toSint16();
|
int16 saveNo = argv[1].toSint16();
|
||||||
const Common::String saveDescription = s->_segMan->getString(argv[2]);
|
const Common::String saveDescription = s->_segMan->getString(argv[2]);
|
||||||
|
@ -1111,7 +1118,7 @@ reg_t kSaveSave32(EngineState *s, int argc, reg_t *argv) {
|
||||||
return TRUE_REG;
|
return TRUE_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_t kSaveRestore32(EngineState *s, int argc, reg_t *argv) {
|
reg_t kRestoreGame32(EngineState *s, int argc, reg_t *argv) {
|
||||||
const Common::String gameName = s->_segMan->getString(argv[0]);
|
const Common::String gameName = s->_segMan->getString(argv[0]);
|
||||||
int16 saveNo = argv[1].toSint16();
|
int16 saveNo = argv[1].toSint16();
|
||||||
const Common::String gameVersion = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]);
|
const Common::String gameVersion = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]);
|
||||||
|
@ -1141,7 +1148,7 @@ reg_t kSaveRestore32(EngineState *s, int argc, reg_t *argv) {
|
||||||
return TRUE_REG;
|
return TRUE_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_t kSaveCheck32(EngineState *s, int argc, reg_t *argv) {
|
reg_t kCheckSaveGame32(EngineState *s, int argc, reg_t *argv) {
|
||||||
const Common::String gameName = s->_segMan->getString(argv[0]);
|
const Common::String gameName = s->_segMan->getString(argv[0]);
|
||||||
int16 saveNo = argv[1].toSint16();
|
int16 saveNo = argv[1].toSint16();
|
||||||
const Common::String gameVersion = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]);
|
const Common::String gameVersion = argv[2].isNull() ? "" : s->_segMan->getString(argv[2]);
|
||||||
|
@ -1168,7 +1175,7 @@ reg_t kSaveCheck32(EngineState *s, int argc, reg_t *argv) {
|
||||||
return TRUE_REG;
|
return TRUE_REG;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_t kSaveList32(EngineState *s, int argc, reg_t *argv) {
|
reg_t kGetSaveFiles32(EngineState *s, int argc, reg_t *argv) {
|
||||||
// argv[0] is gameName, used in SSCI as the name of the save game catalogue
|
// argv[0] is gameName, used in SSCI as the name of the save game catalogue
|
||||||
// but unused here since ScummVM does not support multiple catalogues
|
// but unused here since ScummVM does not support multiple catalogues
|
||||||
SciArray &descriptions = *s->_segMan->lookupArray(argv[1]);
|
SciArray &descriptions = *s->_segMan->lookupArray(argv[1]);
|
||||||
|
@ -1179,8 +1186,8 @@ reg_t kSaveList32(EngineState *s, int argc, reg_t *argv) {
|
||||||
|
|
||||||
// Normally SSCI limits to 20 games per directory, but ScummVM allows more
|
// Normally SSCI limits to 20 games per directory, but ScummVM allows more
|
||||||
// than that
|
// than that
|
||||||
descriptions.resize(SCI_MAX_SAVENAME_LENGTH * saves.size() + 1);
|
descriptions.resize(SCI_MAX_SAVENAME_LENGTH * saves.size() + 1, true);
|
||||||
saveIds.resize(saves.size());
|
saveIds.resize(saves.size(), true);
|
||||||
|
|
||||||
for (uint i = 0; i < saves.size(); ++i) {
|
for (uint i = 0; i < saves.size(); ++i) {
|
||||||
const SavegameDesc &save = saves[i];
|
const SavegameDesc &save = saves[i];
|
||||||
|
@ -1189,18 +1196,22 @@ reg_t kSaveList32(EngineState *s, int argc, reg_t *argv) {
|
||||||
saveIds.int16At(i) = save.id;
|
saveIds.int16At(i) = save.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
descriptions.charAt(SCI_MAX_SAVENAME_LENGTH * saves.size()) = '\0';
|
||||||
|
|
||||||
return make_reg(0, saves.size());
|
return make_reg(0, saves.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv) {
|
reg_t kMakeSaveCatName(EngineState *s, int argc, reg_t *argv) {
|
||||||
// Normally, this creates the name of the save catalogue/directory to save into.
|
// ScummVM does not use SCI catalogues for save games, but game scripts try
|
||||||
// First parameter is the string to save the result into. Second is a string
|
// to write out catalogues manually after a save game is deleted, so we need
|
||||||
// with game parameters. We don't have a use for this at all, as we have our own
|
// to be able to identify and ignore these IO operations by always giving
|
||||||
// savegame directory management, thus we always return an empty string.
|
// back a fixed catalogue name and then ignoring it in kFileIO
|
||||||
|
SciArray &outCatName = *s->_segMan->lookupArray(argv[0]);
|
||||||
|
outCatName.fromString("fake.cat");
|
||||||
return argv[0];
|
return argv[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
reg_t kSaveMakeFileName32(EngineState *s, int argc, reg_t *argv) {
|
reg_t kMakeSaveFileName(EngineState *s, int argc, reg_t *argv) {
|
||||||
SciArray &outFileName = *s->_segMan->lookupArray(argv[0]);
|
SciArray &outFileName = *s->_segMan->lookupArray(argv[0]);
|
||||||
// argv[1] is the game name, which is not used by ScummVM
|
// argv[1] is the game name, which is not used by ScummVM
|
||||||
int16 saveNo = argv[2].toSint16();
|
int16 saveNo = argv[2].toSint16();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue