diff options
-rw-r--r-- | scumm/cursor.cpp | 4 | ||||
-rw-r--r-- | scumm/intern.h | 34 | ||||
-rw-r--r-- | scumm/scumm.cpp | 116 | ||||
-rw-r--r-- | scumm/scumm.h | 2 | ||||
-rw-r--r-- | scumm/util.cpp | 273 | ||||
-rw-r--r-- | scumm/util.h | 46 |
6 files changed, 403 insertions, 72 deletions
diff --git a/scumm/cursor.cpp b/scumm/cursor.cpp index 2c5a6f3a9e..a24a502c31 100644 --- a/scumm/cursor.cpp +++ b/scumm/cursor.cpp @@ -75,8 +75,8 @@ static const uint16 default_he_cursor[64] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; -ScummEngine_v5::ScummEngine_v5(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine(detector, syst, gs, md5sum) { +ScummEngine_v5::ScummEngine_v5(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine(detector, syst, gs, md5sum, substResFileNameIndex) { for (int i = 0; i < 4; i++) { memcpy(_cursorImages[i], default_cursor_images[i], 32); diff --git a/scumm/intern.h b/scumm/intern.h index 094d702a89..7bcde63394 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -53,7 +53,7 @@ protected: byte _cursorHotspots[2 * 4]; public: - ScummEngine_v5(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v5(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); protected: virtual void setupOpcodes(); @@ -196,7 +196,7 @@ protected: */ class ScummEngine_v4 : public ScummEngine_v5 { public: - ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); protected: virtual void readIndexFile(); @@ -213,7 +213,7 @@ protected: */ class ScummEngine_v3 : public ScummEngine_v4 { public: - ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); protected: virtual void readRoomsOffsets(); @@ -225,7 +225,7 @@ protected: */ class ScummEngine_v3old : public ScummEngine_v3 { public: - ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); protected: virtual void readResTypeList(int id, uint32 tag, const char *name); @@ -252,7 +252,7 @@ protected: int8 _mouseOverBoxV2; public: - ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); virtual void scummInit(); @@ -390,7 +390,7 @@ protected: const OpcodeEntryC64 *_opcodesC64; public: - ScummEngine_c64(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_c64(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); protected: virtual void setupOpcodes(); @@ -479,7 +479,7 @@ protected: public: - ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); virtual void scummInit(); @@ -717,7 +717,7 @@ protected: Common::File _hFileTable[17]; public: - ScummEngine_v60he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v6(detector, syst, gs, md5sum) {} + ScummEngine_v60he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : ScummEngine_v6(detector, syst, gs, md5sum, substResFileNameIndex) {} virtual void scummInit(); @@ -777,7 +777,7 @@ protected: bool _skipProcessActors; public: - ScummEngine_v70he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v70he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); ~ScummEngine_v70he(); Wiz _wiz; @@ -832,7 +832,7 @@ protected: class ScummEngine_v71he : public ScummEngine_v70he { public: - ScummEngine_v71he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v71he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); protected: virtual void redrawBGAreas(); @@ -885,7 +885,7 @@ protected: WizParameters _wizParams; public: - ScummEngine_v72he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v72he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); virtual void scummInit(); @@ -1018,7 +1018,7 @@ protected: int32 _heSBNGId; public: - ScummEngine_v80he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v80he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); protected: virtual void setupOpcodes(); @@ -1093,7 +1093,7 @@ protected: SpriteInfo **_activeSpritesTable; public: - ScummEngine_v90he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v80he(detector, syst, gs, md5sum) {} + ScummEngine_v90he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : ScummEngine_v80he(detector, syst, gs, md5sum, substResFileNameIndex) {} ~ScummEngine_v90he(); @@ -1288,7 +1288,7 @@ protected: class ScummEngine_v99he : public ScummEngine_v90he { public: - ScummEngine_v99he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v90he(detector, syst, gs, md5sum) {} + ScummEngine_v99he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : ScummEngine_v90he(detector, syst, gs, md5sum, substResFileNameIndex) {} virtual void scummInit(); @@ -1317,7 +1317,7 @@ protected: const OpcodeEntryV100he *_opcodesV100he; public: - ScummEngine_v100he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v99he(detector, syst, gs, md5sum) {} + ScummEngine_v100he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : ScummEngine_v99he(detector, syst, gs, md5sum, substResFileNameIndex) {} protected: virtual void setupOpcodes(); @@ -1367,7 +1367,7 @@ protected: #ifndef DISABLE_SCUMM_7_8 class ScummEngine_v7 : public ScummEngine_v6 { public: - ScummEngine_v7(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v7(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); ~ScummEngine_v7(); bool _existLanguageFile; @@ -1419,7 +1419,7 @@ protected: ObjectNameId *_objectIDMap; public: - ScummEngine_v8(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine_v8(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); ~ScummEngine_v8(); protected: diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index d79d9ee0f4..65aaeeacb1 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -474,13 +474,13 @@ static const ScummGameSettings multiple_versions_md5_settings[] = { GF_USE_KEY | GF_NEW_COSTUMES, Common::kPlatformUnknown, 0, 0}, {"d8d07efcb88f396bee0b402b10c3b1c9", "Maniac Mansion (NES E)", GID_MANIAC, 1, 0, MDT_NONE, - GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, "Maniac Mansion (E).prg"}, + GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, 0}, {"81bbfa181184cb494e7a81dcfa94fbd9", "Maniac Mansion (NES F)", GID_MANIAC, 1, 0, MDT_NONE, - GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, "Maniac Mansion (F).prg"}, + GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, 0}, {"22d07d6c386c9c25aca5dac2a0c0d94b", "Maniac Mansion (NES SW)", GID_MANIAC, 1, 0, MDT_NONE, - GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, "Maniac Mansion (SW).prg"}, + GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, 0}, {"3905799e081b80a61d4460b7b733c206", "Maniac Mansion (NES U)", GID_MANIAC, 1, 0, MDT_NONE, - GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, "Maniac Mansion (U).prg"}, + GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformNES, 0, 0}, {"7f45ddd6dbfbf8f80c0c0efea4c295bc", "Maniac Mansion (v1)", GID_MANIAC, 1, 0, MDT_PCSPK, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR | GF_OLD_BUNDLE | GF_NO_SCALING, Common::kPlatformUnknown, 0, 0}, @@ -570,6 +570,10 @@ struct SubstResFileNames { static SubstResFileNames substResFileNameTable[] = { { "Intentionally/left/blank", "", kGenMacNoParens}, + { "00.LFL", "zak1.d64", kGenAsIs }, + { "01.LFL", "zak2.d64", kGenAsIs }, + { "00.LFL", "maniac1.d64", kGenAsIs }, + { "01.LFL", "maniac2.d64", kGenAsIs }, { "00.LFL", "Maniac Mansion (E).prg", kGenAsIs }, { "00.LFL", "Maniac Mansion (F).prg", kGenAsIs }, { "00.LFL", "Maniac Mansion (SW).prg", kGenAsIs }, @@ -670,13 +674,14 @@ static int compareMD5Table(const void *a, const void *b) { return strcmp(key, elem->md5); } -ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) +ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) : Engine(syst), _gameId(gs.id), _version(gs.version), _heversion(gs.heversion), _features(gs.features), _platform(gs.platform), + _substResFileNameIndex(substResFileNameIndex), gdi(this), res(this), _pauseDialog(0), _mainMenuDialog(0), _versionDialog(0), @@ -746,9 +751,20 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS // We read data directly from NES ROM instead of extracting it with // external tool - if ((_platform == Common::kPlatformNES) && (_substResFileNameIndex || gs.detectFilename)) + if ((_platform == Common::kPlatformNES) && _substResFileNameIndex) { + char tmpBuf[128]; + generateSubstResFileName("00.LFL", tmpBuf, sizeof(tmpBuf)); _fileHandle = new ScummNESFile(); - else + _containerFile = tmpBuf; + } else if ((_platform == Common::kPlatformC64) && _substResFileNameIndex) { + char tmpBuf1[128], tmpBuf2[128]; + generateSubstResFileName("00.LFL", tmpBuf1, sizeof(tmpBuf1)); + generateSubstResFileName("01.LFL", tmpBuf2, sizeof(tmpBuf2)); + + _fileHandle = new ScummC64File(tmpBuf1, tmpBuf2, _gameId == GID_MANIAC); + + _containerFile = tmpBuf1; + } else _fileHandle = new ScummFile(); // The mac versions of Sam&Max, DOTT, FT and The Dig used a special meta @@ -1248,30 +1264,30 @@ ScummEngine::~ScummEngine() { delete _debugger; } -ScummEngine_v4::ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v5(detector, syst, gs, md5sum) { +ScummEngine_v4::ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v5(detector, syst, gs, md5sum, substResFileNameIndex) { _resourceHeaderSize = 6; } -ScummEngine_v3::ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v4(detector, syst, gs, md5sum) { +ScummEngine_v3::ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v4(detector, syst, gs, md5sum, substResFileNameIndex) { } -ScummEngine_v3old::ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v3(detector, syst, gs, md5sum) { +ScummEngine_v3old::ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v3(detector, syst, gs, md5sum, substResFileNameIndex) { _resourceHeaderSize = 4; } -ScummEngine_v2::ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v3old(detector, syst, gs, md5sum) { +ScummEngine_v2::ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v3old(detector, syst, gs, md5sum, substResFileNameIndex) { } -ScummEngine_c64::ScummEngine_c64(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v2(detector, syst, gs, md5sum) { +ScummEngine_c64::ScummEngine_c64(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v2(detector, syst, gs, md5sum, substResFileNameIndex) { } -ScummEngine_v6::ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine(detector, syst, gs, md5sum) { +ScummEngine_v6::ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine(detector, syst, gs, md5sum, substResFileNameIndex) { _blastObjectQueuePos = 0; memset(_blastObjectQueue, 0, sizeof(_blastObjectQueue)); _blastTextQueuePos = 0; @@ -1292,8 +1308,8 @@ ScummEngine_v6::ScummEngine_v6(GameDetector *detector, OSystem *syst, const Scum } #ifndef DISABLE_HE -ScummEngine_v70he::ScummEngine_v70he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v60he(detector, syst, gs, md5sum) { +ScummEngine_v70he::ScummEngine_v70he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v60he(detector, syst, gs, md5sum, substResFileNameIndex) { if (_platform == Common::kPlatformMacintosh && _heversion == 72) _resExtractor = new MacResExtractor(this); else @@ -1318,16 +1334,16 @@ ScummEngine_v70he::~ScummEngine_v70he() { free(_heV7RoomOffsets); } -ScummEngine_v71he::ScummEngine_v71he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v70he(detector, syst, gs, md5sum) { +ScummEngine_v71he::ScummEngine_v71he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v70he(detector, syst, gs, md5sum, substResFileNameIndex) { _auxBlocksNum = 0; memset(_auxBlocks, 0, sizeof(_auxBlocks)); _auxEntriesNum = 0; memset(_auxEntries, 0, sizeof(_auxEntries)); } -ScummEngine_v72he::ScummEngine_v72he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v71he(detector, syst, gs, md5sum) { +ScummEngine_v72he::ScummEngine_v72he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v71he(detector, syst, gs, md5sum, substResFileNameIndex) { VAR_NUM_ROOMS = 0xFF; VAR_NUM_SCRIPTS = 0xFF; VAR_NUM_SOUNDS = 0xFF; @@ -1346,8 +1362,8 @@ ScummEngine_v72he::ScummEngine_v72he(GameDetector *detector, OSystem *syst, cons VAR_WIZ_TCOLOR = 0xFF; } -ScummEngine_v80he::ScummEngine_v80he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v72he(detector, syst, gs, md5sum) { +ScummEngine_v80he::ScummEngine_v80he(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v72he(detector, syst, gs, md5sum, substResFileNameIndex) { _heSBNGId = 0; } @@ -1359,8 +1375,8 @@ ScummEngine_v90he::~ScummEngine_v90he() { #endif #ifndef DISABLE_SCUMM_7_8 -ScummEngine_v7::ScummEngine_v7(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v6(detector, syst, gs, md5sum) { +ScummEngine_v7::ScummEngine_v7(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v6(detector, syst, gs, md5sum, substResFileNameIndex) { _existLanguageFile = false; _languageBuffer = NULL; _languageIndex = NULL; @@ -1371,8 +1387,8 @@ ScummEngine_v7::~ScummEngine_v7() { free(_languageIndex); } -ScummEngine_v8::ScummEngine_v8(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) - : ScummEngine_v7(detector, syst, gs, md5sum) { +ScummEngine_v8::ScummEngine_v8(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex) + : ScummEngine_v7(detector, syst, gs, md5sum, substResFileNameIndex) { _objectIDMap = 0; } @@ -2884,63 +2900,63 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) { case 1: case 2: if (game.id == GID_MANIAC && game.platform == Common::kPlatformC64) - engine = new ScummEngine_c64(detector, syst, game, md5sum); + engine = new ScummEngine_c64(detector, syst, game, md5sum, substLastIndex); else - engine = new ScummEngine_v2(detector, syst, game, md5sum); + engine = new ScummEngine_v2(detector, syst, game, md5sum, substLastIndex); break; case 3: if (game.features & GF_OLD_BUNDLE) - engine = new ScummEngine_v3old(detector, syst, game, md5sum); + engine = new ScummEngine_v3old(detector, syst, game, md5sum, substLastIndex); else - engine = new ScummEngine_v3(detector, syst, game, md5sum); + engine = new ScummEngine_v3(detector, syst, game, md5sum, substLastIndex); break; case 4: - engine = new ScummEngine_v4(detector, syst, game, md5sum); + engine = new ScummEngine_v4(detector, syst, game, md5sum, substLastIndex); break; case 5: - engine = new ScummEngine_v5(detector, syst, game, md5sum); + engine = new ScummEngine_v5(detector, syst, game, md5sum, substLastIndex); break; case 6: switch (game.heversion) { #ifndef DISABLE_HE case 100: - engine = new ScummEngine_v100he(detector, syst, game, md5sum); + engine = new ScummEngine_v100he(detector, syst, game, md5sum, substLastIndex); break; case 99: - engine = new ScummEngine_v99he(detector, syst, game, md5sum); + engine = new ScummEngine_v99he(detector, syst, game, md5sum, substLastIndex); break; case 98: case 95: case 90: - engine = new ScummEngine_v90he(detector, syst, game, md5sum); + engine = new ScummEngine_v90he(detector, syst, game, md5sum, substLastIndex); break; case 80: - engine = new ScummEngine_v80he(detector, syst, game, md5sum); + engine = new ScummEngine_v80he(detector, syst, game, md5sum, substLastIndex); break; case 72: - engine = new ScummEngine_v72he(detector, syst, game, md5sum); + engine = new ScummEngine_v72he(detector, syst, game, md5sum, substLastIndex); break; case 71: - engine = new ScummEngine_v71he(detector, syst, game, md5sum); + engine = new ScummEngine_v71he(detector, syst, game, md5sum, substLastIndex); break; case 70: - engine = new ScummEngine_v70he(detector, syst, game, md5sum); + engine = new ScummEngine_v70he(detector, syst, game, md5sum, substLastIndex); break; #endif case 61: - engine = new ScummEngine_v60he(detector, syst, game, md5sum); + engine = new ScummEngine_v60he(detector, syst, game, md5sum, substLastIndex); break; default: - engine = new ScummEngine_v6(detector, syst, game, md5sum); + engine = new ScummEngine_v6(detector, syst, game, md5sum, substLastIndex); } break; #ifndef DISABLE_SCUMM_7_8 case 7: - engine = new ScummEngine_v7(detector, syst, game, md5sum); + engine = new ScummEngine_v7(detector, syst, game, md5sum, substLastIndex); break; #ifndef __PALM_OS__ case 8: - engine = new ScummEngine_v8(detector, syst, game, md5sum); + engine = new ScummEngine_v8(detector, syst, game, md5sum, substLastIndex); break; #endif @@ -2949,10 +2965,6 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) { error("Engine_SCUMM_create(): Unknown version of game engine"); } - // FIXME: dirty HACK. Should we introduce another parameter to constructor - // instead? - ((ScummEngine *)engine)->_substResFileNameIndex = substLastIndex; - return engine; } diff --git a/scumm/scumm.h b/scumm/scumm.h index baeac68c73..84eaddbabc 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -408,7 +408,7 @@ protected: public: // Constructor / Destructor - ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16], int substResFileNameIndex); virtual ~ScummEngine(); /** Startup function, main loop. */ diff --git a/scumm/util.cpp b/scumm/util.cpp index 5328eb3787..20e4ad9ad0 100644 --- a/scumm/util.cpp +++ b/scumm/util.cpp @@ -778,9 +778,11 @@ uint16 ScummNESFile::fileReadUint16LE() { uint16 b = fileReadByte(); return a | (b << 8); } + uint32 ScummNESFile::resOffset(Resource *res) { return res->offset[_ROMset]; } + uint16 ScummNESFile::resLength(Resource *res) { return res->length[_ROMset]; } @@ -1272,4 +1274,275 @@ bool ScummNESFile::openSubFile(const char *filename) { } } +#pragma mark - +#pragma mark --- ScummC64File --- +#pragma mark - + +static const int maniacResourcesPerFile[55] = { + 0, 11, 1, 3, 9, 12, 1, 13, 10, 6, + 4, 1, 7, 1, 1, 2, 7, 8, 19, 9, + 6, 9, 2, 6, 8, 4, 16, 8, 3, 3, + 12, 12, 2, 8, 1, 1, 2, 1, 9, 1, + 3, 7, 3, 3, 13, 5, 4, 3, 1, 1, + 3, 10, 1, 0, 0 +}; + +static const int zakResourcesPerFile[59] = { + 0, 29, 12, 14, 13, 4, 4, 10, 7, 4, + 14, 19, 5, 4, 7, 6, 11, 9, 4, 4, + 1, 3, 3, 5, 1, 9, 4, 10, 13, 6, + 7, 10, 2, 6, 1, 11, 2, 5, 7, 1, + 7, 1, 4, 2, 8, 6, 6, 6, 4, 13, + 3, 1, 2, 1, 2, 1, 10, 1, 1 +}; + + +ScummC64File::ScummC64File(char *disk1, char *disk2, bool maniac) : _stream(0), _buf(0), _maniac(maniac) { + _disk1 = disk1; + _disk2 = disk2; + + _openedDisk = 0; + + if (maniac) { + _numGlobalObjects = 256; + _numRooms = 55; + _numCostumes = 25; + _numScripts = 160; + _numSounds = 70; + _resourcesPerFile = maniacResourcesPerFile; + } else { + _numGlobalObjects = 775; + _numRooms = 59; + _numCostumes = 38; + _numScripts = 155; + _numSounds = 127; + _resourcesPerFile = zakResourcesPerFile; + } +} + +uint32 ScummC64File::write(const void *, uint32) { + error("ScummC64File does not support writing!"); + return 0; +} + +void ScummC64File::setEnc(byte enc) { + _stream->setEnc(enc); +} + +byte ScummC64File::fileReadByte() { + byte b = 0; + File::read(&b, 1); + return b; +} + +uint16 ScummC64File::fileReadUint16LE() { + uint16 a = fileReadByte(); + uint16 b = fileReadByte(); + return a | (b << 8); +} + +bool ScummC64File::openDisk(char num) { + if (num == '1') + num = 1; + if (num == '2') + num = 2; + + if (_openedDisk != num || !File::isOpen()) { + if (File::isOpen()) + File::close(); + + if (num == 1) + File::open(_disk1.c_str()); + else if (num == 2) + File::open(_disk2.c_str()); + else { + error("ScummC64File::open(): wrong disk (%c)", num); + return false; + } + + _openedDisk = num; + + if (!File::isOpen()) { + error("ScummC64File::open(): cannot open disk (%d)", num); + return false; + } + } + return true; +} + +bool ScummC64File::open(const char *filename, AccessMode mode) { + uint16 signature; + + // check signature + openDisk(1); + File::seek(0); + + signature = fileReadUint16LE(); + if (signature != 0x0A31) { + error("ScummC64File::open(): signature not found in disk 1!"); + return false; + } + + extractIndex(0); // Fill in resource arrays + + openDisk(2); + File::seek(0); + + signature = fileReadUint16LE(); + if (signature != 0x0132) + error("Error: signature not found in disk 2!\n"); + + return true; +} + + +uint16 ScummC64File::extractIndex(Common::WriteStream *out) { + int i; + uint16 reslen = 0; + + openDisk(1); + File::seek(0); + + // skip signature + fileReadUint16LE(); + + // write expected signature + reslen += write_word(out, 0x0132); + + // copy object flags + for (i = 0; i < _numGlobalObjects; i++) + reslen += write_byte(out, fileReadByte()); + + // copy room offsets + for (i = 0; i < _numRooms; i++) { + _roomDisks[i] = fileReadByte(); + reslen += write_byte(out, _roomDisks[i]); + } + for (i = 0; i < _numRooms; i++) { + _roomSectors[i] = fileReadByte(); + reslen += write_byte(out, _roomSectors[i]); + _roomTracks[i] = fileReadByte(); + reslen += write_byte(out, _roomTracks[i]); + } + for (i = 0; i < _numCostumes; i++) + reslen += write_byte(out, fileReadByte()); + for (i = 0; i < _numCostumes; i++) + reslen += write_word(out, fileReadUint16LE()); + + for (i = 0; i < _numScripts; i++) + reslen += write_byte(out, fileReadByte()); + for (i = 0; i < _numScripts; i++) + reslen += write_word(out, fileReadUint16LE()); + + for (i = 0; i < _numSounds; i++) + reslen += write_byte(out, fileReadByte()); + for (i = 0; i < _numSounds; i++) + reslen += write_word(out, fileReadUint16LE()); + + return reslen; +} + +bool ScummC64File::generateIndex() { + int bufsize; + + bufsize = extractIndex(0); + + free(_buf); + _buf = (byte *)calloc(1, bufsize); + + Common::MemoryWriteStream out(_buf, bufsize); + + extractIndex(&out); + + if (_stream) + delete _stream; + + _stream = new Common::MemoryReadStream(_buf, bufsize); + + return true; +} + +uint16 ScummC64File::extractResource(Common::WriteStream *out, int res) { + const int SectorOffset[36] = { + 0, + 0, 21, 42, 63, 84, 105, 126, 147, 168, 189, 210, 231, 252, 273, 294, 315, 336, + 357, 376, 395, 414, 433, 452, 471, + 490, 508, 526, 544, 562, 580, + 598, 615, 632, 649, 666 + }; + int i; + uint16 reslen = 0; + + openDisk(_roomDisks[res]); + + File::seek((SectorOffset[_roomTracks[res]] + _roomSectors[res]) * 256); + + for (i = 0; i < _resourcesPerFile[res]; i++) { + uint16 len = fileReadUint16LE(); + reslen += write_word(out, len); + + for (len -= 2; len > 0; len--) + reslen += write_byte(out, fileReadByte()); + } + + return reslen; +} + +bool ScummC64File::generateResource(int res) { + int bufsize; + + if (res >= _numRooms) + return false; + + bufsize = extractResource(0, res); + + free(_buf); + _buf = (byte *)calloc(1, bufsize); + + Common::MemoryWriteStream out(_buf, bufsize); + + extractResource(&out, res); + + if (_stream) + delete _stream; + + _stream = new Common::MemoryReadStream(_buf, bufsize); + + return true; +} + +void ScummC64File::close() { + if (_stream) + delete _stream; + _stream = 0; + + free(_buf); + _buf = 0; + + File::close(); +} + +bool ScummC64File::openSubFile(const char *filename) { + assert(isOpen()); + + const char *ext = strrchr(filename, '.'); + char resNum[3]; + int res; + + // We always have file name in form of XX.lfl + resNum[0] = ext[-2]; + resNum[1] = ext[-1]; + resNum[2] = 0; + + res = atoi(resNum); + + if (res == 0) { + return generateIndex(); + } else { + return generateResource(res); + } + + return true; +} + } // End of namespace Scumm diff --git a/scumm/util.h b/scumm/util.h index a687a83b41..989db6a001 100644 --- a/scumm/util.h +++ b/scumm/util.h @@ -111,6 +111,52 @@ public: }; +class ScummC64File : public BaseScummFile { +private: + Common::MemoryReadStream *_stream; + byte _roomDisks[59], _roomTracks[59], _roomSectors[59]; + + byte *_buf; + + bool _maniac; + Common::String _disk1, _disk2; + int _openedDisk; + + int _numGlobalObjects; + int _numRooms; + int _numCostumes; + int _numScripts; + int _numSounds; + const int *_resourcesPerFile; + + bool openDisk(char num); + + bool generateIndex(); + bool generateResource(int res); + + uint16 extractIndex(Common::WriteStream *out); + uint16 extractResource(Common::WriteStream *out, int res); + + byte fileReadByte(); + uint16 fileReadUint16LE(); + +public: + ScummC64File(char *disk1, char *disk2, bool maniac); + void setEnc(byte value); + + bool open(const char *filename, AccessMode mode = kFileReadMode); + bool openSubFile(const char *filename); + + void close(); + bool eof() { return _stream->eos(); } + uint32 pos() { return _stream->pos(); } + uint32 size() { return _stream->size(); } + void seek(int32 offs, int whence = SEEK_SET) { _stream->seek(offs, whence); } + uint32 read(void *dataPtr, uint32 dataSize) { return _stream->read(dataPtr, dataSize); } + uint32 write(const void *dataPtr, uint32 dataSize); +}; + + /* Direction conversion functions (between old dir and new dir format) */ int newDirToOldDir(int dir); int oldDirToNewDir(int dir); |