aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile7
-rw-r--r--backends/midi/timidity.cpp2
-rw-r--r--backends/platform/dc/dc.h6
-rw-r--r--backends/platform/dc/display.cpp26
-rw-r--r--backends/platform/dc/input.cpp2
-rw-r--r--dists/msvc7/gob.vcproj89
-rw-r--r--dists/msvc71/gob.vcproj89
-rw-r--r--dists/msvc8/gob.vcproj72
-rw-r--r--dists/msvc9/gob.vcproj104
-rw-r--r--engines/cruise/ctp.cpp4
-rw-r--r--engines/cruise/font.cpp2
-rw-r--r--engines/cruise/function.cpp2
-rw-r--r--engines/gob/demos/demoplayer.cpp2
-rw-r--r--engines/gob/draw.cpp14
-rw-r--r--engines/gob/draw_v1.cpp35
-rw-r--r--engines/gob/draw_v2.cpp46
-rw-r--r--engines/gob/game.cpp314
-rw-r--r--engines/gob/game.h211
-rw-r--r--engines/gob/game_fascin.cpp203
-rw-r--r--engines/gob/game_v1.cpp1426
-rw-r--r--engines/gob/game_v2.cpp1563
-rw-r--r--engines/gob/game_v6.cpp1114
-rw-r--r--engines/gob/global.cpp2
-rw-r--r--engines/gob/global.h2
-rw-r--r--engines/gob/gob.cpp14
-rw-r--r--engines/gob/gob.h2
-rw-r--r--engines/gob/hotspots.cpp1928
-rw-r--r--engines/gob/hotspots.h241
-rw-r--r--engines/gob/init.h10
-rw-r--r--engines/gob/init_v6.cpp48
-rw-r--r--engines/gob/inter.cpp33
-rw-r--r--engines/gob/inter.h8
-rw-r--r--engines/gob/inter_bargon.cpp12
-rw-r--r--engines/gob/inter_v1.cpp20
-rw-r--r--engines/gob/inter_v2.cpp71
-rw-r--r--engines/gob/inter_v6.cpp31
-rw-r--r--engines/gob/module.mk8
-rw-r--r--engines/gob/mult.cpp2
-rw-r--r--engines/gob/script.cpp4
-rw-r--r--engines/gob/script.h1
-rw-r--r--engines/gob/sound/sound.cpp2
-rw-r--r--engines/gob/util.cpp91
-rw-r--r--engines/gob/util.h48
-rw-r--r--engines/gob/video.h2
-rw-r--r--engines/gob/videoplayer.cpp1
-rw-r--r--engines/gob/videoplayer.h8
-rw-r--r--engines/groovie/groovie.cpp6
-rw-r--r--engines/groovie/music.cpp428
-rw-r--r--engines/groovie/music.h114
-rw-r--r--engines/kyra/detection.cpp22
-rw-r--r--engines/kyra/lol.cpp2
-rw-r--r--engines/kyra/screen.cpp17
-rw-r--r--engines/kyra/screen.h10
-rw-r--r--engines/kyra/screen_lol.cpp152
-rw-r--r--engines/kyra/screen_lol.h16
-rw-r--r--engines/sci/console.cpp31
-rw-r--r--engines/sci/console.h1
-rw-r--r--engines/sci/detection.cpp126
-rw-r--r--engines/sci/engine/game.cpp2
-rw-r--r--engines/sci/engine/kernel.cpp128
-rw-r--r--engines/sci/engine/kernel.h38
-rw-r--r--engines/sci/engine/kgraphics.cpp13
-rw-r--r--engines/sci/engine/ksound.cpp4
-rw-r--r--engines/sci/engine/script.cpp7
-rw-r--r--engines/sci/engine/vm.cpp4
-rw-r--r--engines/sci/engine/vm.h4
-rw-r--r--engines/sci/gfx/gfx_driver.cpp9
-rw-r--r--engines/sci/gfx/gfx_resmgr.cpp2
-rw-r--r--engines/sci/resource.cpp21
-rw-r--r--engines/sci/resource.h2
-rw-r--r--engines/sci/sci.cpp17
-rw-r--r--engines/sci/sci.h65
-rw-r--r--engines/sci/sfx/iterator.cpp18
-rw-r--r--engines/scumm/he/resource_he.cpp2
-rw-r--r--engines/scumm/script.cpp2
-rw-r--r--gui/GuiManager.cpp35
-rw-r--r--gui/GuiManager.h4
77 files changed, 3549 insertions, 5675 deletions
diff --git a/Makefile b/Makefile
index 12718494c7..5771e692dc 100644
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,12 @@ CXXFLAGS+= -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder
# Enable even more warnings...
CXXFLAGS+= -Wpointer-arith -Wcast-qual -Wcast-align
CXXFLAGS+= -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings
-CXXFLAGS+= -Wmissing-format-attribute
+
+# Currently we disable this gcc flag, since it will also warn in cases,
+# where using GCC_PRINTF (means: __attribute__((format(printf, x, y))))
+# is not possible, thus it would fail compiliation with -Werror without
+# being helpful.
+#CXXFLAGS+= -Wmissing-format-attribute
# Disable RTTI and exceptions, and enabled checking of pointers returned by "new"
CXXFLAGS+= -fno-rtti -fno-exceptions -fcheck-new
diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp
index c813441724..d533dab770 100644
--- a/backends/midi/timidity.cpp
+++ b/backends/midi/timidity.cpp
@@ -99,7 +99,7 @@ private:
int connect_to_server(const char* hostname, unsigned short tcp_port);
/* send command to the server; printf-like; returns reply string */
- char *timidity_ctl_command(const char *fmt, ...);
+ char *timidity_ctl_command(const char *fmt, ...) GCC_PRINTF(2, 3);
/* timidity data socket-related stuff */
void timidity_meta_seq(int p1, int p2, int p3);
diff --git a/backends/platform/dc/dc.h b/backends/platform/dc/dc.h
index f86a2c6065..b67bbb51a1 100644
--- a/backends/platform/dc/dc.h
+++ b/backends/platform/dc/dc.h
@@ -194,7 +194,7 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys
SoftKeyboard _softkbd;
int _ms_cur_x, _ms_cur_y, _ms_cur_w, _ms_cur_h, _ms_old_x, _ms_old_y;
- int _ms_hotspot_x, _ms_hotspot_y, _ms_visible, _devpoll;
+ int _ms_hotspot_x, _ms_hotspot_y, _ms_visible, _devpoll, _last_screen_refresh;
int _current_shake_pos, _screen_w, _screen_h;
int _overlay_x, _overlay_y;
unsigned char *_ms_buf;
@@ -220,11 +220,15 @@ class OSystem_Dreamcast : private DCHardware, public BaseBackend, public Filesys
uint initSound();
void checkSound();
+ void updateScreenTextures(void);
+ void updateScreenPolygons(void);
+ void maybeRefreshScreen(void);
void drawMouse(int xdraw, int ydraw, int w, int h,
unsigned char *buf, bool visible);
void setScaling();
+
Common::SaveFileManager *createSavefileManager();
};
diff --git a/backends/platform/dc/display.cpp b/backends/platform/dc/display.cpp
index ba8e1ba04f..d1e95c6a91 100644
--- a/backends/platform/dc/display.cpp
+++ b/backends/platform/dc/display.cpp
@@ -285,11 +285,8 @@ void OSystem_Dreamcast::setShakePos(int shake_pos)
_current_shake_pos = shake_pos;
}
-void OSystem_Dreamcast::updateScreen(void)
+void OSystem_Dreamcast::updateScreenTextures(void)
{
- struct polygon_list mypoly;
- struct packed_colour_vertex_list myvertex;
-
if (_screen_dirty) {
_screen_buffer++;
@@ -328,6 +325,12 @@ void OSystem_Dreamcast::updateScreen(void)
_overlay_dirty = false;
}
+}
+
+void OSystem_Dreamcast::updateScreenPolygons(void)
+{
+ struct polygon_list mypoly;
+ struct packed_colour_vertex_list myvertex;
// *((volatile unsigned int *)(void*)0xa05f8040) = 0x00ff00;
@@ -448,6 +451,21 @@ void OSystem_Dreamcast::updateScreen(void)
ta_commit_frame();
// *((volatile unsigned int *)(void*)0xa05f8040) = 0x0;
+
+ _last_screen_refresh = Timer();
+}
+
+void OSystem_Dreamcast::updateScreen(void)
+{
+ updateScreenTextures();
+ updateScreenPolygons();
+}
+
+void OSystem_Dreamcast::maybeRefreshScreen(void)
+{
+ unsigned int t = Timer();
+ if((int)(t-_last_screen_refresh) > USEC_TO_TIMER(30000))
+ updateScreenPolygons();
}
void OSystem_Dreamcast::drawMouse(int xdraw, int ydraw, int w, int h,
diff --git a/backends/platform/dc/input.cpp b/backends/platform/dc/input.cpp
index 1b85f601a6..5d4ed7ce96 100644
--- a/backends/platform/dc/input.cpp
+++ b/backends/platform/dc/input.cpp
@@ -202,6 +202,8 @@ bool OSystem_Dreamcast::pollEvent(Common::Event &event)
if (((int)(t-_devpoll))>=0)
_devpoll = t + USEC_TO_TIMER(17000);
+ maybeRefreshScreen();
+
int mask = getimask();
setimask(15);
checkSound();
diff --git a/dists/msvc7/gob.vcproj b/dists/msvc7/gob.vcproj
index 1f74676279..fd1cbb9dfe 100644
--- a/dists/msvc7/gob.vcproj
+++ b/dists/msvc7/gob.vcproj
@@ -173,24 +173,6 @@
RelativePath="..\..\engines\gob\demos\batplayer.h">
</File>
<File
- RelativePath="..\..\engines\gob\resources.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\resources.h">
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.h">
- </File>
- <File
- RelativePath="..\..\engines\gob\script.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\script.h">
- </File>
- <File
RelativePath="..\..\engines\gob\dataio.cpp">
</File>
<File
@@ -230,22 +212,16 @@
RelativePath="..\..\engines\gob\driver_vga.h">
</File>
<File
- RelativePath="..\..\engines\gob\game.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\game.h">
- </File>
- <File
- RelativePath="..\..\engines\gob\game_fascin.cpp">
+ RelativePath="..\..\engines\gob\expression.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\game_v1.cpp">
+ RelativePath="..\..\engines\gob\expression.h">
</File>
<File
- RelativePath="..\..\engines\gob\game_v2.cpp">
+ RelativePath="..\..\engines\gob\game.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\game_v6.cpp">
+ RelativePath="..\..\engines\gob\game.h">
</File>
<File
RelativePath="..\..\engines\gob\global.cpp">
@@ -281,6 +257,12 @@
RelativePath="..\..\engines\gob\helper.h">
</File>
<File
+ RelativePath="..\..\engines\gob\hotspots.cpp">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\hotspots.h">
+ </File>
+ <File
RelativePath="..\..\engines\gob\init.cpp">
</File>
<File
@@ -296,6 +278,9 @@
RelativePath="..\..\engines\gob\init_v3.cpp">
</File>
<File
+ RelativePath="..\..\engines\gob\init_v6.cpp">
+ </File>
+ <File
RelativePath="..\..\engines\gob\inter.cpp">
</File>
<File
@@ -359,58 +344,58 @@
RelativePath="..\..\engines\gob\palanim.h">
</File>
<File
- RelativePath="..\..\engines\gob\expression.cpp">
+ RelativePath="..\..\engines\gob\resources.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\expression.h">
+ RelativePath="..\..\engines\gob\resources.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\savefile.h">
+ RelativePath="..\..\engines\gob\save\saveconverter.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\savefile.cpp">
+ RelativePath="..\..\engines\gob\save\saveconverter.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\savehandler.h">
+ RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\savehandler.cpp">
+ RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload.h">
+ RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload.cpp">
+ RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v2.cpp">
+ RelativePath="..\..\engines\gob\save\savefile.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v3.cpp">
+ RelativePath="..\..\engines\gob\save\savefile.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v4.cpp">
+ RelativePath="..\..\engines\gob\save\savehandler.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v6.cpp">
+ RelativePath="..\..\engines\gob\save\savehandler.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter.h">
+ RelativePath="..\..\engines\gob\save\saveload.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter.cpp">
+ RelativePath="..\..\engines\gob\save\saveload.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v2.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v3.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v4.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v6.cpp">
</File>
<File
RelativePath="..\..\engines\gob\scenery.cpp">
@@ -431,6 +416,18 @@
RelativePath="..\..\engines\gob\demos\scnplayer.h">
</File>
<File
+ RelativePath="..\..\engines\gob\script.cpp">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\script.h">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.cpp">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.h">
+ </File>
+ <File
RelativePath="..\..\engines\gob\util.cpp">
</File>
<File
diff --git a/dists/msvc71/gob.vcproj b/dists/msvc71/gob.vcproj
index bbeef85109..b005dbbd6e 100644
--- a/dists/msvc71/gob.vcproj
+++ b/dists/msvc71/gob.vcproj
@@ -187,24 +187,6 @@
RelativePath="..\..\engines\gob\demos\batplayer.h">
</File>
<File
- RelativePath="..\..\engines\gob\resources.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\resources.h">
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.h">
- </File>
- <File
- RelativePath="..\..\engines\gob\script.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\script.h">
- </File>
- <File
RelativePath="..\..\engines\gob\dataio.cpp">
</File>
<File
@@ -244,22 +226,16 @@
RelativePath="..\..\engines\gob\driver_vga.h">
</File>
<File
- RelativePath="..\..\engines\gob\game.cpp">
- </File>
- <File
- RelativePath="..\..\engines\gob\game.h">
- </File>
- <File
- RelativePath="..\..\engines\gob\game_fascin.cpp">
+ RelativePath="..\..\engines\gob\expression.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\game_v1.cpp">
+ RelativePath="..\..\engines\gob\expression.h">
</File>
<File
- RelativePath="..\..\engines\gob\game_v2.cpp">
+ RelativePath="..\..\engines\gob\game.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\game_v6.cpp">
+ RelativePath="..\..\engines\gob\game.h">
</File>
<File
RelativePath="..\..\engines\gob\global.cpp">
@@ -295,6 +271,12 @@
RelativePath="..\..\engines\gob\helper.h">
</File>
<File
+ RelativePath="..\..\engines\gob\hotspots.cpp">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\hotspots.h">
+ </File>
+ <File
RelativePath="..\..\engines\gob\init.cpp">
</File>
<File
@@ -310,6 +292,9 @@
RelativePath="..\..\engines\gob\init_v3.cpp">
</File>
<File
+ RelativePath="..\..\engines\gob\init_v6.cpp">
+ </File>
+ <File
RelativePath="..\..\engines\gob\inter.cpp">
</File>
<File
@@ -373,58 +358,58 @@
RelativePath="..\..\engines\gob\palanim.h">
</File>
<File
- RelativePath="..\..\engines\gob\expression.cpp">
+ RelativePath="..\..\engines\gob\resources.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\expression.h">
+ RelativePath="..\..\engines\gob\resources.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\savefile.h">
+ RelativePath="..\..\engines\gob\save\saveconverter.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\savefile.cpp">
+ RelativePath="..\..\engines\gob\save\saveconverter.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\savehandler.h">
+ RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\savehandler.cpp">
+ RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload.h">
+ RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload.cpp">
+ RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v2.cpp">
+ RelativePath="..\..\engines\gob\save\savefile.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v3.cpp">
+ RelativePath="..\..\engines\gob\save\savefile.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v4.cpp">
+ RelativePath="..\..\engines\gob\save\savehandler.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v6.cpp">
+ RelativePath="..\..\engines\gob\save\savehandler.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter.h">
+ RelativePath="..\..\engines\gob\save\saveload.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter.cpp">
+ RelativePath="..\..\engines\gob\save\saveload.h">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v2.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v3.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v4.cpp">
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp">
+ RelativePath="..\..\engines\gob\save\saveload_v6.cpp">
</File>
<File
RelativePath="..\..\engines\gob\scenery.cpp">
@@ -445,6 +430,18 @@
RelativePath="..\..\engines\gob\demos\scnplayer.h">
</File>
<File
+ RelativePath="..\..\engines\gob\script.cpp">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\script.h">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.cpp">
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.h">
+ </File>
+ <File
RelativePath="..\..\engines\gob\util.cpp">
</File>
<File
diff --git a/dists/msvc8/gob.vcproj b/dists/msvc8/gob.vcproj
index 13bdeb9384..14259ac2fd 100644
--- a/dists/msvc8/gob.vcproj
+++ b/dists/msvc8/gob.vcproj
@@ -259,30 +259,6 @@
>
</File>
<File
- RelativePath="..\..\engines\gob\resources.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\resources.h"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.h"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\script.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\script.h"
- >
- </File>
- <File
RelativePath="..\..\engines\gob\dataio.cpp"
>
</File>
@@ -335,27 +311,19 @@
>
</File>
<File
- RelativePath="..\..\engines\gob\game.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\game.h"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\game_fascin.cpp"
+ RelativePath="..\..\engines\gob\expression.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\game_v1.cpp"
+ RelativePath="..\..\engines\gob\expression.h"
>
</File>
<File
- RelativePath="..\..\engines\gob\game_v2.cpp"
+ RelativePath="..\..\engines\gob\game.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\game_v6.cpp"
+ RelativePath="..\..\engines\gob\game.h"
>
</File>
<File
@@ -403,6 +371,14 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\hotspots.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\hotspots.h"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\init.cpp"
>
</File>
@@ -423,6 +399,10 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\init_v6.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\inter.cpp"
>
</File>
@@ -507,11 +487,11 @@
>
</File>
<File
- RelativePath="..\..\engines\gob\expression.cpp"
+ RelativePath="..\..\engines\gob\resources.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\expression.h"
+ RelativePath="..\..\engines\gob\resources.h"
>
</File>
<File
@@ -603,6 +583,22 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\script.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\script.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.h"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\util.cpp"
>
</File>
diff --git a/dists/msvc9/gob.vcproj b/dists/msvc9/gob.vcproj
index 98bc1a935f..60385473a5 100644
--- a/dists/msvc9/gob.vcproj
+++ b/dists/msvc9/gob.vcproj
@@ -260,30 +260,6 @@
>
</File>
<File
- RelativePath="..\..\engines\gob\resources.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\resources.h"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\totfile.h"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\script.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\script.h"
- >
- </File>
- <File
RelativePath="..\..\engines\gob\dataio.cpp"
>
</File>
@@ -336,27 +312,19 @@
>
</File>
<File
- RelativePath="..\..\engines\gob\game.cpp"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\game.h"
- >
- </File>
- <File
- RelativePath="..\..\engines\gob\game_fascin.cpp"
+ RelativePath="..\..\engines\gob\expression.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\game_v1.cpp"
+ RelativePath="..\..\engines\gob\expression.h"
>
</File>
<File
- RelativePath="..\..\engines\gob\game_v2.cpp"
+ RelativePath="..\..\engines\gob\game.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\game_v6.cpp"
+ RelativePath="..\..\engines\gob\game.h"
>
</File>
<File
@@ -404,6 +372,14 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\hotspots.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\hotspots.h"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\init.cpp"
>
</File>
@@ -424,6 +400,10 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\init_v6.cpp"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\inter.cpp"
>
</File>
@@ -508,75 +488,75 @@
>
</File>
<File
- RelativePath="..\..\engines\gob\expression.cpp"
+ RelativePath="..\..\engines\gob\resources.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\expression.h"
+ RelativePath="..\..\engines\gob\resources.h"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\savefile.h"
+ RelativePath="..\..\engines\gob\save\saveconverter.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\savefile.cpp"
+ RelativePath="..\..\engines\gob\save\saveconverter.h"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\savehandler.h"
+ RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\savehandler.cpp"
+ RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload.h"
+ RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload.cpp"
+ RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v2.cpp"
+ RelativePath="..\..\engines\gob\save\savefile.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v3.cpp"
+ RelativePath="..\..\engines\gob\save\savefile.h"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v4.cpp"
+ RelativePath="..\..\engines\gob\save\savehandler.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveload_v6.cpp"
+ RelativePath="..\..\engines\gob\save\savehandler.h"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter.h"
+ RelativePath="..\..\engines\gob\save\saveload.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter.cpp"
+ RelativePath="..\..\engines\gob\save\saveload.h"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v2.cpp"
+ RelativePath="..\..\engines\gob\save\saveload_v2.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v3.cpp"
+ RelativePath="..\..\engines\gob\save\saveload_v3.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v4.cpp"
+ RelativePath="..\..\engines\gob\save\saveload_v4.cpp"
>
</File>
<File
- RelativePath="..\..\engines\gob\save\saveconverter_v6.cpp"
+ RelativePath="..\..\engines\gob\save\saveload_v6.cpp"
>
</File>
<File
@@ -604,6 +584,22 @@
>
</File>
<File
+ RelativePath="..\..\engines\gob\script.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\script.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\engines\gob\totfile.h"
+ >
+ </File>
+ <File
RelativePath="..\..\engines\gob\util.cpp"
>
</File>
diff --git a/engines/cruise/ctp.cpp b/engines/cruise/ctp.cpp
index be4639af4d..11d5f582ed 100644
--- a/engines/cruise/ctp.cpp
+++ b/engines/cruise/ctp.cpp
@@ -209,9 +209,9 @@ int setNodeState(int nodeIdx, int nodeState) {
int oldState = walkboxState[nodeIdx];
if (nodeState == -1)
- return
+ return oldState;
- walkboxState[nodeIdx] = nodeState;
+ walkboxState[nodeIdx] = nodeState;
return oldState;
}
diff --git a/engines/cruise/font.cpp b/engines/cruise/font.cpp
index d5010b2bf8..8da3621bdc 100644
--- a/engines/cruise/font.cpp
+++ b/engines/cruise/font.cpp
@@ -242,7 +242,7 @@ int32 prepareWordRender(int32 inRightBorder_X, int16 wordSpacingWidth,
if (character == '|' || !character) {
finish = 1;
} else {
- if (charData) {
+ if (charData >= 0) {
if (pixelCount + wordSpacingWidth +
(int16)fontData[charData].charWidth >= inRightBorder_X) {
finish = 1;
diff --git a/engines/cruise/function.cpp b/engines/cruise/function.cpp
index eab69c6846..d0443ef458 100644
--- a/engines/cruise/function.cpp
+++ b/engines/cruise/function.cpp
@@ -828,7 +828,7 @@ int16 Op_Preload(void) {
}
int16 Op_LoadCt(void) {
- return initCt((char*)popPtr());
+ return initCt((const char *)popPtr());
}
int16 Op_EndAnim(void) {
diff --git a/engines/gob/demos/demoplayer.cpp b/engines/gob/demos/demoplayer.cpp
index 0229bb7515..7f65721ce5 100644
--- a/engines/gob/demos/demoplayer.cpp
+++ b/engines/gob/demos/demoplayer.cpp
@@ -222,7 +222,7 @@ void DemoPlayer::playVideoDoubled() {
int16 key;
bool end = false;
while (_vm->_util->checkKey(key))
- if (key == 0x011B)
+ if (key == kKeyEscape)
end = true;
if (end)
break;
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index b3e5e7418c..c20bece7b4 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -360,9 +360,9 @@ int Draw::stringLength(const char *str, int16 fontIndex) {
} else {
- if (_fonts[fontIndex]->extraData)
+ if (_fonts[fontIndex]->charWidths)
while (*str != 0)
- len += *(_fonts[fontIndex]->extraData + (*str++ - _fonts[fontIndex]->startItem));
+ len += *(_fonts[fontIndex]->charWidths + (*str++ - _fonts[fontIndex]->startItem));
else
len = (strlen(str) * _fonts[fontIndex]->itemWidth);
@@ -376,10 +376,10 @@ void Draw::drawString(const char *str, int16 x, int16 y, int16 color1, int16 col
while (*str != '\0') {
_vm->_video->drawLetter(*str, x, y, font, transp, color1, color2, dest);
- if (!font->extraData)
+ if (!font->charWidths)
x += font->itemWidth;
else
- x += *(font->extraData + (*str - font->startItem));
+ x += *(font->charWidths + (*str - font->startItem));
str++;
}
}
@@ -415,12 +415,12 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right,
_fontIndex = fontIndex;
_frontColor = color;
_textToPrint = str;
- if (_fonts[fontIndex]->extraData != 0) {
- byte *data = _fonts[fontIndex]->extraData;
+ if (_fonts[fontIndex]->charWidths != 0) {
+ uint8 *widths = _fonts[fontIndex]->charWidths;
int length = strlen(str);
for (int i = 0; i < length; i++)
- width += *(data + (str[i] - _fonts[_fontIndex]->startItem));
+ width += *(widths + (str[i] - _fonts[_fontIndex]->startItem));
}
else
width = strlen(str) * _fonts[fontIndex]->itemWidth;
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 94ee32a031..91f2a45637 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -33,6 +33,7 @@
#include "gob/util.h"
#include "gob/game.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/scenery.h"
#include "gob/inter.h"
#include "gob/sound/sound.h"
@@ -44,6 +45,12 @@ Draw_v1::Draw_v1(GobEngine *vm) : Draw(vm) {
void Draw_v1::initScreen() {
_backSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0);
+ _frontSurface = _vm->_global->_primarySurfDesc;
+
+ _cursorSprites =
+ _vm->_video->initSurfDesc(_vm->_global->_videoMode, 32, 16, 2);
+ _scummvmCursor =
+ _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, SCUMMVM_CURSOR);
}
void Draw_v1::closeScreen() {
@@ -58,7 +65,6 @@ void Draw_v1::blitCursor() {
}
void Draw_v1::animateCursor(int16 cursor) {
- Game::Collision *ptr;
int16 cursorIndex = cursor;
int16 newX = 0, newY = 0;
uint16 hotspotX = 0, hotspotY = 0;
@@ -66,29 +72,10 @@ void Draw_v1::animateCursor(int16 cursor) {
_showCursor = 2;
if (cursorIndex == -1) {
- cursorIndex = 0;
- for (ptr = _vm->_game->_collisionAreas; ptr->left != 0xFFFF; ptr++) {
- if (ptr->flags & 0xFFF0)
- continue;
-
- if (ptr->left > _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->right < _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->top > _vm->_global->_inter_mouseY)
- continue;
+ cursorIndex =
+ _vm->_game->_hotspots->findCursor(_vm->_global->_inter_mouseX,
+ _vm->_global->_inter_mouseY);
- if (ptr->bottom < _vm->_global->_inter_mouseY)
- continue;
-
- if ((ptr->flags & 0xF) < 3)
- cursorIndex = 1;
- else
- cursorIndex = 3;
- break;
- }
if (_cursorAnimLow[cursorIndex] == -1)
cursorIndex = 1;
}
@@ -317,7 +304,7 @@ void Draw_v1::printTotText(int16 id) {
_renderFlags = savedFlags;
if (_renderFlags & RENDERFLAG_COLLISIONS)
- _vm->_game->checkCollisions(0, 0, 0, 0);
+ _vm->_game->_hotspots->check(0, 0);
if ((_renderFlags & RENDERFLAG_CAPTUREPOP) && *_vm->_scenery->_pCaptureCounter != 0) {
(*_vm->_scenery->_pCaptureCounter)--;
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 2843456f42..a0be23516c 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -34,6 +34,7 @@
#include "gob/game.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/scenery.h"
#include "gob/inter.h"
#include "gob/video.h"
@@ -82,7 +83,6 @@ void Draw_v2::blitCursor() {
}
void Draw_v2::animateCursor(int16 cursor) {
- Game::Collision *ptr;
int16 cursorIndex = cursor;
int16 newX = 0, newY = 0;
uint16 hotspotX = 0, hotspotY = 0;
@@ -91,32 +91,10 @@ void Draw_v2::animateCursor(int16 cursor) {
// .-- _draw_animateCursorSUB1 ---
if (cursorIndex == -1) {
- cursorIndex = 0;
- for (ptr = _vm->_game->_collisionAreas; ptr->left != 0xFFFF; ptr++) {
- if ((ptr->flags & 0xF00) || (ptr->id & 0x4000))
- continue;
-
- if (ptr->left > _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->right < _vm->_global->_inter_mouseX)
- continue;
-
- if (ptr->top > _vm->_global->_inter_mouseY)
- continue;
-
- if (ptr->bottom < _vm->_global->_inter_mouseY)
- continue;
-
- if ((ptr->flags & 0xF000) == 0) {
- if ((ptr->flags & 0xF) >= 3) {
- cursorIndex = 3;
- break;
- } else if (((ptr->flags & 0xF0) != 0x10) && (cursorIndex == 0))
- cursorIndex = 1;
- } else if (cursorIndex == 0)
- cursorIndex = (ptr->flags >> 12) & 0xF;
- }
+ cursorIndex =
+ _vm->_game->_hotspots->findCursor(_vm->_global->_inter_mouseX,
+ _vm->_global->_inter_mouseY);
+
if (_cursorAnimLow[cursorIndex] == -1)
cursorIndex = 1;
}
@@ -407,8 +385,8 @@ void Draw_v2::printTotText(int16 id) {
adjustCoords(2, &rectRight, &rectBottom);
if (colId != -1)
- _vm->_game->addNewCollision(colId + 0xD000, rectLeft, rectTop,
- rectRight, rectBottom, 2, 0, 0, 0);
+ _vm->_game->_hotspots->add(colId + 0xD000, rectLeft, rectTop,
+ rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
if (_needAdjust != 2)
printTextCentered(colCmd & 0x0F, rectLeft + 4, rectTop + 4,
@@ -501,8 +479,8 @@ void Draw_v2::printTotText(int16 id) {
rectBottom = destY + (int16)READ_LE_UINT16(ptr + 6);
adjustCoords(2, &rectLeft, &rectTop);
adjustCoords(2, &rectRight, &rectBottom);
- _vm->_game->addNewCollision(colId + 0x0D000, rectLeft, rectTop,
- rectRight, rectBottom, 2, 0, 0, 0);
+ _vm->_game->_hotspots->add(colId + 0x0D000, rectLeft, rectTop,
+ rectRight, rectBottom, (uint16) Hotspots::kTypeClick, 0, 0, 0, 0);
ptr += 8;
}
break;
@@ -604,7 +582,7 @@ void Draw_v2::printTotText(int16 id) {
if (!(_renderFlags & RENDERFLAG_COLLISIONS))
return;
- _vm->_game->checkCollisions(0, 0, 0, 0);
+ _vm->_game->_hotspots->check(0, 0);
if (*_vm->_scenery->_pCaptureCounter != 0) {
(*_vm->_scenery->_pCaptureCounter)--;
@@ -784,7 +762,7 @@ void Draw_v2::spriteOperation(int16 operation) {
if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) {
- if (!_fonts[_fontIndex]->extraData) {
+ if (!_fonts[_fontIndex]->charWidths) {
if (((int8) _textToPrint[0]) == -1) {
_vm->validateLanguage();
@@ -807,7 +785,7 @@ void Draw_v2::spriteOperation(int16 operation) {
_vm->_video->drawLetter(_textToPrint[i], _destSpriteX,
_destSpriteY, _fonts[_fontIndex], _transparency,
_frontColor, _backColor, *_spritesArray[_destSurface]);
- _destSpriteX += *(_fonts[_fontIndex]->extraData +
+ _destSpriteX += *(_fonts[_fontIndex]->charWidths +
(_textToPrint[i] - _fonts[_fontIndex]->startItem));
}
else
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index 5771ee9f76..d201019d08 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -29,14 +29,15 @@
#include "gob/game.h"
#include "gob/helper.h"
#include "gob/global.h"
-#include "gob/util.h"
#include "gob/dataio.h"
#include "gob/variables.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/inter.h"
#include "gob/draw.h"
#include "gob/mult.h"
+#include "gob/scenery.h"
#include "gob/videoplayer.h"
#include "gob/sound/sound.h"
@@ -170,30 +171,14 @@ bool Environments::has(Resources *resources, uint8 startEnv, int16 except) const
Game::Game(GobEngine *vm) : _vm(vm) {
- _collisionAreas = 0;
- _shouldPushColls = 0;
-
_captureCount = 0;
- _collStackSize = 0;
-
- for (int i = 0; i < 5; i++) {
- _collStack[i] = 0;
- _collStackElemSizes[i] = 0;
- }
-
_curTotFile[0] = 0;
_totToLoad[0] = 0;
_startTimeKey = 0;
- _mouseButtons = 0;
-
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
+ _mouseButtons = kMouseButtonsNone;
- _activeCollResId = 0;
- _activeCollIndex = 0;
_handleMouse = 0;
_forceHandleMouse = 0;
_menuLevel = 0;
@@ -201,10 +186,7 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_preventScroll = false;
_scrollHandleMouse = false;
- _noCd = false;
-
_tempStr[0] = 0;
- _collStr[0] = 0;
_numEnvironments = 0;
_curEnvironment = 0;
@@ -212,19 +194,181 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_environments = new Environments(_vm);
_script = new Script(_vm);
_resources = new Resources(_vm);
+ _hotspots = new Hotspots(_vm);
}
Game::~Game() {
delete _environments;
delete _script;
delete _resources;
+ delete _hotspots;
}
-void Game::freeCollision(int16 id) {
- for (int i = 0; i < 250; i++) {
- if (_collisionAreas[i].id == id)
- _collisionAreas[i].left = 0xFFFF;
+void Game::prepareStart() {
+ _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2;
+ _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1;
+ _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette;
+
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+ _vm->_draw->initScreen();
+ _vm->_video->fillRect(*_vm->_draw->_frontSurface, 0, 0,
+ _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1);
+
+ _vm->_util->setMousePos(152, 92);
+ _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152;
+ _vm->_draw->_cursorY = _vm->_global->_inter_mouseY = 92;
+
+ _vm->_draw->_invalidatedCount = 0;
+ _vm->_draw->_noInvalidated = true;
+ _vm->_draw->_applyPal = false;
+ _vm->_draw->_paletteCleared = false;
+ _vm->_draw->_cursorWidth = 16;
+ _vm->_draw->_cursorHeight = 16;
+ _vm->_draw->_transparentCursor = 1;
+
+ for (int i = 0; i < 40; i++) {
+ _vm->_draw->_cursorAnimLow[i] = -1;
+ _vm->_draw->_cursorAnimDelays[i] = 0;
+ _vm->_draw->_cursorAnimHigh[i] = 0;
}
+
+ _vm->_draw->_renderFlags = 0;
+ _vm->_draw->_backDeltaX = 0;
+ _vm->_draw->_backDeltaY = 0;
+
+ _startTimeKey = _vm->_util->getTimeKey();
+}
+
+void Game::playTot(int16 skipPlay) {
+ char savedTotName[20];
+ int16 *oldCaptureCounter;
+ int16 *oldBreakFrom;
+ int16 *oldNestLevel;
+ int16 _captureCounter;
+ int16 breakFrom;
+ int16 nestLevel;
+
+ oldNestLevel = _vm->_inter->_nestLevel;
+ oldBreakFrom = _vm->_inter->_breakFromLevel;
+ oldCaptureCounter = _vm->_scenery->_pCaptureCounter;
+
+ _script->push();
+
+ _vm->_inter->_nestLevel = &nestLevel;
+ _vm->_inter->_breakFromLevel = &breakFrom;
+ _vm->_scenery->_pCaptureCounter = &_captureCounter;
+ strcpy(savedTotName, _curTotFile);
+
+ if (skipPlay <= 0) {
+ while (!_vm->shouldQuit()) {
+ if (_vm->_inter->_variables)
+ _vm->_draw->animateCursor(4);
+
+ if (skipPlay != -1) {
+ _vm->_inter->initControlVars(1);
+
+ for (int i = 0; i < 4; i++) {
+ _vm->_draw->_fontToSprite[i].sprite = -1;
+ _vm->_draw->_fontToSprite[i].base = -1;
+ _vm->_draw->_fontToSprite[i].width = -1;
+ _vm->_draw->_fontToSprite[i].height = -1;
+ }
+
+ _vm->_mult->initAll();
+ _vm->_mult->zeroMultData();
+
+ _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface;
+ _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface;
+ _vm->_draw->_cursorSpritesBack = _vm->_draw->_cursorSprites;
+ } else
+ _vm->_inter->initControlVars(0);
+
+ _vm->_draw->_cursorHotspotXVar = -1;
+ _totToLoad[0] = 0;
+
+ if ((_curTotFile[0] == 0) && (!_script->isLoaded()))
+ break;
+
+ if (skipPlay == -2) {
+ _vm->_vidPlayer->primaryClose();
+ skipPlay = 0;
+ }
+
+ if (!_script->load(_curTotFile)) {
+ _vm->_draw->blitCursor();
+ _vm->_inter->_terminate = 2;
+ break;
+ }
+
+ _resources->load(_curTotFile);
+
+ _vm->_global->_inter_animDataSize = _script->getAnimDataSize();
+ if (!_vm->_inter->_variables)
+ _vm->_inter->allocateVars(_script->getVariablesCount() & 0xFFFF);
+
+ _script->seek(_script->getFunctionOffset(TOTFile::kFunctionStart));
+
+ _vm->_inter->renewTimeInVars();
+
+ WRITE_VAR(13, _vm->_global->_useMouse);
+ WRITE_VAR(14, _vm->_global->_soundFlags);
+ WRITE_VAR(15, _vm->_global->_fakeVideoMode);
+ WRITE_VAR(16, _vm->_global->_language);
+
+ _vm->_inter->callSub(2);
+
+ if (_totToLoad[0] != 0)
+ _vm->_inter->_terminate = 0;
+
+ _vm->_draw->blitInvalidated();
+
+ _script->unload();
+
+ _resources->unload();
+
+ for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++)
+ capturePop(0);
+
+ if (skipPlay != -1) {
+ _vm->_goblin->freeObjects();
+
+ _vm->_sound->blasterStop(0);
+
+ for (int i = 0; i < Sound::kSoundsCount; i++) {
+ SoundDesc *sound = _vm->_sound->sampleGetBySlot(i);
+
+ if (sound &&
+ ((sound->getType() == SOUND_SND) || (sound->getType() == SOUND_WAV)))
+ _vm->_sound->sampleFree(sound);
+ }
+ }
+
+ if (_totToLoad[0] == 0)
+ break;
+
+ strcpy(_curTotFile, _totToLoad);
+ }
+ } else {
+ _vm->_inter->initControlVars(0);
+ _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;
+ }
+
+ strcpy(_curTotFile, savedTotName);
+
+ _vm->_inter->_nestLevel = oldNestLevel;
+ _vm->_inter->_breakFromLevel = oldBreakFrom;
+ _vm->_scenery->_pCaptureCounter = oldCaptureCounter;
+
+ _script->pop();
}
void Game::capturePush(int16 left, int16 top, int16 width, int16 height) {
@@ -349,7 +493,7 @@ void Game::evaluateScroll(int16 x, int16 y) {
}
int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
- int16 *pButtons, char handleMouse) {
+ MouseButtons *pButtons, char handleMouse) {
_vm->_util->processInput(true);
@@ -373,28 +517,17 @@ int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
if (pMouseX && pMouseY && pButtons) {
_vm->_util->getMouseState(pMouseX, pMouseY, pButtons);
- if (*pButtons == 3)
- *pButtons = 0;
+ if (*pButtons == kMouseButtonsBoth)
+ *pButtons = kMouseButtonsNone;
}
return _vm->_util->checkKey();
}
-int16 Game::adjustKey(int16 key) {
- if (key <= 0x60 || key >= 0x7B)
- return key;
-
- return key - 0x20;
-}
-
-void Game::start(void) {
- _collisionAreas = new Collision[250];
- memset(_collisionAreas, 0, 250 * sizeof(Collision));
-
+void Game::start() {
prepareStart();
playTot(-2);
- delete[] _collisionAreas;
_vm->_draw->closeScreen();
for (int i = 0; i < SPRITES_COUNT; i++)
@@ -406,6 +539,9 @@ void Game::start(void) {
void Game::totSub(int8 flags, const char *newTotFile) {
int8 curBackupPos;
+ if ((flags == 16) || (flags == 17))
+ warning("Urban Stub: Game::totSub(), flags == %d", flags);
+
if (_numEnvironments >= Environments::kEnvironmentCount)
return;
@@ -417,13 +553,14 @@ void Game::totSub(int8 flags, const char *newTotFile) {
_script = new Script(_vm);
_resources = new Resources(_vm);
+
+ if (flags & 0x80)
+ warning("Urban Stub: Game::totSub(), flags & 0x80");
+
if (flags & 1)
_vm->_inter->_variables = 0;
strncpy0(_curTotFile, newTotFile, 9);
-// if (_vm->getGameType() == kGameTypeGeisha)
-// strcat(_curTotFile, ".0OT");
-// else
strcat(_curTotFile, ".TOT");
if (_vm->_inter->_terminate != 0) {
@@ -431,7 +568,7 @@ void Game::totSub(int8 flags, const char *newTotFile) {
return;
}
- pushCollisions(0);
+ _hotspots->push(0, true);
if (flags & 2)
playTot(-1);
@@ -441,7 +578,8 @@ void Game::totSub(int8 flags, const char *newTotFile) {
if (_vm->_inter->_terminate != 2)
_vm->_inter->_terminate = 0;
- popCollisions();
+ _hotspots->clear();
+ _hotspots->pop();
if ((flags & 1) && _vm->_inter->_variables) {
_vm->_inter->delocateVars();
@@ -489,13 +627,13 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
return;
}
- pushCollisions(0);
+ _hotspots->push(0, true);
playTot(skipPlay);
if (_vm->_inter->_terminate != 2)
_vm->_inter->_terminate = 0;
- popCollisions();
+ _hotspots->pop();
clearUnusedEnvironment();
@@ -504,87 +642,6 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_environments->get(_curEnvironment);
}
-void Game::setCollisions(byte arg_0) {
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- Collision *collArea;
-
- for (collArea = _collisionAreas; collArea->left != 0xFFFF; collArea++) {
- if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0))
- continue;
-
- _script->call(collArea->funcSub);
-
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) &&
- (left != 0xFFFF)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
- if (_vm->_draw->_needAdjust != 2) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if ((collArea->flags & 0x0F) < 3)
- _vm->_draw->adjustCoords(2, &width, &height);
- else {
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(2, 0, &height);
- }
- }
- collArea->left = left;
- collArea->top = top;
- collArea->right = left + width - 1;
- collArea->bottom = top + height - 1;
-
- _script->pop();
- }
-}
-
-void Game::collSub(uint16 offset) {
- int16 collStackSize;
-
- _script->call(offset);
-
- _shouldPushColls = 1;
- collStackSize = _collStackSize;
-
- _vm->_inter->funcBlock(0);
-
- if (collStackSize != _collStackSize)
- popCollisions();
-
- _shouldPushColls = 0;
-
- _script->pop();
-
- setCollisions();
-}
-
-void Game::collAreaSub(int16 index, int8 enter) {
- uint16 collId;
-
- collId = _collisionAreas[index].id & 0xF000;
-
- if ((collId == 0xA000) || (collId == 0x9000)) {
- if (enter == 0)
- WRITE_VAR(17, _collisionAreas[index].id & 0x0FFF);
- else
- WRITE_VAR(17, -(_collisionAreas[index].id & 0x0FFF));
- }
-
- if (enter != 0) {
- if (_collisionAreas[index].funcEnter != 0)
- collSub(_collisionAreas[index].funcEnter);
- } else {
- if (_collisionAreas[index].funcLeave != 0)
- collSub(_collisionAreas[index].funcLeave);
- }
-}
-
void Game::clearUnusedEnvironment() {
if (!_environments->has(_script)) {
delete _script;
@@ -594,7 +651,6 @@ void Game::clearUnusedEnvironment() {
delete _resources;
_resources = 0;
}
-
}
} // End of namespace Gob
diff --git a/engines/gob/game.h b/engines/gob/game.h
index ead4a56492..d3a758f014 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -26,11 +26,14 @@
#ifndef GOB_GAME_H
#define GOB_GAME_H
+#include "gob/util.h"
+
namespace Gob {
class Script;
class Resources;
class Variables;
+class Hotspots;
class Environments {
public:
@@ -67,53 +70,30 @@ private:
class Game {
public:
-
-#include "common/pack-start.h" // START STRUCT PACKING
-
- struct Collision {
- int16 id;
- uint16 left;
- uint16 top;
- uint16 right;
- uint16 bottom;
- int16 flags;
- int16 key;
- uint16 funcEnter;
- uint16 funcLeave;
- uint16 funcSub;
- Script *script;
- } PACKED_STRUCT;
-
- struct InputDesc {
- int16 fontIndex;
- int16 backColor;
- int16 frontColor;
- byte *ptr;
- } PACKED_STRUCT;
-
-#include "common/pack-end.h" // END STRUCT PACKING
-
- Collision *_collisionAreas;
- Collision *_collStack[5];
-
- Script *_script;
+ Script *_script;
Resources *_resources;
+ Hotspots *_hotspots;
char _curTotFile[14];
char _totToLoad[20];
int32 _startTimeKey;
- int16 _mouseButtons;
+ MouseButtons _mouseButtons;
bool _noScroll;
bool _preventScroll;
bool _scrollHandleMouse;
- bool _noCd;
+ byte _handleMouse;
+ char _forceHandleMouse;
Game(GobEngine *vm);
virtual ~Game();
+ void prepareStart();
+
+ void playTot(int16 skipPlay);
+
void capturePush(int16 left, int16 top, int16 width, int16 height);
void capturePop(char doDraw);
@@ -122,60 +102,21 @@ public:
void evaluateScroll(int16 x, int16 y);
int16 checkKeys(int16 *pMousex = 0, int16 *pMouseY = 0,
- int16 *pButtons = 0, char handleMouse = 0);
- void start(void);
-
- virtual void totSub(int8 flags, const char *newTotFile);
- virtual void switchTotSub(int16 index, int16 skipPlay);
+ MouseButtons *pButtons = 0, char handleMouse = 0);
+ void start();
- void freeCollision(int16 id);
-
- virtual void playTot(int16 skipPlay) = 0;
-
- virtual void clearCollisions(void) = 0;
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0) = 0;
- virtual void collisionsBlock(void) = 0;
- virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc *inpDesc, int16 *collResId,
- int16 *collIndex, bool mono = true) = 0;
- virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId,
- int16 *collIndex, bool mono = true) = 0;
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex) = 0;
-
- virtual void prepareStart(void) = 0;
-
- virtual void pushCollisions(char all) = 0;
- virtual void popCollisions(void) = 0;
+ void totSub(int8 flags, const char *newTotFile);
+ void switchTotSub(int16 index, int16 skipPlay);
protected:
- int16 _lastCollKey;
- int16 _lastCollAreaIndex;
- int16 _lastCollId;
-
- int16 _activeCollResId;
- int16 _activeCollIndex;
- byte _handleMouse;
- char _forceHandleMouse;
uint32 _menuLevel;
char _tempStr[256];
- int16 _collStackSize;
- int16 _collStackElemSizes[5];
-
- char _shouldPushColls;
-
// Capture
Common::Rect _captureStack[20];
int16 _captureCount;
- char _collStr[256];
-
// For totSub()
int8 _curEnvironment;
int8 _numEnvironments;
@@ -183,129 +124,9 @@ protected:
GobEngine *_vm;
- virtual int16 adjustKey(int16 key);
-
- void collAreaSub(int16 index, int8 enter);
-
- virtual void setCollisions(byte arg_0 = 1);
- virtual void collSub(uint16 offset);
-
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex) = 0;
-
void clearUnusedEnvironment();
};
-class Game_v1 : public Game {
-public:
- virtual void playTot(int16 skipPlay);
-
- virtual void clearCollisions(void);
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0);
- virtual void collisionsBlock(void);
- virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc *inpDesc, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
-
- virtual void prepareStart(void);
-
- virtual void pushCollisions(char all);
- virtual void popCollisions(void);
-
- Game_v1(GobEngine *vm);
- virtual ~Game_v1() {}
-
-protected:
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex);
-};
-
-class Game_v2 : public Game_v1 {
-public:
- virtual void playTot(int16 skipPlay);
-
- virtual void clearCollisions(void);
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0);
- virtual void collisionsBlock(void);
- virtual int16 multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc *inpDesc, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId,
- int16 *collIndex, bool mono = true);
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
-
- virtual void prepareStart(void);
-
- virtual void pushCollisions(char all);
- virtual void popCollisions(void);
-
- Game_v2(GobEngine *vm);
- virtual ~Game_v2() {}
-
-protected:
- struct CollLast {
- int16 key;
- int16 id;
- int16 areaIndex;
- };
-
- CollLast _collLasts[5];
-
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex);
-};
-
-class Game_v6 : public Game_v2 {
-public:
- virtual void totSub(int8 flags, const char *newTotFile);
-
- virtual int16 addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub = 0);
-
- virtual void prepareStart(void);
-
- virtual void pushCollisions(char all);
-
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
- virtual void collisionsBlock(void);
-
- Game_v6(GobEngine *vm);
- virtual ~Game_v6() {}
-
-protected:
- uint32 _someTimeDly;
-
- virtual void setCollisions(byte arg_0 = 1);
- virtual void collSub(uint16 offset);
-
- virtual int16 adjustKey(int16 key);
-
- virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex);
-
- void collSubReenter();
-};
-
-class Game_Fascination : public Game_v2 {
-public:
- virtual int16 checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex);
-
- Game_Fascination(GobEngine *vm);
- virtual ~Game_Fascination() {}
-};
-
} // End of namespace Gob
#endif // GOB_GAME_H
diff --git a/engines/gob/game_fascin.cpp b/engines/gob/game_fascin.cpp
deleted file mode 100644
index 38ad03f0f8..0000000000
--- a/engines/gob/game_fascin.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/endian.h"
-#include "common/stream.h"
-
-#include "gob/gob.h"
-#include "gob/game.h"
-#include "gob/global.h"
-#include "gob/util.h"
-#include "gob/dataio.h"
-#include "gob/draw.h"
-#include "gob/goblin.h"
-#include "gob/inter.h"
-#include "gob/mult.h"
-#include "gob/scenery.h"
-#include "gob/video.h"
-#include "gob/videoplayer.h"
-#include "gob/sound/sound.h"
-
-namespace Gob {
-
-Game_Fascination::Game_Fascination(GobEngine *vm) : Game_v2(vm) {
-}
-
-int16 Game_Fascination::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId,
- int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- int16 oldIndex;
- int16 oldId;
- int16 newkey;
- uint32 timeKey;
-
- _scrollHandleMouse = handleMouse != 0;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- if ((_vm->_draw->_cursorIndex == -1) &&
- (handleMouse != 0) && (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
-
- if (handleMouse != 0) {
- if ((handleMouse==1) && (_vm->_draw->_renderFlags & RENDERFLAG_UNKNOWN))
- warning("checkCollisions : RENDERFLAG_UNKNOWN - Unknown behavior");
- _vm->_draw->animateCursor(-1);
- }
-
- timeKey = _vm->_util->getTimeKey();
- while (1) {
- if (_vm->_inter->_terminate || _vm->shouldQuit()) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- _vm->_video->waitRetrace();
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != 0)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse & 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != 0) {
- if (deltaTime > 0) {
- _vm->_draw->animateCursor(2);
- _vm->_util->delay(deltaTime);
- } else if (handleMouse & 1)
- _vm->_util->waitMouseRelease(1);
- _vm->_draw->animateCursor(-1);
-
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse & 1) &&
- ((deltaTime <= 0) || (_mouseButtons == 0)))
- _vm->_draw->blitCursor();
-
- if ((_lastCollKey != 0) && (key != _lastCollKey))
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- return key;
- }
-
- if (handleMouse & 4)
- return 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- } else if ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) ||
- (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) {
-
- oldIndex = _lastCollAreaIndex;
- oldId = _lastCollId;
- newkey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (newkey != _lastCollKey) {
- if ((_lastCollKey != 0) && (oldId & 0x8000))
- collAreaSub(oldIndex, 0);
-
- _lastCollKey = newkey;
-
- if ((newkey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
- }
- }
-
- if ((deltaTime < 0) && (key == 0) && (_mouseButtons == 0)) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((curtime + deltaTime) > timeKey) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- _vm->_util->delay(10);
- }
-}
-
-} // End of namespace Gob
diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp
deleted file mode 100644
index 87dc78e3b1..0000000000
--- a/engines/gob/game_v1.cpp
+++ /dev/null
@@ -1,1426 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/endian.h"
-#include "common/stream.h"
-
-#include "gob/gob.h"
-#include "gob/game.h"
-#include "gob/helper.h"
-#include "gob/global.h"
-#include "gob/util.h"
-#include "gob/dataio.h"
-#include "gob/script.h"
-#include "gob/resources.h"
-#include "gob/draw.h"
-#include "gob/inter.h"
-#include "gob/mult.h"
-#include "gob/video.h"
-#include "gob/scenery.h"
-#include "gob/sound/sound.h"
-
-namespace Gob {
-
-Game_v1::Game_v1(GobEngine *vm) : Game(vm) {
-}
-
-void Game_v1::playTot(int16 skipPlay) {
- int16 _captureCounter;
- int16 breakFrom;
- int16 nestLevel;
-
- int16 *oldNestLevel = _vm->_inter->_nestLevel;
- int16 *oldBreakFrom = _vm->_inter->_breakFromLevel;
- int16 *oldCaptureCounter = _vm->_scenery->_pCaptureCounter;
-
- _script->push();
-
- _vm->_inter->_nestLevel = &nestLevel;
- _vm->_inter->_breakFromLevel = &breakFrom;
- _vm->_scenery->_pCaptureCounter = &_captureCounter;
-
- char savedTotName[20];
- strcpy(savedTotName, _curTotFile);
-
- if (skipPlay <= 0) {
- while (!_vm->shouldQuit()) {
- for (int i = 0; i < 4; i++) {
- _vm->_draw->_fontToSprite[i].sprite = -1;
- _vm->_draw->_fontToSprite[i].base = -1;
- _vm->_draw->_fontToSprite[i].width = -1;
- _vm->_draw->_fontToSprite[i].height = -1;
- }
-
- if ((_vm->getPlatform() == Common::kPlatformMacintosh)||
- (_vm->getPlatform() == Common::kPlatformWindows))
- _vm->_sound->adlibStop();
- else
- _vm->_sound->cdStop();
-
- _vm->_draw->animateCursor(4);
- _vm->_inter->initControlVars(1);
- _vm->_mult->initAll();
- _vm->_mult->zeroMultData();
-
- for (int i = 0; i < SPRITES_COUNT; i++)
- _vm->_draw->freeSprite(i);
-
- _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface;
- _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface;
- _vm->_draw->_spritesArray[23] = _vm->_draw->_cursorSprites;
-
- for (int i = 0; i < 20; i++)
- freeSoundSlot(i);
-
- _totToLoad[0] = 0;
-
- if ((_curTotFile[0] == 0) && !_script->isLoaded())
- break;
-
- if (!_script->load(_curTotFile)) {
- _vm->_draw->blitCursor();
- break;
- }
-
- _resources->load(_curTotFile);
-
- _vm->_global->_inter_animDataSize = _script->getAnimDataSize();
- if (!_vm->_inter->_variables)
- _vm->_inter->allocateVars(_script->getVariablesCount() & 0xFFFF);
-
- _script->seek(_script->getFunctionOffset(TOTFile::kFunctionStart));
-
- _vm->_inter->renewTimeInVars();
-
- WRITE_VAR(13, _vm->_global->_useMouse);
- WRITE_VAR(14, _vm->_global->_soundFlags);
- WRITE_VAR(15, _vm->_global->_videoMode);
- WRITE_VAR(16, _vm->_global->_language);
-
- _vm->_inter->callSub(2);
- _script->setFinished(false);
-
- if (_totToLoad[0] != 0)
- _vm->_inter->_terminate = 0;
-
- _vm->_draw->blitInvalidated();
-
- _script->unload();
-
- _resources->unload();
-
- for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++)
- capturePop(0);
-
- _vm->_mult->checkFreeMult();
- _vm->_mult->freeAll();
-
- for (int i = 0; i < SPRITES_COUNT; i++)
- _vm->_draw->freeSprite(i);
- _vm->_sound->blasterStop(0);
-
- for (int i = 0; i < 20; i++)
- freeSoundSlot(i);
-
- if (_totToLoad[0] == 0)
- break;
-
- strcpy(_curTotFile, _totToLoad);
- }
- }
-
- strcpy(_curTotFile, savedTotName);
-
- _vm->_inter->_nestLevel = oldNestLevel;
- _vm->_inter->_breakFromLevel = oldBreakFrom;
- _vm->_scenery->_pCaptureCounter = oldCaptureCounter;
-
- _script->pop();
-}
-
-void Game_v1::clearCollisions() {
- for (int i = 0; i < 250; i++) {
- _collisionAreas[i].id = 0;
- _collisionAreas[i].left = 0xFFFF;
- }
-}
-
-int16 Game_v1::addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub) {
- Collision *ptr;
-
- debugC(5, kDebugCollisions, "addNewCollision");
- debugC(5, kDebugCollisions, "id = %X", id);
- debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d",
- left, top, right, bottom);
- debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key);
- debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d",
- funcEnter, funcLeave);
-
- for (int i = 0; i < 250; i++) {
- if (_collisionAreas[i].left != 0xFFFF)
- continue;
-
- ptr = &_collisionAreas[i];
- ptr->id = id;
- ptr->left = left;
- ptr->top = top;
- ptr->right = right;
- ptr->bottom = bottom;
- ptr->flags = flags;
- ptr->key = key;
- ptr->funcEnter = funcEnter;
- ptr->funcLeave = funcLeave;
- ptr->funcSub = funcSub;
- ptr->script = 0;
-
- return i;
- }
- error("Game_v1::addNewCollision(): Collision array full");
- return 0;
-}
-
-void Game_v1::pushCollisions(char all) {
- Collision *srcPtr;
- Collision *destPtr;
- int16 size;
-
- debugC(1, kDebugCollisions, "pushCollisions");
- for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if (all || (srcPtr->id & 0x8000))
- size++;
- }
-
- destPtr = new Collision[size];
- _collStack[_collStackSize] = destPtr;
- _collStackElemSizes[_collStackSize] = size;
- _collStackSize++;
-
- for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if (all || (srcPtr->id & 0x8000)) {
- memcpy(destPtr, srcPtr, sizeof(Collision));
- srcPtr->left = 0xFFFF;
- destPtr++;
- }
- }
-}
-
-void Game_v1::popCollisions(void) {
- Collision *destPtr;
- Collision *srcPtr;
-
- debugC(1, kDebugCollisions, "popCollision");
-
- _collStackSize--;
- for (destPtr = _collisionAreas; destPtr->left != 0xFFFF; destPtr++)
- ;
-
- srcPtr = _collStack[_collStackSize];
- memcpy(destPtr, srcPtr,
- _collStackElemSizes[_collStackSize] * sizeof(Collision));
-
- delete[] _collStack[_collStackSize];
-}
-
-int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime,
- int16 *pResId, int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- int16 oldIndex;
- int16 oldId;
- uint32 timeKey;
- bool firstIteration = true;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- timeKey = _vm->_util->getTimeKey();
-
- if ((_vm->_draw->_cursorIndex == -1) && (handleMouse != 0) &&
- (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) {
- _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter);
- _vm->_inter->funcBlock(0);
- _script->pop();
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- while (1) {
- if (_vm->_inter->_terminate) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- }
-
- // NOTE: the original asm does the below checkKeys call
- // _before_ this check. However, that can cause keypresses to get lost
- // since there's a return statement in this check.
- // Additionally, I added a 'deltaTime == -1' check there, since
- // when this function is called with deltaTime == -1 in inputArea,
- // and the return value is then discarded.
- if (deltaTime < 0) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((deltaTime == -1) || (((curtime + deltaTime) > timeKey) && !firstIteration)) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != 0)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse == 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
- }
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != 0) {
- oldIndex = 0;
-
- _vm->_draw->animateCursor(2);
- if (deltaTime <= 0) {
- if (handleMouse == 1)
- _vm->_util->waitMouseRelease(1);
- } else if (deltaTime > 0)
- _vm->_util->delay(deltaTime);
-
- _vm->_draw->animateCursor(-1);
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
-
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse == 1) &&
- ((deltaTime <= 0) || (_mouseButtons == 0)))
- _vm->_draw->blitCursor();
-
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
- _lastCollKey = 0;
- return key;
- }
-
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
-
- _lastCollKey =
- checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
- } else {
-
- if ((handleMouse != 0) &&
- ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) ||
- (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY))) {
- oldIndex = _lastCollAreaIndex;
- oldId = _lastCollId;
-
- key = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (key != _lastCollKey) {
- if ((_lastCollKey != 0) && ((oldId & 0x8000) != 0)) {
-
- _script->call(_collisionAreas[oldIndex].funcLeave);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
-
- _lastCollKey = key;
- if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) {
-
- _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter);
- _vm->_inter->funcBlock(0);
- _script->pop();
-
- }
-
- }
- }
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- if (deltaTime < -10)
- _vm->_util->delay(10);
-
- firstIteration = false;
- }
-}
-
-void Game_v1::prepareStart(void) {
- clearCollisions();
-
- _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2;
- _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1;
- _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette;
-
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-
- _vm->_draw->initScreen();
- _vm->_video->fillRect(*_vm->_draw->_backSurface, 0, 0, 319, 199, 1);
- _vm->_draw->_frontSurface = _vm->_global->_primarySurfDesc;
- _vm->_video->fillRect(*_vm->_draw->_frontSurface, 0, 0, 319, 199, 1);
-
- _vm->_util->setMousePos(152, 92);
- _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152;
- _vm->_draw->_cursorY = _vm->_global->_inter_mouseY = 92;
-
- _vm->_draw->_invalidatedCount = 0;
- _vm->_draw->_noInvalidated = true;
- _vm->_draw->_applyPal = false;
- _vm->_draw->_paletteCleared = false;
- _vm->_draw->_cursorWidth = 16;
- _vm->_draw->_cursorHeight = 16;
- _vm->_draw->_transparentCursor = 1;
-
- for (int i = 0; i < 40; i++) {
- _vm->_draw->_cursorAnimLow[i] = -1;
- _vm->_draw->_cursorAnimDelays[i] = 0;
- _vm->_draw->_cursorAnimHigh[i] = 0;
- }
-
- _vm->_draw->_cursorAnimLow[1] = 0;
- _vm->_draw->_cursorSprites =
- _vm->_video->initSurfDesc(_vm->_global->_videoMode, 32, 16, 2);
- _vm->_draw->_scummvmCursor =
- _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, SCUMMVM_CURSOR);
- _vm->_draw->_renderFlags = 0;
- _vm->_draw->_backDeltaX = 0;
- _vm->_draw->_backDeltaY = 0;
-
- _startTimeKey = _vm->_util->getTimeKey();
-}
-
-void Game_v1::collisionsBlock(void) {
- InputDesc descArray[20];
- int16 array[250];
- byte count;
- int16 collResId;
- int16 curCmd;
- int16 cmd;
- int16 cmdHigh;
- int16 key;
- int16 flags;
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- int16 var_22;
- int16 index;
- int16 curEditIndex;
- int16 deltaTime;
- int16 descIndex2;
- int16 stackPos2;
- int16 descIndex;
- int16 timeVal;
- char *str;
- int16 savedCollStackSize;
- int16 i;
- int16 counter;
- int16 var_24;
- int16 var_26;
- int16 collStackPos;
- Collision *collPtr;
- uint32 timeKey;
-
- if (_shouldPushColls)
- pushCollisions(1);
-
- collResId = -1;
- _script->skip(1);
- count = _script->readByte();
- _handleMouse = _script->readByte();
- deltaTime = 1000 * _script->readByte();
- descIndex2 = _script->readByte();
- stackPos2 = _script->readByte();
- descIndex = _script->readByte();
-
- if ((stackPos2 != 0) || (descIndex != 0))
- deltaTime /= 100;
-
- timeVal = deltaTime;
- _script->skip(1);
-
- uint32 startPos = _script->pos();
-
- WRITE_VAR(16, 0);
- var_22 = 0;
- index = 0;
- curEditIndex = 0;
-
- for (curCmd = 0; curCmd < count; curCmd++) {
- array[curCmd] = 0;
- cmd = _script->readByte();
-
- if ((cmd & 0x40) != 0) {
- cmd -= 0x40;
- cmdHigh = _script->readByte();
- cmdHigh <<= 8;
- } else
- cmdHigh = 0;
-
- if ((cmd & 0x80) != 0) {
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- } else {
- left = _script->readUint16();
- top = _script->readUint16();
- width = _script->readUint16();
- height = _script->readUint16();
- }
- cmd &= 0x7F;
-
- debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd);
-
- switch (cmd) {
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
-
- _vm->_util->clearKeyBuf();
- var_22 = 1;
- key = _script->readVarIndex();
- descArray[index].fontIndex = _script->readInt16();
- descArray[index].backColor = _script->readByte();
- descArray[index].frontColor = _script->readByte();
-
- if ((cmd < 5) || (cmd > 8)) {
- descArray[index].ptr = 0;
- } else {
- descArray[index].ptr = _script->getData() + _script->pos() + 2;
- _script->skip(_script->readInt16());
- }
-
- if (left == 0xFFFF)
- break;
-
- if ((cmd & 1) == 0) {
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1,
- top + height - 1, cmd, key, 0, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- } else {
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1,
- top + height - 1, cmd, key, 0, 0);
- }
- index++;
- break;
-
- case 21:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key, _script->pos(), 0);
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 20:
- collResId = curCmd;
- // Fall through to case 2
-
- case 2:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1,
- top + height - 1,
- (flags << 4) + cmdHigh + 2, key, 0, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 0:
- _script->skip(6);
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- cmd + cmdHigh, key,
- startPos, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 1:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- if (key == 0)
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmd + cmdHigh, key,
- startPos, _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
- }
- }
-
- _forceHandleMouse = 0;
- _vm->_util->clearKeyBuf();
-
- do {
- if (var_22 != 0) {
- key = multiEdit(deltaTime, index, &curEditIndex,
- descArray, &_activeCollResId, &_activeCollIndex);
-
- if (key == 0x1C0D) {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].flags & 1) != 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) <= 2)
- continue;
-
- collResId = _collisionAreas[i].id;
- _activeCollResId = collResId;
- collResId &= 0x7FFF;
- _activeCollIndex = i;
- break;
- }
- break;
- }
- } else
- key = checkCollisions(_handleMouse, -deltaTime,
- &_activeCollResId, &_activeCollIndex);
-
- if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
- ((key >> 8) > 1) && ((key >> 8) < 12))
- key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
-
- if (_activeCollResId == 0) {
- if (key != 0) {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].key == key) ||
- (_collisionAreas[i].key == 0x7FFF)) {
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
-
- if (_activeCollResId == 0) {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].key & 0xFF00) != 0)
- continue;
-
- if (_collisionAreas[i].key == 0)
- continue;
-
- if ((adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- } else {
-
- if ((deltaTime != 0) && (VAR(16) == 0)) {
- if (stackPos2 != 0) {
- collStackPos = 0;
- collPtr = _collisionAreas;
-
- for (i = 0, collPtr = _collisionAreas;
- collPtr->left != 0xFFFF; i++, collPtr++) {
-
- if ((collPtr->id & 0x8000) == 0)
- continue;
-
- collStackPos++;
- if (collStackPos != stackPos2)
- continue;
-
- _activeCollResId = collPtr->id;
- _activeCollIndex = i;
- WRITE_VAR(2, _vm->_global->_inter_mouseX);
- WRITE_VAR(3, _vm->_global->_inter_mouseY);
- WRITE_VAR(4, _mouseButtons);
- WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]);
-
- if (collPtr->funcLeave != 0) {
- timeKey = _vm->_util->getTimeKey();
-
- uint32 savedPos = _script->pos();
-
- _script->seek(collPtr->funcLeave);
-
- _shouldPushColls = 1;
- savedCollStackSize = _collStackSize;
- _vm->_inter->funcBlock(0);
-
- if (savedCollStackSize != _collStackSize)
- popCollisions();
-
- _shouldPushColls = 0;
-
- _script->seek(savedPos);
-
- deltaTime = timeVal -
- (_vm->_util->getTimeKey() - timeKey);
-
- if (deltaTime < 2)
- deltaTime = 2;
- }
-
- if (VAR(16) == 0)
- _activeCollResId = 0;
- break;
- }
- } else {
- if (descIndex != 0) {
- counter = 0;
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- counter++;
- if (counter != descIndex)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- } else {
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- } else {
- if (descIndex2 != 0) {
- counter = 0;
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- counter++;
- if (counter != descIndex2)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- }
- }
-
- if (_activeCollResId == 0)
- continue;
-
- if (_collisionAreas[_activeCollIndex].funcLeave != 0)
- continue;
-
- WRITE_VAR(2, _vm->_global->_inter_mouseX);
- WRITE_VAR(3, _vm->_global->_inter_mouseY);
- WRITE_VAR(4, _mouseButtons);
- WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]);
-
- if (_collisionAreas[_activeCollIndex].funcEnter != 0) {
- uint32 savedPos = _script->pos();
-
- _script->seek(_collisionAreas[_activeCollIndex].funcEnter);
-
- _shouldPushColls = 1;
-
- collStackPos = _collStackSize;
- _vm->_inter->funcBlock(0);
- if (collStackPos != _collStackSize)
- popCollisions();
- _shouldPushColls = 0;
-
- _script->seek(savedPos);
- }
-
- WRITE_VAR(16, 0);
- _activeCollResId = 0;
- }
- while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
-
- if (((uint16) _activeCollResId & ~0x8000) == collResId) {
- collStackPos = 0;
- var_24 = 0;
- var_26 = 1;
- for (i = 0; i < 250; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0x8000) == 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) < 3)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 10)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 8) {
- char *ptr;
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
- while ((ptr = strchr(_tempStr, ' ')) != 0) {
- _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
- ptr = strchr(_tempStr, ' ');
- }
- WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
- }
-
- if (((_collisionAreas[i].flags & 0x0F) >= 5) &&
- ((_collisionAreas[i].flags & 0x0F) <= 8)) {
- str = (char *) descArray[var_24].ptr;
-
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->prepareStr(_tempStr);
-
- int16 pos = 0;
- do {
- strncpy0(_collStr, str, 255);
- pos += strlen(str) + 1;
-
- str += strlen(str) + 1;
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->prepareStr(_collStr);
-
- if (strcmp(_tempStr, _collStr) == 0) {
- WRITE_VAR(17, VAR(17) + 1);
- WRITE_VAR(17 + var_26, 1);
- break;
- }
- } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
- collStackPos++;
- } else {
- WRITE_VAR(17 + var_26, 2);
- }
- var_24++;
- var_26++;
- }
-
- if (collStackPos != (int16) VAR(17))
- WRITE_VAR(17, 0);
- else
- WRITE_VAR(17, 1);
- }
-
- if (!_vm->_inter->_terminate) {
- _script->seek(_collisionAreas[_activeCollIndex].funcLeave);
-
- WRITE_VAR(2, _vm->_global->_inter_mouseX);
- WRITE_VAR(3, _vm->_global->_inter_mouseY);
- WRITE_VAR(4, _mouseButtons);
-
- if (VAR(16) == 0)
- WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]);
- } else
- _script->setFinished(true);
-
- for (curCmd = 0; curCmd < count; curCmd++)
- freeCollision(curCmd + 0x8000);
-}
-
-int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc * inpDesc, int16 *collResId, int16 *collIndex, bool mono) {
- Collision *collArea;
- int16 descInd;
- int16 key;
- int16 found = -1;
- int16 i;
-
- descInd = 0;
- for (i = 0; i < 250; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0x8000) == 0)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- strncpy0(_tempStr, GET_VARO_STR(collArea->key), 255);
-
- _vm->_draw->_destSpriteX = collArea->left;
- _vm->_draw->_destSpriteY = collArea->top;
- _vm->_draw->_spriteRight = collArea->right - collArea->left + 1;
- _vm->_draw->_spriteBottom = collArea->bottom - collArea->top + 1;
-
- _vm->_draw->_destSurface = 21;
-
- _vm->_draw->_backColor = inpDesc[descInd].backColor;
- _vm->_draw->_frontColor = inpDesc[descInd].frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
- _vm->_draw->_destSpriteY +=
- ((collArea->bottom - collArea->top + 1) - 8) / 2;
-
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT);
- descInd++;
- }
-
- for (i = 0; i < 40; i++)
- WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
-
- while (1) {
- descInd = 0;
-
- for (i = 0; i < 250; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0x8000) == 0)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (descInd == *pCurPos) {
- found = i;
- break;
- }
-
- descInd++;
- }
-
- assert(found != -1);
-
- collArea = &_collisionAreas[found];
-
- key = inputArea(collArea->left, collArea->top,
- collArea->right - collArea->left + 1,
- collArea->bottom - collArea->top + 1,
- inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
- GET_VARO_STR(collArea->key), inpDesc[*pCurPos].fontIndex,
- collArea->flags, &time, collResId, collIndex);
-
- if (_vm->_inter->_terminate)
- return 0;
-
- switch (key) {
- case 0:
- if (*collResId == 0)
- return 0;
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) < 3)
- return 0;
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) > 10)
- return 0;
-
- *pCurPos = 0;
- for (i = 0; i < 250; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0x8000) == 0)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (i == *collIndex)
- break;
-
- pCurPos[0]++;
- }
- break;
-
- case 0x3B00:
- case 0x3C00:
- case 0x3D00:
- case 0x3E00:
- case 0x3F00:
- case 0x4000:
- case 0x4100:
- case 0x4200:
- case 0x4300:
- case 0x4400:
- return key;
-
- case 0x1C0D:
-
- if (index == 1)
- return key;
-
- if (*pCurPos == index - 1) {
- *pCurPos = 0;
- break;
- }
-
- pCurPos[0]++;
- break;
-
- case 0x5000:
- if (index - 1 > *pCurPos)
- pCurPos[0]++;
- break;
-
- case 0x4800:
- if (*pCurPos > 0)
- pCurPos[0]--;
- break;
- }
- }
-}
-
-int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex, bool mono) {
- int16 handleMouse;
- uint32 editSize;
- Video::FontDesc *pFont;
- char curSym;
- int16 key;
- const char *str1;
- const char *str2;
- int16 i;
- uint32 pos;
- int16 flag;
- int16 savedKey;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- pos = strlen(str);
- pFont = _vm->_draw->_fonts[fontIndex];
- editSize = width / pFont->itemWidth;
-
- while (1) {
- strncpy0(_tempStr, str, 254);
- strcat(_tempStr, " ");
- if (strlen(_tempStr) > editSize)
- strncpy0(_tempStr, str, 255);
-
- _vm->_draw->_destSpriteX = xPos;
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteRight = editSize * pFont->itemWidth;
- _vm->_draw->_spriteBottom = height;
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
-
- _vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
-
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT);
- if (pos == editSize)
- pos--;
-
- curSym = _tempStr[pos];
-
- flag = 1;
-
- while (1) {
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
-
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = frontColor;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
-
- if (flag != 0)
- key = checkCollisions(handleMouse, -1, collResId, collIndex);
- flag = 0;
-
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if (*pTotTime > 0) {
- *pTotTime -= 300;
- if (*pTotTime <= 1) {
- key = 0;
- *collResId = 0;
- break;
- }
- }
-
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->spriteOperation(DRAW_FILLRECT);
-
- _vm->_draw->_destSpriteY = yPos + (height - 8) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT);
-
- if ((key != 0) || (*collResId != 0))
- break;
-
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if (*pTotTime > 0) {
- *pTotTime -= 300;
- if (*pTotTime <= 1) {
- key = 0;
- *collResId = 0;
- break;
- }
- }
-
- if ((key != 0) || (*collResId != 0))
- break;
-
- if (_vm->_inter->_terminate)
- return 0;
- }
-
- if ((key == 0) || (*collResId != 0) || _vm->_inter->_terminate)
- return 0;
-
- switch (key) {
- case 0x4D00: // Right Arrow
- if ((pos < strlen(str)) && (pos < (editSize - 1))) {
- pos++;
- continue;
- }
- return 0x5000;
-
- case 0x4B00: // Left Arrow
- if (pos > 0) {
- pos--;
- continue;
- }
- return 0x4800;
-
- case 0xE08: // Backspace
- if (pos > 0) {
- _vm->_util->cutFromStr(str, pos - 1, 1);
- pos--;
- continue;
- }
-
- case 0x5300: // Del
-
- if (pos >= strlen(str))
- continue;
-
- _vm->_util->cutFromStr(str, pos, 1);
- continue;
-
- case 0x1C0D: // Enter
- case 0x3B00: // F1
- case 0x3C00: // F2
- case 0x3D00: // F3
- case 0x3E00: // F4
- case 0x3F00: // F5
- case 0x4000: // F6
- case 0x4100: // F7
- case 0x4200: // F8
- case 0x4300: // F9
- case 0x4400: // F10
- case 0x4800: // Up arrow
- case 0x5000: // Down arrow
- return key;
-
- case 0x11B: // Escape
- if (_vm->_global->_useMouse != 0)
- continue;
-
- _forceHandleMouse = !_forceHandleMouse;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- if (_vm->_global->_pressedKeys[1] == 0)
- continue;
-
- while (_vm->_global->_pressedKeys[1] != 0)
- ;
- continue;
-
- default:
-
- savedKey = key;
- key &= 0xFF;
-
- if (((inpType == 9) || (inpType == 10)) &&
- (key >= ' ') && (key <= 0xFF)) {
- str1 = "0123456789-.,+ ";
- str2 = "0123456789-,,+ ";
-
- if (((savedKey >> 8) > 1) && ((savedKey >> 8) < 12))
- key = ((savedKey >> 8) - 1) % 10 + '0';
-
- for (i = 0; str1[i] != 0; i++) {
- if (key == str1[i]) {
- key = str2[i];
- break;
- }
- }
-
- if (i == (int16) strlen(str1))
- key = 0;
- }
-
- if ((key >= ' ') && (key <= 0xFF)) {
- if (editSize == strlen(str))
- _vm->_util->cutFromStr(str, strlen(str) - 1, 1);
-
- if ((key >= 'a') && (key <= 'z'))
- key += ('A' - 'a');
-
- pos++;
- _tempStr[0] = key;
- _tempStr[1] = 0;
-
- _vm->_util->insertStr(_tempStr, str, pos - 1);
- }
-
- }
- }
-}
-
-int16 Game_v1::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
- Collision *ptr;
- int16 i;
-
- if (resId != 0)
- *resId = 0;
-
- *resIndex = 0;
-
- ptr = _collisionAreas;
- for (i = 0; ptr->left != 0xFFFF; ptr++, i++) {
- if (all) {
- if ((ptr->flags & 0xF) > 1)
- continue;
-
- if ((ptr->flags & 0xFF00) != 0)
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
-
- *resIndex = i;
- return ptr->key;
- } else {
- if ((ptr->flags & 0xFF00) != 0)
- continue;
-
- if (((ptr->flags & 0xF) != 1) && ((ptr->flags & 0xF) != 2))
- continue;
-
- if ((((ptr->flags & 0xF0) >> 4) != (_mouseButtons - 1))
- && (((ptr->flags & 0xF0) >> 4) != 2))
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
- *resIndex = i;
- return ptr->key;
- }
- }
-
- if ((_mouseButtons != 1) && (all == 0))
- return 0x11B;
-
- return 0;
-}
-
-} // End of namespace Gob
diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp
deleted file mode 100644
index 08184e73d0..0000000000
--- a/engines/gob/game_v2.cpp
+++ /dev/null
@@ -1,1563 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/endian.h"
-#include "common/stream.h"
-
-#include "gob/gob.h"
-#include "gob/game.h"
-#include "gob/helper.h"
-#include "gob/global.h"
-#include "gob/util.h"
-#include "gob/dataio.h"
-#include "gob/script.h"
-#include "gob/resources.h"
-#include "gob/draw.h"
-#include "gob/goblin.h"
-#include "gob/inter.h"
-#include "gob/mult.h"
-#include "gob/scenery.h"
-#include "gob/video.h"
-#include "gob/videoplayer.h"
-#include "gob/sound/sound.h"
-
-namespace Gob {
-
-Game_v2::Game_v2(GobEngine *vm) : Game_v1(vm) {
-}
-
-void Game_v2::playTot(int16 skipPlay) {
- char savedTotName[20];
- int16 *oldCaptureCounter;
- int16 *oldBreakFrom;
- int16 *oldNestLevel;
- int16 _captureCounter;
- int16 breakFrom;
- int16 nestLevel;
-
- oldNestLevel = _vm->_inter->_nestLevel;
- oldBreakFrom = _vm->_inter->_breakFromLevel;
- oldCaptureCounter = _vm->_scenery->_pCaptureCounter;
-
- _script->push();
-
- _vm->_inter->_nestLevel = &nestLevel;
- _vm->_inter->_breakFromLevel = &breakFrom;
- _vm->_scenery->_pCaptureCounter = &_captureCounter;
- strcpy(savedTotName, _curTotFile);
-
- if (skipPlay <= 0) {
- while (!_vm->shouldQuit()) {
- if (_vm->_inter->_variables)
- _vm->_draw->animateCursor(4);
-
- if (skipPlay != -1) {
- _vm->_inter->initControlVars(1);
-
- for (int i = 0; i < 4; i++) {
- _vm->_draw->_fontToSprite[i].sprite = -1;
- _vm->_draw->_fontToSprite[i].base = -1;
- _vm->_draw->_fontToSprite[i].width = -1;
- _vm->_draw->_fontToSprite[i].height = -1;
- }
-
- _vm->_mult->initAll();
- _vm->_mult->zeroMultData();
-
- _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface;
- _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface;
- _vm->_draw->_cursorSpritesBack = _vm->_draw->_cursorSprites;
- } else
- _vm->_inter->initControlVars(0);
-
- _vm->_draw->_cursorHotspotXVar = -1;
- _totToLoad[0] = 0;
-
- if ((_curTotFile[0] == 0) && (!_script->isLoaded()))
- break;
-
- if (skipPlay == -2) {
- _vm->_vidPlayer->primaryClose();
- skipPlay = 0;
- }
-
- if (!_script->load(_curTotFile)) {
- _vm->_draw->blitCursor();
- _vm->_inter->_terminate = 2;
- break;
- }
-
- _resources->load(_curTotFile);
-
- _vm->_global->_inter_animDataSize = _script->getAnimDataSize();
- if (!_vm->_inter->_variables)
- _vm->_inter->allocateVars(_script->getVariablesCount() & 0xFFFF);
-
- _script->seek(_script->getFunctionOffset(TOTFile::kFunctionStart));
-
- _vm->_inter->renewTimeInVars();
-
- WRITE_VAR(13, _vm->_global->_useMouse);
- WRITE_VAR(14, _vm->_global->_soundFlags);
- WRITE_VAR(15, _vm->_global->_fakeVideoMode);
- WRITE_VAR(16, _vm->_global->_language);
-
- _vm->_inter->callSub(2);
-
- if (_totToLoad[0] != 0)
- _vm->_inter->_terminate = 0;
-
- _vm->_draw->blitInvalidated();
-
- _script->unload();
-
- _resources->unload();
-
- for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++)
- capturePop(0);
-
- if (skipPlay != -1) {
- _vm->_goblin->freeObjects();
-
- _vm->_sound->blasterStop(0);
-
- for (int i = 0; i < Sound::kSoundsCount; i++) {
- SoundDesc *sound = _vm->_sound->sampleGetBySlot(i);
-
- if (sound &&
- ((sound->getType() == SOUND_SND) || (sound->getType() == SOUND_WAV)))
- _vm->_sound->sampleFree(sound);
- }
- }
-
- if (_totToLoad[0] == 0)
- break;
-
- strcpy(_curTotFile, _totToLoad);
- }
- } else {
- _vm->_inter->initControlVars(0);
- _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;
- }
-
- strcpy(_curTotFile, savedTotName);
-
- _vm->_inter->_nestLevel = oldNestLevel;
- _vm->_inter->_breakFromLevel = oldBreakFrom;
- _vm->_scenery->_pCaptureCounter = oldCaptureCounter;
-
- _script->pop();
-}
-
-void Game_v2::clearCollisions() {
- _lastCollKey = 0;
-
- for (int i = 0; i < 150; i++)
- _collisionAreas[i].left = 0xFFFF;
-}
-
-int16 Game_v2::addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub) {
- Collision *ptr;
-
- debugC(5, kDebugCollisions, "addNewCollision");
- debugC(5, kDebugCollisions, "id = %X", id);
- debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d",
- left, top, right, bottom);
- debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key);
- debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d",
- funcEnter, funcLeave);
-
- for (int i = 0; i < 150; i++) {
- if ((_collisionAreas[i].left != 0xFFFF) && (_collisionAreas[i].id != id))
- continue;
-
- ptr = &_collisionAreas[i];
- ptr->id = id;
- ptr->left = left;
- ptr->top = top;
- ptr->right = right;
- ptr->bottom = bottom;
- ptr->flags = flags;
- ptr->key = key;
- ptr->funcEnter = funcEnter;
- ptr->funcLeave = funcLeave;
- ptr->funcSub = funcSub;
- ptr->script = 0;
-
- return i;
- }
- error("Game_v2::addNewCollision(): Collision array full");
- return 0;
-}
-
-void Game_v2::pushCollisions(char all) {
- Collision *srcPtr;
- Collision *destPtr;
- int16 size;
-
- debugC(1, kDebugCollisions, "pushCollisions");
- for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++)
- if (all || (((uint16) srcPtr->id) >= 20))
- size++;
-
- destPtr = new Collision[size];
- _collStack[_collStackSize] = destPtr;
-
- if (_vm->_inter->_terminate)
- return;
-
- _collStackElemSizes[_collStackSize] = size;
-
- if (_shouldPushColls != 0)
- _collStackElemSizes[_collStackSize] |= 0x8000;
-
- _shouldPushColls = 0;
- _collLasts[_collStackSize].key = _lastCollKey;
- _collLasts[_collStackSize].id = _lastCollId;
- _collLasts[_collStackSize].areaIndex = _lastCollAreaIndex;
- _lastCollKey = 0;
- _lastCollId = 0;
- _lastCollAreaIndex = 0;
- _collStackSize++;
-
- for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if (all || (((uint16) srcPtr->id) >= 20)) {
- memcpy(destPtr, srcPtr, sizeof(Collision));
- srcPtr->left = 0xFFFF;
- destPtr++;
- }
- }
-}
-
-void Game_v2::popCollisions(void) {
- Collision *destPtr;
- Collision *srcPtr;
-
- debugC(1, kDebugCollisions, "popCollision");
-
- _collStackSize--;
-
- _shouldPushColls = _collStackElemSizes[_collStackSize] & 0x8000 ? 1 : 0;
- _collStackElemSizes[_collStackSize] &= 0x7FFF;
-
- _lastCollKey = _collLasts[_collStackSize].key;
- _lastCollId = _collLasts[_collStackSize].id;
- _lastCollAreaIndex = _collLasts[_collStackSize].areaIndex;
-
- for (destPtr = _collisionAreas; destPtr->left != 0xFFFF; destPtr++)
- ;
-
- srcPtr = _collStack[_collStackSize];
- memcpy(destPtr, srcPtr,
- _collStackElemSizes[_collStackSize] * sizeof(Collision));
-
- delete[] _collStack[_collStackSize];
-}
-
-int16 Game_v2::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId,
- int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- int16 oldIndex;
- int16 oldId;
- int16 newkey;
- uint32 timeKey;
-
- _scrollHandleMouse = handleMouse != 0;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- if ((_vm->_draw->_cursorIndex == -1) &&
- (handleMouse != 0) && (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- timeKey = _vm->_util->getTimeKey();
- while (1) {
- if (_vm->_inter->_terminate || _vm->shouldQuit()) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- _vm->_video->waitRetrace();
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != 0)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse & 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != 0) {
- if (deltaTime > 0) {
- _vm->_draw->animateCursor(2);
- _vm->_util->delay(deltaTime);
- } else if (handleMouse & 1)
- _vm->_util->waitMouseRelease(1);
- _vm->_draw->animateCursor(-1);
-
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse & 1) &&
- ((deltaTime <= 0) || (_mouseButtons == 0)))
- _vm->_draw->blitCursor();
-
- if ((_lastCollKey != 0) && (key != _lastCollKey))
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- return key;
- }
-
- if (handleMouse & 4)
- return 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- } else if ((_vm->_global->_inter_mouseX != _vm->_draw->_cursorX) ||
- (_vm->_global->_inter_mouseY != _vm->_draw->_cursorY)) {
-
- oldIndex = _lastCollAreaIndex;
- oldId = _lastCollId;
- newkey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (newkey != _lastCollKey) {
- if ((_lastCollKey != 0) && (oldId & 0x8000))
- collAreaSub(oldIndex, 0);
-
- _lastCollKey = newkey;
-
- if ((newkey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
- }
- }
-
- if ((deltaTime < 0) && (key == 0) && (_mouseButtons == 0)) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((curtime + deltaTime) > timeKey) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- _vm->_util->delay(10);
- }
-}
-
-void Game_v2::prepareStart(void) {
- clearCollisions();
-
- _vm->_global->_pPaletteDesc->unused2 = _vm->_draw->_unusedPalette2;
- _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1;
- _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette;
-
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-
- _vm->_draw->initScreen();
- _vm->_video->fillRect(*_vm->_draw->_frontSurface, 0, 0,
- _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1);
-
- _vm->_util->setMousePos(152, 92);
- _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152;
- _vm->_draw->_cursorY = _vm->_global->_inter_mouseY = 92;
-
- _vm->_draw->_invalidatedCount = 0;
- _vm->_draw->_noInvalidated = true;
- _vm->_draw->_applyPal = false;
- _vm->_draw->_paletteCleared = false;
- _vm->_draw->_cursorWidth = 16;
- _vm->_draw->_cursorHeight = 16;
- _vm->_draw->_transparentCursor = 1;
-
- for (int i = 0; i < 40; i++) {
- _vm->_draw->_cursorAnimLow[i] = -1;
- _vm->_draw->_cursorAnimDelays[i] = 0;
- _vm->_draw->_cursorAnimHigh[i] = 0;
- }
-
- _vm->_draw->_renderFlags = 0;
- _vm->_draw->_backDeltaX = 0;
- _vm->_draw->_backDeltaY = 0;
-
- _startTimeKey = _vm->_util->getTimeKey();
-}
-
-void Game_v2::collisionsBlock(void) {
- InputDesc descArray[20];
- int16 array[250];
- byte count;
- int16 collResId;
- int16 curCmd;
- int16 cmd;
- int16 cmdHigh;
- int16 key;
- int16 flags;
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- int16 var_1C;
- int16 index;
- int16 curEditIndex;
- int16 deltaTime;
- int16 stackPos2;
- int16 descIndex;
- int16 timeVal;
- char *str;
- int16 i;
- int16 counter;
- int16 var_24;
- int16 var_26;
- int16 collStackPos;
- Collision *collPtr;
- Collision *collArea;
- int16 timeKey;
- byte collAreaStart;
- uint32 startPos;
- uint32 offsetPos;
-
- if (_shouldPushColls)
- pushCollisions(0);
-
- collAreaStart = 0;
- while (_collisionAreas[collAreaStart].left != 0xFFFF)
- collAreaStart++;
- collArea = &_collisionAreas[collAreaStart];
-
- _shouldPushColls = 0;
- collResId = -1;
-
- _script->skip(1);
- count = _script->readByte();
-
- _handleMouse = _script->readByte();
- deltaTime = 1000 * _script->readByte();
- _script->skip(1);
- stackPos2 = _script->readByte();
- descIndex = _script->readByte();
-
- if ((stackPos2 != 0) || (descIndex != 0))
- deltaTime /= 100;
-
- timeVal = deltaTime;
- _script->skip(1);
-
- startPos = _script->pos();
- WRITE_VAR(16, 0);
-
- var_1C = 0;
- index = 0;
- curEditIndex = 0;
-
- for (curCmd = 0; curCmd < count; curCmd++) {
- array[curCmd] = 0;
- cmd = _script->readByte();
-
- if ((cmd & 0x40) != 0) {
- cmd -= 0x40;
- cmdHigh = _script->readByte();
- cmdHigh <<= 8;
- } else
- cmdHigh = 0;
-
- if ((cmd & 0x80) != 0) {
- offsetPos = _script->pos();
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- } else {
- offsetPos = 0;
- left = _script->readUint16();
- top = _script->readUint16();
- width = _script->readUint16();
- height = _script->readUint16();
- }
-
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
-
- if (left != 0xFFFF) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if (((cmd & 0x3F) < 20) && ((cmd & 0x3F) >= 3)) {
- if (_vm->_draw->_needAdjust != 2)
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(0, 0, &width);
- } else
- _vm->_draw->adjustCoords(0, &height, &width);
- }
-
- cmd &= 0x7F;
- debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd);
-
- switch (cmd) {
- case 0:
- _script->skip(6);
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 1:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
-
- if (key == 0)
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- _vm->_util->clearKeyBuf();
- var_1C = 1;
- key = _script->readVarIndex();
- descArray[index].fontIndex = _script->readInt16();
- descArray[index].backColor = _script->readByte();
- descArray[index].frontColor = _script->readByte();
-
- if ((cmd >= 5) && (cmd <= 8)) {
- descArray[index].ptr = _script->getData() + _script->pos() + 2;
- _script->skip(_script->peekUint16() + 2);
- } else
- descArray[index].ptr = 0;
-
- if (left == 0xFFFF) {
- if ((cmd & 1) == 0) {
- _script->skip(_script->peekUint16(2) + 2);
- }
- break;
- }
-
- if ((cmd & 1) == 0) {
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1,
- top + height - 1, cmd, key, 0,
- _script->pos());
-
- _script->skip(_script->peekUint16(2) + 2);
- } else
- addNewCollision(curCmd + 0x8000, left, top, left + width *
- _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1,
- top + height - 1, cmd, key, 0, 0);
-
- index++;
- break;
-
- case 11:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xE000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 12:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xD000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 20:
- collResId = curCmd;
- // Fall through to case 2
-
- case 2:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key, 0,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 21:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key,
- _script->pos(), 0, offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
- }
- }
-
- _forceHandleMouse = 0;
- _vm->_util->clearKeyBuf();
-
- do {
- if (var_1C != 0) {
- key = multiEdit(deltaTime, index, &curEditIndex, descArray,
- &_activeCollResId, &_activeCollIndex);
-
- WRITE_VAR(55, curEditIndex);
- if (key == 0x1C0D) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 1) != 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) <= 2)
- continue;
-
- _activeCollResId = _collisionAreas[i].id;
- collResId = _collisionAreas[i].id & 0x7FFF;
- _activeCollIndex = i;
- break;
- }
- break;
- }
- } else
- key = checkCollisions(_handleMouse, -deltaTime,
- &_activeCollResId, &_activeCollIndex);
-
- if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
- ((key >> 8) > 1) && ((key >> 8) < 12))
- key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
-
- if (_activeCollResId == 0) {
- if (key != 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key == key) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
-
- if (_activeCollResId == 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key & 0xFF00) != 0)
- continue;
-
- if (_collisionAreas[i].key == 0)
- continue;
-
- if ((adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- _activeCollResId = _collisionAreas[i].id;
- _activeCollIndex = i;
- break;
- }
- }
- }
- } else if (deltaTime != 0) {
- if (stackPos2 != 0) {
- collStackPos = 0;
-
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) != 0x8000)
- continue;
-
- collStackPos++;
- if (collStackPos != stackPos2)
- continue;
-
- _activeCollResId = collPtr->id;
- _activeCollIndex = i + collAreaStart;
- _vm->_inter->storeMouse();
- if (VAR(16) != 0)
- break;
-
- if ((_activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[_activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, _activeCollResId & 0xFFF);
-
- if (collPtr->funcLeave != 0) {
- int16 collResIdBak = _activeCollResId;
- int16 collIndexBak = _activeCollIndex;
-
- timeKey = _vm->_util->getTimeKey();
- collSub(collPtr->funcLeave);
-
- _activeCollResId = collResIdBak;
- _activeCollIndex = collIndexBak;
-
- _vm->_inter->animPalette();
-
- deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey);
-
- if (deltaTime < 2)
- deltaTime = 2;
- if (deltaTime > timeVal)
- deltaTime = timeVal;
- }
-
- if (VAR(16) == 0)
- _activeCollResId = 0;
- break;
- }
- } else {
- if (descIndex != 0) {
-
- counter = 0;
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000)
- if (++counter == descIndex) {
- _activeCollResId = collPtr->id;
- _activeCollIndex = i + collAreaStart;
- break;
- }
- }
-
- } else {
-
- for (i = 0, collPtr = _collisionAreas; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000) {
- _activeCollResId = collPtr->id;
- _activeCollIndex = i;
- break;
- }
- }
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0))
- collSub(_collisionAreas[_lastCollAreaIndex].funcLeave);
- _lastCollKey = 0;
- }
-
- }
- }
- }
-
- if ((_activeCollResId == 0) ||
- (_collisionAreas[_activeCollIndex].funcLeave != 0))
- continue;
-
- _vm->_inter->storeMouse();
- if ((_activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[_activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, _activeCollResId & 0xFFF);
-
- if (_collisionAreas[_activeCollIndex].funcEnter != 0)
- collSub(_collisionAreas[_activeCollIndex].funcEnter);
-
- WRITE_VAR(16, 0);
- _activeCollResId = 0;
- }
- while ((_activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
-
- if ((_activeCollResId & 0xFFF) == collResId) {
- collStackPos = 0;
- var_24 = 0;
- var_26 = 1;
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0xC000) == 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) < 3)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 10)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 8) {
- char *ptr;
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
- while ((ptr = strchr(_tempStr, ' ')))
- _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
- if (_vm->_language == 2)
- while ((ptr = strchr(_tempStr, '.')))
- *ptr = ',';
- WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
- }
-
- if (((_collisionAreas[i].flags & 0x0F) >= 5) &&
- ((_collisionAreas[i].flags & 0x0F) <= 8)) {
- str = (char *) descArray[var_24].ptr;
-
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->prepareStr(_tempStr);
-
- int16 pos = 0;
- do {
- strncpy0(_collStr, str, 255);
- pos += strlen(str) + 1;
-
- str += strlen(str) + 1;
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->prepareStr(_collStr);
-
- if (strcmp(_tempStr, _collStr) == 0) {
- WRITE_VAR(17, VAR(17) + 1);
- WRITE_VAR(17 + var_26, 1);
- break;
- }
- } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
- collStackPos++;
- } else {
- WRITE_VAR(17 + var_26, 2);
- }
- var_24++;
- var_26++;
- }
-
- if (collStackPos != (int16) VAR(17))
- WRITE_VAR(17, 0);
- else
- WRITE_VAR(17, 1);
- }
-
- if (_handleMouse == 1)
- _vm->_draw->blitCursor();
-
- if (!_vm->_inter->_terminate) {
- _script->seek(_collisionAreas[_activeCollIndex].funcLeave);
-
- _vm->_inter->storeMouse();
- if (VAR(16) == 0) {
- if ((_activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[_activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, _activeCollResId & 0xFFF);
- }
- } else
- _script->setFinished(true);
-
- for (curCmd = 0; curCmd < count; curCmd++)
- freeCollision(curCmd + 0x8000);
-
- for (i = 0; i < 150; i++) {
- if (((_collisionAreas[i].id & 0xF000) == 0xA000) ||
- ((_collisionAreas[i].id & 0xF000) == 0x9000))
- _collisionAreas[i].id |= 0x4000;
- }
-}
-
-int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos,
- InputDesc * inpDesc, int16 *collResId, int16 *collIndex, bool mono) {
- Collision *collArea;
- int16 descInd;
- int16 key;
- int16 found = -1;
- int16 i;
- byte *fontExtraBak = 0;
- int16 needAdjust = 0;
-
- descInd = 0;
- for (i = 0; i < 150; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0xC000) != 0x8000)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- strncpy0(_tempStr, GET_VARO_STR(collArea->key), 255);
-
- _vm->_draw->_destSpriteX = collArea->left;
- _vm->_draw->_destSpriteY = collArea->top;
- _vm->_draw->_spriteRight = collArea->right - collArea->left + 1;
- _vm->_draw->_spriteBottom = collArea->bottom - collArea->top + 1;
-
- _vm->_draw->_destSurface = 21;
-
- _vm->_draw->_backColor = inpDesc[descInd].backColor;
- _vm->_draw->_frontColor = inpDesc[descInd].frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = inpDesc[descInd].fontIndex;
-
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = 0;
- }
-
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
-
- _vm->_draw->_destSpriteY += ((collArea->bottom - collArea->top + 1) -
- _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[_vm->_draw->_fontIndex]->extraData = fontExtraBak;
- }
-
- descInd++;
- }
-
- for (i = 0; i < 40; i++)
- WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
-
- while (1) {
- descInd = 0;
-
- for (i = 0; i < 150; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0xC000) != 0x8000)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (descInd == *pCurPos) {
- found = i;
- break;
- }
-
- descInd++;
- }
-
- assert(found != -1);
-
- collArea = &_collisionAreas[found];
-
- key = inputArea(collArea->left, collArea->top,
- collArea->right - collArea->left + 1,
- collArea->bottom - collArea->top + 1,
- inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
- GET_VARO_STR(collArea->key), inpDesc[*pCurPos].fontIndex,
- collArea->flags, &time, collResId, collIndex, mono);
-
- if (_vm->_inter->_terminate)
- return 0;
-
- switch (key) {
- case 0:
- if (*collResId == 0)
- return 0;
-
- if (_mouseButtons != 0) {
- for (collArea = _collisionAreas, i = 0;
- collArea->left != 0xFFFF; collArea++, i++) {
- if ((collArea->flags & 0xF00))
- continue;
-
- if ((collArea->id & 0x4000))
- continue;
-
- if ((collArea->left > _vm->_global->_inter_mouseX) ||
- (collArea->right < _vm->_global->_inter_mouseX) ||
- (collArea->top > _vm->_global->_inter_mouseY) ||
- (collArea->bottom < _vm->_global->_inter_mouseY))
- continue;
-
- if ((collArea->id & 0xF000))
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- *collIndex = i;
- }
- }
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) < 3)
- return 0;
-
- if ((_collisionAreas[*collIndex].flags & 0x0F) > 10)
- return 0;
-
- *pCurPos = 0;
- for (i = 0; i < 150; i++) {
- collArea = &_collisionAreas[i];
-
- if (collArea->left == 0xFFFF)
- continue;
-
- if ((collArea->id & 0xC000) != 0x8000)
- continue;
-
- if ((collArea->flags & 0x0F) < 3)
- continue;
-
- if ((collArea->flags & 0x0F) > 10)
- continue;
-
- if (i != *collIndex)
- pCurPos[0]++;
- }
- break;
-
- case 0x3B00:
- case 0x3C00:
- case 0x3D00:
- case 0x3E00:
- case 0x3F00:
- case 0x4000:
- case 0x4100:
- case 0x4200:
- case 0x4300:
- case 0x4400:
- return key;
-
- case 0x1C0D:
-
- if (index == 1)
- return key;
-
- if (*pCurPos == index - 1) {
- *pCurPos = 0;
- break;
- }
-
- pCurPos[0]++;
- break;
-
- case 0x5000:
- if (index - 1 > *pCurPos)
- pCurPos[0]++;
- break;
-
- case 0x4800:
- if (*pCurPos > 0)
- pCurPos[0]--;
- break;
- }
- }
-}
-
-int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
- int16 backColor, int16 frontColor, char *str, int16 fontIndex,
- char inpType, int16 *pTotTime, int16 *collResId, int16 *collIndex, bool mono) {
- byte handleMouse;
- uint32 editSize;
- Video::FontDesc *pFont;
- char curSym;
- int16 key;
- const char *str1;
- const char *str2;
- int16 i;
- uint32 pos;
- int16 flag;
- int16 savedKey;
- byte *fontExtraBak = 0;
- int16 needAdjust = 0;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- pos = strlen(str);
- pFont = _vm->_draw->_fonts[fontIndex];
- editSize = (!mono && pFont->extraData) ? 0 : (width / pFont->itemWidth);
-
- while (1) {
- strncpy0(_tempStr, str, 254);
- strcat(_tempStr, " ");
- if ((editSize != 0) && strlen(_tempStr) > editSize)
- strncpy0(_tempStr, str, 255);
-
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[fontIndex]->extraData = 0;
- }
-
- _vm->_draw->_destSpriteX = xPos;
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteRight = mono ? (editSize * pFont->itemWidth) : width;
- _vm->_draw->_spriteBottom = height;
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10 );
-
- _vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
- }
-
- if ((editSize != 0) && (pos == editSize))
- pos--;
-
- curSym = _tempStr[pos];
-
- flag = 1;
-
- if (_vm->_inter->_variables)
- WRITE_VAR(56, pos);
-
- while (1) {
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[fontIndex]->extraData = 0;
- }
-
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
-
- if (pFont->extraData) {
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteBottom = height;
- _vm->_draw->_spriteRight = 1;
-
- _vm->_draw->_destSpriteX = xPos;
- for (uint32 j = 0; j < pos; j++)
- _vm->_draw->_destSpriteX += pFont->extraData[str[j] - pFont->startItem];
-
- } else {
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- }
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = frontColor;
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
- }
-
- if (flag != 0) {
- key = checkCollisions(handleMouse, -1, collResId, collIndex);
- if (key == 0)
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
- flag = 0;
- } else
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if (mono) {
- fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
- needAdjust = _vm->_draw->_needAdjust;
- _vm->_draw->_needAdjust = 2;
- _vm->_draw->_fonts[fontIndex]->extraData = 0;
- }
-
- _tempStr[0] = curSym;
- _tempStr[1] = 0;
-
- if (pFont->extraData) {
- _vm->_draw->_destSpriteY = yPos;
- _vm->_draw->_spriteBottom = height;
- _vm->_draw->_spriteRight = 1;
-
- _vm->_draw->_destSpriteX = xPos;
- for (uint32 j = 0; j < pos; j++)
- _vm->_draw->_destSpriteX += pFont->extraData[str[j] - pFont->startItem];
-
- } else {
- _vm->_draw->_destSpriteX = xPos + pFont->itemWidth * pos;
- _vm->_draw->_destSpriteY = yPos + height - 1;
- _vm->_draw->_spriteRight = pFont->itemWidth;
- _vm->_draw->_spriteBottom = 1;
- }
-
- _vm->_draw->_destSurface = 21;
- _vm->_draw->_backColor = backColor;
- _vm->_draw->_frontColor = frontColor;
- _vm->_draw->_textToPrint = _tempStr;
- _vm->_draw->_transparency = 1;
- _vm->_draw->_fontIndex = fontIndex;
- _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10);
-
- _vm->_draw->_destSpriteY = yPos + (height - pFont->itemHeight) / 2;
- _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
-
- if (mono) {
- _vm->_draw->_needAdjust = needAdjust;
- _vm->_draw->_fonts[fontIndex]->extraData = fontExtraBak;
- }
-
- if ((key != 0) || (*collResId != 0))
- break;
-
- key = checkCollisions(handleMouse, -300, collResId, collIndex);
-
- if ((key != 0) || (*collResId != 0) ||
- _vm->_inter->_terminate || _vm->shouldQuit())
- break;
-
- if (*pTotTime > 0) {
- *pTotTime -= 600;
- if (*pTotTime <= 1) {
- key = 0;
- *collResId = 0;
- break;
- }
- }
- }
-
- if ((key == 0) || (*collResId != 0) ||
- _vm->_inter->_terminate || _vm->shouldQuit())
- return 0;
-
- switch (key) {
- case 0x4D00: // Right Arrow
- if ((pos > strlen(str)) || (pos > (editSize - 1)) || (editSize == 0)) {
- pos++;
- continue;
- }
- return 0x5000;
-
- case 0x4B00: // Left Arrow
- if (pos > 0) {
- pos--;
- continue;
- }
- return 0x4800;
-
- case 0xE08: // Backspace
- if (pos > 0) {
- _vm->_util->cutFromStr(str, pos - 1, 1);
- pos--;
- continue;
- } else {
- if (pos < strlen(str))
- _vm->_util->cutFromStr(str, pos, 1);
- }
-
- case 0x5300: // Del
-
- if (pos >= strlen(str))
- continue;
-
- _vm->_util->cutFromStr(str, pos, 1);
- continue;
-
- case 0x1C0D: // Enter
- case 0x3B00: // F1
- case 0x3C00: // F2
- case 0x3D00: // F3
- case 0x3E00: // F4
- case 0x3F00: // F5
- case 0x4000: // F6
- case 0x4100: // F7
- case 0x4200: // F8
- case 0x4300: // F9
- case 0x4400: // F10
- case 0x4800: // Up arrow
- case 0x5000: // Down arrow
- return key;
-
- case 0x11B: // Escape
- if (_vm->_global->_useMouse != 0)
- continue;
-
- _forceHandleMouse = !_forceHandleMouse;
-
- if ((_handleMouse != 0) &&
- ((_vm->_global->_useMouse != 0) || (_forceHandleMouse != 0)))
- handleMouse = 1;
- else
- handleMouse = 0;
-
- while (_vm->_global->_pressedKeys[1] != 0)
- ;
- continue;
-
- default:
-
- savedKey = key;
- key &= 0xFF;
-
- if (((inpType == 9) || (inpType == 10)) &&
- (key >= ' ') && (key <= 0xFF)) {
- str1 = "0123456789-.,+ ";
- str2 = "0123456789-,,+ ";
-
- if ((((savedKey >> 8) > 1) && ((savedKey >> 8) < 12)) &&
- ((_vm->_global->_pressedKeys[42] != 0) ||
- (_vm->_global->_pressedKeys[56] != 0)))
- key = ((savedKey >> 8) - 1) % 10 + '0';
-
- for (i = 0; str1[i] != 0; i++) {
- if (key == str1[i]) {
- key = str2[i];
- break;
- }
- }
-
- if (i == (int16) strlen(str1))
- key = 0;
- }
-
- if ((key >= ' ') && (key <= 0xFF)) {
- if (editSize == 0) {
- int length = _vm->_draw->stringLength(str, fontIndex) +
- pFont->extraData[' ' - pFont->startItem] +
- pFont->extraData[key - pFont->startItem];
-
- if (length > width)
- continue;
-
- if (((int32) strlen(str)) >= (_vm->_global->_inter_animDataSize * 4 - 1))
- continue;
-
- } else {
- if (strlen(str) > editSize)
- continue;
- else if (editSize == strlen(str))
- _vm->_util->cutFromStr(str, strlen(str) - 1, 1);
- }
-
- pos++;
- _tempStr[0] = key;
- _tempStr[1] = 0;
-
- _vm->_util->insertStr(_tempStr, str, pos - 1);
- }
-
- }
- }
-}
-
-int16 Game_v2::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
- Collision *ptr;
- int16 i;
-
- if (resId != 0)
- *resId = 0;
-
- *resIndex = 0;
-
- ptr = _collisionAreas;
- for (i = 0; ptr->left != 0xFFFF; ptr++, i++) {
- if (ptr->id & 0x4000)
- continue;
-
- if (all) {
- if ((ptr->flags & 0xF) > 1)
- continue;
-
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
-
- *resIndex = i;
- return ptr->key;
- } else {
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((ptr->flags & 0xF) < 1)
- continue;
-
- if ((((ptr->flags & 0xF0) >> 4) != (_mouseButtons - 1)) &&
- (((ptr->flags & 0xF0) >> 4) != 2))
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
- *resIndex = i;
- if (((ptr->flags & 0xF) == 1) || ((ptr->flags & 0xF) == 2))
- return ptr->key;
- return 0;
- }
- }
-
- if ((_mouseButtons != 1) && (all == 0))
- return 0x11B;
-
- return 0;
-}
-
-} // End of namespace Gob
diff --git a/engines/gob/game_v6.cpp b/engines/gob/game_v6.cpp
deleted file mode 100644
index 8d40d41acc..0000000000
--- a/engines/gob/game_v6.cpp
+++ /dev/null
@@ -1,1114 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/endian.h"
-#include "common/stream.h"
-#include "common/file.h"
-
-#include "gob/gob.h"
-#include "gob/game.h"
-#include "gob/helper.h"
-#include "gob/global.h"
-#include "gob/script.h"
-#include "gob/resources.h"
-#include "gob/inter.h"
-#include "gob/draw.h"
-
-namespace Gob {
-
-Game_v6::Game_v6(GobEngine *vm) : Game_v2(vm) {
- _someTimeDly = 0;
-}
-
-// flagbits: 5 = freeInterVariables, 6 = skipPlay
-void Game_v6::totSub(int8 flags, const char *newTotFile) {
- int8 curBackupPos;
-
- if ((flags == 16) || (flags == 17))
- warning("Urban Stub: Game_v6::totSub(), flags == %d", flags);
-
- if (_numEnvironments >= Environments::kEnvironmentCount)
- return;
-
- _environments->set(_numEnvironments);
-
- curBackupPos = _curEnvironment;
- _numEnvironments++;
- _curEnvironment = _numEnvironments;
-
- _script = new Script(_vm);
- _resources = new Resources(_vm);
-
- if (flags & 0x80)
- warning("Urban Stub: Game_v6::totSub(), flags & 0x80");
-
- if (flags & 5)
- _vm->_inter->_variables = 0;
-
- strncpy0(_curTotFile, newTotFile, 9);
- strcat(_curTotFile, ".TOT");
-
- if (_vm->_inter->_terminate != 0) {
- clearUnusedEnvironment();
- return;
- }
-
- pushCollisions(0);
-
- if (flags & 6)
- playTot(-1);
- else
- playTot(0);
-
- if (_vm->_inter->_terminate < 2)
- _vm->_inter->_terminate = 0;
-
- clearCollisions();
- popCollisions();
-
- if ((flags & 5) && _vm->_inter->_variables) {
- _vm->_inter->delocateVars();
- }
-
- clearUnusedEnvironment();
-
- _numEnvironments--;
- _curEnvironment = curBackupPos;
- _environments->get(_numEnvironments);
-}
-
-int16 Game_v6::addNewCollision(int16 id, uint16 left, uint16 top,
- uint16 right, uint16 bottom, int16 flags, int16 key,
- uint16 funcEnter, uint16 funcLeave, uint16 funcSub) {
- Collision *ptr;
-
- debugC(5, kDebugCollisions, "addNewCollision");
- debugC(5, kDebugCollisions, "id = %X", id);
- debugC(5, kDebugCollisions, "left = %d, top = %d, right = %d, bottom = %d",
- left, top, right, bottom);
- debugC(5, kDebugCollisions, "flags = %X, key = %X", flags, key);
- debugC(5, kDebugCollisions, "funcEnter = %d, funcLeave = %d",
- funcEnter, funcLeave);
-
- for (int i = 0; i < 150; i++) {
- if ((_collisionAreas[i].left != 0xFFFF) && (_collisionAreas[i].id != id))
- continue;
-
- ptr = &_collisionAreas[i];
-
- if ((ptr->id & 0xBFFF) != (id & 0xBFFF))
- ptr->id = id;
-
- ptr->left = left;
- ptr->top = top;
- ptr->right = right;
- ptr->bottom = bottom;
- ptr->flags = flags;
- ptr->key = key;
- ptr->funcEnter = funcEnter;
- ptr->funcLeave = funcLeave;
- ptr->funcSub = funcSub;
- ptr->script = _script;
-
- return i;
- }
- error("Game_v6::addNewCollision(): Collision array full");
- return 0;
-}
-
-void Game_v6::prepareStart(void) {
- _noCd = false;
-
- if (Common::File::exists("cd1.itk") && Common::File::exists("cd2.itk") &&
- Common::File::exists("cd3.itk") && Common::File::exists("cd4.itk")) {
- _noCd = true;
- }
-
- Game_v2::prepareStart();
-}
-
-void Game_v6::pushCollisions(char all) {
- Collision *srcPtr;
- Collision *destPtr;
- int16 size;
-
- debugC(1, kDebugCollisions, "pushCollisions");
- for (size = 0, srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if ( (all == 1) ||
- ((all == 0) && (((uint16) srcPtr->id) >= 20)) ||
- ((all == 2) && (((srcPtr->id & 0xF000) == 0xD000) ||
- ((srcPtr->id & 0xF000) == 0x4000) ||
- ((srcPtr->id & 0xF000) == 0xE000))))
- size++;
- }
-
- if (_collStackSize >= 5)
- error("Game_v6::pushCollisions: _collStackSize == %d", _collStackSize);
-
- destPtr = new Collision[size];
- _collStack[_collStackSize] = destPtr;
-
- if (_vm->_inter->_terminate)
- return;
-
- _collStackElemSizes[_collStackSize] = size;
-
- if (_shouldPushColls != 0)
- _collStackElemSizes[_collStackSize] |= 0x8000;
-
- _shouldPushColls = 0;
- _collLasts[_collStackSize].key = _lastCollKey;
- _collLasts[_collStackSize].id = _lastCollId;
- _collLasts[_collStackSize].areaIndex = _lastCollAreaIndex;
- _lastCollKey = 0;
- _lastCollId = 0;
- _lastCollAreaIndex = 0;
- _collStackSize++;
-
- for (srcPtr = _collisionAreas; srcPtr->left != 0xFFFF; srcPtr++) {
- if ( (all == 1) ||
- ((all == 0) && (((uint16) srcPtr->id) >= 20)) ||
- ((all == 2) && (((srcPtr->id & 0xF000) == 0xD000) ||
- ((srcPtr->id & 0xF000) == 0x4000) ||
- ((srcPtr->id & 0xF000) == 0xE000)))) {
-
- memcpy(destPtr, srcPtr, sizeof(Collision));
- srcPtr->left = 0xFFFF;
- destPtr++;
- }
- }
-}
-
-int16 Game_v6::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId,
- int16 *pResIndex) {
- int16 resIndex;
- int16 key;
- uint32 timeKey;
-
- _scrollHandleMouse = handleMouse != 0;
-
- if (deltaTime >= -1) {
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if (pResId != 0)
- *pResId = 0;
-
- resIndex = 0;
-
- if ((_lastCollKey != 0) &&
- ( (_collisionAreas[_lastCollAreaIndex].id != _lastCollId) ||
- (_collisionAreas[_lastCollAreaIndex].key != _lastCollKey))) {
-
- _lastCollKey = 0;
- _lastCollAreaIndex = 0;
- _lastCollId = 0;
- }
-
- if ((_vm->_draw->_cursorIndex == -1) &&
- (handleMouse != 0) && (_lastCollKey == 0)) {
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- }
-
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- timeKey = _vm->_util->getTimeKey();
- _vm->_draw->blitInvalidated();
- while (1) {
- if (_vm->_inter->_terminate || _vm->shouldQuit()) {
- if (handleMouse)
- _vm->_draw->blitCursor();
- return 0;
- }
-
- collSubReenter();
- if (!_vm->_draw->_noInvalidated) {
- if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
- else
- _vm->_draw->blitInvalidated();
- _vm->_video->waitRetrace();
- }
-
- key = checkKeys(&_vm->_global->_inter_mouseX,
- &_vm->_global->_inter_mouseY, &_mouseButtons, handleMouse);
-
- if ((handleMouse == 0) && (_mouseButtons != 0)) {
- _vm->_util->waitMouseRelease(0);
- key = 3;
- }
-
- if (key != 0) {
-
- if (handleMouse & 1)
- _vm->_draw->blitCursor();
-
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- if (key != 0)
- return key;
-
- if (handleMouse)
- _vm->_draw->animateCursor(-1);
- }
-
- if (handleMouse != 0) {
- if (_mouseButtons != 0) {
-
- if (deltaTime > 0) {
- _vm->_draw->animateCursor(2);
- _vm->_util->delay(deltaTime);
- } else if (handleMouse & 1)
- _vm->_util->waitMouseRelease(1);
-
- _vm->_draw->animateCursor(-1);
-
- if (pResId != 0)
- *pResId = 0;
-
- key = checkMousePoint(0, pResId, &resIndex);
- if (pResIndex != 0)
- *pResIndex = resIndex;
-
- if ((key != 0) || ((pResId != 0) && (*pResId != 0))) {
- if ((handleMouse & 1) &&
- ((deltaTime <= 0) || (_mouseButtons == 0)))
- _vm->_draw->blitCursor();
-
- if (key != _lastCollKey)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = 0;
- return key;
- }
-
- if (handleMouse & 4)
- return 0;
-
- if (_lastCollKey != 0)
- collAreaSub(_lastCollAreaIndex, 0);
-
- _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
- } else
- collSubReenter();
- }
-
- if ((deltaTime == -2) && (key == 0) && (_mouseButtons == 0)) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
-
- } else if (handleMouse != 0)
- _vm->_draw->animateCursor(-1);
-
- if ((deltaTime < 0) && (key == 0) && (_mouseButtons == 0)) {
- uint32 curtime = _vm->_util->getTimeKey();
- if ((curtime + deltaTime) > timeKey) {
- if (pResId != 0)
- *pResId = 0;
-
- if (pResIndex != 0)
- *pResIndex = 0;
-
- return 0;
- }
- }
-
- _vm->_util->delay(10);
- }
-}
-
-void Game_v6::collisionsBlock(void) {
- InputDesc descArray[20];
- int16 array[300];
- byte count;
- int16 collResId;
- int16 curCmd;
- int16 cmd;
- int16 cmdHigh;
- int16 key;
- int16 flags;
- uint16 left;
- uint16 top;
- uint16 width;
- uint16 height;
- int16 deltaTime;
- int16 stackPos2;
- int16 descIndex;
- int16 timeVal;
- char *str;
- int16 i;
- int16 counter;
- int16 var_24;
- int16 var_26;
- int16 collStackPos;
- Collision *collPtr;
- Collision *collArea;
- byte collAreaStart;
- int16 activeCollResId = 0;
- int16 activeCollIndex = 0;
- uint32 startPos;
- uint32 offsetPos;
-
- if (_shouldPushColls)
- pushCollisions(0);
-
- collAreaStart = 0;
- while (_collisionAreas[collAreaStart].left != 0xFFFF)
- collAreaStart++;
- collArea = &_collisionAreas[collAreaStart];
-
- _shouldPushColls = 0;
- collResId = -1;
-
- _script->skip(1);
- count = _script->readByte();
-
- _handleMouse = _script->peekByte(0);
- deltaTime = 1000 * _script->peekByte(1);
- stackPos2 = _script->peekByte(3);
- descIndex = _script->peekByte(4);
- byte var_42 = _script->peekByte(5);
-
- if ((stackPos2 != 0) || (descIndex != 0)) {
- deltaTime /= 100;
- if (_script->peekByte(1) == 100)
- deltaTime = 2;
- }
-
- timeVal = deltaTime;
- _script->skip(6);
-
- startPos = _script->pos();
- WRITE_VAR(16, 0);
-
- byte var_41 = 0;
- int16 var_46 = 0;
- int16 var_1C = 0;
- int16 index = 0;
- int16 curEditIndex = 0;
- int right = 0, funcLeave = 0;
-
- for (curCmd = 0; curCmd < count; curCmd++) {
- array[curCmd] = 0;
- cmd = _script->readByte();
-
- if ((cmd & 0x40) != 0) {
- cmd -= 0x40;
- cmdHigh = _script->readByte();
- cmdHigh <<= 8;
- } else
- cmdHigh = 0;
-
- if ((cmd & 0x80) != 0) {
- offsetPos = _script->pos();
- left = _script->readValExpr();
- top = _script->readValExpr();
- width = _script->readValExpr();
- height = _script->readValExpr();
- } else {
- offsetPos = 0;
- left = _script->readUint16();
- top = _script->readUint16();
- width = _script->readUint16();
- height = _script->readUint16();
- }
-
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
-
- if (left != 0xFFFF) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if (((cmd & 0x3F) < 20) && ((cmd & 0x3F) >= 3)) {
- if (_vm->_draw->_needAdjust != 2)
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(0, 0, &width);
- } else
- _vm->_draw->adjustCoords(0, &height, &width);
- }
-
- cmd &= 0x7F;
- debugC(1, kDebugCollisions, "collisionsBlock(%d)", cmd);
-
- switch (cmd) {
- case 0:
- _script->skip(6);
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 1:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- startPos = _script->pos();
- _script->skip(_script->peekUint16(2) + 2);
-
- if (key == 0)
- key = curCmd + 0xA000;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmd + cmdHigh, key, startPos,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 3:
- case 4:
- case 5:
- case 6:
- case 7:
- case 8:
- case 9:
- case 10:
- _vm->_util->clearKeyBuf();
- var_1C = 1;
- key = _script->readVarIndex();
- descArray[index].fontIndex = _script->readInt16();
- descArray[index].backColor = _script->readByte();
- descArray[index].frontColor = _script->readByte();
-
- if ((cmd >= 5) && (cmd <= 8)) {
- descArray[index].ptr = _script->getData() + _script->pos() + 2;
- _script->skip(_script->peekUint16() + 2);
- } else
- descArray[index].ptr = 0;
-
- if (left == 0xFFFF) {
- if ((cmd & 1) == 0) {
- _script->skip(_script->peekUint16(2) + 2);
- }
- break;
- }
-
- right = left + width - 1;
- if (!_vm->_draw->_fonts[descArray[index].fontIndex]->extraData)
- right = left + width * _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1;
-
- funcLeave = 0;
- if (!(cmd & 1))
- funcLeave = _script->pos();
-
- addNewCollision(curCmd + 0x8000, left, top, right,
- top + height - 1, cmd, key, 0, funcLeave, 0);
-
- if (!(cmd & 1)) {
- _script->skip(_script->peekUint16(2) + 2);
- }
-
- index++;
- break;
-
- case 11:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xE000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 12:
- _script->skip(6);
- for (i = 0; i < 150; i++) {
- if ((_collisionAreas[i].id & 0xF000) == 0xD000) {
- _collisionAreas[i].id &= 0xBFFF;
- _collisionAreas[i].funcEnter =
- _script->pos();
- _collisionAreas[i].funcLeave =
- _script->pos();
- }
- }
- _script->skip(_script->peekUint16(2) + 2);
- break;
-
- case 20:
- collResId = curCmd;
- // Fall through to case 2
-
- case 2:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16();
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key, 0,
- _script->pos(), offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
-
- case 21:
- key = _script->readInt16();
- array[curCmd] = _script->readInt16();
- flags = _script->readInt16() & 3;
-
- addNewCollision(curCmd + 0x8000, left, top,
- left + width - 1, top + height - 1,
- (flags << 4) + cmdHigh + 2, key,
- _script->pos(), 0, offsetPos);
-
- _script->skip(_script->peekUint16(2) + 2);
-
- break;
- }
- }
-
- if (var_42 != 0)
- setCollisions(1);
-
- _forceHandleMouse = 0;
- _vm->_util->clearKeyBuf();
-
- do {
- if (var_1C != 0) {
- key = multiEdit(deltaTime, index, &curEditIndex, descArray,
- &activeCollResId, &activeCollIndex, false);
-
- WRITE_VAR(55, curEditIndex);
- if (key == 0x1C0D) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 1) != 0)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) <= 2)
- continue;
-
- activeCollResId = _collisionAreas[i].id;
- collResId = _collisionAreas[i].id & 0x7FFF;
- activeCollIndex = i;
- break;
- }
- break;
- }
- } else
- key = checkCollisions(_handleMouse, -deltaTime,
- &activeCollResId, &activeCollIndex);
-
- if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
- ((key >> 8) > 1) && ((key >> 8) < 12))
- key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
-
- if (activeCollResId == 0) {
- if (key != 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key == key) ||
- (_collisionAreas[i].key == 0x7FFF)) {
- activeCollResId = _collisionAreas[i].id;
- activeCollIndex = i;
- break;
- }
- }
-
- if (activeCollResId == 0) {
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- break;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].key & 0xFF00) != 0)
- continue;
-
- if (_collisionAreas[i].key == 0)
- continue;
-
- if (adjustKey(key & 0xFF) == adjustKey(_collisionAreas[i].key)) {
- activeCollResId = _collisionAreas[i].id;
- activeCollIndex = i;
- break;
- }
- }
- }
- } else if (deltaTime != 0) {
- if (stackPos2 != 0) {
- collStackPos = 0;
-
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) != 0x8000)
- continue;
-
- collStackPos++;
- if (collStackPos != stackPos2)
- continue;
-
- activeCollResId = collPtr->id;
- activeCollIndex = i + collAreaStart;
- _vm->_inter->storeMouse();
- if (VAR(16) != 0)
- break;
-
- if ((activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, activeCollResId & 0xFFF);
-
- if (collPtr->funcLeave != 0) {
- uint32 timeKey = _vm->_util->getTimeKey();
- collSub(collPtr->funcLeave);
-
- if (timeVal != 2) {
- deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey);
-
- if ((deltaTime - var_46) < 3) {
- var_46 -= (deltaTime - 3);
- deltaTime = 3;
- } else if (var_46 != 0) {
- deltaTime -= var_46;
- var_46 = 0;
- }
-
- if (deltaTime > timeVal)
- deltaTime = timeVal;
-
- } else
- deltaTime = 2;
-
- }
-
- if (VAR(16) == 0)
- activeCollResId = 0;
- else
- var_41 = 1;
-
- break;
- }
- } else {
- if (descIndex != 0) {
-
- counter = 0;
- for (i = 0, collPtr = collArea; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000)
- if (++counter == descIndex) {
- activeCollResId = collPtr->id;
- activeCollIndex = i + collAreaStart;
- break;
- }
- }
-
- } else {
-
- for (i = 0, collPtr = _collisionAreas; collPtr->left != 0xFFFF; i++, collPtr++) {
- if ((collPtr->id & 0xF000) == 0x8000) {
- activeCollResId = collPtr->id;
- activeCollIndex = i;
- break;
- }
- }
- if ((_lastCollKey != 0) &&
- (_collisionAreas[_lastCollAreaIndex].funcLeave != 0))
- collSub(_collisionAreas[_lastCollAreaIndex].funcLeave);
-
- _lastCollKey = 0;
- }
-
- }
- }
- }
-
- if (var_41 != 0)
- break;
-
- if ((activeCollResId == 0) ||
- (_collisionAreas[activeCollIndex].funcLeave != 0))
- continue;
-
- _vm->_inter->storeMouse();
- if ((activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, activeCollResId & 0xFFF);
-
- if (_collisionAreas[activeCollIndex].funcEnter != 0)
- collSub(_collisionAreas[activeCollIndex].funcEnter);
-
- WRITE_VAR(16, 0);
- activeCollResId = 0;
- }
- while ((activeCollResId == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
-
- if ((activeCollResId & 0xFFF) == collResId) {
- collStackPos = 0;
- var_24 = 0;
- var_26 = 1;
- for (i = 0; i < 150; i++) {
- if (_collisionAreas[i].left == 0xFFFF)
- continue;
-
- if ((_collisionAreas[i].id & 0xC000) != 0x8000)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) < 3)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 10)
- continue;
-
- if ((_collisionAreas[i].flags & 0x0F) > 8) {
- char *ptr;
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
- while ((ptr = strchr(_tempStr, ' ')))
- _vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
- if (_vm->_language == 2)
- while ((ptr = strchr(_tempStr, '.')))
- *ptr = ',';
- WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
- }
-
- if (((_collisionAreas[i].flags & 0x0F) >= 5) &&
- ((_collisionAreas[i].flags & 0x0F) <= 8)) {
- str = (char *) descArray[var_24].ptr;
-
- strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->prepareStr(_tempStr);
-
- int16 pos = 0;
- do {
- strncpy0(_collStr, str, 255);
- pos += strlen(str) + 1;
-
- str += strlen(str) + 1;
-
- if ((_collisionAreas[i].flags & 0x0F) < 7)
- _vm->_util->prepareStr(_collStr);
-
- if (strcmp(_tempStr, _collStr) == 0) {
- WRITE_VAR(17, VAR(17) + 1);
- WRITE_VAR(17 + var_26, 1);
- break;
- }
- } while (READ_LE_UINT16(descArray[var_24].ptr - 2) > pos);
- collStackPos++;
- } else {
- WRITE_VAR(17 + var_26, 2);
- }
- var_24++;
- var_26++;
- }
-
- if (collStackPos != (int16) VAR(17))
- WRITE_VAR(17, 0);
- else
- WRITE_VAR(17, 1);
- }
-
- if (_handleMouse == 1)
- _vm->_draw->blitCursor();
-
- if (!_vm->_inter->_terminate && (var_41 == 0)) {
- _script->seek(_collisionAreas[activeCollIndex].funcLeave);
-
- _vm->_inter->storeMouse();
- if (VAR(16) == 0) {
- if ((activeCollResId & 0xF000) == 0x8000)
- WRITE_VAR(16, array[activeCollResId & 0xFFF]);
- else
- WRITE_VAR(16, activeCollResId & 0xFFF);
- }
- } else
- _script->setFinished(true);
-
- for (curCmd = 0; curCmd < count; curCmd++)
- freeCollision(curCmd + 0x8000);
-
- for (i = 0; i < 150; i++) {
- if (((_collisionAreas[i].id & 0xF000) == 0xA000) ||
- ((_collisionAreas[i].id & 0xF000) == 0x9000))
- _collisionAreas[i].id |= 0x4000;
- }
-}
-
-void Game_v6::setCollisions(byte arg_0) {
- for (Collision *collArea = _collisionAreas; collArea->left != 0xFFFF; collArea++) {
- if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0))
- continue;
-
- if (arg_0 == 0)
- if (collArea->flags & 0x80)
- continue;
-
- Script *curScript = _script;
-
- _script = collArea->script;
- if (!_script)
- _script = curScript;
-
- _script->call(collArea->funcSub);
-
- int16 left = _script->readValExpr();
- int16 top = _script->readValExpr();
- int16 width = _script->readValExpr();
- int16 height = _script->readValExpr();
- uint16 flags = 0;
-
- if ((collArea->id & 0xF000) == 0xA000)
- flags = _script->readValExpr();
-
- if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) &&
- (left != -1)) {
- left += _vm->_draw->_backDeltaX;
- top += _vm->_draw->_backDeltaY;
- }
- if (_vm->_draw->_needAdjust != 2) {
- _vm->_draw->adjustCoords(0, &left, &top);
- if ((collArea->flags & 0x0F) < 3)
- _vm->_draw->adjustCoords(2, &width, &height);
- else {
- height &= 0xFFFE;
- _vm->_draw->adjustCoords(2, 0, &height);
- }
- }
-
- if (left < 0) {
- width += left;
- left = 0;
- }
-
- if (top < 0) {
- height += top;
- top = 0;
- }
-
- collArea->left = left;
- collArea->top = top;
- collArea->right = left + width - 1;
- collArea->bottom = top + height - 1;
-
- if ((collArea->id & 0xF000) == 0xA000)
- collArea->flags = flags;
-
- _script->pop();
-
- _script = curScript;
- }
-}
-
-void Game_v6::collSub(uint16 offset) {
- int16 collStackSize;
-
- uint32 savedPos = _script->pos();
-
- _script->seek(offset);
-
- _shouldPushColls = 1;
- collStackSize = _collStackSize;
-
- _vm->_inter->funcBlock(0);
-
- if (collStackSize != _collStackSize)
- popCollisions();
-
- _shouldPushColls = 0;
-
- _script->seek(savedPos);
-
- if ((_vm->_util->getTimeKey() - _someTimeDly) > 500)
- setCollisions(0);
-}
-
-static const byte adjustTable[] = {
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x81, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x40, 0x40, 0x40, 0x40, 0x20,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-int16 Game_v6::adjustKey(int16 key) {
- if (key == -1)
- return -1;
-
- if (adjustTable[key & 0xFF] & 8)
- return ((key & 0xFF) - 0x20);
-
- return key & 0xFF;
-}
-
-int16 Game_v6::checkMousePoint(int16 all, int16 *resId, int16 *resIndex) {
- Collision *ptr;
- int16 i;
-
- if (resId != 0)
- *resId = 0;
-
- *resIndex = 0;
-
- ptr = _collisionAreas;
- for (i = 0; ptr->left != 0xFFFF; ptr++, i++) {
- if (ptr->id & 0x4000)
- continue;
-
- if (all) {
- if ((ptr->flags & 0xF) > 1)
- continue;
-
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
-
- *resIndex = i;
- return ptr->key;
- } else {
- if ((ptr->flags & 0xF00) != 0)
- continue;
-
- if ((ptr->flags & 0xF) < 1)
- continue;
-
- if ((((ptr->flags & 0x70) >> 4) != (_mouseButtons - 1)) &&
- (((ptr->flags & 0x70) >> 4) != 2))
- continue;
-
- if ((_vm->_global->_inter_mouseX < ptr->left) ||
- (_vm->_global->_inter_mouseX > ptr->right) ||
- (_vm->_global->_inter_mouseY < ptr->top) ||
- (_vm->_global->_inter_mouseY > ptr->bottom))
- continue;
-
- if (resId != 0)
- *resId = ptr->id;
- *resIndex = i;
- if (((ptr->flags & 0xF) == 1) || ((ptr->flags & 0xF) == 2))
- return ptr->key;
- return 0;
- }
- }
-
- if ((_mouseButtons != 1) && (all == 0))
- return 0x11B;
-
- return 0;
-}
-
-void Game_v6::collSubReenter() {
- int16 lastCollAreaIndex = _lastCollAreaIndex;
- int16 lastCollId = _lastCollId;
- int16 collKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex);
-
- if (collKey == _lastCollKey)
- return;
-
- if ((_lastCollKey != 0) && (lastCollId & 0x8000))
- collAreaSub(lastCollAreaIndex, 0);
-
- _lastCollKey = collKey;
-
- if ((_lastCollKey != 0) && (_lastCollId & 0x8000))
- collAreaSub(_lastCollAreaIndex, 1);
-}
-
-} // End of namespace Gob
diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp
index 4165938966..2969ed0870 100644
--- a/engines/gob/global.cpp
+++ b/engines/gob/global.cpp
@@ -123,6 +123,8 @@ Global::Global(GobEngine *vm) : _vm(vm) {
_inter_mouseY = 0;
_speedFactor = 1;
+
+ _noCd = false;
}
Global::~Global() {
diff --git a/engines/gob/global.h b/engines/gob/global.h
index 982ce113cb..7849490107 100644
--- a/engines/gob/global.h
+++ b/engines/gob/global.h
@@ -141,6 +141,8 @@ public:
// Can be 1, 2 or 3 for normal, double and triple speed, respectively
uint8 _speedFactor;
+ bool _noCd;
+
Global(GobEngine *vm);
~Global();
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index e534464cce..8605dfbd52 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -126,7 +126,7 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst) {
Common::addDebugChannel(kDebugSaveLoad, "SaveLoad", "Saving/Loading debug level");
Common::addDebugChannel(kDebugGraphics, "Graphics", "Graphics debug level");
Common::addDebugChannel(kDebugVideo, "Video", "IMD/VMD video debug level");
- Common::addDebugChannel(kDebugCollisions, "Collisions", "Collisions debug level");
+ Common::addDebugChannel(kDebugHotspots, "Hotspots", "Hotspots debug level");
Common::addDebugChannel(kDebugDemo, "Demo", "Demo script debug level");
syst->getEventManager()->registerRandomSource(_rnd, "gob");
@@ -331,6 +331,7 @@ bool GobEngine::initGameParts() {
_palAnim = new PalAnim(this);
_vidPlayer = new VideoPlayer(this);
_sound = new Sound(this);
+ _game = new Game(this);
switch (_gameType) {
case kGameTypeGeisha:
@@ -341,7 +342,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_v1(this);
_mult = new Mult_v1(this);
_draw = new Draw_v1(this);
- _game = new Game_v1(this);
_map = new Map_v1(this);
_goblin = new Goblin_v1(this);
_scenery = new Scenery_v1(this);
@@ -353,7 +353,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_Fascination(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
- _game = new Game_Fascination(this);
_map = new Map_v2(this);
_goblin = new Goblin_v2(this);
_scenery = new Scenery_v2(this);
@@ -367,7 +366,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_v2(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
- _game = new Game_v2(this);
_map = new Map_v2(this);
_goblin = new Goblin_v2(this);
_scenery = new Scenery_v2(this);
@@ -380,7 +378,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_Bargon(this);
_mult = new Mult_v2(this);
_draw = new Draw_Bargon(this);
- _game = new Game_v2(this);
_map = new Map_v2(this);
_goblin = new Goblin_v2(this);
_scenery = new Scenery_v2(this);
@@ -394,7 +391,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_v3(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
- _game = new Game_v2(this);
_map = new Map_v2(this);
_goblin = new Goblin_v3(this);
_scenery = new Scenery_v2(this);
@@ -407,7 +403,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_v3(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
- _game = new Game_v2(this);
_map = new Map_v2(this);
_goblin = new Goblin_v3(this);
_scenery = new Scenery_v2(this);
@@ -420,7 +415,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_v4(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
- _game = new Game_v2(this);
_map = new Map_v4(this);
_goblin = new Goblin_v4(this);
_scenery = new Scenery_v2(this);
@@ -436,7 +430,6 @@ bool GobEngine::initGameParts() {
_inter = new Inter_v5(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
- _game = new Game_v2(this);
_map = new Map_v4(this);
_goblin = new Goblin_v4(this);
_scenery = new Scenery_v2(this);
@@ -445,12 +438,11 @@ bool GobEngine::initGameParts() {
case kGameTypeAdibou4:
case kGameTypeUrban:
- _init = new Init_v3(this);
+ _init = new Init_v6(this);
_video = new Video_v6(this);
_inter = new Inter_v6(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
- _game = new Game_v6(this);
_map = new Map_v4(this);
_goblin = new Goblin_v4(this);
_scenery = new Scenery_v2(this);
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index 5d1cb3ecf2..5047382316 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -133,7 +133,7 @@ enum {
kDebugSaveLoad = 1 << 7,
kDebugGraphics = 1 << 8,
kDebugVideo = 1 << 9,
- kDebugCollisions = 1 << 10,
+ kDebugHotspots = 1 << 10,
kDebugDemo = 1 << 11
};
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
new file mode 100644
index 0000000000..b717bd76df
--- /dev/null
+++ b/engines/gob/hotspots.cpp
@@ -0,0 +1,1928 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "gob/hotspots.h"
+#include "gob/global.h"
+#include "gob/helper.h"
+#include "gob/draw.h"
+#include "gob/game.h"
+#include "gob/script.h"
+#include "gob/inter.h"
+
+namespace Gob {
+
+Hotspots::Hotspot::Hotspot() {
+ clear();
+}
+
+Hotspots::Hotspot::Hotspot(uint16 i,
+ uint16 l, uint16 t, uint16 r, uint16 b, uint16 f, uint16 k,
+ uint16 enter, uint16 leave, uint16 pos) {
+
+ id = i;
+ left = l;
+ top = t;
+ right = r;
+ bottom = b;
+ flags = f;
+ key = k;
+ funcEnter = enter;
+ funcLeave = leave;
+ funcPos = pos;
+ script = 0;
+}
+
+void Hotspots::Hotspot::clear() {
+ id = 0;
+ left = 0xFFFF;
+ top = 0;
+ right = 0;
+ bottom = 0;
+ flags = 0;
+ key = 0;
+ funcEnter = 0;
+ funcLeave = 0;
+ funcPos = 0;
+ script = 0;
+}
+
+Hotspots::Type Hotspots::Hotspot::getType() const {
+ return (Type) (flags & 0xF);
+}
+
+MouseButtons Hotspots::Hotspot::getButton() const {
+ uint8 buttonBits = ((flags & 0x70) >> 4);
+
+ if (buttonBits == 0)
+ return kMouseButtonsLeft;
+ if (buttonBits == 1)
+ return kMouseButtonsRight;
+ if (buttonBits == 2)
+ return kMouseButtonsAny;
+
+ return kMouseButtonsNone;
+}
+
+uint8 Hotspots::Hotspot::getWindow() const {
+ return (flags & 0x0F00) >> 8;
+}
+
+uint8 Hotspots::Hotspot::getCursor() const {
+ return (flags & 0xF000) >> 12;
+}
+
+uint8 Hotspots::Hotspot::getState(uint16 id) {
+ return (id & 0xF000) >> 12;
+}
+
+uint8 Hotspots::Hotspot::getState() const {
+ return getState(id);
+}
+
+bool Hotspots::Hotspot::isEnd() const {
+ return (left == 0xFFFF);
+}
+
+bool Hotspots::Hotspot::isInput() const {
+ if (getType() < kTypeInput1NoLeave)
+ return false;
+
+ if (getType() > kTypeInputFloatLeave)
+ return false;
+
+ return true;
+}
+
+bool Hotspots::Hotspot::isActiveInput() const {
+ if (isEnd())
+ return false;
+
+ if (!isFilledEnabled())
+ return false;
+
+ if (!isInput())
+ return false;
+
+ return true;
+}
+
+bool Hotspots::Hotspot::isFilled() const {
+ return getState() & kStateFilled;
+}
+
+bool Hotspots::Hotspot::isFilledEnabled() const {
+ return (getState() & kStateFilledDisabled) == kStateFilled;
+}
+
+bool Hotspots::Hotspot::isFilledNew() const {
+ return getState() == kStateFilled;
+}
+
+bool Hotspots::Hotspot::isDisabled() const {
+ return getState() & kStateDisabled;
+}
+
+bool Hotspots::Hotspot::isIn(uint16 x, uint16 y) const {
+ if (x < left)
+ return false;
+ if (x > right)
+ return false;
+ if (y < top)
+ return false;
+ if (y > bottom)
+ return false;
+
+ return true;
+}
+
+bool Hotspots::Hotspot::buttonMatch(MouseButtons button) const {
+ MouseButtons myButton = getButton();
+
+ if (myButton == kMouseButtonsAny)
+ // Any button allowed
+ return true;
+
+ if (myButton == kMouseButtonsNone)
+ // No button allowed
+ return false;
+
+ if (myButton == button)
+ // Exact match
+ return true;
+
+ return false;
+}
+
+void Hotspots::Hotspot::disable() {
+ id |= (kStateDisabled << 12);
+}
+
+void Hotspots::Hotspot::enable() {
+ id &= ~(kStateDisabled << 12);
+}
+
+
+Hotspots::Hotspots(GobEngine *vm) : _vm(vm) {
+ _hotspots = new Hotspot[kHotspotCount];
+
+ _shouldPush = false;
+
+ _currentKey = 0;
+ _currentIndex = 0;
+ _currentId = 0;
+}
+
+Hotspots::~Hotspots() {
+ delete[] _hotspots;
+
+ // Pop the whole stack and free each element's memory
+ while (!_stack.empty()) {
+
+ StackEntry backup = _stack.pop();
+
+ delete[] backup.hotspots;
+ }
+}
+
+void Hotspots::clear() {
+ _currentKey = 0;
+
+ for (int i = 0; i < kHotspotCount; i++)
+ _hotspots[i].clear();
+}
+
+uint16 Hotspots::add(uint16 id,
+ uint16 left, uint16 top, uint16 right, uint16 bottom,
+ uint16 flags, uint16 key,
+ uint16 funcEnter, uint16 funcLeave, uint16 funcPos) {
+
+ Hotspot hotspot(id, left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+
+ return add(hotspot);
+}
+
+uint16 Hotspots::add(const Hotspot &hotspot) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ // free space => add same id => update
+ if (! (spot.isEnd() || (spot.id == hotspot.id)))
+ continue;
+
+ // When updating, keep disabled state intact
+ uint16 id = hotspot.id;
+ if ((spot.id & ~(kStateDisabled << 12)) ==
+ (hotspot.id & ~(kStateDisabled << 12)))
+ id = spot.id;
+
+ // Set
+ spot = hotspot;
+ spot.id = id;
+
+ // Remember the current script
+ spot.script = _vm->_game->_script;
+
+ debugC(1, kDebugHotspots, "Adding hotspot %03d: %3d+%3d+%3d+%3d - %04X, %04X, %04X - %5d, %5d, %5d",
+ i, spot.left, spot.top, spot.right, spot.bottom,
+ spot.id, spot.key, spot.flags, spot.funcEnter, spot.funcLeave, spot.funcPos);
+
+ return i;
+ }
+
+ error("Hotspots::add(): Hotspot array full");
+ return 0xFFFF;
+}
+
+void Hotspots::remove(uint16 id) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ if (_hotspots[i].id == id) {
+ debugC(1, kDebugHotspots, "Removing hotspot %d: %X", i, id);
+ _hotspots[i].clear();
+ }
+ }
+}
+
+void Hotspots::removeState(uint8 state) {
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.getState() == state) {
+ debugC(1, kDebugHotspots, "Removing hotspot %d: %X (by state %X)", i, spot.id, state);
+ spot.clear();
+ }
+ }
+}
+
+void Hotspots::recalculate(bool force) {
+ debugC(5, kDebugHotspots, "Recalculating hotspots");
+
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (!force && ((spot.flags & 0x80) != 0))
+ // Not forcing a special hotspot
+ continue;
+
+ if (spot.funcPos == 0)
+ // Simple coordinates don't need update
+ continue;
+
+ // Setting the needed script
+ Script *curScript = _vm->_game->_script;
+
+ _vm->_game->_script = spot.script;
+ if (!_vm->_game->_script)
+ _vm->_game->_script = curScript;
+
+ // Calling the function that contains the positions
+ _vm->_game->_script->call(spot.funcPos);
+
+ // Calculate positions
+ int16 left = _vm->_game->_script->readValExpr();
+ int16 top = _vm->_game->_script->readValExpr();
+ int16 width = _vm->_game->_script->readValExpr();
+ int16 height = _vm->_game->_script->readValExpr();
+
+ // Re-read the flags too, if applicable
+ uint16 flags = 0;
+ if (spot.getState() == (kStateFilled | kStateType2))
+ flags = _vm->_game->_script->readValExpr();
+
+ // Apply backDelta, if needed
+ if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != -1)) {
+ left += _vm->_draw->_backDeltaX;
+ top += _vm->_draw->_backDeltaY;
+ }
+
+ // Clamping
+ if (left < 0) {
+ width += left;
+ left = 0;
+ }
+ if (top < 0) {
+ height += top;
+ top = 0;
+ }
+
+ // Set the updated position
+ spot.left = left;
+ spot.top = top;
+ spot.right = left + width - 1;
+ spot.bottom = top + height - 1;
+
+ if (spot.getState() == (kStateFilled | kStateType2))
+ spot.flags = flags;
+
+ // Return
+ _vm->_game->_script->pop();
+
+ _vm->_game->_script = curScript;
+ }
+}
+
+void Hotspots::push(uint8 all, bool force) {
+ debugC(1, kDebugHotspots, "Pushing hotspots (%d, %d)", all, force);
+
+ // Should we push at all?
+ if (!_shouldPush && !force)
+ return;
+
+ // Count the hotspots
+ uint32 size = 0;
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ // Save all of them
+ if ( (all == 1) ||
+ // Don't save the global ones
+ ((all == 0) && (spot.id >= 20)) ||
+ // Only save disabled ones
+ ((all == 2) && ((spot.getState() == (kStateFilledDisabled | kStateType1)) ||
+ (spot.getState() == (kStateDisabled)) ||
+ (spot.getState() == (kStateFilledDisabled | kStateType2))))) {
+ size++;
+ }
+
+ }
+
+ StackEntry backup;
+
+ backup.shouldPush = _shouldPush;
+ backup.size = size;
+ backup.key = _currentKey;
+ backup.id = _currentId;
+ backup.index = _currentIndex;
+
+ backup.hotspots = new Hotspot[size];
+
+ // Copy the hotspots
+ Hotspot *destPtr = backup.hotspots;
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ // Save all of them
+ if ( (all == 1) ||
+ // Don't save the global ones
+ ((all == 0) && (spot.id >= 20)) ||
+ // Only save disabled ones
+ ((all == 2) && ((spot.getState() == (kStateFilledDisabled | kStateType1)) ||
+ (spot.getState() == (kStateDisabled)) ||
+ (spot.getState() == (kStateFilledDisabled | kStateType2))))) {
+
+ memcpy(destPtr, &spot, sizeof(Hotspot));
+ destPtr++;
+
+ spot.clear();
+ }
+
+ }
+
+ // Reset current state
+ _shouldPush = false;
+ _currentKey = 0;
+ _currentId = 0;
+ _currentIndex = 0;
+
+ _stack.push(backup);
+}
+
+void Hotspots::pop() {
+ debugC(1, kDebugHotspots, "Popping hotspots");
+
+ assert(!_stack.empty());
+
+ StackEntry backup = _stack.pop();
+
+ // Find the end of the filled hotspot space
+ int i;
+ Hotspot *destPtr = _hotspots;
+ for (i = 0; i < kHotspotCount; i++, destPtr++)
+ if (destPtr->isEnd())
+ break;
+
+ if (((uint32) (kHotspotCount - i)) < backup.size)
+ error("Hotspots::pop(): Not enough free space in the current Hotspot "
+ "array to pop %d elements (got %d)", backup.size, kHotspotCount - i);
+
+ // Copy
+ memcpy(destPtr, backup.hotspots, backup.size * sizeof(Hotspot));
+
+ _shouldPush = backup.shouldPush;
+ _currentKey = backup.key;
+ _currentId = backup.id;
+ _currentIndex = backup.index;
+
+ delete[] backup.hotspots;
+}
+
+bool Hotspots::isValid(uint16 key, uint16 id, uint16 index) const {
+ if (index >= kHotspotCount)
+ return false;
+
+ if (key == 0)
+ return false;
+
+ if (!(Hotspot::getState(id) & kStateFilled))
+ return false;
+
+ return true;
+}
+
+void Hotspots::call(uint16 offset) {
+ debugC(4, kDebugHotspots, "Calling hotspot function %d", offset);
+
+ _vm->_game->_script->call(offset);
+
+ _shouldPush = true;
+
+ int16 stackSize = _stack.size();
+
+ _vm->_inter->funcBlock(0);
+
+ while (stackSize != _stack.size())
+ pop();
+
+ _shouldPush = false;
+
+ _vm->_game->_script->pop();
+
+ recalculate(false);
+}
+
+void Hotspots::enter(uint16 index) {
+ debugC(2, kDebugHotspots, "Entering hotspot %d", index);
+
+ if (index >= kHotspotCount) {
+ warning("Hotspots::enter(): Index %d out of range", index);
+ return;
+ }
+
+ Hotspot &spot = _hotspots[index];
+
+ // If requested, write the ID into a variable
+ if ((spot.getState() == (kStateFilled | kStateType1)) ||
+ (spot.getState() == (kStateFilled | kStateType2)))
+ WRITE_VAR(17, -(spot.id & 0x0FFF));
+
+ if (spot.funcEnter != 0)
+ call(spot.funcEnter);
+}
+
+void Hotspots::leave(uint16 index) {
+ debugC(2, kDebugHotspots, "Leaving hotspot %d", index);
+
+ if (index >= kHotspotCount) {
+ warning("Hotspots::leave(): Index %d out of range", index);
+ return;
+ }
+
+ Hotspot &spot = _hotspots[index];
+
+ // If requested, write the ID into a variable
+ if ((spot.getState() == (kStateFilled | kStateType1)) ||
+ (spot.getState() == (kStateFilled | kStateType2)))
+ WRITE_VAR(17, spot.id & 0x0FFF);
+
+ if (spot.funcLeave != 0)
+ call(spot.funcLeave);
+}
+
+uint16 Hotspots::checkMouse(Type type, uint16 &id, uint16 &index) const {
+ id = 0;
+ index = 0;
+
+ if (type == kTypeMove) {
+ // Check where the mouse was moved to
+
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.isDisabled())
+ // Only consider enabled hotspots
+ continue;
+
+ if (spot.getType() > kTypeMove)
+ // Only consider click and move hotspots
+ continue;
+
+ if (spot.getWindow() != 0)
+ // Only check the main window
+ continue;
+
+ if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+ // If we're not in it, ignore it
+ continue;
+
+ id = spot.id;
+ index = i;
+
+ return spot.key;
+ }
+
+ return 0;
+
+ } else if (type == kTypeClick) {
+ // Check if something was clicked
+
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.isDisabled())
+ // Only consider enabled hotspots
+ continue;
+
+ if (spot.getWindow() != 0)
+ // Only check the main window
+ continue;
+
+ if (spot.getType() < kTypeMove)
+ // Only consider hotspots that can be clicked
+ continue;
+
+ if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+ // If we're not in it, ignore it
+ continue;
+
+ if (!spot.buttonMatch(_vm->_game->_mouseButtons))
+ // Don't follow hotspots with button requirements we don't meet
+ continue;
+
+ id = spot.id;
+ index = i;
+
+ if ((spot.getType() == kTypeMove) || (spot.getType() == kTypeClick))
+ // It's a move or click => return the key
+ return spot.key;
+
+ // Otherwise, the key has a different meaning, so ignore it
+ return 0;
+ }
+
+ if (_vm->_game->_mouseButtons != kMouseButtonsLeft)
+ // Let the right mouse button act as an escape key
+ return kKeyEscape;
+
+ return 0;
+
+ }
+
+ return 0;
+}
+
+bool Hotspots::checkHotspotChanged() {
+ uint16 key, id, index;
+
+ // Get the current hotspot
+ key = checkMouse(kTypeMove, id, index);
+
+ if (key == _currentKey)
+ // Nothing changed => nothing to do
+ return false;
+
+ // Leave the old area
+ if (isValid(_currentKey, _currentId,_currentIndex))
+ leave(_currentIndex);
+
+ _currentKey = key;
+ _currentId = id;
+ _currentIndex = index;
+
+ // Enter the new one
+ if (isValid(key, id, index))
+ enter(index);
+
+ return true;
+}
+
+uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index) {
+ _vm->_game->_scrollHandleMouse = handleMouse != 0;
+
+ if (delay >= -1) {
+ _currentKey = 0;
+ _currentId = 0;
+ _currentIndex = 0;
+ }
+
+ id = 0;
+ index = 0;
+
+ if (handleMouse) {
+ if ((_vm->_draw->_cursorIndex == -1) && (_currentKey == 0)) {
+ // Last know state: No hotspot hit. Look if that changed
+
+ _currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
+
+ if (isValid(_currentKey, _currentId, _currentIndex))
+ enter(_currentIndex);
+ }
+
+ _vm->_draw->animateCursor(-1);
+ }
+
+ uint32 startTime = _vm->_util->getTimeKey();
+
+ // Update display
+ _vm->_draw->blitInvalidated();
+ _vm->_video->retrace();
+
+ uint16 key = 0;
+ while (key == 0) {
+
+ if (_vm->_inter->_terminate || _vm->shouldQuit()) {
+ if (handleMouse)
+ _vm->_draw->blitCursor();
+ return 0;
+ }
+
+ // Anything changed?
+ checkHotspotChanged();
+
+ // Update display
+ if (!_vm->_draw->_noInvalidated) {
+ if (handleMouse)
+ _vm->_draw->animateCursor(-1);
+ else
+ _vm->_draw->blitInvalidated();
+ _vm->_video->waitRetrace();
+ }
+
+ // Update keyboard and mouse state
+ key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX,
+ &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, handleMouse);
+
+ if (!handleMouse && (_vm->_game->_mouseButtons != kMouseButtonsNone)) {
+ // We don't want any mouse input but got one => Wait till it went away
+
+ _vm->_util->waitMouseRelease(0);
+ key = 3;
+ }
+
+ if (key != 0) {
+ // Got a key press
+
+ if (handleMouse & 1)
+ _vm->_draw->blitCursor();
+
+ id = 0;
+ index = 0;
+
+ // Leave the current hotspot
+ if (isValid(_currentKey, _currentId, _currentIndex))
+ leave(_currentIndex);
+
+ _currentKey = 0;
+ break;
+ }
+
+ if (handleMouse) {
+
+ if (_vm->_game->_mouseButtons != kMouseButtonsNone) {
+ // Mouse button pressed
+
+ if (delay > 0) {
+ // If a delay was requested, wait the specified time
+
+ _vm->_draw->animateCursor(2);
+ _vm->_util->delay(delay);
+ } else if (handleMouse & 1)
+ _vm->_util->waitMouseRelease(1);
+
+ _vm->_draw->animateCursor(-1);
+
+ // Which region was clicked?
+ key = checkMouse(kTypeClick, id, index);
+
+ if ((key != 0) || (id != 0)) {
+ // Got a valid region
+
+ if ( (handleMouse & 1) &&
+ ((delay <= 0) || (_vm->_game->_mouseButtons == kMouseButtonsNone)))
+ _vm->_draw->blitCursor();
+
+ // If the hotspot changed, leave the old one
+ if (key != _currentKey)
+ leave(_currentIndex);
+
+ _currentKey = 0;
+ break;
+ }
+
+ if (handleMouse & 4)
+ // Nothing further than one simple check was requested => return
+ return 0;
+
+ // Leave the current area
+ if (_currentKey != 0)
+ leave(_currentIndex);
+
+ // No click, but do we have a move event? If so, enter that hotspot
+ _currentKey = checkMouse(kTypeMove, _currentId, _currentIndex);
+ if (isValid(_currentKey, _currentId, _currentIndex))
+ enter(_currentIndex);
+
+ } else
+ // No mouse button pressed, check whether the position changed at least
+ checkHotspotChanged();
+ }
+
+ if ((delay == -2) && (key == 0) &&
+ (_vm->_game->_mouseButtons == kMouseButtonsNone)) {
+ // Nothing found and no further handling requested. Return.
+
+ id = 0;
+ index = 0;
+ break;
+ }
+
+ if (handleMouse)
+ _vm->_draw->animateCursor(-1);
+
+ if ((delay < 0) && (key == 0) &&
+ (_vm->_game->_mouseButtons == kMouseButtonsNone)) {
+
+ // Look if we've maybe reached the timeout
+
+ uint32 curTime = _vm->_util->getTimeKey();
+ if ((curTime + delay) > startTime) {
+ // If so, return
+
+ id = 0;
+ index = 0;
+ break;
+ }
+
+ }
+
+ // Sleep for a short amount of time
+ _vm->_util->delay(10);
+
+ }
+
+ return key;
+}
+
+uint16 Hotspots::check(uint8 handleMouse, int16 delay) {
+ uint16 id, index;
+
+ // Check and ignore the id and index
+ return Hotspots::check(handleMouse, delay, id, index);
+}
+
+uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
+ uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex,
+ Type type, int16 &duration, uint16 &id, uint16 &index) {
+
+ if ((fontIndex >= 8) || !_vm->_draw->_fonts[fontIndex]) {
+ warning("Hotspots::updateInput(): Invalid font specified: %d", fontIndex);
+ return 0;
+ }
+
+ // Check if we need to consider mouse events
+ bool handleMouse = false;
+ if ( (_vm->_game->_handleMouse != 0) &&
+ ((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0)))
+ handleMouse = true;
+
+ const Video::FontDesc &font = *_vm->_draw->_fonts[fontIndex];
+
+ // The font doesn't specify individual character widths => monospaced
+ bool monoSpaced = (font.charWidths == 0);
+
+ // Current position in the string, preset to the end
+ uint32 pos = strlen(str);
+ /* Size of input field in characters.
+ * If the font is not monospaced, we can't know that */
+ uint32 editSize = monoSpaced ? (width / font.itemWidth) : 0;
+
+ uint16 key = 0;
+ char tempStr[256];
+
+ while (1) {
+ // If we the edit field has enough space, add a space for the new character
+ strncpy0(tempStr, str, 254);
+ strcat(tempStr, " ");
+ if ((editSize != 0) && strlen(tempStr) > editSize)
+ strncpy0(tempStr, str, 255);
+
+ // Clear input area
+ fillRect(xPos, yPos,
+ monoSpaced ? (editSize * font.itemWidth) : width, height,
+ backColor);
+
+ // Print the current string, vertically centered
+ printText(xPos, yPos + (height - font.itemHeight) / 2,
+ tempStr, fontIndex, frontColor);
+
+ // If we've reached the end of the input field, set the cursor to the last character
+ if ((editSize != 0) && (pos == editSize))
+ pos--;
+
+ // The character under the cursor
+ char curSym = tempStr[pos];
+
+ if (_vm->_inter->_variables)
+ WRITE_VAR(56, pos);
+
+ bool first = true;
+ while (1) {
+ tempStr[0] = curSym;
+ tempStr[1] = 0;
+
+ // Draw cursor
+ uint16 cursorX, cursorY, cursorWidth, cursorHeight;
+ getTextCursorPos(font, str, pos, xPos, yPos, width, height,
+ cursorX, cursorY, cursorWidth, cursorHeight);
+ fillRect(cursorX, cursorY, cursorWidth, cursorHeight, frontColor);
+
+ if (first) {
+ // The first time, purge old information too
+ key = check(handleMouse, -1, id, index);
+
+ if (key == 0)
+ // We didn't catch any input, let's try again with a real timeout
+ key = check(handleMouse, -300, id, index);
+
+ first = false;
+ } else
+ // Try to catch a character
+ key = check(handleMouse, -300, id, index);
+
+ tempStr[0] = curSym;
+ tempStr[1] = 0;
+
+ // Clear cursor
+ getTextCursorPos(font, str, pos, xPos, yPos, width, height,
+ cursorX, cursorY, cursorWidth, cursorHeight);
+ fillRect(cursorX, cursorY, cursorWidth, cursorHeight, backColor);
+
+ // Print the current string, vertically centered
+ printText(cursorX, yPos + (height - font.itemHeight) / 2,
+ tempStr, fontIndex, frontColor);
+
+ if ((key != 0) || (id != 0))
+ // We did get a key, stop looking
+ break;
+
+ // Try again
+ key = check(handleMouse, -300, id, index);
+
+ if ((key != 0) || (id != 0) ||
+ _vm->_inter->_terminate || _vm->shouldQuit())
+ // We did get a key, stop looking
+ break;
+
+ if (duration > 0) {
+ // Look if we reached the time limit
+ duration -= 600;
+ if (duration <= 1) {
+ // If so, abort
+ key = 0;
+ id = 0;
+ break;
+ }
+ }
+ }
+
+ if ((key == 0) || (id != 0) ||
+ _vm->_inter->_terminate || _vm->shouldQuit())
+ // Got no key, or a region ID instead, return
+ return 0;
+
+ switch (key) {
+ case kKeyRight:
+ // If possible, move the cursor right
+ if ((pos > strlen(str)) || (pos > (editSize - 1)) || (editSize == 0)) {
+ pos++;
+ continue;
+ }
+ // Continue downwards instead
+ return kKeyDown;
+
+ case kKeyLeft:
+ // If possible, move the cursor left
+ if (pos > 0) {
+ pos--;
+ continue;
+ }
+ // Continue upwards instead
+ return kKeyUp;
+
+ case kKeyBackspace:
+ if (pos > 0) {
+ // Delete the character to the left
+ _vm->_util->cutFromStr(str, pos - 1, 1);
+ pos--;
+ continue;
+ } else {
+ if (pos < strlen(str))
+ // Delete the character to the right
+ _vm->_util->cutFromStr(str, pos, 1);
+ }
+
+ case kKeyDelete:
+ if (pos >= strlen(str))
+ continue;
+
+ // Delete the character to the right
+ _vm->_util->cutFromStr(str, pos, 1);
+ continue;
+
+ case kKeyReturn:
+ case kKeyF1:
+ case kKeyF2:
+ case kKeyF3:
+ case kKeyF4:
+ case kKeyF5:
+ case kKeyF6:
+ case kKeyF7:
+ case kKeyF8:
+ case kKeyF9:
+ case kKeyF10:
+ case kKeyUp:
+ case kKeyDown:
+ return key;
+
+ case kKeyEscape:
+ // If we got an escape event, wait until the mouse buttons have been released
+ if (_vm->_global->_useMouse != 0)
+ continue;
+
+ _vm->_game->_forceHandleMouse = !_vm->_game->_forceHandleMouse;
+
+ handleMouse = false;
+ if ( (_vm->_game->_handleMouse != 0) &&
+ ((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0)))
+ handleMouse = true;
+
+ while (_vm->_global->_pressedKeys[1] != 0);
+ continue;
+
+ default:
+ // Got a "normal" key
+
+ uint16 savedKey = key;
+
+ key &= 0xFF;
+
+ if (((type == kTypeInputFloatNoLeave) || (type == kTypeInputFloatLeave)) &&
+ (key >= ' ') && (key <= 0xFF)) {
+
+ // Only allow character found in numerical floating values
+
+ const char *str1 = "0123456789-.,+ ";
+ const char *str2 = "0123456789-,,+ ";
+
+ if ((((savedKey >> 8) > 1) && ((savedKey >> 8) < 12)) &&
+ ((_vm->_global->_pressedKeys[42] != 0) ||
+ (_vm->_global->_pressedKeys[56] != 0)))
+ key = ((savedKey >> 8) - 1) % 10 + '0';
+
+ int i;
+ for (i = 0; str1[i] != 0; i++) {
+ if (key == str1[i]) {
+ key = str2[i];
+ break;
+ }
+ }
+
+ if (i == (int16) strlen(str1))
+ key = 0;
+ }
+
+ if ((key >= ' ') && (key <= 0xFF)) {
+ if (editSize == 0) {
+ // Length of the string + current character + next one
+ int length = _vm->_draw->stringLength(str, fontIndex) +
+ font.charWidths[' ' - font.startItem] +
+ font.charWidths[key - font.startItem];
+
+ if (length > width)
+ // We're above the limit, ignore the key
+ continue;
+
+ if (((int32) strlen(str)) >= (_vm->_global->_inter_animDataSize * 4 - 1))
+ // Above the limit of character allowed in a string, ignore the key
+ continue;
+
+ } else {
+ if (strlen(str) > editSize)
+ // We're over the upper character limit for this field
+ continue;
+ else if (editSize == strlen(str))
+ // We've reached the upper limit, overwrite the last character
+ _vm->_util->cutFromStr(str, strlen(str) - 1, 1);
+ }
+
+ // Advance cursor
+ pos++;
+ tempStr[0] = key;
+ tempStr[1] = 0;
+
+ // Add character
+ _vm->_util->insertStr(tempStr, str, pos - 1);
+ }
+
+ }
+ }
+}
+
+uint16 Hotspots::handleInputs(int16 time, uint16 inputCount, uint16 &curInput,
+ InputDesc *inputs, uint16 &id, uint16 &index) {
+
+ // Redraw all texts in all inputs we currently manage
+ updateAllTexts(inputs);
+
+ for (int i = 0; i < 40; i++)
+ WRITE_VAR(17 + i, 0);
+
+ while (1) {
+ // Find the hotspot index to our current input
+ uint16 hotspotIndex = inputToHotspot(curInput);
+
+ assert(hotspotIndex != 0xFFFF);
+
+ Hotspot inputSpot = _hotspots[hotspotIndex];
+
+ // Handle input events from that input field
+ uint16 key = updateInput(inputSpot.left, inputSpot.top,
+ inputSpot.right - inputSpot.left + 1,
+ inputSpot.bottom - inputSpot.top + 1,
+ inputs[curInput].backColor, inputs[curInput].frontColor,
+ GET_VARO_STR(inputSpot.key), inputs[curInput].fontIndex,
+ inputSpot.getType(), time, id, index);
+
+ if (_vm->_inter->_terminate)
+ return 0;
+
+ switch (key) {
+ case kKeyNone:
+ if (id == 0)
+ // No key and no hotspot => return
+ return 0;
+
+ if (_vm->_game->_mouseButtons != kMouseButtonsNone)
+ // Clicked something, get the hotspot index
+ index = findClickedInput(index);
+
+ if (!_hotspots[index].isInput())
+ // It's no input, return
+ return 0;
+
+ // Get the associated input index
+ curInput = hotspotToInput(index);
+ break;
+
+ case kKeyF1:
+ case kKeyF2:
+ case kKeyF3:
+ case kKeyF4:
+ case kKeyF5:
+ case kKeyF6:
+ case kKeyF7:
+ case kKeyF8:
+ case kKeyF9:
+ case kKeyF10:
+ return key;
+
+ case kKeyReturn:
+ // Just one input => return
+ if (inputCount == 1)
+ return kKeyReturn;
+
+ // End of input chain reached => wrap
+ if (curInput == (inputCount - 1)) {
+ curInput = 0;
+ break;
+ }
+
+ // Next input
+ curInput++;
+ break;
+
+ case kKeyDown:
+ // Next input
+ if ((inputCount - 1) > curInput)
+ curInput++;
+ break;
+
+ case kKeyUp:
+ // Previous input
+ if (curInput > 0)
+ curInput--;
+ break;
+ }
+ }
+}
+
+void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs,
+ uint16 &validId, bool &hasInput, uint16 &inputCount) {
+
+ ids[i] = 0;
+
+ // Type and window
+ byte type = _vm->_game->_script->readByte();
+ byte window = 0;
+
+ if ((type & 0x40) != 0) {
+ // Got a window ID
+
+ type -= 0x40;
+ window = _vm->_game->_script->readByte();
+ }
+
+ // Coordinates
+ uint16 left, top, width, height, right, bottom;
+ uint32 funcPos = 0;
+ if ((type & 0x80) != 0) {
+ // Complex coordinate expressions
+ funcPos = _vm->_game->_script->pos();
+ left = _vm->_game->_script->readValExpr();
+ top = _vm->_game->_script->readValExpr();
+ width = _vm->_game->_script->readValExpr();
+ height = _vm->_game->_script->readValExpr();
+ } else {
+ // Immediate values
+ funcPos = 0;
+ left = _vm->_game->_script->readUint16();
+ top = _vm->_game->_script->readUint16();
+ width = _vm->_game->_script->readUint16();
+ height = _vm->_game->_script->readUint16();
+ }
+ type &= 0x7F;
+
+ // Apply global drawing offset
+ if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) {
+ left += _vm->_draw->_backDeltaX;
+ top += _vm->_draw->_backDeltaY;
+ }
+
+ right = left + width - 1;
+ bottom = top + height - 1;
+
+ // Enabling the hotspots again
+ if ((type == kTypeEnable2) || (type == kTypeEnable1)) {
+ uint8 wantedState = 0;
+ if (type == kTypeEnable2)
+ wantedState = kStateFilledDisabled | kStateType2;
+ else
+ wantedState = kStateFilledDisabled | kStateType1;
+
+ _vm->_game->_script->skip(6);
+
+ for (int j = 0; j < kHotspotCount; j++) {
+ Hotspot &spot = _hotspots[j];
+
+ if (spot.getState() == wantedState) {
+ spot.enable();
+ spot.funcEnter = _vm->_game->_script->pos();
+ spot.funcLeave = _vm->_game->_script->pos();
+ }
+ }
+
+ _vm->_game->_script->skipBlock();
+
+ return;
+ }
+
+ int16 key = 0;
+ int16 flags = 0;
+ Video::FontDesc *font = 0;
+ uint32 funcEnter = 0, funcLeave = 0;
+
+ // Evaluate parameters for the new hotspot
+ switch (type) {
+ case kTypeNone:
+ _vm->_game->_script->skip(6);
+
+ funcEnter = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ key = i + ((kStateFilled | kStateType2) << 12);
+ flags = type + (window << 8);
+ break;
+
+ case kTypeMove:
+ key = _vm->_game->_script->readInt16();
+ ids[i] = _vm->_game->_script->readInt16();
+ flags = _vm->_game->_script->readInt16();
+
+ funcEnter = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ if (key == 0)
+ key = i + ((kStateFilled | kStateType2) << 12);
+
+ flags = type + (window << 8) + (flags << 4);
+ break;
+
+ case kTypeInput1NoLeave:
+ case kTypeInput1Leave:
+ case kTypeInput2NoLeave:
+ case kTypeInput2Leave:
+ case kTypeInput3NoLeave:
+ case kTypeInput3Leave:
+ case kTypeInputFloatNoLeave:
+ case kTypeInputFloatLeave:
+ hasInput = true;
+
+ _vm->_util->clearKeyBuf();
+
+ // Input text parameters
+ key = _vm->_game->_script->readVarIndex();
+ inputs[inputCount].fontIndex = _vm->_game->_script->readInt16();
+ inputs[inputCount].backColor = _vm->_game->_script->readByte();
+ inputs[inputCount].frontColor = _vm->_game->_script->readByte();
+ inputs[inputCount].length = 0;
+ inputs[inputCount].str = 0;
+
+ if ((type >= kTypeInput2NoLeave) && (type <= kTypeInput3Leave)) {
+ uint16 length = _vm->_game->_script->readUint16();
+
+ inputs[inputCount].str =
+ (const char *) (_vm->_game->_script->getData() + _vm->_game->_script->pos());
+
+ _vm->_game->_script->skip(length);
+ }
+
+ if (left == 0xFFFF) {
+ if (!(type & 1))
+ // No coordinates but a leave block => skip it
+ _vm->_game->_script->skipBlock();
+ break;
+ }
+
+ font = _vm->_draw->_fonts[inputs[inputCount].fontIndex];
+ if (!font->charWidths)
+ // Monospaced font
+ right = left + width * font->itemWidth - 1;
+
+ funcEnter = 0;
+ funcPos = 0;
+ funcLeave = 0;
+ if (!(type & 1)) {
+ // Got a leave
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+ }
+
+ flags = type;
+
+ inputCount++;
+ break;
+
+ case 20:
+ validId = i;
+ // Fall through to case 2
+ case kTypeClick:
+ key = _vm->_game->_script->readInt16();
+ ids[i] = _vm->_game->_script->readInt16();
+ flags = _vm->_game->_script->readInt16();
+
+ funcEnter = 0;
+
+ funcLeave = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ flags = ((uint16) kTypeClick) + (window << 8) + (flags << 4);
+ break;
+
+ case kTypeClickEnter:
+ key = _vm->_game->_script->readInt16();
+ ids[i] = _vm->_game->_script->readInt16();
+ flags = _vm->_game->_script->readInt16() & 3;
+
+ funcEnter = _vm->_game->_script->pos();
+ _vm->_game->_script->skipBlock();
+
+ funcLeave = 0;
+
+ flags = ((uint16) kTypeClick) + (window << 8) + (flags << 4);
+ break;
+ }
+
+ // Add the new hotspot
+ add(i | (kStateFilled << 12), left, top, right, bottom,
+ flags, key, funcEnter, funcLeave, funcPos);
+}
+
+void Hotspots::evaluate() {
+ InputDesc inputs[20];
+ uint16 ids[kHotspotCount];
+ int16 counter;
+ int16 var_24;
+ int16 var_26;
+ int16 collStackPos;
+
+ // Push all local hotspots
+ push(0);
+
+ // Find the current end of the hotspot block
+ uint16 endIndex = 0;
+ while (!_hotspots[endIndex].isEnd())
+ endIndex++;
+
+ _shouldPush = false;
+
+ _vm->_game->_script->skip(1);
+
+ // Number of new hotspots
+ byte count = _vm->_game->_script->readByte();
+
+ // Parameters of this block
+ _vm->_game->_handleMouse = _vm->_game->_script->peekByte(0);
+ int16 duration = _vm->_game->_script->peekByte(1);
+ byte stackPos2 = _vm->_game->_script->peekByte(3);
+ byte descIndex = _vm->_game->_script->peekByte(4);
+ bool needRecalculation = _vm->_game->_script->peekByte(5) != 0;
+
+ // Seconds -> Milliseconds
+ duration *= 1000;
+
+ if ((stackPos2 != 0) || (descIndex != 0)) {
+ duration /= 100;
+ if (_vm->_game->_script->peekByte(1) == 100)
+ duration = 2;
+ }
+
+ int16 timeVal = duration;
+
+ _vm->_game->_script->skip(6);
+
+ // Clear current ID
+ WRITE_VAR(16, 0);
+
+ byte var_41 = 0;
+ int16 var_46 = 0;
+
+ uint16 id = 0;
+ uint16 validId = 0xFFFF;
+ uint16 index = 0;
+
+ bool hasInput = false;
+ uint16 inputCount = 0;
+
+ // Adding new hotspots
+ for (uint16 i = 0; i < count; i++)
+ evaluateNew(i, ids, inputs, validId, hasInput, inputCount);
+
+ // Recalculate all hotspots if requested
+ if (needRecalculation)
+ recalculate(true);
+
+ _vm->_game->_forceHandleMouse = 0;
+ _vm->_util->clearKeyBuf();
+
+ do {
+ uint16 key = 0;
+ if (hasInput) {
+ // Input
+
+ uint16 curInput = 0;
+
+ key = handleInputs(duration, inputCount, curInput, inputs, id, index);
+
+ // Notify the script of the current input index
+ WRITE_VAR(55, curInput);
+ if (key == kKeyReturn) {
+ // Return pressed, invoke input leave
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (!spot.isFilledEnabled())
+ // Not filled or disabled
+ continue;
+
+ if ((spot.getType() & 1) != 0)
+ // Not an input with a leave function
+ continue;
+
+ if (spot.getType() <= kTypeClick)
+ // Not an input
+ continue;
+
+ id = spot.id;
+ validId = spot.id & 0x7FFF;
+ index = i;
+ break;
+ }
+ break;
+ }
+ } else
+ // Normal move or click check
+ key = check(_vm->_game->_handleMouse, -duration, id, index);
+
+ // Handle special number keys
+ if (((key & 0xFF) >= ' ') && ((key & 0xFF) <= 0xFF) &&
+ ((key >> 8) > 1) && ((key >> 8) < 12))
+ key = '0' + (((key >> 8) - 1) % 10) + (key & 0xFF00);
+
+ if (id == 0) {
+ // No hotspot area
+
+ if (key != 0) {
+ // But a key
+
+ // Find the hotspot with that key associated
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (!spot.isFilledEnabled())
+ // Not filled or disabled
+ continue;
+
+ // Key match Catch all
+ if ((spot.key == key) || (spot.key == 0x7FFF)) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+
+ if (id == 0) {
+ // Didn't find such a hotspot
+
+ // Try it again, this time case insensitively
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (!spot.isFilledEnabled())
+ continue;
+
+ if ((spot.key & 0xFF00) != 0)
+ continue;
+
+ if (spot.key == 0)
+ continue;
+
+ if (toupper(key & 0xFF) == toupper(spot.key)) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+ }
+ } else if (duration != 0) {
+ if (stackPos2 != 0) {
+ collStackPos = 0;
+
+ for (int i = endIndex; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (!spot.isFilledNew())
+ continue;
+
+ collStackPos++;
+ if (collStackPos != stackPos2)
+ // Isn't yet the one wanted
+ continue;
+
+ id = spot.id;
+ index = i;
+ _vm->_inter->storeMouse();
+ if (VAR(16) != 0)
+ // We already handle a hotspot
+ break;
+
+ // Notify the scripts that we now handle this hotspot
+ if (Hotspot::getState(id) == kStateFilled)
+ WRITE_VAR(16, ids[id & 0xFFF]);
+ else
+ WRITE_VAR(16, id & 0xFFF);
+
+ if (spot.funcLeave != 0) {
+ // It has a leave function
+
+ uint32 timeKey = _vm->_util->getTimeKey();
+ call(spot.funcLeave);
+
+ if (timeVal != 2) {
+ // Rest time we have left = time we had - time the leave took
+ duration = timeVal - (_vm->_util->getTimeKey() - timeKey);
+
+ // Remove the buffer time
+ if ((duration - var_46) < 3) {
+ var_46 -= (duration - 3);
+ duration = 3;
+ } else if (var_46 != 0) {
+ duration -= var_46;
+ var_46 = 0;
+ }
+
+ // Clamp
+ if (duration > timeVal)
+ duration = timeVal;
+
+ } else
+ duration = 2;
+
+ }
+
+ if (VAR(16) == 0)
+ // Didn't find anything
+ id = 0;
+ else
+ var_41 = 1;
+
+ break;
+ }
+
+ } else {
+ if (descIndex != 0) {
+
+ counter = 0;
+ // Enter the nth hotspot
+ for (int i = endIndex; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.isFilledNew()) {
+ if (++counter == descIndex) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+
+ }
+
+ } else {
+
+ // Enter the first hotspot
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.isFilledNew()) {
+ id = spot.id;
+ index = i;
+ break;
+ }
+ }
+
+ // Leave the current hotspot
+ if ((_currentKey != 0) && (_hotspots[_currentIndex].funcLeave != 0))
+ call(_hotspots[_currentIndex].funcLeave);
+
+ _currentKey = 0;
+ }
+
+ }
+ }
+ }
+
+ if (var_41 != 0)
+ break;
+
+ if ((id == 0) || (_hotspots[index].funcLeave != 0))
+ // We don't have a new ID, but haven't yet handled the leave function
+ continue;
+
+ _vm->_inter->storeMouse();
+
+ // Notify the scripts of the currently handled hotspot
+ if (Hotspot::getState(id) == kStateFilled)
+ WRITE_VAR(16, ids[id & 0xFFF]);
+ else
+ WRITE_VAR(16, id & 0xFFF);
+
+ // Enter it
+ if (_hotspots[index].funcEnter != 0)
+ call(_hotspots[index].funcEnter);
+
+ WRITE_VAR(16, 0);
+ id = 0;
+ }
+ while ((id == 0) && !_vm->_inter->_terminate && !_vm->shouldQuit());
+
+ char tempStr[256];
+ if ((id & 0xFFF) == validId) {
+ collStackPos = 0;
+ var_24 = 0;
+ var_26 = 1;
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ // Looking for all enabled inputs
+ if (spot.isEnd())
+ continue;
+ if (!spot.isFilledEnabled())
+ continue;
+ if (!spot.isInput())
+ continue;
+
+ // Clean up numerical floating values
+ if (spot.getType() >= kTypeInputFloatNoLeave) {
+ // Get the string
+ char *ptr;
+ strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
+
+ // Remove spaces
+ while ((ptr = strchr(tempStr, ' ')))
+ _vm->_util->cutFromStr(tempStr, (ptr - tempStr), 1);
+
+ // Exchange decimal separator if needed
+ if (_vm->_global->_language == kLanguageBritish)
+ while ((ptr = strchr(tempStr, '.')))
+ *ptr = ',';
+
+ // Write it back
+ WRITE_VARO_STR(spot.key, tempStr);
+ }
+
+ if ((spot.getType() >= kTypeInput2NoLeave) && (spot.getType() <= kTypeInput3Leave)) {
+ const char *str = inputs[var_24].str;
+
+ strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
+
+ if (spot.getType() < kTypeInput3NoLeave)
+ _vm->_util->cleanupStr(tempStr);
+
+ // Look if we find a match between the wanted and the typed string
+ int16 pos = 0;
+ do {
+ char spotStr[256];
+
+ strncpy0(spotStr, str, 255);
+ pos += strlen(str) + 1;
+
+ str += strlen(str) + 1;
+
+ if (spot.getType() < kTypeInput3NoLeave)
+ _vm->_util->cleanupStr(spotStr);
+
+ // Compare the entered string with the string we wanted
+ if (strcmp(tempStr, spotStr) == 0) {
+ WRITE_VAR(17, VAR(17) + 1);
+ WRITE_VAR(17 + var_26, 1);
+ break;
+ }
+ } while (inputs[var_24].length > pos);
+
+ collStackPos++;
+ } else
+ WRITE_VAR(17 + var_26, 2);
+
+ var_24++;
+ var_26++;
+ }
+
+ // Notify the scripts if we reached the requested hotspot
+ if (collStackPos != (int16) VAR(17))
+ WRITE_VAR(17, 0);
+ else
+ WRITE_VAR(17, 1);
+ }
+
+ if (_vm->_game->_handleMouse == 1)
+ _vm->_draw->blitCursor();
+
+ if (!_vm->_inter->_terminate && (var_41 == 0)) {
+ _vm->_game->_script->seek(_hotspots[index].funcLeave);
+
+ _vm->_inter->storeMouse();
+ if (VAR(16) == 0) {
+ // No hotspot currently handled, now we'll handle the newly found one
+
+ if (Hotspot::getState(id) == kStateFilled)
+ WRITE_VAR(16, ids[id & 0xFFF]);
+ else
+ WRITE_VAR(16, id & 0xFFF);
+ }
+ } else
+ _vm->_game->_script->setFinished(true);
+
+ for (int i = 0; i < count; i++)
+ // Remove all local hotspots
+ remove(i + (kStateFilled << 12));
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ // Disable the ones still there
+ if ((spot.getState() == (kStateFilled | kStateType1)) ||
+ (spot.getState() == (kStateFilled | kStateType2)))
+ spot.disable();
+ }
+
+}
+
+int16 Hotspots::findCursor(uint16 x, uint16 y) const {
+ int16 cursor = 0;
+
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if ((spot.getWindow() != 0) || spot.isDisabled())
+ // Ignore disabled and non-main-windowed hotspots
+ continue;
+
+ if (!spot.isIn(x, y))
+ // We're not in that hotspot, ignore it
+ continue;
+
+ if (spot.getCursor() == 0) {
+ // Hotspot doesn't itself specify a cursor...
+ if (spot.getType() >= kTypeInput1NoLeave) {
+ // ...but the type has a generic one
+ cursor = 3;
+ break;
+ } else if ((spot.getButton() != kMouseButtonsRight) && (cursor == 0))
+ // ...but there's a generic "click" cursor
+ cursor = 1;
+ } else if (cursor == 0)
+ // Hotspot had an attached cursor index
+ cursor = spot.getCursor();
+ }
+
+ return cursor;
+}
+
+uint16 Hotspots::inputToHotspot(uint16 input) const {
+ uint16 inputIndex = 0;
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (!spot.isActiveInput())
+ // Not an active input
+ continue;
+
+ if (inputIndex == input)
+ // We've found our input
+ return i;
+
+ // Next one
+ inputIndex++;
+ }
+
+ // None found
+ return 0xFFFF;
+}
+
+uint16 Hotspots::hotspotToInput(uint16 hotspot) const {
+ uint16 input = 0;
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (!spot.isActiveInput())
+ // Not an active input
+ continue;
+
+ if (i == hotspot)
+ // We've found our hotspot
+ break;
+
+ // Next one
+ input++;
+ }
+
+ return input;
+}
+
+uint16 Hotspots::findClickedInput(uint16 index) const {
+ for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) {
+ Hotspot &spot = _hotspots[i];
+
+ if (spot.getWindow() != 0)
+ // Ignore other windows
+ continue;
+
+ if (spot.isDisabled())
+ // Ignore disabled hotspots
+ continue;
+
+ if (!spot.isIn(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY))
+ // This one wasn't it
+ continue;
+
+ if (spot.getCursor() != 0)
+ // This one specifies a cursor, so we don't want it
+ continue;
+
+ if (!spot.isInput())
+ // It's no input
+ continue;
+
+ index = i;
+ break;
+ }
+
+ return index;
+}
+
+void Hotspots::getTextCursorPos(const Video::FontDesc &font, const char *str,
+ uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height,
+ uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const {
+
+ if (font.charWidths) {
+ // Cursor to the right of the current character
+
+ cursorX = x;
+ cursorY = y;
+ cursorWidth = 1;
+ cursorHeight = height;
+
+ // Iterate through the string and add each character's width
+ for (uint32 i = 0; i < pos; i++)
+ cursorX += font.charWidths[str[i] - font.startItem];
+
+ } else {
+ // Cursor underlining the current character
+
+ cursorX = x + font.itemWidth * pos;
+ cursorY = y + height - 1;
+ cursorWidth = font.itemWidth;
+ cursorHeight = 1;
+ }
+}
+
+void Hotspots::fillRect(uint16 x, uint16 y, uint16 width, uint16 height, uint16 color) const {
+ _vm->_draw->_destSurface = 21;
+ _vm->_draw->_destSpriteX = x;
+ _vm->_draw->_destSpriteY = y;
+ _vm->_draw->_spriteRight = width;
+ _vm->_draw->_spriteBottom = height;
+ _vm->_draw->_backColor = color;
+
+ _vm->_draw->spriteOperation(DRAW_FILLRECT | 0x10 );
+}
+
+void Hotspots::printText(uint16 x, uint16 y, const char *str, uint16 fontIndex, uint16 color) const {
+ _vm->_draw->_destSpriteX = x;
+ _vm->_draw->_destSpriteY = y;
+ _vm->_draw->_frontColor = color;
+ _vm->_draw->_fontIndex = fontIndex;
+ _vm->_draw->_textToPrint = str;
+ _vm->_draw->_transparency = 1;
+
+ _vm->_draw->spriteOperation(DRAW_PRINTTEXT | 0x10);
+}
+
+void Hotspots::updateAllTexts(const InputDesc *inputs) const {
+ uint16 input = 0;
+
+ for (int i = 0; i < kHotspotCount; i++) {
+ const Hotspot &spot = _hotspots[i];
+
+ if (spot.isEnd())
+ // It's an end, we don't want it
+ continue;
+
+ if (!spot.isFilledEnabled())
+ // This one's either not used or disabled
+ continue;
+
+ if (!spot.isInput())
+ // Not an input
+ continue;
+
+ // Get its text
+ char tempStr[256];
+ strncpy0(tempStr, GET_VARO_STR(spot.key), 255);
+
+ // Coordinates
+ uint16 x = spot.left;
+ uint16 y = spot.top;
+ uint16 width = spot.right - spot.left + 1;
+ uint16 height = spot.bottom - spot.top + 1;
+ // Clear the background
+ fillRect(x, y, width, height, inputs[input].backColor);
+
+ // Center the text vertically
+ y += (height - _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
+
+ // Draw it
+ printText(x, y, tempStr, inputs[input].fontIndex, inputs[input].frontColor);
+
+ input++;
+ }
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h
new file mode 100644
index 0000000000..893991bfbe
--- /dev/null
+++ b/engines/gob/hotspots.h
@@ -0,0 +1,241 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef GOB_HOTSPOTS_H
+#define GOB_HOTSPOTS_H
+
+#include "common/stack.h"
+
+#include "gob/util.h"
+
+namespace Gob {
+
+class Script;
+
+class Hotspots {
+public:
+ static const int kHotspotCount = 250;
+
+ enum Type {
+ kTypeNone = 0,
+ kTypeMove = 1,
+ kTypeClick = 2,
+ kTypeInput1NoLeave = 3,
+ kTypeInput1Leave = 4,
+ kTypeInput2NoLeave = 5,
+ kTypeInput2Leave = 6,
+ kTypeInput3NoLeave = 7,
+ kTypeInput3Leave = 8,
+ kTypeInputFloatNoLeave = 9,
+ kTypeInputFloatLeave = 10,
+ kTypeEnable2 = 11,
+ kTypeEnable1 = 12,
+ kTypeClickEnter = 21
+ };
+
+ enum State {
+ kStateFilledDisabled = 0xC,
+ kStateFilled = 0x8,
+ kStateDisabled = 0x4,
+ kStateType2 = 0x2,
+ kStateType1 = 0x1
+ };
+
+ Hotspots(GobEngine *vm);
+ ~Hotspots();
+
+ /** Remove all hotspots. */
+ void clear();
+
+ /** Add a hotspot, returning the new index. */
+ uint16 add(uint16 id,
+ uint16 left, uint16 top, uint16 right, uint16 bottom,
+ uint16 flags, uint16 key,
+ uint16 funcEnter, uint16 funcLeave, uint16 funcPos);
+
+ /** Remove a specific hotspot. */
+ void remove(uint16 id);
+ /** Remove all hotspots in this state. */
+ void removeState(uint8 state);
+
+ /** Push the current hotspots onto the stack.
+ *
+ * @param all 0: Don't push global ones; 1: Push all; 2: Push only the disabled ones
+ * @param force Force a push although _shouldPush is false
+ */
+ void push(uint8 all, bool force = false);
+ /** Pop hotspots from the stack. */
+ void pop();
+
+ /** Check the current hotspot. */
+ uint16 check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index);
+ /** Check the current hotspot. */
+ uint16 check(uint8 handleMouse, int16 delay);
+
+ /** Evaluate hotspot changes. */
+ void evaluate();
+
+ /** Return the cursor found in the hotspot to the coordinates. */
+ int16 findCursor(uint16 x, uint16 y) const;
+
+private:
+ struct Hotspot {
+ uint16 id;
+ uint16 left;
+ uint16 top;
+ uint16 right;
+ uint16 bottom;
+ uint16 flags;
+ uint16 key;
+ uint16 funcEnter;
+ uint16 funcLeave;
+ uint16 funcPos;
+ Script *script;
+
+ Hotspot();
+ Hotspot(uint16 i,
+ uint16 l, uint16 t, uint16 r, uint16 b, uint16 f, uint16 k,
+ uint16 enter, uint16 leave, uint16 pos);
+
+ void clear();
+
+ Type getType() const;
+ MouseButtons getButton() const;
+ uint8 getWindow() const;
+ uint8 getCursor() const;
+ uint8 getState() const;
+
+ /** Is this hotspot the block end marker? */
+ bool isEnd() const;
+
+ bool isInput() const;
+ bool isActiveInput() const;
+
+ bool isFilled() const;
+ bool isFilledEnabled() const;
+ bool isFilledNew() const;
+ bool isDisabled() const;
+
+ /** Are the specified coordinates in the hotspot? */
+ bool isIn(uint16 x, uint16 y) const;
+ /** Does the specified button trigger the hotspot? */
+ bool buttonMatch(MouseButtons button) const;
+
+ static uint8 getState(uint16 id);
+
+ void disable();
+ void enable();
+ };
+
+ struct StackEntry {
+ bool shouldPush;
+ Hotspot *hotspots;
+ uint32 size;
+ uint32 key;
+ uint32 id;
+ uint32 index;
+ };
+
+ struct InputDesc {
+ uint16 fontIndex;
+ uint16 backColor;
+ uint16 frontColor;
+ uint16 length;
+ const char *str;
+ };
+
+ GobEngine *_vm;
+
+ Hotspot *_hotspots;
+ Common::Stack<StackEntry> _stack;
+
+ bool _shouldPush;
+
+ uint16 _currentKey;
+ uint16 _currentIndex;
+ uint16 _currentId;
+
+ /** Add a hotspot, returning the new index. */
+ uint16 add(const Hotspot &hotspot);
+
+ /** Recalculate all hotspot parameters
+ *
+ * @param force Force recalculation of all hotspots, including global ones.
+ */
+ void recalculate(bool force);
+
+ /** Is this a valid hotspot? */
+ bool isValid(uint16 key, uint16 id, uint16 index) const;
+
+ /** Call a hotspot subroutine. */
+ void call(uint16 offset);
+ /** Handling hotspot enter events. */
+ void enter(uint16 index);
+ /** Handling hotspot leave events. */
+ void leave(uint16 index);
+
+ /** Which hotspot is the mouse cursor currently at? */
+ uint16 checkMouse(Type type, uint16 &id, uint16 &index) const;
+
+ /** Did the current hotspot change in the meantime? */
+ bool checkHotspotChanged();
+
+ /** Update events from a specific input. */
+ uint16 updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 height,
+ uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex,
+ Type type, int16 &duration, uint16 &id, uint16 &index);
+
+ /** Handle all inputs we currently manage. */
+ uint16 handleInputs(int16 time, uint16 inputCount, uint16 &curInput,
+ InputDesc *inputs, uint16 &id, uint16 &index);
+
+ /** Evaluate adding new hotspots script commands. */
+ void evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs,
+ uint16 &validId, bool &hasInput, uint16 &inputCount);
+
+ /** Find the hotspot index that corresponds to the input index. */
+ uint16 inputToHotspot(uint16 input) const;
+ /** Find the input index that corresponds to the hotspot index. */
+ uint16 hotspotToInput(uint16 hotspot) const;
+ /** Find the input that was clicked on. */
+ uint16 findClickedInput(uint16 index) const;
+
+ /** Calculate the graphical cursor position. */
+ void getTextCursorPos(const Video::FontDesc &font, const char *str,
+ uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height,
+ uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const;
+
+ /** Fill that rectangle with the color. */
+ void fillRect(uint16 x, uint16 y, uint16 width, uint16 height, uint16 color) const;
+ /** Print the given text. */
+ void printText(uint16 x, uint16 y, const char *str, uint16 fontIndex, uint16 color) const;
+
+ /** Go through all inputs we manage and redraw their texts. */
+ void updateAllTexts(const InputDesc *inputs) const;
+};
+
+} // End of namespace Gob
+
+#endif // GOB_HOTSPOTS_H
diff --git a/engines/gob/init.h b/engines/gob/init.h
index a8d4b9833e..60642d0189 100644
--- a/engines/gob/init.h
+++ b/engines/gob/init.h
@@ -32,7 +32,7 @@ namespace Gob {
class Init {
public:
- void initGame();
+ virtual void initGame();
virtual void initVideo() = 0;
@@ -72,6 +72,14 @@ public:
virtual ~Init_v3() {}
};
+class Init_v6 : public Init_v3 {
+public:
+ virtual void initGame();
+
+ Init_v6(GobEngine *vm);
+ virtual ~Init_v6() {}
+};
+
} // End of namespace Gob
#endif // GOB_INIT_H
diff --git a/engines/gob/init_v6.cpp b/engines/gob/init_v6.cpp
new file mode 100644
index 0000000000..4b14c8a29c
--- /dev/null
+++ b/engines/gob/init_v6.cpp
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+
+#include "gob/gob.h"
+#include "gob/init.h"
+#include "gob/global.h"
+
+namespace Gob {
+
+Init_v6::Init_v6(GobEngine *vm) : Init_v3(vm) {
+}
+
+void Init_v6::initGame() {
+ _vm->_global->_noCd = false;
+
+ if (Common::File::exists("cd1.itk") && Common::File::exists("cd2.itk") &&
+ Common::File::exists("cd3.itk") && Common::File::exists("cd4.itk")) {
+ _vm->_global->_noCd = true;
+ }
+
+ Init::initGame();
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index 8be07034c6..afd215a00d 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -35,6 +35,7 @@
#include "gob/game.h"
#include "gob/expression.h"
#include "gob/script.h"
+#include "gob/hotspots.h"
#include "gob/scenery.h"
#include "gob/sound/sound.h"
@@ -180,7 +181,7 @@ void Inter::storeMouse() {
WRITE_VAR(2, x);
WRITE_VAR(3, y);
- WRITE_VAR(4, _vm->_game->_mouseButtons);
+ WRITE_VAR(4, (uint32) _vm->_game->_mouseButtons);
}
void Inter::storeKey(int16 key) {
@@ -189,20 +190,20 @@ void Inter::storeKey(int16 key) {
storeMouse();
WRITE_VAR(1, _vm->_sound->blasterPlayingSound());
- if (key == 0x4800)
- key = 0x0B;
- else if (key == 0x5000)
- key = 0x0A;
- else if (key == 0x4D00)
- key = 0x09;
- else if (key == 0x4B00)
- key = 0x08;
- else if (key == 0x011B)
- key = 0x1B;
- else if (key == 0x0E08)
- key = 0x19;
- else if (key == 0x5300)
- key = 0x1A;
+ if (key == kKeyUp)
+ key = kShortKeyUp;
+ else if (key == kKeyDown)
+ key = kShortKeyDown;
+ else if (key == kKeyRight)
+ key = kShortKeyRight;
+ else if (key == kKeyLeft)
+ key = kShortKeyLeft;
+ else if (key == kKeyEscape)
+ key = kShortKeyEscape;
+ else if (key == kKeyBackspace)
+ key = kShortKeyBackspace;
+ else if (key == kKeyDelete)
+ key = kShortKeyDelete;
else if ((key & 0xFF) != 0)
key &= 0xFF;
@@ -334,7 +335,7 @@ void Inter::callSub(int16 retFlag) {
if (block == 1)
funcBlock(retFlag);
else if (block == 2)
- _vm->_game->collisionsBlock();
+ _vm->_game->_hotspots->evaluate();
else
error("Unknown block type %d in Inter::callSub()", block);
}
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index d4ed2d3240..a31860885f 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -238,7 +238,7 @@ protected:
bool o1_playComposition(OpFuncParams &params);
bool o1_getFreeMem(OpFuncParams &params);
bool o1_checkData(OpFuncParams &params);
- bool o1_prepareStr(OpFuncParams &params);
+ bool o1_cleanupStr(OpFuncParams &params);
bool o1_insertStr(OpFuncParams &params);
bool o1_cutStr(OpFuncParams &params);
bool o1_strstr(OpFuncParams &params);
@@ -380,8 +380,8 @@ protected:
bool o2_assign(OpFuncParams &params);
bool o2_printText(OpFuncParams &params);
bool o2_animPalInit(OpFuncParams &params);
- bool o2_addCollision(OpFuncParams &params);
- bool o2_freeCollision(OpFuncParams &params);
+ bool o2_addHotspot(OpFuncParams &params);
+ bool o2_removeHotspot(OpFuncParams &params);
bool o2_goblinFunc(OpFuncParams &params);
bool o2_stopSound(OpFuncParams &params);
bool o2_loadSound(OpFuncParams &params);
@@ -541,7 +541,7 @@ protected:
bool o6_loadCursor(OpFuncParams &params);
bool o6_assign(OpFuncParams &params);
bool o6_palLoad(OpFuncParams &params);
- bool o6_freeCollision(OpFuncParams &params);
+ bool o6_removeHotspot(OpFuncParams &params);
bool o6_fillRect(OpFuncParams &params);
void probe16bitMusic(char *fileName);
diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp
index 12079600c0..b955057bac 100644
--- a/engines/gob/inter_bargon.cpp
+++ b/engines/gob/inter_bargon.cpp
@@ -89,7 +89,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams &params) {
int i;
int16 mouseX;
int16 mouseY;
- int16 buttons;
+ MouseButtons buttons;
SurfaceDescPtr surface;
SoundDesc samples[4];
int16 comp[5] = { 0, 1, 2, 3, -1 };
@@ -107,13 +107,13 @@ void Inter_Bargon::oBargon_intro2(OpGobParams &params) {
for (i = 320; i >= 0; i--) {
_vm->_util->setScrollOffset(i, 0);
_vm->_video->dirtyRectsAll();
- if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) ||
+ if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == kKeyEscape) ||
_vm->shouldQuit()) {
_vm->_palAnim->fade(0, -2, 0);
_vm->_video->clearSurf(*_vm->_draw->_frontSurface);
memset((char *) _vm->_draw->_vgaPalette, 0, 768);
WRITE_VAR(4, buttons);
- WRITE_VAR(0, 0x11B);
+ WRITE_VAR(0, kKeyEscape);
WRITE_VAR(57, (uint32) -1);
break;
}
@@ -137,7 +137,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams &params) {
void Inter_Bargon::oBargon_intro3(OpGobParams &params) {
int16 mouseX;
int16 mouseY;
- int16 buttons;
+ MouseButtons buttons;
Video::Color *palBak;
SoundDesc samples[2];
int16 comp[3] = { 0, 1, -1 };
@@ -158,14 +158,14 @@ void Inter_Bargon::oBargon_intro3(OpGobParams &params) {
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
_vm->_util->longDelay(_vm->_util->getRandom(200));
}
- if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) ||
+ if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == kKeyEscape) ||
_vm->shouldQuit()) {
_vm->_sound->blasterStop(10);
_vm->_palAnim->fade(0, -2, 0);
_vm->_video->clearSurf(*_vm->_draw->_frontSurface);
memset(_vm->_draw->_vgaPalette, 0, 768);
WRITE_VAR(4, buttons);
- WRITE_VAR(0, 0x11B);
+ WRITE_VAR(0, kKeyEscape);
WRITE_VAR(57, (uint32) -1);
break;
}
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 96ecfc6b25..7c5094d175 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -37,6 +37,7 @@
#include "gob/expression.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/goblin.h"
#include "gob/inter.h"
#include "gob/map.h"
@@ -147,7 +148,7 @@ void Inter_v1::setupOpcodesFunc() {
OPCODEFUNC(0x3E, o1_getFreeMem);
OPCODEFUNC(0x3F, o1_checkData);
- OPCODEFUNC(0x41, o1_prepareStr);
+ OPCODEFUNC(0x41, o1_cleanupStr);
OPCODEFUNC(0x42, o1_insertStr);
OPCODEFUNC(0x43, o1_cutStr);
@@ -867,7 +868,16 @@ bool Inter_v1::o1_loadSpriteToPos(OpFuncParams &params) {
_vm->_draw->_spriteLeft = _vm->_game->_script->readInt16();
_vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr();
- _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr();
+
+ // WORKAROUND: The EGA version of Gobliiins 1 has an invalid expression there
+ if (_vm->isEGA() && (_vm->_game->_script->pos() == 1398) &&
+ !scumm_stricmp(_vm->_game->_curTotFile, "intro.tot")) {
+
+ _vm->_draw->_destSpriteY = 0;
+ _vm->_game->_script->skip(1);
+
+ } else
+ _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr();
_vm->_draw->_transparency = _vm->_game->_script->peekByte() & 1;
_vm->_draw->_destSurface = ((int16) (_vm->_game->_script->peekByte() >> 1)) - 1;
@@ -1173,7 +1183,7 @@ bool Inter_v1::o1_keyFunc(OpFuncParams &params) {
case 0:
_vm->_draw->_showCursor &= ~2;
_vm->_util->longDelay(1);
- key = _vm->_game->checkCollisions(0, 0, 0, 0);
+ key = _vm->_game->_hotspots->check(0, 0);
storeKey(key);
_vm->_util->clearKeyBuf();
@@ -1601,11 +1611,11 @@ bool Inter_v1::o1_checkData(OpFuncParams &params) {
return false;
}
-bool Inter_v1::o1_prepareStr(OpFuncParams &params) {
+bool Inter_v1::o1_cleanupStr(OpFuncParams &params) {
int16 strVar;
strVar = _vm->_game->_script->readVarIndex();
- _vm->_util->prepareStr(GET_VARO_FSTR(strVar));
+ _vm->_util->cleanupStr(GET_VARO_FSTR(strVar));
return false;
}
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 82822330b1..20f812bb88 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -39,6 +39,7 @@
#include "gob/expression.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/goblin.h"
#include "gob/map.h"
#include "gob/mult.h"
@@ -121,8 +122,8 @@ void Inter_v2::setupOpcodesFunc() {
OPCODEFUNC(0x17, o2_animPalInit);
- OPCODEFUNC(0x18, o2_addCollision);
- OPCODEFUNC(0x19, o2_freeCollision);
+ OPCODEFUNC(0x18, o2_addHotspot);
+ OPCODEFUNC(0x19, o2_removeHotspot);
OPCODEFUNC(0x25, o2_goblinFunc);
@@ -1176,67 +1177,51 @@ bool Inter_v2::o2_animPalInit(OpFuncParams &params) {
return false;
}
-bool Inter_v2::o2_addCollision(OpFuncParams &params) {
- int16 id;
- int16 left, top, width, height;
- int16 flags;
- int16 key;
- int16 funcSub;
-
- id = _vm->_game->_script->readValExpr();
- funcSub = _vm->_game->_script->pos();
- left = _vm->_game->_script->readValExpr();
- top = _vm->_game->_script->readValExpr();
- width = _vm->_game->_script->readValExpr();
- height = _vm->_game->_script->readValExpr();
- flags = _vm->_game->_script->readValExpr();
- key = _vm->_game->_script->readInt16();
+bool Inter_v2::o2_addHotspot(OpFuncParams &params) {
+ int16 id = _vm->_game->_script->readValExpr();
+ uint16 funcPos = _vm->_game->_script->pos();
+ int16 left = _vm->_game->_script->readValExpr();
+ int16 top = _vm->_game->_script->readValExpr();
+ uint16 width = _vm->_game->_script->readValExpr();
+ uint16 height = _vm->_game->_script->readValExpr();
+ uint16 flags = _vm->_game->_script->readValExpr();
+ uint16 key = _vm->_game->_script->readInt16();
if (key == 0)
key = ABS(id) + 41960;
- _vm->_draw->adjustCoords(0, &left, &top);
- _vm->_draw->adjustCoords(2, &width, &height);
-
if (left < 0) {
width += left;
- left = 0;
+ left = 0;
}
if (top < 0) {
height += top;
- top = 0;
+ top = 0;
}
int16 index;
if (id < 0)
- index = _vm->_game->addNewCollision(0xD000 - id, left & 0xFFFC, top & 0xFFFC,
- left + width + 3, top + height + 3, flags, key, 0, 0);
+ index = _vm->_game->_hotspots->add(0xD000 - id, left & 0xFFFC, top & 0xFFFC,
+ left + width + 3, top + height + 3, flags, key, 0, 0, funcPos);
else
- index = _vm->_game->addNewCollision(0xE000 + id, left, top,
- left + width - 1, top + height - 1, flags, key, 0, 0);
-
- _vm->_game->_collisionAreas[index].funcSub = funcSub;
+ index = _vm->_game->_hotspots->add(0xE000 + id, left, top,
+ left + width - 1, top + height - 1, flags, key, 0, 0, funcPos);
return false;
}
-bool Inter_v2::o2_freeCollision(OpFuncParams &params) {
- int16 id;
+bool Inter_v2::o2_removeHotspot(OpFuncParams &params) {
+ int16 id = _vm->_game->_script->readValExpr();
+ uint8 stateType1 = Hotspots::kStateFilledDisabled | Hotspots::kStateType1;
+ uint8 stateType2 = Hotspots::kStateFilledDisabled | Hotspots::kStateType2;
- id = _vm->_game->_script->readValExpr();
- if (id == -2) {
- for (int i = 0; i < 150; i++) {
- if ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xD000)
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
- } else if (id == -1) {
- for (int i = 0; i < 150; i++) {
- if ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xE000)
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
- } else
- _vm->_game->freeCollision(0xE000 + id);
+ if (id == -2)
+ _vm->_game->_hotspots->removeState(stateType1);
+ else if (id == -1)
+ _vm->_game->_hotspots->removeState(stateType2);
+ else
+ _vm->_game->_hotspots->remove((stateType2 << 12) + id);
return false;
}
diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp
index 506de821d4..aa4721ff0a 100644
--- a/engines/gob/inter_v6.cpp
+++ b/engines/gob/inter_v6.cpp
@@ -31,10 +31,12 @@
#include "gob/inter.h"
#include "gob/helper.h"
#include "gob/global.h"
+#include "gob/dataio.h"
#include "gob/game.h"
#include "gob/expression.h"
#include "gob/script.h"
#include "gob/resources.h"
+#include "gob/hotspots.h"
#include "gob/draw.h"
#include "gob/sound/sound.h"
#include "gob/videoplayer.h"
@@ -64,7 +66,7 @@ void Inter_v6::setupOpcodesFunc() {
OPCODEFUNC(0x03, o6_loadCursor);
OPCODEFUNC(0x09, o6_assign);
OPCODEFUNC(0x13, o6_palLoad);
- OPCODEFUNC(0x19, o6_freeCollision);
+ OPCODEFUNC(0x19, o6_removeHotspot);
OPCODEFUNC(0x33, o6_fillRect);
}
@@ -187,7 +189,7 @@ void Inter_v6::o6_openItk() {
// (it checks CD1.ITK - CD4.ITK and the first that's found determines
// the CD number), while its NO_CD modus wants everything in CD1.ITK.
// So we just open the other ITKs, too.
- if (_vm->_game->_noCd && !scumm_stricmp(fileName, "CD1.ITK")) {
+ if (_vm->_global->_noCd && !scumm_stricmp(fileName, "CD1.ITK")) {
_vm->_dataIO->openDataFile("CD2.ITK", true);
_vm->_dataIO->openDataFile("CD3.ITK", true);
_vm->_dataIO->openDataFile("CD4.ITK", true);
@@ -351,36 +353,33 @@ bool Inter_v6::o6_palLoad(OpFuncParams &params) {
return false;
}
-bool Inter_v6::o6_freeCollision(OpFuncParams &params) {
+bool Inter_v6::o6_removeHotspot(OpFuncParams &params) {
int16 id;
+ uint8 stateType1 = Hotspots::kStateFilledDisabled | Hotspots::kStateType1;
+ uint8 stateType2 = Hotspots::kStateFilledDisabled | Hotspots::kStateType2;
+ uint8 stateDisabled = Hotspots::kStateDisabled;
id = _vm->_game->_script->readValExpr();
switch (id + 5) {
case 0:
- _vm->_game->pushCollisions(1);
+ _vm->_game->_hotspots->push(1);
break;
case 1:
- _vm->_game->popCollisions();
+ _vm->_game->_hotspots->pop();
break;
case 2:
- _vm->_game->pushCollisions(2);
+ _vm->_game->_hotspots->push(2);
break;
case 3:
- for (int i = 0; i < 150; i++) {
- if (((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xD000) ||
- ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0x4000))
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
+ _vm->_game->_hotspots->removeState(stateType1);
+ _vm->_game->_hotspots->removeState(stateDisabled);
break;
case 4:
- for (int i = 0; i < 150; i++) {
- if ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xE000)
- _vm->_game->_collisionAreas[i].left = 0xFFFF;
- }
+ _vm->_game->_hotspots->removeState(stateType2);
break;
default:
- _vm->_game->freeCollision(0xE000 + id);
+ _vm->_game->_hotspots->remove((stateType2 << 12) + id);
break;
}
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 695976da61..66c1b0dbaf 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -11,10 +11,6 @@ MODULE_OBJS := \
driver_vga.o \
expression.o \
game.o \
- game_v1.o \
- game_v2.o \
- game_v6.o \
- game_fascin.o \
global.o \
gob.o \
goblin.o \
@@ -22,11 +18,12 @@ MODULE_OBJS := \
goblin_v2.o \
goblin_v3.o \
goblin_v4.o \
- videoplayer.o \
+ hotspots.o \
init.o \
init_v1.o \
init_v2.o \
init_v3.o \
+ init_v6.o \
inter.o \
inter_v1.o \
inter_v2.o \
@@ -56,6 +53,7 @@ MODULE_OBJS := \
video_v1.o \
video_v2.o \
video_v6.o \
+ videoplayer.o \
demos/demoplayer.o \
demos/scnplayer.o \
demos/batplayer.o \
diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp
index 5aec5ff76e..d383d955c7 100644
--- a/engines/gob/mult.cpp
+++ b/engines/gob/mult.cpp
@@ -204,7 +204,7 @@ void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape,
stop = false;
_vm->_util->processInput();
- if (checkEscape && (_vm->_util->checkKey() == 0x11B))
+ if (checkEscape && (_vm->_util->checkKey() == kKeyEscape))
stop = true;
_frame++;
diff --git a/engines/gob/script.cpp b/engines/gob/script.cpp
index 6162e943bf..38b1f8fa40 100644
--- a/engines/gob/script.cpp
+++ b/engines/gob/script.cpp
@@ -127,6 +127,10 @@ bool Script::skip(int32 offset) {
return seek(offset, SEEK_CUR);
}
+bool Script::skipBlock() {
+ return seek(peekUint16(2) + 2, SEEK_CUR);
+}
+
int32 Script::getOffset(byte *ptr) const {
if (!_totData)
return -1;
diff --git a/engines/gob/script.h b/engines/gob/script.h
index 64a04503b1..84daeaf1af 100644
--- a/engines/gob/script.h
+++ b/engines/gob/script.h
@@ -53,6 +53,7 @@ public:
// Stream seeking
bool seek(int32 offset, int whence = SEEK_SET);
bool skip(int32 offset);
+ bool skipBlock();
// Reading data
byte readByte ();
diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp
index d3afc9baa3..2d7ba02385 100644
--- a/engines/gob/sound/sound.cpp
+++ b/engines/gob/sound/sound.cpp
@@ -506,7 +506,7 @@ void Sound::blasterWaitEndPlay(bool interruptible, bool stopComp) {
_blaster->endComposition();
while (_blaster->isPlaying() && !_vm->shouldQuit()) {
- if (interruptible && (_vm->_util->checkKey() == 0x11B)) {
+ if (interruptible && (_vm->_util->checkKey() == kKeyEscape)) {
WRITE_VAR(57, (uint32) -1);
return;
}
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index b0e7691c07..429b0269cf 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -38,14 +38,14 @@
namespace Gob {
Util::Util(GobEngine *vm) : _vm(vm) {
- _mouseButtons = 0;
- _keyBufferHead = 0;
- _keyBufferTail = 0;
- _fastMode = 0;
- _frameRate = 12;
- _frameWaitTime = 0;
+ _mouseButtons = kMouseButtonsNone,
+ _keyBufferHead = 0;
+ _keyBufferTail = 0;
+ _fastMode = 0;
+ _frameRate = 12;
+ _frameWaitTime = 0;
_startFrameTime = 0;
- _frameWaitLag = 0;
+ _frameWaitLag = 0;
}
uint32 Util::getTimeKey(void) {
@@ -85,7 +85,7 @@ void Util::longDelay(uint16 msecs) {
}
void Util::initInput(void) {
- _mouseButtons = 0;
+ _mouseButtons = kMouseButtonsNone;
_keyBufferHead = _keyBufferTail = 0;
}
@@ -103,16 +103,16 @@ void Util::processInput(bool scroll) {
y = event.mouse.y;
break;
case Common::EVENT_LBUTTONDOWN:
- _mouseButtons |= 1;
+ _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsLeft));
break;
case Common::EVENT_RBUTTONDOWN:
- _mouseButtons |= 2;
+ _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) | ((uint32) kMouseButtonsRight));
break;
case Common::EVENT_LBUTTONUP:
- _mouseButtons &= ~1;
+ _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsLeft));
break;
case Common::EVENT_RBUTTONUP:
- _mouseButtons &= ~2;
+ _mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsRight));
break;
case Common::EVENT_KEYDOWN:
if (event.kbd.flags == Common::KBD_CTRL) {
@@ -179,26 +179,26 @@ int16 Util::translateKey(const Common::KeyState &key) {
int16 from;
int16 to;
} keys[] = {
- {Common::KEYCODE_INVALID, 0x0000},
- {Common::KEYCODE_BACKSPACE, 0x0E08},
- {Common::KEYCODE_SPACE, 0x3920},
- {Common::KEYCODE_RETURN, 0x1C0D},
- {Common::KEYCODE_ESCAPE, 0x011B},
- {Common::KEYCODE_DELETE, 0x5300},
- {Common::KEYCODE_UP, 0x4800},
- {Common::KEYCODE_DOWN, 0x5000},
- {Common::KEYCODE_RIGHT, 0x4D00},
- {Common::KEYCODE_LEFT, 0x4B00},
- {Common::KEYCODE_F1, 0x3B00},
- {Common::KEYCODE_F2, 0x3C00},
- {Common::KEYCODE_F3, 0x3D00},
- {Common::KEYCODE_F4, 0x3E00},
- {Common::KEYCODE_F5, 0x011B},
- {Common::KEYCODE_F6, 0x4000},
- {Common::KEYCODE_F7, 0x4100},
- {Common::KEYCODE_F8, 0x4200},
- {Common::KEYCODE_F9, 0x4300},
- {Common::KEYCODE_F10, 0x4400}
+ {Common::KEYCODE_INVALID, kKeyNone },
+ {Common::KEYCODE_BACKSPACE, kKeyBackspace},
+ {Common::KEYCODE_SPACE, kKeySpace },
+ {Common::KEYCODE_RETURN, kKeyReturn },
+ {Common::KEYCODE_ESCAPE, kKeyEscape },
+ {Common::KEYCODE_DELETE, kKeyDelete },
+ {Common::KEYCODE_UP, kKeyUp },
+ {Common::KEYCODE_DOWN, kKeyDown },
+ {Common::KEYCODE_RIGHT, kKeyRight },
+ {Common::KEYCODE_LEFT, kKeyLeft },
+ {Common::KEYCODE_F1, kKeyF1 },
+ {Common::KEYCODE_F2, kKeyF2 },
+ {Common::KEYCODE_F3, kKeyF3 },
+ {Common::KEYCODE_F4, kKeyF4 },
+ {Common::KEYCODE_F5, kKeyEscape },
+ {Common::KEYCODE_F6, kKeyF6 },
+ {Common::KEYCODE_F7, kKeyF7 },
+ {Common::KEYCODE_F8, kKeyF8 },
+ {Common::KEYCODE_F9, kKeyF9 },
+ {Common::KEYCODE_F10, kKeyF10 }
};
for (int i = 0; i < ARRAYSIZE(keys); i++)
@@ -246,7 +246,7 @@ bool Util::checkKey(int16 &key) {
return true;
}
-void Util::getMouseState(int16 *pX, int16 *pY, int16 *pButtons) {
+void Util::getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons) {
Common::Point mouse = g_system->getEventManager()->getMousePos();
*pX = mouse.x + _vm->_video->_scrollOffsetX - _vm->_video->_screenDeltaX;
*pY = mouse.y + _vm->_video->_scrollOffsetY - _vm->_video->_screenDeltaY;
@@ -264,15 +264,15 @@ void Util::setMousePos(int16 x, int16 y) {
void Util::waitMouseUp(void) {
do {
processInput();
- if (_mouseButtons != 0)
+ if (_mouseButtons != kMouseButtonsNone)
delay(10);
- } while (_mouseButtons != 0);
+ } while (_mouseButtons != kMouseButtonsNone);
}
void Util::waitMouseDown(void) {
int16 x;
int16 y;
- int16 buttons;
+ MouseButtons buttons;
do {
processInput();
@@ -283,7 +283,7 @@ void Util::waitMouseDown(void) {
}
void Util::waitMouseRelease(char drawMouse) {
- int16 buttons;
+ MouseButtons buttons;
int16 mouseX;
int16 mouseY;
@@ -300,8 +300,8 @@ void Util::forceMouseUp(bool onlyWhenSynced) {
if (onlyWhenSynced && (_vm->_game->_mouseButtons != _mouseButtons))
return;
- _vm->_game->_mouseButtons = 0;
- _mouseButtons = 0;
+ _vm->_game->_mouseButtons = kMouseButtonsNone;
+ _mouseButtons = kMouseButtonsNone;
}
void Util::clearPalette(void) {
@@ -403,10 +403,10 @@ Video::FontDesc *Util::loadFont(const char *path) {
fontDesc->bitWidth = fontDesc->itemWidth;
if (data[0] & 0x80)
- fontDesc->extraData = data + 4 + fontDesc->itemSize *
+ fontDesc->charWidths = data + 4 + fontDesc->itemSize *
(fontDesc->endItem - fontDesc->startItem + 1);
else
- fontDesc->extraData = 0;
+ fontDesc->charWidths = 0;
return fontDesc;
}
@@ -452,7 +452,7 @@ static const char trStr2[] =
" ";
static const char trStr3[] = " ";
-void Util::prepareStr(char *str) {
+void Util::cleanupStr(char *str) {
char *start, *end;
char buf[300];
@@ -460,17 +460,20 @@ void Util::prepareStr(char *str) {
strcat(buf, trStr2);
strcat(buf, trStr3);
+ // Translating "wrong" characters
for (size_t i = 0; i < strlen(str); i++)
- str[i] = buf[str[i] - 32];
+ str[i] = buf[MIN<int>(str[i] - 32, 32)];
+ // Trim spaces left
while (str[0] == ' ')
cutFromStr(str, 0, 1);
+ // Trim spaces right
while ((strlen(str) > 0) && (str[strlen(str) - 1] == ' '))
cutFromStr(str, strlen(str) - 1, 1);
+ // Merge double spaces
start = strchr(str, ' ');
-
while (start) {
if (start[1] == ' ') {
cutFromStr(str, start - str, 1);
diff --git a/engines/gob/util.h b/engines/gob/util.h
index 0a76ee40ab..088a78a64d 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -34,6 +34,47 @@ namespace Gob {
#define KEYBUFSIZE 16
+enum MouseButtons {
+ kMouseButtonsNone = 0,
+ kMouseButtonsLeft = 1,
+ kMouseButtonsRight = 2,
+ kMouseButtonsBoth = 3,
+ kMouseButtonsAny = 4
+};
+
+enum Keys {
+ kKeyNone = 0x0000,
+ kKeyBackspace = 0x0E08,
+ kKeySpace = 0x3920,
+ kKeyReturn = 0x1C0D,
+ kKeyEscape = 0x011B,
+ kKeyDelete = 0x5300,
+ kKeyUp = 0x4800,
+ kKeyDown = 0x5000,
+ kKeyRight = 0x4D00,
+ kKeyLeft = 0x4B00,
+ kKeyF1 = 0x3B00,
+ kKeyF2 = 0x3C00,
+ kKeyF3 = 0x3D00,
+ kKeyF4 = 0x3E00,
+ kKeyF5 = 0x3F00,
+ kKeyF6 = 0x4000,
+ kKeyF7 = 0x4100,
+ kKeyF8 = 0x4200,
+ kKeyF9 = 0x4300,
+ kKeyF10 = 0x4400
+};
+
+enum ShortKey {
+ kShortKeyUp = 0x0B,
+ kShortKeyDown = 0x0A,
+ kShortKeyRight = 0x09,
+ kShortKeyLeft = 0x08,
+ kShortKeyEscape = 0x1B,
+ kShortKeyBackspace = 0x19,
+ kShortKeyDelete = 0x1A
+};
+
class Util {
public:
struct ListNode;
@@ -66,7 +107,7 @@ public:
int16 checkKey(void);
bool checkKey(int16 &key);
- void getMouseState(int16 *pX, int16 *pY, int16 *pButtons);
+ void getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons);
void setMousePos(int16 x, int16 y);
void waitMouseUp(void);
void waitMouseDown(void);
@@ -84,7 +125,7 @@ public:
static void insertStr(const char *str1, char *str2, int16 pos);
static void cutFromStr(char *str, int16 from, int16 cutlen);
- static void prepareStr(char *str);
+ static void cleanupStr(char *str);
static void replaceChar(char *str, char c1, char c2);
static void listInsertFront(List *list, void *data);
@@ -95,7 +136,8 @@ public:
Util(GobEngine *vm);
protected:
- int16 _mouseButtons;
+ MouseButtons _mouseButtons;
+
Common::KeyState _keyBuffer[KEYBUFSIZE];
int16 _keyBufferHead;
int16 _keyBufferTail;
diff --git a/engines/gob/video.h b/engines/gob/video.h
index c71a18daa6..8716a637c2 100644
--- a/engines/gob/video.h
+++ b/engines/gob/video.h
@@ -78,7 +78,7 @@ public:
uint8 endItem;
int8 itemSize;
int8 bitWidth;
- byte *extraData;
+ uint8 *charWidths;
FontDesc() : dataPtr(0), itemWidth(0), itemHeight(0), startItem(0),
endItem(0), itemSize(0), bitWidth(0) {}
~FontDesc() {
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index 6c07d22333..da552d7202 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -27,7 +27,6 @@
#include "gob/videoplayer.h"
#include "gob/helper.h"
#include "gob/global.h"
-#include "gob/util.h"
#include "gob/dataio.h"
#include "gob/video.h"
#include "gob/draw.h"
diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h
index 842426f90a..ead752d446 100644
--- a/engines/gob/videoplayer.h
+++ b/engines/gob/videoplayer.h
@@ -31,11 +31,12 @@
#include "graphics/video/coktelvideo/coktelvideo.h"
-#include "gob/dataio.h"
+#include "gob/util.h"
namespace Gob {
class GobEngine;
+class DataStream;
class VideoPlayer {
public:
@@ -60,13 +61,14 @@ public:
bool primaryOpen(const char *videoFile, int16 x = -1, int16 y = -1,
int32 flags = kFlagFrontSurface, Type which = kVideoTypeTry);
- bool primaryPlay(int16 startFrame = -1, int16 lastFrame = -1, int16 breakKey = 27,
+ bool primaryPlay(int16 startFrame = -1, int16 lastFrame = -1,
+ int16 breakKey = kShortKeyEscape,
uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255,
int16 palFrame = -1, int16 endFrame = -1, bool fade = false,
int16 reverseTo = -1, bool forceSeek = false);
void primaryClose();
- void playFrame(int16 frame, int16 breakKey = 27,
+ void playFrame(int16 frame, int16 breakKey = kShortKeyEscape,
uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255,
int16 palFrame = -1 , int16 endFrame = -1);
diff --git a/engines/groovie/groovie.cpp b/engines/groovie/groovie.cpp
index 24f47351a3..cdf05e803b 100644
--- a/engines/groovie/groovie.cpp
+++ b/engines/groovie/groovie.cpp
@@ -108,7 +108,11 @@ Common::Error GroovieEngine::run() {
}
// Create the music player
- _musicPlayer = new MusicPlayer(this, _gameDescription->version == kGroovieT7G ? "fat" : "sample");
+ if (_gameDescription->desc.platform == Common::kPlatformMacintosh) {
+ _musicPlayer = new MusicPlayerMac(this);
+ } else {
+ _musicPlayer = new MusicPlayerXMI(this, _gameDescription->version == kGroovieT7G ? "fat" : "sample");
+ }
// Load volume levels
syncSoundSettings();
diff --git a/engines/groovie/music.cpp b/engines/groovie/music.cpp
index 30889deb44..1a1de92156 100644
--- a/engines/groovie/music.cpp
+++ b/engines/groovie/music.cpp
@@ -31,72 +31,20 @@
namespace Groovie {
-MusicPlayer::MusicPlayer(GroovieEngine *vm, const Common::String &gtlName) :
- _vm(vm), _midiParser(NULL), _data(NULL), _driver(NULL),
- _backgroundFileRef(0), _gameVolume(100), _prevCDtrack(0), _isPlaying(0) {
- // Create the parser
- _midiParser = MidiParser::createParser_XMIDI();
-
- // Create the driver
- int driver = detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
- _driver = createMidi(driver);
- this->open();
-
- // Initialize the channel volumes and banks
- for (int i = 0; i < 0x10; i++) {
- _chanVolumes[i] = 0x7F;
- _chanBanks[i] = 0;
- }
-
- // Load the Global Timbre Library
- if (driver == MD_ADLIB) {
- // MIDI through AdLib
- _musicType = MD_ADLIB;
- loadTimbres(gtlName + ".ad");
-
- // Setup the percussion channel
- for (unsigned int i = 0; i < _timbres.size(); i++) {
- if (_timbres[i].bank == 0x7F)
- setTimbreAD(9, _timbres[i]);
- }
- } else if ((driver == MD_MT32) || ConfMan.getBool("native_mt32")) {
- // MT-32
- _musicType = MD_MT32;
- loadTimbres(gtlName + ".mt");
- } else {
- // GM
- _musicType = 0;
- }
-
- // Set the parser's driver
- _midiParser->setMidiDriver(this);
-
- // Set the timer rate
- _midiParser->setTimerRate(_driver->getBaseTempo());
-}
-
-MusicPlayer::~MusicPlayer() {
- _driver->setTimerCallback(NULL, NULL);
-
- Common::StackLock lock(_mutex);
-
- // Unload the parser
- unload();
- delete _midiParser;
+// MusicPlayer
- // Unload the MIDI Driver
- _driver->close();
- delete _driver;
-
- // Unload the timbres
- clearTimbres();
+MusicPlayer::MusicPlayer(GroovieEngine *vm) :
+ _vm(vm), _isPlaying(false), _backgroundFileRef(0), _gameVolume(100),
+ _prevCDtrack(0) {
}
void MusicPlayer::playSong(uint32 fileref) {
Common::StackLock lock(_mutex);
+ // Set the volumes
_fadingEndVolume = 100;
_gameVolume = 100;
+
// Play the referenced file once
play(fileref, false);
}
@@ -146,6 +94,14 @@ void MusicPlayer::playCD(uint8 track) {
AudioCD.play(track - 1, 1, startms * 75 / 1000, 0);
}
+void MusicPlayer::startBackground() {
+ debugC(3, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: startBackground()");
+ if (!_isPlaying && _backgroundFileRef) {
+ debugC(3, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Starting the background song (0x%4X)", _backgroundFileRef);
+ play(_backgroundFileRef, true);
+ }
+}
+
void MusicPlayer::setUserVolume(uint16 volume) {
Common::StackLock lock(_mutex);
@@ -154,10 +110,8 @@ void MusicPlayer::setUserVolume(uint16 volume) {
if (_userVolume > 0x100)
_userVolume = 0x100;
- // Apply it to all the channels
- for (int i = 0; i < 0x10; i++) {
- updateChanVolume(i);
- }
+ // Apply it
+ updateVolume();
}
void MusicPlayer::setGameVolume(uint16 volume, uint16 time) {
@@ -176,17 +130,15 @@ void MusicPlayer::setGameVolume(uint16 volume, uint16 time) {
_fadingEndVolume = 100;
}
-void MusicPlayer::startBackground() {
- debugC(3, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: startBackground()");
- if (!_isPlaying && _backgroundFileRef) {
- debugC(3, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Starting the background song (0x%4X)", _backgroundFileRef);
- play(_backgroundFileRef, true);
- }
-}
-
-void MusicPlayer::endTrack() {
- debugC(3, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: endTrack()");
+bool MusicPlayer::play(uint32 fileref, bool loop) {
+ // Unload the previous song
unload();
+
+ // Set the new state
+ _isPlaying = true;
+
+ // Load the new file
+ return load(fileref, loop);
}
void MusicPlayer::applyFading() {
@@ -212,13 +164,129 @@ void MusicPlayer::applyFading() {
}
}
- // Apply the new volume to all the channels
+ // Apply it
+ updateVolume();
+}
+
+void MusicPlayer::onTimer(void *refCon) {
+ debugC(9, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: onTimer()");
+ MusicPlayer *music = (MusicPlayer *)refCon;
+ Common::StackLock lock(music->_mutex);
+
+ // Apply the game volume fading
+ if (music->_gameVolume != music->_fadingEndVolume) {
+ // Apply the next step of the fading
+ music->applyFading();
+ }
+
+ // Handle internal timed events
+ music->onTimerInternal();
+}
+
+void MusicPlayer::unload() {
+ debugC(1, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Stopping the playback");
+
+ // Set the new state
+ _isPlaying = false;
+}
+
+
+// MusicPlayerMidi
+
+MusicPlayerMidi::MusicPlayerMidi(GroovieEngine *vm) :
+ MusicPlayer(vm), _midiParser(NULL), _data(NULL), _driver(NULL) {
+ // Initialize the channel volumes
for (int i = 0; i < 0x10; i++) {
- updateChanVolume(i);
+ _chanVolumes[i] = 0x7F;
+ }
+}
+
+MusicPlayerMidi::~MusicPlayerMidi() {
+ // Stop the callback
+ if (_driver)
+ _driver->setTimerCallback(NULL, NULL);
+
+ Common::StackLock lock(_mutex);
+
+ // Unload the parser
+ unload();
+ delete _midiParser;
+
+ // Unload the MIDI Driver
+ if (_driver)
+ _driver->close();
+ delete _driver;
+}
+
+int MusicPlayerMidi::open() {
+ // Don't ever call open without first setting the output driver!
+ if (!_driver)
+ return 255;
+
+ int ret = _driver->open();
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void MusicPlayerMidi::close() {}
+
+void MusicPlayerMidi::send(uint32 b) {
+ if ((b & 0xFFF0) == 0x07B0) { // Volume change
+ // Save the specific channel volume
+ byte chan = b & 0xF;
+ _chanVolumes[chan] = (b >> 16) & 0x7F;
+
+ // Send the updated value
+ updateChanVolume(chan);
+
+ return;
+ }
+ if (_driver)
+ _driver->send(b);
+}
+
+void MusicPlayerMidi::metaEvent(byte type, byte *data, uint16 length) {
+ switch (type) {
+ case 0x2F:
+ // End of Track, play the background song
+ endTrack();
+ break;
+ default:
+ if (_driver)
+ _driver->metaEvent(type, data, length);
+ break;
}
}
-void MusicPlayer::updateChanVolume(byte channel) {
+void MusicPlayerMidi::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
+ if (_driver)
+ _driver->setTimerCallback(timer_param, timer_proc);
+}
+
+uint32 MusicPlayerMidi::getBaseTempo(void) {
+ if (_driver)
+ return _driver->getBaseTempo();
+ else
+ return 0;
+}
+
+MidiChannel *MusicPlayerMidi::allocateChannel() {
+ if (_driver)
+ return _driver->allocateChannel();
+ else
+ return 0;
+}
+
+MidiChannel *MusicPlayerMidi::getPercussionChannel() {
+ if (_driver)
+ return _driver->getPercussionChannel();
+ else
+ return 0;
+}
+
+void MusicPlayerMidi::updateChanVolume(byte channel) {
// Generate a MIDI Control change message for the volume
uint32 b = 0x7B0;
@@ -230,76 +298,119 @@ void MusicPlayer::updateChanVolume(byte channel) {
val &= 0x7F;
// Send it to the driver
- _driver->send(b | (val << 16));
+ if (_driver)
+ _driver->send(b | (val << 16));
}
-bool MusicPlayer::play(uint32 fileref, bool loop) {
- // Unload the previous song
+void MusicPlayerMidi::endTrack() {
+ debugC(3, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: endTrack()");
unload();
+}
- // Set the looping option
- _midiParser->property(MidiParser::mpAutoLoop, loop);
+void MusicPlayerMidi::onTimerInternal() {
+ // TODO: We really only need to call this while music is playing.
+ if (_midiParser)
+ _midiParser->onTimer();
+}
- _isPlaying = true;
- // Load the new file
- return load(fileref);
+void MusicPlayerMidi::updateVolume() {
+ // Apply it to all the channels
+ for (int i = 0; i < 0x10; i++) {
+ updateChanVolume(i);
+ }
}
-bool MusicPlayer::load(uint32 fileref) {
- debugC(1, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Starting the playback of song: %04X", fileref);
+void MusicPlayerMidi::unload() {
+ MusicPlayer::unload();
- // Open the song resource
- Common::SeekableReadStream *xmidiFile = _vm->_resMan->open(fileref);
- if (!xmidiFile) {
- error("Groovie::Music: Couldn't find resource 0x%04X", fileref);
+ // Unload the parser data
+ if (_midiParser)
+ _midiParser->unloadMusic();
+
+ // Unload the data
+ delete[] _data;
+ _data = NULL;
+}
+
+bool MusicPlayerMidi::loadParser(Common::SeekableReadStream *stream, bool loop) {
+ if (!_midiParser)
return false;
- }
// Read the whole file to memory
- int length = xmidiFile->size();
+ int length = stream->size();
_data = new byte[length];
- xmidiFile->read(_data, length);
- delete xmidiFile;
+ stream->read(_data, length);
+ delete stream;
+
+ // Set the looping option
+ _midiParser->property(MidiParser::mpAutoLoop, loop);
// Start parsing the data
if (!_midiParser->loadMusic(_data, length)) {
- error("Groovie::Music: Invalid XMI file");
+ error("Groovie::Music: Couldn't parse the data");
return false;
}
// Activate the timer source
- _driver->setTimerCallback(this, &onTimer);
+ if (_driver)
+ _driver->setTimerCallback(this, &onTimer);
return true;
}
-void MusicPlayer::unload() {
- debugC(1, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Stopping the playback");
- _isPlaying = false;
- // Unload the parser
- _midiParser->unloadMusic();
+// MusicPlayerXMI
- // Unload the xmi file
- delete[] _data;
- _data = NULL;
-}
+MusicPlayerXMI::MusicPlayerXMI(GroovieEngine *vm, const Common::String &gtlName) :
+ MusicPlayerMidi(vm) {
+ // Create the parser
+ _midiParser = MidiParser::createParser_XMIDI();
-int MusicPlayer::open() {
- // Don't ever call open without first setting the output driver!
- if (!_driver)
- return 255;
+ // Create the driver
+ int driver = detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
+ _driver = createMidi(driver);
+ this->open();
- int ret = _driver->open();
- if (ret)
- return ret;
+ // Set the parser's driver
+ _midiParser->setMidiDriver(this);
- return 0;
+ // Set the timer rate
+ _midiParser->setTimerRate(_driver->getBaseTempo());
+
+ // Initialize the channel banks
+ for (int i = 0; i < 0x10; i++) {
+ _chanBanks[i] = 0;
+ }
+
+ // Load the Global Timbre Library
+ if (driver == MD_ADLIB) {
+ // MIDI through AdLib
+ _musicType = MD_ADLIB;
+ loadTimbres(gtlName + ".ad");
+
+ // Setup the percussion channel
+ for (unsigned int i = 0; i < _timbres.size(); i++) {
+ if (_timbres[i].bank == 0x7F)
+ setTimbreAD(9, _timbres[i]);
+ }
+ } else if ((driver == MD_MT32) || ConfMan.getBool("native_mt32")) {
+ // MT-32
+ _musicType = MD_MT32;
+ loadTimbres(gtlName + ".mt");
+ } else {
+ // GM
+ _musicType = 0;
+ }
}
-void MusicPlayer::close() {}
+MusicPlayerXMI::~MusicPlayerXMI() {
+ //~MusicPlayer();
+
+ // Unload the timbres
+ clearTimbres();
+}
-void MusicPlayer::send(uint32 b) {
+void MusicPlayerXMI::send(uint32 b) {
if ((b & 0xFFF0) == 0x72B0) { // XMIDI Patch Bank Select 114
// From AIL2's documentation: XMIDI Patch Bank Select controller (114)
// selects a bank to be used when searching the next patches
@@ -337,63 +448,24 @@ void MusicPlayer::send(uint32 b) {
// If we got here we couldn't find the patch, and the
// received message will be sent unchanged.
}
- } else if ((b & 0xFFF0) == 0x07B0) { // Volume change
- // Save the specific channel volume
- byte chan = b & 0xF;
- _chanVolumes[chan] = (b >> 16) & 0x7F;
-
- // Send the updated value
- updateChanVolume(chan);
-
- return;
- }
- _driver->send(b);
-}
-
-void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
- switch (type) {
- case 0x2F:
- // End of Track, play the background song
- endTrack();
- break;
- default:
- _driver->metaEvent(type, data, length);
- break;
}
+ MusicPlayerMidi::send(b);
}
-void MusicPlayer::onTimer(void *refCon) {
- debugC(9, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: onTimer()");
- MusicPlayer *music = (MusicPlayer *)refCon;
- Common::StackLock lock(music->_mutex);
+bool MusicPlayerXMI::load(uint32 fileref, bool loop) {
+ debugC(1, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Starting the playback of song: %04X", fileref);
- // Apply the game volume fading
- if (music->_gameVolume != music->_fadingEndVolume) {
- // Apply the next step of the fading
- music->applyFading();
+ // Open the song resource
+ Common::SeekableReadStream *file = _vm->_resMan->open(fileref);
+ if (!file) {
+ error("Groovie::Music: Couldn't find resource 0x%04X", fileref);
+ return false;
}
- // TODO: We really only need to call this while music is playing.
- music->_midiParser->onTimer();
-}
-
-void MusicPlayer::setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) {
- _driver->setTimerCallback(timer_param, timer_proc);
-}
-
-uint32 MusicPlayer::getBaseTempo(void) {
- return _driver->getBaseTempo();
-}
-
-MidiChannel *MusicPlayer::allocateChannel() {
- return _driver->allocateChannel();
-}
-
-MidiChannel *MusicPlayer::getPercussionChannel() {
- return _driver->getPercussionChannel();
+ return loadParser(file, loop);
}
-void MusicPlayer::loadTimbres(const Common::String &filename) {
+void MusicPlayerXMI::loadTimbres(const Common::String &filename) {
// Load the Global Timbre Library format as documented in AIL2
debugC(1, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Loading the GTL file %s", filename.c_str());
@@ -451,7 +523,7 @@ void MusicPlayer::loadTimbres(const Common::String &filename) {
delete gtl;
}
-void MusicPlayer::clearTimbres() {
+void MusicPlayerXMI::clearTimbres() {
// Delete the allocated data
int num = _timbres.size();
for (int i = 0; i < num; i++) {
@@ -462,7 +534,7 @@ void MusicPlayer::clearTimbres() {
_timbres.clear();
}
-void MusicPlayer::setTimbreAD(byte channel, const Timbre &timbre) {
+void MusicPlayerXMI::setTimbreAD(byte channel, const Timbre &timbre) {
// Verify the timbre size
if (timbre.size != 12) {
error("Groovie::Music: Invalid size for an AdLib timbre: %d", timbre.size);
@@ -514,7 +586,7 @@ void MusicPlayer::setTimbreAD(byte channel, const Timbre &timbre) {
}
}
-void MusicPlayer::setTimbreMT(byte channel, const Timbre &timbre) {
+void MusicPlayerXMI::setTimbreMT(byte channel, const Timbre &timbre) {
// Verify the timbre size
if (timbre.size != 0xF6) {
error("Groovie::Music: Invalid size for an MT-32 timbre: %d", timbre.size);
@@ -528,4 +600,28 @@ void MusicPlayer::setTimbreMT(byte channel, const Timbre &timbre) {
warning("Groovie::Music: Setting MT32 custom instruments isn't supported yet");
}
+
+// MusicPlayerMac
+
+MusicPlayerMac::MusicPlayerMac(GroovieEngine *vm) :
+ MusicPlayerMidi(vm) {
+}
+
+bool MusicPlayerMac::load(uint32 fileref, bool loop) {
+ debugC(1, kGroovieDebugMIDI | kGroovieDebugAll, "Groovie::Music: Starting the playback of song: %04X", fileref);
+ debug("Groovie::Music: Starting the playback of song: %04X %d", fileref, fileref);
+
+ // Open the song resource
+ /*
+ Common::SeekableReadStream *file = _vm->_resMan->open(fileref);
+ if (!file) {
+ error("Groovie::Music: Couldn't find resource 0x%04X", fileref);
+ return false;
+ }
+ */
+
+ //return loadParser(file, loop);
+ return false;
+}
+
} // End of Groovie namespace
diff --git a/engines/groovie/music.h b/engines/groovie/music.h
index 92c7afde70..db50930c37 100644
--- a/engines/groovie/music.h
+++ b/engines/groovie/music.h
@@ -34,10 +34,11 @@
namespace Groovie {
-class MusicPlayer : public MidiDriver {
+class MusicPlayer {
public:
- MusicPlayer(GroovieEngine *vm, const Common::String &gtlName);
- ~MusicPlayer();
+ MusicPlayer(GroovieEngine *vm);
+ virtual ~MusicPlayer() {}
+
void playSong(uint32 fileref);
void setBackgroundSong(uint32 fileref);
void playCD(uint8 track);
@@ -48,25 +49,89 @@ public:
void setGameVolume(uint16 volume, uint16 time);
private:
- // User volume
- uint16 _userVolume;
+ // Song playback
+ bool play(uint32 fileref, bool loop);
+ bool _isPlaying;
+ uint32 _backgroundFileRef;
+ uint8 _prevCDtrack;
- // Game volume
- uint16 _gameVolume;
+ // Volume fading
uint32 _fadingStartTime;
uint16 _fadingStartVolume;
uint16 _fadingEndVolume;
uint16 _fadingDuration;
- void endTrack();
void applyFading();
- // Song volumes
+protected:
+ GroovieEngine *_vm;
+
+ // Callback
+ static void onTimer(void *data);
+ virtual void onTimerInternal() {}
+ Common::Mutex _mutex;
+
+ // User volume
+ uint16 _userVolume;
+ // Game volume
+ uint16 _gameVolume;
+
+ // These are specific for each type of music
+ virtual void updateVolume() = 0;
+ virtual bool load(uint32 fileref, bool loop) = 0;
+ virtual void unload();
+};
+
+class MusicPlayerMidi : public MusicPlayer, public MidiDriver {
+public:
+ MusicPlayerMidi(GroovieEngine *vm);
+ ~MusicPlayerMidi();
+
+ // MidiDriver interface
+ int open();
+ void close();
+ void send(uint32 b);
+ void metaEvent(byte type, byte *data, uint16 length);
+ void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc);
+ uint32 getBaseTempo(void);
+ MidiChannel *allocateChannel();
+ MidiChannel *getPercussionChannel();
+
+private:
+ // Channel volumes
byte _chanVolumes[0x10];
void updateChanVolume(byte channel);
+ void endTrack();
+
+protected:
+ byte *_data;
+ MidiParser *_midiParser;
+ MidiDriver *_driver;
+
+ void onTimerInternal();
+ void updateVolume();
+ void unload();
+
+ bool loadParser(Common::SeekableReadStream *stream, bool loop);
+};
+
+class MusicPlayerXMI : public MusicPlayerMidi {
+public:
+ MusicPlayerXMI(GroovieEngine *vm, const Common::String &gtlName);
+ ~MusicPlayerXMI();
+
+ void send(uint32 b);
+
+protected:
+ bool load(uint32 fileref, bool loop);
+
+private:
// Channel banks
byte _chanBanks[0x10];
+ // Output music type
+ uint8 _musicType;
+
// Timbres
class Timbre {
public:
@@ -81,35 +146,14 @@ private:
void clearTimbres();
void setTimbreAD(byte channel, const Timbre &timbre);
void setTimbreMT(byte channel, const Timbre &timbre);
+};
+class MusicPlayerMac : public MusicPlayerMidi {
public:
- // MidiDriver interface
- int open();
- void close();
- void send(uint32 b);
- void metaEvent(byte type, byte *data, uint16 length);
- void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc);
- uint32 getBaseTempo(void);
- MidiChannel *allocateChannel();
- MidiChannel *getPercussionChannel();
+ MusicPlayerMac(GroovieEngine *vm);
-private:
- GroovieEngine *_vm;
- Common::Mutex _mutex;
- byte *_data;
- MidiParser *_midiParser;
- MidiDriver *_driver;
- uint8 _musicType;
- bool _isPlaying;
-
- uint32 _backgroundFileRef;
- uint8 _prevCDtrack;
-
- static void onTimer(void *data);
-
- bool play(uint32 fileref, bool loop);
- bool load(uint32 fileref);
- void unload();
+protected:
+ bool load(uint32 fileref, bool loop);
};
} // End of Groovie namespace
diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp
index 3491c54b36..63d15419d2 100644
--- a/engines/kyra/detection.cpp
+++ b/engines/kyra/detection.cpp
@@ -263,26 +263,12 @@ const KYRAGameDescription adGameDescs[] = {
KYRA1_TOWNS_SJIS_FLAGS
},
- { // PC-9821 (CD) version
- {
- "kyra1",
- "CD",
- {
- { "EMC.PAK", 0, "a046bb0b422061aab8e4c4689400343a", -1 },
- { "MUSIC98.PAK", 0, "02fc212f799331b769b274e33d87b37f", -1 },
- { NULL, 0, NULL, 0 }
- },
- Common::EN_ANY,
- Common::kPlatformPC98,
- ADGF_CD,
- Common::GUIO_NOSPEECH
- },
- KYRA1_TOWNS_FLAGS
- },
+ // PC-9801 floppy + CD / PC-9821 floppy version are all using the same data files,
+ // thus we will mark it as non CD game.
{
{
"kyra1",
- "CD",
+ "",
{
{ "JMC.PAK", 0, "9c5707a2a478e8167e44283246612d2c", -1 },
{ "MUSIC98.PAK", 0, "02fc212f799331b769b274e33d87b37f", -1 },
@@ -290,7 +276,7 @@ const KYRAGameDescription adGameDescs[] = {
},
Common::JA_JPN,
Common::kPlatformPC98,
- ADGF_CD,
+ ADGF_NO_FLAGS,
Common::GUIO_NOSPEECH
},
KYRA1_TOWNS_SJIS_FLAGS
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index 020e1ea3ea..7c4b073f29 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -2880,7 +2880,7 @@ void LoLEngine::drinkBezelCup(int numUses, int charNum) {
uint16 step = 0;
do {
- step = (step & 0xff) + (hpDiff * 256) / (bezelAnimData[numUses * 3 + 2]);
+ step = (step & 0xff) + (hpDiff * 256) / (bezelAnimData[numUses * 3 + 1]);
increaseCharacterHitpoints(charNum, step / 256, true);
gui_drawCharPortraitWithStats(charNum);
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index fa54bffa98..963dc3f4d6 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -1529,6 +1529,7 @@ void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int
_dsTmpWidth = shapeWidth;
int cnt = _dsOffscreenLeft;
int scaleState = (this->*_dsProcessMargin)(d, src, cnt);
+
if (_dsTmpWidth) {
cnt += shpWidthScaled1;
if (cnt > 0) {
@@ -1584,7 +1585,6 @@ int Screen::drawShapeMarginScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt)
while (cnt > 0) {
--cnt;
-
if (*src++)
continue;
@@ -1611,7 +1611,6 @@ int Screen::drawShapeMarginScaleDownwind(uint8 *&dst, const uint8 *&src, int &cn
while (cnt > 0) {
--cnt;
-
if (*src++)
continue;
@@ -1640,10 +1639,11 @@ int Screen::drawShapeSkipScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt) {
return 0;
do {
+ --cnt;
if (*src++)
continue;
cnt = cnt + 1 - (*src++);
- } while (--cnt > 0);
+ } while (cnt > 0);
return 0;
}
@@ -1656,16 +1656,17 @@ int Screen::drawShapeSkipScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt)
return 0;
do {
+ --cnt;
if (*src++)
continue;
found = true;
cnt = cnt + 1 - (*src++);
- } while (--cnt > 0);
+ } while (cnt > 0);
return found ? 0 : _dsOffscreenScaleVal1;
}
-void Screen::drawShapeProcessLineNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16) {
+void Screen::drawShapeProcessLineNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int16) {
do {
uint8 c = *src++;
if (c) {
@@ -1680,7 +1681,7 @@ void Screen::drawShapeProcessLineNoScaleUpwind(uint8 *&dst, const uint8 *&src, i
} while (cnt > 0);
}
-void Screen::drawShapeProcessLineNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16) {
+void Screen::drawShapeProcessLineNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int16) {
do {
uint8 c = *src++;
if (c) {
@@ -1695,7 +1696,7 @@ void Screen::drawShapeProcessLineNoScaleDownwind(uint8 *&dst, const uint8 *&src,
} while (cnt > 0);
}
-void Screen::drawShapeProcessLineScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16 scaleState) {
+void Screen::drawShapeProcessLineScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int16 scaleState) {
int c = 0;
do {
@@ -1723,7 +1724,7 @@ void Screen::drawShapeProcessLineScaleUpwind(uint8 *&dst, const uint8 *&src, int
cnt = -1;
}
-void Screen::drawShapeProcessLineScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16 scaleState) {
+void Screen::drawShapeProcessLineScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int16 scaleState) {
int c = 0;
do {
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 390d058bb8..956bd7107e 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -421,10 +421,10 @@ protected:
int drawShapeMarginScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt);
int drawShapeSkipScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt);
int drawShapeSkipScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt);
- void drawShapeProcessLineNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16 scaleState);
- void drawShapeProcessLineNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16 scaleState);
- void drawShapeProcessLineScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16 scaleState);
- void drawShapeProcessLineScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, uint16 scaleState);
+ void drawShapeProcessLineNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int16 scaleState);
+ void drawShapeProcessLineNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int16 scaleState);
+ void drawShapeProcessLineScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int16 scaleState);
+ void drawShapeProcessLineScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int16 scaleState);
void drawShapePlotType0(uint8 *dst, uint8 cmd);
void drawShapePlotType1(uint8 *dst, uint8 cmd);
@@ -446,7 +446,7 @@ protected:
void drawShapePlotType52(uint8 *dst, uint8 cmd);
typedef int (Screen::*DsMarginSkipFunc)(uint8 *&dst, const uint8 *&src, int &cnt);
- typedef void (Screen::*DsLineFunc)(uint8 *&dst, const uint8 *&src, int &cnt, uint16 scaleState);
+ typedef void (Screen::*DsLineFunc)(uint8 *&dst, const uint8 *&src, int &cnt, int16 scaleState);
typedef void (Screen::*DsPlotFunc)(uint8 *dst, uint8 cmd);
DsMarginSkipFunc _dsProcessMargin;
diff --git a/engines/kyra/screen_lol.cpp b/engines/kyra/screen_lol.cpp
index b9bf9961c5..46b243a4cf 100644
--- a/engines/kyra/screen_lol.cpp
+++ b/engines/kyra/screen_lol.cpp
@@ -44,8 +44,6 @@ Screen_LoL::Screen_LoL(LoLEngine *vm, OSystem *system) : Screen_v2(vm, system),
_fadeFlag = 2;
_curDimIndex = 0;
-
- _internDimX = _internDimY = _internDimW = _internDimH = _internDimDstX = _internBlockWidth = _internDimDstY = _internBlockHeight = _internDimU5 = _internDimU6 = _internBlockWidth2 = _internDimU8 = 0;
}
Screen_LoL::~Screen_LoL() {
@@ -588,44 +586,25 @@ void Screen_LoL::copyRegionSpecial(int page1, int w1, int h1, int x1, int y1, in
va_end(args);
}
- // _internDimH: h0
-// _internDimW: w0
-// _internDimDstX: x1
-// _internDimDstY: y1
-// _internBlockWidth: w1
-// _internBlockHeight: h1
-// _internDimU5: x2
-// _internDimU6: y2
-// _internBlockWidth2: w2
-
- _internDimX = _internDimY = 0;
- _internDimW = w1;
- _internDimH = h1;
- calcBoundariesIntern(x1, y1, w3, h3);
- if (_internBlockWidth == -1)
+ int na = 0, nb = 0, nc = w3;
+ if (!calcBounds(w1, h1, x1, y1, w3, h3, na, nb, nc))
return;
- int iu5_1 = _internDimU5;
- int iu6_1 = _internDimU6;
- int ibw_1 = _internBlockWidth;
- int ibh_1 = _internBlockHeight;
- int dx_1 = _internDimDstX;
- int dy_1 = _internDimDstY;
-
- _internDimX = _internDimY = 0;
- _internDimW = w2;
- _internDimH = h2;
+ int iu5_1 = na;
+ int iu6_1 = nb;
+ int ibw_1 = w3;
+ int dx_1 = x1;
+ int dy_1 = y1;
- calcBoundariesIntern(x2, y2, ibw_1, ibh_1);
- if (_internBlockWidth == -1)
+ if (!calcBounds(w2, h2, x2, y2, w3, h3, na, nb, nc))
return;
- int iu5_2 = _internDimU5;
- int iu6_2 = _internDimU6;
- int ibw_2 = _internBlockWidth;
- int ibh_2 = _internBlockHeight;
- int dx_2 = _internDimDstX;
- int dy_2 = _internDimDstY;
+ int iu5_2 = na;
+ int iu6_2 = nb;
+ int ibw_2 = w3;
+ int ibh_2 = h3;
+ int dx_2 = x2;
+ int dy_2 = y2;
uint8 *src = getPagePtr(page1) + (dy_1 + iu6_2) * w1;
uint8 *dst = getPagePtr(page2) + (dy_2 + iu6_1) * w2;
@@ -670,7 +649,7 @@ void Screen_LoL::copyRegionSpecial(int page1, int w1, int h1, int x1, int y1, in
}
if (!page2)
- addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
+ addDirtyRect(x2, y2, w2, h2);
}
void Screen_LoL::copyBlockAndApplyOverlay(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, uint8 *ovl) {
@@ -678,23 +657,23 @@ void Screen_LoL::copyBlockAndApplyOverlay(int page1, int x1, int y1, int page2,
return;
const ScreenDim *cdim = getScreenDim(dim);
- _internDimX = cdim->sx << 3;
- _internDimY = cdim->sy;
- _internDimW = cdim->w << 3;
- _internDimH = cdim->h;
+ int ix = cdim->sx << 3;
+ int iy = cdim->sy;
+ int iw = cdim->w << 3;
+ int ih = cdim->h;
- calcBoundariesIntern(x2, y2, w, h);
- if (_internBlockWidth == -1)
+ int na = 0, nb = 0, nc = w;
+ if (!calcBounds(iw, ih, x2, y2, w, h, na, nb, nc))
return;
uint8 *src = getPagePtr(page1) + y1 * 320 + x1;
- uint8 *dst = getPagePtr(page2) + (_internDimDstY + _internDimY) * 320;
+ uint8 *dst = getPagePtr(page2) + (y2 + iy) * 320;
- for (int i = 0; i < _internBlockHeight; i++) {
- uint8 *s = src + _internDimU5;
- uint8 *d = dst + (_internDimDstX + _internDimX);
+ for (int i = 0; i < h; i++) {
+ uint8 *s = src + na;
+ uint8 *d = dst + (x2 + ix);
- for (int ii = 0; ii < _internBlockWidth; ii++) {
+ for (int ii = 0; ii < w; ii++) {
uint8 p = ovl[*s++];
if (p)
*d = p;
@@ -706,7 +685,7 @@ void Screen_LoL::copyBlockAndApplyOverlay(int page1, int x1, int y1, int page2,
}
if (!page2)
- addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
+ addDirtyRect(x2 + ix, y2 + iy, w, h);
}
void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x2, int y2, int w, int h, int dim, int flag, uint8 *ovl) {
@@ -714,26 +693,26 @@ void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x
return;
const ScreenDim *cdim = getScreenDim(dim);
- _internDimX = cdim->sx << 3;
- _internDimY = cdim->sy;
- _internDimW = cdim->w << 3;
- _internDimH = cdim->h;
+ int ix = cdim->sx << 3;
+ int iy = cdim->sy;
+ int iw = cdim->w << 3;
+ int ih = cdim->h;
- calcBoundariesIntern(x2, y2, w, h);
- if (_internBlockWidth == -1)
+ int na = 0, nb = 0, nc = w;
+ if (!calcBounds(iw, ih, x2, y2, w, h, na, nb, nc))
return;
uint8 *src = getPagePtr(page1) + y1 * 320 + x1;
- uint8 *dst = getPagePtr(page2) + (_internDimDstY + _internDimY) * 320;
+ uint8 *dst = getPagePtr(page2) + (y2 + iy) * 320;
- for (int i = 0; i < _internBlockHeight; i++) {
- uint8 *s = src + _internDimU5;
- uint8 *d = dst + (_internDimDstX + _internDimX);
+ for (int i = 0; i < h; i++) {
+ uint8 *s = src + na;
+ uint8 *d = dst + (x2 + ix);
if (flag)
d += (i >> 1);
- for (int ii = 0; ii < _internBlockWidth; ii++) {
+ for (int ii = 0; ii < w; ii++) {
if (*s++)
*d = ovl[*d];
d++;
@@ -744,7 +723,7 @@ void Screen_LoL::applyOverlaySpecial(int page1, int x1, int y1, int page2, int x
}
if (!page2)
- addDirtyRect(_internDimDstX + _internDimX, _internDimDstY + _internDimY, _internBlockWidth, _internBlockHeight);
+ addDirtyRect(x2 + ix, y2 + iy, w, h);
}
void Screen_LoL::copyBlockAndApplyOverlayOutro(int srcPage, int dstPage, const uint8 *ovl) {
@@ -778,59 +757,6 @@ void Screen_LoL::copyBlockAndApplyOverlayOutro(int srcPage, int dstPage, const u
}
}
-void Screen_LoL::calcBoundariesIntern(int dstX, int dstY, int width, int height) {
- _internBlockWidth = _internBlockWidth2 = width;
- _internBlockHeight = height;
- _internDimDstX = dstX;
- _internDimDstY = dstY;
-
- _internDimU5 = _internDimU6 = _internDimU8 = 0;
-
- int t = _internDimDstX + _internBlockWidth;
- if (t <= 0) {
- _internBlockWidth = _internBlockHeight = -1;
- return;
- }
-
- if (t <= _internDimDstX) {
- _internDimU5 = _internBlockWidth - t;
- _internBlockWidth = t;
- _internDimDstX = 0;
- }
-
- t = _internDimW - _internDimDstX;
- if (t <= 0) {
- _internBlockWidth = _internBlockHeight = -1;
- return;
- }
-
- if (t <= _internBlockWidth)
- _internBlockWidth = t;
-
- _internBlockWidth2 -= _internBlockWidth;
-
- t = _internDimDstY + _internBlockHeight;
- if (t <= 0) {
- _internBlockWidth = _internBlockHeight = -1;
- return;
- }
-
- if (t <= _internDimDstY) {
- _internDimU6 = _internBlockHeight - t;
- _internBlockHeight = t;
- _internDimDstY = 0;
- }
-
- t = _internDimH - _internDimDstY;
- if (t <= 0) {
- _internBlockWidth = _internBlockHeight = -1;
- return;
- }
-
- if (t <= _internBlockHeight)
- _internBlockHeight = t;
-}
-
void Screen_LoL::fadeToBlack(int delay, const UpdateFunctor *upFunc) {
Screen::fadeToBlack(delay, upFunc);
_fadeFlag = 2;
diff --git a/engines/kyra/screen_lol.h b/engines/kyra/screen_lol.h
index 2545064b58..f9cd7133de 100644
--- a/engines/kyra/screen_lol.h
+++ b/engines/kyra/screen_lol.h
@@ -112,22 +112,6 @@ private:
static const uint8 _paletteConvTable[256];
void mergeOverlay(int x, int y, int w, int h);
void postProcessCursor(uint8 *data, int width, int height, int pitch);
-
- // magic atlas
- void calcBoundariesIntern(int dstX, int dstY, int c, int d);
-
- int _internDimX;
- int _internDimY;
- int _internDimW;
- int _internDimH;
- int _internDimDstX;
- int _internBlockWidth;
- int _internDimDstY;
- int _internBlockHeight;
- int _internDimU5;
- int _internDimU6;
- int _internBlockWidth2;
- int _internDimU8;
};
} // end of namespace Kyra
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index bf919c3a25..d978915741 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -67,6 +67,7 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
// Kernel
// DCmd_Register("classes", WRAP_METHOD(Console, cmdClasses)); // TODO
DCmd_Register("opcodes", WRAP_METHOD(Console, cmdOpcodes));
+ DCmd_Register("selector", WRAP_METHOD(Console, cmdSelector));
DCmd_Register("selectors", WRAP_METHOD(Console, cmdSelectors));
DCmd_Register("functions", WRAP_METHOD(Console, cmdKernelFunctions));
DCmd_Register("class_table", WRAP_METHOD(Console, cmdClassTable));
@@ -239,6 +240,7 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf("Kernel:\n");
DebugPrintf(" opcodes - Lists the opcode names\n");
DebugPrintf(" selectors - Lists the selector names\n");
+ DebugPrintf(" selector - Attempts to find the requested selector by name\n");
DebugPrintf(" functions - Lists the kernel functions\n");
DebugPrintf(" class_table - Shows the available classes\n");
DebugPrintf("\n");
@@ -392,6 +394,25 @@ bool Console::cmdOpcodes(int argc, const char **argv) {
return true;
}
+bool Console::cmdSelector(int argc, const char **argv) {
+ if (argc < 2) {
+ DebugPrintf("Attempts to find the requested selector by name.\n");
+ DebugPrintf("Usage: %s <selector name>\n", argv[0]);
+ return true;
+ }
+
+ for (uint seeker = 0; seeker < _vm->_gamestate->_kernel->getSelectorNamesSize(); seeker++) {
+ if (!scumm_stricmp(_vm->_gamestate->_kernel->getSelectorName(seeker).c_str(), argv[1])) {
+ DebugPrintf("Selector %s found at %03x\n", _vm->_gamestate->_kernel->getSelectorName(seeker).c_str(), seeker);
+ return true;
+ }
+ }
+
+ DebugPrintf("Selector %s wasn't found\n", argv[1]);
+
+ return true;
+}
+
bool Console::cmdSelectors(int argc, const char **argv) {
DebugPrintf("Selector names in numeric order:\n");
for (uint seeker = 0; seeker < _vm->_gamestate->_kernel->getSelectorNamesSize(); seeker++) {
@@ -546,11 +567,6 @@ bool Console::cmdHexDump(int argc, const char **argv) {
}
int resNum = atoi(argv[2]);
- if (resNum == 0) {
- DebugPrintf("The resource number specified is not a number");
- return true;
- }
-
ResourceType res = parseResourceType(argv[1]);
if (res == kResourceTypeInvalid)
@@ -607,11 +623,6 @@ bool Console::cmdResourceSize(int argc, const char **argv) {
}
int resNum = atoi(argv[2]);
- if (resNum == 0) {
- DebugPrintf("The resource number specified is not a number");
- return true;
- }
-
ResourceType res = parseResourceType(argv[1]);
if (res == kResourceTypeInvalid)
diff --git a/engines/sci/console.h b/engines/sci/console.h
index 84a8d2f942..bc07ddb530 100644
--- a/engines/sci/console.h
+++ b/engines/sci/console.h
@@ -52,6 +52,7 @@ private:
// Kernel
// bool cmdClasses(int argc, const char **argv); // TODO
bool cmdOpcodes(int argc, const char **argv);
+ bool cmdSelector(int argc, const char **argv);
bool cmdSelectors(int argc, const char **argv);
bool cmdKernelFunctions(int argc, const char **argv);
bool cmdClassTable(int argc, const char **argv);
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index f04c390944..79088c86ff 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -34,10 +34,6 @@ namespace Sci {
#define GF_FOR_SCI0_BEFORE_395 (GF_SCI0_OLD | GF_SCI0_OLDGETTIME)
#define GF_FOR_SCI0_BEFORE_629 GF_SCI0_OLDGETTIME
-// SCI1
-#define GF_FOR_SCI1_200_OR_LATER GF_SCI1_LOFSABSOLUTE
-#define GF_FOR_SCI1_510_OR_LATER (GF_SCI1_LOFSABSOLUTE | GF_SCI1_NEWDOSOUND)
-
// Titles of the games
static const PlainGameDescriptor SciGameTitles[] = {
{"sci", "Sierra SCI Game"},
@@ -147,7 +143,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380},
{"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -162,7 +158,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309},
{"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -188,7 +184,19 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832},
{"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
+ SCI_VERSION_AUTODETECT,
+ SCI_VERSION_1
+ },
+
+ // Castle of Dr. Brain - English DOS Floppy 1.1
+ {{"castlebrain", "", {
+ {"resource.map", 0, "f77728304c70017c54793eb6ca648174", 2745},
+ {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 347071},
+ {"resource.001", 0, "13e81e1839cd7b216d2bb5615c1ca160", 796776},
+ {"resource.002", 0, "930e416bec196b9703a331d81b3d66f2", 1283812},
+ {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -200,7 +208,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694},
{"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302},
{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -382,7 +390,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002},
{"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -399,7 +407,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950},
{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -416,7 +424,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462},
{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -432,7 +440,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237},
{"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -449,7 +457,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243},
{"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA,
+ GF_SCI1_EGA,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -477,7 +485,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914},
{"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -514,7 +522,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816},
{"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -528,7 +536,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316},
{"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -542,7 +550,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581},
{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -557,7 +565,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033},
{"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993},
{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -874,7 +882,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791},
{"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -887,7 +895,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735},
{"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -900,7 +908,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845},
{"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1111,7 +1119,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368},
{"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1482,7 +1490,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041},
{"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1495,7 +1503,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226},
{"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1508,7 +1516,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688},
{"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1535,7 +1543,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908},
{"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556},
{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1549,7 +1557,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759},
{"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160},
{NULL, 0, NULL, 0}}, Common::RU_RUS, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1716,7 +1724,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621},
{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1735,7 +1743,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966},
{"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1764,7 +1772,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1782,7 +1790,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1801,7 +1809,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842},
{NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1820,7 +1828,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136},
{"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222},
{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -1831,7 +1839,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919},
{"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981},
{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2157,7 +2165,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158},
{"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2328,7 +2336,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891},
{"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2345,7 +2353,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738},
{"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2361,7 +2369,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791},
{"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2374,7 +2382,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150},
{"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2390,7 +2398,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956},
{"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2567,7 +2575,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_AUTODETECT,
+ SCI_VERSION_1,
SCI_VERSION_1_1
},
@@ -2578,7 +2586,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH},
0,
- SCI_VERSION_AUTODETECT,
+ SCI_VERSION_1,
SCI_VERSION_1_1
},
@@ -2854,7 +2862,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515},
{"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2870,7 +2878,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262},
{"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2898,7 +2906,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325},
{"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812},
{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -2928,7 +2936,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 545053},
{"resource.005", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 687507},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER,
+ 0,
SCI_VERSION_0,
SCI_VERSION_0
},
@@ -3013,7 +3021,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296},
{"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3030,7 +3038,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745},
{"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3042,7 +3050,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124},
{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3054,7 +3062,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646},
{"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3071,7 +3079,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631},
{"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3088,7 +3096,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765},
{"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3104,7 +3112,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000},
{"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880},
{NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3117,7 +3125,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
{NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA,
+ GF_SCI1_EGA,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3130,7 +3138,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088},
{"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC98, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA,
+ GF_SCI1_EGA,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3158,7 +3166,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752},
{"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328},
{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3173,7 +3181,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801},
{"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408},
{NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3190,7 +3198,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368},
{"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717},
{NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH},
- GF_FOR_SCI1_200_OR_LATER,
+ 0,
SCI_VERSION_AUTODETECT,
SCI_VERSION_1
},
@@ -3413,7 +3421,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
FANMADE("The Legend of the Lost Jewel", "ba1bca315e3818c5626eda51bcfbcccf", 636, "9b0736d69924af0cff32a0f78db96855", 300398),
// FIXME: The vga demo does not have a resource.000/001 file.
- //FANMADE_V("SCI VGA Demo", "00b1abd87bad356b90fcdfcb6132c26f", 8, "", 0, GF_FOR_SCI1_510_OR_LATER),
+ //FANMADE_V("SCI VGA Demo", "00b1abd87bad356b90fcdfcb6132c26f", 8, "", 0, 0),
{AD_TABLE_END_MARKER, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0}
};
diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp
index a1e2c24955..a1e7569967 100644
--- a/engines/sci/engine/game.cpp
+++ b/engines/sci/engine/game.cpp
@@ -377,7 +377,7 @@ int script_init_engine(EngineState *s) {
s->bp_list = NULL; // No breakpoints defined
s->have_bp = 0;
- if ((s->_flags & GF_SCI1_LOFSABSOLUTE) && s->_version < SCI_VERSION_1_1)
+ if (s->_kernel->hasLofsAbsolute())
s->seg_manager->setExportWidth(1);
else
s->seg_manager->setExportWidth(0);
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index b03a073d8f..8ac629d87b 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -356,35 +356,54 @@ static const char *argtype_description[] = {
Kernel::Kernel(ResourceManager *resmgr, bool isOldSci0) : _resmgr(resmgr) {
memset(&_selectorMap, 0, sizeof(_selectorMap)); // FIXME: Remove this once/if we C++ify selector_map_t
- loadKernelNames();
-
+ loadSelectorNames(isOldSci0);
+ mapSelectors(); // Map a few special selectors for later use
loadOpcodes();
+ loadKernelNames();
+ mapFunctions(); // Map the kernel functions
- if (!loadSelectorNames(isOldSci0)) {
- error("Kernel: Could not retrieve selector names");
- }
-
- // Map the kernel functions
- mapFunctions();
+ // SCI0 games using old graphics functions (before version 0.000.502) did not have a
+ // motionCue selector
+ _oldGfxFunctions = (_selectorMap.motionCue == -1 && _resmgr->_sciVersion == SCI_VERSION_0);
- // Map a few special selectors for later use
- mapSelectors();
+ // SCI1 games which use absolute lofs have the egoMoveSpeed selector
+ _hasLofsAbsolute = (_selectorMap.egoMoveSpeed != -1 && _resmgr->_sciVersion < SCI_VERSION_1_1);
- // SCI0 games using old graphics functions (before version 0.000.502) have the TimesSin
- // kernel function, whereas newer games have the SinMult kernel function in its place
- _oldGfxFunctions = !hasKernelFunction("SinMult");
+ printAutoDetectedFeatures();
}
Kernel::~Kernel() {
}
-bool Kernel::loadSelectorNames(bool isOldSci0) {
+void Kernel::printAutoDetectedFeatures() {
+ if (_oldGfxFunctions)
+ printf("Kernel auto-detection: game found to be using old graphics functions\n");
+ else
+ printf("Kernel auto-detection: game found to be using newer graphics functions\n");
+
+ if (_hasLofsAbsolute)
+ printf("Kernel auto-detection: game found to be using absolute parameters for lofs\n");
+ else
+ printf("Kernel auto-detection: game found to be using relative parameters for lofs\n");
+
+ if (_selectorMap.setVol != -1)
+ printf("Kernel auto-detection: using SCI1 sound functions\n");
+ else if (_selectorMap.nodePtr != -1)
+ printf("Kernel auto-detection: using SCI01 sound functions\n");
+ else
+ printf("Kernel auto-detection: using SCI0 sound functions\n");
+
+ if (_resmgr->_sciVersion == SCI_VERSION_0 && _selectorMap.sightAngle != -1)
+ printf("Kernel auto-detection: found SCI0 game using a SCI1 kernel table\n");
+}
+
+void Kernel::loadSelectorNames(bool isOldSci0) {
int count;
Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0);
if (!r) // No such resource?
- return false;
+ error("Kernel: Could not retrieve selector names");
count = READ_LE_UINT16(r->data) + 1; // Counter is slightly off
@@ -394,14 +413,13 @@ bool Kernel::loadSelectorNames(bool isOldSci0) {
Common::String tmp((const char *)r->data + offset + 2, len);
_selectorNames.push_back(tmp);
+ //printf("%s\n", tmp.c_str()); // debug
// Early SCI versions used the LSB in the selector ID as a read/write
// toggle. To compensate for that, we add every selector name twice.
if (isOldSci0)
_selectorNames.push_back(tmp);
}
-
- return true;
}
bool Kernel::loadOpcodes() {
@@ -732,46 +750,39 @@ reg_t *kernel_dereference_reg_pointer(EngineState *s, reg_t pointer, int entries
return (reg_t*)_kernel_dereference_pointer(s, pointer, entries, sizeof(reg_t));
}
-void setDefaultKernelNames(Common::StringList &names) {
- names.resize(SCI_KNAMES_DEFAULT_ENTRIES_NR);
- for (int i = 0; i < SCI_KNAMES_DEFAULT_ENTRIES_NR; i++)
- names[i] = sci_default_knames[i];
-}
-
-static void vocab_get_knames0(ResourceManager *resmgr, Common::StringList &names) {
- int count, i, index = 2, empty_to_add = 1;
- Resource *r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES), 0);
-
- if (!r) { // No kernel name table found? Fall back to default table
- setDefaultKernelNames(names);
- return;
- }
-
- count = READ_LE_UINT16(r->data);
-
- if (count > 1023) {
- // Newer kernel name table, found in KQ1. We can use the default table here
- setDefaultKernelNames(names);
- return;
- }
-
- if (count < SCI0_KNAMES_WELL_DEFINED) {
- empty_to_add = SCI0_KNAMES_WELL_DEFINED - count;
- sciprintf("Less than %d kernel functions; adding %d\n", SCI0_KNAMES_WELL_DEFINED, empty_to_add);
- }
+void Kernel::setDefaultKernelNames() {
+ bool isSci0 = (_resmgr->_sciVersion == SCI_VERSION_0);
+ int offset = 0;
+
+ // Check if we have a SCI01 game which uses a SCI1 kernel table (e.g. the KQ1 demo
+ // and full version). We do this by checking if the sightAngle selector exists, as no
+ // SCI0 game seems to have it
+ if (_selectorMap.sightAngle != -1 && isSci0)
+ isSci0 = false;
+
+ _kernelNames.resize(SCI_KNAMES_DEFAULT_ENTRIES_NR + (isSci0 ? 4 : 0));
+ for (int i = 0; i < SCI_KNAMES_DEFAULT_ENTRIES_NR; i++) {
+ // In SCI0, Platform was DoAvoider
+ if (!strcmp(sci_default_knames[i], "Platform") && isSci0) {
+ _kernelNames[i + offset] = "DoAvoider";
+ continue;
+ }
- names.resize(count + 1 + empty_to_add);
+ _kernelNames[i + offset] = sci_default_knames[i];
- for (i = 0; i < count; i++) {
- int offset = READ_LE_UINT16(r->data + index);
- int len = READ_LE_UINT16(r->data + offset);
- //fprintf(stderr,"Getting name %d of %d...\n", i, count);
- index += 2;
- names[i] = Common::String((const char *)r->data + offset + 2, len);
+ // SCI0 has 4 extra functions between SetCursor (0x28) and Savegame
+ if (!strcmp(sci_default_knames[i], "SetCursor") && isSci0) {
+ _kernelNames[i + 1] = "FOpen";
+ _kernelNames[i + 2] = "FPuts";
+ _kernelNames[i + 3] = "FGets";
+ _kernelNames[i + 4] = "FClose";
+ offset = 4;
+ }
}
- for (i = 0; i < empty_to_add; i++) {
- names[count + i] = SCRIPT_UNKNOWN_FUNCTION_STRING;
+ if (_resmgr->_sciVersion == SCI_VERSION_1_1) {
+ // KQ6CD calls unimplemented function 0x26
+ _kernelNames[0x26] = "Dummy";
}
}
@@ -810,16 +821,9 @@ bool Kernel::loadKernelNames() {
case SCI_VERSION_01:
case SCI_VERSION_01_VGA:
case SCI_VERSION_01_VGA_ODD:
- vocab_get_knames0(_resmgr, _kernelNames);
- break;
- case SCI_VERSION_1_EARLY:
- case SCI_VERSION_1_LATE:
+ case SCI_VERSION_1:
case SCI_VERSION_1_1:
- setDefaultKernelNames(_kernelNames);
- if (_resmgr->_sciVersion == SCI_VERSION_1_1) {
- // KQ6CD calls unimplemented function 0x26
- _kernelNames[0x26] = "Dummy";
- }
+ setDefaultKernelNames();
break;
#ifdef ENABLE_SCI32
case SCI_VERSION_32:
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index e3ecddca26..da3d255329 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -83,14 +83,22 @@ public:
*/
bool hasKernelFunction(const char *functionName) const;
- /* Applies to all versions before 0.000.502
- ** Old SCI versions used to interpret the third DrawPic() parameter inversely,
- ** with the opposite default value (obviously).
- ** Also, they used 15 priority zones from 42 to 200 instead of 14 priority
- ** zones from 42 to 190.
- */
+ /**
+ * Applies to all versions before 0.000.502
+ * Old SCI versions used to interpret the third DrawPic() parameter inversely,
+ * with the opposite default value (obviously).
+ * Also, they used 15 priority zones from 42 to 200 instead of 14 priority
+ * zones from 42 to 190.
+ */
bool usesOldGfxFunctions() const { return _oldGfxFunctions; }
+ /**
+ * Applies to all SCI1 versions after 1.000.200
+ * In late SCI1 versions, the argument of lofs[as] instructions
+ * is absolute rather than relative.
+ */
+ bool hasLofsAbsolute() const { return _hasLofsAbsolute; }
+
// Script dissection/dumping functions
void dissectScript(int scriptNumber, Vocabulary *vocab);
void dumpScriptObject(char *data, int seeker, int objsize);
@@ -112,10 +120,19 @@ private:
bool loadKernelNames();
/**
- * Loads the kernel selector names.
- * @return True upon success, false otherwise.
- */
- bool loadSelectorNames(bool isOldSci0);
+ * Sets the default kernel function names, based on the SCI version used
+ */
+ void setDefaultKernelNames();
+
+ /**
+ * Loads the kernel selector names.
+ */
+ void loadSelectorNames(bool isOldSci0);
+
+ /**
+ * Prints auto-detected features from selectors
+ */
+ void printAutoDetectedFeatures();
/**
* Maps special selectors
@@ -135,6 +152,7 @@ private:
ResourceManager *_resmgr;
bool _oldGfxFunctions;
+ bool _hasLofsAbsolute;
// Kernel-related lists
/**
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp
index 6e737597d6..9d19f3f0c9 100644
--- a/engines/sci/engine/kgraphics.cpp
+++ b/engines/sci/engine/kgraphics.cpp
@@ -304,7 +304,9 @@ static gfx_color_t graph_map_color(EngineState *s, int color, int priority, int
reg_t kSetCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) {
switch (argc) {
case 1 :
- if (s->_version < SCI_VERSION_1_1) {
+ if (s->_version < SCI_VERSION_1) {
+ GFX_ASSERT(gfxop_set_pointer_cursor(s->gfx_state, argv[0].toSint16()));
+ } else if (s->_version == SCI_VERSION_1) {
if (argv[0].toSint16() <= 1) {
// Newer (SCI1.1) semantics: show/hide cursor
CursorMan.showMouse(argv[0].toSint16() != 0);
@@ -312,13 +314,16 @@ reg_t kSetCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) {
// Pre-SCI1.1: set cursor according to the first parameter
GFX_ASSERT(gfxop_set_pointer_cursor(s->gfx_state, argv[0].toSint16()));
}
- } else {
+ } else if (s->_version >= SCI_VERSION_1_1) {
// SCI1.1: Show/hide cursor
CursorMan.showMouse(argv[0].toSint16() != 0);
}
break;
case 2 :
- if (s->_version < SCI_VERSION_1_1) {
+ if (s->_version < SCI_VERSION_1) {
+ GFX_ASSERT(gfxop_set_pointer_cursor(s->gfx_state,
+ argv[1].toSint16() == 0 ? GFXOP_NO_POINTER : argv[0].toSint16()));
+ } else if (s->_version == SCI_VERSION_1) {
// Pre-SCI1.1: set cursor according to the first parameter, and toggle its
// visibility based on the second parameter
// Some late SCI1 games actually use the SCI1.1 version of this call (EcoQuest 1
@@ -337,7 +342,7 @@ reg_t kSetCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) {
GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state,
Common::Point(argv[0].toUint16(), argv[1].toUint16())));
}
- } else {
+ } else if (s->_version >= SCI_VERSION_1_1) {
// SCI1.1 and newer: set pointer position
GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state,
Common::Point(argv[0].toUint16(), argv[1].toUint16())));
diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp
index bb27589d84..fa64ab4086 100644
--- a/engines/sci/engine/ksound.cpp
+++ b/engines/sci/engine/ksound.cpp
@@ -964,9 +964,9 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) {
}
reg_t kDoSound(EngineState *s, int funct_nr, int argc, reg_t *argv) {
- if (s->_version >= SCI_VERSION_1_1 || s->_flags & GF_SCI1_NEWDOSOUND)
+ if (s->_kernel->_selectorMap.setVol != -1)
return kDoSound_SCI1(s, funct_nr, argc, argv);
- else if (s->_version >= SCI_VERSION_01)
+ else if (s->_kernel->_selectorMap.nodePtr != -1)
return kDoSound_SCI01(s, funct_nr, argc, argv);
else
return kDoSound_SCI0(s, funct_nr, argc, argv);
diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp
index fb094e00f6..d4bd094b4a 100644
--- a/engines/sci/engine/script.cpp
+++ b/engines/sci/engine/script.cpp
@@ -97,8 +97,7 @@ void script_adjust_opcode_formats(int res_version) {
break;
case SCI_VERSION_01_VGA:
case SCI_VERSION_01_VGA_ODD:
- case SCI_VERSION_1_EARLY:
- case SCI_VERSION_1_LATE:
+ case SCI_VERSION_1:
case SCI_VERSION_1_1:
g_opcode_formats[op_lofsa][0] = Script_Offset;
g_opcode_formats[op_lofss][0] = Script_Offset;
@@ -203,6 +202,10 @@ void Kernel::mapSelectors() {
FIND_SELECTOR(printLang);
FIND_SELECTOR(subtitleLang);
FIND_SELECTOR(parseLang);
+ FIND_SELECTOR(motionCue);
+ FIND_SELECTOR(sightAngle);
+ FIND_SELECTOR(setVol);
+ FIND_SELECTOR(egoMoveSpeed);
}
void Kernel::dumpScriptObject(char *data, int seeker, int objsize) {
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 92f890512a..a31af68323 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -1193,7 +1193,7 @@ void run_vm(EngineState *s, int restoring) {
if (s->_version >= SCI_VERSION_1_1) {
s->r_acc.offset = opparams[0] + local_script->script_size;
} else {
- if (s->_flags & GF_SCI1_LOFSABSOLUTE)
+ if (s->_kernel->hasLofsAbsolute())
s->r_acc.offset = opparams[0];
else
s->r_acc.offset = xs->addr.pc.offset + opparams[0];
@@ -1210,7 +1210,7 @@ void run_vm(EngineState *s, int restoring) {
case 0x3a: // lofss
r_temp.segment = xs->addr.pc.segment;
- if (s->_flags & GF_SCI1_LOFSABSOLUTE)
+ if (s->_kernel->hasLofsAbsolute())
r_temp.offset = opparams[0];
else
r_temp.offset = xs->addr.pc.offset + opparams[0];
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index a3fabbe44b..adaa064a6c 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -203,6 +203,10 @@ struct selector_map_t {
Selector printLang; /**< Used for i18n */
Selector subtitleLang;
Selector parseLang;
+ Selector motionCue; // Used to detect newer graphics functions semantics.
+ Selector sightAngle; // Used to detect some SCI0/SCI01 games which need a SCI1 table
+ Selector setVol; // Used to detect newer sound semantics
+ Selector egoMoveSpeed; // Used to detect SCI1 games which use absolute values in lofs
};
// A reference to an object's variable.
diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp
index 04ee5a9a4b..9457727b33 100644
--- a/engines/sci/gfx/gfx_driver.cpp
+++ b/engines/sci/gfx/gfx_driver.cpp
@@ -289,15 +289,14 @@ int GfxDriver::setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot) {
} else {
byte *cursorData = createCursor(pointer);
- // FIXME: The palette size check is a workaround for cursors using non-palette colour GFX_CURSOR_TRANSPARENT
- // Note that some cursors don't have a palette in SQ5
+ // FIXME: The palette size check is a workaround for cursors using non-palette color GFX_CURSOR_TRANSPARENT
+ // Note that some cursors don't have a palette (e.g. in SQ5 and QFG3)
byte color_key = GFX_CURSOR_TRANSPARENT;
if ((pointer->color_key != GFX_PIXMAP_COLOR_KEY_NONE) && (pointer->palette && (unsigned int)pointer->color_key < pointer->palette->size()))
color_key = pointer->palette->getColor(pointer->color_key).parent_index;
- // Some cursors in SQ5 don't have a palette. The cursor palette seems to use 64 colors, so setting the color key to 63 works
- // TODO: Is this correct?
+ // Some cursors don't have a palette, so we set the color key directly
if (!pointer->palette)
- color_key = 63;
+ color_key = pointer->color_key;
CursorMan.replaceCursor(cursorData, pointer->width, pointer->height, hotspot->x, hotspot->y, color_key);
CursorMan.showMouse(true);
diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp
index 1b76c65ff4..282931d004 100644
--- a/engines/sci/gfx/gfx_resmgr.cpp
+++ b/engines/sci/gfx/gfx_resmgr.cpp
@@ -535,7 +535,7 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) {
view = gfxr_draw_view0(resid, viewRes->data, viewRes->size, -1);
else if (_version == SCI_VERSION_01 || !_isVGA)
view = gfxr_draw_view0(resid, viewRes->data, viewRes->size, palette);
- else if (_version >= SCI_VERSION_01_VGA && _version <= SCI_VERSION_1_LATE)
+ else if (_version >= SCI_VERSION_01_VGA && _version <= SCI_VERSION_1)
view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, _staticPalette, false);
else if (_version >= SCI_VERSION_1_1)
view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, 0, true);
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 52c079e829..7138a918a1 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -48,8 +48,7 @@ const char *sci_version_types[] = {
"SCI version 0.xxx w/ 1.000 compression",
"SCI version 1.000 w/ 0.xxx resource.map",
"SCI version 1.000 w/ special resource.map",
- "SCI version 1.000 (early)",
- "SCI version 1.000 (late)",
+ "SCI version 1.000",
"SCI version 1.001",
"SCI WIN/32"
};
@@ -509,16 +508,9 @@ ResourceManager::ResourceManager(int version, int maxMemory) {
case SCI_VERSION_01_VGA_ODD:
version = _mapVersion;
break;
- case SCI_VERSION_1: {
- Resource *res = testResource(ResourceId(kResourceTypeScript, 0));
-
- _sciVersion = version = SCI_VERSION_1_EARLY;
- loadResource(res);
-
- if (res->status == kResStatusNoMalloc)
- version = SCI_VERSION_1_LATE;
+ case SCI_VERSION_1:
+ _sciVersion = version = SCI_VERSION_1;
break;
- }
case SCI_VERSION_1_1:
// No need to handle SCI 1.1 here - it was done in resource_map.cpp
version = SCI_VERSION_1_1;
@@ -542,11 +534,8 @@ ResourceManager::ResourceManager(int version, int maxMemory) {
case SCI_VERSION_01_VGA_ODD:
debug("Resmgr: Detected SCI01VGA - Jones/CD or similar");
break;
- case SCI_VERSION_1_EARLY:
- debug("Resmgr: Detected SCI1 Early");
- break;
- case SCI_VERSION_1_LATE:
- debug("Resmgr: Detected SCI1 Late");
+ case SCI_VERSION_1:
+ debug("Resmgr: Detected SCI1");
break;
case SCI_VERSION_1_1:
debug("Resmgr: Detected SCI1.1");
diff --git a/engines/sci/resource.h b/engines/sci/resource.h
index 77c92840ee..8ef42b171d 100644
--- a/engines/sci/resource.h
+++ b/engines/sci/resource.h
@@ -66,8 +66,6 @@ enum {
/* the first critical error number */
};
-#define SCI_VERSION_1 SCI_VERSION_1_EARLY
-
#define MAX_OPENED_VOLUMES 5 // Max number of simultaneously opened volumes
enum ResSourceType {
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index c5bf3f5a32..822542839b 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -43,14 +43,13 @@ namespace Sci {
class GfxDriver;
-const char *versionNames[9] = {
+const char *versionNames[8] = {
"Autodetected",
"SCI0",
"SCI01 EGA",
"SCI01 VGA",
"SCI01 VGA ODD",
- "SCI1 early",
- "SCI1 late",
+ "SCI1",
"SCI1.1",
"SCI32"
};
@@ -154,14 +153,12 @@ Common::Error SciEngine::run() {
_gamestate = new EngineState(_resmgr, version, flags);
// Verify that we haven't got an invalid game detection entry
- if (version < SCI_VERSION_1_EARLY) {
+ if (version < SCI_VERSION_1) {
// SCI0/SCI01
- if (flags & GF_SCI1_EGA ||
- flags & GF_SCI1_LOFSABSOLUTE ||
- flags & GF_SCI1_NEWDOSOUND) {
+ if (flags & GF_SCI1_EGA) {
error("This game entry is erroneous. It's marked as SCI0/SCI01, but it has SCI1 flags set");
}
- } else if (version >= SCI_VERSION_1_EARLY && version <= SCI_VERSION_1_LATE) {
+ } else if (version == SCI_VERSION_1) {
// SCI1
if (flags & GF_SCI0_OLD ||
@@ -169,9 +166,7 @@ Common::Error SciEngine::run() {
error("This game entry is erroneous. It's marked as SCI1, but it has SCI0 flags set");
}
} else if (version == SCI_VERSION_1_1 || version == SCI_VERSION_32) {
- if (flags & GF_SCI1_EGA ||
- flags & GF_SCI1_LOFSABSOLUTE ||
- flags & GF_SCI1_NEWDOSOUND) {
+ if (flags & GF_SCI1_EGA) {
error("This game entry is erroneous. It's marked as SCI1.1/SCI32, but it has SCI1 flags set");
}
diff --git a/engines/sci/sci.h b/engines/sci/sci.h
index ea50976df4..9b5d1de689 100644
--- a/engines/sci/sci.h
+++ b/engines/sci/sci.h
@@ -49,16 +49,15 @@ enum kDebugLevels {
kDebugLevelGfxDriver = 1 << 8,
kDebugLevelBaseSetter = 1 << 9,
kDebugLevelParser = 1 << 10,
- // FIXME: seems that debug level 11 is special (check debugC in common/debug.cpp)
- kDebugLevelMenu = 1 << 12,
- kDebugLevelSaid = 1 << 13,
- kDebugLevelFile = 1 << 14,
- kDebugLevelTime = 1 << 15,
- kDebugLevelRoom = 1 << 16,
- kDebugLevelAvoidPath = 1 << 17,
- kDebugLevelDclInflate = 1 << 18,
- kDebugLevelVM = 1 << 19,
- kDebugLevelScripts = 1 << 20
+ kDebugLevelMenu = 1 << 11,
+ kDebugLevelSaid = 1 << 12,
+ kDebugLevelFile = 1 << 13,
+ kDebugLevelTime = 1 << 14,
+ kDebugLevelRoom = 1 << 15,
+ kDebugLevelAvoidPath = 1 << 16,
+ kDebugLevelDclInflate = 1 << 17,
+ kDebugLevelVM = 1 << 18,
+ kDebugLevelScripts = 1 << 19
};
struct SciGameDescription {
@@ -74,54 +73,38 @@ enum SciGameVersions {
SCI_VERSION_01 = 2,
SCI_VERSION_01_VGA = 3,
SCI_VERSION_01_VGA_ODD = 4,
- SCI_VERSION_1_EARLY = 5,
- SCI_VERSION_1_LATE = 6,
+ SCI_VERSION_1 = 5,
SCI_VERSION_1_1 = 7,
SCI_VERSION_32 = 8
};
-extern const char *versionNames[9];
+extern const char *versionNames[8];
enum SciGameFlags {
- /*
- ** SCI0 flags
- */
+ // SCI0 flags
/* Applies to all versions before 0.000.395 (i.e. KQ4 old, XMAS 1988 and LSL2)
- ** Old SCI versions used two word header for script blocks (first word equal
- ** to 0x82, meaning of the second one unknown). New SCI versions used one
- ** word header.
- ** Also, old SCI versions assign 120 degrees to left & right, and 60 to up
- ** and down. Later versions use an even 90 degree distribution.
- */
+ * Old SCI versions used two word header for script blocks (first word equal
+ * to 0x82, meaning of the second one unknown). New SCI versions used one
+ * word header.
+ * Also, old SCI versions assign 120 degrees to left & right, and 60 to up
+ * and down. Later versions use an even 90 degree distribution.
+ */
GF_SCI0_OLD = (1 << 0),
/* Applies to all versions before 0.000.629
- ** Older SCI versions had simpler code for GetTime()
- */
+ * Older SCI versions had simpler code for GetTime()
+ */
GF_SCI0_OLDGETTIME = (1 << 1),
// ----------------------------------------------------------------------------
- /*
- ** SCI1 flags
- */
+ // SCI1 flags
/*
- ** Used to distinguish SCI1 EGA games
- */
- GF_SCI1_EGA = (1 << 2),
-
- /* Applies to all SCI1 versions after 1.000.200
- ** In late SCI1 versions, the argument of lofs[as] instructions
- ** is absolute rather than relative.
- */
- GF_SCI1_LOFSABSOLUTE = (1 << 3),
-
- /* Applies to all versions from 1.000.510 onwards
- ** kDoSound() is different than in earlier SCI1 versions.
- */
- GF_SCI1_NEWDOSOUND = (1 << 4)
+ * Used to distinguish SCI1 EGA games
+ */
+ GF_SCI1_EGA = (1 << 2)
};
class SciEngine : public Engine {
diff --git a/engines/sci/sfx/iterator.cpp b/engines/sci/sfx/iterator.cpp
index ad33bc8dfb..c1acda7f6c 100644
--- a/engines/sci/sfx/iterator.cpp
+++ b/engines/sci/sfx/iterator.cpp
@@ -1269,6 +1269,14 @@ static void song_iterator_remove_death_listener(SongIterator *it, TeeSongIterato
}
}
+static void song_iterator_transfer_death_listeners(SongIterator *it, SongIterator *it_from) {
+ for (int i = 0; i < SONGIT_MAX_LISTENERS; ++i) {
+ if (it_from->_deathListeners[i])
+ song_iterator_add_death_listener(it, it_from->_deathListeners[i]);
+ it_from->_deathListeners[i] = 0;
+ }
+}
+
static void songit_tee_death_notification(TeeSongIterator *self, SongIterator *corpse) {
if (corpse == self->_children[TEE_LEFT].it) {
self->_status &= ~TEE_LEFT_ACTIVE;
@@ -1505,12 +1513,16 @@ SongIterator *TeeSongIterator::handleMessage(Message msg) {
delete _children[TEE_LEFT].it;
_children[TEE_LEFT].it = 0;
old_it = _children[TEE_RIGHT].it;
+ song_iterator_remove_death_listener(old_it, this);
+ song_iterator_transfer_death_listeners(old_it, this);
delete this;
return old_it;
} else if (!(_status & TEE_RIGHT_ACTIVE)) {
delete _children[TEE_RIGHT].it;
_children[TEE_RIGHT].it = 0;
old_it = _children[TEE_LEFT].it;
+ song_iterator_remove_death_listener(old_it, this);
+ song_iterator_transfer_death_listeners(old_it, this);
delete this;
return old_it;
}
@@ -1582,9 +1594,11 @@ int songit_next(SongIterator **it, byte *buf, int *result, int mask) {
** cleanup iterator */
int channel_mask = (*it)->channel_mask;
- if (mask & IT_READER_MAY_FREE)
- delete *it;
+ SongIterator *old_it = *it;
*it = new CleanupSongIterator(channel_mask);
+ song_iterator_transfer_death_listeners(*it, old_it);
+ if (mask & IT_READER_MAY_FREE)
+ delete old_it;
retval = -9999; /* Continue */
}
} while (!( /* Until one of the following holds */
diff --git a/engines/scumm/he/resource_he.cpp b/engines/scumm/he/resource_he.cpp
index 022dbc0eb3..ce29bf0319 100644
--- a/engines/scumm/he/resource_he.cpp
+++ b/engines/scumm/he/resource_he.cpp
@@ -474,7 +474,7 @@ bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *n
int need_size = (int)((byte *)offset - memory + size);
debugC(DEBUG_RESOURCE, "check_offset: size=%x vs %x offset=%x size=%x",
- need_size, total_size, (byte *)offset - memory, size);
+ need_size, total_size, (uint)((byte *)offset - memory), size);
if (need_size < 0 || need_size > total_size) {
error("%s: premature end", name);
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index c70c819b69..78f7fb0453 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -462,7 +462,7 @@ void ScummEngine::executeScript() {
vm.slot[_currentScript].didexec = true;
debugC(DEBUG_OPCODES, "Script %d, offset 0x%x: [%X] %s()",
vm.slot[_currentScript].number,
- _scriptPointer - _scriptOrgPointer,
+ (uint)(_scriptPointer - _scriptOrgPointer),
_opcode,
getOpcodeDesc(_opcode));
if (_hexdumpScripts == true) {
diff --git a/gui/GuiManager.cpp b/gui/GuiManager.cpp
index cf8b7b2d9d..b97a62109b 100644
--- a/gui/GuiManager.cpp
+++ b/gui/GuiManager.cpp
@@ -72,7 +72,6 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled),
error("Failed to load any GUI theme, aborting");
}
}
- _themeChange = false;
}
GuiManager::~GuiManager() {
@@ -143,12 +142,20 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx)
// Enable the new theme
//
_theme = newTheme;
- _themeChange = true;
+ _useStdCursor = !_theme->ownCursor();
+
+ // If _stateIsSaved is set, we know that a Theme is already initialized,
+ // thus we initialize the new theme properly
+ if (_stateIsSaved) {
+ _theme->enable();
+
+ if (_useStdCursor)
+ setupCursor();
+ }
// refresh all dialogs
- for (int i = 0; i < _dialogStack.size(); ++i) {
+ for (int i = 0; i < _dialogStack.size(); ++i)
_dialogStack[i]->reflowLayout();
- }
// We need to redraw immediately. Otherwise
// some other event may cause a widget to be
@@ -157,10 +164,6 @@ bool GuiManager::loadNewTheme(Common::String id, ThemeEngine::GraphicsMode gfx)
redraw();
_system->updateScreen();
- Common::Event event;
- event.type = Common::EVENT_SCREEN_CHANGED;
- _system->getEventManager()->pushEvent(event);
-
return true;
}
@@ -233,7 +236,6 @@ void GuiManager::runLoop() {
// _theme->refresh();
- _themeChange = false;
_redrawStatus = kRedrawFull;
redraw();
}
@@ -285,21 +287,6 @@ void GuiManager::runLoop() {
Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y);
- // HACK to change the cursor to the new themes one
- if (_themeChange) {
- _theme->enable();
-
- _useStdCursor = !_theme->ownCursor();
- if (_useStdCursor)
- setupCursor();
-
-// _theme->refresh();
-
- _themeChange = false;
- _redrawStatus = kRedrawFull;
- redraw();
- }
-
if (lastRedraw + waitTime < _system->getMillis()) {
_theme->updateScreen();
_system->updateScreen();
diff --git a/gui/GuiManager.h b/gui/GuiManager.h
index 102d612699..ab5c653549 100644
--- a/gui/GuiManager.h
+++ b/gui/GuiManager.h
@@ -120,9 +120,7 @@ protected:
// mouse cursor state
int _cursorAnimateCounter;
int _cursorAnimateTimer;
- byte _cursor[2048];
-
- bool _themeChange;
+ byte _cursor[2048];
void initKeymap();