GOB: save children personal data and completed exercises in Adibou2

child personal data: name, birth date, face sprite
This commit is contained in:
Simon Delamarre 2022-10-29 00:43:38 +02:00 committed by Eugene Sandulenko
parent f104d53bb6
commit 0f95ad760f
No known key found for this signature in database
GPG Key ID: 014D387312D34F08
4 changed files with 400 additions and 26 deletions

View File

@ -661,7 +661,6 @@ protected:
Common::String getFile(const char *path);
private:
bool readSprite(Common::String file, int32 dataVar, int32 size, int32 offset);
};
@ -698,6 +697,8 @@ protected:
void o7_closedBase();
void o7_getDBString();
void o7_readData(OpFuncParams &params);
void o7_oemToANSI(OpGobParams &params);
void o7_gob0x201(OpGobParams &params);

View File

@ -37,6 +37,7 @@
#include "gob/expression.h"
#include "gob/videoplayer.h"
#include "gob/sound/sound.h"
#include "gob/save/saveload.h"
namespace Gob {
@ -81,6 +82,7 @@ void Inter_v7::setupOpcodesDraw() {
void Inter_v7::setupOpcodesFunc() {
Inter_Playtoons::setupOpcodesFunc();
OPCODEFUNC(0x4D, o7_readData);
}
void Inter_v7::setupOpcodesGob() {
@ -635,6 +637,83 @@ void Inter_v7::o7_getDBString() {
WRITE_VAR(27, 1); // Success
}
void Inter_v7::o7_readData(OpFuncParams &params) {
Common::String file = getFile(_vm->_game->_script->evalString());
uint16 dataVar = _vm->_game->_script->readVarIndex();
int32 size = _vm->_game->_script->readValExpr();
int32 offset = _vm->_game->_script->evalInt();
int32 retSize = 0;
debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)",
file.c_str(), dataVar, size, offset);
SaveLoad::SaveMode mode = _vm->_saveLoad->getSaveMode(file.c_str());
if (mode == SaveLoad::kSaveModeSave) {
WRITE_VAR(1, 1);
if (!_vm->_saveLoad->load(file.c_str(), dataVar, size, offset)) {
// Too noisy, the scripts often try to load "save" file not existing (yet)
// GUI::MessageDialog dialog(_("Failed to load saved game from file."));
// dialog.runModal();
} else
WRITE_VAR(1, 0);
return;
} else if (mode == SaveLoad::kSaveModeIgnore)
return;
if (size < 0) {
if (readSprite(file, dataVar, size, offset))
WRITE_VAR(1, 0);
return;
} else if (size == 0) {
dataVar = 0;
size = _vm->_game->_script->getVariablesCount() * 4;
}
byte *buf = _variables->getAddressOff8(dataVar);
if (file[0] == 0) {
WRITE_VAR(1, size);
return;
}
WRITE_VAR(1, 1);
Common::SeekableReadStream *stream = _vm->_dataIO->getFile(file);
if (!stream)
return;
_vm->_draw->animateCursor(4);
if (offset > stream->size()) {
warning("oPlaytoons_readData: File \"%s\", Offset (%d) > file size (%d)",
file.c_str(), offset, (int)stream->size());
delete stream;
return;
}
if (offset < 0)
stream->seek(offset + 1, SEEK_END);
else
stream->seek(offset);
if (((dataVar >> 2) == 59) && (size == 4)) {
WRITE_VAR(59, stream->readUint32LE());
// The scripts in some versions divide through 256^3 then,
// effectively doing a LE->BE conversion
if ((_vm->getPlatform() != Common::kPlatformDOS) && (VAR(59) < 256))
WRITE_VAR(59, SWAP_BYTES_32(VAR(59)));
} else
retSize = stream->read(buf, size);
if (retSize == size)
WRITE_VAR(1, 0);
delete stream;
}
void Inter_v7::o7_oemToANSI(OpGobParams &params) {
_vm->_game->_script->skip(2);
}

View File

@ -888,10 +888,11 @@ protected:
SaveFile *getSaveFile(const char *fileName);
};
/** Save/Load class for Playtoons. */
/** Save/Load class for Adibou 2/Adi. */
class SaveLoad_v7: public SaveLoad {
public:
static const uint32 kChildrenCount = 16;
static const uint32 kAdibou2NbrOfApplications = 5;
SaveLoad_v7(GobEngine *vm, const char *targetName);
~SaveLoad_v7() override;
@ -906,12 +907,51 @@ protected:
const char *description;
};
class FaceHandler : public TempSpriteHandler {
public:
FaceHandler(GobEngine *vm, const Common::String &target, const Common::String &ext);
~FaceHandler() override;
int32 getSize() override;
bool load(int16 dataVar, int32 size, int32 offset) override;
bool save(int16 dataVar, int32 size, int32 offset) override;
private:
class File : public SlotFileStatic {
public:
File(GobEngine *vm, const Common::String &base, const Common::String &ext);
~File() override;
};
File _file;
};
class GameFileHandler : public SaveHandler {
public:
GameFileHandler(GobEngine *vm, const Common::String &target, const Common::String &ext);
~GameFileHandler() override;
int32 getSize() override;
bool load(int16 dataVar, int32 size, int32 offset) override;
bool save(int16 dataVar, int32 size, int32 offset) override;
private:
class File : public SlotFileStatic {
public:
File(GobEngine *vm, const Common::String &base, const Common::String &ext);
~File() override;
};
File _file;
};
static SaveFile _saveFiles[];
TempSpriteHandler *_faceHandler[kChildrenCount];
FaceHandler *_faceHandler[kChildrenCount];
FakeFileHandler *_childrenHandler;
FakeFileHandler *_debilHandler;
FakeFileHandler *_configHandler;
GameFileHandler *_configHandler;
GameFileHandler *_adibou2AppProgressHandler[kChildrenCount][kAdibou2NbrOfApplications];
FakeFileHandler *_addy4BaseHandler[2];
FakeFileHandler *_addy4GrundschuleHandler[11];

View File

@ -45,41 +45,289 @@ SaveLoad_v7::SaveFile SaveLoad_v7::_saveFiles[] = {
{"visage15.inf", kSaveModeSave, nullptr, "face" }, // Child 15
{"visage16.inf", kSaveModeSave, nullptr, "face" }, // Child 16
{ "enfant.inf", kSaveModeSave, nullptr, "children" },
{ "debil.tmp", kSaveModeSave, nullptr, nullptr },
{ "debil.tmp", kSaveModeSave, nullptr, nullptr },
{ "config.inf", kSaveModeSave, nullptr, "configuration"},
// Addy 4 Base
{"config00.inf", kSaveModeSave, nullptr, nullptr },
{"statev00.inf", kSaveModeSave, nullptr, nullptr },
// Adibou Applications 1-5
{"Gsa01_01.inf", kSaveModeSave, nullptr, "app progress" }, // Child 01
{"Gsa02_01.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_01.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_01.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_01.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_02.inf", kSaveModeSave, nullptr, "app progress" }, // Child 02
{"Gsa02_02.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_02.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_02.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_02.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_03.inf", kSaveModeSave, nullptr, "app progress" }, // Child 03
{"Gsa02_03.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_03.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_03.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_03.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_04.inf", kSaveModeSave, nullptr, "app progress" }, // Child 04
{"Gsa02_04.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_04.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_04.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_04.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_05.inf", kSaveModeSave, nullptr, "app progress" }, // Child 05
{"Gsa02_05.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_05.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_05.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_05.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_06.inf", kSaveModeSave, nullptr, "app progress" }, // Child 06
{"Gsa02_06.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_06.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_06.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_06.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_07.inf", kSaveModeSave, nullptr, "app progress" }, // Child 07
{"Gsa02_07.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_07.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_07.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_07.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_08.inf", kSaveModeSave, nullptr, "app progress" }, // Child 08
{"Gsa02_08.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_08.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_08.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_08.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_09.inf", kSaveModeSave, nullptr, "app progress" }, // Child 09
{"Gsa02_09.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_09.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_09.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_09.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_10.inf", kSaveModeSave, nullptr, "app progress" }, // Child 10
{"Gsa02_10.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_10.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_10.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_10.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_11.inf", kSaveModeSave, nullptr, "app progress" }, // Child 11
{"Gsa02_11.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_11.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_11.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_11.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_12.inf", kSaveModeSave, nullptr, "app progress" }, // Child 12
{"Gsa02_12.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_12.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_12.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_12.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_13.inf", kSaveModeSave, nullptr, "app progress" }, // Child 13
{"Gsa02_13.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_13.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_13.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_13.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_14.inf", kSaveModeSave, nullptr, "app progress" }, // Child 14
{"Gsa02_14.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_14.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_14.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_14.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_15.inf", kSaveModeSave, nullptr, "app progress" }, // Child 15
{"Gsa02_15.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_15.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_15.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_15.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa01_16.inf", kSaveModeSave, nullptr, "app progress" }, // Child 16
{"Gsa02_16.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa03_16.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa04_16.inf", kSaveModeSave, nullptr, "app progress" },
{"Gsa05_16.inf", kSaveModeSave, nullptr, "app progress" },
// Addy 4 Base
{"config00.inf", kSaveModeSave, nullptr, nullptr },
{"statev00.inf", kSaveModeSave, nullptr, nullptr },
// Addy 4 Grundschule
{ "premier.dep", kSaveModeSave, nullptr, nullptr },
{ "quitter.dep", kSaveModeSave, nullptr, nullptr },
{ "appel.dep", kSaveModeSave, nullptr, nullptr },
{ "parole.dep", kSaveModeSave, nullptr, nullptr },
{ "ado4.inf", kSaveModeSave, nullptr, nullptr },
{"mcurrent.inf", kSaveModeSave, nullptr, nullptr },
{ "perso.dep", kSaveModeSave, nullptr, nullptr },
{ "nouveau.dep", kSaveModeSave, nullptr, nullptr },
{ "adi.tmp", kSaveModeSave, nullptr, nullptr },
{ "adi.inf", kSaveModeSave, nullptr, nullptr },
{ "adi4.tmp", kSaveModeSave, nullptr, nullptr }
{ "premier.dep", kSaveModeSave, nullptr, nullptr },
{ "quitter.dep", kSaveModeSave, nullptr, nullptr },
{ "appel.dep", kSaveModeSave, nullptr, nullptr },
{ "parole.dep", kSaveModeSave, nullptr, nullptr },
{ "ado4.inf", kSaveModeSave, nullptr, nullptr },
{"mcurrent.inf", kSaveModeSave, nullptr, nullptr },
{ "perso.dep", kSaveModeSave, nullptr, nullptr },
{ "nouveau.dep", kSaveModeSave, nullptr, nullptr },
{ "adi.tmp", kSaveModeSave, nullptr, nullptr },
{ "adi.inf", kSaveModeSave, nullptr, nullptr },
{ "adi4.tmp", kSaveModeSave, nullptr, nullptr }
};
SaveLoad_v7::FaceHandler::File::File(GobEngine *vm, const Common::String &base, const Common::String &ext) :
SlotFileStatic(vm, base, ext) {
}
SaveLoad_v7::FaceHandler::File::~File() {
}
SaveLoad_v7::FaceHandler::FaceHandler(GobEngine *vm, const Common::String &target, const Common::String &ext)
: TempSpriteHandler(vm), _file(vm, target, ext) {
}
SaveLoad_v7::FaceHandler::~FaceHandler() {
}
int32 SaveLoad_v7::FaceHandler::getSize() {
Common::String fileName = _file.build();
if (fileName.empty())
return -1;;
SaveReader reader(1, 0, fileName);
SaveHeader header;
if (!reader.load())
return -1;
if (!reader.readPartHeader(0, &header))
return -1;
// Return the part's size
return header.getSize();
}
bool SaveLoad_v7::FaceHandler::load(int16 dataVar, int32 size, int32 offset)
{
if (!TempSpriteHandler::createFromSprite(dataVar, size, offset))
return false;
Common::String fileName = _file.build();
if (fileName.empty())
return false;
SaveReader reader(1, 0, fileName);
if (!reader.load())
return false;
if (!reader.readPart(0, _sprite))
return false;
return TempSpriteHandler::load(dataVar, size, offset);
}
bool SaveLoad_v7::FaceHandler::save(int16 dataVar, int32 size, int32 offset)
{
if (!TempSpriteHandler::save(dataVar, size, offset))
return false;
Common::String fileName = _file.build();
if (fileName.empty())
return false;
SaveWriter writer(1, 0, fileName);
return writer.writePart(0, _sprite);
}
SaveLoad_v7::GameFileHandler::File::File(GobEngine *vm, const Common::String &base, const Common::String &ext) :
SlotFileStatic(vm, base, ext) {
}
SaveLoad_v7::GameFileHandler::File::~File() {
}
SaveLoad_v7::GameFileHandler::GameFileHandler(GobEngine *vm, const Common::String &target, const Common::String &ext) :
SaveHandler(vm), _file(vm, target, ext) {
}
SaveLoad_v7::GameFileHandler::~GameFileHandler() {
}
int32 SaveLoad_v7::GameFileHandler::getSize() {
Common::String fileName = _file.build();
if (fileName.empty())
return -1;
SaveReader reader(1, 0, fileName);
SaveHeader header;
if (!reader.load())
return -1;
if (!reader.readPartHeader(0, &header))
return -1;
// Return the part's size
return header.getSize();
}
bool SaveLoad_v7::GameFileHandler::load(int16 dataVar, int32 size, int32 offset) {
Common::String fileName = _file.build();
if (fileName.empty())
return false;
uint32 varSize = SaveHandler::getVarSize(_vm);
if (size == 0) {
// Indicator to load all variables
dataVar = 0;
size = (int32) varSize;
}
SaveReader reader(1, 0, fileName);
SavePartVars vars(_vm, size);
if (!reader.load()) {
return false;
}
if (!reader.readPart(0, &vars)) {
return false;
}
if (!vars.writeInto((uint16) dataVar, offset, size)) {
return false;
}
return true;
}
bool SaveLoad_v7::GameFileHandler::save(int16 dataVar, int32 size, int32 offset) {
Common::String fileName = _file.build();
if (fileName.empty())
return false;
uint32 varSize = SaveHandler::getVarSize(_vm);
if (size == 0) {
// Indicator to save all variables
dataVar = 0;
size = (int32) varSize;
}
SaveWriter writer(1, 0, fileName);
SavePartVars vars(_vm, size);
if (!vars.readFrom((uint16) dataVar, offset, size))
return false;
return writer.writePart(0, &vars);
}
SaveLoad_v7::SaveLoad_v7(GobEngine *vm, const char *targetName) :
SaveLoad(vm) {
for (uint32 i = 0; i < kChildrenCount; i++)
_saveFiles[i].handler = _faceHandler[i] = new TempSpriteHandler(_vm);
uint32 index = 0;
for (uint32 i = 0; i < kChildrenCount; i++) {
_saveFiles[index++].handler = _faceHandler[i] = new FaceHandler(_vm,
targetName,
Common::String::format("vsg%02d", i + 1));
}
_saveFiles[16].handler = _childrenHandler = new FakeFileHandler(_vm);
_saveFiles[17].handler = _debilHandler = new FakeFileHandler(_vm);
_saveFiles[18].handler = _configHandler = new FakeFileHandler(_vm);
_saveFiles[index++].handler = _childrenHandler = new FakeFileHandler(_vm);
_saveFiles[index++].handler = _debilHandler = new FakeFileHandler(_vm);
_saveFiles[index++].handler = _configHandler = new GameFileHandler(_vm, targetName, "cfg");
for (uint32 i = 0; i < kChildrenCount; i++)
{
for (uint32 j = 0; j < kAdibou2NbrOfApplications; j++)
{
Common::String ext = Common::String::format("gsa%02d_%02d", j + 1, i + 1);
_saveFiles[index++].handler = _adibou2AppProgressHandler[i][j] = new GameFileHandler(_vm,
targetName,
ext);
}
}
for (int i = 0; i < 2; i++)
_saveFiles[19 + i].handler = _addy4BaseHandler[i] = new FakeFileHandler(_vm);
_saveFiles[index++].handler = _addy4BaseHandler[i] = new FakeFileHandler(_vm);
for (int i = 0; i < 11; i++)
_saveFiles[21 + i].handler = _addy4GrundschuleHandler[i] = new FakeFileHandler(_vm);
_saveFiles[index++].handler = _addy4GrundschuleHandler[i] = new FakeFileHandler(_vm);
}
SaveLoad_v7::~SaveLoad_v7() {
@ -93,6 +341,12 @@ SaveLoad_v7::~SaveLoad_v7() {
delete _debilHandler;
delete _childrenHandler;
for (uint32 i = 0; i < kChildrenCount; i++)
{
for (uint32 j = 0; j < kAdibou2NbrOfApplications; j++)
delete _adibou2AppProgressHandler[i][j];
}
for (uint32 i = 0; i < kChildrenCount; i++)
delete _faceHandler[i];
}