aboutsummaryrefslogtreecommitdiff
path: root/simon
diff options
context:
space:
mode:
authorTravis Howell2005-11-12 06:01:24 +0000
committerTravis Howell2005-11-12 06:01:24 +0000
commitb4908f449e0327516f5e1289f2651ede5da45274 (patch)
treebf5e973d5e41a47063954b17ec5a7b8be350d095 /simon
parent5496f912695fbfa7faf3b84a661f746c34e2ba24 (diff)
downloadscummvm-rg350-b4908f449e0327516f5e1289f2651ede5da45274.tar.gz
scummvm-rg350-b4908f449e0327516f5e1289f2651ede5da45274.tar.bz2
scummvm-rg350-b4908f449e0327516f5e1289f2651ede5da45274.zip
Old targets will be auto updated.
Many non-English versions will be broken until information is updated. svn-id: r19563
Diffstat (limited to 'simon')
-rw-r--r--simon/cursor.cpp2
-rw-r--r--simon/debug.cpp16
-rw-r--r--simon/debugger.cpp8
-rw-r--r--simon/game.cpp715
-rw-r--r--simon/icons.cpp10
-rw-r--r--simon/intern.h64
-rw-r--r--simon/items.cpp50
-rw-r--r--simon/module.mk1
-rw-r--r--simon/res.cpp16
-rw-r--r--simon/saveload.cpp14
-rw-r--r--simon/simon-md5.h40
-rw-r--r--simon/simon.cpp604
-rw-r--r--simon/simon.h45
-rw-r--r--simon/sound.cpp21
-rw-r--r--simon/sound.h6
-rw-r--r--simon/verb.cpp14
-rw-r--r--simon/vga.cpp86
17 files changed, 1182 insertions, 530 deletions
diff --git a/simon/cursor.cpp b/simon/cursor.cpp
index 72e273d6a2..a6406ca3f0 100644
--- a/simon/cursor.cpp
+++ b/simon/cursor.cpp
@@ -223,7 +223,7 @@ static const byte _simon2_cursors[10][256] = {
};
void SimonEngine::draw_mouse_pointer() {
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
_system->setMouseCursor(_simon2_cursors[_mouseCursor], 16, 16, 7, 7);
else
_system->setMouseCursor(_simon1_cursor, 16, 16, 0, 0);
diff --git a/simon/debug.cpp b/simon/debug.cpp
index 8ce2f3101a..b1e26cedb0 100644
--- a/simon/debug.cpp
+++ b/simon/debug.cpp
@@ -37,13 +37,13 @@ const byte *SimonEngine::dumpOpcode(const byte *p) {
opcode = *p++;
if (opcode == 255)
return NULL;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
st = s = feeblefiles_opcode_name_table[opcode];
- } else if (_game & GF_SIMON2 && _game & GF_TALKIE) {
+ } else if (getGameType() == GType_SIMON2 && getFeatures() & GF_TALKIE) {
st = s = simon2talkie_opcode_name_table[opcode];
- } else if (_game & GF_TALKIE) {
+ } else if (getFeatures() & GF_TALKIE) {
st = s = simon1talkie_opcode_name_table[opcode];
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
st = s = simon2dos_opcode_name_table[opcode];
} else {
st = s = simon1dos_opcode_name_table[opcode];
@@ -176,7 +176,7 @@ void SimonEngine::dump_video_script(const byte *src, bool one_opcode_only) {
const char *str, *strn;
do {
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
opcode = READ_BE_UINT16(src);
src += 2;
} else {
@@ -188,9 +188,9 @@ void SimonEngine::dump_video_script(const byte *src, bool one_opcode_only) {
return;
}
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
strn = str = feeblefiles_video_opcode_name_table[opcode];
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
strn = str = simon2_video_opcode_name_table[opcode];
} else {
strn = str = simon1_video_opcode_name_table[opcode];
@@ -200,7 +200,7 @@ void SimonEngine::dump_video_script(const byte *src, bool one_opcode_only) {
strn++;
fprintf(_dumpFile, "%.2d: %s ", opcode, strn + 1);
- int end = (_game == GAME_FEEBLEFILES) ? 9999 : 999;
+ int end = (getGameType() == GType_FF) ? 9999 : 999;
for (; *str != '|'; str++) {
switch (*str) {
case 'x':
diff --git a/simon/debugger.cpp b/simon/debugger.cpp
index 76ec22b404..a6ce24e3d5 100644
--- a/simon/debugger.cpp
+++ b/simon/debugger.cpp
@@ -106,10 +106,10 @@ bool Debugger::Cmd_DebugLevel(int argc, const char **argv) {
bool Debugger::Cmd_PlayMusic(int argc, const char **argv) {
if (argc > 1) {
uint music = atoi(argv[1]);
- uint range = (_vm->_game & GF_SIMON2) ? 93 : 34;
+ uint range = (_vm->getGameType() == GType_SIMON2) ? 93 : 34;
if (music <= range) {
_vm->loadMusic (music);
- if (_vm->_game & GF_SIMON2)
+ if (_vm->getGameType() == GType_SIMON2)
_vm->midi.startTrack (0);
} else
DebugPrintf("Music out of range (0 - %d)\n", range);
@@ -122,7 +122,7 @@ bool Debugger::Cmd_PlayMusic(int argc, const char **argv) {
bool Debugger::Cmd_PlaySound(int argc, const char **argv) {
if (argc > 1) {
uint sound = atoi(argv[1]);
- uint range = (_vm->_game & GF_SIMON2) ? 222 : 127;
+ uint range = (_vm->getGameType() == GType_SIMON2) ? 222 : 127;
if (sound <= range)
_vm->_sound->playEffects(sound);
else
@@ -136,7 +136,7 @@ bool Debugger::Cmd_PlaySound(int argc, const char **argv) {
bool Debugger::Cmd_PlayVoice(int argc, const char **argv) {
if (argc > 1) {
uint voice = atoi(argv[1]);
- uint range = (_vm->_game & GF_SIMON2) ? 3632 : 1996;
+ uint range = (_vm->getGameType() == GType_SIMON2) ? 3632 : 1996;
if (voice <= range)
_vm->_sound->playVoice(voice);
else
diff --git a/simon/game.cpp b/simon/game.cpp
new file mode 100644
index 0000000000..ba3e4e8589
--- /dev/null
+++ b/simon/game.cpp
@@ -0,0 +1,715 @@
+/* ScummVM - Scumm Interpreter
+ * Copyright (C) 2001-2005 The ScummVM project
+ *
+ * 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.
+ *
+ * $Header$
+ *
+ */
+
+#include "common/stdafx.h"
+
+#include "backends/fs/fs.h"
+
+#include "base/gameDetector.h"
+#include "base/plugins.h"
+
+#include "common/config-manager.h"
+#include "common/file.h"
+#include "common/md5.h"
+
+#include "simon/simon.h"
+#include "simon/intern.h"
+
+using Common::File;
+
+namespace Simon {
+
+static int detectGame(const FSList &fslist, bool mode = false, int start = -1);
+
+struct GameMD5 {
+ GameIds id;
+ const char *md5;
+ const char *filename;
+ bool caseSensitive;
+};
+
+#define FILE_MD5_BYTES 5000
+
+static GameMD5 gameMD5[] = {
+ { GID_SIMON1ACORN, "64958b3a38afdcb85da1eeed85169806", "data", false },
+ { GID_SIMON1ACORN, "28261b99cd9da1242189b4f6f2841bd6", "gamebase", false },
+ { GID_SIMON1ACORN, "22107c24dfb31b66ac503c28a6e20b19", "icondata", false},
+ { GID_SIMON1ACORN, "f3b27a3fbb45dcd323a48159496e45e8", "stripped", false},
+ { GID_SIMON1ACORN, "d198a80de2c59e4a0cd24b98814849e8", "tbllist", false},
+
+ { GID_SIMON1CD32, "bab7f19237cf7d7619b6c73631da1854", "gameamiga", true },
+ { GID_SIMON1CD32, "565ef7a98dcc21ef526a2bb10b6f42ed", "icon.pkd", true },
+ { GID_SIMON1CD32, "59be788020441e21861e284236fd08c1", "stripped.txt", true},
+ { GID_SIMON1CD32, "f9d5bf2ce09f82289c791c3ca26e1e4b", "tbllist", true},
+
+ { GID_SIMON1DOS, "9f93d27432ce44a787eef10adb640870", "gamepc", false },
+ { GID_SIMON1DOS, "22107c24dfb31b66ac503c28a6e20b19", "icon.dat", false},
+ { GID_SIMON1DOS, "2af9affc5981eec44b90d4c556145cb8", "stripped.txt", false},
+ { GID_SIMON1DOS, "d198a80de2c59e4a0cd24b98814849e8", "tbllist", false},
+
+ { GID_SIMON1DEMO, "2be4a21bc76e2fdc071867c130651439", "gdemo", false },
+ { GID_SIMON1DEMO, "55af3b4d93972bc58bfee38a86b76c3f", "icon.dat", false},
+ { GID_SIMON1DEMO, "33a2e329b97b2a349858d6a093159eb7", "stripped.txt", false},
+ { GID_SIMON1DEMO, "1247e024e1f13ca54c1e354120c7519c", "tbllist", false},
+
+ { GID_SIMON1TALKIE, "28261b99cd9da1242189b4f6f2841bd6", "gamepc", false },
+ { GID_SIMON1TALKIE, "22107c24dfb31b66ac503c28a6e20b19", "icon.dat", false},
+ { GID_SIMON1TALKIE, "64958b3a38afdcb85da1eeed85169806", "simon.gme", false },
+ { GID_SIMON1TALKIE, "f3b27a3fbb45dcd323a48159496e45e8", "stripped.txt", false},
+ { GID_SIMON1TALKIE, "d198a80de2c59e4a0cd24b98814849e8", "tbllist", false},
+
+ { GID_SIMON1TALKIE_FR, "00000000000000000000000000000000", "gamepc", false },
+ { GID_SIMON1TALKIE_FR, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON1TALKIE_FR, "00000000000000000000000000000000", "simon.gme", false },
+ { GID_SIMON1TALKIE_FR, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON1TALKIE_FR, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON1TALKIE_DE, "00000000000000000000000000000000", "gamepc", false },
+ { GID_SIMON1TALKIE_DE, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON1TALKIE_DE, "00000000000000000000000000000000", "simon.gme", false },
+ { GID_SIMON1TALKIE_DE, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON1TALKIE_DE, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON1TALKIE_HB, "bc66e9c0b296e1b155a246917133f71a", "gamepc", false },
+ { GID_SIMON1TALKIE_HB, "22107c24dfb31b66ac503c28a6e20b19", "icon.dat", false},
+ { GID_SIMON1TALKIE_HB, "a34b2c8642f2e3676d7088b5c8b3e884", "simon.gme", false },
+ { GID_SIMON1TALKIE_HB, "9d31bef42db1a8abe4e9f368014df1d5", "stripped.txt", false},
+ { GID_SIMON1TALKIE_HB, "d198a80de2c59e4a0cd24b98814849e8", "tbllist", false},
+
+ { GID_SIMON1TALKIE_IT, "00000000000000000000000000000000", "gamepc", false },
+ { GID_SIMON1TALKIE_IT, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON1TALKIE_IT, "00000000000000000000000000000000", "simon.gme", false },
+ { GID_SIMON1TALKIE_IT, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON1TALKIE_IT, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON1TALKIE_ES, "439f801ba52c02c9d1844600d1ce0f5e", "gamepc", false },
+ { GID_SIMON1TALKIE_ES, "22107c24dfb31b66ac503c28a6e20b19", "icon.dat", false},
+ { GID_SIMON1TALKIE_ES, "eff2774a73890b9eac533db90cd1afa1", "simon.gme", false },
+ { GID_SIMON1TALKIE_ES, "9d31bef42db1a8abe4e9f368014df1d5", "stripped.txt", false},
+ { GID_SIMON1TALKIE_ES, "d198a80de2c59e4a0cd24b98814849e8", "tbllist", false},
+
+ { GID_SIMON1WIN, "c7c12fea7f6d0bfd22af5cdbc8166862", "gamepc", false },
+ { GID_SIMON1WIN, "22107c24dfb31b66ac503c28a6e20b19", "icon.dat", false},
+ { GID_SIMON1WIN, "b1b18d0731b64c0738c5cc4a2ee792fc", "simon.gme", false },
+ { GID_SIMON1WIN, "a27e87a9ba21212d769804b3df47bfb2", "stripped.txt", false},
+ { GID_SIMON1WIN, "d198a80de2c59e4a0cd24b98814849e8", "tbllist", false},
+
+ { GID_SIMON1WIN_DE, "00000000000000000000000000000000", "gamepc", false },
+ { GID_SIMON1WIN_DE, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON1WIN_DE, "00000000000000000000000000000000", "simon.gme", false },
+ { GID_SIMON1WIN_DE, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON1WIN_DE, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON2DOS, "00000000000000000000000000000000", "game32", false },
+ { GID_SIMON2DOS, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON2DOS, "00000000000000000000000000000000", "simon2.gme", false},
+ { GID_SIMON2DOS, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON2DOS, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON2DEMO, "3794c15887539b8578bacab694ccf08a", "gsptr30", false },
+ { GID_SIMON2DEMO, "72096a62d36e6034ea9fecc13b2dbdab", "icon.dat", false},
+ { GID_SIMON2DEMO, "f8c9e6df1e55923a749e115ba74210c4", "simon2.gme", false},
+ { GID_SIMON2DEMO, "e229f84d46fa83f99b4a7115679f3fb6", "stripped.txt", false},
+ { GID_SIMON2DEMO, "a0d5a494b5d3d209d1a1d76cc8d76601", "tbllist", false},
+
+ { GID_SIMON2TALKIE, "8c301fb9c4fcf119d2730ccd2a565eb3", "gsptr30", false },
+ { GID_SIMON2TALKIE, "72096a62d36e6034ea9fecc13b2dbdab", "icon.dat", false},
+ { GID_SIMON2TALKIE, "9c535d403966750ae98bdaf698375a38", "simon2.gme", false },
+ { GID_SIMON2TALKIE, "e229f84d46fa83f99b4a7115679f3fb6", "stripped.txt", false},
+ { GID_SIMON2TALKIE, "2082f8d02075e590300478853a91ffd9", "tbllist", false},
+
+ { GID_SIMON2TALKIE_FR, "43b3a04d2f0a0cbd1b024c814856561a", "gsptr30", false },
+ { GID_SIMON2TALKIE_FR, "72096a62d36e6034ea9fecc13b2dbdab", "icon.dat", false},
+ { GID_SIMON2TALKIE_FR, "8af0e02c0c3344db64dffc12196eb59d", "simon2.gme", false },
+ { GID_SIMON2TALKIE_FR, "5ea27977b4d7dcfd50eb5074e162ebbf", "stripped.txt", false},
+ { GID_SIMON2TALKIE_FR, "2082f8d02075e590300478853a91ffd9", "tbllist", false},
+
+ { GID_SIMON2TALKIE_DE, "00000000000000000000000000000000", "gsptr30", false },
+ { GID_SIMON2TALKIE_DE, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON2TALKIE_DE, "00000000000000000000000000000000", "simon2.gme", false },
+ { GID_SIMON2TALKIE_DE, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON2TALKIE_DE, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON2TALKIE_HB, "952a2b1be23c3c609ba8d988a9a1627d", "gsptr30", false },
+ { GID_SIMON2TALKIE_HB, "72096a62d36e6034ea9fecc13b2dbdab", "icon.dat", false},
+ { GID_SIMON2TALKIE_HB, "a2b249a82ea182af09789eb95fb6c5be", "simon2.gme", false },
+ { GID_SIMON2TALKIE_HB, "de9dbc24158660e153483fa0cf6c3172", "stripped.txt", false},
+ { GID_SIMON2TALKIE_HB, "2082f8d02075e590300478853a91ffd9", "tbllist", false},
+
+ { GID_SIMON2TALKIE_IT, "00000000000000000000000000000000", "gsptr30", false },
+ { GID_SIMON2TALKIE_IT, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON2TALKIE_IT, "00000000000000000000000000000000", "simon2.gme", false },
+ { GID_SIMON2TALKIE_IT, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON2TALKIE_IT, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON2TALKIE_ES, "00000000000000000000000000000000", "gsptr30", false },
+ { GID_SIMON2TALKIE_ES, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON2TALKIE_ES, "00000000000000000000000000000000", "simon2.gme", false },
+ { GID_SIMON2TALKIE_ES, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON2TALKIE_ES, "00000000000000000000000000000000", "tbllist", false},
+
+ { GID_SIMON2WIN, "608e277904d87dd28725fa08eacc2c0d", "gsptr30", false },
+ { GID_SIMON2WIN, "72096a62d36e6034ea9fecc13b2dbdab", "icon.dat", false},
+ { GID_SIMON2WIN, "e749c4c103d7e7d51b34620ed76c5a04", "simon2.gme", false },
+ { GID_SIMON2WIN, "e229f84d46fa83f99b4a7115679f3fb6", "stripped.txt", false},
+ { GID_SIMON2WIN, "2082f8d02075e590300478853a91ffd9", "tbllist", false},
+
+ { GID_SIMON2WIN_DE, "00000000000000000000000000000000", "gsptr30", false },
+ { GID_SIMON2WIN_DE, "00000000000000000000000000000000", "icon.dat", false},
+ { GID_SIMON2WIN_DE, "00000000000000000000000000000000", "simon2.gme", false },
+ { GID_SIMON2WIN_DE, "00000000000000000000000000000000", "stripped.txt", false},
+ { GID_SIMON2WIN_DE, "00000000000000000000000000000000", "tbllist", false},
+};
+
+// Simon the Sorcerer 1
+static GameFileDescription SIMON1CD32_GameFiles[] = {
+ {"gameamiga", GAME_BASEFILE},
+ {"icon.pkd", GAME_ICONFILE},
+ {"stripped.txt", GAME_STRFILE},
+ {"tbllist", GAME_TBLFILE},
+};
+
+static GameFileDescription SIMON1ACORN_GameFiles[] = {
+ {"data", GAME_GMEFILE},
+ {"gamebase", GAME_BASEFILE},
+ {"icondata", GAME_ICONFILE},
+ {"stripped", GAME_STRFILE},
+ {"tbllist", GAME_TBLFILE},
+};
+
+static GameFileDescription SIMON1DEMO_GameFiles[] = {
+ {"gdemo", GAME_BASEFILE},
+ {"icon.dat", GAME_ICONFILE},
+ {"stripped.txt", GAME_STRFILE},
+ {"tbllist", GAME_TBLFILE},
+};
+
+static GameFileDescription SIMON1DOS_GameFiles[] = {
+ {"gamepc", GAME_BASEFILE},
+ {"icon.dat", GAME_ICONFILE},
+ {"stripped.txt", GAME_STRFILE},
+ {"tbllist", GAME_TBLFILE},
+};
+
+static GameFileDescription SIMON1_GameFiles[] = {
+ {"gamepc", GAME_BASEFILE},
+ {"icon.dat", GAME_ICONFILE},
+ {"simon.gme", GAME_GMEFILE},
+ {"stripped.txt", GAME_STRFILE},
+ {"tbllist", GAME_TBLFILE},
+};
+
+// Simon the Sorcerer 2
+static GameFileDescription SIMON2_GameFiles[] = {
+ {"gsptr30", GAME_BASEFILE},
+ {"icon.dat", GAME_ICONFILE},
+ {"simon2.gme", GAME_GMEFILE},
+ {"stripped.txt", GAME_STRFILE},
+ {"tbllist", GAME_TBLFILE},
+};
+
+static GameDescription gameDescriptions[] = {
+ // Simon the Sorcerer 1 - English Amiga CD32
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1CD32,
+ "Simon the Sorcerer 1 (Amiga CD32)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1CD32_GameFiles,
+ GF_TALKIE | GF_OLD_BUNDLE,
+ Common::EN_USA,
+ Common::kPlatformAmiga,
+ },
+
+ // Simon the Sorcerer 1 - English Acorn CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1ACORN,
+ "Simon the Sorcerer 1 (Acorn CD)",
+ ARRAYSIZE(SIMON1ACORN_GameFiles),
+ SIMON1ACORN_GameFiles,
+ GF_TALKIE,
+ Common::EN_USA,
+ Common::kPlatformAcorn,
+ },
+
+ // Simon the Sorcerer 1 - English DOS Floppy Demo
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1DEMO,
+ "Simon the Sorcerer 1 (DOS Floppy Demo)",
+ ARRAYSIZE(SIMON1DEMO_GameFiles),
+ SIMON1DEMO_GameFiles,
+ GF_OLD_BUNDLE,
+ Common::EN_USA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - English DOS Floppy (Infocom)
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1DOS,
+ "Simon the Sorcerer 1 (DOS Floppy)",
+ ARRAYSIZE(SIMON1DOS_GameFiles),
+ SIMON1DOS_GameFiles,
+ GF_OLD_BUNDLE,
+ Common::EN_USA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - English DOS CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1TALKIE,
+ "Simon the Sorcerer 1 (DOS CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::EN_USA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - French DOS CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1TALKIE_FR,
+ "Simon the Sorcerer 1 (Fr DOS CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - German DOS CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1TALKIE_DE,
+ "Simon the Sorcerer 1 (De DOS CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - Hebrew DOS CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1TALKIE_HB,
+ "Simon the Sorcerer 1 (Hb DOS CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::HB_ISR,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - Italian DOS CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1TALKIE_IT,
+ "Simon the Sorcerer 1 (It DOS CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - Spanish DOS CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1TALKIE_ES,
+ "Simon the Sorcerer 1 (Sp DOS CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::ES_ESP,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 1 - English Windows CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1WIN,
+ "Simon the Sorcerer 1 (Windows CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::EN_USA,
+ Common::kPlatformWindows,
+ },
+
+ // Simon the Sorcerer 1 - German Windows CD
+ {
+ "simon1",
+ GType_SIMON1,
+ GID_SIMON1WIN_DE,
+ "Simon the Sorcerer 1 (De Windows CD)",
+ ARRAYSIZE(SIMON1_GameFiles),
+ SIMON1_GameFiles,
+ GF_TALKIE,
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ },
+
+ // Simon the Sorcerer 2 - English DOS Floppy
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2DOS,
+ "Simon the Sorcerer 2 (DOS Floppy)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ 0,
+ Common::EN_USA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - English DOS CD Demo
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2DEMO,
+ "Simon the Sorcerer 2 (DOS CD Demo)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::EN_USA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - English DOS CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2TALKIE,
+ "Simon the Sorcerer 2 (DOS CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::EN_USA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - French DOS CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2TALKIE_FR,
+ "Simon the Sorcerer 2 (Fr DOS CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::FR_FRA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - German DOS CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2TALKIE_DE,
+ "Simon the Sorcerer 2 (De DOS CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::DE_DEU,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - Hebrew DOS CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2TALKIE_HB,
+ "Simon the Sorcerer 2 (Hb DOS CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::HB_ISR,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - Italian DOS CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2TALKIE_IT,
+ "Simon the Sorcerer 2 (It DOS CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::IT_ITA,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - Spanish DOS CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2TALKIE_ES,
+ "Simon the Sorcerer 2 (Sp DOS CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::ES_ESP,
+ Common::kPlatformPC,
+ },
+
+ // Simon the Sorcerer 2 - English Windows CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2WIN,
+ "Simon the Sorcerer 2 (Windows CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::EN_USA,
+ Common::kPlatformWindows,
+ },
+
+ // Simon the Sorcerer 2 - German Windows CD
+ {
+ "simon2",
+ GType_SIMON2,
+ GID_SIMON2WIN_DE,
+ "Simon the Sorcerer 2 (De Windows CD)",
+ ARRAYSIZE(SIMON2_GameFiles),
+ SIMON2_GameFiles,
+ GF_TALKIE,
+ Common::DE_DEU,
+ Common::kPlatformWindows,
+ },
+};
+
+bool SimonEngine::initGame(void) {
+ int gameNumber;
+ FSList dummy;
+
+ if ((gameNumber = detectGame(dummy)) == -1) {
+ warning("No valid games were found in the specified directory.");
+ return false;
+ }
+
+ debug(0, "Running %s", gameDescriptions[gameNumber].title);
+
+ _gameDescription = &gameDescriptions[gameNumber];
+
+ return true;
+}
+
+DetectedGameList GAME_ProbeGame(const FSList &fslist, int **retmatches) {
+ DetectedGameList detectedGames;
+ int game_n;
+ int index = 0, i, j;
+ int matches[ARRAYSIZE(gameDescriptions)];
+ bool mode = retmatches ? false : true;
+
+ game_n = -1;
+ for (i = 0; i < ARRAYSIZE(gameDescriptions); i++)
+ matches[i] = -1;
+
+ while (1) {
+ game_n = detectGame(fslist, mode, game_n);
+ if (game_n == -1)
+ break;
+ matches[index++] = game_n;
+ }
+
+ // We have some resource sets which are superpositions of other
+ // Particularly it is ite-demo-linux vs ite-demo-win
+ // Now remove lesser set if bigger matches too
+
+ if (index > 1) {
+ // Search max number
+ int maxcount = 0;
+ for (i = 0; i < index; i++) {
+ int count = 0;
+ for (j = 0; j < ARRAYSIZE(gameMD5); j++)
+ if (gameMD5[j].id == gameDescriptions[matches[i]].gameId)
+ count++;
+ maxcount = MAX(maxcount, count);
+ }
+
+ // Now purge targets with number of files lesser than max
+ for (i = 0; i < index; i++) {
+ int count = 0;
+ for (j = 0; j < ARRAYSIZE(gameMD5); j++)
+ if (gameMD5[j].id == gameDescriptions[matches[i]].gameId)
+ count++;
+ if (count < maxcount) {
+ debug(2, "Purged: %s", gameDescriptions[matches[i]].title);
+ matches[i] = -1;
+ }
+ }
+
+ }
+
+ // and now push them into list of detected games
+ for (i = 0; i < index; i++)
+ if (matches[i] != -1)
+ detectedGames.push_back(DetectedGame(gameDescriptions[matches[i]].toGameSettings(),
+ gameDescriptions[matches[i]].language,
+ gameDescriptions[matches[i]].platform));
+
+ if (retmatches) {
+ *retmatches = (int *)calloc(ARRAYSIZE(gameDescriptions), sizeof(int));
+ for (i = 0; i < ARRAYSIZE(gameDescriptions); i++)
+ (*retmatches)[i] = matches[i];
+ }
+
+ return detectedGames;
+}
+
+int detectGame(const FSList &fslist, bool mode, int start) {
+ int game_count = ARRAYSIZE(gameDescriptions);
+ int game_n = -1;
+ typedef Common::Map<Common::String, Common::String> StringMap;
+ StringMap filesMD5;
+
+ typedef Common::Map<Common::String, bool> StringSet;
+ StringSet filesList;
+
+ uint16 file_count;
+ uint16 file_n;
+ Common::File test_file;
+ bool file_missing;
+
+ Common::String tstr, tstr1;
+ char md5str[32+1];
+ uint8 md5sum[16];
+
+ // First we compose list of files which we need MD5s for
+ for (int i = 0; i < ARRAYSIZE(gameMD5); i++) {
+ tstr = Common::String(gameMD5[i].filename);
+ tstr.toLowercase();
+
+ if (gameMD5[i].caseSensitive && !mode)
+ filesList[Common::String(gameMD5[i].filename)] = true;
+ else
+ filesList[tstr] = true;
+ }
+
+ if (mode) {
+ // Now count MD5s for required files
+ for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
+ if (!file->isDirectory()) {
+ tstr = file->displayName();
+ // FIXME: there is a bug in String class. tstr1 = tstr; tstr.toLowercase()
+ // makes tstr1 lowercase as well
+ tstr1 = Common::String(file->displayName().c_str());
+ tstr.toLowercase();
+
+ if (filesList.contains(tstr) || filesList.contains(tstr1)) {
+ if (Common::md5_file(file->path().c_str(), md5sum, NULL, FILE_MD5_BYTES)) {
+ for (int j = 0; j < 16; j++) {
+ sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
+ }
+ filesMD5[tstr] = Common::String(md5str);
+ filesMD5[tstr1] = Common::String(md5str);
+ }
+ }
+ }
+ }
+ } else {
+ Common::File testFile;
+
+ for (StringSet::const_iterator file = filesList.begin(); file != filesList.end(); ++file) {
+ if (testFile.open(file->_key.c_str())) {
+ testFile.close();
+ if (Common::md5_file(file->_key.c_str(), md5sum, NULL, FILE_MD5_BYTES)) {
+ for (int j = 0; j < 16; j++) {
+ sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
+ }
+ filesMD5[file->_key] = Common::String(md5str);
+ }
+ }
+ }
+ }
+
+ for (game_n = start + 1; game_n < game_count; game_n++) {
+ file_count = gameDescriptions[game_n].filesCount;
+ file_missing = false;
+
+ // Try to open all files for this game
+ for (file_n = 0; file_n < file_count; file_n++) {
+ tstr = gameDescriptions[game_n].filesDescriptions[file_n].fileName;
+
+ if (!filesMD5.contains(tstr)) {
+ file_missing = true;
+ break;
+ }
+ }
+
+ // Try the next game, couldn't find all files for the current
+ // game
+ if (file_missing) {
+ continue;
+ } else {
+ bool match = true;
+
+ debug(0, "Probing game: %s", gameDescriptions[game_n].title);
+
+ for (int i = 0; i < ARRAYSIZE(gameMD5); i++) {
+ if (gameMD5[i].id == gameDescriptions[game_n].gameId) {
+ tstr = gameMD5[i].filename;
+
+ if (strcmp(gameMD5[i].md5, filesMD5[tstr].c_str())) {
+ match = false;
+ break;
+ }
+ }
+ }
+ if (!match)
+ continue;
+
+ debug(0, "Found game: %s", gameDescriptions[game_n].title);
+
+ return game_n;
+ }
+ }
+
+ if (!filesMD5.isEmpty() && start == -1) {
+ printf("MD5s of your game version are unknown. Please, report following data to\n");
+ printf("ScummVM team along with your game name and version:\n");
+
+ for (StringMap::const_iterator file = filesMD5.begin(); file != filesMD5.end(); ++file)
+ printf("%s: %s\n", file->_key.c_str(), file->_value.c_str());
+ }
+
+ return -1;
+}
+
+} // End of namespace Simon
diff --git a/simon/icons.cpp b/simon/icons.cpp
index 2d5513a506..809b2e6fb8 100644
--- a/simon/icons.cpp
+++ b/simon/icons.cpp
@@ -30,9 +30,9 @@ namespace Simon {
void SimonEngine::loadIconFile() {
Common::File in;
- if (_game & GF_ACORN)
+ if (getPlatform() == Common::kPlatformAcorn)
in.open("ICONDATA");
- else if (_game & GF_AMIGA)
+ else if (getPlatform() == Common::kPlatformAmiga)
in.open("icon.pkd");
else
in.open("ICON.DAT");
@@ -161,12 +161,12 @@ void SimonEngine::draw_icon_c(FillOrCopyStruct *fcs, uint icon, uint x, uint y)
_lockWord |= 0x8000;
dst = dx_lock_2();
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
// Simon 1
dst += (x + fcs->x) * 8;
dst += (y * 25 + fcs->y) * _dxSurfacePitch;
- if (_game & GF_AMIGA) {
+ if (getPlatform() == Common::kPlatformAmiga) {
src = _iconFilePtr;
src += READ_BE_UINT32(&((uint32 *)src)[icon]);
decompress_icon_amiga (dst, src, 0xE0, _dxSurfacePitch);
@@ -200,7 +200,7 @@ uint SimonEngine::setup_icon_hit_area(FillOrCopyStruct *fcs, uint x, uint y, uin
ha = findEmptyHitArea();
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
ha->x = (x + fcs->x) << 3;
ha->y = y * 25 + fcs->y;
ha->item_ptr = item_ptr;
diff --git a/simon/intern.h b/simon/intern.h
index 3a4bd840fb..c20c90e38a 100644
--- a/simon/intern.h
+++ b/simon/intern.h
@@ -147,30 +147,46 @@ struct GameSpecificSettings {
} // End of namespace Simon
-enum {
- GF_SIMON1 = 1 << 0,
- GF_SIMON2 = 1 << 1,
- GF_WIN = 1 << 2,
- GF_TALKIE = 1 << 3,
- GF_DEMO = 1 << 4,
- GF_AMIGA = 1 << 5,
- GF_ACORN = 1 << 6,
- GF_OLD_BUNDLE = 1 << 7
-};
-
-enum {
- GAME_SIMON1DOS = GF_SIMON1 | GF_OLD_BUNDLE,
- GAME_SIMON1DEMO = GF_SIMON1 | GF_DEMO | GF_OLD_BUNDLE,
- GAME_SIMON1AMIGA = GF_SIMON1 | GF_AMIGA | GF_OLD_BUNDLE,
- GAME_SIMON1CD32 = GF_SIMON1 | GF_TALKIE | GF_AMIGA | GF_OLD_BUNDLE,
- GAME_SIMON1ACORN = GF_SIMON1 | GF_TALKIE | GF_ACORN,
- GAME_SIMON1TALKIE = GF_SIMON1 | GF_TALKIE,
-
- GAME_SIMON2DOS = GF_SIMON2,
- GAME_SIMON2TALKIE = GF_SIMON2 | GF_TALKIE,
- GAME_SIMON2WIN = GF_SIMON2 | GF_WIN | GF_TALKIE,
-
- GAME_FEEBLEFILES = GF_SIMON2 | GF_WIN | GF_TALKIE | GF_OLD_BUNDLE
+enum GameFeatures {
+ GF_TALKIE = 1 << 0,
+ GF_OLD_BUNDLE = 1 << 1
+};
+
+enum GameFileTypes {
+ GAME_BASEFILE = 1 << 0,
+ GAME_ICONFILE = 1 << 1,
+ GAME_GMEFILE = 1 << 2,
+ GAME_STRFILE = 1 << 3,
+ GAME_TBLFILE = 1 << 4
+};
+
+enum GameIds {
+ GID_SIMON1DOS,
+ GID_SIMON1DEMO,
+ GID_SIMON1AMIGA,
+ GID_SIMON1CD32,
+ GID_SIMON1ACORN,
+ GID_SIMON1TALKIE,
+ GID_SIMON1TALKIE_DE,
+ GID_SIMON1TALKIE_FR,
+ GID_SIMON1TALKIE_HB,
+ GID_SIMON1TALKIE_IT,
+ GID_SIMON1TALKIE_ES,
+ GID_SIMON1WIN,
+ GID_SIMON1WIN_DE,
+
+ GID_SIMON2DOS,
+ GID_SIMON2DEMO,
+ GID_SIMON2TALKIE,
+ GID_SIMON2TALKIE_DE,
+ GID_SIMON2TALKIE_FR,
+ GID_SIMON2TALKIE_HB,
+ GID_SIMON2TALKIE_IT,
+ GID_SIMON2TALKIE_ES,
+ GID_SIMON2WIN,
+ GID_SIMON2WIN_DE,
+
+ GAME_FEEBLEFILES
};
#endif
diff --git a/simon/items.cpp b/simon/items.cpp
index 02a5657dcf..55e8f7c97c 100644
--- a/simon/items.cpp
+++ b/simon/items.cpp
@@ -277,7 +277,7 @@ int SimonEngine::runScript() {
// Disable random in simon1amiga for now
// Since copy protection screen is currently unreadable
- if (_game == GAME_SIMON1AMIGA)
+ if (getPlatform() == Common::kPlatformAmiga)
writeVariable(var, 4);
else
writeVariable(var, _rnd.getRandomNumber(value - 1));
@@ -374,7 +374,7 @@ int SimonEngine::runScript() {
case 67:{ /* set item description */
uint var = getVarOrByte();
uint string_id = getNextStringID();
- if (_game & GF_TALKIE) {
+ if (getFeatures() & GF_TALKIE) {
uint speech_id = getNextWord();
if (var < 20) {
_stringIdArray3[var] = string_id;
@@ -400,7 +400,7 @@ int SimonEngine::runScript() {
case 70:{ /* show string from array */
const char *str = (const char *)getStringPtrByID(_stringIdArray3[getVarOrByte()]);
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
writeVariable(51, strlen(str) / 53 * 8 + 8);
}
@@ -449,7 +449,7 @@ int SimonEngine::runScript() {
break;
case 83:{ /* restart subroutine */
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
o_83_helper();
return -10;
}
@@ -527,7 +527,7 @@ int SimonEngine::runScript() {
case 98:{ /* start vga */
uint vga_res, vgaSpriteId, windowNum, x, y, palette;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
vga_res = getVarOrWord();
vgaSpriteId = getVarOrWord();
} else {
@@ -543,7 +543,7 @@ int SimonEngine::runScript() {
break;
case 99:{ /* kill sprite */
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
o_kill_sprite_simon1(getVarOrWord());
} else {
uint a = getVarOrWord();
@@ -741,7 +741,7 @@ int SimonEngine::runScript() {
case 133:{ /* load game */
_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
load_game(readVariable(55));
} else {
o_load_game();
@@ -757,7 +757,7 @@ int SimonEngine::runScript() {
break;
case 135:{ /* quit if user presses y */
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
// Switch CD
debug(1, "Switch to CD number %d", readVariable(97));
} else {
@@ -986,7 +986,7 @@ int SimonEngine::runScript() {
const char *string_ptr = (const char *)getStringPtrByID(_stringIdArray3[string_id]);
TextLocation *tl = getTextLocation(vgaSpriteId);
- if (_game & GF_TALKIE)
+ if (getFeatures() & GF_TALKIE)
speech_id = _speechIdArray4[string_id];
if (_speech && speech_id != 0)
@@ -1003,7 +1003,7 @@ int SimonEngine::runScript() {
case 181:{ /* force lock */
o_force_lock();
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
changeWindow(1);
showMessageFormat("\xC");
}
@@ -1011,10 +1011,10 @@ int SimonEngine::runScript() {
break;
case 182:{ /* load beard */
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
// Load video file
debug(1,"Load video file: %s", getStringPtrByID(getNextStringID()));
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
goto invalid_opcode;
} else {
o_loadBeard();
@@ -1023,10 +1023,10 @@ int SimonEngine::runScript() {
break;
case 183:{ /* unload beard */
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
// Play video
debug(1, "Play video");
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
goto invalid_opcode;
} else {
o_unloadBeard();
@@ -1040,11 +1040,11 @@ int SimonEngine::runScript() {
break;
case 185:{ /* load sound files */
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
goto invalid_opcode;
_soundFileId = getVarOrWord();
- if (_game == GAME_SIMON1CD32) {
+ if (getPlatform() == Common::kPlatformAmiga && getFeatures() & GF_TALKIE) {
char buf[10];
sprintf(buf, "%d%s", _soundFileId, "Effects");
_sound->readSfxFile(buf);
@@ -1061,14 +1061,14 @@ int SimonEngine::runScript() {
break;
case 187:{ /* fade to black */
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
goto invalid_opcode;
o_fade_to_black();
}
break;
case 188: /* string2 is */
- if (_game & GF_SIMON1)
+ if (getGameType() == GType_SIMON1)
goto invalid_opcode;
{
uint i = getVarOrByte();
@@ -1078,7 +1078,7 @@ int SimonEngine::runScript() {
break;
case 189:{ /* clear_op189_flag */
- if (_game & GF_SIMON1)
+ if (getGameType() == GType_SIMON1)
goto invalid_opcode;
_marks = 0;
}
@@ -1086,7 +1086,7 @@ int SimonEngine::runScript() {
case 190:{
uint i;
- if (_game & GF_SIMON1)
+ if (getGameType() == GType_SIMON1)
goto invalid_opcode;
i = getVarOrByte();
if (!(_marks & (1 << i)))
@@ -1310,7 +1310,7 @@ void SimonEngine::o_inventory_descriptions() {
tl = getTextLocation(vgaSpriteId);
}
- if ((_game & GF_SIMON2) && (_game & GF_TALKIE)) {
+ if ((getGameType() == GType_SIMON2) && (getFeatures() & GF_TALKIE)) {
if (child != NULL && child->avail_props & 0x200) {
uint speech_id = child->array[getOffsetOfChild2Param(child, 0x200)];
@@ -1362,7 +1362,7 @@ void SimonEngine::o_inventory_descriptions() {
talk_with_speech(speech_id, vgaSpriteId);
}
- } else if (_game & GF_TALKIE) {
+ } else if (getFeatures() & GF_TALKIE) {
if (child != NULL && child->avail_props & 0x200) {
uint offs = getOffsetOfChild2Param(child, 0x200);
talk_with_speech(child->array[offs], vgaSpriteId);
@@ -1470,7 +1470,7 @@ int SimonEngine::o_unk_132_helper(bool *b, char *buf) {
start_over:;
_keyPressed = 0;
- if (_game == GAME_SIMON1CD32)
+ if (getPlatform() == Common::kPlatformAmiga && getFeatures() & GF_TALKIE)
goto start_over_3;
start_over_2:;
@@ -1604,7 +1604,7 @@ void SimonEngine::o_play_music_resource() {
// actually start a track (so the resource is
// effectively preloaded so there's no latency when
// starting playback).
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
int loop = getVarOrByte();
midi.setLoop (loop != 0);
@@ -1630,7 +1630,7 @@ void SimonEngine::o_unk_120(uint a) {
}
void SimonEngine::o_play_sound(uint sound_id) {
- if (_game == GAME_SIMON1DOS)
+ if (getGameId() == GID_SIMON1DOS)
playSting(sound_id);
else
_sound->playEffects(sound_id);
diff --git a/simon/module.mk b/simon/module.mk
index 28878d9ce3..d2f860fb7f 100644
--- a/simon/module.mk
+++ b/simon/module.mk
@@ -5,6 +5,7 @@ MODULE_OBJS := \
simon/cursor.o \
simon/debug.o \
simon/debugger.o \
+ simon/game.o \
simon/icons.o \
simon/items.o \
simon/midi.o \
diff --git a/simon/res.cpp b/simon/res.cpp
index 39f573ac62..c91a8a7292 100644
--- a/simon/res.cpp
+++ b/simon/res.cpp
@@ -114,14 +114,14 @@ static const char *const opcode_arg_table_feeblefiles[256] = {
};
uint16 SimonEngine::to16Wrapper(uint value) {
- if (_game == GAME_FEEBLEFILES)
+ if (getGameType() == GType_FF)
return TO_LE_16(value);
else
return TO_BE_16(value);
}
uint16 SimonEngine::readUint16Wrapper(const void *src) {
- if (_game == GAME_FEEBLEFILES)
+ if (getGameType() == GType_FF)
return READ_LE_UINT16(src);
else
return READ_BE_UINT16(src);
@@ -179,11 +179,11 @@ void SimonEngine::loadGamePcFile(const char *filename) {
_tablesHeapPtrOrg = _tablesHeapPtr;
_tablesHeapCurPosOrg = _tablesHeapCurPos;
- if (_game == GAME_FEEBLEFILES)
+ if (getGameType() == GType_FF)
return;
/* Read list of TEXT resources */
- if (_game == GAME_SIMON1ACORN)
+ if (getPlatform() == Common::kPlatformAcorn)
in.open("STRIPPED");
else
in.open("STRIPPED.TXT");
@@ -294,13 +294,13 @@ byte *SimonEngine::readSingleOpcode(Common::File *in, byte *ptr) {
const char *const *table;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
table = opcode_arg_table_feeblefiles;
- } else if ((_game & GF_SIMON2) && (_game & GF_TALKIE))
+ } else if ((getGameType() == GType_SIMON2) && (getFeatures() & GF_TALKIE))
table = opcode_arg_table_simon2win;
- else if (_game & GF_SIMON2)
+ else if (getGameType() == GType_SIMON2)
table = opcode_arg_table_simon2dos;
- else if (_game & GF_TALKIE)
+ else if (getFeatures() & GF_TALKIE)
table = opcode_arg_table_simon1win;
else
table = opcode_arg_table_simon1dos;
diff --git a/simon/saveload.cpp b/simon/saveload.cpp
index cee09f15a9..c3e2fca004 100644
--- a/simon/saveload.cpp
+++ b/simon/saveload.cpp
@@ -108,7 +108,7 @@ int SimonEngine::display_savegame_list(int curpos, bool load, char *dst) {
void SimonEngine::quick_load_or_save() {
// simon1demo subroutines are missing too many segments
// original demo didn't allow load or save either.
- if (_game == GAME_SIMON1DEMO)
+ if (getGameId() == GID_SIMON1DEMO)
return;
bool success;
@@ -412,7 +412,7 @@ bool SimonEngine::save_game(uint slot, char *caption) {
return false;
}
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
f->write(caption, 100);
} else {
f->write(caption, 18);
@@ -482,7 +482,7 @@ bool SimonEngine::save_game(uint slot, char *caption) {
f->writeUint16BE(_bitArray[i]);
// Write the bits in array 3
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
for (i = 33; i != 48; i++)
f->writeUint16BE(_bitArray[i]);
}
@@ -499,12 +499,12 @@ bool SimonEngine::save_game(uint slot, char *caption) {
char *SimonEngine::gen_savename(int slot) {
static char buf[15];
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
if (slot == 999)
sprintf(buf, "save.%.3d", slot);
else
sprintf(buf, "feeble.%.3d", slot);
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
sprintf(buf, "simon2.%.3d", slot);
} else {
sprintf(buf, "simon1.%.3d", slot);
@@ -525,7 +525,7 @@ bool SimonEngine::load_game(uint slot) {
return false;
}
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
f->read(ident, 100);
} else {
f->read(ident, 18);
@@ -612,7 +612,7 @@ bool SimonEngine::load_game(uint slot) {
_bitArray[i] = f->readUint16BE();
// Read the bits in array 3
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
for (i = 33; i != 48; i++)
_bitArray[i] = f->readUint16BE();
}
diff --git a/simon/simon-md5.h b/simon/simon-md5.h
deleted file mode 100644
index 8322bbd1b9..0000000000
--- a/simon/simon-md5.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- This file was generated by the md5table tool on Fri Nov 11 22:51:20 2005
- DO NOT EDIT MANUALLY!
- */
-
-struct MD5Table {
- const char *md5;
- const char *target;
- Common::Language language;
- Common::Platform platform;
-};
-
-static const MD5Table md5table[] = {
- { "028c6240c9c8e190d86188238505c5e5", "simon2talkie", Common::DE_DEU, Common::kPlatformPC },
- { "057eac98fc4d14dc7fd04341781b26b3", "simon1talkie", Common::IT_ITA, Common::kPlatformPC },
- { "078b04da0974a40645b92baffdf2781e", "simon2talkie", Common::EN_USA, Common::kPlatformPC },
- { "08bd7abefe9c44e43df396748640e531", "simon1talkie", Common::FR_FRA, Common::kPlatformPC },
- { "1e11ddbad80c408031ae44a0cbce46bb", "simon2talkie", Common::EN_USA, Common::kPlatformPC },
- { "39e8f13ec29de1fcef98c81ca0a2ae57", "simon1amiga", Common::EN_USA, Common::kPlatformAmiga },
- { "3b22f3cc4ce9faa3f7830ab18235b04d", "simon1dos", Common::RU_RUS, Common::kPlatformPC },
- { "3bdf85dc57c1abff8f05416b4571198f", "simon2talkie", Common::DE_DEU, Common::kPlatformPC },
- { "486f026593f894f5b6b346ef3984a7a0", "simon1demo", Common::EN_USA, Common::kPlatformPC },
- { "48ce4ffda968cc7a38870c354571f92c", "simon1dos", Common::EN_USA, Common::kPlatformPC },
- { "79a9d9357c15153c8c502dba73c3eac6", "simon2talkie", Common::ES_ESP, Common::kPlatformPC },
- { "9d58f84988634d217c944cd4153a2a3b", "simon1talkie", Common::HB_ISR, Common::kPlatformPC },
- { "9e858b3bb189c134c3a5f34c3385a8d3", "simon2talkie", Common::DE_DEU, Common::kPlatformWindows },
- { "a3cbdd3450f9fccb0a9d8d6dc28f66fe", "simon2talkie", Common::HB_ISR, Common::kPlatformPC },
- { "b6cfe7449a32418ed523bde22f5125ed", "simon1dos", Common::FR_FRA, Common::kPlatformPC },
- { "bd85a8b5135592ada9cbeae49160f1d3", "simon2talkie", Common::EN_USA, Common::kPlatformWindows },
- { "c5091c98e3b13760764876177fdf4fb4", "simon2talkie", Common::IT_ITA, Common::kPlatformPC },
- { "c8ddd48919aa75423dd2d3e5864909df", "simon2talkie", Common::FR_FRA, Common::kPlatformPC },
- { "c8f5b860a20dcc63915d94cf2bdcfa49", "simon1dos", Common::IT_ITA, Common::kPlatformPC },
- { "d22302abf44219f95d50f2faa807dd1a", "simon1talkie", Common::EN_USA, Common::kPlatformWindows },
- { "d545db8a0efae95a90b23da81aadb201", "simon1talkie", Common::EN_USA, Common::kPlatformPC },
- { "e3712b3ed4429e736123a40276f533d7", "simon1talkie", Common::ES_ESP, Common::kPlatformPC },
- { "ec5358680c117f29b128cbbb322111a4", "simon1cd32", Common::EN_USA, Common::kPlatformAmiga },
- { "ecc01a02c9b97b49d0b4191a346b0940", "simon1talkie", Common::DE_DEU, Common::kPlatformPC },
- { "fa5651a5e5da0f3c89473dd62af095d8", "simon1amiga", Common::EN_USA, Common::kPlatformAmiga },
- { 0, 0, Common::UNK_LANG, Common::kPlatformUnknown }
-};
diff --git a/simon/simon.cpp b/simon/simon.cpp
index 5f2b02e45c..b6704862a7 100644
--- a/simon/simon.cpp
+++ b/simon/simon.cpp
@@ -38,7 +38,6 @@
#include "simon/intern.h"
#include "simon/vga.h"
#include "simon/debugger.h"
-#include "simon/simon-md5.h"
#include "sound/mididrv.h"
#ifdef _WIN32_WCE
@@ -51,117 +50,90 @@ extern bool isSmartphone(void);
using Common::File;
-struct SimonGameSettings {
- const char *name;
- const char *description;
- uint32 features;
- const char *detectname;
+struct ObsoleteTargets {
+ const char *from;
+ const char *to;
+ Common::Platform platform;
+
GameSettings toGameSettings() const {
- GameSettings dummy = { name, description, features };
+ GameSettings dummy = { from, "Obsolete Target", 0 };
return dummy;
}
};
-static const SimonGameSettings simon_settings[] = {
- // Simon the Sorcerer 1 & 2 (not SCUMM games)
- {"simon1acorn", "Simon the Sorcerer 1 (Acorn)", GAME_SIMON1ACORN, "DATA"},
- {"simon1dos", "Simon the Sorcerer 1 (DOS)", GAME_SIMON1DOS, "GAMEPC"},
- {"simon1amiga", "Simon the Sorcerer 1 (Amiga)", GAME_SIMON1AMIGA, "gameamiga"},
- {"simon2dos", "Simon the Sorcerer 2 (DOS)", GAME_SIMON2DOS, "GAME32"},
- {"simon1talkie", "Simon the Sorcerer 1 Talkie", GAME_SIMON1TALKIE, "GAMEPC"},
- {"simon1win", "Simon the Sorcerer 1 Talkie (Windows)", GAME_SIMON1TALKIE, 0},
- {"simon2talkie", "Simon the Sorcerer 2 Talkie", GAME_SIMON2TALKIE, "GSPTR30"},
- {"simon2win", "Simon the Sorcerer 2 Talkie (Windows)", GAME_SIMON2WIN, 0},
- {"simon2mac", "Simon the Sorcerer 2 Talkie (Amiga or Mac)", GAME_SIMON2WIN, 0},
- {"simon1cd32", "Simon the Sorcerer 1 Talkie (Amiga CD32)", GAME_SIMON1CD32, "gameamiga"},
- {"simon1demo", "Simon the Sorcerer 1 (DOS Demo)", GAME_SIMON1DEMO, "GDEMO"},
- {"feeble", "The Feeble Files", GAME_FEEBLEFILES, "GAME22"},
-
- {NULL, NULL, 0, NULL}
+/**
+ * Conversion table mapping old obsolete target names to the
+ * corresponding new target and platform combination.
+ *
+ */
+static ObsoleteTargets obsoleteTargetsTable[] = {
+ {"simon1acorn", "simon1", Common::kPlatformAcorn},
+ {"simon1amiga", "simon1", Common::kPlatformAmiga},
+ {"simon1cd32", "simon1", Common::kPlatformAmiga},
+ {"simon1dos", "simon1", Common::kPlatformPC},
+ {"simon1talkie", "simon1", Common::kPlatformPC},
+ {"simon1win", "simon1", Common::kPlatformWindows},
+ {"simon2dos", "simon2", Common::kPlatformPC},
+ {"simon2talkie", "simon2", Common::kPlatformPC},
+ {"simon2mac", "simon2", Common::kPlatformMacintosh},
+ {"simon2win", "simon2", Common::kPlatformWindows},
+ {NULL, NULL, Common::kPlatformUnknown}
};
-static int compareMD5Table(const void *a, const void *b) {
- const char *key = (const char *)a;
- const MD5Table *elem = (const MD5Table *)b;
- return strcmp(key, elem->md5);
-}
+static const GameSettings simonGames[] = {
+ // Simon the Sorcerer 1 & 2 (not SCUMM games)
+ {"feeble", "The Feeble Files", 0},
+ {"simon1", "Simon the Sorcerer 1", 0},
+ {"simon2", "Simon the Sorcerer 2", 0},
+
+ {"simon1acorn", "Simon the Sorcerer 1 (Acorn)", 0},
+ {"simon1amiga", "Simon the Sorcerer 1 (Amiga)", 0},
+ {"simon1cd32", "Simon the Sorcerer 1 Talkie (Amiga CD32)", 0},
+ {"simon1demo", "Simon the Sorcerer 1 (DOS Demo)", 0},
+ {"simon1dos", "Simon the Sorcerer 1 (DOS)", 0},
+ {"simon1talkie", "Simon the Sorcerer 1 Talkie", 0},
+ {"simon1win", "Simon the Sorcerer 1 Talkie (Windows)", 0},
+ {"simon2dos", "Simon the Sorcerer 2 (DOS)", 0},
+ {"simon2talkie", "Simon the Sorcerer 2 Talkie", 0},
+ {"simon2win", "Simon the Sorcerer 2 Talkie (Windows)", 0},
+ {"simon2mac", "Simon the Sorcerer 2 Talkie (Amiga or Mac)", 0},
+
+ {NULL, NULL, 0}
+};
GameList Engine_SIMON_gameList() {
- const SimonGameSettings *g = simon_settings;
GameList games;
+ const GameSettings *g = simonGames;
while (g->name) {
- games.push_back(g->toGameSettings());
+ games.push_back(*g);
g++;
}
+
return games;
}
DetectedGameList Engine_SIMON_detectGames(const FSList &fslist) {
- DetectedGameList detectedGames;
- const SimonGameSettings *g;
- char detectName[128];
- char detectName2[128];
-
- typedef Common::Map<Common::String, bool> StringSet;
- StringSet fileSet;
-
- for (g = simon_settings; g->name; ++g) {
- if (g->detectname == NULL)
- continue;
-
- strcpy(detectName, g->detectname);
- strcpy(detectName2, g->detectname);
- strcat(detectName2, ".");
+ return Simon::GAME_ProbeGame(fslist);
+}
- // Iterate over all files in the given directory
- for (FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
- if (!file->isDirectory()) {
- const char *name = file->displayName().c_str();
+Engine *Engine_SIMON_create(GameDetector *detector, OSystem *syst) {
+ const ObsoleteTargets *o = obsoleteTargetsTable;
+ while (o->from) {
+ if (!scumm_stricmp(detector->_game.name, o->from)) {
+ detector->_game.name = o->to;
- if ((!scumm_stricmp(detectName, name)) || (!scumm_stricmp(detectName2, name))) {
- // Match found, add to list of candidates, then abort inner loop.
- detectedGames.push_back(g->toGameSettings());
- fileSet.addKey(file->path());
- break;
- }
- }
- }
- }
+ ConfMan.set("gameid", o->to);
- // Now, we check the MD5 sums of the 'candidate' files. If we have an exact match,
- // only return that.
- bool exactMatch = false;
- for (StringSet::const_iterator iter = fileSet.begin(); iter != fileSet.end(); ++iter) {
- uint8 md5sum[16];
- const char *name = iter->_key.c_str();
- if (Common::md5_file(name, md5sum)) {
- char md5str[32+1];
- for (int j = 0; j < 16; j++) {
- sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
- }
+ if (o->platform != Common::kPlatformUnknown)
+ ConfMan.set("platform", Common::getPlatformCode(o->platform));
- const MD5Table *elem;
- elem = (const MD5Table *)bsearch(md5str, md5table, ARRAYSIZE(md5table)-1, sizeof(MD5Table), compareMD5Table);
- if (elem) {
- if (!exactMatch)
- detectedGames.clear(); // Clear all the non-exact candidates
- // Find the GameSettings for that target
- for (g = simon_settings; g->name; ++g) {
- if (0 == scumm_stricmp(g->name, elem->target))
- break;
- }
- assert(g->name);
- // Insert the 'enhanced' game data into the candidate list
- detectedGames.push_back(DetectedGame(g->toGameSettings(), elem->language, elem->platform));
- exactMatch = true;
- }
+ warning("Target upgraded from %s to %s", o->from, o->to);
+ ConfMan.flushToDisk();
+ break;
}
+ o++;
}
- return detectedGames;
-}
-
-Engine *Engine_SIMON_create(GameDetector *detector, OSystem *syst) {
return new Simon::SimonEngine(detector, syst);
}
@@ -279,15 +251,8 @@ static const GameSpecificSettings feeblefiles_settings = {
};
#endif
-static const char* bad_versions[3] = {
- "465eed710cc242b2de7dc77edd467c4c", // simon1dos (English)
- "bed9134804d96f72afa152b8ec5628c3", // simon1dos (French)
- "27c8e7feada80c75b70b9c2f6088d519", // simon2dos (English)
-};
-
SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst)
: Engine(syst), midi(syst) {
- int j =0;
_vcPtr = 0;
_vc_get_out_of_code = 0;
_gameOffsetsPtr = 0;
@@ -295,164 +260,6 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst)
_debugger = 0;
setupVgaOpcodes();
- const SimonGameSettings *g = simon_settings;
- while (g->name) {
- if (!scumm_stricmp(detector->_game.name, g->name))
- break;
- g++;
- }
- if (!g->name)
- error("Invalid game '%s'\n", detector->_game.name);
-
- SimonGameSettings game = *g;
-
- switch (Common::parsePlatform(ConfMan.get("platform"))) {
- case Common::kPlatformAmiga:
- case Common::kPlatformMacintosh:
- if (game.features & GF_SIMON2)
- game.features |= GF_WIN;
- break;
- case Common::kPlatformWindows:
- game.features |= GF_WIN;
- break;
- default:
- break;
- }
-
- _game = game.features;
-
- // Convert older targets
- if (g->detectname == NULL) {
- if (!strcmp("simon1win", g->name)) {
- ConfMan.set("gameid", "simon1talkie");
- ConfMan.set("platform", "Windows");
- } else if (!strcmp("simon2win", g->name) || !strcmp("simon2mac", g->name)) {
- ConfMan.set("gameid", "simon2talkie");
- ConfMan.set("platform", "Windows");
- }
- ConfMan.flushToDisk();
- } else {
- char buf[100];
- uint8 md5sum[16];
- File f;
-
- sprintf(buf, g->detectname);
- f.open(buf);
- if (f.isOpen() == false)
- strcat(buf, ".");
-
- if (Common::md5_file(buf, md5sum)) {
- char md5str[32+1];
- for (j = 0; j < 16; j++) {
- sprintf(md5str + j*2, "%02x", (int)md5sum[j]);
- }
-
- for (j = 0; j < 3; j++) {
- if (!strcmp(md5str, bad_versions[j]))
- error("Cracked versions aren't supported");
- }
-
- printf("%s %s\n", md5str, buf);
- const MD5Table *elem;
- elem = (const MD5Table *)bsearch(md5str, md5table, ARRAYSIZE(md5table)-1, sizeof(MD5Table), compareMD5Table);
- if (elem)
- printf("Match found in database: target %s, language %s, platform %s\n",
- elem->target, Common::getLanguageDescription(elem->language), Common::getPlatformDescription(elem->platform));
- else
- printf("Unknown MD5! Please report the details (language, platform, etc.) of this game to the ScummVM team\n");
- }
- }
-
- VGA_DELAY_BASE = 1;
- if (_game == GAME_FEEBLEFILES) {
- NUM_VIDEO_OP_CODES = 85;
-#ifndef PALMOS_68K
- VGA_MEM_SIZE = 7500000;
-#else
- VGA_MEM_SIZE = gVars->memory[kMemSimon2Games];
-#endif
- TABLES_MEM_SIZE = 200000;
- } else if (_game & GF_SIMON2) {
- TABLE_INDEX_BASE = 1580 / 4;
- TEXT_INDEX_BASE = 1500 / 4;
- NUM_VIDEO_OP_CODES = 75;
-#ifndef PALMOS_68K
- VGA_MEM_SIZE = 2000000;
-#else
- VGA_MEM_SIZE = gVars->memory[kMemSimon2Games];
-#endif
- TABLES_MEM_SIZE = 100000;
- // Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2
- if ((_game & GF_SIMON2) && (ConfMan.getBool("native_mt32") || (_midiDriver == MD_MT32)))
- MUSIC_INDEX_BASE = (1128 + 612) / 4;
- else
- MUSIC_INDEX_BASE = 1128 / 4;
- SOUND_INDEX_BASE = 1660 / 4;
- } else {
- TABLE_INDEX_BASE = 1576 / 4;
- TEXT_INDEX_BASE = 1460 / 4;
- NUM_VIDEO_OP_CODES = 64;
-#ifndef PALMOS_68K
- VGA_MEM_SIZE = 1000000;
-#else
- VGA_MEM_SIZE = gVars->memory[kMemSimon1Games];
-#endif
- TABLES_MEM_SIZE = 50000;
- MUSIC_INDEX_BASE = 1316 / 4;
- SOUND_INDEX_BASE = 0;
- }
-
- _language = Common::parseLanguage(ConfMan.get("language"));
- if (_game == GAME_FEEBLEFILES) {
- gss = PTR(feeblefiles_settings);
- } else if (_game & GF_SIMON2) {
- if (_game & GF_TALKIE) {
- gss = PTR(simon2win_settings);
-
- // Add default file directories
- File::addDefaultDirectory(_gameDataPath + "voices/");
- File::addDefaultDirectory(_gameDataPath + "VOICES/");
- } else {
- gss = PTR(simon2dos_settings);
- }
- } else if (_game & GF_SIMON1) {
- if (_game & GF_ACORN) {
- gss = PTR(simon1acorn_settings);
-
- // Add default file directories
- File::addDefaultDirectory(_gameDataPath + "execute/");
- File::addDefaultDirectory(_gameDataPath + "EXECUTE/");
- } else if (_game & GF_AMIGA) {
- gss = PTR(simon1amiga_settings);
- } else if (_game & GF_DEMO) {
- gss = PTR(simon1demo_settings);
- } else {
- gss = PTR(simon1_settings);
- }
- }
-
- if ((_game & GF_SIMON1) && (_game & GF_TALKIE)) {
- // Add default file directories
- switch (_language) {
- case 20:
- File::addDefaultDirectory(_gameDataPath + "hebrew/");
- File::addDefaultDirectory(_gameDataPath + "HEBREW/");
- break;
- case 5:
- File::addDefaultDirectory(_gameDataPath + "spanish/");
- File::addDefaultDirectory(_gameDataPath + "SPANISH/");
- break;
- case 3:
- File::addDefaultDirectory(_gameDataPath + "italian/");
- File::addDefaultDirectory(_gameDataPath + "ITALIAN/");
- break;
- case 2:
- File::addDefaultDirectory(_gameDataPath + "french/");
- File::addDefaultDirectory(_gameDataPath + "FRENCH/");
- break;
- }
- }
-
_keyPressed = 0;
_gameFile = 0;
@@ -701,16 +508,31 @@ SimonEngine::SimonEngine(GameDetector *detector, OSystem *syst)
memcpy (_hebrew_char_widths,
"\x5\x5\x4\x6\x5\x3\x4\x5\x6\x3\x5\x5\x4\x6\x5\x3\x4\x6\x5\x6\x6\x6\x5\x5\x5\x6\x5\x6\x6\x6\x6\x6", 32);
- if (_game == GAME_FEEBLEFILES) {
+}
+
+int SimonEngine::init(GameDetector &detector) {
+ // Detect game and open resource files
+ if (!initGame()) {
+ return -1;
+ }
+
+ // Checking flags
+ if (getGameType() == GType_SIMON1)
+ printf("Simon1 game\n");
+ else if (getGameType() == GType_SIMON2)
+ printf("Simon2 game\n");
+
+ if (getFeatures() & GF_TALKIE)
+ printf("Talkie\n");
+
+ if (getGameType() == GType_FF) {
_screenWidth = 640;
_screenHeight = 480;
} else {
_screenWidth = 320;
_screenHeight = 200;
}
-}
-int SimonEngine::init(GameDetector &detector) {
// Setup mixer
if (!_mixer->isReady())
warning("Sound initialization failed. "
@@ -721,14 +543,14 @@ int SimonEngine::init(GameDetector &detector) {
_system->beginGFXTransaction();
initCommonGFX(detector);
_system->initSize(_screenWidth, _screenHeight);
- if (_game == GAME_FEEBLEFILES)
+ if (getGameType() == GType_FF)
_system->setGraphicsMode("1x");
_system->endGFXTransaction();
// Setup midi driver
MidiDriver *driver = 0;
_midiDriver = MD_NULL;
- if (_game == GAME_SIMON1AMIGA || _game == GAME_SIMON1CD32)
+ if (getPlatform() == Common::kPlatformAmiga)
driver = MidiDriver::createMidi(MD_NULL); // Create fake MIDI driver for Simon1Amiga and Simon2CD32 for now
else {
_midiDriver = MidiDriver::detectMusicDriver(MDT_ADLIB | MDT_NATIVE);
@@ -739,7 +561,7 @@ int SimonEngine::init(GameDetector &detector) {
else if (ConfMan.getBool("native_mt32") || (_midiDriver == MD_MT32))
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
- midi.mapMT32toGM (!(_game & GF_SIMON2) && !(ConfMan.getBool("native_mt32") || (_midiDriver == MD_MT32)));
+ midi.mapMT32toGM (!(getGameType() == GType_SIMON2) && !(ConfMan.getBool("native_mt32") || (_midiDriver == MD_MT32)));
midi.set_driver(driver);
int ret = midi.open();
@@ -752,17 +574,17 @@ int SimonEngine::init(GameDetector &detector) {
if (ConfMan.hasKey("music_mute") && ConfMan.getBool("music_mute") == 1)
midi.pause(_musicPaused ^= 1);
- if ((_game & GF_SIMON2) && ConfMan.hasKey("speech_mute") && ConfMan.getBool("speech_mute") == 1)
+ if ((getGameType() == GType_SIMON2) && ConfMan.hasKey("speech_mute") && ConfMan.getBool("speech_mute") == 1)
_speech = 0;
- if ((!(_game & GF_SIMON2) && _language > 1) || ((_game & GF_SIMON2) && _language == 20)) {
+ if ((!(getGameType() == GType_SIMON2) && _language > 1) || ((getGameType() == GType_SIMON2) && _language == 20)) {
if (ConfMan.hasKey("subtitles") && ConfMan.getBool("subtitles") == 0)
_subtitles = 0;
} else
_subtitles = ConfMan.getBool("subtitles");
// Make sure either speech or subtitles is enabled
- if ((_game & GF_TALKIE) && !_speech && !_subtitles)
+ if ((getFeatures() & GF_TALKIE) && !_speech && !_subtitles)
_subtitles = 1;
if (ConfMan.hasKey("fade") && ConfMan.getBool("fade") == 0)
@@ -774,6 +596,96 @@ int SimonEngine::init(GameDetector &detector) {
// FIXME Use auto dirty rects cleanup code to reduce CPU usage
g_system->setFeatureState(OSystem::kFeatureAutoComputeDirtyRects, true);
+ VGA_DELAY_BASE = 1;
+ if (getGameType() == GType_FF) {
+ NUM_VIDEO_OP_CODES = 85;
+#ifndef PALMOS_68K
+ VGA_MEM_SIZE = 7500000;
+#else
+ VGA_MEM_SIZE = gVars->memory[kMemSimon2Games];
+#endif
+ TABLES_MEM_SIZE = 200000;
+ } else if (getGameType() == GType_SIMON2) {
+ TABLE_INDEX_BASE = 1580 / 4;
+ TEXT_INDEX_BASE = 1500 / 4;
+ NUM_VIDEO_OP_CODES = 75;
+#ifndef PALMOS_68K
+ VGA_MEM_SIZE = 2000000;
+#else
+ VGA_MEM_SIZE = gVars->memory[kMemSimon2Games];
+#endif
+ TABLES_MEM_SIZE = 100000;
+ // Check whether to use MT-32 MIDI tracks in Simon the Sorcerer 2
+ if ((getGameType() == GType_SIMON2) && (ConfMan.getBool("native_mt32") || (_midiDriver == MD_MT32)))
+ MUSIC_INDEX_BASE = (1128 + 612) / 4;
+ else
+ MUSIC_INDEX_BASE = 1128 / 4;
+ SOUND_INDEX_BASE = 1660 / 4;
+ } else {
+ TABLE_INDEX_BASE = 1576 / 4;
+ TEXT_INDEX_BASE = 1460 / 4;
+ NUM_VIDEO_OP_CODES = 64;
+#ifndef PALMOS_68K
+ VGA_MEM_SIZE = 1000000;
+#else
+ VGA_MEM_SIZE = gVars->memory[kMemSimon1Games];
+#endif
+ TABLES_MEM_SIZE = 50000;
+ MUSIC_INDEX_BASE = 1316 / 4;
+ SOUND_INDEX_BASE = 0;
+ }
+
+ _language = Common::parseLanguage(ConfMan.get("language"));
+ if (getGameType() == GType_FF) {
+ gss = PTR(feeblefiles_settings);
+ } else if (getGameType() == GType_SIMON2) {
+ if (getFeatures() & GF_TALKIE) {
+ gss = PTR(simon2win_settings);
+
+ // Add default file directories
+ File::addDefaultDirectory(_gameDataPath + "voices/");
+ File::addDefaultDirectory(_gameDataPath + "VOICES/");
+ } else {
+ gss = PTR(simon2dos_settings);
+ }
+ } else if (getGameType() == GType_SIMON1) {
+ if (getPlatform() == Common::kPlatformAcorn) {
+ gss = PTR(simon1acorn_settings);
+
+ // Add default file directories
+ File::addDefaultDirectory(_gameDataPath + "execute/");
+ File::addDefaultDirectory(_gameDataPath + "EXECUTE/");
+ } else if (getPlatform() == Common::kPlatformAmiga) {
+ gss = PTR(simon1amiga_settings);
+ } else if (getGameId() == GID_SIMON1DEMO) {
+ gss = PTR(simon1demo_settings);
+ } else {
+ gss = PTR(simon1_settings);
+ }
+ }
+
+ if ((getGameType() == GType_SIMON1) && (getFeatures() & GF_TALKIE)) {
+ // Add default file directories
+ switch (_language) {
+ case 20:
+ File::addDefaultDirectory(_gameDataPath + "hebrew/");
+ File::addDefaultDirectory(_gameDataPath + "HEBREW/");
+ break;
+ case 5:
+ File::addDefaultDirectory(_gameDataPath + "spanish/");
+ File::addDefaultDirectory(_gameDataPath + "SPANISH/");
+ break;
+ case 3:
+ File::addDefaultDirectory(_gameDataPath + "italian/");
+ File::addDefaultDirectory(_gameDataPath + "ITALIAN/");
+ break;
+ case 2:
+ File::addDefaultDirectory(_gameDataPath + "french/");
+ File::addDefaultDirectory(_gameDataPath + "FRENCH/");
+ break;
+ }
+ }
+
return 0;
}
@@ -1406,11 +1318,11 @@ void SimonEngine::loadTablesIntoMem(uint subr_id) {
in = openTablesFile(filename);
readSubroutineBlock(in);
closeTablesFile(in);
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
// TODO
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
_sound->loadSfxTable(_gameFile, _gameOffsetsPtr[atoi(filename + 6) - 1 + SOUND_INDEX_BASE]);
- } else if (_game & GF_TALKIE) {
+ } else if (getFeatures() & GF_TALKIE) {
memcpy(filename, "SFXXXX", 6);
_sound->readSfxFile(filename);
}
@@ -1528,21 +1440,21 @@ File *SimonEngine::openTablesFile_simon1(const char *filename) {
}
uint SimonEngine::loadTextFile(const char *filename, byte *dst) {
- if (_game & GF_OLD_BUNDLE)
+ if (getFeatures() & GF_OLD_BUNDLE)
return loadTextFile_simon1(filename, dst);
else
return loadTextFile_gme(filename, dst);
}
File *SimonEngine::openTablesFile(const char *filename) {
- if (_game & GF_OLD_BUNDLE)
+ if (getFeatures() & GF_OLD_BUNDLE)
return openTablesFile_simon1(filename);
else
return openTablesFile_gme(filename);
}
void SimonEngine::closeTablesFile(File *in) {
- if (_game & GF_OLD_BUNDLE) {
+ if (getFeatures() & GF_OLD_BUNDLE) {
in->close();
delete in;
}
@@ -1675,7 +1587,7 @@ void SimonEngine::o_setup_cond_c() {
void SimonEngine::setup_cond_c_helper() {
HitArea *last;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
_mouseCursor = 0;
if (_hitAreaUnk4 != 999) {
_mouseCursor = 9;
@@ -1788,7 +1700,7 @@ void SimonEngine::handle_mouse_moved() {
hitarea_proc_1();
}
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (_bitArray[4] & 0x8000) {
if (!_vgaVar9) {
if (_mouseX >= 630 / 2 || _mouseX < 9)
@@ -1842,7 +1754,7 @@ void SimonEngine::drawIconArray(uint fcs_index, Item *item_ptr, int unk1, int un
fcs_ptr = _windowArray[fcs_index & 7];
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
width_div_3 = fcs_ptr->width / 3;
height_div_3 = fcs_ptr->height / 3;
} else {
@@ -1871,7 +1783,7 @@ void SimonEngine::drawIconArray(uint fcs_index, Item *item_ptr, int unk1, int un
num_sibs_with_flag = 0;
while (item_ptr && width_div_3 > num_sibs_with_flag) {
if ((unk2 == 0 || item_ptr->classFlags & unk2) && has_item_childflag_0x10(item_ptr))
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
num_sibs_with_flag++;
} else {
num_sibs_with_flag += 20;
@@ -1895,7 +1807,7 @@ void SimonEngine::drawIconArray(uint fcs_index, Item *item_ptr, int unk1, int un
if ((unk2 == 0 || item_ptr->classFlags & unk2) && has_item_childflag_0x10(item_ptr)) {
if (item_again == false) {
fcs_ptr->fcs_data->e[k].item = item_ptr;
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
draw_icon_c(fcs_ptr, item_get_icon_number(item_ptr), x_pos * 3, y_pos);
fcs_ptr->fcs_data->e[k].hit_area =
setup_icon_hit_area(fcs_ptr, x_pos * 3, y_pos,
@@ -1910,12 +1822,12 @@ void SimonEngine::drawIconArray(uint fcs_index, Item *item_ptr, int unk1, int un
fcs_ptr->fcs_data->e[k].item = NULL;
j = 1;
}
- x_pos += (_game & GF_SIMON2) ? 20 : 1;
+ x_pos += (getGameType() == GType_SIMON2) ? 20 : 1;
if (x_pos >= width_div_3) {
x_pos = 0;
- y_pos += (_game & GF_SIMON2) ? 20 : 1;
+ y_pos += (getGameType() == GType_SIMON2) ? 20 : 1;
if (y_pos >= height_div_3)
item_again = true;
}
@@ -1942,7 +1854,7 @@ void SimonEngine::setup_hit_areas(FillOrCopyStruct *fcs, uint fcs_index) {
ha = findEmptyHitArea();
_scrollUpHitArea = ha - _hitAreas;
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
ha->x = 308;
ha->y = 149;
ha->width = 12;
@@ -1967,7 +1879,7 @@ void SimonEngine::setup_hit_areas(FillOrCopyStruct *fcs, uint fcs_index) {
ha = findEmptyHitArea();
_scrollDownHitArea = ha - _hitAreas;
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
ha->x = 308;
ha->y = 176;
ha->width = 12;
@@ -2020,12 +1932,12 @@ void SimonEngine::f10_key() {
_lockWord |= 0x8000;
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
color = 236;
else
color = 225;
- uint limit = (_game & GF_SIMON2) ? 200 : 134;
+ uint limit = (getGameType() == GType_SIMON2) ? 200 : 134;
for (int i = 0; i < 5; i++) {
ha = _hitAreas;
@@ -2050,7 +1962,7 @@ void SimonEngine::f10_key() {
continue;
}
- if (ha->y >= limit || ((_game & GF_SIMON2) && ha->y >= _vgaVar8))
+ if (ha->y >= limit || ((getGameType() == GType_SIMON2) && ha->y >= _vgaVar8))
continue;
y_ = (ha->height / 2) - 4 + ha->y;
@@ -2187,7 +2099,7 @@ startOver:
void SimonEngine::hitarea_stuff_helper() {
time_t cur_time;
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
uint subr_id = _variableArray[254];
if (subr_id != 0) {
Subroutine *sub = getSubroutineByID(subr_id);
@@ -2308,7 +2220,7 @@ void SimonEngine::handle_verb_clicked(uint verb) {
if (sub)
startSubroutine(sub);
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
_runScriptReturn1 = false;
startUp_helper_2();
@@ -2341,14 +2253,14 @@ void SimonEngine::o_print_str() {
if (string_id != 0xFFFF)
string_ptr = getStringPtrByID(string_id);
- if (_game & GF_TALKIE)
+ if (getFeatures() & GF_TALKIE)
speech_id = (uint16)getNextWord();
tl = getTextLocation(vgaSpriteId);
if (_speech && speech_id != 0)
talk_with_speech(speech_id, vgaSpriteId);
- if ((_game & GF_SIMON2) && (_game & GF_TALKIE) && speech_id == 0)
+ if ((getGameType() == GType_SIMON2) && (getFeatures() & GF_TALKIE) && speech_id == 0)
o_kill_sprite_simon2(2, vgaSpriteId + 2);
if (string_ptr != NULL && (speech_id == 0 || _subtitles))
@@ -2509,7 +2421,7 @@ void SimonEngine::set_video_mode_internal(uint mode, uint vga_res_id) {
if (vga_res_id == 0) {
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
_unkPalFlag = true;
} else {
_dxUse3Or4ForLock = true;
@@ -2535,7 +2447,7 @@ void SimonEngine::set_video_mode_internal(uint mode, uint vga_res_id) {
bb = _curVgaFile1;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
b = bb + READ_LE_UINT16(&((VgaFileHeader_Feeble *) bb)->hdr2_start);
//count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageCount);
b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
@@ -2551,7 +2463,7 @@ void SimonEngine::set_video_mode_internal(uint mode, uint vga_res_id) {
b += sizeof(ImageHeader_Simon);
}
- if ((_game & GF_SIMON1) && vga_res_id == 16300) {
+ if ((getGameType() == GType_SIMON1) && vga_res_id == 16300) {
dx_clear_attached_from_top(134);
_usePaletteDelay = true;
} else {
@@ -2566,7 +2478,7 @@ void SimonEngine::set_video_mode_internal(uint mode, uint vga_res_id) {
vc_ptr_org = _vcPtr;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
_vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
} else {
_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
@@ -2577,7 +2489,7 @@ void SimonEngine::set_video_mode_internal(uint mode, uint vga_res_id) {
_vcPtr = vc_ptr_org;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (!_dxUse3Or4ForLock) {
num_lines = _windowNum == 4 ? 134 : 200;
_vgaVar8 = num_lines;
@@ -2603,7 +2515,7 @@ void SimonEngine::set_video_mode_internal(uint mode, uint vga_res_id) {
_lockWord &= ~0x20;
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
if (_unkPalFlag) {
_unkPalFlag = false;
while (_paletteColorCount != 0) {
@@ -2663,7 +2575,7 @@ void SimonEngine::expire_vga_timers() {
_nextVgaTimerToProcess = vte + 1;
delete_vga_timer(vte);
- if ((_game & GF_SIMON2) && script_ptr == NULL) {
+ if ((getGameType() == GType_SIMON2) && script_ptr == NULL) {
// special scroll timer
scroll_timeout();
} else {
@@ -2724,7 +2636,7 @@ void SimonEngine::add_vga_timer(uint num, const byte *code_ptr, uint cur_sprite,
// caused several glitches in this scene.
// We work around the problem by correcting the code_ptr for sprite
// 200 in this scene, if it is wrong.
- if (!(_game & GF_SIMON2) && (_language == 2) &&
+ if (!(getGameType() == GType_SIMON2) && (_language == 2) &&
(code_ptr - _vgaBufferPointers[cur_file].vgaFile1 == 4) && (cur_sprite == 200) && (cur_file == 2))
code_ptr += 0x66;
@@ -2742,7 +2654,7 @@ void SimonEngine::add_vga_timer(uint num, const byte *code_ptr, uint cur_sprite,
}
void SimonEngine::o_force_unlock() {
- if (_game & GF_SIMON2 && _bitArray[4] & 0x8000)
+ if (getGameType() == GType_SIMON2 && _bitArray[4] & 0x8000)
_mouseCursor = 0;
_lockCounter = 0;
}
@@ -2759,7 +2671,7 @@ void SimonEngine::o_wait_for_vga(uint a) {
_exitCutscene = false;
_skipSpeech = false;
while (_vgaWaitFor != 0) {
- if (_skipSpeech && _game & GF_SIMON2) {
+ if (_skipSpeech && getGameType() == GType_SIMON2) {
if (_vgaWaitFor == 200 && !vc_get_bit(14)) {
skip_speech();
break;
@@ -2775,7 +2687,7 @@ void SimonEngine::o_wait_for_vga(uint a) {
delay(10);
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (_timer1 >= 1000) {
warning("wait timed out");
break;
@@ -2808,7 +2720,7 @@ void SimonEngine::timer_vga_sprites() {
if (_paletteFlag == 2)
_paletteFlag = 1;
- if (_game & GF_SIMON2 && _scrollFlag) {
+ if (getGameType() == GType_SIMON2 && _scrollFlag) {
timer_vga_sprites_helper();
}
@@ -2828,7 +2740,7 @@ void SimonEngine::timer_vga_sprites() {
params[2] = readUint16Wrapper(&vsp->x);
params[3] = readUint16Wrapper(&vsp->y);
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
*(byte *)(&params[4]) = (byte)vsp->flags;
} else {
params[4] = READ_BE_UINT16(&vsp->flags);
@@ -3095,11 +3007,11 @@ void SimonEngine::o_pathfind(int x, int y, uint var_1, uint var_2) {
uint x_diff, y_diff;
uint best_i = 0, best_j = 0, best_dist = 0xFFFFFFFF;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
x += _scrollX * 8;
}
- int end = (_game == GAME_FEEBLEFILES) ? 9999 : 999;
+ int end = (getGameType() == GType_FF) ? 9999 : 999;
prev_i = 21 - _variableArray[12];
for (i = 20; i != 0; --i) {
p = (const uint16 *)_pathFindArray[20 - i];
@@ -3153,7 +3065,7 @@ void SimonEngine::removeIconArray(uint fcs_index) {
if (fcs->fcs_data->downArrow != -1) {
delete_hitarea_by_index(fcs->fcs_data->downArrow);
- if (!(_game & GF_SIMON2))
+ if (!(getGameType() == GType_SIMON2))
fcs_unk_5(fcs, fcs_index);
}
@@ -3197,7 +3109,7 @@ void SimonEngine::video_fill_or_copy_from_3_to_2(FillOrCopyStruct *fcs) {
void SimonEngine::copy_img_from_3_to_2(FillOrCopyStruct *fcs) {
_lockWord |= 0x8000;
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
dx_copy_rgn_from_3_to_2(fcs->y + fcs->height * 8 + ((fcs == _windowArray[2]) ? 1 : 0), (fcs->x + fcs->width) * 8, fcs->y, fcs->x * 8);
} else {
if (_vgaVar6 && _windowArray[2] == fcs) {
@@ -3233,7 +3145,7 @@ void SimonEngine::video_erase(FillOrCopyStruct *fcs) {
VgaSprite *SimonEngine::find_cur_sprite() {
VgaSprite *vsp = _vgaSprites;
while (vsp->id) {
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (vsp->id == _vgaCurSpriteId && vsp->fileId == _vgaCurFileId)
break;
} else {
@@ -3248,7 +3160,7 @@ VgaSprite *SimonEngine::find_cur_sprite() {
bool SimonEngine::isSpriteLoaded(uint16 id, uint16 fileId) {
VgaSprite *vsp = _vgaSprites;
while (vsp->id) {
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (vsp->id == id && vsp->fileId == fileId)
return true;
} else {
@@ -3266,7 +3178,7 @@ void SimonEngine::processSpecialKeys() {
_exitCutscene = true;
break;
case 59: // F1
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
vc_write_var(5, 50);
} else {
vc_write_var(5, 40);
@@ -3274,7 +3186,7 @@ void SimonEngine::processSpecialKeys() {
vc_write_var(86, 0);
break;
case 60: // F2
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
vc_write_var(5, 75);
} else {
vc_write_var(5, 60);
@@ -3282,7 +3194,7 @@ void SimonEngine::processSpecialKeys() {
vc_write_var(86, 1);
break;
case 61: // F3
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
vc_write_var(5, 125);
} else {
vc_write_var(5, 100);
@@ -3290,19 +3202,19 @@ void SimonEngine::processSpecialKeys() {
vc_write_var(86, 2);
break;
case 63: // F5
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
_exitCutscene = true;
break;
case 'p':
pause();
break;
case 't':
- if ((_game & GF_SIMON2 && _game & GF_TALKIE) || ( _game & GF_TALKIE && _language > 1))
+ if ((getGameType() == GType_SIMON2 && getFeatures() & GF_TALKIE) || ( getFeatures() & GF_TALKIE && _language > 1))
if (_speech)
_subtitles ^= 1;
break;
case 'v':
- if ((_game & GF_SIMON2) && (_game & GF_TALKIE))
+ if ((getGameType() == GType_SIMON2) && (getFeatures() & GF_TALKIE))
if (_subtitles)
_speech ^= 1;
case '+':
@@ -3315,7 +3227,7 @@ void SimonEngine::processSpecialKeys() {
midi.pause(_musicPaused ^= 1);
break;
case 's':
- if (_game == GAME_SIMON1DOS)
+ if (getGameId() == GID_SIMON1DOS)
midi._enable_sfx ^= 1;
else
_sound->effectsPause(_effectsPaused ^= 1);
@@ -3440,7 +3352,7 @@ void SimonEngine::loadSprite(uint windowNum, uint fileId, uint vgaSpriteId, uint
vsp->image = 0;
vsp->palette = palette;
vsp->id = vgaSpriteId;
- if (_game & GF_SIMON1)
+ if (getGameType() == GType_SIMON1)
vsp->fileId = fileId = vgaSpriteId / 100;
else
vsp->fileId = fileId;
@@ -3456,7 +3368,7 @@ void SimonEngine::loadSprite(uint windowNum, uint fileId, uint vgaSpriteId, uint
}
pp = _curVgaFile1;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
p = pp + READ_LE_UINT16(&((VgaFileHeader_Feeble *) pp)->hdr2_start);
count = READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationCount);
p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
@@ -3467,7 +3379,7 @@ void SimonEngine::loadSprite(uint windowNum, uint fileId, uint vgaSpriteId, uint
}
for (;;) {
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
if (READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->id) == vgaSpriteId) {
if (_startVgaScript)
dump_vga_script(pp + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), fileId, vgaSpriteId);
@@ -3497,7 +3409,7 @@ void SimonEngine::loadSprite(uint windowNum, uint fileId, uint vgaSpriteId, uint
}
void SimonEngine::talk_with_speech(uint speech_id, uint vgaSpriteId) {
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
if (speech_id == 9999) {
if (_subtitles)
return;
@@ -3559,7 +3471,7 @@ void SimonEngine::talk_with_text(uint vgaSpriteId, uint color, const char *strin
lettersPerRowJustified = stringLength / (stringLength / lettersPerRow + 1) + 1;
talkDelay = (stringLength + 3) / 3;
- if ((_game & GF_SIMON1) && (_game & GF_TALKIE)) {
+ if ((getGameType() == GType_SIMON1) && (getFeatures() & GF_TALKIE)) {
if (_variableArray[141] == 0)
_variableArray[141] = 9;
_variableArray[85] = _variableArray[141] * talkDelay;
@@ -3605,13 +3517,13 @@ void SimonEngine::talk_with_text(uint vgaSpriteId, uint color, const char *strin
}
*(convertedString2 - 1) = '\0';
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
o_kill_sprite_simon2(2, vgaSpriteId);
else
o_kill_sprite_simon1(vgaSpriteId + 199);
color = color * 3 + 192;
- if (_game & GF_AMIGA)
+ if (getPlatform() == Common::kPlatformAmiga)
render_string_amiga(vgaSpriteId, color, width, height, convertedString);
else
render_string(vgaSpriteId, color, width, height, convertedString);
@@ -3624,7 +3536,7 @@ void SimonEngine::talk_with_text(uint vgaSpriteId, uint color, const char *strin
if (y < 2)
y = 2;
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
loadSprite(b, 2, vgaSpriteId, x, y, 12);
else
loadSprite(b, 2, vgaSpriteId + 199, x, y, 12);
@@ -3748,7 +3660,7 @@ static bool decrunch_file_amiga (byte *src, byte *dst, uint32 size) {
#undef SD_TYPE_MATCH
void SimonEngine::read_vga_from_datfile_1(uint vga_id) {
- if (_game & GF_OLD_BUNDLE) {
+ if (getFeatures() & GF_OLD_BUNDLE) {
File in;
char buf[15];
uint32 size;
@@ -3757,10 +3669,11 @@ void SimonEngine::read_vga_from_datfile_1(uint vga_id) {
if (vga_id == 328)
vga_id = 119;
- if (_game == GAME_SIMON1CD32) {
- sprintf(buf, "0%d.out", vga_id);
- } else if (_game == GAME_SIMON1AMIGA) {
- sprintf(buf, "0%d.pkd", vga_id);
+ if (getPlatform() == Common::kPlatformAmiga) {
+ if (getFeatures() & GF_TALKIE)
+ sprintf(buf, "0%d.out", vga_id);
+ else
+ sprintf(buf, "0%d.pkd", vga_id);
} else {
sprintf(buf, "0%d.VGA", vga_id);
}
@@ -3770,7 +3683,7 @@ void SimonEngine::read_vga_from_datfile_1(uint vga_id) {
error("read_vga_from_datfile_1: can't open %s", buf);
size = in.size();
- if (_game == GAME_SIMON1AMIGA) {
+ if (getPlatform() == Common::kPlatformAmiga) {
byte *buffer = new byte[size];
if (in.read(buffer, size) != size)
error("read_vga_from_datfile_1: read failed");
@@ -3796,16 +3709,17 @@ byte *SimonEngine::read_vga_from_datfile_2(uint id) {
// is base on: 2 (lines) * 320 (screen width) * 10 (textheight) -- olki
int extraBuffer = (id == 5 ? 6400 : 0);
- if (_game & GF_OLD_BUNDLE) {
+ if (getFeatures() & GF_OLD_BUNDLE) {
File in;
char buf[15];
uint32 size;
byte *dst;
- if (_game == GAME_SIMON1CD32) {
- sprintf(buf, "%.3d%d.out", id / 2, (id & 1) + 1);
- } else if (_game == GAME_SIMON1AMIGA) {
- sprintf(buf, "%.3d%d.pkd", id / 2, (id & 1) + 1);
+ if (getPlatform() == Common::kPlatformAmiga) {
+ if (getFeatures() & GF_TALKIE)
+ sprintf(buf, "%.3d%d.out", id / 2, (id & 1) + 1);
+ else
+ sprintf(buf, "%.3d%d.pkd", id / 2, (id & 1) + 1);
} else {
sprintf(buf, "%.3d%d.VGA", id / 2, (id & 1) + 1);
}
@@ -3815,7 +3729,7 @@ byte *SimonEngine::read_vga_from_datfile_2(uint id) {
error("read_vga_from_datfile_2: can't open %s", buf);
size = in.size();
- if (_game == GAME_SIMON1AMIGA) {
+ if (getPlatform() == Common::kPlatformAmiga) {
byte *buffer = new byte[size];
if (in.read(buffer, size) != size)
error("read_vga_from_datfile_2: read failed");
@@ -3849,7 +3763,7 @@ void SimonEngine::resfile_read(void *dst, uint32 offs, uint32 size) {
}
void SimonEngine::openGameFile() {
- if (!(_game & GF_OLD_BUNDLE)) {
+ if (!(getFeatures() & GF_OLD_BUNDLE)) {
_gameFile = new File();
_gameFile->open(gss->gme_filename);
@@ -3869,7 +3783,7 @@ void SimonEngine::openGameFile() {
#endif
}
- if (_game != GAME_FEEBLEFILES)
+ if (getGameType() != GType_FF)
loadIconFile();
vc34_setMouseOff();
@@ -3969,7 +3883,7 @@ void SimonEngine::dx_update_screen_and_palette() {
memcpy(_sdl_buf_attached, _sdl_buf, _screenWidth * _screenHeight);
if (_paletteColorCount != 0) {
- if (!(_game & GF_SIMON2) && _usePaletteDelay) {
+ if (!(getGameType() == GType_SIMON2) && _usePaletteDelay) {
delay(100);
_usePaletteDelay = false;
}
@@ -4062,11 +3976,11 @@ int SimonEngine::go() {
setup_vga_file_buf_pointers();
- _sound = new Sound(_game, gss, _mixer);
+ _sound = new Sound(this, gss, _mixer);
_debugger = new Debugger(this);
if (ConfMan.hasKey("sfx_mute") && ConfMan.getBool("sfx_mute") == 1) {
- if (_game == GAME_SIMON1DOS)
+ if (getGameId() == GID_SIMON1DOS)
midi._enable_sfx ^= 1;
else
_sound->effectsPause(_effectsPaused ^= 1);
@@ -4095,9 +4009,9 @@ int SimonEngine::go() {
if (gDebugLevel == 5)
_startVgaScript = true;
- if (_game & GF_TALKIE) {
+ if (getFeatures() & GF_TALKIE) {
// English and German versions of Simon the Sorcerer 1 don't have full subtitles
- if (!(_game & GF_SIMON2) && _language < 2)
+ if (!(getGameType() == GType_SIMON2) && _language < 2)
_subtitles = false;
} else {
_subtitles = true;
@@ -4140,7 +4054,7 @@ void SimonEngine::delay(uint amount) {
if (_fastMode)
vga_period = 10;
- else if (_game & GF_SIMON2)
+ else if (getGameType() == GType_SIMON2)
vga_period = 45 * _speed;
else
vga_period = 50 * _speed;
@@ -4207,7 +4121,7 @@ void SimonEngine::delay(uint amount) {
#endif
break;
case OSystem::EVENT_RBUTTONDOWN:
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
_skipSpeech = true;
else
_exitCutscene = true;
@@ -4237,14 +4151,14 @@ void SimonEngine::delay(uint amount) {
void SimonEngine::loadMusic (uint music) {
char buf[4];
- if (_game & GF_AMIGA) {
- if (_game != GAME_SIMON1CD32) {
+ if (getPlatform() == Common::kPlatformAmiga) {
+ if (!(getFeatures() & GF_TALKIE)) {
// TODO Add support for decruncher
debug(5,"loadMusic - Decrunch %dtune attempt", music);
}
// TODO Add Protracker support for simon1amiga/cd32
debug(5,"playMusic - Load %dtune attempt", music);
- } else if (_game & GF_SIMON2) { // Simon 2 music
+ } else if (getGameType() == GType_SIMON2) { // Simon 2 music
midi.stop();
_gameFile->seek(_gameOffsetsPtr[MUSIC_INDEX_BASE + music - 1], SEEK_SET);
_gameFile->read(buf, 4);
@@ -4258,11 +4172,11 @@ void SimonEngine::loadMusic (uint music) {
_lastMusicPlayed = music;
_nextMusicToPlay = -1;
- } else if (_game & GF_SIMON1) { // Simon 1 music
+ } else if (getGameType() == GType_SIMON1) { // Simon 1 music
midi.stop();
midi.setLoop (true); // Must do this BEFORE loading music. (GMF may have its own override.)
- if (_game & GF_TALKIE) {
+ if (getFeatures() & GF_TALKIE) {
// FIXME: The very last music resource, a cymbal crash for when the
// two demons crash into each other, should NOT be looped like the
// other music tracks. In simon1dos/talkie the GMF resource includes
@@ -4290,7 +4204,7 @@ void SimonEngine::loadMusic (uint music) {
warning("Can't load music from '%s'", filename);
return;
}
- if (_game & GF_DEMO)
+ if (getGameId() == GID_SIMON1DEMO)
midi.loadS1D (&f);
else
midi.loadSMF (&f, music);
diff --git a/simon/simon.h b/simon/simon.h
index 35b1f93c17..3f36ca5fba 100644
--- a/simon/simon.h
+++ b/simon/simon.h
@@ -24,6 +24,8 @@
#include <stdio.h>
#include "base/engine.h"
+#include "base/gameDetector.h"
+#include "base/plugins.h"
#include "common/util.h"
#include "simon/midi.h"
#include "simon/sound.h"
@@ -101,6 +103,36 @@ struct VgaTimerEntry {
VgaTimerEntry() { memset(this, 0, sizeof(*this)); }
};
+enum SimonTypes {
+ GType_SIMON1,
+ GType_SIMON2,
+ GType_FF
+};
+
+struct GameFileDescription {
+ const char *fileName;
+ uint16 fileType;
+};
+
+struct GameDescription {
+ const char *name;
+ SimonTypes gameType;
+ GameIds gameId;
+ const char *title;
+ int filesCount;
+ GameFileDescription *filesDescriptions;
+ uint32 features;
+ Common::Language language;
+ Common::Platform platform;
+
+ GameSettings toGameSettings() const {
+ GameSettings dummy = { name, title, features };
+ return dummy;
+ }
+};
+
+DetectedGameList GAME_ProbeGame(const FSList &fslist, int **matches = NULL);
+
struct GameSpecificSettings;
class Debugger;
@@ -113,7 +145,18 @@ class SimonEngine : public Engine {
typedef void (SimonEngine::*VgaOpcodeProc) ();
void setupVgaOpcodes();
const VgaOpcodeProc *_vga_opcode_table;
-
+
+public:
+ GameDescription *_gameDescription;
+
+ bool initGame(void);
+
+ int getGameId() const { return _gameDescription->gameId; }
+ int getGameType() const { return _gameDescription->gameType; }
+ uint32 getFeatures() const { return _gameDescription->features; }
+ Common::Language getLanguage() const { return _gameDescription->language; }
+ Common::Platform getPlatform() const { return _gameDescription->platform; }
+
protected:
void playSting(uint a);
diff --git a/simon/sound.cpp b/simon/sound.cpp
index f0efaab92a..22e4ea9bb5 100644
--- a/simon/sound.cpp
+++ b/simon/sound.cpp
@@ -22,6 +22,7 @@
#include "common/file.h"
#include "common/util.h"
+#include "simon/simon.h"
#include "simon/sound.h"
#include "sound/flac.h"
@@ -231,8 +232,8 @@ void FlacSound::playSound(uint sound, Audio::SoundHandle *handle, byte flags)
}
#endif
-Sound::Sound(const byte game, const GameSpecificSettings *gss, Audio::Mixer *mixer)
- : _game(game), _mixer(mixer) {
+Sound::Sound(SimonEngine *vm, const GameSpecificSettings *gss, Audio::Mixer *mixer)
+ : _vm(vm), _mixer(mixer) {
_voice = 0;
_effects = 0;
@@ -247,8 +248,8 @@ Sound::Sound(const byte game, const GameSpecificSettings *gss, Audio::Mixer *mix
_hasVoiceFile = false;
_ambientPlaying = 0;
- // simon1cd32 uses separate speech files
- if (!(_game & GF_TALKIE) || (_game == GAME_SIMON1CD32))
+ // SIMON1CD32 uses separate speech files
+ if (!(_vm->getFeatures() & GF_TALKIE) || (_vm->getGameId() == GID_SIMON1CD32))
return;
File *file = new File();
@@ -280,7 +281,7 @@ Sound::Sound(const byte game, const GameSpecificSettings *gss, Audio::Mixer *mix
}
}
#endif
- if (!_hasVoiceFile && (_game & GF_SIMON2)) {
+ if (!_hasVoiceFile && _vm->getGameType() == GType_SIMON2) {
// for simon2 mac/amiga, only read index file
file->open("voices.idx");
if (file->isOpen() == true) {
@@ -312,7 +313,7 @@ Sound::Sound(const byte game, const GameSpecificSettings *gss, Audio::Mixer *mix
}
}
- if ((_game & GF_SIMON1) && (_game & GF_TALKIE)) {
+ if ((_vm->getGameType() == GType_SIMON1) && (_vm->getFeatures() & GF_TALKIE)) {
file = new File();
#ifdef USE_MAD
if (!_hasEffectsFile && gss->mp3_effects_filename && gss->mp3_effects_filename[0]) {
@@ -383,7 +384,7 @@ void Sound::readSfxFile(const char *filename) {
}
delete _effects;
- if (_game == GAME_SIMON1CD32) {
+ if (_vm->getGameId() == GID_SIMON1CD32) {
_effects = new VocSound(_mixer, file, 0, SOUND_BIG_ENDIAN);
} else
_effects = new WavSound(_mixer, file);
@@ -392,7 +393,7 @@ void Sound::readSfxFile(const char *filename) {
void Sound::loadSfxTable(File *gameFile, uint32 base) {
stopAll();
- if (_game & GF_WIN)
+ if (_vm->getPlatform() == Common::kPlatformWindows)
_effects = new WavSound(_mixer, gameFile, base);
else
_effects = new VocSound(_mixer, gameFile, base);
@@ -444,7 +445,7 @@ void Sound::playVoice(uint sound) {
return;
_mixer->stopHandle(_voiceHandle);
- _voice->playSound(sound, &_voiceHandle, (_game == GAME_SIMON1CD32) ? 0 : Audio::Mixer::FLAG_UNSIGNED);
+ _voice->playSound(sound, &_voiceHandle, (_vm->getGameId() == GID_SIMON1CD32) ? 0 : Audio::Mixer::FLAG_UNSIGNED);
}
void Sound::playEffects(uint sound) {
@@ -454,7 +455,7 @@ void Sound::playEffects(uint sound) {
if (_effectsPaused)
return;
- _effects->playSound(sound, &_effectsHandle, (_game == GAME_SIMON1CD32) ? 0 : Audio::Mixer::FLAG_UNSIGNED);
+ _effects->playSound(sound, &_effectsHandle, (_vm->getGameId() == GID_SIMON1CD32) ? 0 : Audio::Mixer::FLAG_UNSIGNED);
}
void Sound::playAmbient(uint sound) {
diff --git a/simon/sound.h b/simon/sound.h
index 60cb406b32..efda01f122 100644
--- a/simon/sound.h
+++ b/simon/sound.h
@@ -28,9 +28,11 @@ namespace Simon {
class BaseSound;
+class SimonEngine;
+
class Sound {
private:
- byte _game;
+ SimonEngine *_vm;
Audio::Mixer *_mixer;
@@ -53,7 +55,7 @@ private:
uint _ambientPlaying;
public:
- Sound(const byte game, const GameSpecificSettings *gss, Audio::Mixer *mixer);
+ Sound(SimonEngine *vm, const GameSpecificSettings *gss, Audio::Mixer *mixer);
~Sound();
void readSfxFile(const char *filename);
diff --git a/simon/verb.cpp b/simon/verb.cpp
index e5b6153425..2a3be4b6eb 100644
--- a/simon/verb.cpp
+++ b/simon/verb.cpp
@@ -191,7 +191,7 @@ void SimonEngine::defocusHitarea() {
HitArea *last;
HitArea *ha;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (_bitArray[4] & 0x8000) {
o_unk_120(202);
_lastHitArea2Ptr = NULL;
@@ -265,7 +265,7 @@ void SimonEngine::showActionString(uint x, const byte *string) {
void SimonEngine::hitareaChangedHelper() {
FillOrCopyStruct *fcs;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (_bitArray[4] & 0x8000)
return;
}
@@ -362,7 +362,7 @@ void SimonEngine::hitarea_proc_1() {
uint id;
HitArea *ha;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
id = 2;
if (!(_bitArray[4] & 0x8000))
id = (_mouseY >= 136) ? 102 : 101;
@@ -391,7 +391,7 @@ void SimonEngine::handle_verb_hitarea(HitArea *ha) {
if (ha == tmp)
return;
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
if (tmp != NULL) {
tmp->flags |= 8;
video_toggle_colors(tmp, 0xd5, 0xd0, 0xd5, 0xA);
@@ -414,7 +414,7 @@ void SimonEngine::handle_verb_hitarea(HitArea *ha) {
}
void SimonEngine::hitarea_leave(HitArea *ha) {
- if (!(_game & GF_SIMON2)) {
+ if (!(getGameType() == GType_SIMON2)) {
video_toggle_colors(ha, 0xdf, 0xd5, 0xda, 5);
} else {
video_toggle_colors(ha, 0xe7, 0xe5, 0xe6, 1);
@@ -458,7 +458,7 @@ void SimonEngine::setup_hitarea_from_pos(uint x, uint y, uint mode) {
uint16 x_ = x;
const uint16 y_ = y;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (_bitArray[4] & 0x8000 || y < 134) {
x_ += _scrollX * 8;
}
@@ -528,7 +528,7 @@ bool SimonEngine::hitarea_proc_2(uint a) {
uint x;
const byte *string_ptr;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (_bitArray[4] & 0x8000) {
Subroutine *sub;
_variableArray[84] = a;
diff --git a/simon/vga.cpp b/simon/vga.cpp
index 71fb917d3c..64c356114f 100644
--- a/simon/vga.cpp
+++ b/simon/vga.cpp
@@ -134,7 +134,7 @@ void SimonEngine::run_vga_script() {
}
}
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
opcode = READ_BE_UINT16(_vcPtr);
_vcPtr += 2;
} else {
@@ -208,10 +208,10 @@ void SimonEngine::vc_skip_next_instruction() {
6, 4, 2, 6, 0
};
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
uint opcode = vc_read_next_byte();
_vcPtr += opcode_param_len_feeblefiles[opcode];
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
uint opcode = vc_read_next_byte();
_vcPtr += opcode_param_len_simon2[opcode];
} else {
@@ -279,7 +279,7 @@ void SimonEngine::vc2_call() {
bb = _curVgaFile1;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
b = bb + READ_LE_UINT16(&((VgaFileHeader_Feeble *) bb)->hdr2_start);
b = bb + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) b)->imageTable);
@@ -295,7 +295,7 @@ void SimonEngine::vc2_call() {
vc_ptr_org = _vcPtr;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
_vcPtr = _curVgaFile1 + READ_LE_UINT16(&((ImageHeader_Feeble *) b)->scriptOffs);
} else {
_vcPtr = _curVgaFile1 + READ_BE_UINT16(&((ImageHeader_Simon *) b)->scriptOffs);
@@ -320,7 +320,7 @@ void SimonEngine::vc3_loadSprite() {
windowNum = vc_read_next_word(); /* 0 */
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
fileId = vc_read_next_word(); /* 0 */
vgaSpriteId = vc_read_next_word(); /* 2 */
} else {
@@ -365,7 +365,7 @@ void SimonEngine::vc3_loadSprite() {
}
pp = _curVgaFile1;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
p = pp + READ_LE_UINT16(&((VgaFileHeader_Feeble *) pp)->hdr2_start);
p = pp + READ_LE_UINT16(&((VgaFileHeader2_Feeble *) p)->animationTable);
@@ -400,7 +400,7 @@ void SimonEngine::vc3_loadSprite() {
#endif
if (_startVgaScript) {
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
dump_vga_script(_curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble*)p)->scriptOffs), res, vgaSpriteId);
} else {
dump_vga_script(_curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon*)p)->scriptOffs), res, vgaSpriteId);
@@ -408,7 +408,7 @@ void SimonEngine::vc3_loadSprite() {
}
}
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
add_vga_timer(VGA_DELAY_BASE, _curVgaFile1 + READ_LE_UINT16(&((AnimationHeader_Feeble *) p)->scriptOffs), vgaSpriteId, res);
} else {
add_vga_timer(VGA_DELAY_BASE, _curVgaFile1 + READ_BE_UINT16(&((AnimationHeader_Simon *) p)->scriptOffs), vgaSpriteId, res);
@@ -666,7 +666,7 @@ void SimonEngine::vc10_draw() {
if (state.image == 0)
return;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
state.palette = (_vcPtr[0] * 16);
} else {
state.palette = (_vcPtr[1] * 16);
@@ -674,12 +674,12 @@ void SimonEngine::vc10_draw() {
_vcPtr += 2;
state.x = (int16)vc_read_next_word();
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
state.x -= _scrollX;
}
state.y = (int16)vc_read_next_word();
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
state.flags = vc_read_next_word();
} else {
state.flags = vc_read_next_byte();
@@ -691,7 +691,7 @@ void SimonEngine::vc10_draw() {
p2 = _curVgaFile2 + state.image * 8;
state.depack_src = _curVgaFile2 + READ_BE_UINT32(p2);
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
state.depack_src = _curVgaFile2 + READ_LE_UINT32(p2);
width = READ_LE_UINT16(p2 + 6);
height = READ_LE_UINT16(p2 + 4) & 0x7FFF;
@@ -722,8 +722,8 @@ void SimonEngine::vc10_draw() {
}
}
- maxWidth = (_game == GAME_FEEBLEFILES) ? 640 : 20;
- if (_game & GF_SIMON2 && width > maxWidth) {
+ maxWidth = (getGameType() == GType_FF) ? 640 : 20;
+ if (getGameType() == GType_SIMON2 && width > maxWidth) {
const byte *src;
byte *dst;
uint w;
@@ -752,7 +752,7 @@ void SimonEngine::vc10_draw() {
return;
}
- if (_game != GAME_FEEBLEFILES) {
+ if (getGameType() != GType_FF) {
if (state.flags & 0x10) {
state.depack_src = vc10_uncompressFlip(state.depack_src, width, height);
} else if (state.flags & 1) {
@@ -778,7 +778,7 @@ void SimonEngine::vc10_draw() {
}
state.x = cur;
- maxWidth = (_game == GAME_FEEBLEFILES) ? 640 : (vlut[2] * 2);
+ maxWidth = (getGameType() == GType_FF) ? 640 : (vlut[2] * 2);
cur += state.draw_width - maxWidth;
if (cur > 0) {
do {
@@ -797,7 +797,7 @@ void SimonEngine::vc10_draw() {
}
state.y = cur;
- maxHeight = (_game == GAME_FEEBLEFILES) ? 480 : vlut[3];
+ maxHeight = (getGameType() == GType_FF) ? 480 : vlut[3];
cur += state.draw_height - maxHeight;
if (cur > 0) {
do {
@@ -820,7 +820,7 @@ void SimonEngine::vc10_draw() {
uint offs, offs2;
// Allow one section of Simon the Sorcerer 1 introduction to be displayed
// in lower half of screen
- if ((_game & GF_SIMON1) && _subroutine == 2926) {
+ if ((getGameType() == GType_SIMON1) && _subroutine == 2926) {
offs = ((vlut[0]) * 2 + state.x) * 8;
offs2 = (vlut[1] + state.y);
} else {
@@ -850,7 +850,7 @@ void SimonEngine::vc10_draw() {
dst = state.surf_addr + w * 2; /* edi */
h = state.draw_height;
- if ((_game & GF_SIMON1) && vc_get_bit(88)) {
+ if ((getGameType() == GType_SIMON1) && vc_get_bit(88)) {
/* transparency */
do {
if (mask[0] & 0xF0) {
@@ -991,7 +991,7 @@ void SimonEngine::vc10_draw() {
}
/* vc10_helper_4 */
} else {
- if (_game & GF_SIMON2 && state.flags & 0x4 && _bitArray[10] & 0x800) {
+ if (getGameType() == GType_SIMON2 && state.flags & 0x4 && _bitArray[10] & 0x800) {
state.surf_addr = state.surf2_addr;
state.surf_pitch = state.surf2_pitch;
}
@@ -1100,7 +1100,7 @@ void SimonEngine::vc12_delay() {
VgaSprite *vsp = find_cur_sprite();
uint num;
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
num = vc_read_var_or_word();
} else {
num = vc_read_next_byte() * _frameRate;
@@ -1108,7 +1108,7 @@ void SimonEngine::vc12_delay() {
// Work around to allow inventory arrows to be
// shown in some versions of Simon the Sorcerer 1
- if ((_game & GF_SIMON1) && vsp->id == 0x80)
+ if ((getGameType() == GType_SIMON1) && vsp->id == 0x80)
num = 0;
else
num += VGA_DELAY_BASE;
@@ -1167,7 +1167,7 @@ void SimonEngine::vc17_setPathfinderItem() {
uint a = vc_read_next_word();
_pathFindArray[a - 1] = (const uint16 *)_vcPtr;
- int end = (_game == GAME_FEEBLEFILES) ? 9999 : 999;
+ int end = (getGameType() == GType_FF) ? 9999 : 999;
while (readUint16Wrapper(_vcPtr) != end)
_vcPtr += 4;
_vcPtr += 2;
@@ -1199,7 +1199,7 @@ void SimonEngine::vc20_setRepeat() {
void SimonEngine::vc21_endRepeat() {
int16 a = vc_read_next_word();
const byte *tmp = _vcPtr + a;
- if (_game & GF_SIMON2)
+ if (getGameType() == GType_SIMON2)
tmp += 3;
else
tmp += 4;
@@ -1219,7 +1219,7 @@ void SimonEngine::vc22_setSpritePalette() {
uint palSize = 96;
byte *palptr, *src;
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
num = 256;
palSize = 768;
}
@@ -1283,7 +1283,7 @@ void SimonEngine::vc24_setSpriteXY() {
vsp->x += (int16)vc_read_next_word();
vsp->y += (int16)vc_read_next_word();
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
vsp->flags = vc_read_next_word();
} else {
vsp->flags = vc_read_next_byte();
@@ -1321,7 +1321,7 @@ void SimonEngine::vc27_resetSprite() {
vsp = _vgaSprites;
while (vsp->id) {
- if ((_game & GF_SIMON1) && vsp->id == 128) {
+ if ((getGameType() == GType_SIMON1) && vsp->id == 128) {
memcpy(&bak, vsp, sizeof(VgaSprite));
}
vsp->id = 0;
@@ -1339,7 +1339,7 @@ void SimonEngine::vc27_resetSprite() {
vte = _vgaTimerList;
while (vte->delay) {
- if ((_game & GF_SIMON1) && vsp->id == 128) {
+ if ((getGameType() == GType_SIMON1) && vsp->id == 128) {
vte++;
} else {
vte2 = vte;
@@ -1410,7 +1410,7 @@ void SimonEngine::vc36_setWindowImage() {
uint vga_res = vc_read_next_word();
uint windowNum = vc_read_next_word();
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
if (windowNum == 16) {
_copyPartialMode = 2;
} else {
@@ -1443,7 +1443,7 @@ void SimonEngine::vc40() {
uint var = vc_read_next_word();
int16 value = vc_read_var(var) + vc_read_next_word();
- if ((_game & GF_SIMON2) && var == 15 && !(_bitArray[5] & 1)) {
+ if ((getGameType() == GType_SIMON2) && var == 15 && !(_bitArray[5] & 1)) {
int16 tmp;
if (_scrollCount != 0) {
@@ -1472,7 +1472,7 @@ void SimonEngine::vc41() {
uint var = vc_read_next_word();
int16 value = vc_read_var(var) - vc_read_next_word();
- if ((_game & GF_SIMON2) && var == 15 && !(_bitArray[5] & 1)) {
+ if ((getGameType() == GType_SIMON2) && var == 15 && !(_bitArray[5] & 1)) {
int16 tmp;
if (_scrollCount != 0) {
@@ -1591,18 +1591,18 @@ void SimonEngine::vc51_clear_hitarea_bit_0x40() {
void SimonEngine::vc52_playSound() {
uint16 sound_id = vc_read_next_word();
- if (_game == GAME_FEEBLEFILES) {
+ if (getGameType() == GType_FF) {
uint16 pan = vc_read_next_word();
uint16 vol = vc_read_next_word();
debug(0, "STUB: vc52_playSound: snd %d pan %d vol %d", sound_id, pan, vol);
- } else if (_game & GF_SIMON2) {
+ } else if (getGameType() == GType_SIMON2) {
if (sound_id >= 0x8000) {
sound_id = -sound_id;
_sound->playAmbient(sound_id);
} else {
_sound->playEffects(sound_id);
}
- } else if (_game & GF_TALKIE) {
+ } else if (getFeatures() & GF_TALKIE) {
_sound->playEffects(sound_id);
} else {
playSting(sound_id);
@@ -1644,7 +1644,7 @@ void SimonEngine::vc55_offset_hit_area() {
}
void SimonEngine::vc56_delay() {
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
uint num = vc_read_var_or_word() * _frameRate;
add_vga_timer(num + VGA_DELAY_BASE, _vcPtr, _vgaCurSpriteId, _vgaCurFileId);
@@ -1653,7 +1653,7 @@ void SimonEngine::vc56_delay() {
}
void SimonEngine::vc59() {
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
uint file = vc_read_next_word();
uint start = vc_read_next_word();
uint end = vc_read_next_word() + 1;
@@ -1707,7 +1707,7 @@ void SimonEngine::vc_kill_sprite(uint file, uint sprite) {
vfs = _vgaSleepStructs;
while (vfs->ident != 0) {
- if (vfs->sprite_id == _vgaCurSpriteId && ((_game & GF_SIMON1) || vfs->cur_vga_file == _vgaCurFileId)) {
+ if (vfs->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vfs->cur_vga_file == _vgaCurFileId)) {
while (vfs->ident != 0) {
memcpy(vfs, vfs + 1, sizeof(VgaSleepStruct));
vfs++;
@@ -1723,7 +1723,7 @@ void SimonEngine::vc_kill_sprite(uint file, uint sprite) {
vte = _vgaTimerList;
while (vte->delay != 0) {
- if (vte->sprite_id == _vgaCurSpriteId && ((_game & GF_SIMON1) || vte->cur_vga_file == _vgaCurFileId)) {
+ if (vte->sprite_id == _vgaCurSpriteId && ((getGameType() == GType_SIMON1) || vte->cur_vga_file == _vgaCurFileId)) {
delete_vga_timer(vte);
break;
}
@@ -1739,7 +1739,7 @@ void SimonEngine::vc_kill_sprite(uint file, uint sprite) {
void SimonEngine::vc60_killSprite() {
uint file;
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
file = vc_read_next_word();
} else {
file = _vgaCurFileId;
@@ -1781,7 +1781,7 @@ void SimonEngine::vc62_fastFadeOut() {
delay(5);
}
- if (_game & GF_SIMON1) {
+ if (getGameType() == GType_SIMON1) {
uint16 params[5]; /* parameters to vc10_draw */
VgaSprite *vsp;
VgaPointersEntry *vpe;
@@ -1819,12 +1819,12 @@ void SimonEngine::vc62_fastFadeOut() {
// Allow one section of Simon the Sorcerer 1 introduction to be displayed
// in lower half of screen
- if ((_game & GF_SIMON1) && (_subroutine == 2923 || _subroutine == 2926))
+ if ((getGameType() == GType_SIMON1) && (_subroutine == 2923 || _subroutine == 2926))
dx_clear_surfaces(200);
else
dx_clear_surfaces(_windowNum == 4 ? 134 : 200);
}
- if (_game & GF_SIMON2) {
+ if (getGameType() == GType_SIMON2) {
if (_nextMusicToPlay != -1)
loadMusic(_nextMusicToPlay);
}