diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/gob/inter.h | 2 | ||||
-rw-r--r-- | engines/gob/inter_playtoons.cpp | 118 |
2 files changed, 117 insertions, 3 deletions
diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 057f52b360..43a4941402 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -557,7 +557,9 @@ protected: virtual void setupOpcodesFunc(); virtual void setupOpcodesGob(); + bool oPlaytoons_F_1B(OpFuncParams ¶ms); bool oPlaytoons_checkData(OpFuncParams ¶ms); + bool oPlaytoons_readData(OpFuncParams ¶ms); void oPlaytoons_CD_20_23(); void oPlaytoons_CD_25(); void oPlaytoons_openItk(); diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp index e224f29734..d7cb6b79c2 100644 --- a/engines/gob/inter_playtoons.cpp +++ b/engines/gob/inter_playtoons.cpp @@ -25,6 +25,8 @@ #include "common/endian.h" +#include "gui/message.h" + #include "gob/gob.h" #include "gob/inter.h" #include "gob/helper.h" @@ -77,12 +79,33 @@ void Inter_Playtoons::setupOpcodesDraw() { void Inter_Playtoons::setupOpcodesFunc() { Inter_v6::setupOpcodesFunc(); + OPCODEFUNC(0x1B, oPlaytoons_F_1B); OPCODEFUNC(0x3F, oPlaytoons_checkData); + OPCODEFUNC(0x4D, oPlaytoons_readData); } void Inter_Playtoons::setupOpcodesGob() { } +bool Inter_Playtoons::oPlaytoons_F_1B(OpFuncParams ¶ms) { + int16 var1; + int16 var2; + int16 var3; + int16 var4; + + var1 = _vm->_game->_script->readValExpr(); + var2 = _vm->_game->_script->readValExpr(); + + _vm->_game->_script->evalExpr(0); + + var3 = _vm->_game->_script->readValExpr(); + var4 = _vm->_game->_script->readValExpr(); + + warning("oPlaytoons_F_1B not handled"); + + return false; +} + bool Inter_Playtoons::oPlaytoons_checkData(OpFuncParams ¶ms) { int16 handle; int16 varOff; @@ -101,18 +124,16 @@ bool Inter_Playtoons::oPlaytoons_checkData(OpFuncParams ¶ms) { // In this case, "@:\" is replaced by the CD drive letter. // As the files are copied on the HDD, those characters are skipped. if (strncmp(file, "@:\\", 3) == 0) { - debugC(2, kDebugFileIO, "File check: \"%s\" instead of \"%s\"", file + 3, file); + debugC(2, kDebugFileIO, "oPlaytoons_checkData: \"%s\" instead of \"%s\"", file + 3, file); file += 3; } mode = _vm->_saveLoad->getSaveMode(file); if (mode == SaveLoad::kSaveModeNone) { - if (_vm->_dataIO->existData(file)) size = _vm->_dataIO->getDataSize(file); else warning("File \"%s\" not found", file); - } else if (mode == SaveLoad::kSaveModeSave) size = _vm->_saveLoad->getSize(file); else if (mode == SaveLoad::kSaveModeExists) @@ -130,6 +151,97 @@ bool Inter_Playtoons::oPlaytoons_checkData(OpFuncParams ¶ms) { return false; } +bool Inter_Playtoons::oPlaytoons_readData(OpFuncParams ¶ms) { + int32 retSize; + int32 size; + int32 offset; + int16 dataVar; + int16 handle; + byte *buf; + SaveLoad::SaveMode mode; + + _vm->_game->_script->evalExpr(0); + dataVar = _vm->_game->_script->readVarIndex(); + size = _vm->_game->_script->readValExpr(); + _vm->_game->_script->evalExpr(0); + offset = _vm->_game->_script->getResultInt(); + retSize = 0; + + char *file = _vm->_game->_script->getResultStr(); + + // WORKAROUND: In Playtoons games, some files are read on CD (and only on CD). + // In this case, "@:\" is replaced by the CD drive letter. + // As the files are copied on the HDD, those characters are skipped. + if (strncmp(file, "@:\\", 3) == 0) { + debugC(2, kDebugFileIO, "oPlaytoons_readData: \"%s\" instead of \"%s\"", file + 3, file); + file += 3; + } + + debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)", + file, dataVar, size, offset); + + mode = _vm->_saveLoad->getSaveMode(file); + if (mode == SaveLoad::kSaveModeSave) { + + WRITE_VAR(1, 1); + + if (!_vm->_saveLoad->load(file, dataVar, size, offset)) { + GUI::MessageDialog dialog("Failed to load game state from file."); + dialog.runModal(); + } else + WRITE_VAR(1, 0); + + return false; + + } else if (mode == SaveLoad::kSaveModeIgnore) + return false; + + if (size < 0) { + warning("Attempted to read a raw sprite from file \"%s\"", + file); + return false ; + } else if (size == 0) { + dataVar = 0; + size = _vm->_game->_script->getVariablesCount() * 4; + } + + buf = _variables->getAddressOff8(dataVar); + + if (file[0] == 0) { + WRITE_VAR(1, size); + return false; + } + + WRITE_VAR(1, 1); + handle = _vm->_dataIO->openData(file); + + if (handle < 0) + return false; + + DataStream *stream = _vm->_dataIO->openAsStream(handle, true); + + _vm->_draw->animateCursor(4); + 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::kPlatformPC) && (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; + return false; +} + void Inter_Playtoons::oPlaytoons_CD_20_23() { _vm->_game->_script->evalExpr(0); } |