aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Howell2009-07-07 23:24:34 +0000
committerTravis Howell2009-07-07 23:24:34 +0000
commit3e47aaa151ff751af867c57344b063c30f5f75f3 (patch)
tree84101b9c9d7eb333063c43a076ae3645a95ab703
parentbd87b653aca29c593cadcdedfc2208cec51456aa (diff)
parenta62b26ea8026666fd658337bcc061c1c4e2ab3f9 (diff)
downloadscummvm-rg350-3e47aaa151ff751af867c57344b063c30f5f75f3.tar.gz
scummvm-rg350-3e47aaa151ff751af867c57344b063c30f5f75f3.tar.bz2
scummvm-rg350-3e47aaa151ff751af867c57344b063c30f5f75f3.zip
Merged revisions 42205-42206,42208-42209,42211-42212,42214-42217,42219,42221-42222,42229-42235,42238-42240 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk ........ r42205 | dreammaster | 2009-07-07 17:41:02 +1000 (Tue, 07 Jul 2009) | 1 line Removed the shooting workaround delay - the overlay number can vary, so it isn't a reliable way of identifying the specific message ........ r42206 | thebluegr | 2009-07-07 17:44:25 +1000 (Tue, 07 Jul 2009) | 4 lines - Added auto-detection for EGA graphics. As a result of this, GF_SCI1_EGA has been removed and versions SCI_VERSION_01_EGA and SCI_VERSION_01_VGA have been merged into SCI_VERSION_01 - Simplified the checks for EGA and VGA graphics - Fixed a bug in script_adjust_opcode_formats() - Simplified the code in GfxResManager::getView() a bit ........ r42208 | strangerke | 2009-07-07 17:51:18 +1000 (Tue, 07 Jul 2009) | 1 line Add detection of Playtoons 2 En ........ r42209 | thebluegr | 2009-07-07 17:51:26 +1000 (Tue, 07 Jul 2009) | 1 line Added a SCI1.1 case in the lofss opcode, like in the lofsa opcode (essentially, lofss and lofsa both load an offset, with lofsa loading it in the accumulator and lofss in the stack). lofss is rarely used in SCI1.1 games, which explains why no lofss-related crashes have been observed in SCI1.1 ........ r42211 | thebluegr | 2009-07-07 20:28:05 +1000 (Tue, 07 Jul 2009) | 1 line Added auto-detection for games with older headers for script blocks, and removed game flag GF_SCI0_OLD ........ r42212 | thebluegr | 2009-07-07 21:14:18 +1000 (Tue, 07 Jul 2009) | 1 line Cleanup: added an enum for the auto-detected features, removed the selectors which are only used for auto-detection from the convenience selector map and placed feature auto-detection in a separate function. Also, now the automatically detected graphics resources are shown in the console. ........ r42214 | strangerke | 2009-07-07 21:58:22 +1000 (Tue, 07 Jul 2009) | 2 lines - Separate Playtoons gametypes from in GobEngine::initGameParts() - Add a specific save/load class for Playtoons as some specific files need to be tested ........ r42215 | strangerke | 2009-07-07 22:03:27 +1000 (Tue, 07 Jul 2009) | 3 lines - Add a new gametype for 'The Land of the Magic Stones' - Add detection of the french version - Add a new game feature for 800*600 ........ r42216 | thebluegr | 2009-07-07 22:29:55 +1000 (Tue, 07 Jul 2009) | 1 line Removed the superfluous sci_version_types array (it's essentially the same as the versionNames array) ........ r42217 | strangerke | 2009-07-07 22:51:21 +1000 (Tue, 07 Jul 2009) | 1 line Change SaveLoad_Playtoons case ........ r42219 | thebluegr | 2009-07-07 23:39:24 +1000 (Tue, 07 Jul 2009) | 1 line Removed the weird checks for a maximum resource number (the sci_max_resource_nr array), as it doesn't serve any real purpose and leads to strange errors: if a resource is found which is bigger than the maximum number, it will be remapped to an incorrect number from this check. This makes KQ5CD work properly again (resources would be remapped to incorrect resource numbers from this code as a result of not updating this array with the latest SCI version merges). ........ r42221 | lordhoto | 2009-07-08 00:22:23 +1000 (Wed, 08 Jul 2009) | 1 line Add generic functionallity to draw FM-Towns ROM. (To be used by KYRA and SCI) ........ r42222 | lordhoto | 2009-07-08 00:22:39 +1000 (Wed, 08 Jul 2009) | 1 line Adapt KYRA to use the new Graphics::FontSJIS code. ........ r42229 | sev | 2009-07-08 03:11:29 +1000 (Wed, 08 Jul 2009) | 2 lines kFeatures800 -> kFeatures800x600 in order to have more meaningful name ........ r42230 | lordhoto | 2009-07-08 04:10:35 +1000 (Wed, 08 Jul 2009) | 2 lines - Added support for outlined FM-Towns ROM drawing - Adapted KYRA to use that ........ r42231 | lordhoto | 2009-07-08 04:17:30 +1000 (Wed, 08 Jul 2009) | 2 lines - Rename FontSJIS::enableShadow to enableOutline. - Initialize outline to false by default in FontTowns. ........ r42232 | lordhoto | 2009-07-08 05:00:39 +1000 (Wed, 08 Jul 2009) | 1 line Change "FM-Towns" to "FM-TOWNS" for consistency. ........ r42233 | lordhoto | 2009-07-08 05:00:51 +1000 (Wed, 08 Jul 2009) | 1 line Add guards to only include SJIS font code, when KYRA or SCI is enabled. ........ r42234 | lordhoto | 2009-07-08 05:18:32 +1000 (Wed, 08 Jul 2009) | 1 line Simply compile guard of SJIS code and fix comment. ........ r42235 | lordhoto | 2009-07-08 05:18:53 +1000 (Wed, 08 Jul 2009) | 1 line Change all uses of FM-Towns/fm-towns to FM-TOWNS. ........ r42238 | thebluegr | 2009-07-08 06:01:15 +1000 (Wed, 08 Jul 2009) | 1 line Added a workaround for incorrect font references in LSL1VGA (which was the original purpose of the code removed in rev. 42219) ........ r42239 | thebluegr | 2009-07-08 06:17:07 +1000 (Wed, 08 Jul 2009) | 1 line Improved the LSL1VGA workaround after talking with waltervn ........ r42240 | thebluegr | 2009-07-08 06:43:27 +1000 (Wed, 08 Jul 2009) | 1 line Silenced the very chatty song iterator console messages by converting them to appropriate debug messages ........ svn-id: r42248
-rw-r--r--NEWS2
-rw-r--r--dists/msvc7/gob.vcproj3
-rw-r--r--dists/msvc71/gob.vcproj3
-rw-r--r--dists/msvc8/gob.vcproj4
-rw-r--r--dists/msvc9/gob.vcproj8
-rw-r--r--engines/cruise/function.cpp5
-rw-r--r--engines/gob/detection.cpp56
-rw-r--r--engines/gob/gob.cpp22
-rw-r--r--engines/gob/gob.h5
-rw-r--r--engines/gob/module.mk1
-rw-r--r--engines/gob/save/saveload.h26
-rw-r--r--engines/gob/save/saveload_playtoons.cpp88
-rw-r--r--engines/kyra/detection.cpp4
-rw-r--r--engines/kyra/saveload.cpp2
-rw-r--r--engines/kyra/screen.cpp287
-rw-r--r--engines/kyra/screen.h14
-rw-r--r--engines/kyra/sequences_hof.cpp10
-rw-r--r--engines/kyra/sequences_lok.cpp2
-rw-r--r--engines/sci/console.cpp6
-rw-r--r--engines/sci/detection.cpp49
-rw-r--r--engines/sci/engine/game.cpp22
-rw-r--r--engines/sci/engine/kernel.cpp112
-rw-r--r--engines/sci/engine/kernel.h48
-rw-r--r--engines/sci/engine/kgraphics.cpp22
-rw-r--r--engines/sci/engine/ksound.cpp10
-rw-r--r--engines/sci/engine/savegame.cpp4
-rw-r--r--engines/sci/engine/script.cpp7
-rw-r--r--engines/sci/engine/scriptdebug.cpp2
-rw-r--r--engines/sci/engine/seg_manager.cpp2
-rw-r--r--engines/sci/engine/vm.cpp27
-rw-r--r--engines/sci/engine/vm.h4
-rw-r--r--engines/sci/gfx/gfx_resmgr.cpp49
-rw-r--r--engines/sci/gfx/gfx_resmgr.h6
-rw-r--r--engines/sci/gfx/gfx_resource.h11
-rw-r--r--engines/sci/gfx/operations.cpp6
-rw-r--r--engines/sci/gfx/operations.h3
-rw-r--r--engines/sci/gfx/res_view.cpp4
-rw-r--r--engines/sci/resource.cpp72
-rw-r--r--engines/sci/resource.h7
-rw-r--r--engines/sci/sci.cpp25
-rw-r--r--engines/sci/sci.h33
-rw-r--r--engines/sci/sfx/iterator.cpp23
-rw-r--r--engines/sci/vocabulary.cpp2
-rw-r--r--engines/scumm/verbs.cpp2
-rw-r--r--graphics/module.mk1
-rw-r--r--graphics/sjis.cpp197
-rw-r--r--graphics/sjis.h135
-rw-r--r--tools/create_kyradat/create_kyradat.cpp8
48 files changed, 883 insertions, 558 deletions
diff --git a/NEWS b/NEWS
index ce18b0fea7..2ab1cf239c 100644
--- a/NEWS
+++ b/NEWS
@@ -323,7 +323,7 @@ For a more comprehensive changelog for the latest experimental SVN code, see:
- Renamed Simon engine to AGOS.
Kyrandia:
- - Added support for FM-Towns version (both English and Japanese).
+ - Added support for FM-TOWNS version (both English and Japanese).
BASS:
- Fixed long-standing font bug. We were using the control panel font for
diff --git a/dists/msvc7/gob.vcproj b/dists/msvc7/gob.vcproj
index fd1cbb9dfe..9919d09c9f 100644
--- a/dists/msvc7/gob.vcproj
+++ b/dists/msvc7/gob.vcproj
@@ -398,6 +398,9 @@
RelativePath="..\..\engines\gob\save\saveload_v6.cpp">
</File>
<File
+ RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp">
+ </File>
+ <File
RelativePath="..\..\engines\gob\scenery.cpp">
</File>
<File
diff --git a/dists/msvc71/gob.vcproj b/dists/msvc71/gob.vcproj
index b005dbbd6e..0a5f869970 100644
--- a/dists/msvc71/gob.vcproj
+++ b/dists/msvc71/gob.vcproj
@@ -412,6 +412,9 @@
RelativePath="..\..\engines\gob\save\saveload_v6.cpp">
</File>
<File
+ RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp">
+ </File>
+ <File
RelativePath="..\..\engines\gob\scenery.cpp">
</File>
<File
diff --git a/dists/msvc8/gob.vcproj b/dists/msvc8/gob.vcproj
index 14259ac2fd..0375f339d2 100644
--- a/dists/msvc8/gob.vcproj
+++ b/dists/msvc8/gob.vcproj
@@ -519,6 +519,10 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\save\savefile.cpp"
>
</File>
diff --git a/dists/msvc9/gob.vcproj b/dists/msvc9/gob.vcproj
index 60385473a5..7b339fbad9 100644
--- a/dists/msvc9/gob.vcproj
+++ b/dists/msvc9/gob.vcproj
@@ -536,6 +536,10 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\save\saveconverter.h"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\save\saveload.cpp"
>
</File>
@@ -560,6 +564,10 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\save\saveload_playtoons.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\scenery.cpp"
>
</File>
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
index fb67cef91c..6fe82f76d4 100644
--- a/engines/cruise/function.cpp
+++ b/engines/cruise/function.cpp
@@ -815,11 +815,6 @@ int16 Op_AddMessage(void) {
createTextObject(&cellHead, overlayIdx, var_8, var_6, var_4, var_2, color, masterScreen, currentScriptPtr->overlayNumber, currentScriptPtr->scriptNumber);
- // WORKAROUND: The first message in the 'shooting cutscene' goes too fast on newer systems,
- // so this introduces a delay so the user has more time to read the message
- if ((overlayIdx == 46) && (var_8 == 0))
- userDelay = 3 * (1000 / GAME_FRAME_DELAY_2);
-
return 0;
}
diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp
index 9426c01ef2..3827c3635c 100644
--- a/engines/gob/detection.cpp
+++ b/engines/gob/detection.cpp
@@ -71,6 +71,7 @@ static const PlainGameDescriptor gobGames[] = {
{"bambou", "Playtoons Limited Edition - Bambou le sauveur de la jungle"},
{"fascination", "Fascination"},
{"geisha", "Geisha"},
+ {"magicstones", "The Land of the Magic Stones"},
{"adibou4", "Adibou v4"},
{"adibouunknown", "Adibou (not yet supported)"},
{0, 0}
@@ -3438,6 +3439,24 @@ static const GOBGameDescription gameDescriptions[] = {
"playtoons2",
"",
{
+ {"playtoon.stk", 0, "4772c96be88a57f0561519e4a1526c62", 24406262},
+ {"spirou.stk", 0, "5d9c7644d0c47840169b4d016765cc1a", 9816201},
+ {0, 0, 0, 0}
+ },
+ EN_ANY,
+ kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ },
+ kGameTypePlaytoon,
+ kFeatures640,
+ "intro2.stk", 0, 0
+ },
+ {
+ {
+ "playtoons2",
+ "",
+ {
{"playtoon.stk", 0, "55a85036dd93cce93532d8f743d90074", 17467154},
{"spirou.stk", 0, "e3e1b6148dd72fafc3637f1a8e5764f5", 9812043},
{0, 0, 0, 0}
@@ -3634,6 +3653,24 @@ static const GOBGameDescription gameDescriptions[] = {
},
{
{
+ "magicstones",
+ "",
+ {
+ {"ed4.stk", 0, "98721a7cfdc5a358d7ac56b7c6d3ba3d", 541882},
+ {"ed4cd.itk", 0, "0627a91d9a6f4772c33747ce752024c2", 606993908},
+ {0, 0, 0, 0}
+ },
+ FR_FRA,
+ kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ },
+ kGameTypeMagicStones,
+ kFeatures800x600,
+ "ed4.stk", "main.obc", 0
+ },
+ {
+ {
"adibou4",
"",
AD_ENTRY1s("intro.stk", "a3c35d19b2d28ea261d96321d208cb5a", 6021466),
@@ -4189,6 +4226,20 @@ static const GOBGameDescription fallbackDescs[] = {
},
{
{
+ "magicstones",
+ "unknown",
+ AD_ENTRY1(0, 0),
+ UNK_LANG,
+ kPlatformPC,
+ ADGF_NO_FLAGS,
+ GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ },
+ kGameTypeMagicStones,
+ kFeatures800x600,
+ "ed4.stk", "main.obc", 0
+ },
+ {
+ {
"adibou4",
"",
AD_ENTRY1(0, 0),
@@ -4241,8 +4292,9 @@ static const ADFileBasedFallback fileBased[] = {
{ &fallbackDescs[19], { "intro.stk", "bambou.itk", 0 } },
{ &fallbackDescs[20], { "disk0.stk", "disk1.stk", "disk2.stk", "disk3.stk", 0 } },
{ &fallbackDescs[21], { "disk1.stk", "disk2.stk", "disk3.stk", 0 } },
- { &fallbackDescs[22], { "adif41.stk", "adim41.stk", 0 } },
- { &fallbackDescs[23], { "coktelplayer.scn", 0 } },
+ { &fallbackDescs[22], { "ed4.stk", 0 } },
+ { &fallbackDescs[23], { "adif41.stk", "adim41.stk", 0 } },
+ { &fallbackDescs[24], { "coktelplayer.scn", 0 } },
{ 0, { 0 } }
};
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 8605dfbd52..94255b1277 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -205,6 +205,10 @@ bool GobEngine::isBATDemo() const {
return (_features & kFeaturesBATDemo) != 0;
}
+bool GobEngine::is800x600() const {
+ return (_features & kFeatures800x600) != 0;
+}
+
bool GobEngine::isDemo() const {
return (isSCNDemo() || isBATDemo());
}
@@ -421,9 +425,6 @@ bool GobEngine::initGameParts() {
_saveLoad = new SaveLoad_v4(this, _targetName.c_str());
break;
- case kGameTypePlaytoon:
- case kGameTypePlaytnCk:
- case kGameTypeBambou:
case kGameTypeDynasty:
_init = new Init_v3(this);
_video = new Video_v2(this);
@@ -449,6 +450,21 @@ bool GobEngine::initGameParts() {
_saveLoad = new SaveLoad_v6(this, _targetName.c_str());
break;
+ case kGameTypePlaytoon:
+ case kGameTypePlaytnCk:
+ case kGameTypeBambou:
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+// _inter = new Inter_Playtoons(this);
+ _inter = new Inter_v4(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
+ _saveLoad = new SaveLoad_Playtoons(this);
+ break;
+
default:
deinitGameParts();
return false;
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index 5047382316..02f6af51bf 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -108,6 +108,7 @@ enum GameType {
kGameTypeBambou,
kGameTypeFascination,
kGameTypeGeisha,
+ kGameTypeMagicStones,
kGameTypeAdibou4,
kGameTypeAdibouUnknown
};
@@ -119,7 +120,8 @@ enum Features {
kFeaturesAdlib = 1 << 2,
kFeatures640 = 1 << 3,
kFeaturesSCNDemo = 1 << 4,
- kFeaturesBATDemo = 1 << 5
+ kFeaturesBATDemo = 1 << 5,
+ kFeatures800x600 = 1 << 6
};
enum {
@@ -216,6 +218,7 @@ public:
bool hasAdlib() const;
bool isSCNDemo() const;
bool isBATDemo() const;
+ bool is800x600() const;
bool isDemo() const;
GobEngine(OSystem *syst);
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 66c1b0dbaf..611abb6038 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -64,6 +64,7 @@ MODULE_OBJS := \
save/saveload_v3.o \
save/saveload_v4.o \
save/saveload_v6.o \
+ save/saveload_playtoons.o \
save/saveconverter.o \
save/saveconverter_v2.o \
save/saveconverter_v3.o \
diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index a74b64b883..8d785c7233 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -445,6 +445,32 @@ protected:
SaveFile *getSaveFile(const char *fileName);
};
+/** Save/Load class for Playtoons. */
+/** Only used for the moment to check file presence */
+
+class SaveLoad_Playtoons : public SaveLoad {
+public:
+ SaveLoad_Playtoons(GobEngine *vm);
+ virtual ~SaveLoad_Playtoons();
+
+protected:
+ struct SaveFile {
+ const char *sourceName;
+ SaveMode mode;
+ SaveHandler *handler;
+ const char *description;
+ };
+
+ static SaveFile _saveFiles[];
+
+ SaveMode getSaveMode(const char *fileName) const;
+
+ const SaveFile *getSaveFile(const char *fileName) const;
+
+ SaveFile *getSaveFile(const char *fileName);
+
+};
+
} // End of namespace Gob
#endif // GOB_SAVE_SAVELOAD_H
diff --git a/engines/gob/save/saveload_playtoons.cpp b/engines/gob/save/saveload_playtoons.cpp
new file mode 100644
index 0000000000..97da909e7c
--- /dev/null
+++ b/engines/gob/save/saveload_playtoons.cpp
@@ -0,0 +1,88 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "gob/save/saveload.h"
+#include "gob/inter.h"
+#include "gob/variables.h"
+
+namespace Gob {
+
+SaveLoad_Playtoons::SaveFile SaveLoad_Playtoons::_saveFiles[] = {
+ { "disk.001", kSaveModeExists, 0, 0}, // Playtoons 1 identification file
+ { "disk.002", kSaveModeExists, 0, 0}, // Playtoons 2 identification file
+ { "disk.003", kSaveModeExists, 0, 0}, // Playtoons 3 identification file
+ { "disk.004", kSaveModeExists, 0, 0}, // Playtoons 4 identification file
+ { "disk.005", kSaveModeExists, 0, 0}, // Playtoons 5 identification file
+ { "disk.006", kSaveModeExists, 0, 0}, // Playtoons CK 1 identification file
+ { "disk.007", kSaveModeExists, 0, 0}, // Playtoons CK 2 identification file
+ { "disk.008", kSaveModeExists, 0, 0}, // Playtoons CK 3 identification file
+ { "titre.001", kSaveModeExists, 0, 0}, // Playtoons 1 titles
+ { "titre.002", kSaveModeExists, 0, 0}, // Playtoons 2 titles
+ { "titre.003", kSaveModeExists, 0, 0}, // Playtoons 3 titles
+ { "titre.004", kSaveModeExists, 0, 0}, // Playtoons 4 titles
+ { "titre.005", kSaveModeExists, 0, 0}, // Playtoons 5 titles
+ { "titre.006", kSaveModeExists, 0, 0}, // Playtoons CK 1 empty title (???)
+ { "titre.007", kSaveModeExists, 0, 0}, // Playtoons CK 2 empty title (???)
+ { "titre.008", kSaveModeExists, 0, 0}, // Playtoons CK 3 empty title (???)
+ { "mdo.def", kSaveModeExists, 0, 0},
+};
+
+SaveLoad::SaveMode SaveLoad_Playtoons::getSaveMode(const char *fileName) const {
+ const SaveFile *saveFile = getSaveFile(fileName);
+
+ if (saveFile)
+ return saveFile->mode;
+
+ return kSaveModeNone;
+}
+
+SaveLoad_Playtoons::SaveLoad_Playtoons(GobEngine *vm) :
+ SaveLoad(vm) {
+}
+
+SaveLoad_Playtoons::~SaveLoad_Playtoons() {
+}
+
+const SaveLoad_Playtoons::SaveFile *SaveLoad_Playtoons::getSaveFile(const char *fileName) const {
+ fileName = stripPath(fileName);
+
+ for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
+ if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
+ return &_saveFiles[i];
+
+ return 0;
+}
+
+SaveLoad_Playtoons::SaveFile *SaveLoad_Playtoons::getSaveFile(const char *fileName) {
+ fileName = stripPath(fileName);
+
+ for (int i = 0; i < ARRAYSIZE(_saveFiles); i++)
+ if (!scumm_stricmp(fileName, _saveFiles[i].sourceName))
+ return &_saveFiles[i];
+
+ return 0;
+}
+
+} // End of namespace Gob
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 63d15419d2..3199a043e7 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -230,7 +230,7 @@ const KYRAGameDescription adGameDescs[] = {
KYRA1_FLOPPY_FLAGS
},
- { // FM-Towns version
+ { // FM-TOWNS version
{
"kyra1",
0,
@@ -638,7 +638,7 @@ const KYRAGameDescription adGameDescs[] = {
KYRA2_DEMO_FLAGS
},
- { // FM-Towns
+ { // FM-TOWNS
{
"kyra2",
0,
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index ecd6bbe450..a1aaf77d51 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -168,7 +168,7 @@ Common::SeekableReadStream *KyraEngine_v1::openSaveForReading(const char *filena
delete in;
return 0;
} else if ((header.flags & GF_FMTOWNS) && !(_flags.platform == Common::kPlatformFMTowns || _flags.platform == Common::kPlatformPC98)) {
- warning("Can not load FM-Towns/PC98 savefile for this (non FM-Towns/PC98) gameversion");
+ warning("Can not load FM-TOWNS/PC98 savefile for this (non FM-TOWNS/PC98) gameversion");
delete in;
return 0;
}
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 963dc3f4d6..426907c871 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -26,7 +26,10 @@
#include "common/endian.h"
#include "common/system.h"
+
#include "graphics/cursorman.h"
+#include "graphics/sjis.h"
+
#include "kyra/screen.h"
#include "kyra/kyra_v1.h"
#include "kyra/resource.h"
@@ -43,6 +46,8 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system)
_drawShapeVar3 = 1;
_drawShapeVar4 = 0;
_drawShapeVar5 = 0;
+
+ _sjisFont = 0;
}
Screen::~Screen() {
@@ -56,8 +61,7 @@ Screen::~Screen() {
_fonts[f].fontData = NULL;
}
- delete[] _sjisFontData;
- delete[] _sjisTempPage;
+ delete _sjisFont;
delete _screenPalette;
delete _internFadePalette;
delete[] _decodeShapeBuffer;
@@ -78,8 +82,6 @@ bool Screen::init() {
_useSJIS = false;
_use16ColorMode = _vm->gameFlags().use16ColorMode;
- _sjisTempPage = _sjisFontData = 0;
-
if (_vm->gameFlags().useHiResOverlay) {
_useOverlays = true;
_useSJIS = (_vm->gameFlags().lang == Common::JA_JPN);
@@ -94,14 +96,17 @@ bool Screen::init() {
}
if (_useSJIS) {
- if (!_sjisFontData) {
- // we use the FM-Towns font rom for PC-98, too, until we feel
+ if (!_sjisFont) {
+ // we use the FM-TOWNS font rom for PC-98, too, until we feel
// like adding support for the PC-98 font
//if (_vm->gameFlags().platform == Common::kPlatformFMTowns) {
- // FM-Towns
- _sjisFontData = _vm->resource()->fileData("FMT_FNT.ROM", 0);
- if (!_sjisFontData)
- error("missing font rom ('FMT_FNT.ROM') required for this version");
+ // FM-TOWNS
+ Common::SeekableReadStream *rom = _vm->resource()->createReadStream("FMT_FNT.ROM");
+ Graphics::FontTowns *townsFont = new Graphics::FontTowns();
+ if (!rom || !townsFont || !townsFont->loadFromStream(*rom))
+ error("Could not load font rom ('FMT_FNT.ROM') required for this version");
+ _sjisFont = townsFont;
+ delete rom;
/*} else {
// PC-98
_sjisFontData = _vm->resource()->fileData("FONT.ROM", 0);
@@ -109,16 +114,12 @@ bool Screen::init() {
error("missing font rom ('FONT.ROM') required for this version");
}*/
}
-
- if (!_sjisTempPage) {
- _sjisTempPage = new uint8[420];
- assert(_sjisTempPage);
- _sjisTempPage2 = _sjisTempPage + 60;
- _sjisSourceChar = _sjisTempPage + 384;
- }
+
+ _sjisFont->enableOutline(!_use16ColorMode);
}
}
+
_curPage = 0;
uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE * 8];
for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2)
@@ -657,7 +658,7 @@ void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) {
}
addDirtyRect(0, y, SCREEN_W, h);
// This would remove the text in the end sequence of
- // the (Kyrandia 1) FM-Towns version.
+ // the (Kyrandia 1) FM-TOWNS version.
// Since this method is just used for the Seqplayer
// this shouldn't be a problem anywhere else, so it's
// safe to disable the call here.
@@ -1027,8 +1028,8 @@ int Screen::getCharWidth(uint16 c) const {
if (_vm->gameFlags().platform == Common::kPlatformAmiga)
return 0;
- if (c & 0xFF00)
- return SJIS_CHARSIZE >> 1;
+ if ((c & 0xFF00) && _sjisFont)
+ return _sjisFont->getFontWidth() >> 1;
if (_fonts[_currentFont].lastGlyph < c)
return 0;
@@ -1115,7 +1116,7 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
c = READ_LE_UINT16(str - 1);
++str;
charWidth = getCharWidth(c);
- charHeight = SJIS_CHARSIZE >> 1;
+ charHeight = _sjisFont->getFontHeight() >> 1;
drawCharSJIS(c, x, y);
}
@@ -3007,93 +3008,6 @@ void Screen::copyOverlayRegion(int x, int y, int x2, int y2, int w, int h, int s
}
}
-// SJIS rendering
-
-namespace {
-int SJIStoFMTChunk(int f, int s) { // copied from scumm\charset.cpp
- enum {
- KANA = 0,
- KANJI = 1,
- EKANJI = 2
- };
- int base = s - ((s + 1) % 32);
- int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA;
-
- if (f >= 0x81 && f <= 0x84) kanjiType = KANA;
- if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI;
- if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI;
-
- if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) {
- c = 48; //correction
- p = -8; //correction
- }
-
- if (kanjiType == KANA) {//Kana
- chunk_f = (f - 0x81) * 2;
- } else if (kanjiType == KANJI) {//Standard Kanji
- p += f - 0x88;
- chunk_f = c + 2 * p;
- } else if (kanjiType == EKANJI) {//Enhanced Kanji
- p += f - 0xe0;
- chunk_f = c + 2 * p;
- }
-
- // Base corrections
- if (base == 0x7f && s == 0x7f)
- base -= 0x20;
- if (base == 0x9f && s == 0xbe)
- base += 0x20;
- if (base == 0xbf && s == 0xde)
- base += 0x20;
- //if (base == 0x7f && s == 0x9e)
- // base += 0x20;
-
- switch (base) {
- case 0x3f:
- cr = 0; //3f
- if (kanjiType == KANA) chunk = 1;
- else if (kanjiType == KANJI) chunk = 31;
- else if (kanjiType == EKANJI) chunk = 111;
- break;
- case 0x5f:
- cr = 0; //5f
- if (kanjiType == KANA) chunk = 17;
- else if (kanjiType == KANJI) chunk = 47;
- else if (kanjiType == EKANJI) chunk = 127;
- break;
- case 0x7f:
- cr = -1; //80
- if (kanjiType == KANA) chunk = 9;
- else if (kanjiType == KANJI) chunk = 63;
- else if (kanjiType == EKANJI) chunk = 143;
- break;
- case 0x9f:
- cr = 1; //9e
- if (kanjiType == KANA) chunk = 2;
- else if (kanjiType == KANJI) chunk = 32;
- else if (kanjiType == EKANJI) chunk = 112;
- break;
- case 0xbf:
- cr = 1; //be
- if (kanjiType == KANA) chunk = 18;
- else if (kanjiType == KANJI) chunk = 48;
- else if (kanjiType == EKANJI) chunk = 128;
- break;
- case 0xdf:
- cr = 1; //de
- if (kanjiType == KANA) chunk = 10;
- else if (kanjiType == KANJI) chunk = 64;
- else if (kanjiType == EKANJI) chunk = 144;
- break;
- default:
- debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p);
- }
-
- debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
- return ((chunk_f + chunk) * 32 + (s - base)) + cr;
-}
-} // end of anonymous namespace
-
void Screen::drawCharSJIS(uint16 c, int x, int y) {
int color1, color2;
@@ -3105,14 +3019,13 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
} else {
color1 = _textColorsMap[1];
color2 = _textColorsMap[0];
- }
- memset(_sjisTempPage2, _sjisInvisibleColor, 324);
- memset(_sjisSourceChar, 0, 36);
- memcpy(_sjisSourceChar, _sjisFontData + 0x20 * SJIStoFMTChunk(c & 0xff, c >> 8), 0x20);
+ if (color2 == _sjisInvisibleColor)
+ _sjisFont->enableOutline(false);
+ }
if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x, y, SJIS_CHARSIZE >> 1, SJIS_CHARSIZE >> 1);
+ addDirtyRect(x, y, _sjisFont->getFontWidth() >> 1, _sjisFont->getFontHeight() >> 1);
x <<= 1;
y <<= 1;
@@ -3124,154 +3037,10 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
}
destPage += y * 640 + x;
- uint8 *src = 0, *dst = 0;
-
- if (color2 != _sjisInvisibleColor) {
- // draw color2 shadow
- src = _sjisSourceChar;
- dst = _sjisTempPage2;
-
- for (int i = 0; i < SJIS_CHARSIZE; i++) {
- *((uint16*)dst) = READ_LE_UINT16(src);
- dst += 2; src += 2;
- *dst++ = 0;
- }
-
- src = _sjisTempPage2;
- dst = _sjisTempPage;
- memset(dst, 0, 60);
- for (int i = 0; i < 48; i++)
- *dst++ |= *src++;
-
- src = _sjisTempPage2;
- dst = _sjisTempPage + 3;
- for (int i = 0; i < 48; i++)
- *dst++ |= *src++;
-
- src = _sjisTempPage2;
- dst = _sjisTempPage + 6;
- for (int i = 0; i < 48; i++)
- *dst++ |= *src++;
-
- for (int i = 0; i < 2; i++) {
- src = _sjisTempPage;
- for (int ii = 0; ii < SJIS_CHARSIZE; ii++) {
- uint8 cy2 = 0;
- uint8 cy1 = 0;
- for (int iii = 0; iii < 3; iii++) {
- cy1 = *src & 1;
- *src |= ((*src >> 1) | (cy2 << 7));
- cy2 = cy1;
- src++;
- }
- }
- }
-
- src = _sjisTempPage2;
- for (int i = 0; i < SJIS_CHARSIZE; i++) {
- uint8 cy2 = 0;
- uint8 cy1 = 0;
- for (int ii = 0; ii < 3; ii++) {
- cy1 = *src & 1;
- *src = ((*src >> 1) | (cy2 << 7));
- cy2 = cy1;
- src++;
- }
- }
- src = _sjisTempPage2;
- dst = _sjisTempPage + 3;
- for (int i = 0; i < 48; i++)
- *dst++ ^= *src++;
-
- memset(_sjisTempPage2, _sjisInvisibleColor, 324);
- src = _sjisTempPage;
- dst = _sjisTempPage2;
-
- uint8 height = SJIS_CHARSIZE * 3;
- uint8 width = SJIS_CHARSIZE;
- if (color2 & 0xff00) {
- height -= 3;
- width--;
- dst += 0x13;
- }
-
- for (int i = 0; i < height; i++) {
- uint8 rs = *src++;
- for (int ii = 0; ii < 8; ii++) {
- if (rs & 0x80)
- *dst = (color2 & 0xff);
- rs <<= 1;
- dst++;
-
- if (!--width) {
- width = SJIS_CHARSIZE;
- if (color2 & 0xff00) {
- width--;
- dst++;
- }
- break;
- }
- }
- }
- }
-
- // draw color1 char
- src = _sjisSourceChar;
- dst = _sjisTempPage;
-
- for (int i = 0; i < SJIS_CHARSIZE; i++) {
- *(uint16*)dst = READ_LE_UINT16(src);
- dst += 2; src += 2;
- *dst++ = 0;
- }
+ _sjisFont->drawChar(destPage, c, 640, 1, color1, color2);
- src = _sjisTempPage;
- dst = _sjisTempPage2;
- if (color2 != _sjisInvisibleColor)
- color1 = (color1 & 0xff) | 0x100;
-
- uint8 height = SJIS_CHARSIZE * 3;
- uint8 width = SJIS_CHARSIZE;
- if (color1 & 0xff00) {
- height -= 3;
- width--;
- dst += 0x13;
- }
-
- for (int i = 0; i < height; i++) {
- uint8 rs = *src++;
- for (int ii = 0; ii < 8; ii++) {
- if (rs & 0x80)
- *dst = (color1 & 0xff);
- rs <<= 1;
- dst++;
-
- if (!--width) {
- width = SJIS_CHARSIZE;
- if (color1 & 0xff00) {
- width--;
- dst++;
- }
- break;
- }
- }
- }
-
- // copy char to surface
- src = _sjisTempPage2;
- dst = destPage;
- int pitch = 640 - SJIS_CHARSIZE;
-
- for (int i = 0; i < SJIS_CHARSIZE; i++) {
- for (int ii = 0; ii < SJIS_CHARSIZE; ii++) {
- if (*src != _sjisInvisibleColor)
- *dst = *src;
- src++;
- dst++;
- }
- dst += pitch;
- }
+ _sjisFont->enableOutline(!_use16ColorMode);
}
#pragma mark -
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 956bd7107e..a7a7efa7ca 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -35,6 +35,10 @@
class OSystem;
+namespace Graphics {
+class FontSJIS;
+} // end of namespace Graphics
+
namespace Kyra {
typedef Common::Functor0<void> UpdateFunctor;
@@ -360,11 +364,6 @@ protected:
void drawCharANSI(uint8 c, int x, int y);
void drawCharSJIS(uint16 c, int x, int y);
- enum {
- SJIS_CHARSIZE = 18,
- SJIS_CHARS = 8192
- };
-
int16 encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size);
template<bool noXor> static void wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src);
@@ -377,10 +376,7 @@ protected:
bool _useSJIS;
bool _use16ColorMode;
- uint8 *_sjisFontData;
- uint8 *_sjisTempPage;
- uint8 *_sjisTempPage2;
- uint8 *_sjisSourceChar;
+ Graphics::FontSJIS *_sjisFont;
uint8 _sjisInvisibleColor;
Palette *_screenPalette;
diff --git a/engines/kyra/sequences_hof.cpp b/engines/kyra/sequences_hof.cpp
index 90b2fdd580..81ab237e0f 100644
--- a/engines/kyra/sequences_hof.cpp
+++ b/engines/kyra/sequences_hof.cpp
@@ -770,12 +770,12 @@ int KyraEngine_HoF::seq_introDragon(WSAMovie_v2 *wsaObj, int x, int y, int frm)
}
int KyraEngine_HoF::seq_introDarm(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
- //NULLSUB (at least in fm-towns version)
+ //NULLSUB (at least in FM-TOWNS version)
return frm;
}
int KyraEngine_HoF::seq_introLibrary2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
- //NULLSUB (at least in fm-towns version)
+ //NULLSUB (at least in FM-TOWNS version)
return frm;
}
@@ -788,7 +788,7 @@ int KyraEngine_HoF::seq_introMarco(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
}
int KyraEngine_HoF::seq_introHand1a(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
- //NULLSUB (at least in fm-towns version)
+ //NULLSUB (at least in FM-TOWNS version)
return frm;
}
@@ -805,12 +805,12 @@ int KyraEngine_HoF::seq_introHand1c(WSAMovie_v2 *wsaObj, int x, int y, int frm)
}
int KyraEngine_HoF::seq_introHand2(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
- //NULLSUB (at least in fm-towns version)
+ //NULLSUB (at least in FM-TOWNS version)
return frm;
}
int KyraEngine_HoF::seq_introHand3(WSAMovie_v2 *wsaObj, int x, int y, int frm) {
- //NULLSUB (at least in fm-towns version)
+ //NULLSUB (at least in FM-TOWNS version)
return frm;
}
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index d483409090..0279831c9d 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -1049,7 +1049,7 @@ void KyraEngine_LoK::seq_playCredits() {
_screen->setTextColorMap(colorMap);
_screen->_charWidth = -1;
- // we only need this for the fm-towns version
+ // we only need this for the FM-TOWNS version
if (_flags.platform == Common::kPlatformFMTowns && _configMusic == 1)
snd_playWanderScoreViaMap(53, 1);
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 8f977c04c2..2d11f39835 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -374,10 +374,8 @@ const char *selector_name(EngineState *s, int selector) {
}
bool Console::cmdGetVersion(int argc, const char **argv) {
- int ver = _vm->getVersion();
-
- DebugPrintf("Resource file version: %s\n", sci_version_types[_vm->getResMgr()->_sciVersion]);
- DebugPrintf("Emulated interpreter version: %s\n", versionNames[ver]);
+ DebugPrintf("Resource file version: %s\n", versionNames[_vm->getResMgr()->_sciVersion]);
+ DebugPrintf("Emulated interpreter version: %s\n", versionNames[_vm->getVersion()]);
return true;
}
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index f86810e6b9..a9dac98572 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -31,7 +31,6 @@
namespace Sci {
-#define GF_FOR_SCI0_BEFORE_395 (GF_SCI0_OLD | GF_SCI0_OLDGETTIME)
#define GF_FOR_SCI0_BEFORE_629 GF_SCI0_OLDGETTIME
// Titles of the games
@@ -219,7 +218,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426},
{"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI0_BEFORE_395,
+ GF_FOR_SCI0_BEFORE_629,
SCI_VERSION_AUTODETECT,
SCI_VERSION_0
},
@@ -457,7 +456,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243},
{"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_SCI1_EGA,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -949,8 +948,8 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_01_EGA,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01,
+ SCI_VERSION_01
},
// King's Quest 1 SCI Remake - English DOS Non-Interactive Demo
@@ -1032,7 +1031,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777},
{"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI0_BEFORE_395,
+ GF_FOR_SCI0_BEFORE_629,
SCI_VERSION_AUTODETECT,
SCI_VERSION_0
},
@@ -1049,7 +1048,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288},
{"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI0_BEFORE_395,
+ GF_FOR_SCI0_BEFORE_629,
SCI_VERSION_AUTODETECT,
SCI_VERSION_0
},
@@ -1616,7 +1615,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "96033f57accfca903750413fd09193c8", 274953},
{"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI0_BEFORE_395,
+ GF_FOR_SCI0_BEFORE_629,
SCI_VERSION_AUTODETECT,
SCI_VERSION_0
},
@@ -2066,8 +2065,8 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH},
0,
- SCI_VERSION_01_EGA,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01,
+ SCI_VERSION_01
},
// Mixed-Up Fairy Tales v1.000 - English DOS (supplied by markcoolio in bug report #2723791)
@@ -2081,8 +2080,8 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_01_EGA,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01,
+ SCI_VERSION_01
},
// Mixed-Up Fairy Tales - English DOS Floppy (from jvprat)
@@ -2095,8 +2094,8 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_01_EGA,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01,
+ SCI_VERSION_01
},
// Mixed-Up Mother Goose - English Amiga (from www.back2roots.org)
@@ -2108,8 +2107,8 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_01_EGA,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01,
+ SCI_VERSION_01
},
// Mixed-Up Mother Goose v2.000 - English DOS Floppy (supplied by markcoolio in bug report #2723795)
@@ -2119,8 +2118,8 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_01_EGA,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01,
+ SCI_VERSION_01
},
// Mixed-Up Mother Goose - English DOS CD (from jvprat)
@@ -2520,7 +2519,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH},
0,
SCI_VERSION_AUTODETECT,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01
},
// Quest for Glory 1 - Japanese PC-98 5.25" Floppy
@@ -2533,7 +2532,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH},
0,
SCI_VERSION_AUTODETECT,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01
},
// Quest for Glory 1 - English Amiga
@@ -2606,7 +2605,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
0,
SCI_VERSION_AUTODETECT,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01
},
// Quest for Glory 2 - English (from FRG)
@@ -2621,7 +2620,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
SCI_VERSION_AUTODETECT,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01
},
// Quest for Glory 2 - English DOS
@@ -2639,7 +2638,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
SCI_VERSION_AUTODETECT,
- SCI_VERSION_01_EGA
+ SCI_VERSION_01
},
// Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG)
@@ -3125,7 +3124,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
{NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH},
- GF_SCI1_EGA,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3138,7 +3137,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC98, 0, GUIO_NOSPEECH},
- GF_SCI1_EGA,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index 7eb4c6731a..861294cfa6 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -43,10 +43,8 @@ int _reset_graphics_input(EngineState *s) {
gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 };
debug(2, "Initializing graphics");
- if (s->resmgr->_sciVersion <= SCI_VERSION_01_EGA || (s->_flags & GF_SCI1_EGA)) {
- int i;
-
- for (i = 0; i < 16; i++) {
+ if (!s->resmgr->isVGA()) {
+ for (int i = 0; i < 16; i++) {
if (gfxop_set_color(s->gfx_state, &(s->ega_colors[i]), gfx_sci0_image_colors[sci0_palette][i].r,
gfx_sci0_image_colors[sci0_palette][i].g, gfx_sci0_image_colors[sci0_palette][i].b, 0, -1, -1)) {
return 1;
@@ -97,7 +95,7 @@ int _reset_graphics_input(EngineState *s) {
font_nr = -1;
do {
resource = s->resmgr->testResource(ResourceId(kResourceTypeFont, ++font_nr));
- } while ((!resource) && (font_nr < sci_max_resource_nr[s->resmgr->_sciVersion]));
+ } while ((!resource) && (font_nr < 65536));
if (!resource) {
debug(2, "No text font was found.");
@@ -111,7 +109,7 @@ int _reset_graphics_input(EngineState *s) {
s->iconbar_port = new GfxPort(s->visual, gfx_rect(0, 0, 320, 200), s->ega_colors[0], transparent);
s->iconbar_port->_flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH;
- if (s->resmgr->_sciVersion >= SCI_VERSION_01_VGA) {
+ if (s->resmgr->isVGA()) {
// This bit sets the foreground and background colors in VGA SCI games
gfx_color_t fgcolor;
gfx_color_t bgcolor;
@@ -181,7 +179,7 @@ static void _free_graphics_input(EngineState *s) {
}
int game_init_sound(EngineState *s, int sound_flags) {
- if (s->resmgr->_sciVersion >= SCI_VERSION_01_EGA)
+ if (s->resmgr->_sciVersion >= SCI_VERSION_01)
sound_flags |= SFX_STATE_FLAG_MULTIPLAY;
s->sfx_init_flags = sound_flags;
@@ -259,7 +257,7 @@ static int create_class_table_sci0(EngineState *s) {
Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, scriptnr), 0);
if (script) {
- if (s->_flags & GF_SCI0_OLD)
+ if (s->_kernel->hasOldScriptHeader())
magic_offset = seeker = 2;
else
magic_offset = seeker = 0;
@@ -329,6 +327,9 @@ int script_init_engine(EngineState *s) {
s->kernel_opt_flags = 0;
+ s->_kernel = new Kernel(s->resmgr);
+ s->_vocabulary = new Vocabulary(s->resmgr);
+
if (s->_version >= SCI_VERSION_1_1)
result = create_class_table_sci11(s);
else
@@ -369,9 +370,6 @@ int script_init_engine(EngineState *s) {
s->_executionStack.clear(); // Start without any execution stack
s->execution_stack_base = -1; // No vm is running yet
- s->_kernel = new Kernel(s->resmgr, (s->_flags & GF_SCI0_OLD));
- s->_vocabulary = new Vocabulary(s->resmgr);
-
s->restarting_flags = SCI_GAME_IS_NOT_RESTARTING;
s->bp_list = NULL; // No breakpoints defined
@@ -466,7 +464,7 @@ int game_init(EngineState *s) {
s->successor = NULL; // No successor
s->_statusBarText.clear(); // Status bar is blank
s->status_bar_foreground = 0;
- s->status_bar_background = (s->resmgr->_sciVersion >= SCI_VERSION_01_VGA) ? 255 : 15;
+ s->status_bar_background = !s->resmgr->isVGA() ? 15 : 255;
SystemString *str = &s->sys_strings->strings[SYS_STRING_PARSER_BASE];
str->name = strdup("parser-base");
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 80071b2847..dd2d0dc61a 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -367,59 +367,102 @@ static const char *argtype_description[] = {
"Arithmetic"
};
-Kernel::Kernel(ResourceManager *resmgr, bool isOldSci0) : _resmgr(resmgr) {
+Kernel::Kernel(ResourceManager *resmgr) : _resmgr(resmgr) {
memset(&_selectorMap, 0, sizeof(_selectorMap)); // FIXME: Remove this once/if we C++ify selector_map_t
- loadSelectorNames(isOldSci0);
- mapSelectors(); // Map a few special selectors for later use
+ detectSciFeatures(); // must be called before loadSelectorNames()
+ loadSelectorNames();
+ mapSelectors(); // Map a few special selectors for later use
loadOpcodes();
loadKernelNames();
- mapFunctions(); // Map the kernel functions
-
- // SCI0 games using old graphics functions (before version 0.000.502) did not have a
- // motionCue selector
- _oldGfxFunctions = (_selectorMap.motionCue == -1 && _resmgr->_sciVersion == SCI_VERSION_0);
-
- // SCI1 games which use absolute lofs have the egoMoveSpeed selector
- _hasLofsAbsolute = (_selectorMap.egoMoveSpeed != -1 && _resmgr->_sciVersion < SCI_VERSION_1_1);
-
- printAutoDetectedFeatures();
+ mapFunctions(); // Map the kernel functions
}
Kernel::~Kernel() {
}
-void Kernel::printAutoDetectedFeatures() {
- if (_oldGfxFunctions)
- printf("Kernel auto-detection: game found to be using old graphics functions\n");
+void Kernel::detectSciFeatures() {
+ Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0);
+
+ if (!r) // No such resource?
+ error("Kernel: Could not retrieve selector names");
+
+ int count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off
+ features = 0;
+
+ // Initialize features based on SCI version
+ if (_resmgr->_sciVersion == SCI_VERSION_0) {
+ features |= kFeatureOldScriptHeader;
+ features |= kFeatureOldGfxFunctions;
+ }
+
+ for (int i = 0; i < count; i++) {
+ int offset = READ_LE_UINT16(r->data + 2 + i * 2);
+ int len = READ_LE_UINT16(r->data + offset);
+
+ Common::String tmp((const char *)r->data + offset + 2, len);
+
+ if (tmp == "setTarget") // "motionInited" can also be used
+ features &= ~kFeatureOldScriptHeader;
+
+ if (tmp == "motionCue")
+ features &= ~kFeatureOldGfxFunctions;
+
+ if (tmp == "egoMoveSpeed" && _resmgr->_sciVersion < SCI_VERSION_1_1)
+ features |= kFeatureLofsAbsolute;
+
+ if (tmp == "sightAngle" && _resmgr->_sciVersion == SCI_VERSION_0)
+ features |= kFeatureSci0Sci1Table;
+
+ if (tmp == "setVol")
+ features |= kFeatureSci1Sound;
+
+ if (tmp == "nodePtr")
+ features |= kFeatureSci01Sound;
+ }
+
+ if (features & kFeatureSci1Sound)
+ features &= ~kFeatureSci01Sound;
+
+ printf("Kernel auto-detected features:\n");
+
+ printf("Script block headers: ");
+ if (features & kFeatureOldScriptHeader)
+ printf("old\n");
else
- printf("Kernel auto-detection: game found to be using newer graphics functions\n");
+ printf("new\n");
- if (_hasLofsAbsolute)
- printf("Kernel auto-detection: game found to be using absolute parameters for lofs\n");
+ printf("Graphics functions: ");
+ if (features & kFeatureOldGfxFunctions)
+ printf("old\n");
else
- printf("Kernel auto-detection: game found to be using relative parameters for lofs\n");
+ printf("new\n");
- if (_selectorMap.setVol != -1)
- printf("Kernel auto-detection: using SCI1 sound functions\n");
- else if (_selectorMap.nodePtr != -1)
- printf("Kernel auto-detection: using SCI01 sound functions\n");
+ printf("lofs parameters: ");
+ if (features & kFeatureLofsAbsolute)
+ printf("absolute\n");
else
- printf("Kernel auto-detection: using SCI0 sound functions\n");
+ printf("relative\n");
- if (_resmgr->_sciVersion == SCI_VERSION_0 && _selectorMap.sightAngle != -1)
- printf("Kernel auto-detection: found SCI0 game using a SCI1 kernel table\n");
-}
+ printf("Sound functions: ");
+ if (features & kFeatureSci1Sound)
+ printf("SCI1\n");
+ else if (features & kFeatureSci01Sound)
+ printf("SCI01\n");
+ else
+ printf("SCI0\n");
-void Kernel::loadSelectorNames(bool isOldSci0) {
- int count;
+ if (features & kFeatureSci0Sci1Table)
+ printf("Found SCI0 game using a SCI1 kernel table\n");
+}
+void Kernel::loadSelectorNames() {
Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0);
if (!r) // No such resource?
error("Kernel: Could not retrieve selector names");
- count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off
+ int count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off
for (int i = 0; i < count; i++) {
int offset = READ_LE_UINT16(r->data + 2 + i * 2);
@@ -431,7 +474,7 @@ void Kernel::loadSelectorNames(bool isOldSci0) {
// Early SCI versions used the LSB in the selector ID as a read/write
// toggle. To compensate for that, we add every selector name twice.
- if (isOldSci0)
+ if (features & kFeatureOldScriptHeader)
_selectorNames.push_back(tmp);
}
}
@@ -771,7 +814,7 @@ void Kernel::setDefaultKernelNames() {
// Check if we have a SCI01 game which uses a SCI1 kernel table (e.g. the KQ1 demo
// and full version). We do this by checking if the sightAngle selector exists, as no
// SCI0 game seems to have it
- if (_selectorMap.sightAngle != -1 && isSci0)
+ if (features & kFeatureSci0Sci1Table)
isSci0 = false;
_kernelNames.resize(SCI_KNAMES_DEFAULT_ENTRIES_NR + (isSci0 ? 4 : 0));
@@ -832,8 +875,7 @@ bool Kernel::loadKernelNames() {
switch (_resmgr->_sciVersion) {
case SCI_VERSION_0:
- case SCI_VERSION_01_EGA:
- case SCI_VERSION_01_VGA:
+ case SCI_VERSION_01:
case SCI_VERSION_01_VGA_ODD:
case SCI_VERSION_1:
case SCI_VERSION_1_1:
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 9c92519cf0..4814bd0317 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -55,9 +55,18 @@ struct KernelFuncWithSignature {
Common::String orig_name; /**< Original name, in case we couldn't map it */
};
+enum AutoDetectedFeatures {
+ kFeatureOldScriptHeader = 1 << 0,
+ kFeatureOldGfxFunctions = 1 << 1,
+ kFeatureLofsAbsolute = 1 << 2,
+ kFeatureSci01Sound = 1 << 3,
+ kFeatureSci1Sound = 1 << 4,
+ kFeatureSci0Sci1Table = 1 << 5
+};
+
class Kernel {
public:
- Kernel(ResourceManager *resmgr, bool isOldSci0);
+ Kernel(ResourceManager *resmgr);
~Kernel();
uint getOpcodesSize() const { return _opcodes.size(); }
@@ -84,20 +93,40 @@ public:
bool hasKernelFunction(const char *functionName) const;
/**
+ * Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2).
+ * Old SCI versions used two word header for script blocks (first word equal
+ * to 0x82, meaning of the second one unknown). New SCI versions used one
+ * word header.
+ * Also, old SCI versions assign 120 degrees to left & right, and 60 to up
+ * and down. Later versions use an even 90 degree distribution.
+ */
+ bool hasOldScriptHeader() const { return (features & kFeatureOldScriptHeader); }
+
+ /**
* Applies to all versions before 0.000.502
* Old SCI versions used to interpret the third DrawPic() parameter inversely,
* with the opposite default value (obviously).
* Also, they used 15 priority zones from 42 to 200 instead of 14 priority
* zones from 42 to 190.
*/
- bool usesOldGfxFunctions() const { return _oldGfxFunctions; }
+ bool usesOldGfxFunctions() const { return (features & kFeatureOldGfxFunctions); }
/**
* Applies to all SCI1 versions after 1.000.200
* In late SCI1 versions, the argument of lofs[as] instructions
* is absolute rather than relative.
*/
- bool hasLofsAbsolute() const { return _hasLofsAbsolute; }
+ bool hasLofsAbsolute() const { return (features & kFeatureLofsAbsolute); }
+
+ /**
+ * Determines if the game is using SCI01 sound functions
+ */
+ bool usesSci01SoundFunctions() const { return (features & kFeatureSci01Sound); }
+
+ /**
+ * Determines if the game is using SCI1 sound functions
+ */
+ bool usesSci1SoundFunctions() const { return (features & kFeatureSci1Sound); }
// Script dissection/dumping functions
void dissectScript(int scriptNumber, Vocabulary *vocab);
@@ -127,17 +156,17 @@ private:
/**
* Loads the kernel selector names.
*/
- void loadSelectorNames(bool isOldSci0);
+ void loadSelectorNames();
/**
- * Prints auto-detected features from selectors
+ * Maps special selectors
*/
- void printAutoDetectedFeatures();
+ void mapSelectors();
/**
- * Maps special selectors
+ * Detects SCI features based on the existence of certain selectors
*/
- void mapSelectors();
+ void detectSciFeatures();
/**
* Maps kernel functions
@@ -151,8 +180,7 @@ private:
bool loadOpcodes();
ResourceManager *_resmgr;
- bool _oldGfxFunctions;
- bool _hasLofsAbsolute;
+ uint32 features;
// Kernel-related lists
/**
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 487813a4c7..d46ce3b938 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -269,7 +269,7 @@ void graph_restore_box(EngineState *s, reg_t handle) {
}
PaletteEntry get_pic_color(EngineState *s, int color) {
- if (s->resmgr->_sciVersion < SCI_VERSION_01_VGA)
+ if (!s->resmgr->isVGA())
return s->ega_colors[color].visual;
if (color == -1 || color == 255) // -1 occurs in Eco Quest 1. Not sure if this is the best approach, but it seems to work
@@ -286,7 +286,7 @@ PaletteEntry get_pic_color(EngineState *s, int color) {
static gfx_color_t graph_map_color(EngineState *s, int color, int priority, int control) {
gfx_color_t retval;
- if (s->resmgr->_sciVersion < SCI_VERSION_01_VGA) {
+ if (!s->resmgr->isVGA()) {
retval = s->ega_colors[(color >=0 && color < 16)? color : 0];
gfxop_set_color(s->gfx_state, &retval, (color < 0) ? -1 : retval.visual.r, retval.visual.g, retval.visual.b,
(color == -1) ? 255 : 0, priority, control);
@@ -502,7 +502,7 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) {
case K_GRAPH_GET_COLORS_NR:
- return make_reg(0, s->resmgr->_sciVersion < SCI_VERSION_01_VGA ? 0x10 : 0x100);
+ return make_reg(0, !s->resmgr->isVGA() ? 0x10 : 0x100);
break;
case K_GRAPH_DRAW_LINE: {
@@ -696,7 +696,7 @@ void _k_dirloop(reg_t obj, uint16 angle, EngineState *s, int funct_nr, int argc,
angle %= 360;
- if (!(s->_flags & GF_SCI0_OLD)) {
+ if (!s->_kernel->hasOldScriptHeader()) {
if (angle < 45)
loop = 3;
else if (angle < 136)
@@ -2502,7 +2502,7 @@ reg_t kNewWindow(EngineState *s, int funct_nr, int argc, reg_t *argv) {
int16 bgColor = (argc > 8 + argextra) ? argv[8 + argextra].toSint16() : 255;
if (bgColor >= 0) {
- if (s->resmgr->_sciVersion < SCI_VERSION_01_VGA)
+ if (!s->resmgr->isVGA())
bgcolor.visual = get_pic_color(s, MIN<int>(bgColor, 15));
else
bgcolor.visual = get_pic_color(s, bgColor);
@@ -2528,7 +2528,7 @@ reg_t kNewWindow(EngineState *s, int funct_nr, int argc, reg_t *argv) {
black.alpha = 0;
black.control = -1;
black.priority = -1;
- lWhite.visual = get_pic_color(s, s->resmgr->_sciVersion < SCI_VERSION_01_VGA ? 15 : 255);
+ lWhite.visual = get_pic_color(s, !s->resmgr->isVGA() ? 15 : 255);
lWhite.mask = GFX_MASK_VISUAL;
lWhite.alpha = 0;
lWhite.priority = -1;
@@ -3149,7 +3149,7 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) {
bg_color = port->_bgcolor;
// TODO: in SCI1VGA the default colors for text and background are #0 (black)
// SCI0 case should be checked
- if (s->resmgr->_sciVersion >= SCI_VERSION_01_VGA) {
+ if (s->resmgr->isVGA()) {
// This priority check fixes the colors in the menus in KQ5
// TODO/FIXME: Is this correct?
if (color0.priority >= 0)
@@ -3191,10 +3191,10 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) {
temp = argv[argpt++].toSint16();
debugC(2, kDebugLevelGraphics, "Display: set_color(%d)\n", temp);
- if ((s->resmgr->_sciVersion < SCI_VERSION_01_VGA) && temp >= 0 && temp <= 15)
+ if (!s->resmgr->isVGA() && temp >= 0 && temp <= 15)
color0 = (s->ega_colors[temp]);
else
- if (s->resmgr->_sciVersion >= SCI_VERSION_01_VGA && temp >= 0 && temp < 256) {
+ if (s->resmgr->isVGA() && temp >= 0 && temp < 256) {
color0.visual = get_pic_color(s, temp);
color0.mask = GFX_MASK_VISUAL;
} else
@@ -3208,10 +3208,10 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) {
temp = argv[argpt++].toSint16();
debugC(2, kDebugLevelGraphics, "Display: set_bg_color(%d)\n", temp);
- if (s->resmgr->_sciVersion < SCI_VERSION_01_VGA && temp >= 0 && temp <= 15)
+ if (!s->resmgr->isVGA() && temp >= 0 && temp <= 15)
bg_color = s->ega_colors[temp];
else
- if ((s->resmgr->_sciVersion >= SCI_VERSION_01_VGA) && temp >= 0 && temp <= 256) {
+ if (s->resmgr->isVGA() && temp >= 0 && temp <= 256) {
bg_color.visual = get_pic_color(s, temp);
bg_color.mask = GFX_MASK_VISUAL;
} else
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index ef02f8ee21..7614b2bc10 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -154,7 +154,7 @@ void process_sound_events(EngineState *s) { /* Get all sound events, apply their
SongHandle handle;
int cue;
- if (s->_version >= SCI_VERSION_01_EGA)
+ if (s->_version >= SCI_VERSION_01)
return;
/* SCI01 and later explicitly poll for everything */
@@ -940,14 +940,14 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) {
case SI_ABSOLUTE_CUE:
signal = cue;
- fprintf(stderr, "[CUE] %04x:%04x Absolute Cue: %d\n",
+ debugC(2, kDebugLevelSound, "[CUE] %04x:%04x Absolute Cue: %d\n",
PRINT_REG(obj), signal);
PUT_SEL32V(obj, signal, signal);
break;
case SI_RELATIVE_CUE:
- fprintf(stderr, "[CUE] %04x:%04x Relative Cue: %d\n",
+ debugC(2, kDebugLevelSound, "[CUE] %04x:%04x Relative Cue: %d\n",
PRINT_REG(obj), cue);
PUT_SEL32V(obj, dataInc, cue);
@@ -982,9 +982,9 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) {
* Used for synthesized music playback
*/
reg_t kDoSound(EngineState *s, int funct_nr, int argc, reg_t *argv) {
- if (s->_kernel->_selectorMap.setVol != -1)
+ if (s->_kernel->usesSci1SoundFunctions())
return kDoSound_SCI1(s, funct_nr, argc, argv);
- else if (s->_kernel->_selectorMap.nodePtr != -1)
+ else if (s->_kernel->usesSci01SoundFunctions())
return kDoSound_SCI01(s, funct_nr, argc, argv);
else
return kDoSound_SCI0(s, funct_nr, argc, argv);
diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp
index ade0304683..f44af2b1cd 100644
--- a/engines/sci/engine/savegame.cpp
+++ b/engines/sci/engine/savegame.cpp
@@ -497,7 +497,7 @@ static SegmentId find_unique_seg_by_type(SegManager *self, int type) {
}
static byte *find_unique_script_block(EngineState *s, byte *buf, int type) {
- if (s->_flags & GF_SCI0_OLD)
+ if (s->_kernel->hasOldScriptHeader())
buf += 2;
do {
@@ -693,7 +693,7 @@ int _reset_graphics_input(EngineState *s);
static void reconstruct_sounds(EngineState *s) {
Song *seeker;
- SongIteratorType it_type = s->resmgr->_sciVersion >= SCI_VERSION_01_EGA ? SCI_SONG_ITERATOR_TYPE_SCI1 : SCI_SONG_ITERATOR_TYPE_SCI0;
+ SongIteratorType it_type = s->resmgr->_sciVersion >= SCI_VERSION_01 ? SCI_SONG_ITERATOR_TYPE_SCI1 : SCI_SONG_ITERATOR_TYPE_SCI0;
seeker = s->_sound._songlib._lib;
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index e78f3fd77f..b7529c33bd 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -91,9 +91,8 @@ opcode_format g_opcode_formats[128][4] = {
void script_adjust_opcode_formats(int res_version) {
switch (res_version) {
case SCI_VERSION_0:
- case SCI_VERSION_01_EGA:
break;
- case SCI_VERSION_01_VGA:
+ case SCI_VERSION_01:
case SCI_VERSION_01_VGA_ODD:
case SCI_VERSION_1:
case SCI_VERSION_1_1:
@@ -200,10 +199,6 @@ void Kernel::mapSelectors() {
FIND_SELECTOR(printLang);
FIND_SELECTOR(subtitleLang);
FIND_SELECTOR(parseLang);
- FIND_SELECTOR(motionCue);
- FIND_SELECTOR(sightAngle);
- FIND_SELECTOR(setVol);
- FIND_SELECTOR(egoMoveSpeed);
}
void Kernel::dumpScriptObject(char *data, int seeker, int objsize) {
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index a524ddd365..d5f0a21385 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -243,7 +243,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
int stackframe = (scr[pos.offset + 2] >> 1) + (*debugState.p_restadjust);
int argc = ((*debugState.p_sp)[- stackframe - 1]).offset;
- if (!(s->_flags & GF_SCI0_OLD))
+ if (!s->_kernel->hasOldScriptHeader())
argc += (*debugState.p_restadjust);
printf(" Kernel params: (");
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index d81768c9c8..74486ef015 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -138,7 +138,7 @@ void SegManager::setScriptSize(Script &scr, EngineState *s, int script_nr) {
if (!script || (s->_version >= SCI_VERSION_1_1 && !heap)) {
error("SegManager::setScriptSize: failed to load %s", !script ? "script" : "heap");
}
- if (s->_flags & GF_SCI0_OLD) {
+ if (s->_kernel->hasOldScriptHeader()) {
scr.buf_size = script->size + READ_LE_UINT16(script->data) * 2;
//locals_size = READ_LE_UINT16(script->data) * 2;
} else if (s->_version < SCI_VERSION_1_1) {
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 09ed541d17..c6643b8a90 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -961,7 +961,7 @@ void run_vm(EngineState *s, int restoring) {
gc_countdown(s);
xs->sp -= (opparams[1] >> 1) + 1;
- if (!(s->_flags & GF_SCI0_OLD)) {
+ if (!s->_kernel->hasOldScriptHeader()) {
xs->sp -= restadjust;
s->r_amp_rest = 0; // We just used up the restadjust, remember?
}
@@ -971,7 +971,7 @@ void run_vm(EngineState *s, int restoring) {
} else {
int argc = ASSERT_ARITHMETIC(xs->sp[0]);
- if (!(s->_flags & GF_SCI0_OLD))
+ if (!s->_kernel->hasOldScriptHeader())
argc += restadjust;
if (s->_kernel->_kernelFuncs[opparams[0]].signature
@@ -988,7 +988,7 @@ void run_vm(EngineState *s, int restoring) {
xs_new = &(s->_executionStack.back());
s->_executionStackPosChanged = true;
- if (!(s->_flags & GF_SCI0_OLD))
+ if (!s->_kernel->hasOldScriptHeader())
restadjust = s->r_amp_rest;
}
@@ -1211,10 +1211,15 @@ void run_vm(EngineState *s, int restoring) {
case 0x3a: // lofss
r_temp.segment = xs->addr.pc.segment;
- if (s->_kernel->hasLofsAbsolute())
- r_temp.offset = opparams[0];
- else
- r_temp.offset = xs->addr.pc.offset + opparams[0];
+ if (s->_version >= SCI_VERSION_1_1) {
+ r_temp.offset = opparams[0] + local_script->script_size;
+ } else {
+ if (s->_kernel->hasLofsAbsolute())
+ r_temp.offset = opparams[0];
+ else
+ r_temp.offset = xs->addr.pc.offset + opparams[0];
+ }
+
#ifndef DISABLE_VALIDATIONS
if (r_temp.offset >= code_buf_size) {
error("VM: lofss operation overflowed: %04x:%04x beyond end"
@@ -1495,7 +1500,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select
// Early SCI versions used the LSB in the selector ID as a read/write
// toggle, meaning that we must remove it for selector lookup.
- if (s->_flags & GF_SCI0_OLD)
+ if (s->_kernel->hasOldScriptHeader())
selector_id &= ~1;
if (!obj) {
@@ -1654,7 +1659,7 @@ int script_instantiate_sci0(EngineState *s, int script_nr) {
Script *scr = s->seg_manager->getScript(seg_id);
- if (s->_flags & GF_SCI0_OLD) {
+ if (s->_kernel->hasOldScriptHeader()) {
//
int locals_nr = READ_LE_UINT16(script->data);
@@ -1830,7 +1835,7 @@ int script_instantiate(EngineState *s, int script_nr) {
}
void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) {
- reg_t reg = make_reg(seg, (s->_flags & GF_SCI0_OLD) ? 2 : 0);
+ reg_t reg = make_reg(seg, s->_kernel->hasOldScriptHeader() ? 2 : 0);
int objtype, objlength;
Script *scr = s->seg_manager->getScript(seg);
@@ -1874,7 +1879,7 @@ void script_uninstantiate_sci0(EngineState *s, int script_nr, SegmentId seg) {
}
void script_uninstantiate(EngineState *s, int script_nr) {
- reg_t reg = make_reg(0, (s->_flags & GF_SCI0_OLD) ? 2 : 0);
+ reg_t reg = make_reg(0, s->_kernel->hasOldScriptHeader() ? 2 : 0);
reg.segment = s->seg_manager->segGet(script_nr);
Script *scr = script_locate_by_segment(s, reg.segment);
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index adaa064a6c..a3fabbe44b 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -203,10 +203,6 @@ struct selector_map_t {
Selector printLang; /**< Used for i18n */
Selector subtitleLang;
Selector parseLang;
- Selector motionCue; // Used to detect newer graphics functions semantics.
- Selector sightAngle; // Used to detect some SCI0/SCI01 games which need a SCI1 table
- Selector setVol; // Used to detect newer sound semantics
- Selector egoMoveSpeed; // Used to detect SCI1 games which use absolute values in lofs
};
// A reference to an object's variable.
diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp
index 4abcc1fb78..9343b66cb8 100644
--- a/engines/sci/gfx/gfx_resmgr.cpp
+++ b/engines/sci/gfx/gfx_resmgr.cpp
@@ -49,14 +49,14 @@ struct param_struct {
GfxDriver *driver;
};
-GfxResManager::GfxResManager(int version, bool isVGA, gfx_options_t *options, GfxDriver *driver, ResourceManager *resManager) :
- _version(version), _isVGA(isVGA), _options(options), _driver(driver), _resManager(resManager),
+GfxResManager::GfxResManager(int version, gfx_options_t *options, GfxDriver *driver, ResourceManager *resManager) :
+ _version(version), _options(options), _driver(driver), _resManager(resManager),
_lockCounter(0), _tagLockCounter(0), _staticPalette(0) {
gfxr_init_static_palette();
_portBounds = Common::Rect(0, 10, 320, 200); // default value, with a titlebar of 10px
- if (_version < SCI_VERSION_01_VGA || !_isVGA) {
+ if (!_resManager->isVGA()) {
_staticPalette = gfx_sci0_pic_colors->getref();
} else if (_version == SCI_VERSION_1_1) {
debugC(2, kDebugLevelGraphics, "Palettes are not yet supported in this SCI version\n");
@@ -99,7 +99,7 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic
if (_version == SCI_VERSION_1_1)
gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _staticPalette, _portBounds);
else
- gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _isVGA, _staticPalette, _portBounds);
+ gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _resManager->isVGA(), _staticPalette, _portBounds);
}
if (scaled_pic && scaled_pic->undithered_buffer)
@@ -108,9 +108,9 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic
if (_version == SCI_VERSION_1_1)
gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _staticPalette, _portBounds);
else
- gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _isVGA, _staticPalette, _portBounds);
+ gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _resManager->isVGA(), _staticPalette, _portBounds);
- if (!_isVGA) {
+ if (!_resManager->isVGA()) {
if (need_unscaled)
gfxr_remove_artifacts_pic0(scaled_pic, unscaled_pic);
@@ -144,7 +144,7 @@ int GfxResManager::getOptionsHash(gfx_resource_type_t type) {
case GFX_RESOURCE_TYPE_PIC:
#ifdef CUSTOM_GRAPHICS_OPTIONS
- if (_version >= SCI_VERSION_01_VGA)
+ if (_resManager->isVGA())
// NOTE: here, it is assumed that the upper port bound is always 10, but this doesn't seem to matter for the
// generated options hash anyway
return 10;
@@ -153,7 +153,7 @@ int GfxResManager::getOptionsHash(gfx_resource_type_t type) {
| (_options->pic0_dither_pattern << 8) | (_options->pic0_brush_mode << 4)
| (_options->pic0_line_mode);
#else
- if (_version >= SCI_VERSION_01_VGA)
+ if (_resManager->isVGA())
return 10;
else
return 0x10000 | (GFXR_DITHER_PATTERN_SCALED << 8) | (GFX_BRUSH_MODE_RANDOM_ELLIPSES << 4) | GFX_LINE_MODE_CORRECT;
@@ -341,12 +341,12 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale
#ifdef CUSTOM_GRAPHICS_OPTIONS
if (_options->pic0_unscaled) {
need_unscaled = 0;
- pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _version >= SCI_VERSION_01_VGA);
+ pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resManager->isVGA());
} else
- pic = gfxr_init_pic(_driver->getMode(), GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _version >= SCI_VERSION_01_VGA);
+ pic = gfxr_init_pic(_driver->getMode(), GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resManager->isVGA());
#else
need_unscaled = 0;
- pic = gfxr_init_pic(_driver->getMode(), GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _version >= SCI_VERSION_01_VGA);
+ pic = gfxr_init_pic(_driver->getMode(), GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resManager->isVGA());
#endif
if (!pic) {
@@ -357,7 +357,7 @@ gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_pale
gfxr_clear_pic0(pic, SCI_TITLEBAR_SIZE);
if (need_unscaled) {
- unscaled_pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _version >= SCI_VERSION_01_VGA);
+ unscaled_pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resManager->isVGA());
if (!unscaled_pic) {
error("Failed to allocate unscaled pic");
return NULL;
@@ -530,17 +530,16 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) {
return NULL;
int resid = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr);
+
+ if (!_resManager->isVGA()) {
+ int pal = (_version == SCI_VERSION_0) ? -1 : palette;
+ view = getEGAView(resid, viewRes->data, viewRes->size, pal);
+ } else {
+ if (_version < SCI_VERSION_1_1)
+ view = getVGAView(resid, viewRes->data, viewRes->size, _staticPalette, false);
+ else
+ view = getVGAView(resid, viewRes->data, viewRes->size, 0, true);
- if (_version < SCI_VERSION_01_EGA)
- view = gfxr_draw_view0(resid, viewRes->data, viewRes->size, -1);
- else if (_version == SCI_VERSION_01_EGA || !_isVGA)
- view = gfxr_draw_view0(resid, viewRes->data, viewRes->size, palette);
- else if (_version >= SCI_VERSION_01_VGA && _version <= SCI_VERSION_1)
- view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, _staticPalette, false);
- else if (_version >= SCI_VERSION_1_1)
- view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, 0, true);
-
- if (_isVGA) {
if (!view->palette) {
view->palette = new Palette(_staticPalette->size());
view->palette->name = "interpreter_get_view";
@@ -554,7 +553,6 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) {
view->palette->setColor(i, sc.r, sc.g, sc.b);
}
}
-
}
if (!res) {
@@ -619,6 +617,11 @@ gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) {
gfx_resource_t *res = NULL;
int hash = getOptionsHash(GFX_RESOURCE_TYPE_FONT);
+ // Workaround: LSL1VGA mixes its own internal fonts with the global
+ // SCI ones, so we translate them here, by removing their extra bits
+ if (!resMap.contains(num) && !_resManager->testResource(ResourceId(kResourceTypeFont, num)))
+ num = num & 0x7ff;
+
res = resMap.contains(num) ? resMap[num] : NULL;
if (!res || res->mode != hash) {
diff --git a/engines/sci/gfx/gfx_resmgr.h b/engines/sci/gfx/gfx_resmgr.h
index 1f0f58dce9..8230e84aa0 100644
--- a/engines/sci/gfx/gfx_resmgr.h
+++ b/engines/sci/gfx/gfx_resmgr.h
@@ -90,7 +90,7 @@ typedef Common::HashMap<int, gfx_resource_t *> IntResMap;
/** Graphics resource manager */
class GfxResManager {
public:
- GfxResManager(int version, bool isVGA, gfx_options_t *options,
+ GfxResManager(int version, gfx_options_t *options,
GfxDriver *driver, ResourceManager *resManager);
~GfxResManager();
@@ -311,14 +311,12 @@ public:
*
* @return Number of pallete entries
*/
- int getColorCount()
- {
+ int getColorCount() {
return _staticPalette ? _staticPalette->size() : 0;
}
private:
int _version;
- bool _isVGA;
gfx_options_t *_options;
GfxDriver *_driver;
Palette *_staticPalette;
diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h
index 780060bc4f..9c83cf07cd 100644
--- a/engines/sci/gfx/gfx_resource.h
+++ b/engines/sci/gfx/gfx_resource.h
@@ -245,7 +245,7 @@ void gfxr_remove_artifacts_pic0(gfxr_pic_t *dest, gfxr_pic_t *src);
void gfxr_dither_pic0(gfxr_pic_t *pic, int mode, int pattern);
/**
- * Calculates a SCI0 view.
+ * Calculates an EGA view.
*
* @param[in] id Resource ID of the view
* @param[in] resource Pointer to the resource to read
@@ -253,7 +253,7 @@ void gfxr_dither_pic0(gfxr_pic_t *pic, int mode, int pattern);
* @param[in] palette The palette to use
* @return The resulting view
*/
-gfxr_view_t *gfxr_draw_view0(int id, byte *resource, int size, int palette);
+gfxr_view_t *getEGAView(int id, byte *resource, int size, int palette);
/**
* Calculates a SCI cursor.
@@ -265,8 +265,7 @@ gfxr_view_t *gfxr_draw_view0(int id, byte *resource, int size, int palette);
* @return A newly allocated pixmap containing an index color
* representation of the cursor
*/
-gfx_pixmap_t *gfxr_draw_cursor(int id, byte *resource, int size,
- bool isSci01);
+gfx_pixmap_t *gfxr_draw_cursor(int id, byte *resource, int size, bool isSci01);
/** @} */
@@ -304,7 +303,7 @@ Palette *gfxr_read_pal1_amiga(Common::File &file);
Palette *gfxr_read_pal11(int id, byte *resource, int size);
/**
- * Calculates an SCI1 view.
+ * Calculates a VGA view.
*
* @param[in] id Resource ID of the view
* @param[in] resource Pointer to the resource to read
@@ -313,7 +312,7 @@ Palette *gfxr_read_pal11(int id, byte *resource, int size);
* @param[in] isSci11 true if SCI1.1, false otherwise
* @return The resulting view
*/
-gfxr_view_t *gfxr_draw_view1(int id, byte *resource, int size, Palette *static_pal, bool isSci11);
+gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, bool isSci11);
gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, bool isAmiga, bool isSci11);
/** @} */
diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp
index 80adb9eddb..057f28b56f 100644
--- a/engines/sci/gfx/operations.cpp
+++ b/engines/sci/gfx/operations.cpp
@@ -404,7 +404,7 @@ static void init_aux_pixmap(gfx_pixmap_t **pixmap) {
(*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR);
}
-int gfxop_init(int version, bool isVGA, GfxState *state,
+int gfxop_init(int version, GfxState *state,
gfx_options_t *options, ResourceManager *resManager,
Graphics::PixelFormat mode, int xfact, int yfact) {
//int color_depth = bpp ? bpp : 1;
@@ -424,8 +424,8 @@ int gfxop_init(int version, bool isVGA, GfxState *state,
state->driver = new GfxDriver(xfact, yfact, mode);
- state->gfxResMan = new GfxResManager(version, isVGA, state->options, state->driver, resManager);
-
+ state->gfxResMan = new GfxResManager(version, state->options, state->driver, resManager);
+
gfxop_set_clip_zone(state, gfx_rect(0, 0, 320, 200));
init_aux_pixmap(&(state->control_map));
diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h
index d567934ceb..ec0a810224 100644
--- a/engines/sci/gfx/operations.h
+++ b/engines/sci/gfx/operations.h
@@ -135,7 +135,6 @@ struct GfxState {
* Initializes a graphics mode.
*
* @param[in] version The interpreter version
- * @param[in] isVGA true if using VGA resolution
* @param[in] state The state to initialize
* @param[in] xfact Horizontal scale factor
* @param[in] yfact Vertical scale factors
@@ -146,7 +145,7 @@ struct GfxState {
* is unavailable, or GFX_FATAL if the graphics driver
* is unable to provide any useful graphics support
*/
-int gfxop_init(int version, bool isVGA, GfxState *state,
+int gfxop_init(int version, GfxState *state,
gfx_options_t *options, ResourceManager *resManager,
Graphics::PixelFormat mode, int xfact = 1, int yfact = 1);
diff --git a/engines/sci/gfx/res_view.cpp b/engines/sci/gfx/res_view.cpp
index 41cb55fa75..d484136f8e 100644
--- a/engines/sci/gfx/res_view.cpp
+++ b/engines/sci/gfx/res_view.cpp
@@ -135,7 +135,7 @@ gfx_pixmap_t *gfxr_draw_cel0(int id, int loop, int cel, byte *resource, int size
return retval;
}
-gfxr_view_t *gfxr_draw_view0(int id, byte *resource, int size, int palette) {
+gfxr_view_t *getEGAView(int id, byte *resource, int size, int palette) {
int i;
gfxr_view_t *view;
int mirror_bitpos = 1;
@@ -365,7 +365,7 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso
return retval;
}
-gfxr_view_t *gfxr_draw_view1(int id, byte *resource, int size, Palette *static_pal, bool isSci11) {
+gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, bool isSci11) {
uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + (isSci11 ? 2 : 0));
uint16 headerSize = isSci11 ? READ_LE_UINT16(resource + V2_HEADER_SIZE) : 0;
byte* seeker = resource + headerSize;
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 15e05ea656..30e917557d 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -42,19 +42,6 @@ namespace Sci {
//#define SCI_VERBOSE_RESMGR 1
-const char *sci_version_types[] = {
- "SCI version undetermined (Autodetect failed / not run)",
- "SCI version 0.xxx",
- "SCI version 0.xxx w/ 1.000 compression",
- "SCI version 1.000 w/ 0.xxx resource.map",
- "SCI version 1.000 w/ special resource.map",
- "SCI version 1.000",
- "SCI version 1.001",
- "SCI WIN/32"
-};
-
-const int sci_max_resource_nr[] = {65536, 1000, 2048, 2048, 2048, 65536, 65536, 65536};
-
static const char *sci_error_types[] = {
"No error",
"I/O error",
@@ -358,7 +345,7 @@ int ResourceManager::guessSciVersion() {
file.close();
if (compression == 3) {
- return SCI_VERSION_01_VGA;
+ return SCI_VERSION_01;
}
}
@@ -382,7 +369,7 @@ int ResourceManager::guessSciVersion() {
file.close();
if (compression == 3) {
- return SCI_VERSION_01_VGA;
+ return SCI_VERSION_01;
}
}
@@ -484,8 +471,8 @@ ResourceManager::ResourceManager(int version, int maxMemory) {
_mapVersion = detectMapVersion();
_volVersion = detectVolVersion();
}
- debug("Using resource map version %d %s", _mapVersion, sci_version_types[_mapVersion]);
- debug("Using volume version %d %s", _volVersion, sci_version_types[_volVersion]);
+ debug("Using resource map version %d %s", _mapVersion, versionNames[_mapVersion]);
+ debug("Using volume version %d %s", _volVersion, versionNames[_volVersion]);
scanNewSources();
addInternalSources();
@@ -495,14 +482,14 @@ ResourceManager::ResourceManager(int version, int maxMemory) {
switch (_mapVersion) {
case SCI_VERSION_0:
if (testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB))) {
- version = guessSciVersion() ? SCI_VERSION_01_VGA : SCI_VERSION_0;
+ version = guessSciVersion() ? SCI_VERSION_01 : SCI_VERSION_0;
} else if (testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB))) {
version = guessSciVersion();
- if (version != SCI_VERSION_01_VGA) {
- version = testResource(ResourceId(kResourceTypeVocab, 912)) ? SCI_VERSION_0 : SCI_VERSION_01_EGA;
+ if (version != SCI_VERSION_01) {
+ version = testResource(ResourceId(kResourceTypeVocab, 912)) ? SCI_VERSION_0 : SCI_VERSION_01;
}
} else {
- version = guessSciVersion() ? SCI_VERSION_01_VGA : SCI_VERSION_0;
+ version = guessSciVersion() ? SCI_VERSION_01 : SCI_VERSION_0;
}
break;
case SCI_VERSION_01_VGA_ODD:
@@ -519,18 +506,37 @@ ResourceManager::ResourceManager(int version, int maxMemory) {
version = SCI_VERSION_AUTODETECT;
}
+ _isVGA = false;
+
+ // Determine if the game is using EGA graphics or not
+ if (version == SCI_VERSION_0) {
+ _isVGA = false; // There is no SCI0 VGA game
+ } else if (version >= SCI_VERSION_1_1) {
+ _isVGA = true; // There is no SCI11 EGA game
+ } else {
+ // SCI01 or SCI1: EGA games have the second byte of their views set
+ // to 0, VGA ones to non-zero
+ int i = 0;
+
+ while (true) {
+ Resource *res = findResource(ResourceId(kResourceTypeView, i), 0);
+ if (res) {
+ _isVGA = (res->data[1] != 0);
+ break;
+ }
+ i++;
+ }
+ }
+
_sciVersion = version;
// temporary version printout - should be reworked later
switch (_sciVersion) {
case SCI_VERSION_0:
debug("Resmgr: Detected SCI0");
break;
- case SCI_VERSION_01_EGA:
+ case SCI_VERSION_01:
debug("Resmgr: Detected SCI01");
break;
- case SCI_VERSION_01_VGA:
- debug("Resmgr: Detected SCI01VGA - KQ5 or similar");
- break;
case SCI_VERSION_01_VGA_ODD:
debug("Resmgr: Detected SCI01VGA - Jones/CD or similar");
break;
@@ -549,6 +555,11 @@ ResourceManager::ResourceManager(int version, int maxMemory) {
debug("Resmgr: Couldn't determine SCI version");
break;
}
+
+ if (_isVGA)
+ debug("Resmgr: Detected VGA graphic resources");
+ else
+ debug("Resmgr: Detected non-VGA/EGA graphic resources");
}
ResourceManager::~ResourceManager() {
@@ -636,16 +647,7 @@ Common::List<ResourceId> *ResourceManager::listResources(ResourceType type, int
}
Resource *ResourceManager::findResource(ResourceId id, bool lock) {
- Resource *retval;
-
- if (id.number >= sci_max_resource_nr[_sciVersion]) {
- ResourceId moddedId = ResourceId(id.type, id.number % sci_max_resource_nr[_sciVersion], id.tuple);
- warning("[resmgr] Requested invalid resource %s, mapped to %s",
- id.toString().c_str(), moddedId.toString().c_str());
- id = moddedId;
- }
-
- retval = testResource(id);
+ Resource *retval = testResource(id);
if (!retval)
return NULL;
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 8ef42b171d..b212a36710 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -82,10 +82,6 @@ enum ResSourceType {
#define SCI1_RESMAP_ENTRIES_SIZE 6
#define SCI11_RESMAP_ENTRIES_SIZE 5
-extern const char *sci_version_types[];
-extern const int sci_max_resource_nr[]; /**< Highest possible resource numbers */
-
-
enum ResourceType {
kResourceTypeView = 0,
kResourceTypePic,
@@ -214,6 +210,8 @@ public:
int _mapVersion; //!< RESOURCE.MAP version
int _volVersion; //!< RESOURCE.0xx version
+ bool isVGA() const { return _isVGA; }
+
/**
* Creates a new SCI resource manager.
* @param version The SCI version to look for; use SCI_VERSION_AUTODETECT
@@ -265,6 +263,7 @@ public:
void setAudioLanguage(int language);
protected:
+ bool _isVGA; // Used to determine if the game has EGA or VGA graphics
int _maxMemory; //!< Config option: Maximum total byte number allocated
Common::List<ResourceSource *> _sources;
int _memoryLocked; //!< Amount of resource bytes in locked memory
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index 7e2940dbd1..2992a1b347 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -43,11 +43,10 @@ namespace Sci {
class GfxDriver;
-const char *versionNames[8] = {
+const char *versionNames[7] = {
"Autodetected",
"SCI0",
- "SCI01 EGA",
- "SCI01 VGA",
+ "SCI01",
"SCI01 VGA ODD",
"SCI1",
"SCI1.1",
@@ -158,27 +157,14 @@ Common::Error SciEngine::run() {
// Verify that we haven't got an invalid game detection entry
if (version < SCI_VERSION_1) {
// SCI0/SCI01
- if (flags & GF_SCI1_EGA) {
- error("This game entry is erroneous. It's marked as SCI0/SCI01, but it has SCI1 flags set");
- }
} else if (version == SCI_VERSION_1) {
- // SCI1
-
- if (flags & GF_SCI0_OLD ||
- flags & GF_SCI0_OLDGETTIME) {
+ if (flags & GF_SCI0_OLDGETTIME) {
error("This game entry is erroneous. It's marked as SCI1, but it has SCI0 flags set");
}
} else if (version == SCI_VERSION_1_1 || version == SCI_VERSION_32) {
- if (flags & GF_SCI1_EGA) {
- error("This game entry is erroneous. It's marked as SCI1.1/SCI32, but it has SCI1 flags set");
- }
-
- if (flags & GF_SCI0_OLD ||
- flags & GF_SCI0_OLDGETTIME) {
+ if (flags & GF_SCI0_OLDGETTIME) {
error("This game entry is erroneous. It's marked as SCI1.1/SCI32, but it has SCI0 flags set");
}
-
- // SCI1.1 / SCI32
} else {
error ("Unknown SCI version in game entry");
}
@@ -225,8 +211,7 @@ Common::Error SciEngine::run() {
// Default config ends
#endif
- bool isVGA = _resmgr->_sciVersion >= SCI_VERSION_01_VGA && !(getFlags() & GF_SCI1_EGA);
- if (gfxop_init(_resmgr->_sciVersion, isVGA, &gfx_state, &gfx_options, _resmgr, gfxmode, 1, 1)) {
+ if (gfxop_init(_resmgr->_sciVersion, &gfx_state, &gfx_options, _resmgr, gfxmode, 1, 1)) {
warning("Graphics initialization failed. Aborting...");
return Common::kUnknownError;
}
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index 4404165c53..a2de5c3136 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -71,41 +71,22 @@ struct SciGameDescription {
enum SciGameVersions {
SCI_VERSION_AUTODETECT = 0,
SCI_VERSION_0 = 1,
- SCI_VERSION_01_EGA = 2,
- SCI_VERSION_01_VGA = 3,
- SCI_VERSION_01_VGA_ODD = 4,
- SCI_VERSION_1 = 5,
- SCI_VERSION_1_1 = 6,
- SCI_VERSION_32 = 7
+ SCI_VERSION_01 = 2,
+ SCI_VERSION_01_VGA_ODD = 3,
+ SCI_VERSION_1 = 4,
+ SCI_VERSION_1_1 = 5,
+ SCI_VERSION_32 = 6
};
-extern const char *versionNames[8];
+extern const char *versionNames[7];
enum SciGameFlags {
// SCI0 flags
- /* Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2)
- * Old SCI versions used two word header for script blocks (first word equal
- * to 0x82, meaning of the second one unknown). New SCI versions used one
- * word header.
- * Also, old SCI versions assign 120 degrees to left & right, and 60 to up
- * and down. Later versions use an even 90 degree distribution.
- */
- GF_SCI0_OLD = (1 << 0),
-
/* Applies to all versions before 0.000.629
* Older SCI versions had simpler code for GetTime()
*/
- GF_SCI0_OLDGETTIME = (1 << 1),
-
- // ----------------------------------------------------------------------------
-
- // SCI1 flags
-
- /*
- * Used to distinguish SCI1 EGA games
- */
- GF_SCI1_EGA = (1 << 2)
+ GF_SCI0_OLDGETTIME = (1 << 0)
};
class SciEngine : public Engine {
diff --git a/engines/sci/sfx/iterator.cpp b/engines/sci/sfx/iterator.cpp
index 4e5b20a5d2..ebba4bceac 100644
--- a/engines/sci/sfx/iterator.cpp
+++ b/engines/sci/sfx/iterator.cpp
@@ -27,6 +27,7 @@
#include "common/util.h"
+#include "sci/sci.h"
#include "sci/sfx/iterator_internal.h"
#include "sci/sfx/misc.h" // for sfx_player_tell_synth
#include "sci/tools.h"
@@ -233,7 +234,7 @@ int BaseSongIterator::parseMidiCommand(byte *buf, int *result, SongIteratorChann
channel->state = SI_STATE_DELTA_TIME;
channel->total_timepos = channel->loop_timepos;
channel->last_cmd = 0xfe;
- fprintf(stderr, "Looping song iterator %08lx.\n", ID);
+ debugC(2, kDebugLevelSound, "Looping song iterator %08lx.\n", ID);
return SI_LOOP;
} else {
channel->state = SI_STATE_FINISHED;
@@ -379,7 +380,7 @@ int BaseSongIterator::processMidi(byte *buf, int *result,
channel->state = SI_STATE_FINISHED;
delay = (size * 50 + format.rate - 1) / format.rate; /* number of ticks to completion*/
- fprintf(stderr, "delaying %d ticks\n", delay);
+ debugC(2, kDebugLevelSound, "delaying %d ticks\n", delay);
return delay;
}
@@ -523,7 +524,7 @@ static int _sci0_get_pcm_data(Sci0SongIterator *self,
}
static Audio::AudioStream *makeStream(byte *data, int size, sfx_pcm_config_t conf) {
- printf("Playing PCM data of size %d, rate %d\n", size, conf.rate);
+ debugC(2, kDebugLevelSound, "Playing PCM data of size %d, rate %d\n", size, conf.rate);
// Duplicate the data
byte *sound = (byte *)malloc(size);
@@ -563,7 +564,7 @@ SongIterator *Sci0SongIterator::handleMessage(Message msg) {
case _SIMSG_BASEMSG_PRINT:
print_tabs_id(msg._arg.i, ID);
- fprintf(stderr, "SCI0: dev=%d, active-chan=%d, size=%d, loops=%d\n",
+ debugC(2, kDebugLevelSound, "SCI0: dev=%d, active-chan=%d, size=%d, loops=%d\n",
_deviceId, _numActiveChannels, _data.size(), _loops);
break;
@@ -980,7 +981,7 @@ SongIterator *Sci1SongIterator::handleMessage(Message msg) {
playmask |= _channels[i].playmask;
print_tabs_id(msg._arg.i, ID);
- fprintf(stderr, "SCI1: chan-nr=%d, playmask=%04x\n",
+ debugC(2, kDebugLevelSound, "SCI1: chan-nr=%d, playmask=%04x\n",
_numChannels, playmask);
}
break;
@@ -1142,7 +1143,7 @@ public:
SongIterator *CleanupSongIterator::handleMessage(Message msg) {
if (msg._class == _SIMSG_BASEMSG_PRINT && msg._type == _SIMSG_BASEMSG_PRINT) {
print_tabs_id(msg._arg.i, ID);
- fprintf(stderr, "CLEANUP\n");
+ debugC(2, kDebugLevelSound, "CLEANUP\n");
}
return NULL;
@@ -1208,7 +1209,7 @@ SongIterator *FastForwardSongIterator::handleMessage(Message msg) {
if (msg._class == _SIMSG_BASE && msg._type == _SIMSG_BASEMSG_PRINT) {
print_tabs_id(msg._arg.i, ID);
- fprintf(stderr, "FASTFORWARD:\n");
+ debugC(2, kDebugLevelSound, "FASTFORWARD:\n");
msg._arg.i++;
}
@@ -1532,7 +1533,7 @@ SongIterator *TeeSongIterator::handleMessage(Message msg) {
if (msg._class == _SIMSG_BASE && msg._type == _SIMSG_BASEMSG_PRINT) {
print_tabs_id(msg._arg.i, ID);
- fprintf(stderr, "TEE:\n");
+ debugC(2, kDebugLevelSound, "TEE:\n");
msg._arg.i++;
}
@@ -1576,15 +1577,15 @@ int songit_next(SongIterator **it, byte *buf, int *result, int mask) {
do {
retval = (*it)->nextCommand(buf, result);
if (retval == SI_MORPH) {
- fprintf(stderr, " Morphing %p (stored at %p)\n", (void *)*it, (void *)it);
+ debugC(2, kDebugLevelSound, " Morphing %p (stored at %p)\n", (void *)*it, (void *)it);
if (!SIMSG_SEND((*it), SIMSG_ACK_MORPH)) {
error("SI_MORPH failed. Breakpoint in %s, line %d", __FILE__, __LINE__);
} else
- fprintf(stderr, "SI_MORPH successful\n");
+ debugC(2, kDebugLevelSound, "SI_MORPH successful\n");
}
if (retval == SI_FINISHED)
- fprintf(stderr, "[song-iterator] Song finished. mask = %04x, cm=%04x\n",
+ debugC(2, kDebugLevelSound, "[song-iterator] Song finished. mask = %04x, cm=%04x\n",
mask, (*it)->channel_mask);
if (retval == SI_FINISHED
&& (mask & IT_READER_MAY_CLEAN)
diff --git a/engines/sci/vocabulary.cpp b/engines/sci/vocabulary.cpp
index dd56cdf88a..5253e7885b 100644
--- a/engines/sci/vocabulary.cpp
+++ b/engines/sci/vocabulary.cpp
@@ -91,7 +91,7 @@ Vocabulary::Vocabulary(ResourceManager *resmgr) : _resmgr(resmgr) {
debug(2, "Initializing vocabulary");
- if (_resmgr->_sciVersion < SCI_VERSION_01_VGA && loadParserWords()) {
+ if (_resmgr->_sciVersion <= SCI_VERSION_01 && loadParserWords()) {
loadSuffixes();
if (loadBranches())
// Now build a GNF grammar out of this
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index e62d9406d3..81b28ce563 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -567,7 +567,7 @@ void ScummEngine::checkExecVerbs() {
}
if (_game.platform == Common::kPlatformFMTowns && _game.version == 3) {
- // HACK: In the FM-Towns games Indy3, Loom and Zak the most significant bit is set for special keys
+ // HACK: In the FM-TOWNS games Indy3, Loom and Zak the most significant bit is set for special keys
// like F5 (=0x8005) or joystick buttons (mask 0xFE00, e.g. SELECT=0xFE40 for the save/load menu).
// Hence the distinction with (_mouseAndKeyboardStat < MBS_MAX_KEY) between mouse- and key-events is not applicable
// to this games, so we have to remap the special keys here.
diff --git a/graphics/module.mk b/graphics/module.mk
index 8d7f2031c0..2387bb708c 100644
--- a/graphics/module.mk
+++ b/graphics/module.mk
@@ -16,6 +16,7 @@ MODULE_OBJS := \
primitives.o \
scaler.o \
scaler/thumbnail_intern.o \
+ sjis.o \
surface.o \
thumbnail.o \
VectorRenderer.o \
diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp
new file mode 100644
index 0000000000..5392a1c9a4
--- /dev/null
+++ b/graphics/sjis.cpp
@@ -0,0 +1,197 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+#include "graphics/sjis.h"
+
+#ifdef GRAPHICS_SJIS_H
+
+#include "common/debug.h"
+
+namespace Graphics {
+
+bool FontTowns::loadFromStream(Common::ReadStream &stream) {
+ for (uint i = 0; i < (kFontRomSize / 2); ++i)
+ _fontData[i] = stream.readUint16BE();
+ return !stream.err();
+}
+
+template<typename Color>
+void FontTowns::drawCharInternOutline(const uint16 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const {
+ uint32 outlineGlyph[18];
+ memset(outlineGlyph, 0, sizeof(outlineGlyph));
+
+ // Create an outline map including the original character
+ const uint16 *src = glyph;
+ for (int i = 0; i < 16; ++i) {
+ uint32 line = *src++;
+ line = (line << 2) | (line << 1) | (line << 0);
+
+ outlineGlyph[i + 0] |= line;
+ outlineGlyph[i + 1] |= line;
+ outlineGlyph[i + 2] |= line;
+ }
+
+ uint8 *dstLine = dst;
+ for (int y = 0; y < 18; ++y) {
+ Color *lineBuf = (Color *)dstLine;
+ uint32 line = outlineGlyph[y];
+
+ for (int x = 0; x < 18; ++x) {
+ if (line & 0x20000)
+ *lineBuf = c2;
+ line <<= 1;
+ ++lineBuf;
+ }
+
+ dstLine += pitch;
+ }
+
+ // draw the original char
+ drawCharIntern<Color>(glyph, dst + pitch + 1, pitch, c1);
+}
+
+template<typename Color>
+void FontTowns::drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const {
+ for (int y = 0; y < 16; ++y) {
+ Color *lineBuf = (Color *)dst;
+ uint16 line = *glyph++;
+
+ for (int x = 0; x < 16; ++x) {
+ if (line & 0x8000)
+ *lineBuf = c1;
+ line <<= 1;
+ ++lineBuf;
+ }
+
+ dst += pitch;
+ }
+}
+
+void FontTowns::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const {
+ const uint16 *glyphSource = _fontData + sjisToChunk(ch & 0xFF, ch >> 8) * 16;
+
+ if (bpp == 1) {
+ if (!_outlineEnabled)
+ drawCharIntern<uint8>(glyphSource, (uint8 *)dst, pitch, c1);
+ else
+ drawCharInternOutline<uint8>(glyphSource, (uint8 *)dst, pitch, c1, c2);
+ } else if (bpp == 2) {
+ if (!_outlineEnabled)
+ drawCharIntern<uint16>(glyphSource, (uint8 *)dst, pitch, c1);
+ else
+ drawCharInternOutline<uint16>(glyphSource, (uint8 *)dst, pitch, c1, c2);
+ } else {
+ error("FontTowns::drawChar: unsupported bpp: %d", bpp);
+ }
+}
+
+uint FontTowns::sjisToChunk(uint8 f, uint8 s) {
+ // copied from scumm\charset.cpp
+ enum {
+ KANA = 0,
+ KANJI = 1,
+ EKANJI = 2
+ };
+
+ int base = s - ((s + 1) % 32);
+ int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA;
+
+ if (f >= 0x81 && f <= 0x84) kanjiType = KANA;
+ if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI;
+ if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI;
+
+ if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) {
+ c = 48; //correction
+ p = -8; //correction
+ }
+
+ if (kanjiType == KANA) {//Kana
+ chunk_f = (f - 0x81) * 2;
+ } else if (kanjiType == KANJI) {//Standard Kanji
+ p += f - 0x88;
+ chunk_f = c + 2 * p;
+ } else if (kanjiType == EKANJI) {//Enhanced Kanji
+ p += f - 0xe0;
+ chunk_f = c + 2 * p;
+ }
+
+ // Base corrections
+ if (base == 0x7f && s == 0x7f)
+ base -= 0x20;
+ if (base == 0x9f && s == 0xbe)
+ base += 0x20;
+ if (base == 0xbf && s == 0xde)
+ base += 0x20;
+ //if (base == 0x7f && s == 0x9e)
+ // base += 0x20;
+
+ switch (base) {
+ case 0x3f:
+ cr = 0; //3f
+ if (kanjiType == KANA) chunk = 1;
+ else if (kanjiType == KANJI) chunk = 31;
+ else if (kanjiType == EKANJI) chunk = 111;
+ break;
+ case 0x5f:
+ cr = 0; //5f
+ if (kanjiType == KANA) chunk = 17;
+ else if (kanjiType == KANJI) chunk = 47;
+ else if (kanjiType == EKANJI) chunk = 127;
+ break;
+ case 0x7f:
+ cr = -1; //80
+ if (kanjiType == KANA) chunk = 9;
+ else if (kanjiType == KANJI) chunk = 63;
+ else if (kanjiType == EKANJI) chunk = 143;
+ break;
+ case 0x9f:
+ cr = 1; //9e
+ if (kanjiType == KANA) chunk = 2;
+ else if (kanjiType == KANJI) chunk = 32;
+ else if (kanjiType == EKANJI) chunk = 112;
+ break;
+ case 0xbf:
+ cr = 1; //be
+ if (kanjiType == KANA) chunk = 18;
+ else if (kanjiType == KANJI) chunk = 48;
+ else if (kanjiType == EKANJI) chunk = 128;
+ break;
+ case 0xdf:
+ cr = 1; //de
+ if (kanjiType == KANA) chunk = 10;
+ else if (kanjiType == KANJI) chunk = 64;
+ else if (kanjiType == EKANJI) chunk = 144;
+ break;
+ default:
+ debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p);
+ }
+
+ debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr);
+ return ((chunk_f + chunk) * 32 + (s - base)) + cr;
+}
+
+} // end of namespace Graphics
+
+#endif // defined(GRAPHICS_SJIS_H)
+
diff --git a/graphics/sjis.h b/graphics/sjis.h
new file mode 100644
index 0000000000..f7321742af
--- /dev/null
+++ b/graphics/sjis.h
@@ -0,0 +1,135 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ */
+
+// The code in this file is currently only used in KYRA and SCI.
+// So if neither of those is enabled, we will skip compiling it.
+// If you plan to use this code in another engine, you will have
+// to add the proper define check here.
+// Also please add the define check at the comment after the
+// matching #endif further down this file.
+#if defined(ENABLE_KYRA) || defined(ENABLE_SCI)
+
+#ifndef GRAPHICS_SJIS_H
+#define GRAPHICS_SJIS_H
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+
+#include "graphics/surface.h"
+
+namespace Graphics {
+
+/**
+ * A font that is able to draw SJIS encoded characters.
+ *
+ * The font is always monospaced.
+ */
+class FontSJIS {
+public:
+ virtual ~FontSJIS() {}
+
+ /**
+ * Enable outline drawing.
+ *
+ * After changing outline state, getFontHeight and getFontWidth might return
+ * different values!
+ */
+ virtual void enableOutline(bool enable) {}
+
+ /**
+ * Returns the height of the font.
+ */
+ virtual uint getFontHeight() const = 0;
+
+ /**
+ * Returns the width of the font.
+ */
+ virtual uint getFontWidth() const = 0;
+
+ /**
+ * Draws a SJIS encoded character on the given surface.
+ */
+ void drawChar(Graphics::Surface &dst, uint16 ch, int x, int y, uint32 c1, uint32 c2) const {
+ drawChar(dst.getBasePtr(x, y), ch, c1, c2, dst.pitch, dst.bytesPerPixel);
+ }
+
+ /**
+ * Draws a SJIS char on the given raw buffer.
+ *
+ * @param dst pointer to the destination
+ * @param ch character to draw
+ * @param pitch pitch of the destination buffer (size in *bytes*)
+ * @param bpp bytes per pixel of the destination buffer
+ * @param c1 forground color
+ * @param c2 outline color
+ */
+ virtual void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const = 0;
+};
+
+/**
+ * FM-TOWNS ROM based SJIS compatible font.
+ *
+ * This is used in KYRA and SCI.
+ */
+class FontTowns : public FontSJIS {
+public:
+ FontTowns() : _outlineEnabled(false) {}
+
+ /**
+ * Loads the ROM data from the given read stream.
+ */
+ bool loadFromStream(Common::ReadStream &stream);
+
+ void enableOutline(bool enable) { _outlineEnabled = enable; }
+
+ uint getFontHeight() const { return _outlineEnabled ? 18 : 16; }
+ uint getFontWidth() const { return _outlineEnabled ? 18 : 16; }
+
+ void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const;
+
+private:
+ template<typename Color>
+ void drawCharInternOutline(const uint16 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const;
+
+ template<typename Color>
+ void drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const;
+
+ enum {
+ kFontRomSize = 262144
+ };
+
+ bool _outlineEnabled;
+ uint16 _fontData[kFontRomSize / 2];
+
+ static uint sjisToChunk(uint8 low, uint8 high);
+};
+
+// TODO: Consider adding support for PC98 ROM
+
+} // end of namespace Graphics
+
+#endif
+
+#endif // defined(ENABLE_KYRA) || defined(ENABLE_SCI)
+
diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp
index a87a6eeaa6..ead0c232b1 100644
--- a/tools/create_kyradat/create_kyradat.cpp
+++ b/tools/create_kyradat/create_kyradat.cpp
@@ -507,14 +507,14 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32
if (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ ||
g->special == k2TownsFile1E || g->special == k2TownsFile1J ||
g->special == k2TownsFile2E || g->special == k2TownsFile2J || fmtPatch == 5) {
- // prevents creation of empty entries (which we have mostly between all strings in the fm-towns version)
+ // prevents creation of empty entries (which we have mostly between all strings in the FM-TOWNS version)
while (!data[++i]) {
if (i == size)
break;
targetsize--;
}
if (fmtPatch == 1) {
- // Here is the first step of the extra treatment for all fm-towns string arrays that
+ // Here is the first step of the extra treatment for all FM-TOWNS string arrays that
// contain more than one string and which the original code
// addresses via stringname[boolJapanese].
// We simply skip every other string
@@ -593,7 +593,7 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32
}
if (fmtPatch == 1) {
- // Here is the extra treatment for all fm-towns string arrays that
+ // Here is the extra treatment for all FM-TOWNS string arrays that
// contain more than one string and which the original code
// addresses via stringname[boolJapanese].
// We simply skip every other string
@@ -637,7 +637,7 @@ bool extractStrings(PAKFile &out, const Game *g, const byte *data, const uint32
}
bool extractRooms(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) {
- // different entry size for the fm-towns version
+ // different entry size for the FM-TOWNS version
const int roomEntrySize = (g->special == kFMTownsVersionE || g->special == kFMTownsVersionJ) ? (0x69) : ((g->special == kAmigaVersion) ? 0x52 : 0x51);
const int countRooms = size / roomEntrySize;