diff options
Diffstat (limited to 'engines/scumm')
45 files changed, 1644 insertions, 619 deletions
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp index 0c375efcdd..5c148a7b57 100644 --- a/engines/scumm/actor.cpp +++ b/engines/scumm/actor.cpp @@ -1880,7 +1880,7 @@ bool Actor::actorHitTest(int x, int y) { #endif void Actor::startAnimActor(int f) { - if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) { + if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) { switch (f) { case 1001: f = _initFrame; @@ -1968,7 +1968,7 @@ void Actor_v0::startAnimActor(int f) { void Actor::animateActor(int anim) { int cmd, dir; - if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) { + if (_vm->_game.version >= 7 && !((_vm->_game.id == GID_FT) && (_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) { if (anim == 0xFF) anim = 2000; diff --git a/engines/scumm/debugger.cpp b/engines/scumm/debugger.cpp index dc5acbdb7d..9b6dd1e687 100644 --- a/engines/scumm/debugger.cpp +++ b/engines/scumm/debugger.cpp @@ -741,10 +741,6 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) { "Silence", "Shaping", "Unmaking", "Transcendence" }; - int odds[] = { - 15162, 15676, 16190, 64, 16961, 17475, 17989, 18503, - 73, 19274, 76, 77, 20302, 20816, 21330, 84 - }; const char *notes = "cdefgabC"; int i, base, draft; @@ -754,9 +750,9 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) { return true; } - // There are 16 drafts, stored from variable 50 or 100 and upwards. - // Each draft occupies two variables. Even-numbered variables contain - // the notes for each draft, and a number of flags: + // There are 16 drafts, stored from variable 50, 55 or 100 and upwards. + // Each draft occupies two variables, the first of which contains the + // notes for the draft and a number of flags. // // +---+---+---+---+-----+-----+-----+-----+ // | A | B | C | D | 444 | 333 | 222 | 111 | @@ -771,13 +767,16 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) { // 222 The second note // 111 The first note // - // I don't yet know what the odd-numbered variables are used for. - // Possibly they store information on where and/or how the draft can - // be used. They appear to remain constant throughout the game. + // I don't yet know what the second variable is used for. Possibly to + // store information on where and/or how the draft can be used. They + // appear to remain constant throughout the game. if (_vm->_game.version == 4 || _vm->_game.platform == Common::kPlatformPCEngine) { // DOS CD version / PC-Engine version base = 100; + } else if (_vm->_game.platform == Common::kPlatformMacintosh) { + // Macintosh version + base = 55; } else { // All (?) other versions base = 50; @@ -801,28 +800,13 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) { DebugPrintf("Learned all drafts and notes.\n"); return true; } - - // During the testing of EGA Loom we had some trouble with the - // drafts data structure being overwritten. I don't expect - // this command is particularly useful any more, but it will - // attempt to repair the (probably) static part of it. - - if (strcmp(argv[1], "fix") == 0) { - for (i = 0; i < 16; i++) - _vm->_scummVars[base + 2 * i + 1] = odds[i]; - DebugPrintf( - "An attempt has been made to repair\n" - "the internal drafts data structure.\n" - "Continue on your own risk.\n"); - return true; - } } // Probably the most useful command for ordinary use: list the drafts. for (i = 0; i < 16; i++) { draft = _vm->_scummVars[base + i * 2]; - DebugPrintf("%d %-13s %c%c%c%c %c%c %5d %c\n", + DebugPrintf("%d %-13s %c%c%c%c %c%c\n", base + 2 * i, names[i], notes[draft & 0x0007], @@ -830,9 +814,7 @@ bool ScummDebugger::Cmd_PrintDraft(int argc, const char **argv) { notes[(draft & 0x01c0) >> 6], notes[(draft & 0x0e00) >> 9], (draft & 0x2000) ? 'K' : ' ', - (draft & 0x4000) ? 'U' : ' ', - _vm->_scummVars[base + 2 * i + 1], - (_vm->_scummVars[base + 2 * i + 1] != odds[i]) ? '!' : ' '); + (draft & 0x4000) ? 'U' : ' '); } return true; diff --git a/engines/scumm/debugger.h b/engines/scumm/debugger.h index a9b340d691..b60a1a2f03 100644 --- a/engines/scumm/debugger.h +++ b/engines/scumm/debugger.h @@ -35,7 +35,6 @@ public: private: ScummEngine *_vm; - bool _old_soundsPaused; // Commands bool Cmd_Room(int argc, const char **argv); diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index e5c3023380..170ca0993c 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -963,7 +963,7 @@ static Common::String generatePreferredTarget(const DetectorResult &x) { } // Append the platform, if a non-standard one has been specified. - if (x.game.platform != Common::kPlatformPC && x.game.platform != Common::kPlatformUnknown) { + if (x.game.platform != Common::kPlatformDOS && x.game.platform != Common::kPlatformUnknown) { // HACK: For CoMI, it's pointless to encode the fact that it's for Windows if (x.game.id != GID_CMI) res = res + "-" + Common::getPlatformAbbrev(x.game.platform); diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h index 3120017db6..cb807997e9 100644 --- a/engines/scumm/detection_tables.h +++ b/engines/scumm/detection_tables.h @@ -205,11 +205,11 @@ static const Engines::ObsoleteGameID obsoleteGameIDsTable[] = { static const GameSettings gameVariantsTable[] = { {"maniac", "Apple II", 0, GID_MANIAC, 0, 0, MDT_APPLEIIGS, 0, Common::kPlatformApple2GS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"maniac", "C64", 0, GID_MANIAC, 0, 0, MDT_C64, 0, Common::kPlatformC64, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI) }, - {"maniac", "V1", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, 0, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, - {"maniac", "V1 Demo", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, + {"maniac", "V1", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, 0, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, + {"maniac", "V1 Demo", "v1", GID_MANIAC, 1, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"maniac", "NES", 0, GID_MANIAC, 1, 0, MDT_NONE, 0, Common::kPlatformNES, GUIO3(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_NOASPECT)}, {"maniac", "V2", "v2", GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, - {"maniac", "V2 Demo", "v2", GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, + {"maniac", "V2 Demo", "v2", GID_MANIAC, 2, 0, MDT_PCSPK | MDT_PCJR, GF_DEMO, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"zak", "V1", "v1", GID_ZAK, 1, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"zak", "V2", "v2", GID_ZAK, 2, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, @@ -220,7 +220,7 @@ static const GameSettings gameVariantsTable[] = { {"indy3", "EGA", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"indy3", "No AdLib", "ega", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR, 0, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, - {"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, + {"indy3", "VGA", "vga", GID_INDY3, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_OLD256 | GF_FEW_LOCALS, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"indy3", "FM-TOWNS", 0, GID_INDY3, 3, 0, MDT_TOWNS, GF_OLD256 | GF_FEW_LOCALS | GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)}, {"loom", "EGA", "ega", GID_LOOM, 3, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)}, @@ -229,14 +229,14 @@ static const GameSettings gameVariantsTable[] = { {"loom", "PC-Engine", 0, GID_LOOM, 3, 0, MDT_NONE, GF_AUDIOTRACKS | GF_OLD256 | GF_16BIT_COLOR, Common::kPlatformPCEngine, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, #endif {"loom", "FM-TOWNS", 0, GID_LOOM, 3, 0, MDT_TOWNS, GF_AUDIOTRACKS | GF_OLD256, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)}, - {"loom", "VGA", "vga", GID_LOOM, 4, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, + {"loom", "VGA", "vga", GID_LOOM, 4, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, - {"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, + {"pass", 0, 0, GID_PASS, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"monkey", "VGA", "vga", GID_MONKEY_VGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, 0, UNK, GUIO1(GUIO_NOSPEECH)}, - {"monkey", "EGA", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_16COLOR, Common::kPlatformPC, GUIO1(GUIO_NOSPEECH)}, + {"monkey", "EGA", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB | MDT_MIDI | MDT_PREFER_MT32, GF_16COLOR, Common::kPlatformDOS, GUIO1(GUIO_NOSPEECH)}, {"monkey", "No AdLib", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR, GF_16COLOR, Common::kPlatformAtariST, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, - {"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformPC, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, + {"monkey", "Demo", "ega", GID_MONKEY_EGA, 4, 0, MDT_PCSPK | MDT_PCJR | MDT_CMS | MDT_ADLIB, GF_16COLOR, Common::kPlatformDOS, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"monkey", "CD", 0, GID_MONKEY, 5, 0, MDT_ADLIB, GF_AUDIOTRACKS, UNK, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, {"monkey", "FM-TOWNS", 0, GID_MONKEY, 5, 0, MDT_TOWNS, GF_AUDIOTRACKS, Common::kPlatformFMTowns, GUIO4(GUIO_NOSPEECH, GUIO_NOMIDI, GUIO_MIDITOWNS, GUIO_NOASPECT)}, {"monkey", "SEGA", 0, GID_MONKEY, 5, 0, MDT_NONE, GF_AUDIOTRACKS, Common::kPlatformSegaCD, GUIO2(GUIO_NOSPEECH, GUIO_NOMIDI)}, @@ -705,6 +705,7 @@ static const GameFilenamePattern gameFilenamesTable[] = { { "freddi4", "FF4 demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "freddi4", "Freddi 4", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, { "freddi4", "Freddi 4 Demo", kGenHEMac, UNK_LANG, Common::kPlatformMacintosh, 0 }, + { "freddi4", "FreddiCMP", kGenHEPC, Common::IT_ITA, Common::kPlatformWindows, 0 }, { "freddi4", "FreddiGS", kGenHEPC, Common::DE_DEU, UNK, 0 }, { "freddi4", "FreddiGS", kGenHEMac, Common::DE_DEU, Common::kPlatformMacintosh, 0 }, { "freddi4", "FreddiHRBG", kGenHEPC, Common::EN_GRB, UNK, 0 }, diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp index ffff329036..50ff0b3988 100644 --- a/engines/scumm/gfx.cpp +++ b/engines/scumm/gfx.cpp @@ -3609,7 +3609,7 @@ void Gdi::unkDecode9(byte *dst, int dstPitch, const byte *src, int height) const int i; uint buffer = 0, mask = 128; int h = height; - i = run = 0; + run = 0; int x = 8; for (;;) { diff --git a/engines/scumm/he/animation_he.h b/engines/scumm/he/animation_he.h index 7fa31a195d..e17c1b9a39 100644 --- a/engines/scumm/he/animation_he.h +++ b/engines/scumm/he/animation_he.h @@ -55,7 +55,6 @@ private: Video::VideoDecoder *_video; - char baseName[40]; uint32 _flags; uint32 _wizResNum; }; diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index fc5e4bcdf0..a674288775 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -628,7 +628,6 @@ public: void parseEvents(); - bool _quit; OSystem *_syst; GameSettings _game; diff --git a/engines/scumm/he/logic/football.cpp b/engines/scumm/he/logic/football.cpp index b405d634a4..ea990ca86b 100644 --- a/engines/scumm/he/logic/football.cpp +++ b/engines/scumm/he/logic/football.cpp @@ -218,10 +218,10 @@ int LogicHEfootball::nextPoint(int32 *args) { if (res >= (double)args[6]) { var8 = (double)args[6] * var8 / res; var10 = (double)args[6] * var10 / res; - res = (double)args[6] * var6 / res; + var6 = (double)args[6] * var6 / res; } - writeScummVar(108, (int32)res); + writeScummVar(108, (int32)var6); writeScummVar(109, (int32)var10); writeScummVar(110, (int32)var8); @@ -297,6 +297,15 @@ private: int initScreenTranslations(); int getPlaybookFiles(int32 *args); int largestFreeBlock(); + + float _var0; + float _var1; + float _var2; + float _var3; + float _var4; + float _angle; + int32 _maxX; + int32 _minX; }; int32 LogicHEfootball2002::dispatch(int op, int numArgs, int32 *args) { @@ -325,8 +334,16 @@ int32 LogicHEfootball2002::dispatch(int op, int numArgs, int32 *args) { res = 1; break; + case 1030: + // Get Computer Name (online play only) + break; + + case 1515: + // Initialize Session (online play only) + break; + case 1516: - // Start auto LAN game + // Start auto LAN game (online play only) break; default: @@ -338,13 +355,74 @@ int32 LogicHEfootball2002::dispatch(int op, int numArgs, int32 *args) { } int LogicHEfootball2002::translateWorldToScreen(int32 *args) { - // TODO: Implement modified 2002 version - return LogicHEfootball::translateWorldToScreen(args); + // While this performs the same task as football's 1006 opcode, + // the implementation is different. Note that this is also the + // same as basketball's 1006 opcode with different constants! + + double v9; + if (args[1] >= _minX) { + if (args[1] < _maxX) { + v9 = (sqrt(_var1 + args[1]) - sqrt(_var1)) / sqrt(_var0); + } else { + double v10 = sqrt(_var0 * (_maxX + _var1)); + v9 = 1.0 / (v10 + v10) * (args[1] - _maxX) + 451.0; + } + } else { + double v8 = sqrt(_var0 * (_minX + _var1)); + v9 = 1.0 / (v8 + v8) * (args[1] - _minX) - 29.0; + } + + double v11 = tan(_angle); + double v12, v13; + + if (v9 >= -29.0) { + if (v9 >= 451.0) { + v12 = 1517.0 - (451.0 / v11 + 451.0 / v11); + v13 = tan(1.570796326794895 - _angle) * 451.0; + } else { + v12 = 1517.0 - (v9 / v11 + v9 / v11); + v13 = tan(1.570796326794895 - _angle) * v9; + } + } else { + v12 = 1517.0 - (-29.0 / v11 + -29.0 / v11); + v13 = tan(1.570796326794895 - _angle) * -29.0; + } + + writeScummVar(108, scummRound(v12 * args[0] / 12200.0 + v13 + 41.0)); + writeScummVar(109, scummRound(611.0 - v9 - v12 * args[2] / 12200.0)); + + return 1; } int LogicHEfootball2002::translateScreenToWorld(int32 *args) { - // TODO: Implement modified 2002 version - return LogicHEfootball::translateScreenToWorld(args); + // While this performs the same task as football's 1010 opcode, + // the implementation is different. Note that this is also the + // same as basketball's 1010 opcode with different constants! + + double v15 = 611.0 - args[1]; + double v5 = tan(_angle); + double v4, v6, v7; + + if (v15 >= -29.0) { + if (v15 >= 451.0) { + v4 = (_var2 * 902.0 + _var3) * (v15 - 451.0) + _maxX; + v6 = 1517.0 - (451.0 / v5 + 451.0 / v5); + v7 = tan(1.570796326794895 - _angle) * 451.0; + } else { + v4 = (v15 * _var2 + _var3) * v15 + _var4; + v6 = 1517.0 - (v15 / v5 + v15 / v5); + v7 = tan(1.570796326794895 - _angle) * v15; + } + } else { + v4 = (_var3 - _var2 * 58.0) * (v15 - -29.0) + _minX; + v6 = 1517.0 - (-29.0 / v5 + -29.0 / v5); + v7 = tan(1.570796326794895 - _angle) * -29.0; + } + + writeScummVar(108, scummRound((args[0] - (v7 + 41.0)) * (12200.0 / v6))); + writeScummVar(109, scummRound(v4)); + + return 1; } int LogicHEfootball2002::getDayOfWeek() { @@ -358,7 +436,14 @@ int LogicHEfootball2002::getDayOfWeek() { } int LogicHEfootball2002::initScreenTranslations() { - // TODO: Set values used by translateWorldToScreen/translateScreenToWorld + // Set values used by translateWorldToScreen/translateScreenToWorld + _var0 = _var2 = 0.0029172597f; + _var1 = 4896.3755f; + _var3 = 7.5588355f; + _var4 = 0.0f; + _angle = (float)atan(2.899280575539569); + _maxX = 4002; + _minX = -217; return 1; } diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp index a2eb42214b..b024154c7f 100644 --- a/engines/scumm/he/script_v100he.cpp +++ b/engines/scumm/he/script_v100he.cpp @@ -2237,7 +2237,10 @@ void ScummEngine_v100he::o100_videoOps() { switch (subOp) { case 0: memset(_videoParams.filename, 0, sizeof(_videoParams.filename)); + _videoParams.status = 0; + _videoParams.flags = 0; _videoParams.unk2 = pop(); + _videoParams.wizResNum = 0; break; case 19: _videoParams.status = 19; diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp index 5e359385b6..bbd8725904 100644 --- a/engines/scumm/he/script_v60he.cpp +++ b/engines/scumm/he/script_v60he.cpp @@ -804,7 +804,7 @@ void ScummEngine_v60he::o60_readFile() { int val; // Fatty Bear uses positive values - if (_game.platform == Common::kPlatformPC && _game.id == GID_FBEAR) + if (_game.platform == Common::kPlatformDOS && _game.id == GID_FBEAR) size = -size; assert(_hInFileTable[slot]); @@ -834,7 +834,7 @@ void ScummEngine_v60he::o60_writeFile() { int slot = pop(); // Fatty Bear uses positive values - if (_game.platform == Common::kPlatformPC && _game.id == GID_FBEAR) + if (_game.platform == Common::kPlatformDOS && _game.id == GID_FBEAR) size = -size; assert(_hOutFileTable[slot]); diff --git a/engines/scumm/he/sound_he.cpp b/engines/scumm/he/sound_he.cpp index f94b74ac45..1afb1b4074 100644 --- a/engines/scumm/he/sound_he.cpp +++ b/engines/scumm/he/sound_he.cpp @@ -804,7 +804,7 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { byte *snd1Ptr, *snd2Ptr; byte *sbng1Ptr, *sbng2Ptr; byte *sdat1Ptr, *sdat2Ptr; - byte *src, *dst, *tmp; + byte *src, *dst; int len, offs, size; int sdat1size, sdat2size; @@ -844,6 +844,7 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { if (sbng1Ptr != NULL && sbng2Ptr != NULL) { if (chan != -1 && ((SoundHE *)_sound)->_heChannel[chan].codeOffs > 0) { + // Copy any code left over to the beginning of the code block int curOffs = ((SoundHE *)_sound)->_heChannel[chan].codeOffs; src = snd1Ptr + curOffs; @@ -851,29 +852,33 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { size = READ_BE_UINT32(sbng1Ptr + 4); len = sbng1Ptr - snd1Ptr + size - curOffs; - byte *data = (byte *)malloc(len); - memcpy(data, src, len); - memcpy(dst, data, len); - free(data); + memmove(dst, src, len); + // Now seek to the end of this code block dst = sbng1Ptr + 8; while ((size = READ_LE_UINT16(dst)) != 0) dst += size; } else { + // We're going to overwrite the code block completely dst = sbng1Ptr + 8; } - ((SoundHE *)_sound)->_heChannel[chan].codeOffs = sbng1Ptr - snd1Ptr + 8; + // Reset the current code offset to the beginning of the code block + if (chan >= 0) + ((SoundHE *)_sound)->_heChannel[chan].codeOffs = sbng1Ptr - snd1Ptr + 8; - tmp = sbng2Ptr + 8; + // Seek to the end of the code block for sound 2 + byte *tmp = sbng2Ptr + 8; while ((offs = READ_LE_UINT16(tmp)) != 0) { tmp += offs; } + // Copy the code block for sound 2 to the code block for sound 1 src = sbng2Ptr + 8; len = tmp - sbng2Ptr - 6; memcpy(dst, src, len); + // Rewrite the time for this new code block to be after the sound 1 code block int32 time; while ((size = READ_LE_UINT16(dst)) != 0) { time = READ_LE_UINT32(dst + 2); @@ -883,6 +888,7 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { } } + // Find the data pointers and sizes if (findSoundTag(MKTAG('d','a','t','a'), snd1Ptr)) { sdat1Ptr = findSoundTag(MKTAG('d','a','t','a'), snd1Ptr); assert(sdat1Ptr); @@ -906,6 +912,8 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { sdat1size = _sndDataSize - _sndPtrOffs; if (sdat2size < sdat1size) { + // We have space leftover at the end of sound 1 + // -> Just append sound 2 src = sdat2Ptr + 8; dst = sdat1Ptr + 8 + _sndPtrOffs; len = sdat2size; @@ -915,6 +923,8 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { _sndPtrOffs += sdat2size; _sndTmrOffs += sdat2size; } else { + // We might not have enough space leftover at the end of sound 1 + // -> Append as much of possible of sound 2 to sound 1 src = sdat2Ptr + 8; dst = sdat1Ptr + 8 + _sndPtrOffs; len = sdat1size; @@ -922,6 +932,8 @@ void ScummEngine_v80he::createSound(int snd1id, int snd2id) { memcpy(dst, src, len); if (sdat2size != sdat1size) { + // We don't have enough space + // -> Start overwriting the beginning of the sound again src = sdat2Ptr + 8 + sdat1size; dst = sdat1Ptr + 8; len = sdat2size - sdat1size; diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp index 798f703db6..ca360803bd 100644 --- a/engines/scumm/he/wiz_he.cpp +++ b/engines/scumm/he/wiz_he.cpp @@ -1548,12 +1548,18 @@ uint8 *Wiz::drawWizImage(int resNum, int state, int maskNum, int maskState, int if (rScreen.intersects(clip)) { rScreen.clip(clip); } else { + if (flags & kWIFBlitToMemBuffer) + free(dst); + return 0; } } else if (_rectOverrideEnabled) { if (rScreen.intersects(_rectOverride)) { rScreen.clip(_rectOverride); } else { + if (flags & kWIFBlitToMemBuffer) + free(dst); + return 0; } } diff --git a/engines/scumm/imuse/imuse.cpp b/engines/scumm/imuse/imuse.cpp index 016ba89e7b..12ebfef9b7 100644 --- a/engines/scumm/imuse/imuse.cpp +++ b/engines/scumm/imuse/imuse.cpp @@ -46,7 +46,6 @@ namespace Scumm { IMuseInternal::IMuseInternal() : _native_mt32(false), _enable_gs(false), - _sc55(false), _midi_adlib(NULL), _midi_native(NULL), _sysex(NULL), @@ -363,7 +362,7 @@ void IMuseInternal::pause(bool paused) { _paused = paused; } -int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm) { +int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAfterLoad) { Common::StackLock lock(_mutex, "IMuseInternal::save_or_load()"); const SaveLoadEntry mainEntries[] = { MKLINE(IMuseInternal, _queue_end, sleUint8, VER(8)), @@ -440,7 +439,16 @@ int IMuseInternal::save_or_load(Serializer *ser, ScummEngine *scumm) { for (i = 0; i < 8; ++i) ser->saveLoadEntries(0, volumeFaderEntries); - if (ser->isLoading()) { + // Normally, we have to fix up the data structures after loading a + // saved game. But there are cases where we don't. For instance, The + // Macintosh version of Monkey Island 1 used to convert the Mac0 music + // resources to General MIDI and play it through iMUSE as a rough + // approximation. Now it has its own player, but old savegame still + // have the iMUSE data in them. We have to skip that data, using a + // dummy iMUSE object, but since the resource is no longer recognizable + // to iMUSE, the fixup fails hard. So yes, this is a bit of a hack. + + if (ser->isLoading() && fixAfterLoad) { // Load all sounds that we need fix_players_after_load(scumm); fix_parts_after_load(); @@ -486,12 +494,9 @@ uint32 IMuseInternal::property(int prop, uint32 value) { case IMuse::PROP_GS: _enable_gs = (value > 0); - // If True Roland MT-32 is not selected, run in GM or GS mode. - // If it is selected, change the Roland GS synth to MT-32 mode. - if (_midi_native && !_native_mt32) - initGM(_midi_native); - else if (_midi_native && _native_mt32 && _enable_gs) { - _sc55 = true; + // GS Mode emulates MT-32 on a GS device, so _native_mt32 should always be true + if (_midi_native && _enable_gs) { + _native_mt32 = true; initGM(_midi_native); } break; @@ -1490,7 +1495,7 @@ void IMuseInternal::initGM(MidiDriver *midi) { if (_enable_gs) { // All GS devices recognize the GS Reset command, - // even with Roland's ID. It is impractical to + // even using Roland's ID. It is impractical to // support other manufacturers' devices for // further GS settings, as there are limitless // numbers of them out there that would each @@ -1504,30 +1509,28 @@ void IMuseInternal::initGM(MidiDriver *midi) { midi->sysEx(buffer, 9); debug(2, "GS SysEx: GS Reset"); _system->delayMillis(200); + + // Set global Master Tune to 442.0kHz, as on the MT-32 + memcpy(&buffer[4], "\x40\x00\x00\x00\x04\x04\x0F\x29", 8); + midi->sysEx(buffer, 12); + debug(2, "GS SysEx: Master Tune set to 442.0kHz"); - if (_sc55) { - // This mode is for GS devices that support an MT-32-compatible - // Map, such as the Roland Sound Canvas line of modules. It - // will allow them to work with True MT-32 mode, but will - // obviously still ignore MT-32 SysEx (and thus custom - // instruments). - - // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation - for (i = 0; i < 16; ++i) { - midi->send((127 << 16) | (0 << 8) | (0xB0 | i)); - midi->send((1 << 16) | (32 << 8) | (0xB0 | i)); - midi->send((0 << 16) | (0 << 8) | (0xC0 | i)); - } - debug(2, "GS Program Change: CM-64/32L Map Selected"); - - // Set Percussion Channel to SC-55 Map (CC#32, 01H), then - // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums) - midi->getPercussionChannel()->controlChange(0, 0); - midi->getPercussionChannel()->controlChange(32, 1); - midi->send(127 << 8 | 0xC0 | 9); - debug(2, "GS Program Change: Drum Map is CM-64/32L"); + // Note: All Roland GS devices support CM-64/32L maps + // Set Channels 1-16 to SC-55 Map, then CM-64/32L Variation + for (i = 0; i < 16; ++i) { + midi->send((127 << 16) | (0 << 8) | (0xB0 | i)); + midi->send((1 << 16) | (32 << 8) | (0xB0 | i)); + midi->send((0 << 16) | (0 << 8) | (0xC0 | i)); } + debug(2, "GS Program Change: CM-64/32L Map Selected"); + + // Set Percussion Channel to SC-55 Map (CC#32, 01H), then + // Switch Drum Map to CM-64/32L (MT-32 Compatible Drums) + midi->getPercussionChannel()->controlChange(0, 0); + midi->getPercussionChannel()->controlChange(32, 1); + midi->send(127 << 8 | 0xC0 | 9); + debug(2, "GS Program Change: Drum Map is CM-64/32L"); // Set Master Chorus to 0. The MT-32 has no chorus capability. memcpy(&buffer[4], "\x40\x01\x3A\x00\x05", 5); @@ -1732,10 +1735,10 @@ void IMuseInternal::copyGlobalInstrument(byte slot, Instrument *dest) { // In case we have an valid instrument set up, copy it to the part. _global_instruments[slot].copy_to(dest); } else if (_pcSpeaker) { - debug(0, "Trying to use non-existant global PC Speaker instrument %d", slot); + debug(0, "Trying to use non-existent global PC Speaker instrument %d", slot); dest->pcspk(defaultInstr); } else { - debug(0, "Trying to use non-existant global AdLib instrument %d", slot); + debug(0, "Trying to use non-existent global AdLib instrument %d", slot); dest->adlib(defaultInstr); } } diff --git a/engines/scumm/imuse/imuse.h b/engines/scumm/imuse/imuse.h index 23449e470b..cce5309229 100644 --- a/engines/scumm/imuse/imuse.h +++ b/engines/scumm/imuse/imuse.h @@ -62,7 +62,7 @@ public: public: virtual void on_timer(MidiDriver *midi) = 0; virtual void pause(bool paused) = 0; - virtual int save_or_load(Serializer *ser, ScummEngine *scumm) = 0; + virtual int save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAfterLoad = true) = 0; virtual bool get_sound_active(int sound) const = 0; virtual int32 doCommand(int numargs, int args[]) = 0; virtual int clear_queue() = 0; diff --git a/engines/scumm/imuse/imuse_internal.h b/engines/scumm/imuse/imuse_internal.h index 846e2d7545..d17d4ed28b 100644 --- a/engines/scumm/imuse/imuse_internal.h +++ b/engines/scumm/imuse/imuse_internal.h @@ -390,7 +390,6 @@ class IMuseInternal : public IMuse { protected: bool _native_mt32; bool _enable_gs; - bool _sc55; MidiDriver *_midi_adlib; MidiDriver *_midi_native; TimerCallbackInfo _timer_info_adlib; @@ -518,7 +517,7 @@ protected: public: // IMuse interface void pause(bool paused); - int save_or_load(Serializer *ser, ScummEngine *scumm); + int save_or_load(Serializer *ser, ScummEngine *scumm, bool fixAfterLoad = true); bool get_sound_active(int sound) const; int32 doCommand(int numargs, int args[]); uint32 property(int prop, uint32 value); diff --git a/engines/scumm/imuse/imuse_part.cpp b/engines/scumm/imuse/imuse_part.cpp index 89c16a8bb5..5e928f3d44 100644 --- a/engines/scumm/imuse/imuse_part.cpp +++ b/engines/scumm/imuse/imuse_part.cpp @@ -111,8 +111,19 @@ void Part::saveLoadWithSerializer(Serializer *ser) { } void Part::set_detune(int8 detune) { - _detune_eff = clamp((_detune = detune) + _player->getDetune(), -128, 127); - sendPitchBend(); + // Sam&Max does not have detune, so we just ignore this here. We still get + // this called, since Sam&Max uses the same controller for a different + // purpose. + if (_se->_game_id == GID_SAMNMAX) { +#if 0 + if (_mc) { + _mc->controlChange(17, detune + 0x40); + } +#endif + } else { + _detune_eff = clamp((_detune = detune) + _player->getDetune(), -128, 127); + sendPitchBend(); + } } void Part::pitchBend(int16 value) { diff --git a/engines/scumm/imuse_digi/dimuse.cpp b/engines/scumm/imuse_digi/dimuse.cpp index eb3717494f..a737539c44 100644 --- a/engines/scumm/imuse_digi/dimuse.cpp +++ b/engines/scumm/imuse_digi/dimuse.cpp @@ -275,9 +275,12 @@ void IMuseDigital::callback() { feedSize &= ~1; if (channels == 2) feedSize &= ~3; - } else { + } else if (bits == 8) { if (channels == 2) feedSize &= ~1; + } else { + warning("IMuseDigita::callback: Unexpected sample width, %d bits", bits); + continue; } if (feedSize == 0) diff --git a/engines/scumm/insane/insane.cpp b/engines/scumm/insane/insane.cpp index b8089ff226..44528e5bac 100644 --- a/engines/scumm/insane/insane.cpp +++ b/engines/scumm/insane/insane.cpp @@ -54,7 +54,7 @@ Insane::Insane(ScummEngine_v7 *scumm) { initvars(); - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) { + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) { readFileToMem("roadrash.rip", &_smush_roadrashRip); readFileToMem("roadrsh2.rip", &_smush_roadrsh2Rip); readFileToMem("roadrsh3.rip", &_smush_roadrsh3Rip); @@ -173,7 +173,7 @@ void Insane::initvars() { _iactBits[i] = 0; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { init_enemyStruct(EN_ROTT1, EN_ROTT1, 0, 0, 60, 0, INV_MACE, 63, "endcrshr.san", 25, 15, 16, 26, 13, 3); } else { @@ -356,7 +356,7 @@ void Insane::initvars() { init_scenePropStruct(138, 57, 0, 59, 134, 0xFF, 0xFF, 0xFF, 0, 30, 0); _actor[0].damage = 0; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) _actor[0].maxdamage = 60; else _actor[0].maxdamage = 80; @@ -466,7 +466,7 @@ void Insane::init_enemyStruct(int n, int32 handler, int32 initializer, _enemy[n].isEmpty = isEmpty; _enemy[n].weapon = weapon; _enemy[n].sound = sound; - strncpy(_enemy[n].filename, filename, 20); + Common::strlcpy(_enemy[n].filename, filename, 20); _enemy[n].costume4 = costume4; _enemy[n].costume6 = costume6; _enemy[n].costume5 = costume5; @@ -632,7 +632,7 @@ void Insane::putActors() { void Insane::readState() { // PATCH - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { _actor[0].inventory[INV_CHAIN] = 0; _actor[0].inventory[INV_CHAINSAW] = 0; _actor[0].inventory[INV_MACE] = 0; @@ -801,7 +801,7 @@ void Insane::prepareScenePropScene(int32 scenePropNum, bool arg_4, bool arg_8) { debugC(DEBUG_INSANE, "Insane::prepareScenePropScene(%d, %d, %d)", scenePropNum, arg_4, arg_8); - if (((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) || !loadScenePropSounds(idx)) + if (((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) || !loadScenePropSounds(idx)) return; _actor[0].defunct = arg_4; @@ -898,7 +898,7 @@ int32 Insane::weaponDamage(int32 actornum) { } void Insane::reinitActors() { - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { smlayer_setActorCostume(0, 2, readArray(11)); smlayer_setActorCostume(0, 0, readArray(13)); smlayer_setActorCostume(0, 1, readArray(12)); @@ -966,7 +966,7 @@ void Insane::escapeKeyHandler() { debugC(DEBUG_INSANE, "scene: %d", _currSceneId); switch (_currSceneId) { case 1: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0); } else { queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300); @@ -979,7 +979,7 @@ void Insane::escapeKeyHandler() { break; case 2: flu = &_fluConf[14 + _iactSceneId2]; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(4, 0, "tovista.san", 64, 0, 0, 0); else queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0, @@ -1033,7 +1033,7 @@ void Insane::escapeKeyHandler() { break; case 8: flu = &_fluConf[7 + _iactSceneId2]; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0); else queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0, @@ -1041,7 +1041,7 @@ void Insane::escapeKeyHandler() { break; case 7: flu = &_fluConf[0 + _iactSceneId2]; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0); else queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0, @@ -1060,7 +1060,7 @@ void Insane::escapeKeyHandler() { queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame1, 1300); break; case 13: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0); else queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, _continueFrame, 1300); @@ -1195,7 +1195,7 @@ void Insane::smlayer_setActorLayer(int actornum, int actnum, int layer) { } void Insane::smlayer_setFluPalette(byte *pal, int shut_flag) { - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) return; // if (shut_flag) @@ -1311,7 +1311,7 @@ void Insane::procSKIP(int32 subSize, Common::SeekableReadStream &b) { int16 par1, par2; _player->_skipNext = false; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { assert(subSize >= 2); par1 = b.readUint16LE(); par2 = 0; diff --git a/engines/scumm/insane/insane_ben.cpp b/engines/scumm/insane/insane_ben.cpp index 48aaab505a..a7fa72c417 100644 --- a/engines/scumm/insane/insane_ben.cpp +++ b/engines/scumm/insane/insane_ben.cpp @@ -125,7 +125,7 @@ int32 Insane::actionBen() { bool doDamage = false; int sound; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) sound = 59; else sound = 95; @@ -558,7 +558,7 @@ void Insane::actor02Reaction(int32 buttons) { _actor[0].weaponClass = 1; _actor[0].act[2].state = 3; _actor[0].act[2].tilt = calcTilt(_actor[0].tilt); - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) smlayer_startSfx(63); break; case 3: @@ -567,7 +567,7 @@ void Insane::actor02Reaction(int32 buttons) { if (_actor[0].act[2].frame == 2) { if (_currEnemy != EN_CAVEFISH) { tmp = calcEnemyDamage(1, 1); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { if (tmp == 1) smlayer_startSfx(50); } else { @@ -634,7 +634,7 @@ void Insane::actor02Reaction(int32 buttons) { _actor[0].newFacingFlag = 1; _actor[0].kicking = false; if ((_actor[0].act[2].frame == 3) && (calcEnemyDamage(0, 0) == 1)) { - _actor[1].damage = weaponDamage(0); + _actor[1].damage += weaponDamage(0); smlayer_startSfx(64); _actor[1].cursorX = 320; } @@ -805,7 +805,7 @@ void Insane::actor02Reaction(int32 buttons) { if ((_actor[1].x - _actor[0].x <= weaponMaxRange(0)) && (_actor[1].x - _actor[0].x >= weaponMinRange(0))) { smlayer_startSfx(76); - _actor[1].damage = weaponDamage(0); + _actor[1].damage += weaponDamage(0); } break; default: @@ -813,7 +813,7 @@ void Insane::actor02Reaction(int32 buttons) { smlayer_startSfx(76); break; } - smlayer_setActorFacing(0, 2, 21,180); + smlayer_setActorFacing(0, 2, 21, 180); _actor[0].act[2].state = 17; } _actor[0].act[2].tilt = calcTilt(_actor[0].tilt); @@ -855,7 +855,7 @@ void Insane::actor02Reaction(int32 buttons) { break; case INV_CHAINSAW: if (_actor[1].kicking || _actor[1].field_44) - _actor[0].act[2].state = 20; + _actor[0].act[2].state = 106; else { smlayer_setActorFacing(0, 2, 20, 180); _actor[0].act[2].state = 20; @@ -890,7 +890,7 @@ void Insane::actor02Reaction(int32 buttons) { case INV_2X4: case INV_BOOT: tmp = calcEnemyDamage(1, 1); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { if (tmp == 1) smlayer_startSfx(52); if (tmp == 1000) @@ -1015,7 +1015,7 @@ void Insane::actor02Reaction(int32 buttons) { smlayer_setActorFacing(0, 2, 19, 180); _actor[0].act[2].state = 27; _actor[0].act[2].tilt = calcTilt(_actor[0].tilt); - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) smlayer_startSfx(72); break; case 27: @@ -1058,7 +1058,7 @@ void Insane::actor02Reaction(int32 buttons) { case INV_BOOT: case INV_DUST: tmp = calcEnemyDamage(1, 1); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { if (tmp == 1) smlayer_startSfx(58); if (tmp == 1000) @@ -1170,14 +1170,15 @@ void Insane::actor02Reaction(int32 buttons) { if (!smlayer_actorNeedRedraw(0, 2)) { switchBenWeapon(); - _actor[0].act[2].tilt = 0; + _actor[0].act[2].state = 1; } _actor[0].act[2].tilt = calcTilt(_actor[0].tilt); break; case 36: + _actor[0].lost = true; smlayer_setActorLayer(0, 2, 5); _actor[0].kicking = false; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(17)); else smlayer_setActorCostume(0, 2, readArray(18)); @@ -1213,7 +1214,7 @@ void Insane::actor02Reaction(int32 buttons) { smlayer_setActorLayer(0, 2, 25); _actor[0].cursorX = 0; _actor[0].kicking = false; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { if (_actor[0].act[2].frame >= 28) { queueSceneSwitch(9, 0, "bencrshe.san", 64, 0, 0, 0); _actor[0].act[2].state = 38; @@ -1228,7 +1229,7 @@ void Insane::actor02Reaction(int32 buttons) { case EN_ROTT1: case EN_ROTT2: case EN_ROTT3: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(9, 0, "bencrshe.san", 64, 0, 0, 0); else queueSceneSwitch(9, 0, "wr2_benr.san", 64, 0, 0, 0); @@ -1901,7 +1902,7 @@ void Insane::switchBenWeapon() { switch (_actor[0].weapon) { case INV_CHAIN: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(19)); else smlayer_setActorCostume(0, 2, readArray(20)); @@ -1910,7 +1911,7 @@ void Insane::switchBenWeapon() { _actor[0].act[2].state = 34; break; case INV_CHAINSAW: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(23)); else smlayer_setActorCostume(0, 2, readArray(24)); @@ -1919,7 +1920,7 @@ void Insane::switchBenWeapon() { _actor[0].act[2].state = 34; break; case INV_MACE: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(22)); else smlayer_setActorCostume(0, 2, readArray(23)); @@ -1928,7 +1929,7 @@ void Insane::switchBenWeapon() { _actor[0].act[2].state = 34; break; case INV_2X4: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { smlayer_setActorCostume(0, 2, readArray(18)); } else { if (_currEnemy == EN_CAVEFISH) @@ -1941,7 +1942,7 @@ void Insane::switchBenWeapon() { _actor[0].act[2].state = 34; break; case INV_WRENCH: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(24)); else smlayer_setActorCostume(0, 2, readArray(25)); @@ -1952,7 +1953,7 @@ void Insane::switchBenWeapon() { case INV_BOOT: case INV_HAND: case INV_DUST: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(11)); else smlayer_setActorCostume(0, 2, readArray(12)); @@ -2003,7 +2004,7 @@ int32 Insane::setBenState() { void Insane::ouchSoundBen() { _actor[0].act[3].state = 52; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { smlayer_startVoice(54); return; } diff --git a/engines/scumm/insane/insane_enemy.cpp b/engines/scumm/insane/insane_enemy.cpp index 913f761f31..fa6d4264ec 100644 --- a/engines/scumm/insane/insane_enemy.cpp +++ b/engines/scumm/insane/insane_enemy.cpp @@ -266,6 +266,8 @@ int32 Insane::enemy1handler(int32 actor1, int32 actor2, int32 probability) { _enHdlVar[EN_ROTT2][0] = 0; else _enHdlVar[EN_ROTT2][0] = 1; + } else { + _enHdlVar[EN_ROTT2][0] = 1; } _enHdlVar[EN_ROTT2][1] = 0; _enHdlVar[EN_ROTT2][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1); @@ -310,7 +312,7 @@ int32 Insane::enemy1handler(int32 actor1, int32 actor2, int32 probability) { retval = 1; } if (_actor[actor2].kicking) { - if (weaponMaxRange(actor2) <= dist) + if (weaponMaxRange(actor2) >= dist) if (_vm->_rnd.getRandomNumber(probability * 2 - 1) <= 1) retval = 1; } @@ -369,6 +371,8 @@ int32 Insane::enemy1handler(int32 actor1, int32 actor2, int32 probability) { _actor[actor1].cursorX = 320; else if (act1x > 280) _actor[actor1].cursorX = -160; + else if (_actor[actor1].defunct) + _actor[actor1].cursorX = 0; // Shift+V cheat to win the battle if (_vm->getKeyState('V') && !_beenCheated && @@ -410,7 +414,9 @@ int32 Insane::enemy2handler(int32 actor1, int32 actor2, int32 probability) { _enHdlVar[EN_ROTT3][0] = 0; else _enHdlVar[EN_ROTT3][0] = 1; - } + } else + _enHdlVar[EN_ROTT3][0] = 1; + _enHdlVar[EN_ROTT3][1] = 0; _enHdlVar[EN_ROTT3][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1); } @@ -453,7 +459,7 @@ int32 Insane::enemy2handler(int32 actor1, int32 actor2, int32 probability) { retval = 1; } if (_actor[actor2].kicking) { - if (weaponMaxRange(actor2) >= dist) + if (weaponMaxRange(actor2) <= dist) if (_vm->_rnd.getRandomNumber(probability * 2 - 1) <= 1) retval = 1; } @@ -553,9 +559,12 @@ int32 Insane::enemy3handler(int32 actor1, int32 actor2, int32 probability) { if (!_actor[actor1].defunct) { if (_enHdlVar[EN_VULTF1][1] > _enHdlVar[EN_VULTF1][2]) { - if ((act1damage - act2damage >= 30) && (_vm->_rnd.getRandomNumber(probability - 1) != 1)) - _enHdlVar[EN_VULTF1][0] = 0; - else + if (act1damage - act2damage >= 30) { + if (_vm->_rnd.getRandomNumber(probability - 1) != 1) + _enHdlVar[EN_VULTF1][0] = 0; + else + _enHdlVar[EN_VULTF1][0] = 1; + } else _enHdlVar[EN_VULTF1][0] = 1; _enHdlVar[EN_VULTF1][1] = 0; @@ -714,7 +723,9 @@ int32 Insane::enemy4handler(int32 actor1, int32 actor2, int32 probability) { _enHdlVar[EN_VULTM1][0] = 0; else _enHdlVar[EN_VULTM1][0] = 1; - } + } else + _enHdlVar[EN_VULTM1][0] = 1; + _enHdlVar[EN_VULTM1][1] = 0; _enHdlVar[EN_VULTM1][2] = _vm->_rnd.getRandomNumber(probability * 2 - 1); } @@ -757,7 +768,7 @@ int32 Insane::enemy4handler(int32 actor1, int32 actor2, int32 probability) { retval = 1; } if (_actor[actor2].kicking) { - if (weaponMaxRange(actor2) >= dist) // that's weird but original is >= + if (weaponMaxRange(actor2) >= dist) if (_vm->_rnd.getRandomNumber(probability * 2 - 1) <= 1) retval = 1; } @@ -792,12 +803,12 @@ int32 Insane::enemy4handler(int32 actor1, int32 actor2, int32 probability) { case 3: prepareScenePropScene(44, 0, 0); break; - case 9: + case 9: // Original is 10 here which never happens prepareScenePropScene(45, 0, 0); break; } } else { - if (weaponMaxRange(actor2) <= dist) { + if (weaponMaxRange(actor2) >= dist) { switch (_vm->_rnd.getRandomNumber(9)) { case 3: if (!_enemyState[EN_VULTM1][3]) { @@ -805,7 +816,7 @@ int32 Insane::enemy4handler(int32 actor1, int32 actor2, int32 probability) { prepareScenePropScene(42, 0, 0); } break; - case 9: + case 9: // Original is 10 here which never happens if (!_enemyState[EN_VULTM1][4]) { _enemyState[EN_VULTM1][4] = 1; prepareScenePropScene(43, 0, 0); @@ -901,12 +912,8 @@ int32 Insane::enemy5handler(int32 actor1, int32 actor2, int32 probability) { retval = 1; } else { if (weaponMaxRange(actor2) >= dist && _actor[actor2].weapon == INV_CHAINSAW) { - if (!_actor[actor2].kicking) { - if (_vm->_rnd.getRandomNumber(probability - 1) == 1) - retval = 1; - } else { + if (_actor[actor2].kicking || (_vm->_rnd.getRandomNumber(probability - 1) == 1)) retval = 1; - } } _actor[actor1].cursorX = 0; if (_enHdlVar[EN_VULTF2][0] >= 100) @@ -944,7 +951,7 @@ int32 Insane::enemy5handler(int32 actor1, int32 actor2, int32 probability) { prepareScenePropScene(11, 0, 0); _enemyState[EN_VULTF2][2] = 1; break; - case 9: + case 9: // Original is 10 _enemyState[EN_VULTF2][1] = 1; prepareScenePropScene(10, 0, 0); break; @@ -969,9 +976,6 @@ int32 Insane::enemy5handler(int32 actor1, int32 actor2, int32 probability) { } } - if (_actor[actor1].defunct) - _actor[actor1].cursorX = 0; - if (_actor[actor1].weapon == -1) retval = 2; @@ -981,6 +985,8 @@ int32 Insane::enemy5handler(int32 actor1, int32 actor2, int32 probability) { _actor[actor1].cursorX = 320; else if (act1x > 280) _actor[actor1].cursorX = -160; + else if (_actor[actor1].defunct) + _actor[actor1].cursorX = 0; _enHdlVar[EN_VULTF2][2] = _enHdlVar[EN_VULTF2][1]; _enHdlVar[EN_VULTF2][0]++; @@ -1106,10 +1112,14 @@ int32 Insane::enemy6handler(int32 actor1, int32 actor2, int32 probability) { _actor[actor1].cursorX = 320; else if (act1x > 280) _actor[actor1].cursorX = -160; + else + _actor[actor1].cursorX = 0; if (_actor[actor1].weapon == -1) retval = 2; + _enHdlVar[EN_VULTM2][0]++; + // Shift+V cheat to win the battle if (_vm->getKeyState('V') && !_beenCheated && !_actor[0].lost && !_actor[1].lost) { @@ -1234,7 +1244,7 @@ void Insane::ouchSoundEnemy() { _actor[1].act[3].state = 52; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { smlayer_startVoice(55); return; } @@ -1661,7 +1671,7 @@ void Insane::actor12Reaction(int32 buttons) { _actor[1].weaponClass = 1; _actor[1].act[2].state = 3; _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) smlayer_startSfx(63); break; case 3: @@ -1669,7 +1679,7 @@ void Insane::actor12Reaction(int32 buttons) { _actor[1].weaponClass = 1; if (_actor[1].act[2].frame >= 6) { tmp = calcBenDamage(1, 1); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { if (tmp == 1) smlayer_startSfx(50); } else if (tmp == 1) @@ -1841,7 +1851,7 @@ void Insane::actor12Reaction(int32 buttons) { smlayer_setActorFacing(1, 2, 19, 180); _actor[1].act[2].state = 19; _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) { + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) { smlayer_startSfx(69); if (!_actor[1].field_54) { tmp = _vm->_rnd.getRandomNumber(4); @@ -1892,6 +1902,7 @@ void Insane::actor12Reaction(int32 buttons) { break; } } + _actor[1].kicking = true; _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); break; case 20: @@ -1905,7 +1916,7 @@ void Insane::actor12Reaction(int32 buttons) { case INV_2X4: case INV_BOOT: tmp = calcBenDamage(1, 1); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { if (tmp == 1) smlayer_startSfx(52); else if (tmp == 1000) @@ -1932,6 +1943,7 @@ void Insane::actor12Reaction(int32 buttons) { _actor[1].kicking = false; if (_actor[1].act[2].frame >= 5) { smlayer_setActorFacing(1, 2, 25, 180); + smlayer_setActorLayer(1, 2, 5); _actor[1].act[2].state = 65; } _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); @@ -2012,7 +2024,6 @@ void Insane::actor12Reaction(int32 buttons) { } else { smlayer_setActorFacing(1, 2, 20, 180); _actor[1].act[2].state = 28; - break; } } _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); @@ -2023,7 +2034,7 @@ void Insane::actor12Reaction(int32 buttons) { _actor[1].kicking = true; if (_actor[1].act[2].frame >= 3) { tmp = calcBenDamage(1, 1); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { if (tmp == 1) smlayer_startSfx(57); } else if (tmp == 1) @@ -2063,10 +2074,8 @@ void Insane::actor12Reaction(int32 buttons) { smlayer_setActorLayer(1, 2, 5); _actor[1].kicking = false; - if (!smlayer_actorNeedRedraw(1, 2)) { + if (!smlayer_actorNeedRedraw(1, 2)) switchEnemyWeapon(); - _actor[1].act[2].tilt = 0; - } _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); break; case 36: @@ -2079,7 +2088,7 @@ void Insane::actor12Reaction(int32 buttons) { smlayer_setActorLayer(1, 2, 25); _actor[1].act[2].state = 37; - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) { + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) { smlayer_startSfx(96); switch (_currEnemy) { case EN_ROTT1: @@ -2156,16 +2165,8 @@ void Insane::actor12Reaction(int32 buttons) { _actor[1].kicking = false; _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); break; + case 62: case 65: - smlayer_setActorLayer(1, 2, 5); - if (_actor[1].act[2].animTilt) { - smlayer_setActorFacing(1, 2, 25, 180); - _actor[1].act[2].animTilt = 0; - } - _actor[1].weaponClass = 1; - _actor[1].kicking = false; - _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); - break; case 66: smlayer_setActorLayer(1, 2, 5); if (_actor[1].act[2].animTilt) { @@ -2322,6 +2323,7 @@ void Insane::actor12Reaction(int32 buttons) { smlayer_startSfx(100); _actor[1].act[2].state = 90; _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); + smlayer_setActorLayer(1, 2, 26); break; case 90: smlayer_setActorLayer(1, 2, 26); @@ -2343,6 +2345,7 @@ void Insane::actor12Reaction(int32 buttons) { _actor[1].kicking = false; break; case 92: + case 96: smlayer_setActorLayer(1, 2, 5); _actor[1].kicking = false; break; @@ -2353,6 +2356,7 @@ void Insane::actor12Reaction(int32 buttons) { smlayer_setActorFacing(1, 2, 18, 180); _actor[1].act[2].state = 94; _actor[1].act[2].tilt = calcTilt(_actor[1].tilt); + smlayer_startSfx(102); break; case 94: smlayer_setActorLayer(1, 2, 4); @@ -2529,7 +2533,6 @@ void Insane::actor12Reaction(int32 buttons) { _actor[1].act[0].room = 0; _actor[1].cursorX = 0; _actor[1].act[2].state = 116; - smlayer_startVoice(232); break; case 116: smlayer_setActorLayer(1, 2, 25); diff --git a/engines/scumm/insane/insane_iact.cpp b/engines/scumm/insane/insane_iact.cpp index 48c96b537c..9c395beea6 100644 --- a/engines/scumm/insane/insane_iact.cpp +++ b/engines/scumm/insane/insane_iact.cpp @@ -171,7 +171,7 @@ void Insane::iactScene1(byte *renderBitmap, int32 codecparam, int32 setupsan12, } void Insane::chooseEnemy() { - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { _currEnemy = EN_ROTT1; return; } diff --git a/engines/scumm/insane/insane_scenes.cpp b/engines/scumm/insane/insane_scenes.cpp index db0b0171bc..06d5d7ac68 100644 --- a/engines/scumm/insane/insane_scenes.cpp +++ b/engines/scumm/insane/insane_scenes.cpp @@ -61,7 +61,7 @@ void Insane::runScene(int arraynum) { case 1: initScene(1); setupValues(); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(9)); else smlayer_setActorCostume(0, 2, readArray(10)); @@ -70,14 +70,14 @@ void Insane::runScene(int arraynum) { break; case 2: setupValues(); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(10)); else smlayer_setActorCostume(0, 2, readArray(11)); smlayer_putActor(0, 2, _actor[0].x, _actor[0].y1 + 190, _smlayer_room2); _mainRoadPos = readArray(2); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { initScene(5); startVideo("tovista.san", 1, 32, 12, 0); } else if (_mainRoadPos == _posBrokenTruck) { @@ -93,7 +93,7 @@ void Insane::runScene(int arraynum) { break; case 3: setupValues(); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(10)); else smlayer_setActorCostume(0, 2, readArray(11)); @@ -148,7 +148,7 @@ void Insane::runScene(int arraynum) { _insaneIsRunning = false; _player->insanity(false); - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) { + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) { writeArray(50, _actor[0].inventory[INV_CHAIN]); writeArray(51, _actor[0].inventory[INV_CHAINSAW]); writeArray(52, _actor[0].inventory[INV_MACE]); @@ -243,7 +243,7 @@ void Insane::stopSceneSounds(int sceneId) { _actor[1].defunct = 0; _actor[1].scenePropSubIdx = 0; _actor[1].field_54 = 0; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { smlayer_stopSound(59); smlayer_stopSound(63); } else { @@ -319,7 +319,7 @@ void Insane::shutCurrentScene() { // insane_loadSceneData1 & insane_loadSceneData2 int Insane::loadSceneData(int scene, int flag, int phase) { - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) return 1; int retvalue = 1; @@ -621,7 +621,7 @@ void Insane::setSceneCostumes(int sceneId) { switch (sceneId) { case 1: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(9)); else smlayer_setActorCostume(0, 2, readArray(10)); @@ -634,7 +634,7 @@ void Insane::setSceneCostumes(int sceneId) { setupValues(); return; case 2: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(9)); else smlayer_setActorCostume(0, 2, readArray(10)); @@ -653,7 +653,7 @@ void Insane::setSceneCostumes(int sceneId) { case 4: case 5: case 6: - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) smlayer_setActorCostume(0, 2, readArray(10)); else smlayer_setActorCostume(0, 2, readArray(11)); @@ -672,7 +672,7 @@ void Insane::setEnemyCostumes() { debugC(DEBUG_INSANE, "setEnemyCostumes(%d)", _currEnemy); - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { smlayer_setActorCostume(0, 2, readArray(11)); smlayer_setActorCostume(0, 0, readArray(13)); smlayer_setActorCostume(0, 1, readArray(12)); @@ -1000,7 +1000,7 @@ void Insane::postCase11(byte *renderBitmap, int32 codecparam, int32 setupsan12, if (_firstBattle) { smush_setToFinish(); } else { - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0); else queueSceneSwitch(1, _smush_minedrivFlu, "minedriv.san", 64, 0, @@ -1096,7 +1096,7 @@ void Insane::postCase1(byte *renderBitmap, int32 codecparam, int32 setupsan12, if ((curFrame >= maxFrame) && !_needSceneSwitch) { flu = &_fluConf[14 + _iactSceneId2]; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(4, 0, "tovista.san", 64, 0, 0, 0); else queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0, @@ -1224,7 +1224,7 @@ void Insane::postCase6(byte *renderBitmap, int32 codecparam, int32 setupsan12, else flu = &_fluConf[0 + _iactSceneId2]; - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0); else queueSceneSwitch(flu->sceneId, *flu->fluPtr, flu->filenamePtr, 64, 0, @@ -1243,7 +1243,7 @@ void Insane::postCase8(byte *renderBitmap, int32 codecparam, int32 setupsan12, queueSceneSwitch(13, _smush_minefiteFlu, "minefite.san", 64, 0, _continueFrame, 1300); } else { - if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC)) { + if ((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS)) { queueSceneSwitch(1, 0, "minedriv.san", 64, 0, 0, 0); } else { if (_currSceneId == 23) { diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index 8499c9bad3..28884d7f78 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -36,6 +36,7 @@ MODULE_OBJS := \ object.o \ palette.o \ player_apple2.o \ + player_mac.o \ player_mod.o \ player_nes.o \ player_pce.o \ @@ -47,7 +48,9 @@ MODULE_OBJS := \ player_v2base.o \ player_v2cms.o \ player_v3a.o \ + player_v3m.o \ player_v4a.o \ + player_v5m.o \ resource_v2.o \ resource_v3.o \ resource_v4.o \ diff --git a/engines/scumm/music.h b/engines/scumm/music.h index a527c77b72..9fd14d830e 100644 --- a/engines/scumm/music.h +++ b/engines/scumm/music.h @@ -24,6 +24,7 @@ #define SCUMM_MUSIC_H #include "common/scummsys.h" +#include "engines/scumm/saveload.h" namespace Scumm { @@ -78,6 +79,11 @@ public: * @return the music timer */ virtual int getMusicTimer() { return 0; } + + /** + * Save or load the music state. + */ + virtual void saveLoadWithSerializer(Serializer *ser) {} }; } // End of namespace Scumm diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp index 77c75c4ad6..ed77a863cd 100644 --- a/engines/scumm/object.cpp +++ b/engines/scumm/object.cpp @@ -433,10 +433,14 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) { y = od.y_pos + (int16)READ_LE_UINT16(&imhd->old.hotspot[state].y); } } else if (_game.version <= 2) { - if (od.actordir) { - x = od.walk_x; - y = od.walk_y; - } else { + x = od.walk_x; + y = od.walk_y; + + // Adjust x, y when no actor direction is set, but only perform this + // adjustment for V0 games (e.g. MM C64), otherwise certain scenes in + // newer games are affected as well (e.g. the interior of the Shuttle + // Bus scene in Zak V2, where no actor is present). Refer to bug #3526089. + if (!od.actordir && _game.version == 0) { x = od.x_pos + od.width / 2; y = od.y_pos + od.height / 2; } diff --git a/engines/scumm/player_mac.cpp b/engines/scumm/player_mac.cpp new file mode 100644 index 0000000000..c16c85bff3 --- /dev/null +++ b/engines/scumm/player_mac.cpp @@ -0,0 +1,415 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "common/macresman.h" +#include "common/translation.h" +#include "engines/engine.h" +#include "gui/message.h" +#include "scumm/player_mac.h" +#include "scumm/resource.h" +#include "scumm/scumm.h" +#include "scumm/imuse/imuse.h" + +namespace Scumm { + +Player_Mac::Player_Mac(ScummEngine *scumm, Audio::Mixer *mixer, int numberOfChannels, int channelMask, bool fadeNoteEnds) + : _vm(scumm), + _mixer(mixer), + _sampleRate(_mixer->getOutputRate()), + _soundPlaying(-1), + _numberOfChannels(numberOfChannels), + _channelMask(channelMask), + _fadeNoteEnds(fadeNoteEnds) { + assert(scumm); + assert(mixer); +} + +void Player_Mac::init() { + _channel = new Player_Mac::Channel[_numberOfChannels]; + + int i; + + for (i = 0; i < _numberOfChannels; i++) { + _channel[i]._looped = false; + _channel[i]._length = 0; + _channel[i]._data = NULL; + _channel[i]._pos = 0; + _channel[i]._pitchModifier = 0; + _channel[i]._velocity = 0; + _channel[i]._remaining = 0; + _channel[i]._notesLeft = false; + _channel[i]._instrument._data = NULL; + _channel[i]._instrument._size = 0; + _channel[i]._instrument._rate = 0; + _channel[i]._instrument._loopStart = 0; + _channel[i]._instrument._loopEnd = 0; + _channel[i]._instrument._baseFreq = 0; + _channel[i]._instrument._pos = 0; + _channel[i]._instrument._subPos = 0; + } + + _pitchTable[116] = 1664510; + _pitchTable[117] = 1763487; + _pitchTable[118] = 1868350; + _pitchTable[119] = 1979447; + _pitchTable[120] = 2097152; + _pitchTable[121] = 2221855; + _pitchTable[122] = 2353973; + _pitchTable[123] = 2493948; + _pitchTable[124] = 2642246; + _pitchTable[125] = 2799362; + _pitchTable[126] = 2965820; + _pitchTable[127] = 3142177; + for (i = 115; i >= 0; --i) { + _pitchTable[i] = _pitchTable[i + 12] / 2; + } + + setMusicVolume(255); + + if (!checkMusicAvailable()) { + return; + } + + _mixer->playStream(Audio::Mixer::kPlainSoundType, &_soundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); +} + +Player_Mac::~Player_Mac() { + Common::StackLock lock(_mutex); + _mixer->stopHandle(_soundHandle); + stopAllSounds_Internal(); + delete[] _channel; +} + +void Player_Mac::saveLoadWithSerializer(Serializer *ser) { + Common::StackLock lock(_mutex); + if (ser->getVersion() < VER(94)) { + if (_vm->_game.id == GID_MONKEY && ser->isLoading()) { + IMuse *dummyImuse = IMuse::create(_vm->_system, NULL, NULL); + dummyImuse->save_or_load(ser, _vm, false); + delete dummyImuse; + } + } else { + static const SaveLoadEntry musicEntries[] = { + MKLINE(Player_Mac, _sampleRate, sleUint32, VER(94)), + MKLINE(Player_Mac, _soundPlaying, sleInt16, VER(94)), + MKEND() + }; + + static const SaveLoadEntry channelEntries[] = { + MKLINE(Channel, _pos, sleUint16, VER(94)), + MKLINE(Channel, _pitchModifier, sleInt32, VER(94)), + MKLINE(Channel, _velocity, sleUint8, VER(94)), + MKLINE(Channel, _remaining, sleUint32, VER(94)), + MKLINE(Channel, _notesLeft, sleUint8, VER(94)), + MKEND() + }; + + static const SaveLoadEntry instrumentEntries[] = { + MKLINE(Instrument, _pos, sleUint32, VER(94)), + MKLINE(Instrument, _subPos, sleUint32, VER(94)), + MKEND() + }; + + uint32 mixerSampleRate = _sampleRate; + int i; + + ser->saveLoadEntries(this, musicEntries); + + if (ser->isLoading() && _soundPlaying != -1) { + const byte *ptr = _vm->getResourceAddress(rtSound, _soundPlaying); + assert(ptr); + loadMusic(ptr); + } + + ser->saveLoadArrayOf(_channel, _numberOfChannels, sizeof(Channel), channelEntries); + for (i = 0; i < _numberOfChannels; i++) { + ser->saveLoadEntries(&_channel[i], instrumentEntries); + } + + if (ser->isLoading()) { + // If necessary, adjust the channel data to fit the + // current sample rate. + if (_soundPlaying != -1 && _sampleRate != mixerSampleRate) { + double mult = (double)_sampleRate / (double)mixerSampleRate; + for (i = 0; i < _numberOfChannels; i++) { + _channel[i]._pitchModifier = (int)((double)_channel[i]._pitchModifier * mult); + _channel[i]._remaining = (int)((double)_channel[i]._remaining / mult); + } + } + _sampleRate = mixerSampleRate; + } + } +} + +void Player_Mac::setMusicVolume(int vol) { + debug(5, "Player_Mac::setMusicVolume(%d)", vol); +} + +void Player_Mac::stopAllSounds_Internal() { + if (_soundPlaying != -1) { + _vm->_res->unlock(rtSound, _soundPlaying); + } + _soundPlaying = -1; + for (int i = 0; i < _numberOfChannels; i++) { + // The channel data is managed by the resource manager, so + // don't delete that. + delete[] _channel[i]._instrument._data; + _channel[i]._instrument._data = NULL; + + _channel[i]._remaining = 0; + _channel[i]._notesLeft = false; + } +} + +void Player_Mac::stopAllSounds() { + Common::StackLock lock(_mutex); + debug(5, "Player_Mac::stopAllSounds()"); + stopAllSounds_Internal(); +} + +void Player_Mac::stopSound(int nr) { + Common::StackLock lock(_mutex); + debug(5, "Player_Mac::stopSound(%d)", nr); + + if (nr == _soundPlaying) { + stopAllSounds(); + } +} + +void Player_Mac::startSound(int nr) { + Common::StackLock lock(_mutex); + debug(5, "Player_Mac::startSound(%d)", nr); + + stopAllSounds_Internal(); + + const byte *ptr = _vm->getResourceAddress(rtSound, nr); + assert(ptr); + + if (!loadMusic(ptr)) { + return; + } + + _vm->_res->lock(rtSound, nr); + _soundPlaying = nr; +} + +bool Player_Mac::Channel::loadInstrument(Common::SeekableReadStream *stream) { + uint16 soundType = stream->readUint16BE(); + if (soundType != 1) { + warning("Player_Mac::loadInstrument: Unsupported sound type %d", soundType); + return false; + } + uint16 typeCount = stream->readUint16BE(); + if (typeCount != 1) { + warning("Player_Mac::loadInstrument: Unsupported data type count %d", typeCount); + return false; + } + uint16 dataType = stream->readUint16BE(); + if (dataType != 5) { + warning("Player_Mac::loadInstrument: Unsupported data type %d", dataType); + return false; + } + + stream->readUint32BE(); // initialization option + + uint16 cmdCount = stream->readUint16BE(); + if (cmdCount != 1) { + warning("Player_Mac::loadInstrument: Unsupported command count %d", cmdCount); + return false; + } + uint16 command = stream->readUint16BE(); + if (command != 0x8050 && command != 0x8051) { + warning("Player_Mac::loadInstrument: Unsupported command 0x%04X", command); + return false; + } + + stream->readUint16BE(); // 0 + uint32 soundHeaderOffset = stream->readUint32BE(); + + stream->seek(soundHeaderOffset); + + uint32 soundDataOffset = stream->readUint32BE(); + uint32 size = stream->readUint32BE(); + uint32 rate = stream->readUint32BE() >> 16; + uint32 loopStart = stream->readUint32BE(); + uint32 loopEnd = stream->readUint32BE(); + byte encoding = stream->readByte(); + byte baseFreq = stream->readByte(); + + if (encoding != 0) { + warning("Player_Mac::loadInstrument: Unsupported encoding %d", encoding); + return false; + } + + stream->skip(soundDataOffset); + + byte *data = new byte[size]; + stream->read(data, size); + + _instrument._data = data; + _instrument._size = size; + _instrument._rate = rate; + _instrument._loopStart = loopStart; + _instrument._loopEnd = loopEnd; + _instrument._baseFreq = baseFreq; + + return true; +} + +int Player_Mac::getMusicTimer() { + return 0; +} + +int Player_Mac::getSoundStatus(int nr) const { + return _soundPlaying == nr; +} + +uint32 Player_Mac::durationToSamples(uint16 duration) { + // The correct formula should be: + // + // (duration * 473 * _sampleRate) / (4 * 480 * 480) + // + // But that's likely to cause integer overflow, so we do it in two + // steps and hope that the rounding error won't be noticeable. + // + // The original code is a bit unclear on if it should be 473 or 437, + // but since the comments indicated 473 I'm assuming 437 was a typo. + uint32 samples = (duration * _sampleRate) / (4 * 480); + samples = (samples * 473) / 480; + return samples; +} + +int Player_Mac::noteToPitchModifier(byte note, Instrument *instrument) { + if (note > 0) { + const int pitchIdx = note + 60 - instrument->_baseFreq; + // I don't want to use floating-point arithmetics here, but I + // ran into overflow problems with the church music in Monkey + // Island. It's only once per note, so it should be ok. + double mult = (double)instrument->_rate / (double)_sampleRate; + return (int)(mult * _pitchTable[pitchIdx]); + } else { + return 0; + } +} + +int Player_Mac::readBuffer(int16 *data, const int numSamples) { + Common::StackLock lock(_mutex); + + memset(data, 0, numSamples * 2); + if (_soundPlaying == -1) { + return numSamples; + } + + bool notesLeft = false; + + for (int i = 0; i < _numberOfChannels; i++) { + if (!(_channelMask & (1 << i))) { + continue; + } + + uint samplesLeft = numSamples; + int16 *ptr = data; + + while (samplesLeft > 0) { + int generated; + if (_channel[i]._remaining == 0) { + uint32 samples; + int pitchModifier; + byte velocity; + if (getNextNote(i, samples, pitchModifier, velocity)) { + _channel[i]._remaining = samples; + _channel[i]._pitchModifier = pitchModifier; + _channel[i]._velocity = velocity; + + } else { + _channel[i]._pitchModifier = 0; + _channel[i]._velocity = 0; + _channel[i]._remaining = samplesLeft; + } + } + generated = MIN<uint32>(_channel[i]._remaining, samplesLeft); + if (_channel[i]._velocity != 0) { + _channel[i]._instrument.generateSamples(ptr, _channel[i]._pitchModifier, _channel[i]._velocity, generated, _channel[i]._remaining, _fadeNoteEnds); + } + ptr += generated; + samplesLeft -= generated; + _channel[i]._remaining -= generated; + } + + if (_channel[i]._notesLeft) { + notesLeft = true; + } + } + + if (!notesLeft) { + stopAllSounds_Internal(); + } + + return numSamples; +} + +void Player_Mac::Instrument::generateSamples(int16 *data, int pitchModifier, int volume, int numSamples, int remainingSamplesOnNote, bool fadeNoteEnds) { + int samplesLeft = numSamples; + while (samplesLeft) { + _subPos += pitchModifier; + while (_subPos >= 0x10000) { + _subPos -= 0x10000; + _pos++; + if (_pos >= _loopEnd) { + _pos = _loopStart; + } + } + + int newSample = (((int16)((_data[_pos] << 8) ^ 0x8000)) * volume) / 255; + + if (fadeNoteEnds) { + // Fade out the last 100 samples on each note. Even at + // low output sample rates this is just a fraction of a + // second, but it gets rid of distracting "pops" at the + // end when the sample would otherwise go abruptly from + // something to nothing. This was particularly + // noticeable on the distaff notes in Loom. + // + // The reason it's conditional is that Monkey Island + // appears to have a "hold current note" command, and + // if we fade out the current note in that case we + // will actually introduce new "pops". + + remainingSamplesOnNote--; + if (remainingSamplesOnNote < 100) { + newSample = (newSample * remainingSamplesOnNote) / 100; + } + } + + int sample = *data + newSample; + if (sample > 32767) { + sample = 32767; + } else if (sample < -32768) { + sample = -32768; + } + + *data++ = sample; + samplesLeft--; + } +} + +} // End of namespace Scumm diff --git a/engines/scumm/player_mac.h b/engines/scumm/player_mac.h new file mode 100644 index 0000000000..09307b4e57 --- /dev/null +++ b/engines/scumm/player_mac.h @@ -0,0 +1,133 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_PLAYER_MAC_H +#define SCUMM_PLAYER_MAC_H + +#include "common/scummsys.h" +#include "common/util.h" +#include "common/mutex.h" +#include "scumm/music.h" +#include "scumm/saveload.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" + +#define RES_SND MKTAG('s', 'n', 'd', ' ') + +class Mixer; + +namespace Scumm { + +class ScummEngine; + +/** + * Scumm Macintosh music driver, base class. + */ +class Player_Mac : public Audio::AudioStream, public MusicEngine { +public: + Player_Mac(ScummEngine *scumm, Audio::Mixer *mixer, int numberOfChannels, int channelMask, bool fadeNoteEnds); + virtual ~Player_Mac(); + + void init(); + + // MusicEngine API + virtual void setMusicVolume(int vol); + virtual void startSound(int sound); + virtual void stopSound(int sound); + virtual void stopAllSounds(); + virtual int getMusicTimer(); + virtual int getSoundStatus(int sound) const; + + // AudioStream API + virtual int readBuffer(int16 *buffer, const int numSamples); + virtual bool isStereo() const { return false; } + virtual bool endOfData() const { return false; } + virtual int getRate() const { return _sampleRate; } + + virtual void saveLoadWithSerializer(Serializer *ser); + +private: + Common::Mutex _mutex; + Audio::Mixer *const _mixer; + Audio::SoundHandle _soundHandle; + uint32 _sampleRate; + int _soundPlaying; + + void stopAllSounds_Internal(); + + struct Instrument { + byte *_data; + uint32 _size; + uint32 _rate; + uint32 _loopStart; + uint32 _loopEnd; + byte _baseFreq; + + uint _pos; + uint _subPos; + + void newNote() { + _pos = 0; + _subPos = 0; + } + + void generateSamples(int16 *data, int pitchModifier, int volume, int numSamples, int remainingSamplesOnNote, bool fadeNoteEnds); + }; + + int _pitchTable[128]; + int _numberOfChannels; + int _channelMask; + bool _fadeNoteEnds; + + virtual bool checkMusicAvailable() { return false; } + virtual bool loadMusic(const byte *ptr) { return false; } + virtual bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) { return false; } + +protected: + struct Channel { + virtual ~Channel() {} + + Instrument _instrument; + bool _looped; + uint32 _length; + const byte *_data; + + uint _pos; + int _pitchModifier; + byte _velocity; + uint32 _remaining; + + bool _notesLeft; + + bool loadInstrument(Common::SeekableReadStream *stream); + }; + + ScummEngine *const _vm; + Channel *_channel; + + uint32 durationToSamples(uint16 duration); + int noteToPitchModifier(byte note, Instrument *instrument); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/player_v3m.cpp b/engines/scumm/player_v3m.cpp new file mode 100644 index 0000000000..0f222d84fe --- /dev/null +++ b/engines/scumm/player_v3m.cpp @@ -0,0 +1,214 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + We have the following information from Lars Christensen (lechimp) and + Jamieson Christian (jamieson630): + + RESOURCE DATA + LE 2 bytes Resource size + 2 bytes Unknown + 2 bytes 'so' + 14 bytes Unknown + BE 2 bytes Instrument for Stream 1 + BE 2 bytes Instrument for Stream 2 + BE 2 bytes Instrument for Stream 3 + BE 2 bytes Instrument for Stream 4 + BE 2 bytes Instrument for Stream 5 + BE 2 bytes Offset to Stream 1 + BE 2 bytes Offset to Stream 2 + BE 2 bytes Offset to Stream 3 + BE 2 bytes Offset to Stream 4 + BE 2 bytes Offset to Stream 5 + ? bytes The streams + + STREAM DATA + BE 2 bytes Unknown (always 1?) + 2 bytes Unknown (always 0?) + BE 2 bytes Number of events in stream + ? bytes Stream data + + Each stream event is exactly 3 bytes, therefore one can + assert that numEvents == (streamSize - 6) / 3. The + polyphony of a stream appears to be 1; in other words, only + one note at a time can be playing in each stream. The next + event is not executed until the current note (or rest) is + finished playing; therefore, note duration also serves as the + time delta between events. + + FOR EACH EVENTS + BE 2 bytes Note duration + 1 byte Note number to play (0 = rest/silent) + + Oh, and quick speculation -- Stream 1 may be used for a + single-voice interleaved version of the music, where Stream 2- + 5 represent a version of the music in up to 4-voice + polyphony, one voice per stream. I postulate thus because + the first stream of the Mac Loom theme music contains + interleaved voices, whereas the second stream seemed to + contain only the pizzicato bottom-end harp. Stream 5, in this + example, is empty, so if my speculation is correct, this + particular musical number supports 3-voice polyphony at + most. I must check out Streams 3 and 4 to see what they + contain. + + ========== + + The instruments appear to be identified by their resource IDs: + + 1000 Dual Harp + 10895 harp1 + 11445 strings1 + 11548 silent + 13811 staff1 + 15703 brass1 + 16324 flute1 + 25614 accordian 1 + 28110 f horn1 + 29042 bassoon1 +*/ + +#include "common/macresman.h" +#include "common/translation.h" +#include "engines/engine.h" +#include "gui/message.h" +#include "scumm/player_v3m.h" +#include "scumm/scumm.h" + +namespace Scumm { + +Player_V3M::Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer) + : Player_Mac(scumm, mixer, 5, 0x1E, true) { + assert(_vm->_game.id == GID_LOOM); + + // Channel 0 seems to be what was played on low-end macs, that couldn't + // handle multi-channel music and play the game at the same time. I'm + // not sure if stream 4 is ever used, but let's use it just in case. +} + +// \xAA is a trademark glyph in Mac OS Roman. We try that, but also the Windows +// version, the UTF-8 version, and just plain without in case the file system +// can't handle exotic characters like that. + +static const char *loomFileNames[] = { + "Loom\xAA", + "Loom\x99", + "Loom\xE2\x84\xA2", + "Loom" +}; + +bool Player_V3M::checkMusicAvailable() { + Common::MacResManager resource; + + for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) { + if (resource.exists(loomFileNames[i])) { + return true; + } + } + + GUI::MessageDialog dialog(_( + "Could not find the 'Loom' Macintosh executable to read the\n" + "instruments from. Music will be disabled."), _("OK")); + dialog.runModal(); + return false; +} + +bool Player_V3M::loadMusic(const byte *ptr) { + Common::MacResManager resource; + bool found = false; + + for (int i = 0; i < ARRAYSIZE(loomFileNames); i++) { + if (resource.open(loomFileNames[i])) { + found = true; + break; + } + } + + if (!found) { + return false; + } + + if (ptr[4] != 's' || ptr[5] != 'o') { + // Like the original we ignore all sound resources which do not have + // a 'so' tag in them. + // See bug #3602239 ("Mac Loom crashes using opening spell on + // gravestone") for a case where this is required. Loom Mac tries to + // play resource 11 here. This resource is no Mac sound resource + // though, it is a PC Speaker resource. A test with the original + // interpreter also has shown that no sound is played while the + // screen is shaking. + debug(5, "Player_V3M::loadMusic: Skipping unknown music type %02X%02X", ptr[4], ptr[5]); + resource.close(); + return false; + } + + uint i; + for (i = 0; i < 5; i++) { + int instrument = READ_BE_UINT16(ptr + 20 + 2 * i); + int offset = READ_BE_UINT16(ptr + 30 + 2 * i); + + _channel[i]._looped = false; + _channel[i]._length = READ_BE_UINT16(ptr + offset + 4) * 3; + _channel[i]._data = ptr + offset + 6; + _channel[i]._pos = 0; + _channel[i]._pitchModifier = 0; + _channel[i]._velocity = 0; + _channel[i]._remaining = 0; + _channel[i]._notesLeft = true; + + Common::SeekableReadStream *stream = resource.getResource(RES_SND, instrument); + if (_channel[i].loadInstrument(stream)) { + debug(6, "Player_V3M::loadMusic: Channel %d - Loaded Instrument %d (%s)", i, instrument, resource.getResName(RES_SND, instrument).c_str()); + } else { + resource.close(); + return false; + } + } + + resource.close(); + return true; +} + +bool Player_V3M::getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) { + _channel[ch]._instrument.newNote(); + if (_channel[ch]._pos >= _channel[ch]._length) { + if (!_channel[ch]._looped) { + _channel[ch]._notesLeft = false; + return false; + } + _channel[ch]._pos = 0; + } + uint16 duration = READ_BE_UINT16(&_channel[ch]._data[_channel[ch]._pos]); + byte note = _channel[ch]._data[_channel[ch]._pos + 2]; + samples = durationToSamples(duration); + if (note > 0) { + pitchModifier = noteToPitchModifier(note, &_channel[ch]._instrument); + velocity = 127; + } else { + pitchModifier = 0; + velocity = 0; + } + _channel[ch]._pos += 3; + return true; +} + +} // End of namespace Scumm diff --git a/engines/scumm/player_v3m.h b/engines/scumm/player_v3m.h new file mode 100644 index 0000000000..359bab32a9 --- /dev/null +++ b/engines/scumm/player_v3m.h @@ -0,0 +1,54 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_PLAYER_V3M_H +#define SCUMM_PLAYER_V3M_H + +#include "common/scummsys.h" +#include "common/util.h" +#include "common/mutex.h" +#include "scumm/music.h" +#include "scumm/player_mac.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" + +class Mixer; + +namespace Scumm { + +class ScummEngine; + +/** + * Scumm V3 Macintosh music driver. + */ +class Player_V3M : public Player_Mac { +public: + Player_V3M(ScummEngine *scumm, Audio::Mixer *mixer); + + virtual bool checkMusicAvailable(); + virtual bool loadMusic(const byte *ptr); + virtual bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity); +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/player_v5m.cpp b/engines/scumm/player_v5m.cpp new file mode 100644 index 0000000000..500f3bbc40 --- /dev/null +++ b/engines/scumm/player_v5m.cpp @@ -0,0 +1,246 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* + From Markus Magnuson (superqult) we got this information: + Mac0 + --- + 4 bytes - 'SOUN' + BE 4 bytes - block length + + 4 bytes - 'Mac0' + BE 4 bytes - (blockLength - 27) + 28 bytes - ??? + + do this three times (once for each channel): + 4 bytes - 'Chan' + BE 4 bytes - channel length + 4 bytes - instrument name (e.g. 'MARI') + + do this for ((chanLength-24)/4) times: + 2 bytes - note duration + 1 byte - note value + 1 byte - note velocity + + 4 bytes - ??? + 4 bytes - 'Loop'/'Done' + 4 bytes - ??? + + 1 byte - 0x09 + --- + + The instruments presumably correspond to the snd resource names in the + Monkey Island executable: + + Instruments + "MARI" - MARIMBA + "PLUC" - PLUCK + "HARM" - HARMONIC + "PIPE" - PIPEORGAN + "TROM" - TROMBONE + "STRI" - STRINGS + "HORN" - HORN + "VIBE" - VIBES + "SHAK" - SHAKUHACHI + "PANP" - PANPIPE + "WHIS" - WHISTLE + "ORGA" - ORGAN3 + "BONG" - BONGO + "BASS" - BASS + + --- + + Note values <= 1 are silent. +*/ + +#include "common/macresman.h" +#include "common/translation.h" +#include "engines/engine.h" +#include "gui/message.h" +#include "scumm/player_v5m.h" +#include "scumm/scumm.h" + +namespace Scumm { + +Player_V5M::Player_V5M(ScummEngine *scumm, Audio::Mixer *mixer) + : Player_Mac(scumm, mixer, 3, 0x07, false) { + assert(_vm->_game.id == GID_MONKEY); +} + +// Try both with and without underscore in the filename, because hfsutils may +// turn the space into an underscore. At least, it did for me. + +static const char *monkeyIslandFileNames[] = { + "Monkey Island", + "Monkey_Island" +}; + +bool Player_V5M::checkMusicAvailable() { + Common::MacResManager resource; + + for (int i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) { + if (resource.exists(monkeyIslandFileNames[i])) { + return true; + } + } + + GUI::MessageDialog dialog(_( + "Could not find the 'Monkey Island' Macintosh executable to read the\n" + "instruments from. Music will be disabled."), _("OK")); + dialog.runModal(); + return false; +} + +bool Player_V5M::loadMusic(const byte *ptr) { + Common::MacResManager resource; + bool found = false; + uint i; + + for (i = 0; i < ARRAYSIZE(monkeyIslandFileNames); i++) { + if (resource.open(monkeyIslandFileNames[i])) { + found = true; + break; + } + } + + if (!found) { + return false; + } + + ptr += 8; + // TODO: Decipher the unknown bytes in the header. For now, skip 'em + ptr += 28; + + Common::MacResIDArray idArray = resource.getResIDArray(RES_SND); + + // Load the three channels and their instruments + for (i = 0; i < 3; i++) { + assert(READ_BE_UINT32(ptr) == MKTAG('C', 'h', 'a', 'n')); + uint32 len = READ_BE_UINT32(ptr + 4); + uint32 instrument = READ_BE_UINT32(ptr + 8); + + _channel[i]._length = len - 20; + _channel[i]._data = ptr + 12; + _channel[i]._looped = (READ_BE_UINT32(ptr + len - 8) == MKTAG('L', 'o', 'o', 'p')); + _channel[i]._pos = 0; + _channel[i]._pitchModifier = 0; + _channel[i]._velocity = 0; + _channel[i]._remaining = 0; + _channel[i]._notesLeft = true; + + for (uint j = 0; j < idArray.size(); j++) { + Common::String name = resource.getResName(RES_SND, idArray[j]); + if (instrument == READ_BE_UINT32(name.c_str())) { + debug(6, "Player_V5M::loadMusic: Channel %d: Loading instrument '%s'", i, name.c_str()); + Common::SeekableReadStream *stream = resource.getResource(RES_SND, idArray[j]); + + if (!_channel[i].loadInstrument(stream)) { + resource.close(); + return false; + } + + break; + } + } + + ptr += len; + } + + resource.close(); + + // The last note of each channel is just zeroes. We will adjust this + // note so that all the channels end at the same time. + + uint32 samples[3]; + uint32 maxSamples = 0; + for (i = 0; i < 3; i++) { + samples[i] = 0; + for (uint j = 0; j < _channel[i]._length; j += 4) { + samples[i] += durationToSamples(READ_BE_UINT16(&_channel[i]._data[j])); + } + if (samples[i] > maxSamples) { + maxSamples = samples[i]; + } + } + + for (i = 0; i < 3; i++) { + _lastNoteSamples[i] = maxSamples - samples[i]; + } + + return true; +} + +bool Player_V5M::getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity) { + if (_channel[ch]._pos >= _channel[ch]._length) { + if (!_channel[ch]._looped) { + _channel[ch]._notesLeft = false; + return false; + } + // FIXME: Jamieson630: The jump seems to be happening + // too quickly! There should maybe be a pause after + // the last Note Off? But I couldn't find one in the + // MI1 Lookout music, where I was hearing problems. + _channel[ch]._pos = 0; + } + uint16 duration = READ_BE_UINT16(&_channel[ch]._data[_channel[ch]._pos]); + byte note = _channel[ch]._data[_channel[ch]._pos + 2]; + samples = durationToSamples(duration); + + if (note != 1) { + _channel[ch]._instrument.newNote(); + } + + if (note > 1) { + pitchModifier = noteToPitchModifier(note, &_channel[ch]._instrument); + velocity = _channel[ch]._data[_channel[ch]._pos + 3]; + } else if (note == 1) { + // This is guesswork, but Monkey Island uses two different + // "special" note values: 0, which is clearly a rest, and 1 + // which is... I thought at first it was a "soft" key off, to + // fade out the note, but listening to the music in a Mac + // emulator (which unfortunately doesn't work all that well), + // I hear no trace of fading out. + // + // It could mean "change the volume on the current note", but + // I can't hear that either, and it always seems to use the + // exact same velocity on this note. + // + // So it appears it really just is a "hold the current note", + // but why? Couldn't they just have made the original note + // longer? + + pitchModifier = _channel[ch]._pitchModifier; + velocity = _channel[ch]._velocity; + } else { + pitchModifier = 0; + velocity = 0; + } + + _channel[ch]._pos += 4; + + if (_channel[ch]._pos >= _channel[ch]._length) { + samples = _lastNoteSamples[ch]; + } + return true; +} + +} // End of namespace Scumm diff --git a/engines/scumm/player_v5m.h b/engines/scumm/player_v5m.h new file mode 100644 index 0000000000..b2079ee331 --- /dev/null +++ b/engines/scumm/player_v5m.h @@ -0,0 +1,57 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCUMM_PLAYER_V5M_H +#define SCUMM_PLAYER_V5M_H + +#include "common/scummsys.h" +#include "common/util.h" +#include "common/mutex.h" +#include "scumm/music.h" +#include "scumm/player_mac.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" + +class Mixer; + +namespace Scumm { + +class ScummEngine; + +/** + * Scumm V5 Macintosh music driver. + */ +class Player_V5M : public Player_Mac { +public: + Player_V5M(ScummEngine *scumm, Audio::Mixer *mixer); + + virtual bool checkMusicAvailable(); + virtual bool loadMusic(const byte *ptr); + virtual bool getNextNote(int ch, uint32 &samples, int &pitchModifier, byte &velocity); + +private: + uint32 _lastNoteSamples[3]; +}; + +} // End of namespace Scumm + +#endif diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp index b2093e9c1a..7c42b40f58 100644 --- a/engines/scumm/resource.cpp +++ b/engines/scumm/resource.cpp @@ -1214,7 +1214,7 @@ void ScummEngine_v7::readMAXS(int blockSize) { _objectRoomTable = (byte *)calloc(_numGlobalObjects, 1); if ((_game.id == GID_FT) && (_game.features & GF_DEMO) && - (_game.platform == Common::kPlatformPC)) + (_game.platform == Common::kPlatformDOS)) _numGlobalScripts = 300; else _numGlobalScripts = 2000; diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 72896e097a..3453e53a18 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -1477,9 +1477,13 @@ void ScummEngine::saveOrLoad(Serializer *s) { } - // Save/load FM-Towns audio status - if (_townsPlayer) - _townsPlayer->saveLoadWithSerializer(s); + // + // Save/load music engine status + // + if (_musicEngine) { + _musicEngine->saveLoadWithSerializer(s); + } + // // Save/load the charset renderer state diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h index a640bc1e17..7b2ff91ad3 100644 --- a/engines/scumm/saveload.h +++ b/engines/scumm/saveload.h @@ -47,7 +47,7 @@ namespace Scumm { * only saves/loads those which are valid for the version of the savegame * which is being loaded/saved currently. */ -#define CURRENT_VER 93 +#define CURRENT_VER 94 /** * An auxillary macro, used to specify savegame versions. We use this instead @@ -74,7 +74,7 @@ namespace Scumm { * what POD means refer to <http://en.wikipedia.org/wiki/Plain_Old_Data_Structures> or * to <http://www.informit.com/guides/content.asp?g=cplusplus&seqNum=32&rl=1>) */ -#define OFFS(type,item) (((ptrdiff_t)(&((type *)42)->type::item))-42) +#define OFFS(type,item) ((uint32)(((ptrdiff_t)(&((type *)42)->type::item))-42)) /** * Similar to the OFFS macro, this macro computes the size (in bytes) of a @@ -84,19 +84,19 @@ namespace Scumm { // Any item that is still in use automatically gets a maxVersion equal to CURRENT_VER #define MKLINE(type,item,saveas,minVer) {OFFS(type,item),saveas,SIZE(type,item),minVer,CURRENT_VER} -#define MKARRAY(type,item,saveas,dim,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {dim,1,0,0,0} -#define MKARRAY2(type,item,saveas,dim,dim2,rowlen,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {dim,dim2,rowlen,0,0} +#define MKARRAY(type,item,saveas,dim,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {(uint32)(dim),1,0,0,0} +#define MKARRAY2(type,item,saveas,dim,dim2,rowlen,minVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,CURRENT_VER}, {(uint32)(dim),(uint32)(dim2),(uint16)(rowlen),0,0} // Use this if you have an entry that used to be smaller: #define MKLINE_OLD(type,item,saveas,minVer,maxVer) {OFFS(type,item),saveas,SIZE(type,item),minVer,maxVer} -#define MKARRAY_OLD(type,item,saveas,dim,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {dim,1,0,0,0} -#define MKARRAY2_OLD(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {dim,dim2,rowlen,0,0} +#define MKARRAY_OLD(type,item,saveas,dim,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {(uint32)(dim),1,0,0,0} +#define MKARRAY2_OLD(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {OFFS(type,item),128|saveas,SIZE(type,item),minVer,maxVer}, {(uint32)(dim),(uint32)(dim2),(uint16)(rowlen),0,0} // An obsolete item/array, to be ignored upon load. We retain the type/item params to make it easier to debug. // Obsolete items have size == 0. #define MK_OBSOLETE(type,item,saveas,minVer,maxVer) {0,saveas,0,minVer,maxVer} -#define MK_OBSOLETE_ARRAY(type,item,saveas,dim,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {dim,1,0,0,0} -#define MK_OBSOLETE_ARRAY2(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {dim,dim2,rowlen,0,0} +#define MK_OBSOLETE_ARRAY(type,item,saveas,dim,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {(uint32)(dim),1,0,0,0} +#define MK_OBSOLETE_ARRAY2(type,item,saveas,dim,dim2,rowlen,minVer,maxVer) {0,128|saveas,0,minVer,maxVer}, {(uint32)(dim),(uint32)(dim2),(uint16)(rowlen),0,0} // End marker #define MKEND() {0xFFFF,0xFF,0xFF,0,0} diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index d8c4948ea8..c8eabdd61c 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -49,6 +49,8 @@ void ScummEngine::runScript(int script, bool freezeResistant, bool recursive, in if (!recursive) stopScript(script); + uint16 number = (_currentScript != 0xFF) ? vm.slot[_currentScript].number : 0; + if (script < _numGlobalScripts) { // Call getResourceAddress to ensure the resource is loaded & its usage count reset /*scriptPtr =*/ getResourceAddress(rtScript, script); @@ -56,7 +58,7 @@ void ScummEngine::runScript(int script, bool freezeResistant, bool recursive, in scriptType = WIO_GLOBAL; debugC(DEBUG_SCRIPTS, "runScript(Global-%d) from %d-%d", script, - vm.slot[_currentScript].number, _roomResource); + number, _roomResource); } else { scriptOffs = _localScriptOffsets[script - _numGlobalScripts]; if (scriptOffs == 0) @@ -64,7 +66,7 @@ void ScummEngine::runScript(int script, bool freezeResistant, bool recursive, in scriptType = WIO_LOCAL; debugC(DEBUG_SCRIPTS, "runScript(%d) from %d-%d", script, - vm.slot[_currentScript].number, _roomResource); + number, _roomResource); } if (cycle == 0) @@ -138,10 +140,10 @@ void ScummEngine::runObjectScript(int object, int entry, bool freezeResistant, b void ScummEngine::initializeLocals(int slot, int *vars) { int i; if (!vars) { - for (i = 0; i < 25; i++) + for (i = 0; i < NUM_SCRIPT_LOCAL; i++) vm.localvar[slot][i] = 0; } else { - for (i = 0; i < 25; i++) + for (i = 0; i < NUM_SCRIPT_LOCAL; i++) vm.localvar[slot][i] = vars[i]; } } @@ -755,13 +757,13 @@ void ScummEngine::stopObjectCode() { } void ScummEngine::runInventoryScript(int i) { - int args[24]; - memset(args, 0, sizeof(args)); - args[0] = i; if (VAR(VAR_INVENTORY_SCRIPT)) { if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh) { inventoryScriptIndy3Mac(); } else { + int args[NUM_SCRIPT_LOCAL]; + memset(args, 0, sizeof(args)); + args[0] = i; runScript(VAR(VAR_INVENTORY_SCRIPT), 0, 0, args); } } @@ -1060,7 +1062,7 @@ void ScummEngine::doSentence(int verb, int objectA, int objectB) { void ScummEngine::checkAndRunSentenceScript() { int i; - int localParamList[24]; + int localParamList[NUM_SCRIPT_LOCAL]; const ScriptSlot *ss; int sentenceScript; @@ -1308,7 +1310,7 @@ void ScummEngine_v0::runSentenceScript() { } void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) { - int args[24]; + int args[NUM_SCRIPT_LOCAL]; int verbScript; verbScript = 4; @@ -1332,7 +1334,7 @@ void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) { } void ScummEngine::runInputScript(int clickArea, int val, int mode) { - int args[24]; + int args[NUM_SCRIPT_LOCAL]; int verbScript; verbScript = VAR(VAR_VERB_SCRIPT); @@ -1366,9 +1368,15 @@ void ScummEngine::runInputScript(int clickArea, int val, int mode) { // Clicks are handled differently in Indy3 mac: param 2 of the // input script is set to 0 for normal clicks, and to 1 for double clicks. + // The EGA DOS version of Loom also checks that the second click happens + // close enough to the first one, but that seems like overkill. uint32 time = _system->getMillis(); args[2] = (time < _lastInputScriptTime + 500); // 500 ms double click delay _lastInputScriptTime = time; + } else if (_game.id == GID_LOOM && _game.platform == Common::kPlatformMacintosh) { + uint32 time = _system->getMillis(); + VAR(52) = (time < _lastInputScriptTime + 500); // 500 ms double click delay + _lastInputScriptTime = time; } if (verbScript) @@ -1484,7 +1492,7 @@ void ScummEngine::beginCutscene(int *args) { void ScummEngine::endCutscene() { ScriptSlot *ss = &vm.slot[_currentScript]; - int args[16]; + int args[NUM_SCRIPT_LOCAL]; if (ss->cutsceneOverride > 0) // Only terminate if active ss->cutsceneOverride--; diff --git a/engines/scumm/script.h b/engines/scumm/script.h index 7b2c625144..74ffaaf426 100644 --- a/engines/scumm/script.h +++ b/engines/scumm/script.h @@ -66,13 +66,15 @@ struct OpcodeEntry : Common::NonCopyable { /** * The number of script slots, which determines the maximal number - * of concurrently running scripts. - * WARNING: Do NOT changes this value unless you really have to, as + * of concurrently running scripts, and the number of local variables + * in a script. + * WARNING: Do NOT changes these values unless you really have to, as * this will break savegame compatibility if done carelessly. If you - * have to change it, make sure you update saveload.cpp accordingly! + * have to change them, make sure you update saveload.cpp accordingly! */ enum { - NUM_SCRIPT_SLOT = 80 + NUM_SCRIPT_SLOT = 80, + NUM_SCRIPT_LOCAL = 25 }; /* Script status type (slot.status) */ @@ -122,7 +124,8 @@ struct VirtualMachineState { int16 cutSceneScriptIndex; byte cutSceneStackPointer; ScriptSlot slot[NUM_SCRIPT_SLOT]; - int32 localvar[NUM_SCRIPT_SLOT][26]; + // Why does localvar have space for one extra local variable? + int32 localvar[NUM_SCRIPT_SLOT][NUM_SCRIPT_LOCAL + 1]; NestedScript nest[kMaxScriptNesting]; byte numNestedScripts; diff --git a/engines/scumm/script_v4.cpp b/engines/scumm/script_v4.cpp index 1de9f08168..ec3ac4b00f 100644 --- a/engines/scumm/script_v4.cpp +++ b/engines/scumm/script_v4.cpp @@ -415,7 +415,7 @@ void ScummEngine_v4::o4_saveLoadGame() { char* ptr; int firstSlot = (_game.id == GID_LOOM) ? STRINGID_SAVENAME1_LOOM : STRINGID_SAVENAME1; ptr = (char *)getStringAddress(slot + firstSlot - 1); - strncpy(name, ptr, sizeof(name)); + Common::strlcpy(name, ptr, sizeof(name)); } if (savePreparedSavegame(slot, name)) diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 0bf51a2816..2d4c326b68 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -630,7 +630,7 @@ void ScummEngine_v5::o5_breakHere() { } void ScummEngine_v5::o5_chainScript() { - int vars[16]; + int vars[NUM_SCRIPT_LOCAL]; int script; int cur; @@ -663,7 +663,7 @@ void ScummEngine_v5::o5_chainScript() { void ScummEngine_v5::o5_cursorCommand() { int i, j, k; - int table[16]; + int table[NUM_SCRIPT_LOCAL]; switch ((_opcode = fetchScriptByte()) & 0x1F) { case 1: // SO_CURSOR_ON _cursor.state = 1; @@ -736,7 +736,7 @@ void ScummEngine_v5::o5_cursorCommand() { } void ScummEngine_v5::o5_cutscene() { - int args[16]; + int args[NUM_SCRIPT_LOCAL]; getWordVararg(args); beginCutscene(args); } @@ -2083,14 +2083,14 @@ void ScummEngine_v5::o5_isSoundRunning() { } void ScummEngine_v5::o5_soundKludge() { - int items[16]; + int items[NUM_SCRIPT_LOCAL]; int num = getWordVararg(items); _sound->soundKludge(items, num); } void ScummEngine_v5::o5_startObject() { int obj, script; - int data[16]; + int data[NUM_SCRIPT_LOCAL]; obj = getVarOrDirectWord(PARAM_1); script = getVarOrDirectByte(PARAM_2); @@ -2101,7 +2101,7 @@ void ScummEngine_v5::o5_startObject() { void ScummEngine_v5::o5_startScript() { int op, script; - int data[16]; + int data[NUM_SCRIPT_LOCAL]; op = _opcode; script = getVarOrDirectByte(PARAM_1); @@ -2130,7 +2130,7 @@ void ScummEngine_v5::o5_startScript() { // Method used by original games to skip copy protection scheme if (!_copyProtection) { // Copy protection was disabled in LucasArts Classic Adventures (PC Disk) - if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPC && _game.version == 3 && _currentRoom == 69 && script == 201) + if (_game.id == GID_LOOM && _game.platform == Common::kPlatformDOS && _game.version == 3 && _currentRoom == 69 && script == 201) script = 205; // Copy protection was disabled in KIXX XL release (Amiga Disk) and // in LucasArts Classic Adventures (PC Disk) @@ -2556,7 +2556,7 @@ void ScummEngine_v5::o5_walkActorToObject() { int ScummEngine_v5::getWordVararg(int *ptr) { int i; - for (i = 0; i < 16; i++) + for (i = 0; i < NUM_SCRIPT_LOCAL; i++) ptr[i] = 0; i = 0; diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp index decd34222d..a75e864e7a 100644 --- a/engines/scumm/script_v6.cpp +++ b/engines/scumm/script_v6.cpp @@ -2510,7 +2510,7 @@ void ScummEngine_v7::o6_kernelSetFunctions() { _disableFadeInEffect = true; } } else if (_game.id == GID_FT && !_skipVideo) { - const int insaneVarNum = ((_game.features & GF_DEMO) && (_game.platform == Common::kPlatformPC)) + const int insaneVarNum = ((_game.features & GF_DEMO) && (_game.platform == Common::kPlatformDOS)) ? 232 : 233; _insane->setSmushParams(_smushFrameRate); diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index d4eefe8c28..db8da21bbc 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Sat Jul 07 23:39:27 2012 + This file was generated by the md5table tool on Sun Jun 23 22:18:47 2013 DO NOT EDIT MANUALLY! */ @@ -17,7 +17,7 @@ static const MD5Table md5table[] = { { "008e76ec3ae58d0add637ea7aa299a2c", "freddi3", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh }, { "02cae0e7ff8504f73618391873d5781a", "freddi3", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows }, { "0305e850382b812fec6e5998ef88a966", "pajama", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, - { "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, + { "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, { "037385a953789190298494d92b89b3d0", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows }, { "0425954a9db5c340861672892c3e678d", "samnmax", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, @@ -33,7 +33,7 @@ static const MD5Table md5table[] = { { "07b810e37be7489263f7bc7627d4765d", "freddi4", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows }, { "084ed0fa98a6d1e9368d67fe9cfbd417", "freddi", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "0855496dde35356b1a9691e22ba84cdc", "freddi", "HE 73", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, - { "08656dd9698ddf1023ba9bf8a195e37b", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformPC }, + { "08656dd9698ddf1023ba9bf8a195e37b", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "08cc5c3eedaf72ebe12734eee94f7fa2", "balloon", "HE 80", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "09820417db26687bb7fe0c83cc4c553b", "ft", "", "Version A", 19697, Common::EN_ANY, Common::kPlatformUnknown }, { "0a212fa35fa8421f31c1f3961272caf0", "monkey", "VGA", "VGA", -1, Common::DE_DEU, Common::kPlatformAmiga }, @@ -43,15 +43,15 @@ static const MD5Table md5table[] = { { "0aa050f4ad79402fbe9c4f78fb8ac494", "loom", "PC-Engine", "", 6532, Common::EN_ANY, Common::kPlatformPCEngine }, { "0ab19be9e2a3f6938226638b2a3744fe", "PuttTime", "HE 100", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "0ac41e2e3d2174e5a042a6b565328dba", "puttrace", "HE 98", "Demo", 13110, Common::EN_USA, Common::kPlatformUnknown }, - { "0b3222aaa7efcf283eb621e0cefd26cc", "puttputt", "HE 60", "", -1, Common::RU_RUS, Common::kPlatformPC }, - { "0be88565f734b1e9e77ccaaf3bb14b29", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC }, + { "0b3222aaa7efcf283eb621e0cefd26cc", "puttputt", "HE 60", "", -1, Common::RU_RUS, Common::kPlatformDOS }, + { "0be88565f734b1e9e77ccaaf3bb14b29", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS }, { "0bf1a3eb198ca1bd2ebe104825cec770", "puttrace", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, { "0c331637580950aea2346e012ef2a868", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformAtariST }, { "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", "", "Demo", 13884, Common::DE_DEU, Common::kPlatformUnknown }, { "0cccfa5223099a60e76cfcca57a1a141", "freddi3", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, - { "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformPC }, + { "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformDOS }, { "0ddf1174d0d097956ba10dd452ea65e6", "freddi3", "HE 99", "", -1, Common::HE_ISR, Common::kPlatformWindows }, - { "0e4c5d54a0ad4b26132e78b5ea76642a", "samnmax", "Floppy", "Demo", 6485, Common::EN_ANY, Common::kPlatformPC }, + { "0e4c5d54a0ad4b26132e78b5ea76642a", "samnmax", "Floppy", "Demo", 6485, Common::EN_ANY, Common::kPlatformDOS }, { "0e96ab45a4eb72acc1b46813976589fd", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "0e9b01430e31d9fcd94071d433bbc6bf", "loom", "No AdLib", "EGA", -1, Common::FR_FRA, Common::kPlatformAtariST }, { "0f5935bd5e88ba6f09e558d64459746d", "thinker1", "", "Demo", 30919, Common::EN_USA, Common::kPlatformWindows }, @@ -62,7 +62,7 @@ static const MD5Table md5table[] = { { "1005456bfe351c1b679e1ff2dc2849e9", "puttzoo", "", "", -1, Common::UNK_LANG, Common::kPlatformWindows }, { "100b4c8403ad6a83d4bf7dbf83e44dc4", "spyfox", "", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "10d8e66cd11049ce64815ebb9fd76eb3", "spyozon", "", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, - { "114acdc2659a273c220f86ee9edb24c1", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC }, + { "114acdc2659a273c220f86ee9edb24c1", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformDOS }, { "11ddf1fde76e3156eb3a38da213f484e", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformAmiga }, { "11e6e244078ff09b0f3832e35420e0a7", "catalog", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "132bff65e6367c09cc69318ce1b59333", "monkey2", "", "", 11155, Common::EN_ANY, Common::kPlatformAmiga }, @@ -74,20 +74,20 @@ static const MD5Table md5table[] = { { "15240c59d3681ed53f714f8d925cb2d6", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformAtariST }, { "157367c3c21e0d03a0cba44361b4cf65", "indy3", "No AdLib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST }, { "15878e3bee2e1e759184abee98589eaa", "spyfox", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformIOS }, - { "15e03ffbfeddb9c2aebc13dcb2a4a8f4", "monkey", "VGA", "VGA", 8357, Common::EN_ANY, Common::kPlatformPC }, + { "15e03ffbfeddb9c2aebc13dcb2a4a8f4", "monkey", "VGA", "VGA", 8357, Common::EN_ANY, Common::kPlatformDOS }, { "15f588e887e857e8c56fe6ade4956168", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformAmiga }, { "16542a7342a918bfe4ba512007d36c47", "FreddisFunShop", "HE 99L", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "166553538ff320c69edafeee29525419", "samnmax", "", "CD", 199195304, Common::EN_ANY, Common::kPlatformMacintosh }, { "16effd200aa6b8abe9c569c3e578814d", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "179879b6e35c1ead0d93aab26db0951b", "fbear", "HE 70", "", 13381, Common::EN_ANY, Common::kPlatformWindows }, - { "17b5d5e6af4ae89d62631641d66d5a05", "indy3", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformPC }, + { "17b5d5e6af4ae89d62631641d66d5a05", "indy3", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformDOS }, { "17f7296f63c78642724f057fd8e736a7", "maniac", "NES", "", 2082, Common::EN_GRB, Common::kPlatformNES }, - { "17fa250eb72dae2dad511ba79c0b6b0a", "tentacle", "", "Demo", -1, Common::FR_FRA, Common::kPlatformPC }, - { "182344899c2e2998fca0bebcd82aa81a", "atlantis", "", "CD", 12035, Common::EN_ANY, Common::kPlatformPC }, - { "183d7464902d40d00800e8ee1f04117c", "maniac", "V2", "V2", 1988, Common::DE_DEU, Common::kPlatformPC }, - { "1875b90fade138c9253a8e967007031a", "indy3", "VGA", "VGA", 6295, Common::EN_ANY, Common::kPlatformPC }, - { "187d315f6b5168f68680dfe8c3d76a3e", "loom", "EGA", "EGA", -1, Common::HE_ISR, Common::kPlatformPC }, - { "1900e501a52fbf55bde6e4196f6d2aa6", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC }, + { "17fa250eb72dae2dad511ba79c0b6b0a", "tentacle", "", "Demo", -1, Common::FR_FRA, Common::kPlatformDOS }, + { "182344899c2e2998fca0bebcd82aa81a", "atlantis", "", "CD", 12035, Common::EN_ANY, Common::kPlatformDOS }, + { "183d7464902d40d00800e8ee1f04117c", "maniac", "V2", "V2", 1988, Common::DE_DEU, Common::kPlatformDOS }, + { "1875b90fade138c9253a8e967007031a", "indy3", "VGA", "VGA", 6295, Common::EN_ANY, Common::kPlatformDOS }, + { "187d315f6b5168f68680dfe8c3d76a3e", "loom", "EGA", "EGA", -1, Common::HE_ISR, Common::kPlatformDOS }, + { "1900e501a52fbf55bde6e4196f6d2aa6", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformDOS }, { "19263586f749a560c1adf8b3393a9593", "socks", "HE 85", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "19bf6938a94698296bcb0c99c31c91a7", "spyfox2", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows }, { "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh }, @@ -96,13 +96,13 @@ static const MD5Table md5table[] = { { "1c792d28376d45e145cb916bca0400a2", "spyfox2", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "1c7e7db2cfab1ad62746ab680a634204", "maniac", "NES", "", -1, Common::FR_FRA, Common::kPlatformNES }, { "1ca86e2cf9aaa2068738a1e5ba477e60", "zak", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns }, - { "1d05cd189e4908f79b57e78a4402f292", "monkey", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC }, + { "1d05cd189e4908f79b57e78a4402f292", "monkey", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "1d7a2e1ddcade791e2de0cfceac86725", "pajama", "", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, - { "1dd3c11ea4439adfe681e4e405b624e1", "monkey", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC }, + { "1dd3c11ea4439adfe681e4e405b624e1", "monkey", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS }, { "1dd7aa088e09f96d06818aa9a9deabe0", "indy3", "No AdLib", "EGA", 5361, Common::EN_ANY, Common::kPlatformMacintosh }, { "1ed22f601f8b3695804a6583cc3083f1", "puttrace", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "1f2e62b5a9c50589fc342285a6bb3a27", "freddi", "HE 73", "", -1, Common::HE_ISR, Common::kPlatformWindows }, - { "1fbebd7b2b692df5297870447a80cfed", "atlantis", "Floppy", "Floppy", 12030, Common::DE_DEU, Common::kPlatformPC }, + { "1fbebd7b2b692df5297870447a80cfed", "atlantis", "Floppy", "Floppy", 12030, Common::DE_DEU, Common::kPlatformDOS }, { "1ff5997c78fbd0a841a75ef15a05d9d5", "BluesBirthday", "Red", "Red", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "2012f854d83d9cc6f73b2b544cd8bbf8", "water", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "20176076d708bf14407bcc9bdcd7a418", "pajama3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows }, @@ -115,22 +115,23 @@ static const MD5Table md5table[] = { { "225e18566e810c634bf7de63e7568e3e", "mustard", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "22c9eb04455440131ffc157aeb8d40a8", "fbear", "HE 70", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "22de86b2f7ec6e5db745ed1123310b44", "spyfox2", "", "Demo", 15832, Common::FR_FRA, Common::kPlatformWindows }, - { "22f4ea88a09da12df9308ba30bcb7d0f", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC }, + { "22f4ea88a09da12df9308ba30bcb7d0f", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "23394c8d29cc63c61313959431a12476", "spyfox", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, { "254fede2f15dbb32a23760d601b01816", "zak", "V1", "", -1, Common::EN_ANY, Common::kPlatformC64 }, - { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformPC }, + { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformDOS }, { "27b2ef1653089fe5b897d9cc89ce784f", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "27b3a4224ad63d5b04627595c1c1a025", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformAmiga }, { "28d24a33448fab6795850bc9f159a4a2", "atlantis", "FM-TOWNS", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns }, - { "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformPC }, + { "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformDOS }, { "28f07458f1b6c24e118a1ea056827701", "lost", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, - { "2a208ffbcd0e83e86f4356e6f64aa6e1", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC }, + { "291fb06071e65897f755846611f5ad40", "ft", "", "7-Wolf", 19697, Common::RU_RUS, Common::kPlatformUnknown }, + { "2a208ffbcd0e83e86f4356e6f64aa6e1", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS }, { "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", "", "Demo", 2439158, Common::EN_ANY, Common::kPlatformMacintosh }, { "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows }, { "2a8658dbd13d84d1bce64a71a35995eb", "pajama2", "HE 99", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows }, - { "2c04aacffb8428f30ccf4f734fbe3adc", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformPC }, + { "2c04aacffb8428f30ccf4f734fbe3adc", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformDOS }, { "2ccd8891ce4d3f1a334d21bff6a88ca2", "monkey", "CD", "", 9455, Common::EN_ANY, Common::kPlatformMacintosh }, - { "2d1e891fe52df707c30185e52c50cd92", "monkey", "CD", "CD", 8955, Common::EN_ANY, Common::kPlatformPC }, + { "2d1e891fe52df707c30185e52c50cd92", "monkey", "CD", "CD", 8955, Common::EN_ANY, Common::kPlatformDOS }, { "2d388339d6050d8ccaa757b64633954e", "indyloom", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns }, { "2d4536a56e01da4b02eb021e7770afa2", "zak", "FM-TOWNS", "", 7520, Common::EN_ANY, Common::kPlatformFMTowns }, { "2d4acbdcfd8e374c9da8c2e7303a5cd0", "BluesBirthday", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, @@ -139,14 +140,14 @@ static const MD5Table md5table[] = { { "2e85f7aa054930c692a5b1bed1dfc295", "football2002", "", "Patched", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "2e8a1f76ea33bc5e04347646feee173d", "pajama3", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "2fe369ad70f52a8cf7ad6077ee64f81a", "loom", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformAmiga }, - { "305d3dd57c96c65b017bc70c8c7cfb5e", "monkey", "CD", "CD", 8955, Common::DE_DEU, Common::kPlatformPC }, + { "305d3dd57c96c65b017bc70c8c7cfb5e", "monkey", "CD", "CD", 8955, Common::DE_DEU, Common::kPlatformDOS }, { "30ba1e825d4ad2b448143ae8df18482a", "pajama2", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "30d1903b0715759af064be2127381cd0", "freddi", "HE 100", "", 34837, Common::DE_DEU, Common::kPlatformWii }, { "319a4dde52c7960b5aae8a1ec348d918", "monkey", "VGA", "VGA", -1, Common::DE_DEU, Common::kPlatformAmiga }, - { "31aa57f460a3d12429f0552a46a90b39", "puttputt", "Demo", "Demo", 6150, Common::EN_ANY, Common::kPlatformPC }, + { "31aa57f460a3d12429f0552a46a90b39", "puttputt", "Demo", "Demo", 6150, Common::EN_ANY, Common::kPlatformDOS }, { "31b8fda4c8c7413fa6b39997e776eba4", "loom", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns }, { "32709cbeeb3044b34129950860a83f14", "pajama2", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, - { "32a433dea56b86a55b59e4ff7d755711", "ft", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, + { "32a433dea56b86a55b59e4ff7d755711", "ft", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, { "330f631502e381a4e199a3f7cb483c20", "indy3", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "33e989f85da700e2014d00f345cab3d7", "puttrace", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "3433be9866ca4261b2d5d25374e3f243", "monkey", "VGA", "VGA", -1, Common::FR_FRA, Common::kPlatformAmiga }, @@ -154,16 +155,16 @@ static const MD5Table md5table[] = { { "356fb5f680b68251333016175935d126", "BluesABCTime", "HE CUP", "Preview", 4133436, Common::UNK_LANG, Common::kPlatformUnknown }, { "35a2d3040fa512f8232d9e443319d84d", "dig", "", "", 659335495, Common::EN_ANY, Common::kPlatformMacintosh }, { "362c1d281fb9899254cda66ad246c66a", "dig", "Demo", "Demo", 3472, Common::EN_ANY, Common::kPlatformUnknown }, - { "3686cf8f89e102ececf4366e1d2c8126", "monkey2", "", "", 11135, Common::EN_ANY, Common::kPlatformPC }, + { "3686cf8f89e102ececf4366e1d2c8126", "monkey2", "", "", 11135, Common::EN_ANY, Common::kPlatformDOS }, { "36a6750e03fb505fc19fc2bf3e4dbe91", "pajama2", "", "Demo", 58749, Common::EN_ANY, Common::kPlatformUnknown }, { "3769b56c9a22f5521d74525ee459f88d", "puttrace", "HE 99", "Demo", 13108, Common::DE_DEU, Common::kPlatformWindows }, { "37aed3f91c1ef959e0bd265f9b13781f", "pajama", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, - { "37f56ceb13e401a7ac7d9e6b37fecaf7", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformPC }, + { "37f56ceb13e401a7ac7d9e6b37fecaf7", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformDOS }, { "37ff1b308999c4cca7319edfcc1280a0", "puttputt", "HE 70", "Demo", 8269, Common::EN_ANY, Common::kPlatformWindows }, - { "3824e60cdf639d22f6df92a03dc4b131", "fbear", "HE 62", "", 7732, Common::EN_ANY, Common::kPlatformPC }, - { "387a544b8b10b26912d8413bab63a853", "monkey2", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, + { "3824e60cdf639d22f6df92a03dc4b131", "fbear", "HE 62", "", 7732, Common::EN_ANY, Common::kPlatformDOS }, + { "387a544b8b10b26912d8413bab63a853", "monkey2", "", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, { "3938ee1aa4433fca9d9308c9891172b1", "indyzak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns }, - { "399b217b0c8d65d0398076da486363a9", "indy3", "VGA", "VGA", 6295, Common::DE_DEU, Common::kPlatformPC }, + { "399b217b0c8d65d0398076da486363a9", "indy3", "VGA", "VGA", 6295, Common::DE_DEU, Common::kPlatformDOS }, { "39cb9dec16fa16f38d79acd80effb059", "loom", "EGA", "EGA", -1, Common::UNK_LANG, Common::kPlatformAmiga }, { "39fd6db10d0222d817025c4d3346e3b4", "farm", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "3a03dab514e4038df192d8a8de469788", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformAmiga }, @@ -173,31 +174,32 @@ static const MD5Table md5table[] = { { "3a5ec90d556d4920976c5578bfbfaf79", "maniac", "NES", "", -1, Common::DE_DEU, Common::kPlatformNES }, { "3ae7f002d9256b8bdf76aaf8a3a069f8", "freddi", "HE 100", "", 34837, Common::EN_GRB, Common::kPlatformWii }, { "3af61c5edf8e15b43dbafd285b2e9777", "puttcircus", "", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows }, - { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC }, + { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformDOS }, { "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformUnknown }, { "3c4c471342bd95505a42334367d8f127", "puttmoon", "HE 70", "", 12161, Common::RU_RUS, Common::kPlatformWindows }, - { "3cce1913a3bc586b51a75c3892ff18dd", "indy3", "VGA", "VGA", -1, Common::RU_RUS, Common::kPlatformPC }, - { "3d219e7546039543307b55a91282bf18", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC }, + { "3cce1913a3bc586b51a75c3892ff18dd", "indy3", "VGA", "VGA", -1, Common::RU_RUS, Common::kPlatformDOS }, + { "3d219e7546039543307b55a91282bf18", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformDOS }, { "3de99ef0523f8ca7958faa3afccd035a", "spyfox", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "3df6ead57930488bc61e6e41901d0e97", "fbear", "HE 62", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "3e48298920fab9b7aec5a971e1bd1fab", "pajama3", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows }, { "3e861421f494711bc6f619d4aba60285", "airport", "", "", 93231, Common::RU_RUS, Common::kPlatformWindows }, - { "40564ec47da48a67787d1f9bd043902a", "maniac", "V2 Demo", "V2 Demo", 1988, Common::EN_ANY, Common::kPlatformPC }, + { "40564ec47da48a67787d1f9bd043902a", "maniac", "V2 Demo", "V2 Demo", 1988, Common::EN_ANY, Common::kPlatformDOS }, { "4167a92a1d46baa4f4127d918d561f88", "tentacle", "", "CD", 7932, Common::EN_ANY, Common::kPlatformUnknown }, { "41958e24d03181ff9a381a66d048a581", "ft", "", "", -1, Common::PT_BRA, Common::kPlatformUnknown }, { "425205754fa749f4f0b0dd9d09fa45fd", "football", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "430bc518017b6fac046f58bab6baad5d", "monkey2", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns }, { "439a7f4adf510489981ac52308e7d7a2", "maniac", "C64", "", -1, Common::DE_DEU, Common::kPlatformC64 }, { "45082a5c9f42ba14dacfe1fdeeba819d", "freddicove", "HE 100", "Demo", 18422, Common::EN_ANY, Common::kPlatformUnknown }, - { "45152f7cf2ba8f43cf8a8ea2e740ae09", "monkey", "VGA", "VGA", 8357, Common::ES_ESP, Common::kPlatformPC }, + { "45152f7cf2ba8f43cf8a8ea2e740ae09", "monkey", "VGA", "VGA", 8357, Common::ES_ESP, Common::kPlatformDOS }, { "4521138d15d1fd7649c31fb981746231", "pajama2", "HE 98.5", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "4522564b3c31aaf218b6a96826a549fd", "maze", "HE 99", "", -1, Common::EN_USA, Common::kPlatformWindows }, - { "46b53fd430adcfbed791b48a0d4b079f", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC }, - { "470c45b636139bb40716daa1c7edaad0", "loom", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformPC }, - { "477dbafbd66a53c98416dc01aef019ad", "monkey", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformPC }, - { "47e75b1bdcb44c78cb94883d1731ccf8", "fbear", "HE 62", "Demo", 6203, Common::EN_ANY, Common::kPlatformPC }, + { "46b53fd430adcfbed791b48a0d4b079f", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformDOS }, + { "470c45b636139bb40716daa1c7edaad0", "loom", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformDOS }, + { "477dbafbd66a53c98416dc01aef019ad", "monkey", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformDOS }, + { "47e041521d35c7a801bb1c010d84da9d", "freddi4", "HE 99", "Demo", -1, Common::IT_ITA, Common::kPlatformWindows }, + { "47e75b1bdcb44c78cb94883d1731ccf8", "fbear", "HE 62", "Demo", 6203, Common::EN_ANY, Common::kPlatformDOS }, { "48b9f04b348bc5013327753f0d12a144", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformAmiga }, - { "49210e124e4c2b30f1290a9ef6306301", "monkey", "EGA", "EGA", 8357, Common::EN_ANY, Common::kPlatformPC }, + { "49210e124e4c2b30f1290a9ef6306301", "monkey", "EGA", "EGA", 8357, Common::EN_ANY, Common::kPlatformDOS }, { "499c958affc394f2a3868f1eb568c3ee", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "49a1739981a89066b1121fac04b710f4", "spyfox2", "HE CUP", "Preview", 5756234, Common::UNK_LANG, Common::kPlatformUnknown }, { "4aa93cb30e485b728504ba3a693f12bf", "pajama", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows }, @@ -210,7 +212,7 @@ static const MD5Table md5table[] = { { "4c4820518e16e1a0e3616a3b021a04f3", "catalog", "HE CUP", "Preview", 10927456, Common::DE_DEU, Common::kPlatformUnknown }, { "4cb9c3618f71668f8e4346c8f323fa82", "monkey2", "", "", 10700, Common::EN_ANY, Common::kPlatformMacintosh }, { "4ce2d5b355964bbcb5e5ce73236ef868", "freddicove", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows }, - { "4cfd3fda4a4e6e64a1fc488eba973b7a", "fbpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC }, + { "4cfd3fda4a4e6e64a1fc488eba973b7a", "fbpack", "", "", -1, Common::EN_ANY, Common::kPlatformDOS }, { "4d34042713958b971cb139fba4658586", "atlantis", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns }, { "4d3fbc888de4e6565013f61dc83da6b6", "FreddisFunShop", "HE 99", "", 36245, Common::NL_NLD, Common::kPlatformUnknown }, { "4dbff3787aedcd96b0b325f2d92d7ad9", "maze", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, @@ -220,7 +222,7 @@ static const MD5Table md5table[] = { { "4edbf9d03550f7ba01e7f34d69b678dd", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "4f04b321a95d4315ce6d65f8e1dd0368", "maze", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "4f138ac6f9b2ac5a41bc68b2c3296064", "freddi4", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows }, - { "4f1d6f8b38343dba405472538b5037ed", "fbear", "HE 62", "", 7717, Common::EN_ANY, Common::kPlatformPC }, + { "4f1d6f8b38343dba405472538b5037ed", "fbear", "HE 62", "", 7717, Common::EN_ANY, Common::kPlatformDOS }, { "4f267a901719623de7dde83e47d5b474", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "4f580a021eee026f3b4589e17d130d78", "freddi4", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown }, { "4fa6870d9bc8c313b65d54b1da5a1891", "pajama", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, @@ -229,15 +231,15 @@ static const MD5Table md5table[] = { { "5057fb0e99e5aa29df1836329232f101", "freddi2", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows }, { "507bb360688dc4180fdf0d7597352a69", "freddi", "HE 73", "", 26402, Common::SE_SWE, Common::kPlatformWindows }, { "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 101", "", -1, Common::EN_ANY, Common::kPlatformWii }, - { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC }, + { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformDOS }, { "51305e929e330e24a75a0351c8f9975e", "freddi2", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "513f91a9dbe8d5490b39e56a3ac5bbdf", "pajama2", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "5262a27afcaee04e5c4900220bd463e7", "PuttsFunShop", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, - { "52a4bae0746a11d7b1e8554e91a6645c", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC }, + { "52a4bae0746a11d7b1e8554e91a6645c", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformDOS }, { "53e94115b55dd51d4b8ff0871aa1df1e", "spyfox", "", "Demo", 20103, Common::EN_ANY, Common::kPlatformUnknown }, { "54a936ad06161ff7bfefcb96200f7bff", "monkey", "VGA", "VGA Demo", 7617, Common::EN_ANY, Common::kPlatformAmiga }, { "55518cd73cf9c6d23ea29c51ee06bdfe", "ft", "", "", -1, Common::IT_ITA, Common::kPlatformUnknown }, - { "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, + { "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "Akella", -1, Common::RU_RUS, Common::kPlatformUnknown }, { "55f4e9402bec2bded383843123f37c5c", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows }, { "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows }, { "56b5922751be7ffd771b38dda56b028b", "freddi", "HE 100", "", 34837, Common::NL_NLD, Common::kPlatformWii }, @@ -245,53 +247,53 @@ static const MD5Table md5table[] = { { "5798972220cd458be2626d54c80f71d7", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga }, { "57a17febe2183f521250e55d55b83e60", "PuttTime", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "57a5cfec9ef231a007043cc1917e8988", "freddi", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii }, - { "57b0d89af79befe1cabce3bece869e7f", "tentacle", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC }, + { "57b0d89af79befe1cabce3bece869e7f", "tentacle", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformDOS }, { "58436e634f4fae1d9973591c2ffa1fcb", "spyfox", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "589601b676c98b1c0c987bc031ab68b3", "chase", "HE 95", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "58fdf4c7ad13540a734e18f8584cad89", "puttzoo", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "590e6546aacd0d374b7f3a4f53013ab1", "freddicove", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown }, { "59d5cfcc5e672a6e07baae01328b918b", "PuttTime", "HE 90", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown }, - { "5a35e36fd777e9c37a49c5b2faca52f9", "loom", "EGA", "EGA Demo", 6108, Common::EN_ANY, Common::kPlatformPC }, + { "5a35e36fd777e9c37a49c5b2faca52f9", "loom", "EGA", "EGA Demo", 6108, Common::EN_ANY, Common::kPlatformDOS }, { "5b08000a9c47b2887df6506ac767ca68", "fbear", "HE 62", "", -1, Common::EN_ANY, Common::kPlatform3DO }, { "5bd335265a61caa3d78956ad9f88ba23", "football", "", "Demo", 23135, Common::EN_ANY, Common::kPlatformUnknown }, { "5c21fc49aee8f46e58fef21579e614a1", "thinker1", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "5c9cecbd2952ccec14c9ecebf5822a34", "puttzoo", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformIOS }, - { "5d88b9d6a88e6f8e90cded9d01b7f082", "loom", "VGA", "VGA", 8307, Common::EN_ANY, Common::kPlatformPC }, + { "5d88b9d6a88e6f8e90cded9d01b7f082", "loom", "VGA", "VGA", 8307, Common::EN_ANY, Common::kPlatformDOS }, { "5dda73606533d66a4c3f4f9ea6e842af", "farm", "", "", 87061, Common::RU_RUS, Common::kPlatformWindows }, { "5e8fb66971a60e523e5afbc4c129c0e8", "socks", "HE 85", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "5ebb57234b2fe5c5dff641e00184ad81", "freddi", "HE 73", "", -1, Common::FR_FRA, Common::kPlatformWindows }, - { "5fbe557049892eb4b709d90916ec97ca", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformPC }, + { "5fbe557049892eb4b709d90916ec97ca", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformDOS }, { "5fdb2ac2483908b065c6e77988338a54", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows }, { "600abd3e9f47e63e670188b7e4e86ac7", "spyozon", "", "", 47128, Common::EN_USA, Common::kPlatformUnknown }, { "6027e9ca9c35746d95dee2068cec17e5", "zak", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "60ba818dc3bede86d40357e3913f8505", "ft", "", "Version B", 19697, Common::EN_ANY, Common::kPlatformUnknown }, { "613f64f78ea26c7353b2a5940eb61d6a", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAtariST }, { "62050da376483d8edcbd98cd26b6cb57", "puttrace", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, - { "624cdb93654667c869d204a64af7e57f", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformPC }, + { "624cdb93654667c869d204a64af7e57f", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformDOS }, { "6269b8fbf51a353e5b501e4ad98cdc67", "arttime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "6271130f440066830eca9056c1d7926f", "water", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "62b8c16b6db226ba95aaa8be73f9885c", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformAmiga }, { "632d2fddb8ba97723fa15334763ae857", "thinker1", "", "", 33270, Common::EN_ANY, Common::kPlatformWindows }, { "63fdcdc95cdeea00060883aed38e5504", "PuttTime", "HE 85", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "6508fd55530e6915507e1cc37f7f045d", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC }, + { "6508fd55530e6915507e1cc37f7f045d", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "65563295c3a06493351870f20a1630cf", "spyozon", "HE CUP", "Preview", 5235008, Common::UNK_LANG, Common::kPlatformUnknown }, { "659942b9a6b519f123a13cca3c333a13", "jungle", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "65fa23d6884e8ca23d5d2406d70de7e8", "puttzoo", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, - { "66236cd1aec24e1d4aff4c4cc93b7e18", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC }, + { "66236cd1aec24e1d4aff4c4cc93b7e18", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS }, { "663743c03ae0c007f3d665cf631c0e6b", "puttrace", "HE 99", "Demo", 13135, Common::DE_DEU, Common::kPlatformUnknown }, - { "66fd5ff9a810dfeb6d6bdada18221140", "monkey", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformPC }, + { "66fd5ff9a810dfeb6d6bdada18221140", "monkey", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformDOS }, { "672dec94b82f7f0877ebb5b5cf7f4bc1", "pajama", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, - { "675d71151e9b5a968c8ce46d9fbf4cbf", "zak", "V2", "V2", 1916, Common::EN_ANY, Common::kPlatformPC }, + { "675d71151e9b5a968c8ce46d9fbf4cbf", "zak", "V2", "V2", 1916, Common::EN_ANY, Common::kPlatformDOS }, { "679855cf61932f9bf995c8f3677380ed", "pajama3", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, { "68155a6bf082221525f431c2cbdac8ab", "SamsFunShop", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "684732efb5799c0f78804c99d8de9aba", "puttputt", "HE 62", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "68530d2e15f339fbbf3150b78b4d2ffb", "freddi", "HE 73", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "688328c5bdc4c8ec4145688dfa077bf2", "freddi4", "HE 99", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, - { "6886e5d08cee329b1f2e743ae2e3ceed", "monkey2", "", "", 11135, Common::DE_DEU, Common::kPlatformPC }, + { "6886e5d08cee329b1f2e743ae2e3ceed", "monkey2", "", "", 11135, Common::DE_DEU, Common::kPlatformDOS }, { "695fe0b3963333b7e15b37514db3c745", "thinkerk", "", "Demo", 29789, Common::EN_USA, Common::kPlatformUnknown }, - { "697c9b7c55a05d8199c48b48e379d2c8", "puttmoon", "", "", -1, Common::HE_ISR, Common::kPlatformPC }, - { "69d70269fafc4445adbb0d223e4f9a3f", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformPC }, - { "69ea626f1f87eecb78ea0d6c6b983a1d", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformPC }, + { "697c9b7c55a05d8199c48b48e379d2c8", "puttmoon", "", "", -1, Common::HE_ISR, Common::kPlatformDOS }, + { "69d70269fafc4445adbb0d223e4f9a3f", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformDOS }, + { "69ea626f1f87eecb78ea0d6c6b983a1d", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformDOS }, { "69ffe29185b8d71f09f6199f8b2a87cb", "lost", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "6a30a07f353a75cdc602db27d73e1b42", "puttputt", "HE 70", "", -1, Common::EN_ANY, Common::kPlatformWindows }, { "6a60d395b78b205c93a956100b1bf5ae", "pajama2", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, @@ -299,7 +301,7 @@ static const MD5Table md5table[] = { { "6b19d0e25cbf720d05822379b8b90ed9", "PuttTime", "HE 90", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "6b257bb2827dd894b8109a50a1a18b5a", "freddicove", "HE 100", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "6b27dbcd8d5697d5c918eeca0f68ef6a", "puttrace", "HE CUP", "Preview", 3901484, Common::UNK_LANG, Common::kPlatformUnknown }, - { "6b3ec67da214f558dc5ceaa2acd47453", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC }, + { "6b3ec67da214f558dc5ceaa2acd47453", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "6b5a3fef241e90d4b2e77f1e222773ee", "maniac", "NES", "", -1, Common::SE_SWE, Common::kPlatformNES }, { "6bca7a1a96d16e52b8f3c42b50dbdca3", "fbear", "HE 62", "", -1, Common::JA_JPN, Common::kPlatform3DO }, { "6bf70eee5de3d24d2403e0dd3d267e8a", "spyfox", "", "", 49221, Common::UNK_LANG, Common::kPlatformWindows }, @@ -310,36 +312,36 @@ static const MD5Table md5table[] = { { "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown }, { "6ea966b4d660c870b9ee790d1fbfc535", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformAmiga }, { "6f0be328c64d689bb606d22a389e1b0f", "loom", "No AdLib", "EGA", 5748, Common::EN_ANY, Common::kPlatformMacintosh }, - { "6f6ef668c608c7f534fea6e6d3878dde", "indy3", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformPC }, - { "6f8a22bfa397be1f7ed4b74aba0e397e", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC }, + { "6f6ef668c608c7f534fea6e6d3878dde", "indy3", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformDOS }, + { "6f8a22bfa397be1f7ed4b74aba0e397e", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS }, { "701246819d1a70573f41bf33fc19214f", "soccer", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "7015b059ab72cff3a0ef9fb4d5e9889d", "spyozon", "", "", -1, Common::DE_DEU, Common::kPlatformWindows }, - { "7020931d5a2be0a49d68e7a1882363e4", "zak", "V1", "V1", 1896, Common::EN_ANY, Common::kPlatformPC }, + { "7020931d5a2be0a49d68e7a1882363e4", "zak", "V1", "V1", 1896, Common::EN_ANY, Common::kPlatformDOS }, { "70b0719ac3a5b47ae233c561823d5b96", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh }, - { "71523b539491527d9860f4407faf0411", "monkey", "Demo", "EGA Demo", 7607, Common::EN_ANY, Common::kPlatformPC }, + { "71523b539491527d9860f4407faf0411", "monkey", "Demo", "EGA Demo", 7607, Common::EN_ANY, Common::kPlatformDOS }, { "71d384e7676c53d513ddd333eae1d82c", "Blues123time", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "71fe97c3108678cf604f14abe342341b", "spyfox2", "", "", -1, Common::NL_NLD, Common::kPlatformWindows }, { "7222f260253f325c21fcfa68b5bfab67", "spyfox2", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "72ac6bc980d5101c2142189d746bd62f", "spyfox", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "732845548b1d6c2da572cb6a1bf81b07", "spyfox2", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "73b8197e236da4bf49adc99fe8f5fa1b", "spyfox", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, - { "73e5ab7dbb9a8061cc6d25df02dbd1e7", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC }, + { "73e5ab7dbb9a8061cc6d25df02dbd1e7", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "7410a8ba9795020cd42f171c4320659e", "pajama3", "", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "746e88c172a5b7a1ae89ac0ee3ee681a", "freddi", "HE 90", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows }, { "74da3494fbe1a7d20213b0afe0954755", "catalog", "HE CUP", "Preview", 10841544, Common::FR_FRA, Common::kPlatformUnknown }, { "754feb59d3bf86b8a00840df74fd7b26", "freddi3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, - { "75ba23fff4fd63fa446c02864f2a5a4b", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC }, + { "75ba23fff4fd63fa446c02864f2a5a4b", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformDOS }, { "75bff95816b84672b877d22a911ab811", "freddi3", "HE 99", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows }, { "76b66b43e593ad4d2f1dfb5cc8f19700", "spyfox", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformWindows }, - { "771bc18ec6f93837b839c992b211904b", "monkey", "Demo", "EGA Demo", -1, Common::DE_DEU, Common::kPlatformPC }, - { "7766c9487f9d53a8cb0edabda5119c3d", "puttputt", "HE 60", "", 8022, Common::EN_ANY, Common::kPlatformPC }, + { "771bc18ec6f93837b839c992b211904b", "monkey", "Demo", "EGA Demo", -1, Common::DE_DEU, Common::kPlatformDOS }, + { "7766c9487f9d53a8cb0edabda5119c3d", "puttputt", "HE 60", "", 8022, Common::EN_ANY, Common::kPlatformDOS }, { "77f5c9cc0986eb729c1a6b4c8823bbae", "zakloom", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns }, - { "780e4a0ae2ff17dc296f4a79543b44f8", "puttmoon", "", "", -1, Common::UNK_LANG, Common::kPlatformPC }, + { "780e4a0ae2ff17dc296f4a79543b44f8", "puttmoon", "", "", -1, Common::UNK_LANG, Common::kPlatformDOS }, { "782393c5934ecd0b536eaf5fd541bd26", "pajama", "HE 101", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, { "784b499c98d07260a30952685758636b", "pajama3", "", "Demo", 13911, Common::DE_DEU, Common::kPlatformWindows }, { "78bd5f036ea35a878b74e4f47941f784", "freddi4", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "78c07ca088526d8d4446a4c2cb501203", "freddi3", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, - { "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformPC }, + { "7974365d3dc0f43a2748c975f91ff042", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformDOS }, { "79b05f628586837e7166e82b2279bb50", "loom", "PC-Engine", "", -1, Common::JA_JPN, Common::kPlatformPCEngine }, { "7bad72e332a59f9fcc1d437f4edad32a", "puttcircus", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, { "7c2e76087027eeee9c8f8985f93a1cc5", "freddi4", "", "Demo", 13584, Common::EN_ANY, Common::kPlatformUnknown }, @@ -349,7 +351,7 @@ static const MD5Table md5table[] = { { "7e151c17adf624f1966c8fc5827c95e9", "puttputt", "HE 61", "", -1, Common::EN_ANY, Common::kPlatform3DO }, { "7ea2da67ebabea4ac20cee9f4f9d2934", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown }, - { "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", "V1", "V1", 1972, Common::EN_ANY, Common::kPlatformPC }, + { "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", "V1", "V1", 1972, Common::EN_ANY, Common::kPlatformDOS }, { "7f945525abcd48015adf1632637a44a1", "pajama", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "7fc6cdb46b4c9d384c52327f4bca6416", "football", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "810a9da887aefa597b0cf3c77d262897", "BluesABCTime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, @@ -362,18 +364,18 @@ static const MD5Table md5table[] = { { "84e3c23a49ded8a6f9197735c8eb3de7", "PuttTime", "HE 85", "", -1, Common::DE_DEU, Common::kPlatformWindows }, { "8539c0ff89868e55a08e652ac44daaae", "water", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "861e59ed72a1cd0e6d454f7ee7e2bf3d", "comi", "", "", -1, Common::RU_RUS, Common::kPlatformWindows }, - { "86be8ada36371d4fdc35659d0e912a26", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC }, + { "86be8ada36371d4fdc35659d0e912a26", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS }, { "86c9902b7bec1a17926d4dae85beaa45", "airport", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, { "870d1e3c86bc50846d808d14a36b4e08", "monkey", "VGA", "VGA", -1, Common::ES_ESP, Common::kPlatformAmiga }, { "8776caed014c321272af407c1502a2df", "monkey", "CD", "", 8955, Common::EN_ANY, Common::kPlatformMacintosh }, { "87df3e0074624040407764b7c5e710b9", "pajama", "", "Demo", 18354, Common::NL_NLD, Common::kPlatformWindows }, - { "87f6e8037b7cc996e13474b491a7a98e", "maniac", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC }, + { "87f6e8037b7cc996e13474b491a7a98e", "maniac", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformDOS }, { "8801fb4a1200b347f7a38523339526dd", "jungle", "", "", -1, Common::EN_ANY, Common::kPlatformWindows }, { "880c5ca5b944648b3f8b03feb41705a8", "freddi", "HE 100", "", 34837, Common::SE_SWE, Common::kPlatformWii }, { "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", "", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown }, { "898ce8eb1234a955ef75e87141902bb3", "freddi3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "898eaa21f79cf8d4f08db856244689ff", "pajama", "HE 99", "Updated", 66505, Common::EN_ANY, Common::kPlatformWindows }, - { "89cfc425566003ff74b7dc7b3e6fd469", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC }, + { "89cfc425566003ff74b7dc7b3e6fd469", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS }, { "8a484262363a8e18be87112454f1456b", "pjgames", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "8aa05d3cdb0e795436043f0546af2da2", "tentacle", "", "CD?", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "8aed489aba45d2b9fb8a04079c9c6e6a", "baseball", "HE CUP", "Preview", 12876596, Common::UNK_LANG, Common::kPlatformUnknown }, @@ -382,40 +384,41 @@ static const MD5Table md5table[] = { { "8d479e36f35e80257dfc102cf4b8a912", "farm", "HE 72", "Demo", 34333, Common::EN_ANY, Common::kPlatformWindows }, { "8de13897f0121c79d29a2377159f9ad0", "socks", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, { "8e3241ddd6c8dadf64305e8740d45e13", "balloon", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "8e4ee4db46954bfe2912e259a16fad82", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformPC }, + { "8e4ee4db46954bfe2912e259a16fad82", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformDOS }, { "8e9417564f33790815445b2136efa667", "atlantis", "", "CD", 11915, Common::JA_JPN, Common::kPlatformMacintosh }, { "8e9830a6f2702be5b22c8fa0a6aaf977", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformMacintosh }, { "8eb84cee9b429314c7f0bdcf560723eb", "monkey", "FM-TOWNS", "", 9925, Common::EN_ANY, Common::kPlatformFMTowns }, { "8ee63cafb1fe9d62aa0d5a23117e70e7", "freddi2", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, - { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC }, + { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformDOS }, { "8fec68383202d38c0d25e9e3b757c5df", "comi", "Demo", "Demo", 18041, Common::UNK_LANG, Common::kPlatformWindows }, { "8ffd618a776a4c0d8922bb28b09f8ce8", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, - { "90a329d8ad5b7ce0690429e98cfbb32f", "funpack", "", "", -1, Common::HE_ISR, Common::kPlatformPC }, + { "90a329d8ad5b7ce0690429e98cfbb32f", "funpack", "", "", -1, Common::HE_ISR, Common::kPlatformDOS }, { "90c755e1c9b9b8a4129d37b2259d0655", "chase", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "90e2f0af4f779629695c6394a65bb702", "spyfox2", "", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, - { "910e31cffb28226bd68c569668a0d6b4", "monkey", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC }, + { "910e31cffb28226bd68c569668a0d6b4", "monkey", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS }, { "91469353f7be1b122fa88d23480a1320", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAmiga }, { "91d5db93187fab54d823f73bd6441cb6", "maniac", "NES", "", -1, Common::EN_USA, Common::kPlatformNES }, { "927a764615c7fcdd72f591355e089d8c", "monkey", "No AdLib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST }, - { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC }, + { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "92e7727e67f5cd979d8a1070e4eb8cb3", "puttzoo", "HE 98.5", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "92fc0073a4cf259ff36070ecb8628ba8", "thinkerk", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, - { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC }, + { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "94db6519da85b8d08c976d8e9a858ea7", "baseball", "HE CUP", "Preview", 10044774, Common::UNK_LANG, Common::kPlatformUnknown }, { "95818b178d473c989ac753574e8892aa", "readtime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "95b3806e043be08668c54c3ffe98650f", "BluesABCTime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "95be99181bd0f10fef4872c2d4a771cb", "zak", "V1", "", -1, Common::DE_DEU, Common::kPlatformC64 }, { "96a3069a3c63caa7329588ce1fef41ee", "spyozon", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, - { "9708cf716ed8bcc9ff3fcfc69413b746", "puttputt", "HE 62", "", -1, Common::EN_ANY, Common::kPlatformPC }, + { "9708cf716ed8bcc9ff3fcfc69413b746", "puttputt", "HE 62", "", -1, Common::EN_ANY, Common::kPlatformDOS }, + { "9778341eefc6feb447ca07e7be21791c", "puttrace", "HE 99", "Demo", -1, Common::IT_ITA, Common::kPlatformWindows }, { "9781422e4288dbc090720e4563168ba7", "puttzoo", "", "", -1, Common::FR_FRA, Common::kPlatformWindows }, { "981e1e1891f2be7e25a01f50ae55a5af", "puttrace", "HE 98", "", -1, Common::EN_USA, Common::kPlatformUnknown }, - { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, + { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, { "99128b6a5bdd9831d9682fb8b5cbf8d4", "BluesBirthday", "Yellow", "Yellow", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "99a3699f80b8f776efae592b44b9b991", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC }, - { "99b6f822b0b2612415407865438697d6", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, + { "99a3699f80b8f776efae592b44b9b991", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformDOS }, + { "99b6f822b0b2612415407865438697d6", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, { "9b7452b5cd6d3ffb2b2f5118010af84f", "ft", "Demo", "Demo", 116463537, Common::EN_ANY, Common::kPlatformMacintosh }, { "9bc548e179cdb0767009401c094d0895", "maniac", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAmiga }, - { "9bd2a8f72613e715c199246dd511e10f", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC }, + { "9bd2a8f72613e715c199246dd511e10f", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformDOS }, { "9bda5fee51d2fda5253d02c642016bf4", "spyfox", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "9c0ee9c252785e9fca0143e42ac4b256", "freddi2", "HE 99", "Updated", -1, Common::DE_DEU, Common::kPlatformWindows }, { "9c0fee288ad564a7d25ec3e841810d79", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformAmiga }, @@ -427,8 +430,8 @@ static const MD5Table md5table[] = { { "9dc02577bf50d4cfaf3de3fbac06fbe2", "puttmoon", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "9e5e0fb43bd22f4628719b7501adb717", "monkey", "No AdLib", "EGA", -1, Common::FR_FRA, Common::kPlatformAtariST }, { "9fd66fb3b04703bd50da4356e4202558", "spyfox2", "", "", 51295, Common::EN_ANY, Common::kPlatformMacintosh }, - { "a00554c31d623fdb9fcb0f924b89b42b", "loom", "EGA", "EGA Demo", -1, Common::EN_ANY, Common::kPlatformPC }, - { "a01fab4a64d47b96e2e58e6b0f825cc7", "monkey", "VGA", "VGA", 8347, Common::FR_FRA, Common::kPlatformPC }, + { "a00554c31d623fdb9fcb0f924b89b42b", "loom", "EGA", "EGA Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, + { "a01fab4a64d47b96e2e58e6b0f825cc7", "monkey", "VGA", "VGA", 8347, Common::FR_FRA, Common::kPlatformDOS }, { "a095616d2d23ccf43b8e257711202cba", "football2002", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "a095e33061606d231ff37dca4c64c8ac", "pajama", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "a0a7dea72003933b8b3f8b99b9f7ddeb", "loom", "No AdLib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST }, @@ -438,7 +441,7 @@ static const MD5Table md5table[] = { { "a2386da005672cbd5136f4f27a626c5f", "farm", "", "", 87061, Common::NL_NLD, Common::kPlatformWindows }, { "a28135a7ade38cc0208b04507c46efd1", "spyfox", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", "HE 99", "Demo", 15540, Common::EN_ANY, Common::kPlatformWindows }, - { "a3036878840720fbefa41e6965fa4a0a", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC }, + { "a3036878840720fbefa41e6965fa4a0a", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformDOS }, { "a336134914eaab4892d35625aa15ad1d", "freddi4", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "a525c1753c1db5011c00417da37887ef", "PuttTime", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, { "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, @@ -454,38 +457,38 @@ static const MD5Table md5table[] = { { "a9543ef0d79bcb47cd76ec197ad0a967", "puttmoon", "", "", -1, Common::EN_ANY, Common::kPlatform3DO }, { "a99c39ba65b6086be28aef576da69595", "spyozon", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, { "a9f2f04b1ecaab9495b59befffe9bf88", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, - { "aa6a91b7f6f119d1b7b1f2a4c9e24d59", "puttmoon", "", "Demo", 6233, Common::EN_ANY, Common::kPlatformPC }, - { "aa7a07d94ae853f6460be4ce0a1bf530", "monkey", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC }, + { "aa6a91b7f6f119d1b7b1f2a4c9e24d59", "puttmoon", "", "Demo", 6233, Common::EN_ANY, Common::kPlatformDOS }, + { "aa7a07d94ae853f6460be4ce0a1bf530", "monkey", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS }, { "aa81aa6d5545ce172fdba81f2e2f9d36", "puttzoo", "", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows }, - { "aa8a0cb65f3afbbe2c14c3f9f92775a3", "monkey", "CD", "CD", 8955, Common::FR_FRA, Common::kPlatformPC }, + { "aa8a0cb65f3afbbe2c14c3f9f92775a3", "monkey", "CD", "CD", 8955, Common::FR_FRA, Common::kPlatformDOS }, { "aaa587701cde7e74692c68c1024b85eb", "puttrace", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "aaa7f36a253f277dd29dd1c051b0e4b9", "indy3", "No AdLib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST }, { "ab0693e9324cfcf498fdcbb12acf8bb4", "puttcircus", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "ac1642b6edfb8521ca03760126f1c250", "tentacle", "", "Demo", -1, Common::DE_DEU, Common::kPlatformPC }, + { "ac1642b6edfb8521ca03760126f1c250", "tentacle", "", "Demo", -1, Common::DE_DEU, Common::kPlatformDOS }, { "ac62d50e39492ee3738b4e83a5ac780f", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows }, { "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC }, + { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformDOS }, { "aeec382acef62e122bf0d5b14581cfa4", "zak", "V1", "", -1, Common::IT_ITA, Common::kPlatformC64 }, { "aefa244ea034b7cd2041f0a44be7d9ba", "pajama3", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "af2bd1a43b50b55915d87994e093203d", "freddi", "HE 99", "Updated", 34829, Common::DE_DEU, Common::kPlatformWindows }, { "b100abf7ff83146df50db78dbd5e9cfa", "freddicove", "HE 100", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, - { "b23f7cd7c304d7dff08e92a96120d5b4", "zak", "V1", "V1", -1, Common::EN_ANY, Common::kPlatformPC }, - { "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformPC }, - { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC }, + { "b23f7cd7c304d7dff08e92a96120d5b4", "zak", "V1", "V1", -1, Common::EN_ANY, Common::kPlatformDOS }, + { "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformDOS }, + { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformDOS }, { "b47be81e39a9710f6f595f7b527b60f8", "puttrace", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows }, { "b5298a5c15ffbe8b381d51ea4e26d35c", "freddi4", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, - { "b597e0403cc0002f69170e6caba7edd9", "indy3", "EGA", "EGA Demo", 5361, Common::EN_ANY, Common::kPlatformPC }, + { "b597e0403cc0002f69170e6caba7edd9", "indy3", "EGA", "EGA Demo", 5361, Common::EN_ANY, Common::kPlatformDOS }, { "b628506f7def772e40de0aa5440fb8e1", "activity", "HE 70", "", -1, Common::EN_ANY, Common::kPlatformWindows }, { "b7d37d6b786b5a22deea3b038eca96ca", "maniac", "NES", "", -1, Common::ES_ESP, Common::kPlatformNES }, - { "b886b0a5d909c7158a914e1d7c1c6c65", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC }, + { "b886b0a5d909c7158a914e1d7c1c6c65", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS }, { "b8955d7d23b4972229060d1592489fef", "freddicove", "HE 100", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "b9ba19ce376efc69be78ef3baef8d2b9", "monkey", "CD", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, - { "b9bb68c5d2c9b6e2d9c513a29a754a57", "puttmoon", "", "", 7828, Common::EN_ANY, Common::kPlatformPC }, + { "b9bb68c5d2c9b6e2d9c513a29a754a57", "puttmoon", "", "", 7828, Common::EN_ANY, Common::kPlatformDOS }, { "ba888e6831517597859e91aa173f945c", "spyfox", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "bab0fb81dcb12b8930c5d850b8f2a7de", "balloon", "HE 80", "", 12800, Common::DE_DEU, Common::kPlatformWindows }, { "bbadf7309c4a2c2763e4bbba3c3be634", "freddi3", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "bc4700bc0e12879f6d25d14d6be6cfdd", "spyfox2", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, - { "bd126753de619a495f9f22adc951c8d5", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformPC }, + { "bd126753de619a495f9f22adc951c8d5", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformDOS }, { "bd5fd7835335dfce03064d5f77b7f0ae", "dog", "", "", 19681, Common::NL_NLD, Common::kPlatformWindows }, { "be2abe172f58db170de3a037daa1dd27", "puttputt", "HE 61", "", -1, Common::JA_JPN, Common::kPlatform3DO }, { "be39a5d4db60e8aa736b9086778cb45c", "spyozon", "", "", -1, Common::EN_GRB, Common::kPlatformWindows }, @@ -499,18 +502,18 @@ static const MD5Table md5table[] = { { "c24c490373aeb48fbd54caa8e7ae376d", "loom", "No AdLib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST }, { "c25755b08a8d0d47695e05f1e2111bfc", "freddi4", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "c30ef068add4277104243c31ce46c12b", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformAmiga }, - { "c3196c5349e53e387aaff1533d95e53a", "samnmax", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC }, + { "c3196c5349e53e387aaff1533d95e53a", "samnmax", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformDOS }, { "c3b22fa4654bb580b20325ebf4174841", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformWindows }, - { "c3df37df9d3b481b45f75283a9907c47", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformPC }, - { "c4787c3e8b5e2dfda90850ee800af00f", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC }, + { "c3df37df9d3b481b45f75283a9907c47", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformDOS }, + { "c4787c3e8b5e2dfda90850ee800af00f", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformDOS }, { "c4ffae9fac495475d6bc3343ccc8faf9", "Soccer2004", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "c5cc7cba02a2fbd539c4439e775b0536", "puttzoo", "HE 99", "Updated", 43470, Common::DE_DEU, Common::kPlatformWindows }, { "c5d10e190d4b4d59114b824f2fdbd00e", "loom", "FM-TOWNS", "", 7540, Common::EN_ANY, Common::kPlatformFMTowns }, - { "c63ee46143ba65f9ce14cf539ca51bd7", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC }, + { "c63ee46143ba65f9ce14cf539ca51bd7", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformDOS }, { "c666a998af90d81db447eccba9f72c8d", "monkey", "No AdLib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST }, { "c6907d44f1166941d982864cd42cdc89", "pajama2", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "c782fbbe74a987c3df8ac73cd3e289ed", "freddi", "HE 73", "", -1, Common::SE_SWE, Common::kPlatformMacintosh }, - { "c7890e038806df2bb5c0c8c6f1986ea2", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformPC }, + { "c7890e038806df2bb5c0c8c6f1986ea2", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformDOS }, { "c7be10f775404fd9785a8b92a06d240c", "atlantis", "FM-TOWNS", "", 12030, Common::EN_ANY, Common::kPlatformFMTowns }, { "c7c492a107ec520d7a7943037d0ca54a", "freddi", "HE 71", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows }, { "c8253da0f4626d2236b5291b99e33408", "puttcircus", "HE 99", "", -1, Common::HE_ISR, Common::kPlatformWindows }, @@ -522,15 +525,15 @@ static const MD5Table md5table[] = { { "cb1559e8405d17a5a278a6b5ad9338d1", "freddi3", "", "Demo", 22718, Common::EN_ANY, Common::kPlatformUnknown }, { "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", "", "CD", 282467632, Common::EN_ANY, Common::kPlatformMacintosh }, { "cc0c4111449054f1692bb3c0c5e04629", "BluesBirthday", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "Floppy", "Demo", 7485, Common::DE_DEU, Common::kPlatformPC }, + { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "Floppy", "Demo", 7485, Common::DE_DEU, Common::kPlatformDOS }, { "cd424f143a141bc59226ad83a6e40f51", "maze", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, - { "cd46c9f122272d02bbf79332ff521898", "loom", "EGA", "EGA", 5748, Common::RU_RUS, Common::kPlatformPC }, + { "cd46c9f122272d02bbf79332ff521898", "loom", "EGA", "EGA", 5748, Common::RU_RUS, Common::kPlatformDOS }, { "cd9c05e755d7bf8e9b9590ad1ebe273e", "dig", "Demo", "Demo", 45156007, Common::EN_ANY, Common::kPlatformMacintosh }, - { "cdd760228cf1010c2903f37e788ea31c", "zak", "V2", "V2", 1916, Common::DE_DEU, Common::kPlatformPC }, + { "cdd760228cf1010c2903f37e788ea31c", "zak", "V2", "V2", 1916, Common::DE_DEU, Common::kPlatformDOS }, { "ce2304f3919e1dcfcc512a81d7b603e0", "SoccerMLS", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "ce6a4cef315b20fef58a95bc40a2d8d3", "monkey", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC }, + { "ce6a4cef315b20fef58a95bc40a2d8d3", "monkey", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformDOS }, { "ce7733f185b838e248927c7ba1a04204", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAmiga }, - { "ce7fd0c382389a6791fc3e199c117ef4", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC }, + { "ce7fd0c382389a6791fc3e199c117ef4", "indy3", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformDOS }, { "cea91e3dd47f2518ea418e41611aa77f", "spyfox2", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, { "cf400d20769fb70eb21766582f4924f7", "moonbase", "", "", -1, Common::EN_ANY, Common::kPlatformWindows }, { "cf4ef315214c7d8cdab6302cdb7e50db", "freddi", "HE 73", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows }, @@ -539,13 +542,13 @@ static const MD5Table md5table[] = { { "cf90b4db5486ef798db78fe6fbf897e5", "pajama3", "", "Demo", 13902, Common::EN_USA, Common::kPlatformWindows }, { "d00ffc8c32d17e575fd985d435d2eb88", "arttime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "d0549508a06bbb9f99ed19c9e97891f3", "football2002", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "d06fbe28818fef7bfc45c2cdf0c0849d", "zak", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformPC }, + { "d06fbe28818fef7bfc45c2cdf0c0849d", "zak", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformDOS }, { "d0ad929def3e9cfe39dea55bd12098d4", "puttcircus", "", "", -1, Common::FR_FRA, Common::kPlatformWindows }, - { "d0b531227a27c6662018d2bd05aac52a", "monkey", "VGA", "VGA", 8357, Common::DE_DEU, Common::kPlatformPC }, + { "d0b531227a27c6662018d2bd05aac52a", "monkey", "VGA", "VGA", 8357, Common::DE_DEU, Common::kPlatformDOS }, { "d220d154aafbfa12bd6f3ab1b2dae420", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformMacintosh }, { "d2cc8e31bce61e6cf2951249e10638fe", "basketball", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "d37c55388294b66e53e7ced3af88fa68", "freddi2", "HE 100", "Updated Demo", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "d43352a805d78b5f4936c6d7779bf575", "samnmax", "", "CD", -1, Common::RU_RUS, Common::kPlatformPC }, + { "d43352a805d78b5f4936c6d7779bf575", "samnmax", "", "CD", -1, Common::RU_RUS, Common::kPlatformDOS }, { "d4aac997e2f4e15341f0bfbf905419bd", "PuttTime", "HE 99", "", 62698, Common::EN_GRB, Common::kPlatformWindows }, { "d4b8ee426b1afd3e53bc0cf020418cf6", "dog", "HE 99", "", -1, Common::EN_ANY, Common::kPlatformWindows }, { "d4cccb5af88f3e77f370896e9ba8c5f9", "freddi", "HE 71", "", -1, Common::UNK_LANG, Common::kPlatformWindows }, @@ -553,7 +556,7 @@ static const MD5Table md5table[] = { { "d54622d31255619d207dd245d3f92327", "freddi4", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, { "d55eff37c2100f5065cde9de428621fa", "zak", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformAtariST }, { "d62047a6729349ab36f7ee065bf26509", "dig", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown }, - { "d62d248c3df6ec177405e2cb23d923b2", "indy3", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformPC }, + { "d62d248c3df6ec177405e2cb23d923b2", "indy3", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformDOS }, { "d6334a5a9b61afe18c368540fdf522ca", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "d6dd0646404768a63e963891a96daadd", "atlantis", "Floppy", "Floppy", 12035, Common::EN_ANY, Common::kPlatformMacintosh }, { "d73c851b942af44deb9b6d5f416a0972", "freddi3", "HE 99", "Demo", -1, Common::HE_ISR, Common::kPlatformWindows }, @@ -562,9 +565,9 @@ static const MD5Table md5table[] = { { "d7b247c26bf1f01f8f7daf142be84de3", "balloon", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows }, { "d8323015ecb8b10bf53474f6e6b0ae33", "dig", "", "", 16304, Common::UNK_LANG, Common::kPlatformUnknown }, { "d917f311a448e3cc7239c31bddb00dd2", "samnmax", "", "CD", 9080, Common::EN_ANY, Common::kPlatformUnknown }, - { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "", "Demo", 6478, Common::EN_ANY, Common::kPlatformPC }, + { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "", "Demo", 6478, Common::EN_ANY, Common::kPlatformDOS }, { "da09e666fc8f5b78d7b0ac65d1a3b56e", "monkey2", "FM-TOWNS", "", 11135, Common::EN_ANY, Common::kPlatformFMTowns }, - { "da6269b18fcb08189c0aa9c95533cce2", "monkey", "CD", "CD", 8955, Common::IT_ITA, Common::kPlatformPC }, + { "da6269b18fcb08189c0aa9c95533cce2", "monkey", "CD", "CD", 8955, Common::IT_ITA, Common::kPlatformDOS }, { "da669b20271b85182e9c17a2a37ea02e", "monkey2", "", "", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "db21a6e338fe3b70c2723b6530865bf2", "PuttTime", "HE 85", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, { "db74136c20557eca6ed3411bff39f7a1", "puttcircus", "", "", -1, Common::EN_GRB, Common::kPlatformWindows }, @@ -572,7 +575,7 @@ static const MD5Table md5table[] = { { "dcf0119a90451a7d6e0f1920931ba130", "freddi4", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows }, { "dd30a53035393baa5a5e222e716559af", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAtariST }, { "de4efb910210736813c9a1185384bace", "puttzoo", "HE 72", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows }, - { "debe337f73d660e951ece7c1f1c81add", "zak", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformPC }, + { "debe337f73d660e951ece7c1f1c81add", "zak", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformDOS }, { "defb8cb9ec4b0f91acfb6b61c6129ad9", "PuttTime", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "df03ee021aa9b81d90cab9c26da07614", "indy3", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformAmiga }, { "df047cc4792150f601290357566d36a6", "freddi", "HE 90", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown }, @@ -581,7 +584,7 @@ static const MD5Table md5table[] = { { "e144f5f49d9241d2a9dee2576b3d09cb", "airport", "", "Demo", 51152, Common::EN_ANY, Common::kPlatformWindows }, { "e17db1ddf91b39ca6bbc8ad3ed19e883", "monkey", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns }, { "e246e02db9630533a40d99c9f54a8e01", "monkey2", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, - { "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformPC }, + { "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformDOS }, { "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows }, { "e44ea295a3f8fe4f41983080dab1e9ce", "freddi", "HE 90", "Updated", -1, Common::FR_FRA, Common::kPlatformMacintosh }, { "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga }, @@ -590,35 +593,36 @@ static const MD5Table md5table[] = { { "e62056ba675ad65d8854ab3c5ad4b3c0", "spyfox2", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows }, { "e63a0b9249b5ca4cc4d3ac34305ae360", "freddi", "HE 99", "", -1, Common::NB_NOR, Common::kPlatformWindows }, { "e689bdf67f98b1d760ce4487ec0e8d06", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformAmiga }, - { "e6cd81b25ab1453a8a6d3482118c391e", "pass", "", "", 7857, Common::EN_ANY, Common::kPlatformPC }, + { "e6cd81b25ab1453a8a6d3482118c391e", "pass", "", "", 7857, Common::EN_ANY, Common::kPlatformDOS }, { "e72bb4c2b613db2cf50f89ff6350e70a", "ft", "", "", -1, Common::ES_ESP, Common::kPlatformUnknown }, { "e781230da44a44e2f0770edb2b3b3633", "maniac", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformAmiga }, - { "e8d0697906e53fee8b7e9f5652696da8", "atlantis", "", "CD", 11915, Common::JA_JPN, Common::kPlatformPC }, + { "e8d0697906e53fee8b7e9f5652696da8", "atlantis", "", "CD", 11915, Common::JA_JPN, Common::kPlatformDOS }, + { "e9271b3d0694c7101f10d675ab7c0133", "freddi4", "HE 99", "", -1, Common::IT_ITA, Common::kPlatformWindows }, { "e94c7cc3686fce406d3c91b5eae5a72d", "zak", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformAmiga }, { "e95cf980719c0be078fb68a67af97b4a", "funpack", "", "", -1, Common::JA_JPN, Common::kPlatform3DO }, - { "e98b982ceaf9d253d730bde8903233d6", "monkey", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformPC }, + { "e98b982ceaf9d253d730bde8903233d6", "monkey", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformDOS }, { "eae95b2b3546d8ba86ae1d397c383253", "dog", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "eb700bb73ca1cc44a1ad5e4b1a4bdeaf", "indy3", "EGA", "EGA", 5361, Common::DE_DEU, Common::kPlatformPC }, + { "eb700bb73ca1cc44a1ad5e4b1a4bdeaf", "indy3", "EGA", "EGA", 5361, Common::DE_DEU, Common::kPlatformDOS }, { "ebd0b2c8a387f18887282afe6cad894a", "spyozon", "", "Demo", 15317, Common::EN_ANY, Common::kPlatformUnknown }, { "ebd324dcf06a4c49e1ba5c231eee1060", "freddi4", "HE 99", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown }, { "ecc4340c2b801f5af8da4e00c0e432d9", "puttcircus", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "ed2b074bc3166087a747acb2a3c6abb0", "freddi3", "HE 98.5", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "ed361270102e355afe5236954216aba2", "lost", "", "", -1, Common::EN_USA, Common::kPlatformUnknown }, { "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh }, - { "edfdb24a499d92c59f824c52987c0eec", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC }, + { "edfdb24a499d92c59f824c52987c0eec", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "ee41f6afbc5b26fa475754b56fe92048", "puttputt", "HE 61", "", 8032, Common::JA_JPN, Common::kPlatform3DO }, { "ee785fe2569bc9965526e774f7ab86f1", "spyfox", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh }, { "eea4d9ac2fb6f145945a308e8866915b", "maniac", "C64", "", -1, Common::EN_ANY, Common::kPlatformC64 }, - { "ef347474f3c7be3b29584eaa133cca05", "samnmax", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC }, + { "ef347474f3c7be3b29584eaa133cca05", "samnmax", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformDOS }, { "ef71a322b6530ac45b1a070f7c0795f7", "moonbase", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows }, - { "ef74d9071d4e564b037cb44bd6774de7", "fbear", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformPC }, + { "ef74d9071d4e564b037cb44bd6774de7", "fbear", "HE 62", "", -1, Common::HE_ISR, Common::kPlatformDOS }, { "efe0a04a703e765ebebe92b6c8aa6b86", "baseball2003", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown }, - { "f049e38c1f8302b5db6170f1872af89a", "monkey", "CD", "CD", 8955, Common::ES_ESP, Common::kPlatformPC }, - { "f06e66fd45b2f8b0f4a2833ff4476050", "fbpack", "", "", -1, Common::HE_ISR, Common::kPlatformPC }, + { "f049e38c1f8302b5db6170f1872af89a", "monkey", "CD", "CD", 8955, Common::ES_ESP, Common::kPlatformDOS }, + { "f06e66fd45b2f8b0f4a2833ff4476050", "fbpack", "", "", -1, Common::HE_ISR, Common::kPlatformDOS }, { "f08145577e4f13584cc90b3d6e9caa55", "pajama3", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "f1b0e0d587b85052de5534a3847e68fe", "water", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown }, { "f237bf8a5ef9af78b2a6a4f3901da341", "pajama", "", "Demo", 18354, Common::EN_ANY, Common::kPlatformUnknown }, - { "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC }, + { "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformDOS }, { "f2ec78e50bdc63b70044e9758be10914", "spyfox", "HE 98.5", "Demo", -1, Common::NL_NLD, Common::kPlatformMacintosh }, { "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", "", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows }, { "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "HE 60", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh }, @@ -628,7 +632,7 @@ static const MD5Table md5table[] = { { "f7711f9264d4d43c2a1518ec7c10a607", "pajama3", "", "", 79382, Common::EN_USA, Common::kPlatformUnknown }, { "f79e60c17cca601e411f1f75e8ee9b5a", "spyfox2", "", "", 51286, Common::UNK_LANG, Common::kPlatformUnknown }, { "f8be685007a8b425ba2a455da732f59f", "pajama2", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh }, - { "fa127d7c4bb47d05bb1c33ddcaa9f767", "loom", "EGA", "EGA", 5748, Common::DE_DEU, Common::kPlatformPC }, + { "fa127d7c4bb47d05bb1c33ddcaa9f767", "loom", "EGA", "EGA", 5748, Common::DE_DEU, Common::kPlatformDOS }, { "fa30c4a7a806629626269b6dcab59a15", "BluesBirthday", "HE CUP", "Preview", 7819264, Common::UNK_LANG, Common::kPlatformUnknown }, { "fa3cb1541f9d7cf99ccbae6249bc150c", "maniac", "NES", "", -1, Common::IT_ITA, Common::kPlatformNES }, { "fa84cb1018103a4ee4e5fa8041c1d0d1", "freddi4", "", "Demo", 13609, Common::DE_DEU, Common::kPlatformWindows }, @@ -636,8 +640,8 @@ static const MD5Table md5table[] = { { "fbb697d89d2beca87360a145f467bdae", "PuttTime", "HE 90", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown }, { "fbbbb38a81fc9d6a61d509278390a290", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh }, { "fbdd947d21e8f5bac6d6f7a316af1c5a", "spyfox", "", "Demo", 15693, Common::EN_ANY, Common::kPlatformUnknown }, - { "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC }, - { "fc6b6148e80d67939d9a18697c0f626a", "monkey", "EGA", "EGA", 8367, Common::DE_DEU, Common::kPlatformPC }, + { "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformDOS }, + { "fc6b6148e80d67939d9a18697c0f626a", "monkey", "EGA", "EGA", 8367, Common::DE_DEU, Common::kPlatformDOS }, { "fc8d197a22146e74766e9cb0cfcaf1da", "freddi2", "HE 80", "Demo", 27298, Common::EN_ANY, Common::kPlatformUnknown }, { "fcb78ebecab2757264c590890c319cc5", "PuttTime", "HE 85", "", -1, Common::NL_NLD, Common::kPlatformUnknown }, { "fce4b8010704b103acfeea9413788f32", "freddi2", "HE 80", "", -1, Common::DE_DEU, Common::kPlatformUnknown }, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 2c79fb8de0..2a14673855 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -61,7 +61,9 @@ #include "scumm/player_v2cms.h" #include "scumm/player_v2a.h" #include "scumm/player_v3a.h" +#include "scumm/player_v3m.h" #include "scumm/player_v4a.h" +#include "scumm/player_v5m.h" #include "scumm/resource.h" #include "scumm/he/resource_he.h" #include "scumm/scumm_v0.h" @@ -1745,7 +1747,7 @@ void ScummEngine::setupMusic(int midi) { } if ((_game.id == GID_MONKEY_EGA || (_game.id == GID_LOOM && _game.version == 3)) - && (_game.platform == Common::kPlatformPC) && _sound->_musicType == MDT_MIDI) { + && (_game.platform == Common::kPlatformDOS) && _sound->_musicType == MDT_MIDI) { Common::String fileName; bool missingFile = false; if (_game.id == GID_LOOM) { @@ -1819,6 +1821,12 @@ void ScummEngine::setupMusic(int midi) { #endif } else if (_game.platform == Common::kPlatformAmiga && _game.version <= 4) { _musicEngine = new Player_V4A(this, _mixer); + } else if (_game.platform == Common::kPlatformMacintosh && _game.id == GID_LOOM) { + _musicEngine = new Player_V3M(this, _mixer); + ((Player_V3M *)_musicEngine)->init(); + } else if (_game.platform == Common::kPlatformMacintosh && _game.id == GID_MONKEY) { + _musicEngine = new Player_V5M(this, _mixer); + ((Player_V5M *)_musicEngine)->init(); } else if (_game.id == GID_MANIAC && _game.version == 1) { _musicEngine = new Player_V1(this, _mixer, MidiDriver::getMusicType(dev) != MT_PCSPK); } else if (_game.version <= 2) { @@ -1858,6 +1866,8 @@ void ScummEngine::setupMusic(int midi) { if (_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS || multi_midi) { adlibMidiDriver = MidiDriver::createMidi(MidiDriver::detectDevice(_sound->_musicType == MDT_TOWNS ? MDT_TOWNS : MDT_ADLIB)); adlibMidiDriver->property(MidiDriver::PROP_OLD_ADLIB, (_game.features & GF_SMALL_HEADER) ? 1 : 0); + // Try to use OPL3 mode for Sam&Max when possible. + adlibMidiDriver->property(MidiDriver::PROP_SCUMM_OPL3, (_game.id == GID_SAMNMAX) ? 1 : 0); } else if (_sound->_musicType == MDT_PCSPK) { adlibMidiDriver = new PcSpkDriver(_mixer); } @@ -2114,7 +2124,7 @@ load_game: // HACK as in game save stuff isn't supported currently if (_game.id == GID_LOOM) { - int args[16]; + int args[NUM_SCRIPT_LOCAL]; uint var; memset(args, 0, sizeof(args)); args[0] = 2; @@ -2502,7 +2512,7 @@ void ScummEngine::restart() { } void ScummEngine::runBootscript() { - int args[16]; + int args[NUM_SCRIPT_LOCAL]; memset(args, 0, sizeof(args)); args[0] = _bootParam; if (_game.id == GID_MANIAC && (_game.features & GF_DEMO)) diff --git a/engines/scumm/smush/smush_player.cpp b/engines/scumm/smush/smush_player.cpp index a53b808ba1..ce098f07aa 100644 --- a/engines/scumm/smush/smush_player.cpp +++ b/engines/scumm/smush/smush_player.cpp @@ -920,7 +920,7 @@ void SmushPlayer::handleAnimHeader(int32 subSize, Common::SeekableReadStream &b) void SmushPlayer::setupAnim(const char *file) { if (_insanity) { - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) readString("mineroad.trs"); } else readString(file); @@ -933,7 +933,7 @@ SmushFont *SmushPlayer::getFont(int font) { return _sf[font]; if (_vm->_game.id == GID_FT) { - if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformPC))) { + if (!((_vm->_game.features & GF_DEMO) && (_vm->_game.platform == Common::kPlatformDOS))) { const char *ft_fonts[] = { "scummfnt.nut", "techfnt.nut", diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp index a1cecfa0b3..3f6290f8fc 100644 --- a/engines/scumm/sound.cpp +++ b/engines/scumm/sound.cpp @@ -346,29 +346,6 @@ void Sound::playSound(int soundID) { warning("Scumm::Sound::playSound: encountered audio resoure with chunk type 'SOUN' and sound type %d", type); } } - else if ((_vm->_game.id == GID_LOOM) && (_vm->_game.platform == Common::kPlatformMacintosh)) { - // Mac version of Loom uses yet another sound format - /* - playSound #9 (room 70) - 000000: 55 00 00 45 73 6f 00 64 01 00 00 00 00 00 00 00 |U..Eso.d........| - 000010: 00 05 00 8e 2a 8f 2d 1c 2a 8f 2a 8f 2d 1c 00 28 |....*.-.*.*.-..(| - 000020: 00 31 00 3a 00 43 00 4c 00 01 00 00 00 01 00 64 |.1.:.C.L.......d| - 000030: 5a 00 01 00 00 00 01 00 64 00 00 01 00 00 00 01 |Z.......d.......| - 000040: 00 64 5a 00 01 00 00 00 01 00 64 5a 00 01 00 00 |.dZ.......dZ....| - 000050: 00 01 00 64 00 00 00 00 00 00 00 07 00 00 00 64 |...d...........d| - 000060: 64 00 00 4e 73 6f 00 64 01 00 00 00 00 00 00 00 |d..Nso.d........| - 000070: 00 05 00 89 3d 57 2d 1c 3d 57 3d 57 2d 1c 00 28 |....=W-.=W=W-..(| - playSound #16 (room 69) - 000000: dc 00 00 a5 73 6f 00 64 01 00 00 00 00 00 00 00 |....so.d........| - 000010: 00 05 00 00 2a 8f 03 e8 03 e8 03 e8 03 e8 00 28 |....*..........(| - 000020: 00 79 00 7f 00 85 00 d6 00 01 00 00 00 19 01 18 |.y..............| - 000030: 2f 00 18 00 01 18 32 00 18 00 01 18 36 00 18 00 |/.....2.....6...| - 000040: 01 18 3b 00 18 00 01 18 3e 00 18 00 01 18 42 00 |..;.....>.....B.| - 000050: 18 00 01 18 47 00 18 00 01 18 4a 00 18 00 01 18 |....G.....J.....| - 000060: 4e 00 10 00 01 18 53 00 10 00 01 18 56 00 10 00 |N.....S.....V...| - 000070: 01 18 5a 00 10 00 02 28 5f 00 01 00 00 00 00 00 |..Z....(_.......| - */ - } else if ((_vm->_game.platform == Common::kPlatformMacintosh) && (_vm->_game.id == GID_INDY3) && READ_BE_UINT16(ptr + 8) == 0x1C) { // Sound format as used in Indy3 EGA Mac. // It seems to be closely related to the Amiga format, see player_v3a.cpp @@ -414,8 +391,7 @@ void Sound::playSound(int soundID) { } else { - if (_vm->_game.id == GID_MONKEY_VGA || _vm->_game.id == GID_MONKEY_EGA - || (_vm->_game.id == GID_MONKEY && _vm->_game.platform == Common::kPlatformMacintosh)) { + if (_vm->_game.id == GID_MONKEY_VGA || _vm->_game.id == GID_MONKEY_EGA) { // Works around the fact that in some places in MonkeyEGA/VGA, // the music is never explicitly stopped. // Rather it seems that starting a new music is supposed to @@ -1086,9 +1062,6 @@ void Sound::saveLoadWithSerializer(Serializer *ser) { #pragma mark --- Sound resource handling --- #pragma mark - -static void convertMac0Resource(ResourceManager *res, ResId idx, byte *src_ptr, int size); - - /* * TODO: The way we handle sound/music resources really is one huge hack. * We probably should reconsider how we do this, and maybe come up with a @@ -1208,11 +1181,9 @@ int ScummEngine::readSoundResource(ResId idx) { case MKTAG('M','a','c','0'): _fileHandle->seek(-12, SEEK_CUR); total_size = _fileHandle->readUint32BE() - 8; - ptr = (byte *)calloc(total_size, 1); + ptr = _res->createResource(rtSound, idx, total_size); _fileHandle->read(ptr, total_size); //dumpResource("sound-", idx, ptr); - convertMac0Resource(_res, idx, ptr, total_size); - free(ptr); return 1; case MKTAG('M','a','c','1'): @@ -1445,219 +1416,6 @@ static byte *writeVLQ(byte *ptr, int value) { return ptr; } -static byte Mac0ToGMInstrument(uint32 type, int &transpose) { - transpose = 0; - switch (type) { - case MKTAG('M','A','R','I'): return 12; - case MKTAG('P','L','U','C'): return 45; - case MKTAG('H','A','R','M'): return 22; - case MKTAG('P','I','P','E'): return 19; - case MKTAG('T','R','O','M'): transpose = -12; return 57; - case MKTAG('S','T','R','I'): return 48; - case MKTAG('H','O','R','N'): return 60; - case MKTAG('V','I','B','E'): return 11; - case MKTAG('S','H','A','K'): return 77; - case MKTAG('P','A','N','P'): return 75; - case MKTAG('W','H','I','S'): return 76; - case MKTAG('O','R','G','A'): return 17; - case MKTAG('B','O','N','G'): return 115; - case MKTAG('B','A','S','S'): transpose = -24; return 35; - default: - error("Unknown Mac0 instrument %s found", tag2str(type)); - } -} - -static void convertMac0Resource(ResourceManager *res, ResId idx, byte *src_ptr, int size) { - /* - From Markus Magnuson (superqult) we got this information: - Mac0 - --- - 4 bytes - 'SOUN' - BE 4 bytes - block length - - 4 bytes - 'Mac0' - BE 4 bytes - (blockLength - 27) - 28 bytes - ??? - - do this three times (once for each channel): - 4 bytes - 'Chan' - BE 4 bytes - channel length - 4 bytes - instrument name (e.g. 'MARI') - - do this for ((chanLength-24)/4) times: - 2 bytes - note duration - 1 byte - note value - 1 byte - note velocity - - 4 bytes - ??? - 4 bytes - 'Loop'/'Done' - 4 bytes - ??? - - 1 byte - 0x09 - --- - - Instruments (General Midi): - "MARI" - Marimba (12) - "PLUC" - Pizzicato Strings (45) - "HARM" - Harmonica (22) - "PIPE" - Church Organ? (19) or Flute? (73) or Bag Pipe (109) - "TROM" - Trombone (57) - "STRI" - String Ensemble (48 or 49) - "HORN" - French Horn? (60) or English Horn? (69) - "VIBE" - Vibraphone (11) - "SHAK" - Shakuhachi? (77) - "PANP" - Pan Flute (75) - "WHIS" - Whistle (78) / Bottle (76) - "ORGA" - Drawbar Organ (16; but could also be 17-20) - "BONG" - Woodblock? (115) - "BASS" - Bass (32-39) - - - Now the task could be to convert this into MIDI, to be fed into iMuse. - Or we do something similiar to what is done in Player_V3, assuming - we can identify SFX in the MI datafiles for each of the instruments - listed above. - */ - -#if 0 - byte *ptr = _res->createResource(rtSound, idx, size); - memcpy(ptr, src_ptr, size); -#else - const int ppqn = 480; - byte *ptr, *start_ptr; - - int total_size = 0; - total_size += kMIDIHeaderSize; // Header - total_size += 7; // Tempo META - total_size += 3 * 3; // Three program change mesages - total_size += 22; // Possible jump SysEx - total_size += 5; // EOT META - - int i, len; - byte track_instr[3]; - byte *track_data[3]; - int track_len[3]; - int track_transpose[3]; - bool looped = false; - - src_ptr += 8; - // TODO: Decipher the unknown bytes in the header. For now, skip 'em - src_ptr += 28; - - // Parse the three channels - for (i = 0; i < 3; i++) { - assert(READ_BE_UINT32(src_ptr) == MKTAG('C','h','a','n')); - len = READ_BE_UINT32(src_ptr + 4); - track_len[i] = len - 24; - track_instr[i] = Mac0ToGMInstrument(READ_BE_UINT32(src_ptr + 8), track_transpose[i]); - track_data[i] = src_ptr + 12; - src_ptr += len; - looped = (READ_BE_UINT32(src_ptr - 8) == MKTAG('L','o','o','p')); - - // For each note event, we need up to 6 bytes for the - // Note On (3 VLQ, 3 event), and 6 bytes for the Note - // Off (3 VLQ, 3 event). So 12 bytes total. - total_size += 12 * track_len[i]; - } - assert(*src_ptr == 0x09); - - // Create sound resource - start_ptr = res->createResource(rtSound, idx, total_size); - - // Insert MIDI header - ptr = writeMIDIHeader(start_ptr, "GMD ", ppqn, total_size); - - // Write a tempo change Meta event - // 473 / 4 Hz, convert to micro seconds. - uint32 dw = 1000000 * 437 / 4 / ppqn; // 1000000 * ppqn * 4 / 473; - memcpy(ptr, "\x00\xFF\x51\x03", 4); ptr += 4; - *ptr++ = (byte)((dw >> 16) & 0xFF); - *ptr++ = (byte)((dw >> 8) & 0xFF); - *ptr++ = (byte)(dw & 0xFF); - - // Insert program change messages - *ptr++ = 0; // VLQ - *ptr++ = 0xC0; - *ptr++ = track_instr[0]; - *ptr++ = 0; // VLQ - *ptr++ = 0xC1; - *ptr++ = track_instr[1]; - *ptr++ = 0; // VLQ - *ptr++ = 0xC2; - *ptr++ = track_instr[2]; - - // And now, the actual composition. Please turn all cell phones - // and pagers off during the performance. Thank you. - uint16 nextTime[3] = { 1, 1, 1 }; - int stage[3] = { 0, 0, 0 }; - - while (track_len[0] | track_len[1] | track_len[2]) { - int best = -1; - uint16 bestTime = 0xFFFF; - for (i = 0; i < 3; ++i) { - if (track_len[i] && nextTime[i] < bestTime) { - bestTime = nextTime[i]; - best = i; - } - } - assert (best != -1); - - if (!stage[best]) { - // We are STARTING this event. - if (track_data[best][2] > 1) { - // Note On - ptr = writeVLQ(ptr, nextTime[best]); - *ptr++ = 0x90 | best; - *ptr++ = track_data[best][2] + track_transpose[best]; - *ptr++ = track_data[best][3] * 127 / 100; // Scale velocity - for (i = 0; i < 3; ++i) - nextTime[i] -= bestTime; - } - nextTime[best] += READ_BE_UINT16 (track_data[best]); - stage[best] = 1; - } else { - // We are ENDING this event. - if (track_data[best][2] > 1) { - // There was a Note On, so do a Note Off - ptr = writeVLQ(ptr, nextTime[best]); - *ptr++ = 0x80 | best; - *ptr++ = track_data[best][2] + track_transpose[best]; - *ptr++ = track_data[best][3] * 127 / 100; // Scale velocity - for (i = 0; i < 3; ++i) - nextTime[i] -= bestTime; - } - track_data[best] += 4; - track_len[best] -= 4; - stage[best] = 0; - } - } - - // Is this a looped song? If so, effect a loop by - // using the S&M maybe_jump SysEx command. - // FIXME: Jamieson630: The jump seems to be happening - // too quickly! There should maybe be a pause after - // the last Note Off? But I couldn't find one in the - // MI1 Lookout music, where I was hearing problems. - if (looped) { - memcpy(ptr, "\x00\xf0\x13\x7d\x30\00", 6); ptr += 6; // maybe_jump - memcpy(ptr, "\x00\x00", 2); ptr += 2; // cmd -> 0 means always jump - memcpy(ptr, "\x00\x00\x00\x00", 4); ptr += 4; // track -> 0 (only track) - memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4; // beat -> 1 (first beat) - memcpy(ptr, "\x00\x00\x00\x01", 4); ptr += 4; // tick -> 1 - memcpy(ptr, "\x00\xf7", 2); ptr += 2; // SysEx end marker - } - - // Insert end of song META - memcpy(ptr, "\x00\xff\x2f\x00\x00", 5); ptr += 5; - - assert(ptr <= start_ptr + total_size); - - // Rewrite MIDI header, this time with true size - total_size = ptr - start_ptr; - ptr = writeMIDIHeader(start_ptr, "GMD ", ppqn, total_size); -#endif -} - static void convertADResource(ResourceManager *res, const GameSettings& game, ResId idx, byte *src_ptr, int size) { // We will ignore the PPQN in the original resource, because // it's invalid anyway. We use a constant PPQN of 480. @@ -2057,7 +1815,7 @@ int ScummEngine::readSoundResourceSmallHeader(ResId idx) { debug(4, "readSoundResourceSmallHeader(%d)", idx); - if ((_game.id == GID_LOOM) && (_game.version == 3) && (_game.platform == Common::kPlatformPC) && VAR(VAR_SOUNDCARD) == 4) { + if ((_game.id == GID_LOOM) && (_game.version == 3) && (_game.platform == Common::kPlatformDOS) && VAR(VAR_SOUNDCARD) == 4) { // Roland resources in Loom are tagless // So we add an RO tag to allow imuse to detect format byte *ptr, *src_ptr; diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp index 6d132c601f..77c7daa0df 100644 --- a/engines/scumm/vars.cpp +++ b/engines/scumm/vars.cpp @@ -741,7 +741,7 @@ void ScummEngine::resetScummVars() { break; default: if ((_game.id == GID_MONKEY_EGA || _game.id == GID_MONKEY_VGA || (_game.id == GID_LOOM && _game.version == 3)) - && (_game.platform == Common::kPlatformPC)) { + && (_game.platform == Common::kPlatformDOS)) { VAR(VAR_SOUNDCARD) = 4; } else { VAR(VAR_SOUNDCARD) = 3; @@ -770,7 +770,7 @@ void ScummEngine::resetScummVars() { // Set screen size for the Macintosh version of Indy3/Loom VAR(39) = 320; } - if (_game.platform == Common::kPlatformPC && _game.id == GID_LOOM && _game.version == 3) { + if (_game.platform == Common::kPlatformDOS && _game.id == GID_LOOM && _game.version == 3) { // Set number of sound resources VAR(39) = 80; } |