aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTravis Howell2009-08-11 02:04:17 +0000
committerTravis Howell2009-08-11 02:04:17 +0000
commit1b47344cc173ae424e84d8b0eea6e4d0c84f506c (patch)
treee35bc14e03f954917182af94240a655783dc4732 /engines
parent773c1a270b682ddc845907a605085f2f7d505d1f (diff)
parent40c58d4ed06b5f6bfa348be34d879c2180c516ec (diff)
downloadscummvm-rg350-1b47344cc173ae424e84d8b0eea6e4d0c84f506c.tar.gz
scummvm-rg350-1b47344cc173ae424e84d8b0eea6e4d0c84f506c.tar.bz2
scummvm-rg350-1b47344cc173ae424e84d8b0eea6e4d0c84f506c.zip
Merged revisions 43066,43068,43088,43093,43095,43097,43101-43102,43107,43112,43114,43117,43119-43120,43122-43123,43126,43131,43139,43143,43145,43147,43150,43152,43155-43156,43163,43165,43167,43171-43172,43178-43179,43183,43186-43200,43202,43205-43223,43227-43235,43237-43241 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk ........ r43066 | dreammaster | 2009-08-05 20:44:37 +1000 (Wed, 05 Aug 2009) | 1 line Bugfix for music not being stopped when music volume is set to zero ........ r43068 | scott_t | 2009-08-05 23:57:40 +1000 (Wed, 05 Aug 2009) | 1 line T7G: Fix bug #2831041 by implementing opcode responsible for starting music partway through a video ........ r43088 | knakos | 2009-08-07 04:05:50 +1000 (Fri, 07 Aug 2009) | 1 line overload showMouse to kill mouse shadows in kyra ........ r43093 | dreammaster | 2009-08-07 19:25:06 +1000 (Fri, 07 Aug 2009) | 1 line Bugfix for #2831159 - Palace guards saying !!HIGH STRING!! ........ r43095 | knakos | 2009-08-07 20:44:34 +1000 (Fri, 07 Aug 2009) | 1 line hint backend about virtual keyboard on save, in LoK ........ r43097 | knakos | 2009-08-07 21:05:58 +1000 (Fri, 07 Aug 2009) | 1 line show VK in gui_v2 games of kyra ........ r43101 | dhewg | 2009-08-08 04:16:58 +1000 (Sat, 08 Aug 2009) | 3 lines Merge creation of Info.plist into update-version.pl. This fixes the static version info after branching (#2820503). ........ r43102 | knakos | 2009-08-08 05:33:39 +1000 (Sat, 08 Aug 2009) | 1 line mouse up events need the same lovin' as mouse down events do. don't underestimate 'em. fixes bug #2833549 ........ r43107 | drmccoy | 2009-08-08 12:23:04 +1000 (Sat, 08 Aug 2009) | 1 line When opening a data stream, don't read the whole file into memory if not necessary. This vastly improves the loading times of Gob3 on small devices ........ r43112 | dreammaster | 2009-08-08 19:34:23 +1000 (Sat, 08 Aug 2009) | 1 line Commit of dhewg's patch to fix screen refreshes on the Wii ........ r43114 | knakos | 2009-08-08 19:38:12 +1000 (Sat, 08 Aug 2009) | 1 line forward port of wince 3.0 fix for paths from branch 0.13.0, r39978 ........ r43117 | dhewg | 2009-08-08 21:30:56 +1000 (Sat, 08 Aug 2009) | 1 line tweaked the mapped keys to reintroduce SHIFT for mass adding games ........ r43119 | lordhoto | 2009-08-08 21:42:29 +1000 (Sat, 08 Aug 2009) | 1 line Add workaround for bug #2820054 "DW1: No intro music at first start on Wii", which actually happened on all systems, when using the multilanguage version. ........ r43120 | lordhoto | 2009-08-08 21:51:15 +1000 (Sat, 08 Aug 2009) | 1 line Fix for bug #2412336 "DW2: Voices cut off" (commit on behalf of dreammaster) ........ r43122 | lordhoto | 2009-08-08 22:00:34 +1000 (Sat, 08 Aug 2009) | 1 line Formatting fix. ........ r43123 | lordhoto | 2009-08-08 22:22:34 +1000 (Sat, 08 Aug 2009) | 1 line Change workaround for bug #2820054 to apply for all GRA versions. ........ r43126 | lordhoto | 2009-08-08 23:57:21 +1000 (Sat, 08 Aug 2009) | 1 line Fix XMIDI looping implementation. Now for example the music in the ferret village of ITE plays fine. ........ r43131 | sev | 2009-08-09 04:01:44 +1000 (Sun, 09 Aug 2009) | 2 lines Implement FR#2821534: "GUI: Mute All disable volume sliders" ........ r43139 | sev | 2009-08-09 06:08:22 +1000 (Sun, 09 Aug 2009) | 2 lines Add DS version of Atari MM from Bug #2834054 ........ r43143 | sev | 2009-08-09 06:16:58 +1000 (Sun, 09 Aug 2009) | 2 lines Patch #2832247: "GMM: Enable loading & deleting of unnamed savegames" ........ r43145 | sev | 2009-08-09 06:49:13 +1000 (Sun, 09 Aug 2009) | 2 lines Fix bug #2825565: "Unable to select subtitles in Atlantis and Simon 1" ........ r43147 | drmccoy | 2009-08-09 07:43:07 +1000 (Sun, 09 Aug 2009) | 1 line Changed the scroll-handling to be more like the original. This fixes bug #2832362 ("GOB3: Scrolling locked after cutscene") ........ r43150 | dreammaster | 2009-08-09 11:05:47 +1000 (Sun, 09 Aug 2009) | 1 line Changed subtitles display speed to also include the time taken to say voice samples (if voices are turned on). This means subtitles will display for the same time irrespective of whether voices are on or not ........ r43152 | Kirben | 2009-08-09 11:20:08 +1000 (Sun, 09 Aug 2009) | 1 line Fix bug #2834254 - ELVIRA: Buggy scroll arrows when mixing spells. ........ r43155 | dreammaster | 2009-08-09 11:45:39 +1000 (Sun, 09 Aug 2009) | 1 line Slight adjustment to Spanish font lookup table, based on mac_es's description of character lookup problems ........ r43156 | Kirben | 2009-08-09 11:55:34 +1000 (Sun, 09 Aug 2009) | 1 line Fix bug #2834252 - ELVIRA1 Problem with 8-character-long save names. ........ r43163 | Kirben | 2009-08-09 17:16:08 +1000 (Sun, 09 Aug 2009) | 1 line Fix bug #2834260 - ELVIRA1: Graphic glitch when bird takes off. ........ r43165 | Kirben | 2009-08-09 20:28:11 +1000 (Sun, 09 Aug 2009) | 1 line Fix glitch when removing arrows from spell book in Elvira 1. ........ r43167 | djwillis | 2009-08-09 22:12:24 +1000 (Sun, 09 Aug 2009) | 1 line GP2X: Commit local version of backend, contains a 'fix' to work around a GP2X SDL 'feature' that was removing the ability to disable aspect ratio correction. Also misc cleanup and changes to default volume levels to cut down on sample clipping. ........ r43171 | dreammaster | 2009-08-09 22:23:01 +1000 (Sun, 09 Aug 2009) | 1 line Removed redundant code related to Midi handling ........ r43172 | lordhoto | 2009-08-10 01:37:00 +1000 (Mon, 10 Aug 2009) | 1 line Fix for bug #2834250 "GUI: Incorrect behavior of sliders". ........ r43178 | knakos | 2009-08-10 04:34:08 +1000 (Mon, 10 Aug 2009) | 1 line removing support for flac (good riddance) and mpeg2 ........ r43179 | knakos | 2009-08-10 04:37:29 +1000 (Mon, 10 Aug 2009) | 1 line update news files for 1.0.0rc1 release ........ r43183 | lordhoto | 2009-08-10 05:11:10 +1000 (Mon, 10 Aug 2009) | 1 line Cleanup AMIGA graphics conversion. ........ r43186 | lordhoto | 2009-08-10 08:46:25 +1000 (Mon, 10 Aug 2009) | 1 line Create a "Font" interface and create a "DOSFont" implementation for handling DOS version fonts. ........ r43187 | lordhoto | 2009-08-10 08:46:43 +1000 (Mon, 10 Aug 2009) | 1 line Add support for the font format used in Kyrandia 1 Amiga. (font colors are wrong though) ........ r43188 | lordhoto | 2009-08-10 09:23:48 +1000 (Mon, 10 Aug 2009) | 1 line Unbreak basic Kyra1 amiga in game support, by disabling some palette code for the amiga version. ........ r43189 | lordhoto | 2009-08-10 09:32:52 +1000 (Mon, 10 Aug 2009) | 1 line Clear the destination page for bitmap loading, this fixes graphics artifacts in Kyra1 amiga. ........ r43190 | waltervn | 2009-08-10 11:08:20 +1000 (Mon, 10 Aug 2009) | 3 lines SCI: Added detection entries for French versions of Eco Quest 1/2 (reported by Strangerke). ........ r43191 | lordhoto | 2009-08-10 11:32:22 +1000 (Mon, 10 Aug 2009) | 1 line Disable menu text fading in kyra1 amiga for now. ........ r43192 | lordhoto | 2009-08-10 11:32:39 +1000 (Mon, 10 Aug 2009) | 1 line Initial support for correct colors in the interface of Kyra1 AMIGA. ........ r43193 | lordhoto | 2009-08-10 11:32:59 +1000 (Mon, 10 Aug 2009) | 1 line Fix inventory background color. ........ r43194 | lordhoto | 2009-08-10 11:33:18 +1000 (Mon, 10 Aug 2009) | 1 line Fix text color in character speeches in Kyra1 amiga. ........ r43195 | lordhoto | 2009-08-10 11:33:36 +1000 (Mon, 10 Aug 2009) | 1 line Fix interface text color. ........ r43196 | lordhoto | 2009-08-10 11:33:56 +1000 (Mon, 10 Aug 2009) | 1 line Enable interface text fading in Kyra1 amiga again. ........ r43197 | lordhoto | 2009-08-10 11:34:14 +1000 (Mon, 10 Aug 2009) | 1 line Use interface palette for mouse cursor in Kyra1 amiga, when it's enabled. ........ r43198 | lordhoto | 2009-08-10 11:34:29 +1000 (Mon, 10 Aug 2009) | 1 line Cleanup. ........ r43199 | lordhoto | 2009-08-10 11:34:46 +1000 (Mon, 10 Aug 2009) | 1 line Remove dead code. ........ r43200 | lordhoto | 2009-08-10 12:32:19 +1000 (Mon, 10 Aug 2009) | 1 line Fix bug when setting up mouse cursor with inventory palette. ........ r43202 | athrxx | 2009-08-10 20:25:53 +1000 (Mon, 10 Aug 2009) | 1 line LOL: fix main menu in floppy version ........ r43205 | lordhoto | 2009-08-10 23:46:17 +1000 (Mon, 10 Aug 2009) | 1 line Made font color configuration independend from font style configuration. ........ r43206 | lordhoto | 2009-08-11 00:05:14 +1000 (Tue, 11 Aug 2009) | 1 line Rename 'font_color' attribute for 'text' draw step to 'text_color'. ........ r43207 | lordhoto | 2009-08-11 00:35:28 +1000 (Tue, 11 Aug 2009) | 1 line Fix copyright string displaying in Kyra1 amiga. Unlike the DOS version it does not use a second print for creating a shadow look. ........ r43208 | lordhoto | 2009-08-11 02:42:39 +1000 (Tue, 11 Aug 2009) | 4 lines - Fix extraction of Kyra 1 amiga string tables in kyra.dat - Fix "taken" string offsets in kyra.dat - Add temporary workaround for only one "taken" string being present in Kyra 1 amiga. - Update kyra.dat ........ r43209 | lordhoto | 2009-08-11 03:14:03 +1000 (Tue, 11 Aug 2009) | 1 line Fix GUI strings in Kyrandia 1 Amiga. ........ r43210 | lordhoto | 2009-08-11 03:14:22 +1000 (Tue, 11 Aug 2009) | 1 line Implement item to item name list index mapping for Kyrandia 1 Amiga. ........ r43211 | lordhoto | 2009-08-11 03:17:19 +1000 (Tue, 11 Aug 2009) | 1 line Typo. ........ r43212 | lordhoto | 2009-08-11 04:01:28 +1000 (Tue, 11 Aug 2009) | 1 line Fix GUI font colors and text drawing in Kyrandia 1 Amiga. ........ r43213 | lordhoto | 2009-08-11 04:03:37 +1000 (Tue, 11 Aug 2009) | 1 line Fix GUI button outline colors in Kyra1 Amiga. ........ r43214 | tramboi | 2009-08-11 04:03:54 +1000 (Tue, 11 Aug 2009) | 2 lines Option "desired_screen_aspect_ratio" for fullscreen mode in the SDL backend Shortcoming: the picture is not centered ........ r43215 | lordhoto | 2009-08-11 04:04:53 +1000 (Tue, 11 Aug 2009) | 1 line Fix GUI menu colors for Kyrandia 1 Amiga. ........ r43216 | lordhoto | 2009-08-11 04:13:01 +1000 (Tue, 11 Aug 2009) | 1 line Remove unused variables. ........ r43217 | waltervn | 2009-08-11 04:37:47 +1000 (Tue, 11 Aug 2009) | 2 lines SCI: Improved multilanguage support for SCI1 and SCI1.1. ........ r43218 | waltervn | 2009-08-11 04:43:15 +1000 (Tue, 11 Aug 2009) | 2 lines SCI: Fix warnings. ........ r43219 | waltervn | 2009-08-11 04:59:59 +1000 (Tue, 11 Aug 2009) | 2 lines SCI: Fix vmvars debug command. ........ r43220 | lordhoto | 2009-08-11 05:08:00 +1000 (Tue, 11 Aug 2009) | 2 lines - Fix AMIGA to DOS palette conversion - Amiga version uses 13 instead of 12 palette buffers ........ r43221 | lordhoto | 2009-08-11 05:09:13 +1000 (Tue, 11 Aug 2009) | 1 line Fix incorrect converted colors in Kyra1 Amiga speech text color setup. ........ r43222 | lordhoto | 2009-08-11 05:10:11 +1000 (Tue, 11 Aug 2009) | 1 line Implement differences for Kyrandia 1 Amiga in o1_setCustomPaletteRange. ........ r43223 | sev | 2009-08-11 05:31:08 +1000 (Tue, 11 Aug 2009) | 2 lines Add support for Italian MM NES ........ r43227 | strangerke | 2009-08-11 06:57:26 +1000 (Tue, 11 Aug 2009) | 1 line gob - Add a workaround for files (at least in Playtoons) that are tested on CD only, with the '@' symbol ........ r43228 | strangerke | 2009-08-11 06:58:13 +1000 (Tue, 11 Aug 2009) | 1 line gob - Add 2 files tested and used by Playtoons and Playtoons CK ........ r43229 | waltervn | 2009-08-11 07:30:16 +1000 (Tue, 11 Aug 2009) | 2 lines SCI: Added several debug command aliases. ........ r43230 | lordhoto | 2009-08-11 08:18:18 +1000 (Tue, 11 Aug 2009) | 1 line Cleanup. ........ r43231 | lordhoto | 2009-08-11 08:18:33 +1000 (Tue, 11 Aug 2009) | 1 line Fix o1_makeAmuletAppear for Kyrandia 1 Amiga. ........ r43232 | lordhoto | 2009-08-11 08:18:47 +1000 (Tue, 11 Aug 2009) | 1 line Fix WSA movies for final sequence of Kyrandia 1 Amiga. (this is just a theoretical fix, the game isn't yet playable till then) ........ r43233 | lordhoto | 2009-08-11 08:54:25 +1000 (Tue, 11 Aug 2009) | 1 line Proper implementation of o1_fadeSpecialPalette for Kyrandia 1 Amiga. ........ r43234 | lordhoto | 2009-08-11 08:54:45 +1000 (Tue, 11 Aug 2009) | 1 line Fix cauldron water color in Zanthia's home in Kyrandia 1 Amiga. ........ r43235 | mthreepwood | 2009-08-11 09:01:11 +1000 (Tue, 11 Aug 2009) | 1 line Provide a better detection method for Indy3 Mac sound effects. This fixes sounds such as the music that plays when Indy uses the whip on the hook in the giant cork. This also is a proper fix for bug #1852635 -- Sound 54 is actually not a sound effect. ........ r43237 | lordhoto | 2009-08-11 09:34:35 +1000 (Tue, 11 Aug 2009) | 1 line Implement different in Kyrandia 1 Amiga in o1_setFireberryGlowPalette. ........ r43238 | lordhoto | 2009-08-11 09:35:16 +1000 (Tue, 11 Aug 2009) | 1 line Fix yet another inventory background color glitch in Kyrandia 1 Amiga. ........ r43239 | lordhoto | 2009-08-11 10:14:24 +1000 (Tue, 11 Aug 2009) | 1 line Fix a little graphics bug in Kyrandia 1 Amiga, when jewels are enabled. ........ r43240 | lordhoto | 2009-08-11 10:14:40 +1000 (Tue, 11 Aug 2009) | 1 line Disable Kyragem fading for Kyrandia 1 Amiga. ........ r43241 | lordhoto | 2009-08-11 10:14:54 +1000 (Tue, 11 Aug 2009) | 1 line Fix regression introduced with r41081. ........ svn-id: r43250
Diffstat (limited to 'engines')
-rw-r--r--engines/agos/detection_tables.h12
-rw-r--r--engines/agos/icons.cpp23
-rw-r--r--engines/agos/saveload.cpp4
-rw-r--r--engines/agos/vga.cpp2
-rw-r--r--engines/cruise/cruise.cpp12
-rw-r--r--engines/cruise/cruise.h4
-rw-r--r--engines/cruise/staticres.cpp4
-rw-r--r--engines/gob/dataio.cpp262
-rw-r--r--engines/gob/dataio.h66
-rw-r--r--engines/gob/draw_v2.cpp2
-rw-r--r--engines/gob/game.cpp39
-rw-r--r--engines/gob/game.h10
-rw-r--r--engines/gob/hotspots.cpp5
-rw-r--r--engines/gob/inter_v2.cpp15
-rw-r--r--engines/gob/inter_v4.cpp5
-rw-r--r--engines/gob/inter_v6.cpp5
-rw-r--r--engines/gob/mult_v2.cpp11
-rw-r--r--engines/gob/save/saveload_playtoons.cpp2
-rw-r--r--engines/gob/util.cpp3
-rw-r--r--engines/groovie/music.cpp14
-rw-r--r--engines/groovie/music.h5
-rw-r--r--engines/groovie/script.cpp11
-rw-r--r--engines/groovie/script.h1
-rw-r--r--engines/kyra/gui.cpp26
-rw-r--r--engines/kyra/gui_lok.cpp33
-rw-r--r--engines/kyra/gui_v2.cpp2
-rw-r--r--engines/kyra/items_lok.cpp67
-rw-r--r--engines/kyra/kyra_lok.cpp5
-rw-r--r--engines/kyra/kyra_lok.h65
-rw-r--r--engines/kyra/lol.cpp5
-rw-r--r--engines/kyra/saveload_lok.cpp4
-rw-r--r--engines/kyra/scene_lok.cpp64
-rw-r--r--engines/kyra/screen.cpp588
-rw-r--r--engines/kyra/screen.h128
-rw-r--r--engines/kyra/screen_lok.cpp16
-rw-r--r--engines/kyra/screen_lok.h3
-rw-r--r--engines/kyra/script_lok.cpp115
-rw-r--r--engines/kyra/seqplayer.cpp3
-rw-r--r--engines/kyra/sequences_lok.cpp19
-rw-r--r--engines/kyra/staticres.cpp25
-rw-r--r--engines/kyra/text.cpp120
-rw-r--r--engines/kyra/text.h6
-rw-r--r--engines/kyra/text_lok.cpp32
-rw-r--r--engines/kyra/wsamovie.cpp13
-rw-r--r--engines/kyra/wsamovie.h1
-rw-r--r--engines/sci/console.cpp27
-rw-r--r--engines/sci/detection.cpp25
-rw-r--r--engines/sci/engine/game.cpp3
-rw-r--r--engines/sci/engine/kernel.cpp2
-rw-r--r--engines/sci/engine/kernel.h1
-rw-r--r--engines/sci/engine/kmisc.cpp2
-rw-r--r--engines/sci/engine/kstring.cpp17
-rw-r--r--engines/sci/engine/message.cpp18
-rw-r--r--engines/sci/engine/state.cpp57
-rw-r--r--engines/sci/engine/state.h1
-rw-r--r--engines/sci/engine/vm.cpp4
-rw-r--r--engines/scumm/detection_tables.h1
-rw-r--r--engines/scumm/file_nes.cpp113
-rw-r--r--engines/scumm/file_nes.h1
-rw-r--r--engines/scumm/scumm-md5.h6
-rw-r--r--engines/scumm/sound.cpp8
-rw-r--r--engines/tinsel/background.cpp2
-rw-r--r--engines/tinsel/bmv.cpp1
-rw-r--r--engines/tinsel/dw.h2
-rw-r--r--engines/tinsel/graphics.cpp1
-rw-r--r--engines/tinsel/music.cpp39
-rw-r--r--engines/tinsel/palette.cpp7
-rw-r--r--engines/tinsel/pcode.cpp15
-rw-r--r--engines/tinsel/tinlib.cpp12
69 files changed, 1597 insertions, 625 deletions
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index 0c672aef52..533f35d304 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -1600,7 +1600,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1625,7 +1625,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1675,7 +1675,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::HB_ISR,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1700,7 +1700,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1726,7 +1726,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
@@ -1751,7 +1751,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON1,
diff --git a/engines/agos/icons.cpp b/engines/agos/icons.cpp
index 2fd93e64f2..d06e4ec6fc 100644
--- a/engines/agos/icons.cpp
+++ b/engines/agos/icons.cpp
@@ -860,16 +860,16 @@ void AGOSEngine::addArrows(WindowBlock *window, uint8 num) {
x = 30;
y = 151;
if (num != 2) {
- y = window->height * 4 + window->y - 19;
- x = window->width + window->x;
+ y = window->y + window->height * 4 - 19;
+ x = window->x + window->width;
}
drawArrow(x, y, 16);
ha = findEmptyHitArea();
_scrollUpHitArea = ha - _hitAreas;
- ha->x = 30 * 8;
- ha->y = 151;
+ ha->x = x * 8;
+ ha->y = y;
ha->width = 16;
ha->height = 19;
ha->flags = kBFBoxInUse;
@@ -881,16 +881,16 @@ void AGOSEngine::addArrows(WindowBlock *window, uint8 num) {
x = 30;
y = 170;
if (num != 2) {
- y = window->height * 4;
- x = window->width + window->x;
+ y = window->y + window->height * 4;
+ x = window->x + window->width;
}
drawArrow(x, y, -16);
ha = findEmptyHitArea();
_scrollDownHitArea = ha - _hitAreas;
- ha->x = 30 * 8;
- ha->y = 170;
+ ha->x = x * 8;
+ ha->y = y;
ha->width = 16;
ha->height = 19;
ha->flags = kBFBoxInUse;
@@ -956,7 +956,8 @@ void AGOSEngine::drawArrow(uint16 x, uint16 y, int8 dir) {
for (h = 0; h < 19; h++) {
for (w = 0; w < 16; w++) {
- dst[w] = src[w] + 16;
+ if (src[w])
+ dst[w] = src[w] + 16;
}
src += dir;
@@ -984,8 +985,8 @@ void AGOSEngine_Elvira2::removeArrows(WindowBlock *window, uint num) {
void AGOSEngine::removeArrows(WindowBlock *window, uint num) {
if (num != 2) {
- uint y = window->height * 4 + window->y - 19;
- uint x = window->width + window->x;
+ uint y = window->y + window->height * 4 - 19;
+ uint x = (window->x + window->width) * 8;
restoreBlock(x, y, x + 16, y + 38);
} else {
colorBlock(window, 240, 151, 16, 38);
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 3787617be7..77b503b2e3 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -283,7 +283,7 @@ void AGOSEngine::userGame(bool load) {
const char *message1;
int i = 0, numSaveGames;
char *name;
- char buf[8];
+ char buf[10];
numSaveGames = countSaveGames();
@@ -312,7 +312,7 @@ restart:
for (; *message1; message1++)
windowPutChar(window, *message1);
- memset(buf, 0, 8);
+ memset(buf, 0, 10);
name = buf;
_saveGameNameLen = 0;
diff --git a/engines/agos/vga.cpp b/engines/agos/vga.cpp
index d37681508e..7855d0e805 100644
--- a/engines/agos/vga.cpp
+++ b/engines/agos/vga.cpp
@@ -1258,7 +1258,7 @@ void AGOSEngine::clearVideoWindow(uint16 num, uint16 color) {
dst += screen->pitch;
}
_system->unlockScreen();
- } else if (num == 4) {
+ } else {
const uint16 *vlut = &_videoWindows[num * 4];
uint16 xoffs = (vlut[0] - _videoWindows[16]) * 16;
uint16 yoffs = (vlut[1] - _videoWindows[17]);
diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
index 7abf83f054..1286c38ff3 100644
--- a/engines/cruise/cruise.cpp
+++ b/engines/cruise/cruise.cpp
@@ -124,18 +124,6 @@ void CruiseEngine::initialize() {
// another bit of video init
readVolCnf();
-
- // Setup mixer
-// _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
-// _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
-
- int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
- _mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
- _adlib = (midiDriver == MD_ADLIB);
-
- _driver = MidiDriver::createMidi(midiDriver);
- if (_mt32)
- _driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
}
void CruiseEngine::deinitialise() {
diff --git a/engines/cruise/cruise.h b/engines/cruise/cruise.h
index af098b4997..574017dfc7 100644
--- a/engines/cruise/cruise.h
+++ b/engines/cruise/cruise.h
@@ -56,9 +56,7 @@ class CruiseEngine: public Engine {
private:
bool _preLoad;
Debugger *_debugger;
- MidiDriver *_driver;
PCSound *_sound;
- bool _mt32, _adlib;
Common::StringList _langStrings;
CursorType _savedCursor;
uint32 lastTick, lastTickDebug;
@@ -89,8 +87,6 @@ public:
Common::Language getLanguage() const;
Common::Platform getPlatform() const;
PCSound &sound() { return *_sound; }
- bool mt32() const { return _mt32; }
- bool adlib() const { return _adlib; }
virtual GUI::Debugger *getDebugger() { return _debugger; }
virtual void pauseEngine(bool pause);
const char *langString(LangStringId langId) { return _langStrings[(int)langId].c_str(); }
diff --git a/engines/cruise/staticres.cpp b/engines/cruise/staticres.cpp
index 595ac5a38b..fa77555314 100644
--- a/engines/cruise/staticres.cpp
+++ b/engines/cruise/staticres.cpp
@@ -182,7 +182,7 @@ int16 spanish_fontCharacterTable[256] = {
-1, -1, -1,
0x72, 0x80
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0x7f, 0x79, 0x7b, 0x81, 0x82, 0x83,
-1, -1,
0x7d,
@@ -218,7 +218,7 @@ int16 spanish_fontCharacterTable[256] = {
0x67,
-1,
0x68,
- -1, -1, -1, -1
+ -1, -1, -1
};
//
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp
index 99cf7c1193..3b7a61d485 100644
--- a/engines/gob/dataio.cpp
+++ b/engines/gob/dataio.cpp
@@ -35,21 +35,22 @@ namespace Gob {
DataStream::DataStream(DataIO &io, int16 handle, uint32 dSize, bool dispose) {
_io = &io;
- _handle = handle;
- _size = dSize;
+
+ _handle = handle;
+ _size = dSize;
_dispose = dispose;
- _data = 0;
+ _data = 0;
_stream = 0;
}
DataStream::DataStream(byte *buf, uint32 dSize, bool dispose) {
- _data = buf;
- _size = dSize;
- _stream = new Common::MemoryReadStream(_data, _size);
+ _data = buf;
+ _size = dSize;
+ _stream = new Common::MemoryReadStream(_data, _size);
_dispose = dispose;
- _io = 0;
+ _io = 0;
_handle = -1;
}
@@ -84,7 +85,7 @@ int32 DataStream::size() const {
bool DataStream::seek(int32 offset, int whence) {
if (_stream)
return _stream->seek(offset, whence);
- else if ((_handle < 50) || (_handle >= 128))
+ else if (!_io->isDataFileChunk(_handle))
return _io->file_getHandle(_handle)->seek(offset, whence);
else {
_io->seekChunk(_handle, offset, whence);
@@ -103,7 +104,7 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) {
if (_stream)
return _stream->read(dataPtr, dataSize);
- if ((_handle < 50) || (_handle >= 128))
+ if (!_io->isDataFileChunk(_handle))
return _io->file_getHandle(_handle)->read((byte *) dataPtr, dataSize);
byte *data = (byte *) dataPtr;
@@ -111,7 +112,7 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) {
while (dataSize > 0x3FFF) {
_io->readChunk(_handle, (byte *) data, 0x3FFF);
dataSize -= 0x3FFF;
- data += 0x3FFF;
+ data += 0x3FFF;
haveRead += 0x3FFF;
}
_io->readChunk(_handle, (byte *) data, dataSize);
@@ -121,11 +122,10 @@ uint32 DataStream::read(void *dataPtr, uint32 dataSize) {
DataIO::DataIO(GobEngine *vm) : _vm(vm) {
for (int i = 0; i < MAX_DATA_FILES; i++) {
- _dataFiles[i] = 0;
- _numDataChunks[i] = 0;
+ _dataFiles[i] = 0;
+ _numDataChunks[i] = 0;
_dataFileHandles[i] = -1;
}
- _packedSize = 0;
}
DataIO::~DataIO() {
@@ -136,6 +136,46 @@ DataIO::~DataIO() {
}
}
+bool DataIO::isDataFileChunk(int16 handle) const {
+ return (handle >= 50) && (handle < 128);
+}
+
+bool DataIO::isPacked(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return false;
+
+ return _chunk[getIndex(handle)]->packed != 0;
+}
+
+int DataIO::getFile(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return -1;
+
+ return (handle - 50) / 10;
+}
+
+int DataIO::getSlot(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return -1;
+
+ return (handle - 50) % 10;
+}
+
+int DataIO::getIndex(int16 handle) const {
+ if (!isDataFileChunk(handle))
+ return -1;
+
+ return getIndex(getFile(handle), getSlot(handle));
+}
+
+int DataIO::getIndex(int file, int slot) const {
+ return file * MAX_SLOT_COUNT + slot;
+}
+
+int16 DataIO::getHandle(int file, int slot) const {
+ return file * 10 + slot + 50;
+}
+
int32 DataIO::unpackData(byte *src, byte *dest) {
uint32 realSize;
uint32 counter;
@@ -222,13 +262,11 @@ int16 DataIO::file_open(const char *path) {
}
int16 DataIO::getChunk(const char *chunkName) {
- int16 slot;
- struct ChunkDesc *dataDesc;
-
for (int16 file = 0; file < MAX_DATA_FILES; file++) {
if (_dataFiles[file] == 0)
return -1;
+ int16 slot;
for (slot = 0; slot < MAX_SLOT_COUNT; slot++)
if (_chunkPos[file * MAX_SLOT_COUNT + slot] == -1)
break;
@@ -238,59 +276,55 @@ int16 DataIO::getChunk(const char *chunkName) {
return -1;
}
- dataDesc = _dataFiles[file];
+ ChunkDesc *dataDesc = _dataFiles[file];
for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) {
if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0)
continue;
- _isCurrentSlot[file * MAX_SLOT_COUNT + slot] = false;
- _chunkSize[file * MAX_SLOT_COUNT + slot] = dataDesc->size;
- _chunkOffset[file * MAX_SLOT_COUNT + slot] = dataDesc->offset;
- _chunkPos[file * MAX_SLOT_COUNT + slot] = 0;
- return file * 10 + slot + 50;
+ int index = getIndex(file, slot);
+
+ _isCurrentSlot[index] = false;
+ _chunk [index] = dataDesc;
+ _chunkPos [index] = 0;
+
+ return getHandle(file, slot);
}
}
return -1;
}
char DataIO::freeChunk(int16 handle) {
- if ((handle >= 50) && (handle < 128)) {
- handle -= 50;
- _chunkPos[(handle / 10) * MAX_SLOT_COUNT + (handle % 10)] = -1;
+ if (isDataFileChunk(handle)) {
+ _chunkPos[getIndex(handle)] = -1;
return 0;
}
return 1;
}
int32 DataIO::readChunk(int16 handle, byte *buf, uint16 size) {
- int16 file;
- int16 slot;
- int16 i;
- int32 offset;
-
- if ((handle < 50) || (handle >= 128))
+ if (!isDataFileChunk(handle))
return -2;
- file = (handle - 50) / 10;
- slot = (handle - 50) % 10;
- int index = file * MAX_SLOT_COUNT + slot;
+ int file = getFile(handle);
+ int slot = getSlot(handle);
+ int index = getIndex(file, slot);
- _chunkPos[index] = CLIP<int32>(_chunkPos[index], 0, _chunkSize[index]);
+ _chunkPos[index] = CLIP<int32>(_chunkPos[index], 0, _chunk[index]->size);
if (!_isCurrentSlot[index]) {
- for (i = 0; i < MAX_SLOT_COUNT; i++)
+ for (int16 i = 0; i < MAX_SLOT_COUNT; i++)
_isCurrentSlot[file * MAX_SLOT_COUNT + i] = false;
- offset = _chunkOffset[index] + _chunkPos[index];
+ int32 offset = _chunk[index]->offset + _chunkPos[index];
- debugC(7, kDebugFileIO, "seek: %d, %d", _chunkOffset[index], _chunkPos[index]);
+ debugC(7, kDebugFileIO, "seek: %d, %d", _chunk[index]->offset, _chunkPos[index]);
file_getHandle(_dataFileHandles[file])->seek(offset, SEEK_SET);
}
_isCurrentSlot[index] = true;
- if ((_chunkPos[index] + size) > (_chunkSize[index]))
- size = _chunkSize[index] - _chunkPos[index];
+ if ((_chunkPos[index] + size) > (int32) (_chunk[index]->size))
+ size = _chunk[index]->size - _chunkPos[index];
file_getHandle(_dataFileHandles[file])->read(buf, size);
_chunkPos[index] += size;
@@ -298,15 +332,12 @@ int32 DataIO::readChunk(int16 handle, byte *buf, uint16 size) {
}
int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) {
- int16 file;
- int16 slot;
-
- if ((handle < 50) || (handle >= 128))
+ if (!isDataFileChunk(handle))
return -1;
- file = (handle - 50) / 10;
- slot = (handle - 50) % 10;
- int index = file * MAX_SLOT_COUNT + slot;
+ int file = getFile(handle);
+ int slot = getSlot(handle);
+ int index = getIndex(file, slot);
_isCurrentSlot[index] = false;
if (from == SEEK_SET)
@@ -314,50 +345,45 @@ int16 DataIO::seekChunk(int16 handle, int32 pos, int16 from) {
else if (from == SEEK_CUR)
_chunkPos[index] += pos;
else if (from == SEEK_END)
- _chunkPos[index] = _chunkSize[index] - pos;
+ _chunkPos[index] = _chunk[index]->size - pos;
return _chunkPos[index];
}
uint32 DataIO::getChunkPos(int16 handle) const {
- int16 file;
- int16 slot;
-
- if ((handle < 50) || (handle >= 128))
+ if (!isDataFileChunk(handle))
return 0xFFFFFFFF;
- file = (handle - 50) / 10;
- slot = (handle - 50) % 10;
+ int file = getFile(handle);
+ int slot = getSlot(handle);
return _chunkPos[file * MAX_SLOT_COUNT + slot];
}
-int32 DataIO::getChunkSize(const char *chunkName) {
- int16 file;
- struct ChunkDesc *dataDesc;
- int16 slot;
- int32 realSize;
-
- for (file = 0; file < MAX_DATA_FILES; file++) {
+int32 DataIO::getChunkSize(const char *chunkName, int32 &packSize) {
+ for (int16 file = 0; file < MAX_DATA_FILES; file++) {
if (_dataFiles[file] == 0)
return -1;
- dataDesc = _dataFiles[file];
+ ChunkDesc *dataDesc = _dataFiles[file];
for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) {
if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0)
continue;
if (dataDesc->packed == 0) {
- _packedSize = -1;
+ packSize = -1;
return dataDesc->size;
}
- for (slot = 0; slot < MAX_SLOT_COUNT; slot++)
+ for (int16 slot = 0; slot < MAX_SLOT_COUNT; slot++)
_isCurrentSlot[slot] = false;
+ int32 realSize;
+
file_getHandle(_dataFileHandles[file])->seek(dataDesc->offset, SEEK_SET);
realSize = file_getHandle(_dataFileHandles[file])->readUint32LE();
- _packedSize = dataDesc->size;
+ packSize = dataDesc->size;
+
return realSize;
}
}
@@ -365,10 +391,7 @@ int32 DataIO::getChunkSize(const char *chunkName) {
}
void DataIO::openDataFile(const char *src, bool itk) {
- ChunkDesc *dataDesc;
char path[128];
- int16 file;
- char *fakeTotPtr;
strncpy0(path, src, 127);
if (!strchr(path, '.')) {
@@ -376,6 +399,7 @@ void DataIO::openDataFile(const char *src, bool itk) {
strcat(path, ".stk");
}
+ int16 file;
for (file = 0; file < MAX_DATA_FILES; file++)
if (_dataFiles[file] == 0)
break;
@@ -388,17 +412,17 @@ void DataIO::openDataFile(const char *src, bool itk) {
if (_dataFileHandles[file] == -1)
error("DataIO::openDataFile(): Can't open data file \"%s\"", path);
- _dataFileItk[file] = itk;
+ _dataFileItk [file] = itk;
_numDataChunks[file] = file_getHandle(_dataFileHandles[file])->readUint16LE();
debugC(7, kDebugFileIO, "DataChunks: %d [for %s]", _numDataChunks[file], path);
- dataDesc = new ChunkDesc[_numDataChunks[file]];
+ ChunkDesc *dataDesc = new ChunkDesc[_numDataChunks[file]];
_dataFiles[file] = dataDesc;
for (int i = 0; i < _numDataChunks[file]; i++) {
file_getHandle(_dataFileHandles[file])->read(dataDesc[i].chunkName, 13);
- dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE();
+ dataDesc[i].size = file_getHandle(_dataFileHandles[file])->readUint32LE();
dataDesc[i].offset = file_getHandle(_dataFileHandles[file])->readUint32LE();
dataDesc[i].packed = file_getHandle(_dataFileHandles[file])->readByte();
@@ -410,7 +434,7 @@ void DataIO::openDataFile(const char *src, bool itk) {
Util::replaceChar(dataDesc[i].chunkName, (char) 0x92, 'T');
// Geisha use 0ot files, which are compressed TOT files without the packed byte set.
- fakeTotPtr = strstr(dataDesc[i].chunkName, "0OT");
+ char *fakeTotPtr = strstr(dataDesc[i].chunkName, "0OT");
if (fakeTotPtr != 0) {
strncpy(fakeTotPtr, "TOT", 3);
dataDesc[i].packed = 1;
@@ -436,33 +460,29 @@ void DataIO::closeDataFile(bool itk) {
}
byte *DataIO::getUnpackedData(const char *name) {
- int32 realSize;
- int16 chunk;
- byte *unpackBuf;
- byte *packBuf;
- byte *ptr;
- int32 sizeLeft;
-
- realSize = getChunkSize(name);
- if ((_packedSize == -1) || (realSize == -1))
+ int32 realSize, packSize;
+
+ realSize = getChunkSize(name, packSize);
+
+ if ((packSize == -1) || (realSize == -1))
return 0;
- chunk = getChunk(name);
+ int16 chunk = getChunk(name);
if (chunk == -1)
return 0;
- unpackBuf = new byte[realSize];
+ byte *unpackBuf = new byte[realSize];
assert(unpackBuf);
- packBuf = new byte[_packedSize];
+ byte *packBuf = new byte[packSize];
assert(packBuf);
- sizeLeft = _packedSize;
- ptr = packBuf;
+ int32 sizeLeft = packSize;
+ byte *ptr = packBuf;
while (sizeLeft > 0x4000) {
readChunk(chunk, ptr, 0x4000);
sizeLeft -= 0x4000;
- ptr += 0x4000;
+ ptr += 0x4000;
}
readChunk(chunk, ptr, sizeLeft);
freeChunk(chunk);
@@ -478,9 +498,7 @@ void DataIO::closeData(int16 handle) {
}
int16 DataIO::openData(const char *path) {
- int16 handle;
-
- handle = getChunk(path);
+ int16 handle = getChunk(path);
if (handle >= 0)
return handle;
@@ -492,7 +510,6 @@ bool DataIO::existData(const char *path) {
return false;
int16 handle = openData(path);
-
if (handle < 0)
return false;
@@ -510,9 +527,7 @@ DataStream *DataIO::openAsStream(int16 handle, bool dispose) {
}
uint32 DataIO::getPos(int16 handle) {
- uint32 resPos;
-
- resPos = getChunkPos(handle);
+ uint32 resPos = getChunkPos(handle);
if (resPos != 0xFFFFFFFF)
return resPos;
@@ -520,9 +535,7 @@ uint32 DataIO::getPos(int16 handle) {
}
void DataIO::seekData(int16 handle, int32 pos, int16 from) {
- int32 resPos;
-
- resPos = seekChunk(handle, pos, from);
+ int32 resPos = seekChunk(handle, pos, from);
if (resPos != -1)
return;
@@ -530,9 +543,7 @@ void DataIO::seekData(int16 handle, int32 pos, int16 from) {
}
int32 DataIO::readData(int16 handle, byte *buf, uint16 size) {
- int32 res;
-
- res = readChunk(handle, buf, size);
+ int16 res = readChunk(handle, buf, size);
if (res >= 0)
return res;
@@ -541,45 +552,42 @@ int32 DataIO::readData(int16 handle, byte *buf, uint16 size) {
int32 DataIO::getDataSize(const char *name) {
char buf[128];
- int32 chunkSz;
- Common::File file;
strncpy0(buf, name, 127);
- chunkSz = getChunkSize(buf);
- if (chunkSz >= 0)
- return chunkSz;
+ int32 chunkSize, packSize;
+
+ chunkSize = getChunkSize(buf, packSize);
+ if (chunkSize >= 0)
+ return chunkSize;
+ Common::File file;
if (!file.open(buf))
error("DataIO::getDataSize(): Can't find data \"%s\"", name);
- chunkSz = file.size();
+ chunkSize = file.size();
file.close();
- return chunkSz;
+ return chunkSize;
}
byte *DataIO::getData(const char *path) {
- byte *data;
- byte *ptr;
- int32 size;
- int16 handle;
-
- data = getUnpackedData(path);
+ byte *data = getUnpackedData(path);
if (data)
return data;
- size = getDataSize(path);
+ int32 size = getDataSize(path);
+
data = new byte[size];
assert(data);
- handle = openData(path);
+ int16 handle = openData(path);
- ptr = data;
+ byte *ptr = data;
while (size > 0x4000) {
readData(handle, ptr, 0x4000);
size -= 0x4000;
- ptr += 0x4000;
+ ptr += 0x4000;
}
readData(handle, ptr, size);
closeData(handle);
@@ -588,12 +596,26 @@ byte *DataIO::getData(const char *path) {
DataStream *DataIO::getDataStream(const char *path) {
if (!existData(path))
+ return 0;
+
+ int16 handle = openData(path);
+ if (handle < 0)
return 0;
- uint32 size = getDataSize(path);
- byte *data = getData(path);
+ if (isDataFileChunk(handle) && isPacked(handle)) {
+ // It's a packed chunk in the data files, packed,
+ // so we have to read it in completely and unpack it
+
+ closeData(handle);
+
+ uint32 size = getDataSize(path);
+ byte *data = getData(path);
+
+ return new DataStream(data, size);
- return new DataStream(data, size);
+ } else
+ // Otherwise, we can just return a stream
+ return openAsStream(handle, true);
}
} // End of namespace Gob
diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h
index 1f55cac90d..6a86667e1b 100644
--- a/engines/gob/dataio.h
+++ b/engines/gob/dataio.h
@@ -26,16 +26,14 @@
#ifndef GOB_DATAIO_H
#define GOB_DATAIO_H
-
#include "common/endian.h"
-
#include "common/file.h"
namespace Gob {
-#define MAX_FILES 30
-#define MAX_DATA_FILES 8
-#define MAX_SLOT_COUNT 8
+#define MAX_FILES 30
+#define MAX_DATA_FILES 8
+#define MAX_SLOT_COUNT 8
class DataIO;
@@ -56,20 +54,20 @@ public:
private:
DataIO *_io;
- int16 _handle;
- uint32 _size;
- byte *_data;
+ int16 _handle;
+ uint32 _size;
+ byte *_data;
+ bool _dispose;
Common::MemoryReadStream *_stream;
- bool _dispose;
};
class DataIO {
public:
struct ChunkDesc {
- char chunkName[13];
+ char chunkName[13];
uint32 size;
uint32 offset;
- byte packed;
+ byte packed;
ChunkDesc() : size(0), offset(0), packed(0) { chunkName[0] = 0; }
};
@@ -77,10 +75,13 @@ public:
void openDataFile(const char *src, bool itk = 0);
void closeDataFile(bool itk = 0);
+
byte *getUnpackedData(const char *name);
- void closeData(int16 handle);
+
+ void closeData(int16 handle);
int16 openData(const char *path);
- bool existData(const char *path);
+ bool existData(const char *path);
+
DataStream *openAsStream(int16 handle, bool dispose = false);
int32 getDataSize(const char *name);
@@ -92,34 +93,47 @@ public:
protected:
Common::File _filesHandles[MAX_FILES];
- struct ChunkDesc *_dataFiles[MAX_DATA_FILES];
- uint16 _numDataChunks[MAX_DATA_FILES];
- int16 _dataFileHandles[MAX_DATA_FILES];
- bool _dataFileItk[MAX_DATA_FILES];
- int32 _chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES];
- int32 _chunkOffset[MAX_SLOT_COUNT * MAX_DATA_FILES];
- int32 _chunkSize[MAX_SLOT_COUNT * MAX_DATA_FILES];
- bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES];
- int32 _packedSize;
+
+ ChunkDesc *_dataFiles [MAX_DATA_FILES];
+ uint16 _numDataChunks [MAX_DATA_FILES];
+ int16 _dataFileHandles[MAX_DATA_FILES];
+ bool _dataFileItk [MAX_DATA_FILES];
+
+ ChunkDesc *_chunk [MAX_SLOT_COUNT * MAX_DATA_FILES];
+ int32 _chunkPos [MAX_SLOT_COUNT * MAX_DATA_FILES];
+ bool _isCurrentSlot[MAX_SLOT_COUNT * MAX_DATA_FILES];
class GobEngine *_vm;
+ bool isDataFileChunk(int16 handle) const;
+ bool isPacked (int16 handle) const;
+
+ int getFile (int16 handle) const;
+ int getSlot (int16 handle) const;
+ int getIndex(int16 handle) const;
+
+ int getIndex (int file, int slot) const;
+ int16 getHandle(int file, int slot) const;
+
int16 file_open(const char *path);
Common::File *file_getHandle(int16 handle);
const Common::File *file_getHandle(int16 handle) const;
int16 getChunk(const char *chunkName);
- char freeChunk(int16 handle);
+ char freeChunk(int16 handle);
int32 readChunk(int16 handle, byte *buf, uint16 size);
int16 seekChunk(int16 handle, int32 pos, int16 from);
+
uint32 getChunkPos(int16 handle) const;
- int32 getChunkSize(const char *chunkName);
+
+ int32 getChunkSize(const char *chunkName, int32 &packSize);
uint32 getPos(int16 handle);
- void seekData(int16 handle, int32 pos, int16 from);
+ void seekData(int16 handle, int32 pos, int16 from);
+
int32 readData(int16 handle, byte *buf, uint16 size);
-friend class DataStream;
+ friend class DataStream;
};
} // End of namespace Gob
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index a1074d7ecb..486b12b022 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -46,6 +46,8 @@ Draw_v2::Draw_v2(GobEngine *vm) : Draw_v1(vm) {
}
void Draw_v2::initScreen() {
+ _vm->_game->_preventScroll = false;
+
_scrollOffsetX = 0;
_scrollOffsetY = 0;
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index 4e2bd223b7..af9f03ecbf 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -181,10 +181,12 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_handleMouse = 0;
_forceHandleMouse = 0;
- _menuLevel = 0;
_noScroll = true;
_preventScroll = false;
- _scrollHandleMouse = false;
+
+ _wantScroll = false;
+ _wantScrollX = 0;
+ _wantScrollY = 0;
_tempStr[0] = 0;
@@ -360,9 +362,7 @@ void Game::playTot(int16 skipPlay) {
_vm->_scenery->_pCaptureCounter = oldCaptureCounter;
_script->seek(_script->getFunctionOffset(skipPlay + 1));
- _menuLevel++;
_vm->_inter->callSub(2);
- _menuLevel--;
if (_vm->_inter->_terminate != 0)
_vm->_inter->_terminate = 2;
@@ -439,22 +439,27 @@ void Game::freeSoundSlot(int16 slot) {
_vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot));
}
-void Game::evaluateScroll(int16 x, int16 y) {
- if (_preventScroll || !_scrollHandleMouse || (_menuLevel > 0))
+void Game::wantScroll(int16 x, int16 y) {
+ _wantScroll = true;
+ _wantScrollX = x;
+ _wantScrollY = y;
+}
+
+void Game::evaluateScroll() {
+ if (_noScroll || _preventScroll || !_wantScroll)
return;
- if (_noScroll ||
- ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18)))
+ if ((_vm->_global->_videoMode != 0x14) && (_vm->_global->_videoMode != 0x18))
return;
- if ((x == 0) && (_vm->_draw->_scrollOffsetX > 0)) {
+ if ((_wantScrollX == 0) && (_vm->_draw->_scrollOffsetX > 0)) {
uint16 off;
off = MIN(_vm->_draw->_cursorWidth, _vm->_draw->_scrollOffsetX);
off = MAX(off / 2, 1);
_vm->_draw->_scrollOffsetX -= off;
_vm->_video->dirtyRectsAll();
- } else if ((y == 0) && (_vm->_draw->_scrollOffsetY > 0)) {
+ } else if ((_wantScrollY == 0) && (_vm->_draw->_scrollOffsetY > 0)) {
uint16 off;
off = MIN(_vm->_draw->_cursorHeight, _vm->_draw->_scrollOffsetY);
@@ -463,9 +468,9 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_video->dirtyRectsAll();
}
- int16 cursorRight = x + _vm->_draw->_cursorWidth;
- int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width;
- int16 cursorBottom = y + _vm->_draw->_cursorHeight;
+ int16 cursorRight = _wantScrollX + _vm->_draw->_cursorWidth;
+ int16 screenRight = _vm->_draw->_scrollOffsetX + _vm->_width;
+ int16 cursorBottom = _wantScrollY + _vm->_draw->_cursorHeight;
int16 screenBottom = _vm->_draw->_scrollOffsetY + _vm->_height;
if ((cursorRight >= _vm->_width) &&
@@ -479,7 +484,7 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_draw->_scrollOffsetX += off;
_vm->_video->dirtyRectsAll();
- _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, y);
+ _vm->_util->setMousePos(_vm->_width - _vm->_draw->_cursorWidth, _wantScrollY);
} else if ((cursorBottom >= (_vm->_height - _vm->_video->_splitHeight2)) &&
(screenBottom < _vm->_video->_surfHeight)) {
uint16 off;
@@ -491,11 +496,13 @@ void Game::evaluateScroll(int16 x, int16 y) {
_vm->_draw->_scrollOffsetY += off;
_vm->_video->dirtyRectsAll();
- _vm->_util->setMousePos(x, _vm->_height - _vm->_video->_splitHeight2 -
- _vm->_draw->_cursorHeight);
+ _vm->_util->setMousePos(_wantScrollX,
+ _vm->_height - _vm->_video->_splitHeight2 - _vm->_draw->_cursorHeight);
}
_vm->_util->setScrollOffset();
+
+ _wantScroll = false;
}
int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
diff --git a/engines/gob/game.h b/engines/gob/game.h
index d3a758f014..8b8be90ef4 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -82,7 +82,10 @@ public:
bool _noScroll;
bool _preventScroll;
- bool _scrollHandleMouse;
+
+ bool _wantScroll;
+ int16 _wantScrollX;
+ int16 _wantScrollY;
byte _handleMouse;
char _forceHandleMouse;
@@ -99,7 +102,8 @@ public:
void freeSoundSlot(int16 slot);
- void evaluateScroll(int16 x, int16 y);
+ void wantScroll(int16 x, int16 y);
+ void evaluateScroll();
int16 checkKeys(int16 *pMousex = 0, int16 *pMouseY = 0,
MouseButtons *pButtons = 0, char handleMouse = 0);
@@ -109,8 +113,6 @@ public:
void switchTotSub(int16 index, int16 skipPlay);
protected:
- uint32 _menuLevel;
-
char _tempStr[256];
// Capture
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
index b218634d4e..d21eb906ee 100644
--- a/engines/gob/hotspots.cpp
+++ b/engines/gob/hotspots.cpp
@@ -628,8 +628,6 @@ bool Hotspots::checkHotspotChanged() {
}
uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index) {
- _vm->_game->_scrollHandleMouse = handleMouse != 0;
-
if (delay >= -1) {
_currentKey = 0;
_currentId = 0;
@@ -679,6 +677,9 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index
_vm->_video->waitRetrace();
}
+ if (handleMouse)
+ _vm->_game->evaluateScroll();
+
// Update keyboard and mouse state
key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX,
&_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, handleMouse);
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 19cac86465..b4e5bf7623 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -935,6 +935,8 @@ void Inter_v2::o2_setScrollOffset() {
offsetY = _vm->_game->_script->readValExpr();
if (offsetX == -1) {
+ _vm->_game->_preventScroll = !_vm->_game->_preventScroll;
+
WRITE_VAR(2, _vm->_draw->_scrollOffsetX);
WRITE_VAR(3, _vm->_draw->_scrollOffsetY);
} else {
@@ -996,11 +998,8 @@ void Inter_v2::o2_playImd() {
close = false;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
@@ -1306,8 +1305,14 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
char *file = _vm->_game->_script->getResultStr();
+ // WORKAROUND: In some games (at least all the Playtoons), some files are
+ // read on CD (and only on CD). "@:\" is replaced by the CD drive letter.
+ // As the files are copied on the HDD, those characters are skipped.
+ if (strncmp(file, "@:\\", 3) ==0 )
+ file += 3;
+
// WORKAROUND: For some reason, the variable indicating which TOT to load next
- // is overwritten in the guard house card game in Woodruff
+ // is overwritten in the guard house card game in Woodruff.
if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(file, "6.TOT"))
strcpy(file, "EMAP2011.TOT");
diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp
index 48378a5987..1f6899d85c 100644
--- a/engines/gob/inter_v4.cpp
+++ b/engines/gob/inter_v4.cpp
@@ -233,11 +233,8 @@ void Inter_v4::o4_playVmdOrMusic() {
return;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp
index aa4721ff0a..4e2ec69cf2 100644
--- a/engines/gob/inter_v6.cpp
+++ b/engines/gob/inter_v6.cpp
@@ -164,12 +164,9 @@ void Inter_v6::o6_playVmdOrMusic() {
return;
}
- if (startFrame >= 0) {
- _vm->_game->_preventScroll = true;
+ if (startFrame >= 0)
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey,
palCmd, palStart, palEnd, 0, -1, false, -1, true);
- _vm->_game->_preventScroll = false;
- }
if (close)
_vm->_vidPlayer->primaryClose();
diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp
index 135c50c92c..bad4723159 100644
--- a/engines/gob/mult_v2.cpp
+++ b/engines/gob/mult_v2.cpp
@@ -1105,8 +1105,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
int16 baseFrame, palFrame, lastFrame;
uint16 flags;
- _vm->_game->_preventScroll = true;
-
if (_vm->_draw->_renderFlags & 0x100) {
x = VAR(55);
y = VAR(56);
@@ -1115,7 +1113,6 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
if (key.imdFile == -1) {
_vm->_vidPlayer->primaryClose();
- _vm->_game->_preventScroll = false;
return;
}
@@ -1131,15 +1128,12 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
if ((palFrame != -1) && (lastFrame != -1))
if ((lastFrame - palFrame) < startFrame)
if (!(key.flags & 0x4000)) {
- _vm->_game->_preventScroll = false;
_vm->_vidPlayer->primaryClose();
return;
}
- if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags)) {
- _vm->_game->_preventScroll = false;
+ if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags))
return;
- }
if (palFrame == -1)
palFrame = 0;
@@ -1265,9 +1259,6 @@ void Mult_v2::advanceObjects(int16 index) {
}
}
- if (!hasImds && (_vm->_draw->_showCursor == 3))
- _vm->_game->_preventScroll = false;
-
doSoundAnim(stop, frame);
WRITE_VAR(22, frame);
diff --git a/engines/gob/save/saveload_playtoons.cpp b/engines/gob/save/saveload_playtoons.cpp
index 97da909e7c..3014e3f2bf 100644
--- a/engines/gob/save/saveload_playtoons.cpp
+++ b/engines/gob/save/saveload_playtoons.cpp
@@ -47,6 +47,8 @@ SaveLoad_Playtoons::SaveFile SaveLoad_Playtoons::_saveFiles[] = {
{ "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},
+ { "dan.itk", kSaveModeNone, 0, 0},
+ { "did.inf", kSaveModeSave, 0, 0},
};
SaveLoad::SaveMode SaveLoad_Playtoons::getSaveMode(const char *fileName) const {
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 1a8668b1c2..d51cbad6b3 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -141,7 +141,8 @@ void Util::processInput(bool scroll) {
y -= _vm->_video->_screenDeltaY;
_vm->_util->setMousePos(x, y);
- _vm->_game->evaluateScroll(x, y);
+
+ _vm->_game->wantScroll(x, y);
}
}
diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index 1a1de92156..797290a6f3 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -35,7 +35,7 @@ namespace Groovie {
MusicPlayer::MusicPlayer(GroovieEngine *vm) :
_vm(vm), _isPlaying(false), _backgroundFileRef(0), _gameVolume(100),
- _prevCDtrack(0) {
+ _prevCDtrack(0), _backgroundDelay(0) {
}
void MusicPlayer::playSong(uint32 fileref) {
@@ -56,6 +56,18 @@ void MusicPlayer::setBackgroundSong(uint32 fileref) {
_backgroundFileRef = fileref;
}
+void MusicPlayer::frameTick() {
+ if (_backgroundDelay > 0) {
+ _backgroundDelay--;
+ if (_backgroundDelay == 0)
+ playSong(_backgroundFileRef);
+ }
+}
+
+void MusicPlayer::setBackgroundDelay(uint16 delay) {
+ _backgroundDelay = delay;
+}
+
void MusicPlayer::playCD(uint8 track) {
int startms = 0;
diff --git a/engines/groovie/music.h b/engines/groovie/music.h
index db50930c37..9909c8a185 100644
--- a/engines/groovie/music.h
+++ b/engines/groovie/music.h
@@ -44,6 +44,9 @@ public:
void playCD(uint8 track);
void startBackground();
+ void frameTick();
+ void setBackgroundDelay(uint16 delay);
+
// Volume
void setUserVolume(uint16 volume);
void setGameVolume(uint16 volume, uint16 time);
@@ -55,6 +58,8 @@ private:
uint32 _backgroundFileRef;
uint8 _prevCDtrack;
+ uint16 _backgroundDelay;
+
// Volume fading
uint32 _fadingStartTime;
uint16 _fadingStartVolume;
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index 86713ee3e6..d58bb78607 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -579,6 +579,7 @@ bool Script::playvideofromref(uint32 fileref) {
// Video available, play one frame
if (_videoFile) {
bool endVideo = _vm->_videoPlayer->playFrame();
+ _vm->_musicPlayer->frameTick();
if (endVideo) {
// Close the file
@@ -1506,6 +1507,14 @@ void Script::o_playcd() {
_vm->_musicPlayer->playCD(val);
}
+void Script::o_musicdelay() {
+ uint16 delay = readScript16bits();
+
+ debugScript(1, true, "MUSICDELAY %d", delay);
+
+ _vm->_musicPlayer->setBackgroundDelay(delay);
+}
+
void Script::o_hotspot_outrect() {
uint16 left = readScript16bits();
uint16 top = readScript16bits();
@@ -1687,7 +1696,7 @@ Script::OpcodeFunc Script::_opcodesT7G[NUM_OPCODES] = {
&Script::o_nop8,
&Script::o_getcd, // 0x4C
&Script::o_playcd,
- &Script::o_nop16,
+ &Script::o_musicdelay,
&Script::o_nop16,
&Script::o_nop16, // 0x50
&Script::o_nop16,
diff --git a/engines/groovie/script.h b/engines/groovie/script.h
index 4ff79b36b6..9e35d6fcde 100644
--- a/engines/groovie/script.h
+++ b/engines/groovie/script.h
@@ -220,6 +220,7 @@ private:
void o_sethotspotleft();
void o_getcd();
void o_playcd();
+ void o_musicdelay();
void o_hotspot_outrect();
void o_stub56();
void o_stub59();
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index d9924d233b..cc1add9ce7 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -95,7 +95,8 @@ void GUI::initMenu(Menu &menu) {
if (_vm->gameFlags().gameID == GI_LOL) {
printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 9);
} else {
- printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuTitle(menu), textX - 1, textY + 1, defaultColor1(), defaultColor2(), 0);
printMenuText(getMenuTitle(menu), textX, textY, menu.textColor, 0, 0);
}
@@ -142,7 +143,9 @@ void GUI::initMenu(Menu &menu) {
else
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
} else {
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+
if (i == menu.highlightedItem)
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
else
@@ -158,7 +161,8 @@ void GUI::initMenu(Menu &menu) {
menu.item[i].labelY = menu.item[i].y + 3;
printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 10);
} else {
- printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX - 1, menu.y + menu.item[i].labelY + 1, defaultColor1(), 0, 0);
printMenuText(getMenuItemLabel(menu.item[i]), menu.x + menu.item[i].labelX, menu.y + menu.item[i].labelY, menu.item[i].textColor, 0, 0);
}
}
@@ -253,7 +257,8 @@ void GUI::redrawText(const Menu &menu) {
textY++;
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 8);
} else {
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].textColor, 0, 0);
}
}
@@ -278,7 +283,8 @@ void GUI::redrawHighlight(const Menu &menu) {
textY++;
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 8);
} else {
- printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ printMenuText(getMenuItemTitle(menu.item[i]), textX - 1, textY + 1, defaultColor1(), 0, 0);
printMenuText(getMenuItemTitle(menu.item[i]), textX, textY, menu.item[i].highlightColor, 0, 0);
}
}
@@ -324,7 +330,10 @@ int GUI::redrawButtonCallback(Button *button) {
return 0;
_screen->hideMouse();
- _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 17);
+ else
+ _screen->drawBox(button->x + 1, button->y + 1, button->x + button->width - 1, button->y + button->height - 1, 0xF8);
_screen->showMouse();
return 0;
@@ -335,7 +344,10 @@ int GUI::redrawShadedButtonCallback(Button *button) {
return 0;
_screen->hideMouse();
- _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 31, 18);
+ else
+ _screen->drawShadedBox(button->x, button->y, button->x + button->width, button->y + button->height, 0xF9, 0xFA);
_screen->showMouse();
return 0;
diff --git a/engines/kyra/gui_lok.cpp b/engines/kyra/gui_lok.cpp
index 9f42697ec7..9ef20ba8a3 100644
--- a/engines/kyra/gui_lok.cpp
+++ b/engines/kyra/gui_lok.cpp
@@ -56,10 +56,10 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
return 0;
} else {
_screen->hideMouse();
- _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
+ _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
snd_playSoundEffect(0x35);
setMouseItem(inventoryItem);
- updateSentenceCommand(_itemList[inventoryItem], _takenList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179);
_itemInHand = inventoryItem;
_screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = 0xFF;
@@ -68,10 +68,14 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
if (inventoryItem != 0xFF) {
snd_playSoundEffect(0x35);
_screen->hideMouse();
- _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, 12);
+ _screen->fillRect(_itemPosX[itemOffset], _itemPosY[itemOffset], _itemPosX[itemOffset] + 15, _itemPosY[itemOffset] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
_screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
setMouseItem(inventoryItem);
- updateSentenceCommand(_itemList[inventoryItem], _takenList[1], 179);
+ // TODO: Proper support for both taken strings in Amiga version
+ if (_flags.platform == Common::kPlatformAmiga)
+ updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[0], 179);
+ else
+ updateSentenceCommand(_itemList[getItemListIndex(inventoryItem)], _takenList[1], 179);
_screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
_itemInHand = inventoryItem;
@@ -80,7 +84,7 @@ int KyraEngine_LoK::buttonInventoryCallback(Button *caller) {
_screen->hideMouse();
_screen->drawShape(0, _shapes[216+_itemInHand], _itemPosX[itemOffset], _itemPosY[itemOffset], 0, 0);
_screen->setMouseCursor(1, 1, _shapes[0]);
- updateSentenceCommand(_itemList[_itemInHand], _placedList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _placedList[0], 179);
_screen->showMouse();
_currentCharacter->inventoryItems[itemOffset] = _itemInHand;
_itemInHand = -1;
@@ -365,6 +369,10 @@ void GUI_LoK::setGUILabels() {
offsetOptions = 10;
offsetOn = 0;
walkspeedGarbageOffset = 0;
+ } else if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ // English Amiga version
+ offsetOptions = 8;
+ walkspeedGarbageOffset = 2;
}
assert(offset + 27 < _vm->_guiStringsSize);
@@ -448,8 +456,14 @@ int GUI_LoK::buttonMenuCallback(Button *caller) {
_vm->snd_playSoundEffect(0x36);
return 0;
}
- // XXX
- _screen->setPaletteIndex(0xFE, 60, 60, 0);
+
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ _screen->setPaletteIndex(0x10, 0x3F, 0x3F, 0x3F);
+ _screen->setInterfacePalette(_screen->getPalette(1), 0x3F, 0x3F, 0x3F);
+ } else {
+ _screen->setPaletteIndex(0xFE, 60, 60, 0);
+ }
+
for (int i = 0; i < 6; i++) {
_menuButtonData[i].data0Val1 = _menuButtonData[i].data1Val1 = _menuButtonData[i].data2Val1 = 4;
_menuButtonData[i].data0Callback = _redrawShadedButtonFunctor;
@@ -681,6 +695,7 @@ void GUI_LoK::updateSavegameString() {
}
int GUI_LoK::saveGame(Button *button) {
+ g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
updateMenuButton(button);
_vm->_gameToLoad = _menu[2].item[button->index-0xC].saveSlot;
@@ -729,6 +744,7 @@ int GUI_LoK::saveGame(Button *button) {
}
}
+ g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
return 0;
}
@@ -921,6 +937,9 @@ void GUI_LoK::setupControls(Menu &menu) {
menu.item[3].itemString = "ERROR";
}
} else {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ clickableOffset = 5;
+
menu.item[4].enabled = 0;
menu.item[4].labelString = 0;
}
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index e5c8637fb5..3633a546e7 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -661,7 +661,9 @@ int GUI_v2::clickSaveSlot(Button *caller) {
initMenu(_savenameMenu);
_screen->fillRect(0x26, 0x5B, 0x11F, 0x66, textFieldColor2());
+ g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
const char *desc = nameInputProcess(_saveDescription, 0x27, 0x5C, textFieldColor1(), textFieldColor2(), textFieldColor3(), 0x50);
+ g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
restorePage1(_vm->_screenBuffer);
backUpPage1(_vm->_screenBuffer);
if (desc) {
diff --git a/engines/kyra/items_lok.cpp b/engines/kyra/items_lok.cpp
index aef5ba5f13..bc490d9764 100644
--- a/engines/kyra/items_lok.cpp
+++ b/engines/kyra/items_lok.cpp
@@ -414,7 +414,7 @@ int KyraEngine_LoK::processItemDrop(uint16 sceneId, uint8 item, int x, int y, in
if (unk1 == 0 && unk2 != 0) {
assert(_itemList && _droppedList);
- updateSentenceCommand(_itemList[item], _droppedList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(item)], _droppedList[0], 179);
}
return 1;
@@ -434,7 +434,7 @@ void KyraEngine_LoK::exchangeItemWithMouseItem(uint16 sceneId, int itemIndex) {
setMouseItem(_itemInHand);
assert(_itemList && _takenList);
- updateSentenceCommand(_itemList[_itemInHand], _takenList[1], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(_itemInHand)], _takenList[1], 179);
_screen->showMouse();
clickEventHandler2();
}
@@ -693,7 +693,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) {
if (itemPos != -1) {
restoreItemRect1(x, y);
- _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
+ _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
backUpItemRect1(x, y);
}
@@ -715,7 +715,7 @@ void KyraEngine_LoK::magicOutMouseItem(int animIndex, int itemPos) {
} else {
_characterList[0].inventoryItems[itemPos] = 0xFF;
_screen->hideMouse();
- _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, 12, 0);
+ _screen->fillRect(_itemPosX[itemPos], _itemPosY[itemPos], _itemPosX[itemPos] + 15, _itemPosY[itemPos] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
_screen->showMouse();
}
_screen->showMouse();
@@ -879,7 +879,7 @@ void KyraEngine_LoK::redrawInventory(int page) {
_screen->_curPage = page;
_screen->hideMouse();
for (int i = 0; i < 10; ++i) {
- _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, 12, page);
+ _screen->fillRect(_itemPosX[i], _itemPosY[i], _itemPosX[i] + 15, _itemPosY[i] + 15, _flags.platform == Common::kPlatformAmiga ? 19 : 12, page);
if (_currentCharacter->inventoryItems[i] != 0xFF) {
uint8 item = _currentCharacter->inventoryItems[i];
_screen->drawShape(page, _shapes[216+item], _itemPosX[i], _itemPosY[i], 0, 0);
@@ -910,5 +910,62 @@ void KyraEngine_LoK::restoreItemRect1(int xpos, int ypos) {
_screen->copyBlockToPage(_screen->_curPage, xpos, ypos, 4<<3, 32, _itemBkgBackUp[1]);
}
+int KyraEngine_LoK::getItemListIndex(uint16 item) {
+ if (_flags.platform != Common::kPlatformAmiga)
+ return item;
+
+ // "Unknown item" is at 81.
+ if (item == 0xFFFF || item == 0xFF)
+ return 81;
+ // The first item names are mapped directly
+ else if (item <= 28)
+ return item;
+ // There's only one string for "Fireberries"
+ else if (item >= 29 && item <= 33)
+ return 29;
+ // Correct offsets
+ else if (item >= 34 && item <= 59)
+ return item - 4;
+ // There's only one string for "Red Potion"
+ else if (item >= 60 && item <= 61)
+ return 56;
+ // There's only one string for "Blue Potion"
+ else if (item >= 62 && item <= 63)
+ return 57;
+ // There's only one string for "Yellow Potion"
+ else if (item >= 64 && item <= 65)
+ return 58;
+ // Correct offsets
+ else if (item >= 66 && item <= 69)
+ return item - 7;
+ // There's only one string for "Fresh Water"
+ else if (item >= 70 && item <= 71)
+ return 63;
+ // There's only one string for "Salt Water"
+ else if (item >= 72 && item <= 73)
+ return 64;
+ // There's only one string for "Mineral Water"
+ else if (item >= 74 && item <= 75)
+ return 65;
+ // There's only one string for "Magical Water"
+ else if (item >= 76 && item <= 77)
+ return 66;
+ // There's only one string for "Empty Flask"
+ else if (item >= 78 && item <= 79)
+ return 67;
+ // There's only one string for "Scroll"
+ else if (item >= 80 && item <= 89)
+ return 68;
+ // There's only one string for "Parchment scrap"
+ else if (item >= 90 && item <= 94)
+ return 69;
+ // Correct offsets
+ else if (item >= 95)
+ return item - 25;
+
+ // This should never happen, but still GCC warns about it.
+ return 81;
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/kyra_lok.cpp b/engines/kyra/kyra_lok.cpp
index a3a249de18..36f134d9e4 100644
--- a/engines/kyra/kyra_lok.cpp
+++ b/engines/kyra/kyra_lok.cpp
@@ -363,6 +363,9 @@ void KyraEngine_LoK::startup() {
loadMainScreen();
_screen->loadPalette("PALETTE.COL", _screen->getPalette(0));
+ if (_flags.platform == Common::kPlatformAmiga)
+ _screen->loadPaletteTable("PALETTE.DAT", 6);
+
// XXX
_animator->initAnimStateList();
setCharactersInDefaultScene();
@@ -664,7 +667,7 @@ int KyraEngine_LoK::processInputHelper(int xpos, int ypos) {
currentRoom->itemsTable[item] = 0xFF;
setMouseItem(item2);
assert(_itemList && _takenList);
- updateSentenceCommand(_itemList[item2], _takenList[0], 179);
+ updateSentenceCommand(_itemList[getItemListIndex(item2)], _takenList[0], 179);
_itemInHand = item2;
_screen->showMouse();
clickEventHandler2();
diff --git a/engines/kyra/kyra_lok.h b/engines/kyra/kyra_lok.h
index a905c5521b..e22cc0d997 100644
--- a/engines/kyra/kyra_lok.h
+++ b/engines/kyra/kyra_lok.h
@@ -289,6 +289,8 @@ protected:
void removeHandItem();
void setMouseItem(uint16 item);
+ int getItemListIndex(uint16 item);
+
// -> graphics effects
void wipeDownMouseItem(int xpos, int ypos);
void itemSpecialFX(int x, int y, int item);
@@ -520,35 +522,35 @@ protected:
const uint8 *_seq_Demo4;
const uint8 *_seq_Reunion;
- const char * const*_seq_WSATable;
- const char * const*_seq_CPSTable;
- const char * const*_seq_COLTable;
- const char * const*_seq_textsTable;
+ const char * const *_seq_WSATable;
+ const char * const *_seq_CPSTable;
+ const char * const *_seq_COLTable;
+ const char * const *_seq_textsTable;
int _seq_WSATable_Size;
int _seq_CPSTable_Size;
int _seq_COLTable_Size;
int _seq_textsTable_Size;
- const char * const*_itemList;
- const char * const*_takenList;
- const char * const*_placedList;
- const char * const*_droppedList;
- const char * const*_noDropList;
- const char * const*_putDownFirst;
- const char * const*_waitForAmulet;
- const char * const*_blackJewel;
- const char * const*_poisonGone;
- const char * const*_healingTip;
- const char * const*_thePoison;
- const char * const*_fluteString;
- const char * const*_wispJewelStrings;
- const char * const*_magicJewelString;
- const char * const*_flaskFull;
- const char * const*_fullFlask;
- const char * const*_veryClever;
- const char * const*_homeString;
- const char * const*_newGameString;
+ const char * const *_itemList;
+ const char * const *_takenList;
+ const char * const *_placedList;
+ const char * const *_droppedList;
+ const char * const *_noDropList;
+ const char * const *_putDownFirst;
+ const char * const *_waitForAmulet;
+ const char * const *_blackJewel;
+ const char * const *_poisonGone;
+ const char * const *_healingTip;
+ const char * const *_thePoison;
+ const char * const *_fluteString;
+ const char * const *_wispJewelStrings;
+ const char * const *_magicJewelString;
+ const char * const *_flaskFull;
+ const char * const *_fullFlask;
+ const char * const *_veryClever;
+ const char * const *_homeString;
+ const char * const *_newGameString;
int _itemList_Size;
int _takenList_Size;
@@ -570,13 +572,13 @@ protected:
int _homeString_Size;
int _newGameString_Size;
- const char * const*_characterImageTable;
+ const char * const *_characterImageTable;
int _characterImageTableSize;
- const char * const*_guiStrings;
+ const char * const *_guiStrings;
int _guiStringsSize;
- const char * const*_configStrings;
+ const char * const *_configStrings;
int _configStringsSize;
Shape *_defaultShapeTable;
@@ -614,16 +616,16 @@ protected:
Room *_roomTable;
int _roomTableSize;
- const char * const*_roomFilenameTable;
+ const char * const *_roomFilenameTable;
int _roomFilenameTableSize;
const uint8 *_amuleteAnim;
- const uint8 * const*_specialPalettes;
+ const uint8 * const *_specialPalettes;
- const char *const *_soundFiles;
+ const char * const *_soundFiles;
int _soundFilesSize;
- const char *const *_soundFilesIntro;
+ const char * const *_soundFilesIntro;
int _soundFilesIntroSize;
const int32 *_cdaTrackTable;
int _cdaTrackTableSize;
@@ -646,6 +648,9 @@ protected:
static const uint16 _amuletY[];
static const uint16 _amuletX2[];
static const uint16 _amuletY2[];
+
+ // special palette handling for AMIGA
+ void setupZanthiaPalette(int pal);
protected:
void setupOpcodeTable();
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index d2c8be9556..f102e92802 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -730,7 +730,7 @@ int LoLEngine::mainMenu() {
// 16 color mode
{
{ 0, 0, 0, 0, 0 },
- { 0x01, 0x04, 0x0C, 0x03, 0x00, 0xC1, 0xE1 },
+ { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xC1, 0xE1 },
{ 0xCC, 0xDD, 0xDD, 0xDD },
Screen::FID_9_FNT, 1
}
@@ -738,6 +738,9 @@ int LoLEngine::mainMenu() {
int dataIndex = _flags.use16ColorMode ? 1 : 0;
+ if (!_flags.isTalkie)
+ --data[dataIndex].menuTable[3];
+
if (hasSave)
++data[dataIndex].menuTable[3];
diff --git a/engines/kyra/saveload_lok.cpp b/engines/kyra/saveload_lok.cpp
index c59f2bebf6..3c92b8f2d4 100644
--- a/engines/kyra/saveload_lok.cpp
+++ b/engines/kyra/saveload_lok.cpp
@@ -177,8 +177,8 @@ Common::Error KyraEngine_LoK::loadGameState(int slot) {
seq_createAmuletJewel(i-0x55, 10, 1, 1);
}
}
- _screen->copyRegion(0, 0, 0, 0, 320, 200, 10, 8);
- _screen->copyRegion(0, 0, 0, 0, 320, 200, 8, 0);
+
+ _screen->copyRegion(8, 8, 8, 8, 304, 212, 10, 0);
}
setHandItem(_itemInHand);
diff --git a/engines/kyra/scene_lok.cpp b/engines/kyra/scene_lok.cpp
index fc1ca41189..e7f4ecbae0 100644
--- a/engines/kyra/scene_lok.cpp
+++ b/engines/kyra/scene_lok.cpp
@@ -778,10 +778,10 @@ void KyraEngine_LoK::initSceneScreen(int brandonAlive) {
if (_unkScreenVar2 == 1)
_screen->shuffleScreen(8, 8, 304, 128, 2, 0, _unkScreenVar3, false);
else
- _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0);
+ _screen->copyRegion(8, 8, 8, 8, 304, 128, 2, 0, Screen::CR_NO_P_CHECK);
if (_unkScreenVar1 && !queryGameFlag(0xA0)) {
- if (_currentCharacter->sceneId == 45 && _paletteChanged)
+ if (_currentCharacter->sceneId == 45 && _cauldronState)
_screen->getPalette(0).copy(_screen->getPalette(4), 12, 1);
if (_currentCharacter->sceneId >= 229 && _currentCharacter->sceneId <= 245 && (_brandonStatusBit & 1))
@@ -1203,6 +1203,66 @@ bool KyraEngine_LoK::lineIsPassable(int x, int y) {
#pragma mark -
+void KyraEngine_LoK::setupZanthiaPalette(int pal) {
+ uint8 r, g, b;
+
+ switch (pal - 17) {
+ case 0:
+ // 0x88F
+ r = 33;
+ g = 33;
+ b = 63;
+ break;
+
+ case 1:
+ // 0x00F
+ r = 0;
+ g = 0;
+ b = 63;
+ break;
+
+ case 2:
+ // 0xF88
+ r = 63;
+ g = 33;
+ b = 33;
+ break;
+
+ case 3:
+ // 0xF00
+ r = 63;
+ g = 0;
+ b = 0;
+ break;
+
+ case 4:
+ // 0xFF9
+ r = 63;
+ g = 63;
+ b = 37;
+ break;
+
+ case 5:
+ // 0xFF1
+ r = 63;
+ g = 63;
+ b = 4;
+ break;
+
+ default:
+ // 0xFFF
+ r = 63;
+ g = 63;
+ b = 63;
+ }
+
+ _screen->getPalette(4)[12 * 3 + 0] = r;
+ _screen->getPalette(4)[12 * 3 + 1] = g;
+ _screen->getPalette(4)[12 * 3 + 2] = b;
+}
+
+#pragma mark -
+
void KyraEngine_LoK::setupSceneResource(int sceneId) {
if (!_flags.isTalkie)
return;
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 7a7544a589..97ecbcfb28 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -48,6 +48,7 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system)
_drawShapeVar5 = 0;
_sjisFont = 0;
+ memset(_fonts, 0, sizeof(_fonts));
}
Screen::~Screen() {
@@ -56,10 +57,8 @@ Screen::~Screen() {
delete[] _pagePtrs[0];
- for (int f = 0; f < ARRAYSIZE(_fonts); ++f) {
- delete[] _fonts[f].fontData;
- _fonts[f].fontData = NULL;
- }
+ for (int f = 0; f < ARRAYSIZE(_fonts); ++f)
+ delete _fonts[f];
delete _sjisFont;
delete _screenPalette;
@@ -103,7 +102,6 @@ bool Screen::init() {
}
}
-
_curPage = 0;
uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE * 8];
for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2)
@@ -112,9 +110,11 @@ bool Screen::init() {
memset(_shapePages, 0, sizeof(_shapePages));
- const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 12 : 4;
+ const int paletteCount = (_vm->gameFlags().platform == Common::kPlatformAmiga) ? 13 : 4;
const int numColors = _use16ColorMode ? 16 : ((_vm->gameFlags().platform == Common::kPlatformAmiga) ? 32 : 256);
+ _interfacePaletteEnabled = false;
+
_screenPalette = new Palette(numColors);
assert(_screenPalette);
@@ -219,8 +219,23 @@ void Screen::updateScreen() {
}
void Screen::updateDirtyRects() {
- if (_forceFullUpdate) {
- _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
+ // TODO: Enable dirty rect handling for the AMIGA version
+ if (_forceFullUpdate || _vm->gameFlags().platform == Common::kPlatformAmiga) {
+ if (_interfacePaletteEnabled) {
+ _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, 136);
+
+ // Page 8 is not used by Kyra 1 AMIGA, thus we can use it to adjust the colors
+ copyRegion(0, 136, 0, 0, 320, 64, 0, 8, CR_NO_P_CHECK);
+
+ uint8 *dst = getPagePtr(8);
+ for (int y = 0; y < 64; ++y)
+ for (int x = 0; x < 320; ++x)
+ *dst++ += 32;
+
+ _system->copyRectToScreen(getCPagePtr(8), SCREEN_W, 0, 136, SCREEN_W, 64);
+ } else {
+ _system->copyRectToScreen(getCPagePtr(0), SCREEN_W, 0, 0, SCREEN_W, SCREEN_H);
+ }
} else {
const byte *page0 = getCPagePtr(0);
Common::List<Common::Rect>::iterator it;
@@ -622,6 +637,41 @@ void Screen::setScreenPalette(const Palette &pal) {
_system->setPalette(screenPal, 0, pal.getNumColors());
}
+void Screen::enableInterfacePalette(bool e) {
+ _interfacePaletteEnabled = e;
+
+ _forceFullUpdate = true;
+ _dirtyRects.clear();
+
+ // TODO: We might need to reset the mouse cursor
+
+ updateScreen();
+}
+
+void Screen::setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b) {
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ return;
+
+ uint8 screenPal[32 * 4];
+
+ assert(32 <= pal.getNumColors());
+
+ for (int i = 0; i < pal.getNumColors(); ++i) {
+ if (i != 0x10) {
+ screenPal[4 * i + 0] = (pal[i * 3 + 0] * 0xFF) / 0x3F;
+ screenPal[4 * i + 1] = (pal[i * 3 + 1] * 0xFF) / 0x3F;
+ screenPal[4 * i + 2] = (pal[i * 3 + 2] * 0xFF) / 0x3F;
+ } else {
+ screenPal[4 * i + 0] = (r * 0xFF) / 0x3F;
+ screenPal[4 * i + 1] = (g * 0xFF) / 0x3F;
+ screenPal[4 * i + 2] = (b * 0xFF) / 0x3F;
+ }
+ screenPal[4 * i + 3] = 0;
+ }
+
+ _system->setPalette(screenPal, 32, pal.getNumColors());
+}
+
void Screen::copyToPage0(int y, int h, uint8 page, uint8 *seqBuf) {
assert(y + h <= SCREEN_H);
const uint8 *src = getPagePtr(page) + y * SCREEN_W;
@@ -948,81 +998,52 @@ void Screen::setTextColor(const uint8 *cmap, int a, int b) {
}
bool Screen::loadFont(FontId fontId, const char *filename) {
- Font *fnt = &_fonts[fontId];
-
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return true;
-
- if (!fnt)
- error("fontId %d is invalid", fontId);
-
- if (fnt->fontData)
- delete[] fnt->fontData;
-
- uint32 sz = 0;
- uint8 *fontData = fnt->fontData = _vm->resource()->fileData(filename, &sz);
-
- if (!fontData || !sz)
- error("Couldn't load font file '%s'", filename);
+ Font *&fnt = _fonts[fontId];
- uint16 fontSig = READ_LE_UINT16(fontData + 2);
-
- if (fontSig != 0x500)
- error("Invalid font data (file '%s', fontSig: %.04X)", filename, fontSig);
+ if (!fnt) {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ fnt = new AMIGAFont();
+ else
+ fnt = new DOSFont();
- fnt->charWidthTable = fontData + READ_LE_UINT16(fontData + 8);
- fnt->fontDescOffset = READ_LE_UINT16(fontData + 4);
- fnt->charBitmapOffset = READ_LE_UINT16(fontData + 6);
- fnt->charWidthTableOffset = READ_LE_UINT16(fontData + 8);
- fnt->charHeightTableOffset = READ_LE_UINT16(fontData + 0xC);
+ assert(fnt);
+ }
- fnt->lastGlyph = *(fnt->fontData + fnt->fontDescOffset + 3);
+ Common::SeekableReadStream *file = _vm->resource()->createReadStream(filename);
+ if (!file)
+ error("Font file '%s' is missing", filename);
- return true;
+ bool ret = fnt->load(*file);
+ fnt->setColorMap(_textColorsMap);
+ delete file;
+ return ret;
}
Screen::FontId Screen::setFont(FontId fontId) {
FontId prev = _currentFont;
_currentFont = fontId;
+
+ assert(_fonts[_currentFont]);
+
return prev;
}
int Screen::getFontHeight() const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
- return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 4);
+ return _fonts[_currentFont]->getHeight();
}
int Screen::getFontWidth() const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
- return *(_fonts[_currentFont].fontData + _fonts[_currentFont].fontDescOffset + 5);
+ return _fonts[_currentFont]->getWidth();
}
int Screen::getCharWidth(uint16 c) const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
if ((c & 0xFF00) && _sjisFont)
return _sjisFont->getFontWidth() >> 1;
- if (_fonts[_currentFont].lastGlyph < c)
- return 0;
- else
- return (int)_fonts[_currentFont].charWidthTable[c] + _charWidth;
+ return _fonts[_currentFont]->getCharWidth(c) + _charWidth;
}
int Screen::getTextWidth(const char *str) const {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return 0;
-
int curLineLen = 0;
int maxLineLen = 0;
while (1) {
@@ -1050,9 +1071,6 @@ int Screen::getTextWidth(const char *str) const {
}
void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2) {
- // FIXME: add font support for amiga version
- if (_vm->gameFlags().platform == Common::kPlatformAmiga)
- return;
uint8 cmap[2];
cmap[0] = color2;
cmap[1] = color1;
@@ -1107,73 +1125,19 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2
}
void Screen::drawCharANSI(uint8 c, int x, int y) {
- Font *fnt = &_fonts[_currentFont];
-
- if (c > fnt->lastGlyph)
- return;
-
- uint8 *dst = getPagePtr(_curPage) + y * SCREEN_W + x;
-
- uint16 bitmapOffset = READ_LE_UINT16(fnt->fontData + fnt->charBitmapOffset + c * 2);
- if (bitmapOffset == 0)
- return;
+ Font *fnt = _fonts[_currentFont];
+ assert(fnt);
- uint8 charWidth = *(fnt->fontData + fnt->charWidthTableOffset + c);
- if (!charWidth || charWidth + x > SCREEN_W)
- return;
+ const int charWidth = fnt->getCharWidth(c);
+ const int charHeight = fnt->getHeight();
- uint8 charH0 = getFontHeight();
- if (!charH0 || charH0 + y > SCREEN_H)
+ if (x + charWidth > SCREEN_W || y + charHeight > SCREEN_H)
return;
- uint8 charH1 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2);
- uint8 charH2 = *(fnt->fontData + fnt->charHeightTableOffset + c * 2 + 1);
-
- charH0 -= charH1 + charH2;
-
- const uint8 *src = fnt->fontData + bitmapOffset;
- const int pitch = SCREEN_W - charWidth;
-
- while (charH1--) {
- uint8 col = _textColorsMap[0];
- for (int i = 0; i < charWidth; ++i) {
- if (col != 0)
- *dst = col;
- ++dst;
- }
- dst += pitch;
- }
-
- while (charH2--) {
- uint8 b = 0;
- for (int i = 0; i < charWidth; ++i) {
- uint8 col;
- if (i & 1) {
- col = _textColorsMap[b >> 4];
- } else {
- b = *src++;
- col = _textColorsMap[b & 0xF];
- }
- if (col != 0) {
- *dst = col;
- }
- ++dst;
- }
- dst += pitch;
- }
-
- while (charH0--) {
- uint8 col = _textColorsMap[0];
- for (int i = 0; i < charWidth; ++i) {
- if (col != 0)
- *dst = col;
- ++dst;
- }
- dst += pitch;
- }
+ fnt->drawChar(c, getPagePtr(_curPage) + y * SCREEN_W + x, SCREEN_W);
if (_curPage == 0 || _curPage == 1)
- addDirtyRect(x, y, charWidth, getFontHeight());
+ addDirtyRect(x, y, charWidth, charHeight);
}
void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) {
@@ -2068,85 +2032,94 @@ void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch, bool
wrapped_decodeFrameDeltaPage<false>(dst, src, pitch);
}
-void Screen::convertAmigaGfx(uint8 *data, int w, int h, bool offscreen) {
- static uint8 tmp[320*200];
-
- if (offscreen) {
- uint8 *curLine = tmp;
- const uint8 *src = data;
- int hC = h;
- while (hC--) {
- uint8 *dst1 = curLine;
- uint8 *dst2 = dst1 + 8000;
- uint8 *dst3 = dst2 + 8000;
- uint8 *dst4 = dst3 + 8000;
- uint8 *dst5 = dst4 + 8000;
-
- int width = w >> 3;
- while (width--) {
- *dst1++ = *src++;
- *dst2++ = *src++;
- *dst3++ = *src++;
- *dst4++ = *src++;
- *dst5++ = *src++;
- }
-
- curLine += 40;
+void Screen::convertAmigaGfx(uint8 *data, int w, int h, int depth, bool wsa, int bytesPerPlane) {
+ const int planeWidth = (bytesPerPlane == -1) ? (w + 7) / 8 : bytesPerPlane;
+ const int planeSize = planeWidth * h;
+ const uint imageSize = planeSize * depth;
+
+ // Our static buffer which holds the plane data. We need this
+ // because the "data" pointer is both source and destination pointer.
+ // The buffer has enough space to fit the AMIGA MSC files, which are
+ // the biggest graphics files found in the AMIGA version.
+ static uint8 temp[40320];
+ assert(imageSize <= sizeof(temp));
+
+ // WSA files store their graphics data in a little different format, than
+ // the usual AMIGA graphics format used in BitMaps. Thus we need to do
+ // some special handling for them here. Means we convert them into
+ // the usual format.
+ //
+ // TODO: We might think of moving this conversion into the WSAMovieAmiga
+ // class.
+ if (wsa) {
+ const byte *src = data;
+ for (int y = 0; y < h; ++y) {
+ for (int x = 0; x < planeWidth; ++x)
+ for (int i = 0; i < depth; ++i)
+ temp[y * planeWidth + x + planeSize * i] = *src++;
}
} else {
- memcpy(tmp, data, w*h);
+ memcpy(temp, data, imageSize);
}
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
- int bytePos = x/8+y*40;
- int bitPos = 7-(x&7);
-
- byte colorIndex = 0;
- colorIndex |= (((tmp[bytePos + 8000 * 0] & (1 << bitPos)) >> bitPos) & 0x1) << 0;
- colorIndex |= (((tmp[bytePos + 8000 * 1] & (1 << bitPos)) >> bitPos) & 0x1) << 1;
- colorIndex |= (((tmp[bytePos + 8000 * 2] & (1 << bitPos)) >> bitPos) & 0x1) << 2;
- colorIndex |= (((tmp[bytePos + 8000 * 3] & (1 << bitPos)) >> bitPos) & 0x1) << 3;
- colorIndex |= (((tmp[bytePos + 8000 * 4] & (1 << bitPos)) >> bitPos) & 0x1) << 4;
- *data++ = colorIndex;
+ const int bytePos = x / 8 + y * planeWidth;
+ const int bitPos = 7 - (x & 7); // x & 7 == x % 8
+
+ byte col = 0;
+
+ for (int i = 0; i < depth; ++i)
+ col |= ((temp[bytePos + planeSize * i] >> bitPos) & 1) << i;
+
+ *data++ = col;
}
}
}
void Screen::convertAmigaMsc(uint8 *data) {
- byte *plane1 = data + 5760 * 1;
- byte *plane2 = data + 5760 * 2;
- byte *plane3 = data + 5760 * 3;
- byte *plane4 = data + 5760 * 4;
- byte *plane5 = data + 5760 * 5;
- byte *plane6 = data + 5760 * 6;
- for (int i = 0; i < 5760; ++i) {
- byte d = plane6[i];
- d = (plane5[i] |= d);
- d = (plane4[i] |= d);
- d = (plane3[i] |= d);
- d = (plane2[i] |= d);
- d = (plane1[i] |= d);
- }
- byte dst[320*144];
- memset(dst, 0, sizeof(dst));
- static const byte flagTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
- for (int y = 0; y < 144; ++y) {
- for (int x = 0; x < 320; ++x) {
- if (!(flagTable[x&7] & data[y*40+(x>>3)]))
- dst[y*320+x] |= 0x80;
-
- int layer = 0;
- for (int i = 0; i < 7; ++i) {
- if (flagTable[x&7] & data[y*40+(x>>3)+i*5760])
- layer = i;
- }
+ // MSC files are always 320x144, thus we can safely assume
+ // this to be correct. Also they contain 7 planes instead
+ // of the normal 5 planes, which is used in 32 color mode.
+ // The need for 7 planes can be explained, because the MSC
+ // files have 6 bits for the layer number (bits 1 to 6)
+ // and one bit for the "blocked" flag (bit 0), and every
+ // plane contains one bit per pixel.
+ convertAmigaGfx(data, 320, 144, 7);
+
+ // We need to do some post conversion, since
+ // the AMIGA MSC format is different from the DOS
+ // one we use internally for our code.That is even
+ // after converting it from the AMIGA plane based
+ // approach to one byte per pixel approach.
+ for (int i = 0; i < 320 * 144; ++i) {
+ // The lowest bit indicates, whether the position
+ // is walkable or not. If the bit is set, the
+ // position is walkable, elsewise it is blocked.
+ if (data[i] & 1)
+ data[i] &= 0xFE;
+ else
+ data[i] |= 0x80;
- if (layer)
- dst[y*320+x] |= (layer+1);
- }
+ // The graphics layer for the pixel is saved
+ // in the following format:
+ // The highest bit set indicates the number of
+ // the graphics layer. We count the first
+ // bit as 0 here, thus we need to add one,
+ // to get the correct number.
+ //
+ // Funnily since the first bit (bit 0) is
+ // resevered for testing whether the position
+ // is walkable or not, there is no possibility
+ // for layer 1 to be present.
+ int layer = 0;
+ for (int k = 0; k < 7; ++k)
+ if (data[i] & (1 << k))
+ layer = k + 1;
+
+ data[i] &= 0x80;
+ data[i] |= layer;
}
- memcpy(data, dst, 320*144);
}
template<bool noXor>
@@ -2794,6 +2767,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
uint8 *srcPtr = srcData + 10 + palSize;
uint8 *dstData = getPagePtr(dstPage);
+ memset(dstData, 0, SCREEN_PAGE_SIZE);
if (dstPage == 0 || tempPage == 0)
_forceFullUpdate = true;
@@ -2815,7 +2789,7 @@ void Screen::loadBitmap(const char *filename, int tempPage, int dstPage, Palette
if (!scumm_stricmp(ext, "MSC"))
Screen::convertAmigaMsc(dstData);
else
- Screen::convertAmigaGfx(dstData, 320, 200, false);
+ Screen::convertAmigaGfx(dstData, 320, 200);
}
if (skip)
@@ -3026,6 +3000,230 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) {
#pragma mark -
+DOSFont::DOSFont() {
+ _data = _widthTable = _heightTable = 0;
+ _colorMap = 0;
+ _width = _height = _numGlyphs = 0;
+ _bitmapOffsets = 0;
+}
+
+bool DOSFont::load(Common::SeekableReadStream &file) {
+ unload();
+
+ _data = new uint8[file.size()];
+ assert(_data);
+
+ file.read(_data, file.size());
+ if (file.err())
+ return false;
+
+ const uint16 fontSig = READ_LE_UINT16(_data + 2);
+
+ if (fontSig != 0x0500) {
+ warning("DOSFont: invalid font: %.04X)", fontSig);
+ return false;
+ }
+
+ const uint16 descOffset = READ_LE_UINT16(_data + 4);
+
+ _width = _data[descOffset + 5];
+ _height = _data[descOffset + 4];
+ _numGlyphs = _data[descOffset + 3] + 1;
+
+ _bitmapOffsets = (uint16 *)(_data + READ_LE_UINT16(_data + 6));
+ _widthTable = _data + READ_LE_UINT16(_data + 8);
+ _heightTable = _data + READ_LE_UINT16(_data + 12);
+
+ for (int i = 0; i < _numGlyphs; ++i)
+ _bitmapOffsets[i] = READ_LE_UINT16(&_bitmapOffsets[i]);
+
+ return true;
+}
+
+int DOSFont::getCharWidth(uint8 c) const {
+ if (c >= _numGlyphs)
+ return 0;
+ return _widthTable[c];
+}
+
+void DOSFont::drawChar(uint8 c, byte *dst, int pitch) const {
+ if (c >= _numGlyphs)
+ return;
+
+ if (!_bitmapOffsets[c])
+ return;
+
+ const uint8 *src = _data + _bitmapOffsets[c];
+ const uint8 charWidth = _widthTable[c];
+
+ if (!charWidth)
+ return;
+
+ pitch -= charWidth;
+
+ uint8 charH1 = _heightTable[c * 2 + 0];
+ uint8 charH2 = _heightTable[c * 2 + 1];
+ uint8 charH0 = _height - (charH1 + charH2);
+
+ while (charH1--) {
+ uint8 col = _colorMap[0];
+ for (int i = 0; i < charWidth; ++i) {
+ if (col != 0)
+ *dst = col;
+ ++dst;
+ }
+ dst += pitch;
+ }
+
+ while (charH2--) {
+ uint8 b = 0;
+ for (int i = 0; i < charWidth; ++i) {
+ uint8 col;
+ if (i & 1) {
+ col = _colorMap[b >> 4];
+ } else {
+ b = *src++;
+ col = _colorMap[b & 0xF];
+ }
+ if (col != 0) {
+ *dst = col;
+ }
+ ++dst;
+ }
+ dst += pitch;
+ }
+
+ while (charH0--) {
+ uint8 col = _colorMap[0];
+ for (int i = 0; i < charWidth; ++i) {
+ if (col != 0)
+ *dst = col;
+ ++dst;
+ }
+ dst += pitch;
+ }
+}
+
+void DOSFont::unload() {
+ delete[] _data;
+ _data = _widthTable = _heightTable = 0;
+ _colorMap = 0;
+ _width = _height = _numGlyphs = 0;
+ _bitmapOffsets = 0;
+}
+
+
+AMIGAFont::AMIGAFont() {
+ _width = _height = 0;
+ memset(_chars, 0, sizeof(_chars));
+}
+
+bool AMIGAFont::load(Common::SeekableReadStream &file) {
+ const uint16 dataSize = file.readUint16BE();
+ if (dataSize + 2 != file.size())
+ return false;
+
+ _width = file.readByte();
+ _height = file.readByte();
+
+ // Read the character definition offset table
+ uint16 offsets[ARRAYSIZE(_chars)];
+ for (int i = 0; i < ARRAYSIZE(_chars); ++i)
+ offsets[i] = file.readUint16BE() + 4;
+
+ if (file.err())
+ return false;
+
+ for (int i = 0; i < ARRAYSIZE(_chars); ++i) {
+ file.seek(offsets[i], SEEK_SET);
+
+ _chars[i].yOffset = file.readByte();
+ _chars[i].xOffset = file.readByte();
+ _chars[i].width = file.readByte();
+ file.readByte(); // unused
+
+ // If the y offset is 255, then the character
+ // does not have any bitmap representation
+ if (_chars[i].yOffset != 255) {
+ Character::Graphics &g = _chars[i].graphics;
+
+ g.width = file.readUint16BE();
+ g.height = file.readUint16BE();
+
+ int depth = file.readByte();
+ int specialWidth = file.readByte();
+ int flags = file.readByte();
+ int bytesPerPlane = file.readByte();
+
+ assert(depth != 0 && specialWidth == 0 && flags == 0 && bytesPerPlane != 0);
+
+ // Allocate a temporary buffer to store the plane data
+ const int planesSize = bytesPerPlane * g.height * depth;
+ uint8 *tempData = new uint8[MAX(g.width * g.height, planesSize)];
+ assert(tempData);
+
+ file.read(tempData, planesSize);
+
+ // Convert the plane based graphics to our graphic format
+ Screen::convertAmigaGfx(tempData, g.width, g.height, depth, false, bytesPerPlane);
+
+ // Create a buffer perfectly fitting the character
+ g.bitmap = new uint8[g.width * g.height];
+ assert(g.bitmap);
+
+ memcpy(g.bitmap, tempData, g.width * g.height);
+ delete[] tempData;
+ }
+
+ if (file.err())
+ return false;
+ }
+
+ return !file.err();
+}
+
+int AMIGAFont::getCharWidth(uint8 c) const {
+ if (c >= 255)
+ return 0;
+ return _chars[c].width;
+}
+
+void AMIGAFont::drawChar(uint8 c, byte *dst, int pitch) const {
+ if (c >= 255)
+ return;
+
+ if (_chars[c].yOffset == 255)
+ return;
+
+ dst += _chars[c].yOffset * pitch;
+ dst += _chars[c].xOffset;
+
+ pitch -= _chars[c].graphics.width;
+
+ const uint8 *src = _chars[c].graphics.bitmap;
+ assert(src);
+
+ for (int y = 0; y < _chars[c].graphics.height; ++y) {
+ for (int x = 0; x < _chars[c].graphics.width; ++x) {
+ if (*src)
+ *dst = *src;
+ ++src;
+ ++dst;
+ }
+
+ dst += pitch;
+ }
+}
+
+void AMIGAFont::unload() {
+ _width = _height = 0;
+ for (int i = 0; i < ARRAYSIZE(_chars); ++i)
+ delete[] _chars[i].graphics.bitmap;
+ memset(_chars, 0, sizeof(_chars));
+}
+
+#pragma mark -
+
Palette::Palette(const int numColors) : _palData(0), _numColors(numColors) {
_palData = new uint8[numColors * 3];
assert(_palData);
@@ -3049,9 +3247,9 @@ void Palette::loadAmigaPalette(Common::ReadStream &stream, int startIndex, int c
for (int i = 0; i < colors; ++i) {
uint16 col = stream.readUint16BE();
- _palData[(i + startIndex) * 3 + 2] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
- _palData[(i + startIndex) * 3 + 1] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
- _palData[(i + startIndex) * 3 + 0] = ((col & 0xF) * 0xFF) / 0x3F; col >>= 4;
+ _palData[(i + startIndex) * 3 + 2] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4;
+ _palData[(i + startIndex) * 3 + 1] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4;
+ _palData[(i + startIndex) * 3 + 0] = ((col & 0xF) * 0x3F) / 0xF; col >>= 4;
}
}
@@ -3061,9 +3259,9 @@ void Palette::loadPC98Palette(Common::ReadStream &stream, int startIndex, int co
for (int i = 0; i < colors; ++i) {
const byte g = stream.readByte(), r = stream.readByte(), b = stream.readByte();
- _palData[(i + startIndex) * 3 + 0] = ((r & 0x0F) * 0x3F) / 0x0F;
- _palData[(i + startIndex) * 3 + 1] = ((g & 0x0F) * 0x3F) / 0x0F;
- _palData[(i + startIndex) * 3 + 2] = ((b & 0x0F) * 0x3F) / 0x0F;
+ _palData[(i + startIndex) * 3 + 0] = ((r & 0xF) * 0x3F) / 0xF;
+ _palData[(i + startIndex) * 3 + 1] = ((g & 0xF) * 0x3F) / 0xF;
+ _palData[(i + startIndex) * 3 + 2] = ((b & 0xF) * 0x3F) / 0xF;
}
}
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index d8380d104d..41837c90e3 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -56,15 +56,114 @@ struct ScreenDim {
uint16 unkE;
};
-struct Font {
- uint8 *fontData;
- uint8 *charWidthTable;
- uint16 fontDescOffset;
- uint16 charBitmapOffset;
- uint16 charWidthTableOffset;
- uint16 charHeightTableOffset;
-
- uint8 lastGlyph;
+/**
+ * A class that handles KYRA fonts.
+ */
+class Font {
+public:
+ virtual ~Font() {}
+
+ /**
+ * Tries to load a file from the given stream
+ */
+ virtual bool load(Common::SeekableReadStream &file) = 0;
+
+ /**
+ * The font height.
+ */
+ virtual int getHeight() const = 0;
+
+ /**
+ * The font width, this is the maximal character
+ * width.
+ */
+ virtual int getWidth() const = 0;
+
+ /**
+ * Gets the width of a specific character.
+ */
+ virtual int getCharWidth(uint8 c) const = 0;
+
+ /**
+ * Sets a text palette map. The map contains 16 entries.
+ */
+ virtual void setColorMap(const uint8 *src) = 0;
+
+ /**
+ * Draws a specific character.
+ *
+ * TODO/FIXME: Replace this with a nicer API. Currently
+ * the user has to assure that the character fits.
+ * We use this API, since it's hard to assure dirty rect
+ * handling from outside Screen.
+ */
+ virtual void drawChar(uint8 c, byte *dst, int pitch) const = 0;
+};
+
+/**
+ * Implementation of the Font interface for DOS fonts.
+ *
+ * TODO: Clean up the implementation. For example we might be able
+ * to not to keep the whole font in memory.
+ */
+class DOSFont : public Font {
+public:
+ DOSFont();
+ ~DOSFont() { unload(); }
+
+ bool load(Common::SeekableReadStream &file);
+ int getHeight() const { return _height; }
+ int getWidth() const { return _width; }
+ int getCharWidth(uint8 c) const;
+ void setColorMap(const uint8 *src) { _colorMap = src; }
+ void drawChar(uint8 c, byte *dst, int pitch) const;
+
+private:
+ void unload();
+
+ const uint8 *_colorMap;
+
+ uint8 *_data;
+
+ int _width, _height;
+
+ uint8 _numGlyphs;
+
+ uint8 *_widthTable;
+ uint8 *_heightTable;
+ uint16 *_bitmapOffsets;
+};
+
+/**
+ * Implementation of the Font interface for AMIGA fonts.
+ */
+class AMIGAFont : public Font {
+public:
+ AMIGAFont();
+ ~AMIGAFont() { unload(); }
+
+ bool load(Common::SeekableReadStream &file);
+ int getHeight() const { return _height; }
+ int getWidth() const { return _width; }
+ int getCharWidth(uint8 c) const;
+ void setColorMap(const uint8 *src) {}
+ void drawChar(uint8 c, byte *dst, int pitch) const;
+
+private:
+ void unload();
+
+ int _width, _height;
+
+ struct Character {
+ uint8 yOffset, xOffset, width;
+
+ struct Graphics {
+ uint16 width, height;
+ uint8 *bitmap;
+ } graphics;
+ };
+
+ Character _chars[255];
};
/**
@@ -256,6 +355,10 @@ public:
void setPaletteIndex(uint8 index, uint8 red, uint8 green, uint8 blue);
virtual void setScreenPalette(const Palette &pal);
+ // AMIGA version only
+ void enableInterfacePalette(bool e);
+ void setInterfacePalette(const Palette &pal, uint8 r, uint8 g, uint8 b);
+
void getRealPalette(int num, uint8 *dst);
Palette &getPalette(int num);
void copyPalette(const int dst, const int src);
@@ -342,7 +445,7 @@ public:
static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);
static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch, bool noXor);
- static void convertAmigaGfx(uint8 *data, int w, int h, bool offscreen = true);
+ static void convertAmigaGfx(uint8 *data, int w, int h, int depth = 5, bool wsa = false, int bytesPerPlane = -1);
static void convertAmigaMsc(uint8 *data);
protected:
@@ -382,7 +485,7 @@ protected:
Common::Array<Palette *> _palettes;
Palette *_internFadePalette;
- Font _fonts[FID_NUM];
+ Font *_fonts[FID_NUM];
uint8 _textColorsMap[16];
uint8 *_decodeShapeBuffer;
@@ -469,6 +572,9 @@ protected:
int _drawShapeVar4;
int _drawShapeVar5;
+ // AMIGA version
+ bool _interfacePaletteEnabled;
+
// debug
bool _debugEnabled;
};
diff --git a/engines/kyra/screen_lok.cpp b/engines/kyra/screen_lok.cpp
index 9fdeae1398..feddb29dd2 100644
--- a/engines/kyra/screen_lok.cpp
+++ b/engines/kyra/screen_lok.cpp
@@ -240,6 +240,22 @@ int Screen_LoK::getRectSize(int x, int y) {
return ((x*y) << 3);
}
+void Screen_LoK::postProcessCursor(uint8 *data, int width, int height, int pitch) {
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga && _interfacePaletteEnabled) {
+ pitch -= width;
+
+ for (int y = 0; y < height; ++y) {
+ for (int x = 0; x < width; ++x) {
+ if (*data != _cursorColorKey)
+ *data += 32;
+ ++data;
+ }
+
+ data += pitch;
+ }
+ }
+}
+
#pragma mark -
Screen_LoK_16::Screen_LoK_16(KyraEngine_LoK *vm, OSystem *system) : Screen_LoK(vm, system) {
diff --git a/engines/kyra/screen_lok.h b/engines/kyra/screen_lok.h
index 4eb22df374..ae1d85c0a7 100644
--- a/engines/kyra/screen_lok.h
+++ b/engines/kyra/screen_lok.h
@@ -59,6 +59,9 @@ public:
void addBitBlitRect(int x, int y, int w, int h);
void bitBlitRects();
+ // AMIGA specific
+ virtual void postProcessCursor(uint8 *data, int width, int height, int pitch);
+
protected:
enum {
kNumBitBlitRects = 10
diff --git a/engines/kyra/script_lok.cpp b/engines/kyra/script_lok.cpp
index 849c6b776d..929fbae1eb 100644
--- a/engines/kyra/script_lok.cpp
+++ b/engines/kyra/script_lok.cpp
@@ -231,12 +231,11 @@ int KyraEngine_LoK::o1_fadeSpecialPalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
if (_currentCharacter->sceneId != 45) {
if (stackPos(0) == 13) {
- // TODO: Check this!
_screen->copyPalette(0, 12);
_screen->setScreenPalette(_screen->getPalette(0));
}
} else {
- warning("KyraEngine_LoK::o1_fadeSpecialPalette not implemented");
+ setupZanthiaPalette(stackPos(0));
}
} else {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_fadeSpecialPalette(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
@@ -579,7 +578,17 @@ int KyraEngine_LoK::o1_restoreAllObjectBackgrounds(EMCState *script) {
int KyraEngine_LoK::o1_setCustomPaletteRange(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setCustomPaletteRange(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
- _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1));
+ if (_flags.platform == Common::kPlatformAmiga) {
+ if (_currentCharacter->sceneId == 45) {
+ setupZanthiaPalette(stackPos(0));
+ } else if (stackPos(0) == 29) {
+ _screen->copyPalette(0, 11);
+ } else if (stackPos(0) == 13) {
+ _screen->copyPalette(0, 12);
+ }
+ } else {
+ _screen->getPalette(1).copy(_specialPalettes[stackPos(0)], 0, stackPos(2), stackPos(1));
+ }
return 0;
}
@@ -1213,37 +1222,77 @@ int KyraEngine_LoK::o1_findBrightestFireberry(EMCState *script) {
int KyraEngine_LoK::o1_setFireberryGlowPalette(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_setFireberryGlowPalette(%p) (%d)", (const void *)script, stackPos(0));
- int palIndex = 0;
- switch (stackPos(0)) {
- case 0x1E:
- palIndex = 9;
- break;
- case 0x1F:
- palIndex = 10;
- break;
+ if (_flags.platform == Common::kPlatformAmiga) {
+ int palIndex = 0;
+
+ switch (stackPos(0)) {
+ case -1:
+ // The original seemed to draw some lines on page 2 here, which looks strange...
+ //if (!(_brandonStatusBit & 2))
+ // warning("Unimplemented case for o1_setFireberryGlowPalette");
+ palIndex = 9;
+ break;
- case 0x20:
- palIndex = 11;
- break;
+ case 30:
+ palIndex = 7;
+ break;
- case 0x21:
- case -1:
- palIndex = 12;
- break;
+ case 31:
+ palIndex = 8;
+ break;
- default:
- palIndex = 8;
- }
- if (_brandonStatusBit & 2) {
- if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 &&
- _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 &&
- (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) {
- palIndex = 14;
+ case 32:
+ case 33:
+ palIndex = 9;
+ break;
+
+ case 28: case 29: default:
+ palIndex = 6;
+ }
+
+ if (_brandonStatusBit & 2) {
+ if (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)
+ palIndex = 10;
}
+
+ _screen->copyPalette(0, palIndex);
+ } else {
+ int palIndex = 0;
+
+ switch (stackPos(0)) {
+ case 0x1E:
+ palIndex = 9;
+ break;
+
+ case 0x1F:
+ palIndex = 10;
+ break;
+
+ case 0x20:
+ palIndex = 11;
+ break;
+
+ case 0x21:
+ case -1:
+ palIndex = 12;
+ break;
+
+ default:
+ palIndex = 8;
+ }
+
+ if (_brandonStatusBit & 2) {
+ if (_currentCharacter->sceneId != 133 && _currentCharacter->sceneId != 137 &&
+ _currentCharacter->sceneId != 165 && _currentCharacter->sceneId != 173 &&
+ (_currentCharacter->sceneId < 187 || _currentCharacter->sceneId > 198)) {
+ palIndex = 14;
+ }
+ }
+
+ _screen->getPalette(1).copy(_specialPalettes[palIndex], 0, 15, 228);
}
- _screen->getPalette(1).copy(_specialPalettes[palIndex], 0, 15, 228);
return 0;
}
@@ -1255,9 +1304,11 @@ int KyraEngine_LoK::o1_drinkPotionAnimation(EMCState *script) {
int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_LoK::o1_makeAmuletAppear(%p) ()", (const void *)script);
- WSAMovie_v1 amulet(this);
- amulet.open("AMULET.WSA", 1, 0);
- if (amulet.opened()) {
+ Movie *amulet = createWSAMovie();
+ assert(amulet);
+ amulet->open("AMULET.WSA", 1, 0);
+
+ if (amulet->opened()) {
assert(_amuleteAnim);
_screen->hideMouse();
snd_playSoundEffect(0x70);
@@ -1275,7 +1326,7 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) {
if (code == 14)
snd_playSoundEffect(0x73);
- amulet.displayFrame(code, 0, 224, 152, 0, 0, 0);
+ amulet->displayFrame(code, 0, 224, 152, 0, 0, 0);
_animator->_updateScreen = true;
while (_system->getMillis() < nextTime) {
@@ -1287,6 +1338,8 @@ int KyraEngine_LoK::o1_makeAmuletAppear(EMCState *script) {
}
_screen->showMouse();
}
+
+ delete amulet;
setGameFlag(0x2D);
return 0;
}
diff --git a/engines/kyra/seqplayer.cpp b/engines/kyra/seqplayer.cpp
index 2145591c03..38d1b90e7a 100644
--- a/engines/kyra/seqplayer.cpp
+++ b/engines/kyra/seqplayer.cpp
@@ -389,7 +389,8 @@ void SeqPlayer::s1_copyRegionSpecial() {
const int x = (Screen::SCREEN_W - _screen->getTextWidth(copyStr)) / 2;
const int y = 179;
_screen->setTextColorMap(colorMap);
- _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC);
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ _screen->printText(copyStr, x + 1, y + 1, 0xB, 0xC);
_screen->printText(copyStr, x, y, 0xF, 0xC);
}
break;
diff --git a/engines/kyra/sequences_lok.cpp b/engines/kyra/sequences_lok.cpp
index 0279831c9d..3c953ef1d4 100644
--- a/engines/kyra/sequences_lok.cpp
+++ b/engines/kyra/sequences_lok.cpp
@@ -901,13 +901,13 @@ int KyraEngine_LoK::seq_playEnd() {
if (_endSequenceNeedLoading) {
snd_playWanderScoreViaMap(50, 1);
setupPanPages();
- _finalA = new WSAMovie_v1(this);
+ _finalA = createWSAMovie();
assert(_finalA);
_finalA->open("finala.wsa", 1, 0);
- _finalB = new WSAMovie_v1(this);
+ _finalB = createWSAMovie();
assert(_finalB);
_finalB->open("finalb.wsa", 1, 0);
- _finalC = new WSAMovie_v1(this);
+ _finalC = createWSAMovie();
assert(_finalC);
_endSequenceNeedLoading = 0;
_finalC->open("finalc.wsa", 1, 0);
@@ -1473,7 +1473,7 @@ int KyraEngine_LoK::handleBeadState() {
_beadStateVar = 0;
}
} else {
- _screen->copyBlockToPage(_screen->_curPage, beadState1.x >> 3, beadState1.y, beadState1.width, beadState1.height, _endSequenceBackUpRect);
+ _screen->copyBlockToPage(_screen->_curPage, beadState1.x, beadState1.y, beadState1.width << 3, beadState1.height, _endSequenceBackUpRect);
_screen->addBitBlitRect(beadState1.x, beadState1.y, beadState1.width2, beadState1.height);
beadState1.x = x;
beadState1.y = y;
@@ -1663,6 +1663,14 @@ void KyraEngine_LoK::closeFinalWsa() {
}
void KyraEngine_LoK::updateKyragemFading() {
+ if (_flags.platform == Common::kPlatformAmiga) {
+ // The AMIGA version seems to have no fading for the Kyragem. The code does not
+ // alter the screen palette.
+ //
+ // TODO: Check this in the original.
+ return;
+ }
+
static const uint8 kyraGemPalette[0x28] = {
0x3F, 0x3B, 0x38, 0x34, 0x32, 0x2F, 0x2C, 0x29, 0x25, 0x22,
0x1F, 0x1C, 0x19, 0x16, 0x12, 0x0F, 0x0C, 0x0A, 0x06, 0x03,
@@ -1674,14 +1682,17 @@ void KyraEngine_LoK::updateKyragemFading() {
return;
_kyragemFadingState.timerCount = _system->getMillis() + 4 * _tickLength;
+
int palPos = 684;
for (int i = 0; i < 20; ++i) {
_screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.rOffset];
_screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.gOffset];
_screen->getPalette(0)[palPos++] = kyraGemPalette[i + _kyragemFadingState.bOffset];
}
+
_screen->setScreenPalette(_screen->getPalette(0));
_animator->_updateScreen = true;
+
switch (_kyragemFadingState.nextOperation) {
case 0:
--_kyragemFadingState.bOffset;
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 86680a7b76..2062b9e88a 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -1598,10 +1598,15 @@ void KyraEngine_LoK::loadMainScreen(int page) {
else
warning("no main graphics file found");
- if (_flags.platform == Common::kPlatformAmiga)
+ _screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0, Screen::CR_NO_P_CHECK);
+
+ if (_flags.platform == Common::kPlatformAmiga) {
_screen->copyPalette(1, 0);
+ _screen->setInterfacePalette(_screen->getPalette(1), 0x3F, 0x3F, 0x3F);
- _screen->copyRegion(0, 0, 0, 0, 320, 200, page, 0);
+ // TODO: Move this to a better place
+ _screen->enableInterfacePalette(true);
+ }
}
void KyraEngine_HoF::initStaticResource() {
@@ -2249,6 +2254,22 @@ void GUI_LoK::initStaticResource() {
_menu[5].item[2].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeWalk);
_menu[5].item[4].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsChangeText);
_menu[5].item[5].callback = BUTTON_FUNCTOR(GUI_LoK, this, &GUI_LoK::controlsApply);
+
+ // The AMIGA version uses different colors, due to its 32 color nature. We did setup the 256 color version
+ // colors above, so we need to overwrite those with the correct values over here.
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga) {
+ for (int i = 0; i < 6; ++i) {
+ _menu[i].bkgdColor = 17;
+ _menu[i].color1 = 31;
+ _menu[i].color2 = 18;
+
+ for (int j = 0; j < _menu[i].numberOfItems; ++j) {
+ _menu[i].item[j].bkgdColor = 17;
+ _menu[i].item[j].color1 = 31;
+ _menu[i].item[j].color2 = 18;
+ }
+ }
+ }
}
void KyraEngine_LoK::setupButtonData() {
diff --git a/engines/kyra/text.cpp b/engines/kyra/text.cpp
index 4d511eae01..6965dbc985 100644
--- a/engines/kyra/text.cpp
+++ b/engines/kyra/text.cpp
@@ -200,37 +200,15 @@ void TextDisplayer::printTalkTextMessage(const char *text, int x, int y, uint8 c
_screen->copyRegion(_talkCoords.x, _talkMessageY, _talkCoords.x, _talkCoords.y, _talkCoords.w, _talkMessageH, srcPage, dstPage, Screen::CR_NO_P_CHECK);
int curPage = _screen->_curPage;
_screen->_curPage = srcPage;
- for (int i = 0; i < lineCount; ++i) {
- top = i * 10 + _talkMessageY;
- char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
- int left = getCenterStringX(msg, x1, x2);
- printText(msg, left, top, color, 0xC, 0);
- }
- _screen->_curPage = curPage;
- _talkMessagePrinted = true;
-}
-void TextDisplayer::printIntroTextMessage(const char *text, int x, int y, uint8 col1, uint8 col2, uint8 col3, int dstPage, Screen::FontId font) {
- char *str = preprocessString(text);
- int lineCount = buildMessageSubstrings(str);
- int top = y - lineCount * 10;
- if (top < 0) {
- top = 0;
- }
- _talkMessageY = top;
- _talkMessageH = lineCount * 10;
- int w = getWidestLineWidth(lineCount);
- int x1, x2;
- calcWidestLineBounds(x1, x2, w, x);
- _talkCoords.x = x1;
- _talkCoords.w = w + 2;
- int curPage = _screen->setCurPage(dstPage);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ setTextColor(color);
for (int i = 0; i < lineCount; ++i) {
top = i * 10 + _talkMessageY;
char *msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
int left = getCenterStringX(msg, x1, x2);
- printText(msg, left, top, col1, col2, col3, font);
+ printText(msg, left, top, color, 0xC, 0);
}
_screen->_curPage = curPage;
_talkMessagePrinted = true;
@@ -248,7 +226,7 @@ void TextDisplayer::printText(const char *str, int x, int y, uint8 c0, uint8 c1,
}
void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX) {
- uint8 colorTable[] = {0x0F, 0x9, 0x0C9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
+ uint8 colorTable[] = {0x0F, 0x09, 0xC9, 0x80, 0x5, 0x81, 0x0E, 0xD8, 0x55, 0x3A, 0x3a};
int top, left, x1, x2, w, x;
char *msg;
@@ -259,6 +237,9 @@ void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX
x = charX;
calcWidestLineBounds(x1, x2, w, x);
+ if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+ setTextColor(color);
+
for (int i = 0; i < lineCount; ++i) {
top = i * 10 + _talkMessageY;
msg = &_talkSubstrings[i * TALK_SUBSTRING_LEN];
@@ -266,4 +247,91 @@ void TextDisplayer::printCharacterText(const char *text, int8 charNum, int charX
printText(msg, left, top, color, 0xC, 0);
}
}
+
+void TextDisplayer::setTextColor(uint8 color) {
+ byte r, g, b;
+
+ switch (color) {
+ case 4:
+ // 0x09E
+ r = 0;
+ g = 37;
+ b = 58;
+ break;
+
+ case 5:
+ // 0xFF5
+ r = 63;
+ g = 63;
+ b = 21;
+ break;
+
+ case 27:
+ // 0x5FF
+ r = 21;
+ g = 63;
+ b = 63;
+ break;
+
+ case 34:
+ // 0x8E5
+ r = 33;
+ g = 58;
+ b = 21;
+ break;
+
+ case 58:
+ // 0x9FB
+ r = 37;
+ g = 63;
+ b = 46;
+ break;
+
+ case 85:
+ // 0x7CF
+ r = 29;
+ g = 50;
+ b = 63;
+ break;
+
+ case 114:
+ case 117:
+ // 0xFAF
+ r = 63;
+ g = 42;
+ b = 63;
+ break;
+
+ case 128:
+ case 129:
+ // 0xFCC
+ r = 63;
+ g = 50;
+ b = 50;
+ break;
+
+ case 201:
+ // 0xFD8
+ r = 63;
+ g = 54;
+ b = 33;
+ break;
+
+ case 216:
+ // 0xFC6
+ r = 63;
+ g = 50;
+ b = 25;
+ break;
+
+ default:
+ // 0xEEE
+ r = 58;
+ g = 58;
+ b = 58;
+ }
+
+ _screen->setPaletteIndex(0x10, r, g, b);
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/text.h b/engines/kyra/text.h
index d45e5f9242..73d77dcb4c 100644
--- a/engines/kyra/text.h
+++ b/engines/kyra/text.h
@@ -50,8 +50,6 @@ public:
virtual void calcWidestLineBounds(int &x1, int &x2, int w, int cx);
virtual void restoreTalkTextMessageBkgd(int srcPage, int dstPage);
void printTalkTextMessage(const char *text, int x, int y, uint8 color, int srcPage, int dstPage);
- void printIntroTextMessage(const char *text, int x, int y, uint8 col1, uint8 col2, uint8 col3,
- int dstPage, Screen::FontId font=Screen::FID_8_FNT);
virtual void printText(const char *str, int x, int y, uint8 c0, uint8 c1, uint8 c2, Screen::FontId font=Screen::FID_8_FNT);
void printCharacterText(const char *text, int8 charNum, int charX);
@@ -66,6 +64,9 @@ protected:
uint16 y, x, w;
};
+ // TODO: AMIGA and LoK specific, move to a better location
+ void setTextColor(uint8 color);
+
enum {
TALK_SUBSTRING_LEN = 80,
TALK_SUBSTRING_NUM = 6
@@ -76,6 +77,7 @@ protected:
TalkCoords _talkCoords;
bool _talkMessagePrinted;
};
+
} // end of namespace Kyra
#endif
diff --git a/engines/kyra/text_lok.cpp b/engines/kyra/text_lok.cpp
index 3f4bfb65ac..d2128b7037 100644
--- a/engines/kyra/text_lok.cpp
+++ b/engines/kyra/text_lok.cpp
@@ -322,18 +322,27 @@ void KyraEngine_LoK::characterSays(int vocFile, const char *chatStr, int8 charNu
void KyraEngine_LoK::drawSentenceCommand(const char *sentence, int color) {
_screen->hideMouse();
- _screen->fillRect(8, 143, 311, 152, 12);
+ _screen->fillRect(8, 143, 311, 152, _flags.platform == Common::kPlatformAmiga ? 19 : 12);
- if (_startSentencePalIndex != color || _fadeText != false) {
- _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3];
+ if (_flags.platform == Common::kPlatformAmiga) {
+ if (color != 19) {
+ _currSentenceColor[0] = 0x3F;
+ _currSentenceColor[1] = 0x3F;
+ _currSentenceColor[2] = 0x3F;
+
+ _screen->setInterfacePalette(_screen->getPalette(1),
+ _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
+ }
+ } else if (_startSentencePalIndex != color || _fadeText != false) {
+ _currSentenceColor[0] = _screen->getPalette(0)[765] = _screen->getPalette(0)[color*3+0];
_currSentenceColor[1] = _screen->getPalette(0)[766] = _screen->getPalette(0)[color*3+1];
_currSentenceColor[2] = _screen->getPalette(0)[767] = _screen->getPalette(0)[color*3+2];
_screen->setScreenPalette(_screen->getPalette(0));
- _startSentencePalIndex = 0;
+ _startSentencePalIndex = color;
}
- _text->printText(sentence, 8, 143, 0xFF, 12, 0);
+ _text->printText(sentence, 8, 143, 0xFF, _flags.platform == Common::kPlatformAmiga ? 19 : 12, 0);
_screen->showMouse();
setTextFadeTimerCountdown(15);
_fadeText = false;
@@ -364,10 +373,15 @@ void KyraEngine_LoK::updateTextFade() {
}
}
- _screen->getPalette(0)[765] = _currSentenceColor[0];
- _screen->getPalette(0)[766] = _currSentenceColor[1];
- _screen->getPalette(0)[767] = _currSentenceColor[2];
- _screen->setScreenPalette(_screen->getPalette(0));
+ if (_flags.platform == Common::kPlatformAmiga) {
+ _screen->setInterfacePalette(_screen->getPalette(1),
+ _currSentenceColor[0], _currSentenceColor[1], _currSentenceColor[2]);
+ } else {
+ _screen->getPalette(0)[765] = _currSentenceColor[0];
+ _screen->getPalette(0)[766] = _currSentenceColor[1];
+ _screen->getPalette(0)[767] = _currSentenceColor[2];
+ _screen->setScreenPalette(_screen->getPalette(0));
+ }
if (finished) {
_fadeText = false;
diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp
index ef3fd1a966..b221f869b7 100644
--- a/engines/kyra/wsamovie.cpp
+++ b/engines/kyra/wsamovie.cpp
@@ -75,11 +75,10 @@ int WSAMovie_v1::open(const char *filename, int offscreenDecode, Palette *palBuf
}
if (_numFrames & 0x8000) {
- // This is used in the Amiga version, the wsa playing code
- // doesn't include any handling of it though, so we disable
- // this warning for now.
- //warning("Unhandled wsa flags 0x80");
- _flags |= 0x80;
+ // This is used in the Amiga version.
+ if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+ warning("Unhandled wsa flags 0x8000");
+ _flags |= WF_FLIPPED;
_numFrames &= 0x7FFF;
}
_currentFrame = _numFrames;
@@ -262,7 +261,7 @@ void WSAMovieAmiga::displayFrame(int frameNum, int pageNum, int x, int y, uint16
if (_currentFrame == _numFrames) {
if (!(_flags & WF_NO_FIRST_FRAME)) {
Screen::decodeFrameDelta(dst, _deltaBuffer, true);
- Screen::convertAmigaGfx(dst, _width, _height);
+ Screen::convertAmigaGfx(dst, _width, _height, 5, (_flags & WF_FLIPPED) != 0);
if (_flags & WF_OFFSCREEN_DECODE) {
dst = _offscreenBuffer;
@@ -341,7 +340,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) {
const uint8 *src = _frameData + _frameOffsTable[frameNum];
Screen::decodeFrame4(src, _deltaBuffer, _deltaBufferSize);
Screen::decodeFrameDelta(dst, _deltaBuffer, true);
- Screen::convertAmigaGfx(dst, _width, _height);
+ Screen::convertAmigaGfx(dst, _width, _height, 5, (_flags & WF_FLIPPED) != 0);
src = dst;
dst = 0;
diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h
index 49ac5a28fe..957ee386ef 100644
--- a/engines/kyra/wsamovie.h
+++ b/engines/kyra/wsamovie.h
@@ -85,6 +85,7 @@ public:
WF_OFFSCREEN_DECODE = 0x10,
WF_NO_LAST_FRAME = 0x20,
WF_NO_FIRST_FRAME = 0x40,
+ WF_FLIPPED = 0x80,
WF_HAS_PALETTE = 0x100,
WF_XOR = 0x200
};
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 2ddc6979c9..eacae8e697 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -120,8 +120,11 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
#endif
// Segments
DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
+ DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
DCmd_Register("segment_info", WRAP_METHOD(Console, cmdSegmentInfo));
+ DCmd_Register("seginfo", WRAP_METHOD(Console, cmdSegmentInfo)); // alias
DCmd_Register("segment_kill", WRAP_METHOD(Console, cmdKillSegment));
+ DCmd_Register("segkill", WRAP_METHOD(Console, cmdKillSegment)); // alias
// Garbage collection
DCmd_Register("gc", WRAP_METHOD(Console, cmdGCInvoke));
DCmd_Register("gc_objects", WRAP_METHOD(Console, cmdGCObjects));
@@ -157,7 +160,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
DCmd_Register("go", WRAP_METHOD(Console, cmdGo));
// Breakpoints
DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList));
+ DCmd_Register("bplist", WRAP_METHOD(Console, cmdBreakpointList)); // alias
DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete));
+ DCmd_Register("bpdel", WRAP_METHOD(Console, cmdBreakpointDelete)); // alias
DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod));
DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointExecMethod)); // alias
DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction));
@@ -165,7 +170,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
// VM
DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps));
DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist));
+ DCmd_Register("vmvarlist", WRAP_METHOD(Console, cmdVMVarlist)); // alias
DCmd_Register("vm_vars", WRAP_METHOD(Console, cmdVMVars));
+ DCmd_Register("vmvars", WRAP_METHOD(Console, cmdVMVars)); // alias
DCmd_Register("stack", WRAP_METHOD(Console, cmdStack));
DCmd_Register("value_type", WRAP_METHOD(Console, cmdValueType));
DCmd_Register("view_listnode", WRAP_METHOD(Console, cmdViewListNode));
@@ -300,9 +307,9 @@ bool Console::cmdHelp(int argc, const char **argv) {
#endif
DebugPrintf("\n");
DebugPrintf("Segments:\n");
- DebugPrintf(" segment_table - Lists all segments\n");
- DebugPrintf(" segment_info - Provides information on the specified segment\n");
- DebugPrintf(" segment_kill - Deletes the specified segment\n");
+ DebugPrintf(" segment_table / segtable - Lists all segments\n");
+ DebugPrintf(" segment_info / seginfo - Provides information on the specified segment\n");
+ DebugPrintf(" segment_kill / segkill - Deletes the specified segment\n");
DebugPrintf("\n");
DebugPrintf("Garbage collection:\n");
DebugPrintf(" gc - Invokes the garbage collector\n");
@@ -335,15 +342,15 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" go - Executes the script\n");
DebugPrintf("\n");
DebugPrintf("Breakpoints:\n");
- DebugPrintf(" bp_list - Lists the current breakpoints\n");
- DebugPrintf(" bp_del - Deletes a breakpoint with the specified index\n");
+ DebugPrintf(" bp_list / bplist - Lists the current breakpoints\n");
+ DebugPrintf(" bp_del / bpdel - Deletes a breakpoint with the specified index\n");
DebugPrintf(" bp_exec_method / bpx - Sets a breakpoint on the execution of the specified method\n");
DebugPrintf(" bp_exec_function / bpe - Sets a breakpoint on the execution of the specified exported function\n");
DebugPrintf("\n");
DebugPrintf("VM:\n");
DebugPrintf(" script_steps - Shows the number of executed SCI operations\n");
- DebugPrintf(" vm_varlist - Shows the addresses of variables in the VM\n");
- DebugPrintf(" vm_vars - Displays or changes variables in the VM\n");
+ DebugPrintf(" vm_varlist / vmvarlist - Shows the addresses of variables in the VM\n");
+ DebugPrintf(" vm_vars / vmvars - Displays or changes variables in the VM\n");
DebugPrintf(" stack - Lists the specified number of stack elements\n");
DebugPrintf(" value_type - Determines the type of a value\n");
DebugPrintf(" view_listnode - Examines the list node at the given address\n");
@@ -1713,7 +1720,7 @@ bool Console::cmdVMVarlist(int argc, const char **argv) {
}
bool Console::cmdVMVars(int argc, const char **argv) {
- if (argc < 2) {
+ if (argc < 3) {
DebugPrintf("Displays or changes variables in the VM\n");
DebugPrintf("Usage: %s <type> <varnum> [<value>]\n", argv[0]);
DebugPrintf("First parameter is either g(lobal), l(ocal), t(emp) or p(aram).\n");
@@ -1747,10 +1754,10 @@ bool Console::cmdVMVars(int argc, const char **argv) {
}
switch (argc) {
- case 2:
+ case 3:
DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(scriptState.variables[vartype][idx]));
break;
- case 3:
+ case 4:
if (parse_reg_t(_vm->_gamestate, argv[3], &scriptState.variables[vartype][idx])) {
DebugPrintf("Invalid address passed.\n");
DebugPrintf("Check the \"addresses\" command on how to use addresses\n");
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index 7118eb682d..d0b3919c60 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -569,6 +569,20 @@ static const struct SciGameDescription SciGameDescriptions[] = {
SCI_VERSION_1
},
+ // Eco Quest - French DOS Floppy (from Strangerke)
+ // SCI interpreter version 1.ECO.013
+ {{"ecoquest", "Floppy", {
+ {"resource.map", 0, "67742945cd59b896d9f22a549f605217", 4407},
+ {"resource.000", 0, "0b12a91c935e385308af8d17811deded", 973723},
+ {"resource.001", 0, "fc7fba54b6bb88fd7e9c229636599aa9", 1205841},
+ {"resource.002", 0, "b836c6ee9de67d814ac5d1b05f5b9858", 1173872},
+ {"resource.003", 0, "f8f767f9d6351432621c6e54c1b2ba8c", 1141520},
+ {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH},
+ 0,
+ SCI_VERSION_AUTODETECT,
+ SCI_VERSION_1
+ },
+
// Eco Quest 2 - English DOS Non-Interactive Demo
// SCI interpreter version 1.001.055
{{"ecoquest2", "Demo", {
@@ -591,6 +605,17 @@ static const struct SciGameDescription SciGameDescriptions[] = {
SCI_VERSION_1_1
},
+ // Eco Quest 2 - French DOS Floppy (from Strangerke)
+ // SCI interpreter version 1.001.081
+ {{"ecoquest2", "Floppy", {
+ {"resource.map", 0, "c22ab8b33c339c138b6b1697b77b9e79", 5588},
+ {"resource.000", 0, "1c4093f7248240329121fdf8c0d59152", 4231946},
+ {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH},
+ 0,
+ SCI_VERSION_AUTODETECT,
+ SCI_VERSION_1_1
+ },
+
// Freddy Pharkas - English DOS demo (from FRG)
// SCI interpreter version 1.001.069
{{"freddypharkas", "Demo", {
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index 0a74ac32e4..fa64957bec 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -497,6 +497,9 @@ int game_init(EngineState *s) {
if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
game_init_sound(s, 0);
+ // Load game language into printLang property of game object
+ s->getLanguage();
+
return 0;
}
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 4133f4cb3b..2ccd88b709 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -320,6 +320,7 @@ SciKernelFunction kfunct_mappers[] = {
/*(?)*/ DEFUN("Lock", kLock, "iii*"),
/*(?)*/ DEFUN("Palette", kPalette, "i.*"),
/*(?)*/ DEFUN("IsItSkip", kIsItSkip, "iiiii"),
+ /*7b*/ DEFUN("StrSplit", kStrSplit, "rrZr"),
// Non-experimental Functions without a fixed ID
DEFUN("CosMult", kTimesCos, "ii"),
@@ -345,7 +346,6 @@ SciKernelFunction kfunct_mappers[] = {
DEFUN("MemorySegment", kStub, ".*"),
DEFUN("ListOps", kStub, ".*"),
DEFUN("ATan", kStub, ".*"),
- DEFUN("StrSplit", kStub, ".*"),
DEFUN("MergePoly", kStub, ".*"),
DEFUN("AssertPalette", kStub, ".*"),
DEFUN("TextColors", kStub, ".*"),
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 15f7c9fcf3..83b43542d4 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -540,6 +540,7 @@ reg_t kResCheck(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t kShowMovie(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t kSetVideoMode(EngineState *s, int funct_nr, int argc, reg_t *argv);
+reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv);
reg_t k_Unknown(EngineState *s, int funct_nr, int argc, reg_t *argv);
// The Unknown/Unnamed kernel function
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index c693009b35..2f0072ec67 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -251,7 +251,7 @@ reg_t kStub(EngineState *s, int funct_nr, int argc, reg_t *argv) {
}
strcat(tmpbuf, ")");
- warning(tmpbuf);
+ warning("%s", tmpbuf);
return NULL_REG;
}
diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp
index b6bb404d5b..6e5a19bba9 100644
--- a/engines/sci/engine/kstring.cpp
+++ b/engines/sci/engine/kstring.cpp
@@ -812,4 +812,21 @@ reg_t kSetQuitStr(EngineState *s, int funct_nr, int argc, reg_t *argv) {
return s->r_acc;
}
+reg_t kStrSplit(EngineState *s, int funct_nr, int argc, reg_t *argv) {
+ const char *format = kernel_dereference_char_pointer(s, argv[1], 0);
+ const char *sep = !argv[2].isNull() ? kernel_dereference_char_pointer(s, argv[2], 0) : NULL;
+ Common::String str = s->strSplit(format, sep);
+
+ // Make sure target buffer is large enough
+ char *buf = kernel_dereference_char_pointer(s, argv[0], str.size() + 1);
+
+ if (buf) {
+ strcpy(buf, str.c_str());
+ return argv[0];
+ } else {
+ warning("StrSplit: buffer %04x:%04x invalid or too small to hold the following text of %i bytes: '%s'", PRINT_REG(argv[0]), str.size() + 1, str.c_str());
+ return NULL_REG;
+ }
+}
+
} // End of namespace Sci
diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp
index c019f7a3bc..a55d692afe 100644
--- a/engines/sci/engine/message.cpp
+++ b/engines/sci/engine/message.cpp
@@ -33,7 +33,7 @@ MessageTuple MessageState::getTuple() {
t.noun = *(_engineCursor.index_record + 0);
t.verb = *(_engineCursor.index_record + 1);
- if (_version == 2101) {
+ if (_version == 2) {
t.cond = 0;
t.seq = 1;
} else {
@@ -47,7 +47,7 @@ MessageTuple MessageState::getTuple() {
MessageTuple MessageState::getRefTuple() {
MessageTuple t;
- if (_version == 2101) {
+ if (_version == 2) {
t.noun = 0;
t.verb = 0;
t.cond = 0;
@@ -68,7 +68,7 @@ void MessageState::initCursor() {
}
void MessageState::advanceCursor(bool increaseSeq) {
- _engineCursor.index_record += ((_version == 2101) ? 4 : 11);
+ _engineCursor.index_record += ((_version == 2) ? 4 : 11);
_engineCursor.index++;
if (increaseSeq)
@@ -142,7 +142,7 @@ int MessageState::getMessage() {
}
int MessageState::getTalker() {
- return (_version == 2101) ? -1 : *(_engineCursor.index_record + 4);
+ return (_version == 2) ? -1 : *(_engineCursor.index_record + 4);
}
MessageTuple &MessageState::getLastTuple() {
@@ -154,7 +154,7 @@ int MessageState::getLastModule() {
}
Common::String MessageState::getText() {
- char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
+ char *str = (char *)_currentResource->data + READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5));
Common::String strippedStr;
Common::String skippedSubstr;
@@ -215,7 +215,7 @@ void MessageState::gotoNext() {
}
int MessageState::getLength() {
- int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2101) ? 2 : 5));
+ int offset = READ_LE_UINT16(_engineCursor.index_record + ((_version == 2) ? 2 : 5));
char *stringptr = (char *)_currentResource->data + offset;
return strlen(stringptr);
}
@@ -244,8 +244,12 @@ int MessageState::loadRes(ResourceManager *resmgr, int module, bool lock) {
_locked = lock;
_version = READ_LE_UINT16(_currentResource->data);
+ debug(5, "Message: reading resource %d.msg, version %d.%03d", _module, _version / 1000, _version % 1000);
- int offs = (_version == 2101) ? 0 : 4;
+ // We assume for now that storing the major version is sufficient
+ _version /= 1000;
+
+ int offs = (_version == 2) ? 0 : 4;
_recordCount = READ_LE_UINT16(_currentResource->data + 4 + offs);
_indexRecords = _currentResource->data + 6 + offs;
diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp
index 38320c29cc..405c9ec66f 100644
--- a/engines/sci/engine/state.cpp
+++ b/engines/sci/engine/state.cpp
@@ -172,15 +172,62 @@ Common::String EngineState::getLanguageString(const char *str, kLanguage lang) c
return Common::String(str);
}
+kLanguage EngineState::getLanguage() {
+ kLanguage lang = K_LANG_ENGLISH;
+
+ if (((SciEngine*)g_engine)->getKernel()->_selectorMap.printLang != -1) {
+ EngineState *s = this;
+
+ lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
+
+ if ((_version == SCI_VERSION_1_1) || (lang == K_LANG_NONE)) {
+ // If language is set to none, we use the language from the game detector.
+ // SSCI reads this from resource.cfg (early games do not have a language
+ // setting in resource.cfg, but instead have the secondary language number
+ // hardcoded in the game script).
+ // SCI1.1 games always use the language setting from the config file
+ // (essentially disabling runtime language switching).
+ // Note: only a limited number of multilanguage games have been tested
+ // so far, so this information may not be 100% accurate.
+ switch (((Sci::SciEngine*)g_engine)->getLanguage()) {
+ case Common::FR_FRA:
+ lang = K_LANG_FRENCH;
+ break;
+ case Common::ES_ESP:
+ lang = K_LANG_SPANISH;
+ break;
+ case Common::IT_ITA:
+ lang = K_LANG_ITALIAN;
+ break;
+ case Common::DE_DEU:
+ lang = K_LANG_GERMAN;
+ break;
+ case Common::JA_JPN:
+ lang = K_LANG_JAPANESE;
+ break;
+ case Common::PT_BRA:
+ lang = K_LANG_PORTUGUESE;
+ break;
+ default:
+ lang = K_LANG_ENGLISH;
+ }
+
+ // Store language in printLang selector
+ PUT_SEL32V(s->game_obj, printLang, lang);
+ }
+ }
+
+ return lang;
+}
+
Common::String EngineState::strSplit(const char *str, const char *sep) {
EngineState *s = this;
- kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang);
- kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
+ kLanguage lang = getLanguage();
+ kLanguage subLang = K_LANG_NONE;
- // Use English when no language settings are present in the game
- if (lang == K_LANG_NONE)
- lang = K_LANG_ENGLISH;
+ if (((SciEngine*)g_engine)->getKernel()->_selectorMap.subtitleLang != -1)
+ subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang);
Common::String retval = getLanguageString(str, lang);
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index b41e9e383a..3db926ab3d 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -125,6 +125,7 @@ public:
virtual ~EngineState();
virtual void saveLoadWithSerializer(Common::Serializer &ser);
+ kLanguage getLanguage();
public:
int widget_serial_counter; /**< Used for savegames */
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 0f8fee0876..02c287a99a 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -126,9 +126,9 @@ static int validate_variable(reg_t *r, reg_t *stack_base, int type, int max, int
}
if (g_debug_weak_validations)
- warning(txt);
+ warning("%s", txt);
else
- error(txt);
+ error("%s", txt);
#ifdef STRICT_READ
return 1;
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 5054bffd30..99a28153c4 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -413,6 +413,7 @@ static const GameFilenamePattern gameFilenamesTable[] = {
{ "maniac", "Maniac Mansion (SW).prg", kGenUnchanged, Common::SE_SWE, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (U).prg", kGenUnchanged, Common::EN_USA, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (G).prg", kGenUnchanged, Common::DE_DEU, Common::kPlatformNES, "NES" },
+ { "maniac", "Maniac Mansion (I).prg", kGenUnchanged, Common::IT_ITA, Common::kPlatformNES, "NES" },
{ "maniac", "Maniac Mansion (Sp).prg", kGenUnchanged, Common::ES_ESP, Common::kPlatformNES, "NES" },
{ "zak", "%02d.LFL", kGenRoomNum, UNK_LANG, UNK, 0 },
diff --git a/engines/scumm/file_nes.cpp b/engines/scumm/file_nes.cpp
index 444b117037..e2604039a4 100644
--- a/engines/scumm/file_nes.cpp
+++ b/engines/scumm/file_nes.cpp
@@ -113,6 +113,16 @@ static const ScummNESFile::Resource res_roomgfx_esp[40] = {
{ 0x07CA4, 0x02D6 }, { 0x10001, 0x06A3 }, { 0x106A4, 0x091F }, { 0x10FC3, 0x0361 }, { 0x11324, 0x0489 },
{ 0x117AD, 0x0437 }, { 0x11BE4, 0x086E }, { 0x12452, 0x0199 }, { 0x125EB, 0x0947 }, { 0x12F32, 0x037A }
};
+static const ScummNESFile::Resource res_roomgfx_ita[40] = {
+ { 0x04001, 0x03EF }, { 0x043F0, 0x069E }, { 0x04A8E, 0x0327 }, { 0x04DB5, 0x053B }, { 0x052F0, 0x06BE },
+ { 0x059AE, 0x0682 }, { 0x06030, 0x0778 }, { 0x067A8, 0x0517 }, { 0x06CBF, 0x07FB }, { 0x074BA, 0x07BE },
+ { 0x08001, 0x07A5 }, { 0x087A6, 0x06DD }, { 0x08E83, 0x04EA }, { 0x0936D, 0x07E2 }, { 0x09B4F, 0x0791 },
+ { 0x0A2E0, 0x07B5 }, { 0x0AA95, 0x0515 }, { 0x0AFAA, 0x0799 }, { 0x0B743, 0x04BB }, { 0x0BBFE, 0x0319 },
+ { 0x0C001, 0x0464 }, { 0x0C465, 0x072C }, { 0x0CB91, 0x0827 }, { 0x0D3B8, 0x0515 }, { 0x0D8CD, 0x064E },
+ { 0x0DF1B, 0x0775 }, { 0x0E690, 0x06DD }, { 0x0ED6D, 0x0376 }, { 0x0F0E3, 0x05F7 }, { 0x0F6DA, 0x0787 },
+ { 0x07C78, 0x02D6 }, { 0x10001, 0x06A3 }, { 0x106A4, 0x0921 }, { 0x10FC5, 0x0361 }, { 0x11326, 0x0489 },
+ { 0x117AF, 0x0437 }, { 0x11BE6, 0x0863 }, { 0x12449, 0x0199 }, { 0x125E2, 0x0947 }, { 0x12F29, 0x037A }
+};
const ScummNESFile::ResourceGroup res_roomgfx = {
ScummNESFile::NES_ROOMGFX,
@@ -123,6 +133,7 @@ const ScummNESFile::ResourceGroup res_roomgfx = {
res_roomgfx_fra,
res_roomgfx_ger,
res_roomgfx_esp,
+ res_roomgfx_ita,
}
};
@@ -132,6 +143,7 @@ static const ScummNESFile::Resource res_costumegfx_swe[2] = { { 0x2EFE1, 0x0EB8
static const ScummNESFile::Resource res_costumegfx_fra[2] = { { 0x30001, 0x0EB8 }, { 0x2F608, 0x0340 } };
static const ScummNESFile::Resource res_costumegfx_ger[2] = { { 0x30001, 0x0EB8 }, { 0x2F4CE, 0x0340 } };
static const ScummNESFile::Resource res_costumegfx_esp[2] = { { 0x30001, 0x0EB8 }, { 0x2F0F6, 0x0340 } };
+static const ScummNESFile::Resource res_costumegfx_ita[2] = { { 0x30001, 0x0EB8 }, { 0x2F4A0, 0x0340 } };
const ScummNESFile::ResourceGroup res_costumegfx = {
ScummNESFile::NES_COSTUMEGFX,
@@ -142,6 +154,7 @@ const ScummNESFile::ResourceGroup res_costumegfx = {
res_costumegfx_fra,
res_costumegfx_ger,
res_costumegfx_esp,
+ res_costumegfx_ita,
}
};
@@ -223,6 +236,19 @@ static const ScummNESFile::Resource res_rooms_esp[55] = {
{ 0x289BE, 0x058E }, { 0x2A418, 0x0201 }, { 0x2A6BE, 0x0325 }, { 0x23D84, 0x01FC }, { 0x2AC46, 0x02A9 },
{ 0x2AEEF, 0x02C9 }, { 0x2B2C0, 0x03D2 }, { 0x27D12, 0x0207 }, { 0x2B7FC, 0x0168 }, { 0x2BD06, 0x0169 }
};
+static const ScummNESFile::Resource res_rooms_ita[55] = {
+ { 0x00000, 0x0000 }, { 0x14001, 0x0D70 }, { 0x132A3, 0x04EA }, { 0x15423, 0x086E }, { 0x1378D, 0x06B1 },
+ { 0x15D16, 0x070F }, { 0x16658, 0x04DB }, { 0x16B33, 0x0AEF }, { 0x18001, 0x06DF }, { 0x17991, 0x03E1 },
+ { 0x18C5C, 0x065E }, { 0x19316, 0x04AF }, { 0x199EA, 0x0448 }, { 0x1A09D, 0x0479 }, { 0x1A516, 0x0445 },
+ { 0x1A95B, 0x03A7 }, { 0x1AD02, 0x0826 }, { 0x1B588, 0x0693 }, { 0x1C001, 0x0B92 }, { 0x1CD70, 0x0484 },
+ { 0x1D4E3, 0x0598 }, { 0x1DFCB, 0x0538 }, { 0x1E9C9, 0x05D1 }, { 0x1F052, 0x0394 }, { 0x1F70D, 0x0741 },
+ { 0x20001, 0x04C2 }, { 0x2053F, 0x0528 }, { 0x21718, 0x05F6 }, { 0x21EB5, 0x0486 }, { 0x223E8, 0x048C },
+ { 0x228DA, 0x093A }, { 0x24001, 0x037A }, { 0x247EE, 0x03CA }, { 0x24BB8, 0x050D }, { 0x25289, 0x0346 },
+ { 0x1BCAC, 0x01CA }, { 0x255CF, 0x045F }, { 0x25A2E, 0x0552 }, { 0x25F80, 0x0651 }, { 0x26B93, 0x024B },
+ { 0x26DDE, 0x01FA }, { 0x270D6, 0x0217 }, { 0x275E4, 0x02F4 }, { 0x28001, 0x045C }, { 0x284CE, 0x08BD },
+ { 0x28DDF, 0x05DF }, { 0x27AC9, 0x0201 }, { 0x2A8A3, 0x0325 }, { 0x27D6F, 0x01FC }, { 0x2AE66, 0x02A9 },
+ { 0x2B10F, 0x02E7 }, { 0x2B4F9, 0x03DE }, { 0x2BA31, 0x0206 }, { 0x2C001, 0x0168 }, { 0x17DC0, 0x0169 }
+};
const ScummNESFile::ResourceGroup res_rooms = {
ScummNESFile::NES_ROOM,
@@ -233,6 +259,7 @@ const ScummNESFile::ResourceGroup res_rooms = {
res_rooms_fra,
res_rooms_ger,
res_rooms_esp,
+ res_rooms_ita,
}
};
@@ -464,6 +491,44 @@ static const ScummNESFile::Resource res_scripts_esp[179] = {
{ 0x2A2C7, 0x0005 }, { 0x2A2CC, 0x0005 }, { 0x2A2D1, 0x0005 }, { 0x2A2D6, 0x0005 }, { 0x216E8, 0x0033 },
{ 0x2A2DB, 0x0005 }, { 0x00000, 0x0000 }, { 0x2A2E0, 0x009C }, { 0x2A37C, 0x009C }
};
+static const ScummNESFile::Resource res_scripts_ita[179] = {
+ { 0x00000, 0x0000 }, { 0x293BE, 0x046B }, { 0x29829, 0x020C }, { 0x29A35, 0x00AA }, { 0x29ADF, 0x03FD },
+ { 0x29EDC, 0x01A1 }, { 0x00000, 0x0000 }, { 0x2A07D, 0x005C }, { 0x00000, 0x0000 }, { 0x2A0D9, 0x0005 },
+ { 0x2C169, 0x000D }, { 0x2C176, 0x000D }, { 0x186E0, 0x0040 }, { 0x18720, 0x0016 }, { 0x1B528, 0x0046 },
+ { 0x1EF9A, 0x00B8 }, { 0x21D0E, 0x0056 }, { 0x17622, 0x0027 }, { 0x1FE4E, 0x0027 }, { 0x1FE75, 0x0027 },
+ { 0x1BC1B, 0x0022 }, { 0x15C91, 0x0085 }, { 0x2233B, 0x001E }, { 0x22359, 0x008F }, { 0x192BA, 0x002B },
+ { 0x1CB93, 0x0065 }, { 0x1CBF8, 0x003F }, { 0x1CC37, 0x004E }, { 0x1CC85, 0x0055 }, { 0x204C3, 0x007C },
+ { 0x16425, 0x0035 }, { 0x1645A, 0x001C }, { 0x16476, 0x0014 }, { 0x1648A, 0x001C }, { 0x164A6, 0x0027 },
+ { 0x164CD, 0x018B }, { 0x1D1F4, 0x009B }, { 0x1D28F, 0x010A }, { 0x1D399, 0x001C }, { 0x1D3B5, 0x0056 },
+ { 0x1D40B, 0x0072 }, { 0x1E503, 0x0028 }, { 0x1E52B, 0x01AA }, { 0x1E6D5, 0x0233 }, { 0x2845D, 0x0071 },
+ { 0x17D72, 0x004E }, { 0x13E3E, 0x0039 }, { 0x18736, 0x02C8 }, { 0x189FE, 0x00BB }, { 0x18AB9, 0x019E },
+ { 0x00000, 0x0000 }, { 0x19E32, 0x00F8 }, { 0x21D64, 0x00F7 }, { 0x1E908, 0x00B0 }, { 0x21E5B, 0x0047 },
+ { 0x2C183, 0x004D }, { 0x13E77, 0x0024 }, { 0x14D71, 0x0014 }, { 0x17649, 0x0058 }, { 0x176A1, 0x010A },
+ { 0x177AB, 0x0009 }, { 0x14D85, 0x01B7 }, { 0x2ABC8, 0x029E }, { 0x23214, 0x070B }, { 0x2C1D0, 0x001A },
+ { 0x2C1EA, 0x0021 }, { 0x2C20B, 0x0022 }, { 0x2C22D, 0x0023 }, { 0x2C250, 0x0016 }, { 0x2C266, 0x001E },
+ { 0x2C284, 0x0016 }, { 0x2C29A, 0x0027 }, { 0x00000, 0x0000 }, { 0x2C2C1, 0x000E }, { 0x177B4, 0x00AA },
+ { 0x22874, 0x0066 }, { 0x14F3C, 0x007B }, { 0x1F3E6, 0x0126 }, { 0x1FE9C, 0x001D }, { 0x1F50C, 0x00B4 },
+ { 0x1F5C0, 0x00AA }, { 0x1785E, 0x006D }, { 0x178CB, 0x003F }, { 0x1F66A, 0x00A3 }, { 0x2C2CF, 0x00AF },
+ { 0x2C37E, 0x00BD }, { 0x2C43B, 0x0085 }, { 0x20A67, 0x01AA }, { 0x20C11, 0x016A }, { 0x20D7B, 0x0073 },
+ { 0x20DEE, 0x003B }, { 0x20E29, 0x00F0 }, { 0x20F19, 0x0047 }, { 0x20F60, 0x00FD }, { 0x2105D, 0x00FF },
+ { 0x2115C, 0x0157 }, { 0x212B3, 0x0195 }, { 0x21448, 0x002E }, { 0x21476, 0x00A9 }, { 0x2437B, 0x011F },
+ { 0x1BC3D, 0x006F }, { 0x1CCDA, 0x0096 }, { 0x28D8B, 0x0054 }, { 0x19F2A, 0x00B8 }, { 0x19FE2, 0x0071 },
+ { 0x14FB7, 0x0057 }, { 0x272ED, 0x02F7 }, { 0x1DA7B, 0x021C }, { 0x1DC97, 0x00FA }, { 0x1DD91, 0x0053 },
+ { 0x1DDE4, 0x01CF }, { 0x1500E, 0x004D }, { 0x26FD8, 0x00FE }, { 0x21EA2, 0x0013 }, { 0x2A0DE, 0x00F0 },
+ { 0x2449A, 0x00DC }, { 0x2151F, 0x00E7 }, { 0x24576, 0x0022 }, { 0x2B8D7, 0x00FE }, { 0x24598, 0x00BB },
+ { 0x250C5, 0x0188 }, { 0x1B56E, 0x000D }, { 0x1B57B, 0x000D }, { 0x2391F, 0x0182 }, { 0x278D8, 0x01F1 },
+ { 0x23AA1, 0x0150 }, { 0x23BF1, 0x01C2 }, { 0x23DB3, 0x0016 }, { 0x2B9D5, 0x005C }, { 0x23DC9, 0x0020 },
+ { 0x27CCA, 0x00A5 }, { 0x2A1CE, 0x0384 }, { 0x1505B, 0x00FA }, { 0x2B3F6, 0x005E }, { 0x00000, 0x0000 },
+ { 0x2524D, 0x003C }, { 0x1E9B8, 0x0011 }, { 0x13E9B, 0x0018 }, { 0x265D1, 0x001F }, { 0x265F0, 0x0054 },
+ { 0x26644, 0x0155 }, { 0x26799, 0x004B }, { 0x267E4, 0x017C }, { 0x26960, 0x0027 }, { 0x26987, 0x0041 },
+ { 0x269C8, 0x01CB }, { 0x13EB3, 0x001F }, { 0x24653, 0x002A }, { 0x15155, 0x01A4 }, { 0x192E5, 0x0031 },
+ { 0x1790A, 0x0087 }, { 0x21606, 0x00DF }, { 0x1D47D, 0x0018 }, { 0x1D495, 0x004E }, { 0x18C57, 0x0005 },
+ { 0x152F9, 0x011F }, { 0x15418, 0x000B }, { 0x2467D, 0x0136 }, { 0x247B3, 0x0014 }, { 0x1DFB3, 0x0018 },
+ { 0x247C7, 0x0027 }, { 0x1A053, 0x004A }, { 0x00000, 0x0000 }, { 0x2B454, 0x00A5 }, { 0x2A552, 0x00BB },
+ { 0x2A60D, 0x0140 }, { 0x197C5, 0x00C6 }, { 0x1988B, 0x014D }, { 0x199D8, 0x0012 }, { 0x2A74D, 0x0005 },
+ { 0x2A752, 0x0005 }, { 0x2A757, 0x0005 }, { 0x2A75C, 0x0005 }, { 0x2A761, 0x0005 }, { 0x216E5, 0x0033 },
+ { 0x2A766, 0x0005 }, { 0x00000, 0x0000 }, { 0x2A76B, 0x009C }, { 0x2A807, 0x009C }
+};
const ScummNESFile::ResourceGroup res_scripts = {
ScummNESFile::NES_SCRIPT,
@@ -474,6 +539,7 @@ const ScummNESFile::ResourceGroup res_scripts = {
res_scripts_fra,
res_scripts_ger,
res_scripts_esp,
+ res_scripts_ita,
}
};
@@ -591,6 +657,25 @@ static const ScummNESFile::Resource res_sounds_esp[82] = {
{ 0x36320, 0x0E56 }, { 0x37176, 0x0C70 }, { 0x38001, 0x0DEC }, { 0x38DED, 0x0B77 }, { 0x33B4F, 0x042F },
{ 0x39964, 0x0AC5 }, { 0x3A429, 0x0BE4 }
};
+static const ScummNESFile::Resource res_sounds_ita[82] = {
+ { 0x0BF54, 0x000A }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 }, { 0x30ECA, 0x0832 },
+ { 0x30ECA, 0x0832 }, { 0x0BF5E, 0x0011 }, { 0x1FEB9, 0x0073 }, { 0x0BF6F, 0x0011 }, { 0x13F57, 0x0011 },
+ { 0x23EFE, 0x0056 }, { 0x1BF37, 0x001F }, { 0x13F68, 0x0011 }, { 0x0FF76, 0x000A }, { 0x17F64, 0x000A },
+ { 0x1BF56, 0x0019 }, { 0x1FF2C, 0x004B }, { 0x17F6E, 0x000A }, { 0x1BF6F, 0x000F }, { 0x23F54, 0x001D },
+ { 0x2BE61, 0x0045 }, { 0x23F71, 0x000F }, { 0x2BEA6, 0x001B }, { 0x2BEC1, 0x0033 }, { 0x27F6B, 0x0011 },
+ { 0x2BEF4, 0x000F }, { 0x2BF03, 0x0075 }, { 0x2F7F1, 0x0014 }, { 0x0BF54, 0x000A }, { 0x2F805, 0x00FF },
+ { 0x2F904, 0x000F }, { 0x2F913, 0x000F }, { 0x2F922, 0x0092 }, { 0x2F922, 0x0092 }, { 0x2F9B4, 0x002D },
+ { 0x2F9E1, 0x00F8 }, { 0x2FAD9, 0x0016 }, { 0x2FAEF, 0x0011 }, { 0x2FB00, 0x004B }, { 0x2FB4B, 0x0011 },
+ { 0x2FB5C, 0x003B }, { 0x2FB97, 0x008A }, { 0x2FC21, 0x0011 }, { 0x2FC32, 0x000F }, { 0x2FC41, 0x00A2 },
+ { 0x2FCE3, 0x00D3 }, { 0x2FDB6, 0x0097 }, { 0x2BEF4, 0x000F }, { 0x2FC41, 0x00A2 }, { 0x316FC, 0x05D1 },
+ { 0x316FC, 0x05D1 }, { 0x2FE4D, 0x0011 }, { 0x0BF54, 0x000A }, { 0x2BF03, 0x0075 }, { 0x1BF37, 0x001F },
+ { 0x31CCD, 0x098E }, { 0x2FB00, 0x004B }, { 0x2FE5E, 0x0011 }, { 0x30ECA, 0x0832 }, { 0x2FE6F, 0x000F },
+ { 0x2FE7E, 0x002F }, { 0x2FEAD, 0x001D }, { 0x2FECA, 0x0018 }, { 0x2FEE2, 0x0016 }, { 0x2FEF8, 0x001B },
+ { 0x3265B, 0x0088 }, { 0x2FF13, 0x0065 }, { 0x326E3, 0x0065 }, { 0x32748, 0x0073 }, { 0x327BB, 0x00F9 },
+ { 0x328B4, 0x049E }, { 0x32D52, 0x0EA8 }, { 0x34001, 0x0B18 }, { 0x34B19, 0x0B9C }, { 0x356B5, 0x0C6B },
+ { 0x36320, 0x0E56 }, { 0x37176, 0x0C70 }, { 0x38001, 0x0DEC }, { 0x38DED, 0x0B77 }, { 0x39964, 0x042F },
+ { 0x39D93, 0x0AC5 }, { 0x3A858, 0x0BE4 }
+};
const ScummNESFile::ResourceGroup res_sounds = {
ScummNESFile::NES_SOUND,
@@ -601,6 +686,7 @@ const ScummNESFile::ResourceGroup res_sounds = {
res_sounds_fra,
res_sounds_ger,
res_sounds_esp,
+ res_sounds_ita,
}
};
@@ -646,6 +732,13 @@ static const ScummNESFile::Resource res_costumes_esp[25] = {
{ 0x0FEF1, 0x0055 }, { 0x13F28, 0x003B }, { 0x0FEF1, 0x0055 }, { 0x17F2A, 0x0045 }, { 0x1FE71, 0x0040 },
{ 0x1FEB1, 0x003C }, { 0x13EEE, 0x003A }, { 0x13EEE, 0x003A }, { 0x0FEF1, 0x0055 }, { 0x13EA3, 0x004B }
};
+static const ScummNESFile::Resource res_costumes_ita[25] = {
+ { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 },
+ { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x13ED2, 0x004B }, { 0x0FEEB, 0x0055 },
+ { 0x0FEEB, 0x0055 }, { 0x0FEEB, 0x0055 }, { 0x0FF40, 0x0036 }, { 0x13F1D, 0x003A }, { 0x13F1D, 0x003A },
+ { 0x0FEEB, 0x0055 }, { 0x17F29, 0x003B }, { 0x0FEEB, 0x0055 }, { 0x1BE76, 0x0045 }, { 0x1BEBB, 0x0040 },
+ { 0x1BEFB, 0x003C }, { 0x13F1D, 0x003A }, { 0x13F1D, 0x003A }, { 0x0FEEB, 0x0055 }, { 0x13ED2, 0x004B }
+};
const ScummNESFile::ResourceGroup res_costumes = {
ScummNESFile::NES_COSTUME,
@@ -656,6 +749,7 @@ const ScummNESFile::ResourceGroup res_costumes = {
res_costumes_fra,
res_costumes_ger,
res_costumes_esp,
+ res_costumes_ita,
}
};
@@ -665,6 +759,7 @@ static const ScummNESFile::Resource res_globdata_swe[1] = { { 0x2C001, 0x0307 }
static const ScummNESFile::Resource res_globdata_fra[1] = { { 0x2C628, 0x0307 } };
static const ScummNESFile::Resource res_globdata_ger[1] = { { 0x2C4EE, 0x0307 } };
static const ScummNESFile::Resource res_globdata_esp[1] = { { 0x2C001, 0x0307 } };
+static const ScummNESFile::Resource res_globdata_ita[1] = { { 0x2C4C0, 0x0307 } };
const ScummNESFile::ResourceGroup res_globdata = {
ScummNESFile::NES_GLOBDATA,
@@ -675,6 +770,7 @@ const ScummNESFile::ResourceGroup res_globdata = {
res_globdata_fra,
res_globdata_ger,
res_globdata_esp,
+ res_globdata_ita,
}
};
@@ -685,6 +781,7 @@ static const ScummNESFile::Resource res_sprpals_swe[2] = { { 0x07F55, 0x0010 },
static const ScummNESFile::Resource res_sprpals_fra[2] = { { 0x07ED8, 0x0010 }, { 0x07EE8, 0x0010 } };
static const ScummNESFile::Resource res_sprpals_ger[2] = { { 0x07F6B, 0x0010 }, { 0x0BF17, 0x0010 } };
static const ScummNESFile::Resource res_sprpals_esp[2] = { { 0x0BF15, 0x0010 }, { 0x0BF25, 0x0010 } };
+static const ScummNESFile::Resource res_sprpals_ita[2] = { { 0x07F54, 0x0010 }, { 0x07F64, 0x0010 } };
const ScummNESFile::ResourceGroup res_sprpals = {
ScummNESFile::NES_SPRPALS,
@@ -695,6 +792,7 @@ const ScummNESFile::ResourceGroup res_sprpals = {
res_sprpals_fra,
res_sprpals_ger,
res_sprpals_esp,
+ res_sprpals_ita,
}
};
@@ -705,6 +803,7 @@ static const ScummNESFile::Resource res_sprdesc_swe[2] = { { 0x0BF1B, 0x0031 },
static const ScummNESFile::Resource res_sprdesc_fra[2] = { { 0x07EF8, 0x0031 }, { 0x07F29, 0x0009 } };
static const ScummNESFile::Resource res_sprdesc_ger[2] = { { 0x0BF27, 0x0031 }, { 0x0BF58, 0x0009 } };
static const ScummNESFile::Resource res_sprdesc_esp[2] = { { 0x0BF35, 0x0031 }, { 0x0BF66, 0x0009 } };
+static const ScummNESFile::Resource res_sprdesc_ita[2] = { { 0x0BF17, 0x0031 }, { 0x07F74, 0x0009 } };
const ScummNESFile::ResourceGroup res_sprdesc = {
ScummNESFile::NES_SPRDESC,
@@ -715,6 +814,7 @@ const ScummNESFile::ResourceGroup res_sprdesc = {
res_sprdesc_fra,
res_sprdesc_ger,
res_sprdesc_esp,
+ res_sprdesc_ita,
}
};
@@ -725,6 +825,7 @@ static const ScummNESFile::Resource res_sprlens_swe[2] = { { 0x13E6A, 0x0115 },
static const ScummNESFile::Resource res_sprlens_fra[2] = { { 0x0FE61, 0x0115 }, { 0x07ED2, 0x0006 } };
static const ScummNESFile::Resource res_sprlens_ger[2] = { { 0x2BE1A, 0x0115 }, { 0x07F65, 0x0006 } };
static const ScummNESFile::Resource res_sprlens_esp[2] = { { 0x2EFE1, 0x0115 }, { 0x07F7A, 0x0006 } };
+static const ScummNESFile::Resource res_sprlens_ita[2] = { { 0x23DE9, 0x0115 }, { 0x07F4E, 0x0006 } };
const ScummNESFile::ResourceGroup res_sprlens = {
ScummNESFile::NES_SPRLENS,
@@ -735,6 +836,7 @@ const ScummNESFile::ResourceGroup res_sprlens = {
res_sprlens_fra,
res_sprlens_ger,
res_sprlens_esp,
+ res_sprlens_ita,
}
};
@@ -745,6 +847,7 @@ static const ScummNESFile::Resource res_sproffs_swe[2] = { { 0x2BCE0, 0x022A },
static const ScummNESFile::Resource res_sproffs_fra[2] = { { 0x2F959, 0x022A }, { 0x07F32, 0x000C } };
static const ScummNESFile::Resource res_sproffs_ger[2] = { { 0x2F81F, 0x022A }, { 0x0BF61, 0x000C } };
static const ScummNESFile::Resource res_sproffs_esp[2] = { { 0x2F447, 0x022A }, { 0x0BF6F, 0x000C } };
+static const ScummNESFile::Resource res_sproffs_ita[2] = { { 0x2BC37, 0x022A }, { 0x0BF48, 0x000C } };
const ScummNESFile::ResourceGroup res_sproffs = {
ScummNESFile::NES_SPROFFS,
@@ -755,6 +858,7 @@ const ScummNESFile::ResourceGroup res_sproffs = {
res_sproffs_fra,
res_sproffs_ger,
res_sproffs_esp,
+ res_sproffs_ita,
}
};
@@ -765,6 +869,7 @@ static const ScummNESFile::Resource res_sprdata_swe[2] = { { 0x2C401, 0x2BE0 },
static const ScummNESFile::Resource res_sprdata_fra[2] = { { 0x2CA28, 0x2BE0 }, { 0x07E48, 0x008A } };
static const ScummNESFile::Resource res_sprdata_ger[2] = { { 0x2C8EE, 0x2BE0 }, { 0x0FE61, 0x008A } };
static const ScummNESFile::Resource res_sprdata_esp[2] = { { 0x2C401, 0x2BE0 }, { 0x0FE67, 0x008A } };
+static const ScummNESFile::Resource res_sprdata_ita[2] = { { 0x2C8C0, 0x2BE0 }, { 0x0FE61, 0x008A } };
const ScummNESFile::ResourceGroup res_sprdata = {
ScummNESFile::NES_SPRDATA,
@@ -775,6 +880,7 @@ const ScummNESFile::ResourceGroup res_sprdata = {
res_sprdata_fra,
res_sprdata_ger,
res_sprdata_esp,
+ res_sprdata_ita,
}
};
@@ -784,6 +890,7 @@ static const ScummNESFile::Resource res_charset_swe[1] = { { 0x3F739, 0x0090 } }
static const ScummNESFile::Resource res_charset_fra[1] = { { 0x3F739, 0x0090 } };
static const ScummNESFile::Resource res_charset_ger[1] = { { 0x3F739, 0x0090 } };
static const ScummNESFile::Resource res_charset_esp[1] = { { 0x3F739, 0x0090 } };
+static const ScummNESFile::Resource res_charset_ita[1] = { { 0x3F739, 0x0090 } };
const ScummNESFile::ResourceGroup res_charset = {
ScummNESFile::NES_CHARSET,
@@ -794,6 +901,7 @@ const ScummNESFile::ResourceGroup res_charset = {
res_charset_fra,
res_charset_ger,
res_charset_esp,
+ res_charset_ita,
}
};
@@ -803,6 +911,7 @@ static const ScummNESFile::Resource res_preplist_swe[1] = { { 0x3FBA9, 0x000E }
static const ScummNESFile::Resource res_preplist_fra[1] = { { 0x3FBAF, 0x0010 } };
static const ScummNESFile::Resource res_preplist_ger[1] = { { 0x3FBAB, 0x000F } };
static const ScummNESFile::Resource res_preplist_esp[1] = { { 0x3FBAE, 0x000F } };
+static const ScummNESFile::Resource res_preplist_ita[1] = { { 0x3FBAA, 0x0010 } };
const ScummNESFile::ResourceGroup res_preplist = {
ScummNESFile::NES_PREPLIST,
@@ -813,6 +922,7 @@ const ScummNESFile::ResourceGroup res_preplist = {
res_preplist_fra,
res_preplist_ger,
res_preplist_esp,
+ res_preplist_ita,
}
};
@@ -1281,6 +1391,9 @@ bool ScummNESFile::open(const Common::String &filename) {
} else if (!strcmp(md5str, "f163cf53f7850e43fb482471e5c52e1a")) {
_ROMset = kROMsetSpain;
debug(2, "ROM contents verified as Maniac Mansion (Spain)");
+ } else if (!strcmp(md5str, "54a68a5f5e3c86da42b7ca5f51e79b1d")) {
+ _ROMset = kROMsetItaly;
+ debug(2, "ROM contents verified as Maniac Mansion (Italy)");
} else {
error("Unsupported Maniac Mansion ROM, md5: %s", md5str);
return false;
diff --git a/engines/scumm/file_nes.h b/engines/scumm/file_nes.h
index b255705922..274ec02ed0 100644
--- a/engines/scumm/file_nes.h
+++ b/engines/scumm/file_nes.h
@@ -41,6 +41,7 @@ public:
kROMsetFrance,
kROMsetGermany,
kROMsetSpain,
+ kROMsetItaly,
kROMsetNum
};
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index cb7f906f13..9a1d6485e2 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Thu Jul 30 10:23:41 2009
+ This file was generated by the md5table tool on Mon Aug 10 19:27:14 2009
DO NOT EDIT MANUALLY!
*/
@@ -46,6 +46,7 @@ static const MD5Table md5table[] = {
{ "0b3222aaa7efcf283eb621e0cefd26cc", "puttputt", "HE 60", "", -1, Common::RU_RUS, Common::kPlatformPC },
{ "0be88565f734b1e9e77ccaaf3bb14b29", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC },
{ "0bf1a3eb198ca1bd2ebe104825cec770", "puttrace", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
+ { "0c331637580950aea2346e012ef2a868", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformAtariST },
{ "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "0cccfa5223099a60e76cfcca57a1a141", "freddi3", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformPC },
@@ -425,7 +426,7 @@ static const MD5Table md5table[] = {
{ "a525c1753c1db5011c00417da37887ef", "PuttTime", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a56e8d9d4281c53c3f63c9bd22a59e21", "catalog", "HE CUP", "Preview", 10978342, Common::EN_ANY, Common::kPlatformUnknown },
- { "a570381b028972d891052ee1e51dc011", "maniac", "V2", "V2", -1, Common::EN_ANY, Common::kPlatformAtariST },
+ { "a570381b028972d891052ee1e51dc011", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformAtariST },
{ "a5c5388da9bf0e6662fdca8813a79d13", "farm", "", "", 86962, Common::EN_ANY, Common::kPlatformWindows },
{ "a654fb60c3b67d6317a7894ffd9f25c5", "pajama3", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a7cacad9c40c4dc9e1812abf6c8af9d5", "puttcircus", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -563,6 +564,7 @@ static const MD5Table md5table[] = {
{ "e144f5f49d9241d2a9dee2576b3d09cb", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "e17db1ddf91b39ca6bbc8ad3ed19e883", "monkey", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
{ "e246e02db9630533a40d99c9f54a8e01", "monkey2", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "e28bc6dbec750bced1b7c98d6caa32ce", "maniac", "NES", "", 262144, Common::IT_ITA, Common::kPlatformNES },
{ "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC },
{ "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "e44ea295a3f8fe4f41983080dab1e9ce", "freddi", "HE 90", "Updated", -1, Common::FR_FRA, Common::kPlatformMacintosh },
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index 2362427779..528cceb0cc 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -391,8 +391,8 @@ void Sound::playSound(int soundID) {
000070: 01 18 5a 00 10 00 02 28 5f 00 01 00 00 00 00 00 |..Z....(_.......|
*/
}
- else if ((_vm->_game.platform == Common::kPlatformMacintosh) && (_vm->_game.id == GID_INDY3) && (ptr[26] == 0)) {
- // Sound fomat as used in Indy3 EGA Mac.
+ else if ((_vm->_game.platform == Common::kPlatformMacintosh) && (_vm->_game.id == GID_INDY3) && READ_BE_UINT16(ptr + 8) == 0x1C) {
+ // Sound format as used in Indy3 EGA Mac.
// It seems to be closely related to the Amiga format, see player_v3a.cpp
// The following is known:
// offset 0, 16 LE: total size
@@ -411,8 +411,8 @@ void Sound::playSound(int soundID) {
flags = Audio::Mixer::FLAG_AUTOFREE;
size = READ_BE_UINT16(ptr + 12);
- if (size == 0) // WORKAROUND bug #1852635: Sound 54 has size 0.
- return;
+ assert(size);
+
rate = 3579545 / READ_BE_UINT16(ptr + 20);
sound = (char *)malloc(size);
int vol = ptr[24] * 4;
diff --git a/engines/tinsel/background.cpp b/engines/tinsel/background.cpp
index 94525e33dd..583b9817a9 100644
--- a/engines/tinsel/background.cpp
+++ b/engines/tinsel/background.cpp
@@ -249,6 +249,8 @@ void DrawBackgnd(void) {
UpdateScreenRect(*r);
}
+ g_system->updateScreen();
+
// delete all the clipping rectangles
ResetClipRect();
}
diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp
index 1df932f1af..1e9693542e 100644
--- a/engines/tinsel/bmv.cpp
+++ b/engines/tinsel/bmv.cpp
@@ -1118,6 +1118,7 @@ void CopyMovieToScreen(void) {
BmvDrawText(true);
PalettesToVideoDAC(); // Keep palette up-to-date
UpdateScreenRect(Common::Rect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT));
+ g_system->updateScreen();
BmvDrawText(false);
}
diff --git a/engines/tinsel/dw.h b/engines/tinsel/dw.h
index 826c0e38ba..943d728354 100644
--- a/engines/tinsel/dw.h
+++ b/engines/tinsel/dw.h
@@ -100,7 +100,7 @@ typedef int HPOLYGON;
#define NO_ENTRY_NUM (-3458) // Magic unlikely number
-#define SAMPLETIMEOUT (15*ONE_SECOND)
+#define SAMPLETIMEOUT (20*ONE_SECOND)
// Language for the resource strings
enum LANGUAGE {
diff --git a/engines/tinsel/graphics.cpp b/engines/tinsel/graphics.cpp
index cb334d96b0..0b3f2e6e24 100644
--- a/engines/tinsel/graphics.cpp
+++ b/engines/tinsel/graphics.cpp
@@ -713,7 +713,6 @@ void UpdateScreenRect(const Common::Rect &pClip) {
byte *pSrc = (byte *)_vm->screen().getBasePtr(pClip.left, pClip.top);
g_system->copyRectToScreen(pSrc, _vm->screen().pitch, pClip.left, pClip.top + yOffset,
pClip.width(), pClip.height());
- g_system->updateScreen();
}
/**
diff --git a/engines/tinsel/music.cpp b/engines/tinsel/music.cpp
index 12d9f0393a..6ce1ea7288 100644
--- a/engines/tinsel/music.cpp
+++ b/engines/tinsel/music.cpp
@@ -189,7 +189,7 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
}
// the index and length of the last tune loaded
- static uint32 dwLastMidiIndex;
+ static uint32 dwLastMidiIndex = 0;
//static uint32 dwLastSeqLen;
uint32 dwSeqLen = 0; // length of the sequence
@@ -256,6 +256,23 @@ bool PlayMidiSequence(uint32 dwFileOffset, bool bLoop) {
midiStream.close();
+ // WORKAROUND for bug #2820054 "DW1: No intro music at first start on Wii",
+ // which actually affects all ports, since it's specific to the GRA version.
+ //
+ // The GRA version does not seem to set the channel volume at all for the first
+ // intro track, thus we need to do that here. We only initialize the channels
+ // used in that sequence. And we are using 127 as default channel volume.
+ //
+ // Only in the GRA version dwFileOffset can be "38888", just to be sure, we
+ // check for the SCN files feature flag not being set though.
+ if (_vm->getGameID() == GID_DW1 && dwFileOffset == 38888 && !(_vm->getFeatures() & GF_SCNFILES)) {
+ _vm->_midiMusic->send(0x7F07B0 | 3);
+ _vm->_midiMusic->send(0x7F07B0 | 5);
+ _vm->_midiMusic->send(0x7F07B0 | 8);
+ _vm->_midiMusic->send(0x7F07B0 | 10);
+ _vm->_midiMusic->send(0x7F07B0 | 13);
+ }
+
_vm->_midiMusic->playXMIDI(midiBuffer.pDat, dwSeqLen, bLoop);
// Store the length
@@ -303,6 +320,8 @@ int GetMidiVolume() {
return volMusic;
}
+static int priorVolMusic = 0;
+
/**
* Sets the volume of the MIDI music.
* @param vol New volume - 0..MAXMIDIVOL
@@ -310,23 +329,24 @@ int GetMidiVolume() {
void SetMidiVolume(int vol) {
assert(vol >= 0 && vol <= Audio::Mixer::kMaxChannelVolume);
- if (vol == 0 && volMusic == 0) {
+ if (vol == 0 && priorVolMusic == 0) {
// Nothing to do
- } else if (vol == 0 && volMusic != 0) {
+ } else if (vol == 0 && priorVolMusic != 0) {
// Stop current midi sequence
StopMidi();
- } else if (vol != 0 && volMusic == 0) {
+ _vm->_midiMusic->setVolume(vol);
+ } else if (vol != 0 && priorVolMusic == 0) {
// Perhaps restart last midi sequence
- if (currentLoop) {
+ if (currentLoop)
PlayMidiSequence(currentMidi, true);
- _vm->_midiMusic->setVolume(vol);
- }
- } else if (vol != 0 && volMusic != 0) {
+
+ _vm->_midiMusic->setVolume(vol);
+ } else if (vol != 0 && priorVolMusic != 0) {
// Alter current volume
_vm->_midiMusic->setVolume(vol);
}
- volMusic = vol;
+ priorVolMusic = vol;
}
/**
@@ -374,6 +394,7 @@ void DeleteMidiBuffer() {
MidiMusicPlayer::MidiMusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false) {
memset(_channel, 0, sizeof(_channel));
+ memset(_channelVolume, 0, sizeof(_channelVolume));
_masterVolume = 0;
this->open();
_xmidiParser = MidiParser::createParser_XMIDI();
diff --git a/engines/tinsel/palette.cpp b/engines/tinsel/palette.cpp
index 8df9e9a375..84e88fe06b 100644
--- a/engines/tinsel/palette.cpp
+++ b/engines/tinsel/palette.cpp
@@ -133,7 +133,6 @@ void psxPaletteMapper(PALQ *originalPal, uint8 *psxClut, byte *mapperTable) {
void PalettesToVideoDAC(void) {
PALQ *pPalQ; // palette Q iterator
VIDEO_DAC_Q *pDACtail = vidDACdata; // set tail pointer
- bool needUpdate = false;
// while Q is not empty
while (pDAChead != pDACtail) {
@@ -162,9 +161,6 @@ void PalettesToVideoDAC(void) {
pColours = pDACtail->pal.pRGBarray;
}
- if (pDACtail->numColours > 0)
- needUpdate = true;
-
// update the system palette
g_system->setPalette((byte *)pColours, pDACtail->destDACindex, pDACtail->numColours);
@@ -179,9 +175,6 @@ void PalettesToVideoDAC(void) {
// clear all palette moved bits
for (pPalQ = palAllocData; pPalQ < palAllocData + NUM_PALETTES; pPalQ++)
pPalQ->posInDAC &= ~PALETTE_MOVED;
-
- if (needUpdate)
- g_system->updateScreen();
}
/**
diff --git a/engines/tinsel/pcode.cpp b/engines/tinsel/pcode.cpp
index 1d73411e13..e6ed9df5c9 100644
--- a/engines/tinsel/pcode.cpp
+++ b/engines/tinsel/pcode.cpp
@@ -120,6 +120,12 @@ const byte fragment2[] = {OP_LIBCALL | OPSIZE8, 110};
const int fragment2_size = 2;
const byte fragment3[] = {OP_ZERO, OP_GSTORE | OPSIZE16, 490 % 256, 490 / 256};
const int fragment3_size = 4;
+const byte fragment4[] = {OP_IMM | OPSIZE16, 900 % 256, 900 / 256, OP_JUMP, 466 % 256, 466 / 256};
+const int fragment4_size = 6;
+const byte fragment5[] = {OP_IMM | OPSIZE16, 901 % 256, 901 / 256, OP_JUMP, 488 % 256, 488 / 256};
+const int fragment5_size = 6;
+const byte fragment6[] = {OP_IMM | OPSIZE16, 903 % 256, 903 / 256, OP_JUMP, 516 % 256, 516 / 256};
+const int fragment6_size = 6;
const WorkaroundEntry workaroundList[] = {
// DW1-SCN: Global 206 is whether Rincewind is trying to take the book back to the present.
@@ -135,6 +141,12 @@ const WorkaroundEntry workaroundList[] = {
// Present Outside Inn
{TINSEL_V1, false, 352600876, 0, fragment2_size, fragment2},
+ // DW1-GRA: Talking to palace guards in Act 2 gives !!!HIGH STRING||| - this happens if you initiate dialog
+ // with one of the guards, but not the other. So this fix routes the talk parameters of the broken one
+ {TINSEL_V1, false, 310506872, 463, fragment4_size, fragment4},
+ {TINSEL_V1, false, 310506872, 485, fragment5_size, fragment5},
+ {TINSEL_V1, false, 310506872, 513, fragment6_size, fragment6},
+
// DW2: In the garden, global #490 is set when the bees begin their 'out of hive' animation, and reset when done.
// But if the game is saved/restored during it, the animation sequence is reset without the global being cleared.
// This causes bugs in several actions which try to disable the bees animation, since they wait indefinitely for
@@ -636,6 +648,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
case OP_JUMP: // unconditional jump
ip = Fetch(opcode, ic->code, wkEntry, ip);
+ wkEntry = NULL; // In case a jump occurs from a workaround
break;
case OP_JMPFALSE: // conditional jump
@@ -644,6 +657,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
if (ic->stack[ic->sp--] == 0) {
// condition satisfied - do the jump
ip = tmp;
+ wkEntry = NULL; // In case a jump occurs from a workaround
}
break;
@@ -653,6 +667,7 @@ void Interpret(CORO_PARAM, INT_CONTEXT *ic) {
if (ic->stack[ic->sp--] != 0) {
// condition satisfied - do the jump
ip = tmp;
+ wkEntry = NULL; // In case a jump occurs from a workaround
}
break;
diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp
index 4b5e0ce450..957c4f7626 100644
--- a/engines/tinsel/tinlib.cpp
+++ b/engines/tinsel/tinlib.cpp
@@ -2196,6 +2196,10 @@ static void PrintObj(CORO_PARAM, const SCNHANDLE hText, const INV_OBJECT *pinvo,
_ctx->bSample = false;
}
}
+
+ // Decrement the subtitles timeout counter
+ if (_ctx->ticks > 0) --_ctx->ticks;
+
} else {
// No sample - just depends on time
if (_ctx->ticks-- <= 0)
@@ -2327,6 +2331,10 @@ static void PrintObjNonPointed(CORO_PARAM, const SCNHANDLE text, const OBJECT *p
_ctx->bSample = false;
}
}
+
+ // Decrement the subtitles timeout counter
+ if (_ctx->ticks > 0) --_ctx->ticks;
+
} else {
// No sample - just depends on time
if (_ctx->ticks-- <= 0)
@@ -3437,6 +3445,10 @@ static void TalkOrSay(CORO_PARAM, SPEECH_TYPE speechType, SCNHANDLE hText, int x
_ctx->bSample = false;
}
}
+
+ // Decrement the subtitles timeout counter
+ if (_ctx->ticks > 0) --_ctx->ticks;
+
} else {
// No sample - just depends on time
if (_ctx->ticks-- <= 0)