diff options
| author | Travis Howell | 2009-07-06 06:34:40 +0000 | 
|---|---|---|
| committer | Travis Howell | 2009-07-06 06:34:40 +0000 | 
| commit | f63b02b9200606069a605e27d828f4c8c59119fc (patch) | |
| tree | 705a39e27a252ed5fe897d0ef0e08b7091d43cd8 | |
| parent | 4b1c6b526dbfa8d084fbd2475b4d4caa173e442c (diff) | |
| parent | 08df8dc2721808c7019f49d9051e2eebfe8dad9c (diff) | |
| download | scummvm-rg350-f63b02b9200606069a605e27d828f4c8c59119fc.tar.gz scummvm-rg350-f63b02b9200606069a605e27d828f4c8c59119fc.tar.bz2 scummvm-rg350-f63b02b9200606069a605e27d828f4c8c59119fc.zip | |
Merged revisions 42087-42088,42093-42095,42097-42099,42104-42107,42110,42112-42113,42115-42132,42134-42150,42153-42155,42161-42162 via svnmerge from 
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk
........
  r42087 | thebluegr | 2009-07-04 21:24:09 +1000 (Sat, 04 Jul 2009) | 1 line
  
  Newer DoSound() semantics are now detected automatically, by the existence of the "setVol" selector. Removed game flag GF_SCI1_NEWDOSOUND
........
  r42088 | thebluegr | 2009-07-04 21:33:51 +1000 (Sat, 04 Jul 2009) | 1 line
  
  Removed silly FIXME (mixup between debug and engine debug levels)
........
  r42093 | thebluegr | 2009-07-05 01:22:42 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Added a new console command, "selector", which attempts to find a selector by name
........
  r42094 | thebluegr | 2009-07-05 01:39:31 +1000 (Sun, 05 Jul 2009) | 1 line
  
  - Changed some comments to DOxygen style
........
  r42095 | thebluegr | 2009-07-05 01:45:04 +1000 (Sun, 05 Jul 2009) | 3 lines
  
  - Kernel function names are no longer loaded from vocab.999, but are constructed from the hardcoded function table, depending on the SCI version used
  - SCI0 games using older graphics functions are now detected by the presence of the "curAngle" selector
  - SCI0 games using a SCI1 table (like KQ1 demo version and full version) are detected by the presence of the "sightAngle" selector (as no SCI0 game seems to have it)
........
  r42097 | thebluegr | 2009-07-05 02:30:20 +1000 (Sun, 05 Jul 2009) | 3 lines
  
  - Merged the "early" and "late" SCI1 versions - these are functionally equivalent, and the code that does the version check is unreliable (e.g. it sets SQ1 VGA to SCI1 "late" and EcoQuest 1 to SCI1 "early")
  - Cleanup of the vocabulary setting functions
  - Cleanup of the cursor manipulation code
........
  r42098 | thebluegr | 2009-07-05 02:36:56 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Merged SCI1 versions in one more file
........
  r42099 | thebluegr | 2009-07-05 03:39:43 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Cursors without a palette are now initialized correctly (from patch #2816652). Fixes the cursor transparent color in QFG3
........
  r42104 | lordhoto | 2009-07-05 04:54:06 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Add GCC_PRINTF parameter.
........
  r42105 | lordhoto | 2009-07-05 04:54:27 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Fix mismatching format arguments.
........
  r42106 | lordhoto | 2009-07-05 04:54:43 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Kyra1 PC-98 never offered English as language settings, thus remove it. (The CD version *does* supply English files, but those will work as FM-Towns version, so this causes no drawback for the user and is faithful to the original)
........
  r42107 | lordhoto | 2009-07-05 05:04:39 +1000 (Sun, 05 Jul 2009) | 1 line
  
  After discussing with Max, disable -Wmissing-format-attribute again. Also added a comment explaining why it is disabled.
........
  r42110 | athrxx | 2009-07-05 07:18:20 +1000 (Sun, 05 Jul 2009) | 1 line
  
  KYRA: fix minor bug in Screen::drawShape()
........
  r42112 | wjpalenstijn | 2009-07-05 09:52:24 +1000 (Sun, 05 Jul 2009) | 1 line
  
  When morphing a TeeSongIterator, transfer death listeners to remaining child
........
  r42113 | wjpalenstijn | 2009-07-05 11:16:53 +1000 (Sun, 05 Jul 2009) | 1 line
  
  When creating a CleanupSongIterator, transfer death listeners to it
........
  r42115 | dreammaster | 2009-07-05 17:21:17 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Bugfix for word-wrapping of text, which sometimes failed for strings with special characters
........
  r42116 | jvprat | 2009-07-05 19:34:54 +1000 (Sun, 05 Jul 2009) | 3 lines
  
  - Refactorized Groovie::MusicPlayer to make it extensible
  - Added an empty MusicPlayerMac to let the Macintosh version of The 7th Guest start
........
  r42117 | thebluegr | 2009-07-05 20:34:43 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Removed validity check for atoi, which prevented console commands from interacting with resources with id 0
........
  r42118 | thebluegr | 2009-07-05 21:08:53 +1000 (Sun, 05 Jul 2009) | 1 line
  
  SCI1 games with absolute parameters to lofs instructions are automatically detected now. Removed the GF_SCI1_LOFSABSOLUTE game flag
........
  r42119 | drmccoy | 2009-07-05 21:26:23 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Adding an enum MouseButtons
........
  r42120 | drmccoy | 2009-07-05 21:26:42 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Commenting prepareStr a bit and renaming it to cleanupStr
........
  r42121 | drmccoy | 2009-07-05 21:27:11 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Added a Key and ShortKey enum
........
  r42122 | drmccoy | 2009-07-05 21:27:26 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Added a skipBlock() method
........
  r42123 | drmccoy | 2009-07-05 21:27:54 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Moving the "Collision" stuff to Hotspots in hotspots.cpp/.h
........
  r42124 | drmccoy | 2009-07-05 21:28:09 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Wrapping the block end marker checks into Hotspots::Hotspot::isEnd()
........
  r42125 | drmccoy | 2009-07-05 21:28:25 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Removing the now empty Game_Fascination class
........
  r42126 | drmccoy | 2009-07-05 21:28:38 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Fixing indent
........
  r42127 | drmccoy | 2009-07-05 21:28:57 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Merging Game_v1's and Game_v2's prepareStart()
........
  r42128 | drmccoy | 2009-07-05 21:29:13 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Merging Game's and Game_v6's totSub()
........
  r42129 | drmccoy | 2009-07-05 21:29:30 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Merging playTot()
........
  r42130 | drmccoy | 2009-07-05 21:29:54 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Putting the Urban noCD check into Init_v6::initGame()
........
  r42131 | drmccoy | 2009-07-05 21:30:14 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Removing the now unneeded Game_v* classes
........
  r42132 | thebluegr | 2009-07-05 21:49:05 +1000 (Sun, 05 Jul 2009) | 2 lines
  
  - Fixed feature auto-detection for Conquests of Camelot
  - Auto-detected features are now printed in the console (to ease debugging)
........
  r42134 | thebluegr | 2009-07-05 21:58:42 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Updated the MSVC project files of the gob engine
........
  r42135 | drmccoy | 2009-07-05 22:52:14 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Adding a workaround for an invalid expression in Gob1 EGA
........
  r42136 | thebluegr | 2009-07-05 23:07:11 +1000 (Sun, 05 Jul 2009) | 1 line
  
  Merged the two SCI1 versions in one more file
........
  r42137 | lordhoto | 2009-07-06 00:11:54 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Got rid of HACK, which was used to setup new cursor on theme change.
........
  r42138 | lordhoto | 2009-07-06 00:12:04 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Removed pushing of EVENT_SCREEN_CHANGED on theme load. This event should only be pushed by the backend.
........
  r42139 | marcus_c | 2009-07-06 00:57:03 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Refresh the screen if pollEvent() is called without updateScreen() being called for a long time.
........
  r42140 | athrxx | 2009-07-06 00:58:22 +1000 (Mon, 06 Jul 2009) | 1 line
  
  LOL: - reduce code duplication
........
  r42141 | athrxx | 2009-07-06 02:29:17 +1000 (Mon, 06 Jul 2009) | 1 line
  
  LOL: cleanup
........
  r42142 | drmccoy | 2009-07-06 05:56:03 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Encapsulating hotspot state reading
........
  r42143 | drmccoy | 2009-07-06 05:56:23 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Correcting an input related mistake
........
  r42144 | drmccoy | 2009-07-06 05:56:40 +1000 (Mon, 06 Jul 2009) | 1 line
  
  More state-related encapsulation
........
  r42145 | drmccoy | 2009-07-06 05:56:54 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Split off Hotspots::evaluateNew()
........
  r42146 | drmccoy | 2009-07-06 05:57:08 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Ooops, fixing monospaced text input again
........
  r42147 | drmccoy | 2009-07-06 05:57:22 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Split off some drawing related functions
........
  r42148 | drmccoy | 2009-07-06 05:57:37 +1000 (Mon, 06 Jul 2009) | 1 line
  
  More input related split-offs
........
  r42149 | drmccoy | 2009-07-06 05:57:55 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Renaming FontDesc::extraData to charWidths
........
  r42150 | drmccoy | 2009-07-06 05:58:09 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Reordering some methods
........
  r42153 | drmccoy | 2009-07-06 07:39:55 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Renaming the last occurences of "Collision" to "Hotspot"
........
  r42154 | drmccoy | 2009-07-06 07:40:20 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Adding some hotspot debug messages
........
  r42155 | drmccoy | 2009-07-06 07:40:51 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Added an enum for the hotspot states
........
  r42161 | drmccoy | 2009-07-06 11:41:29 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Adding more comments
........
  r42162 | dreammaster | 2009-07-06 12:46:59 +1000 (Mon, 06 Jul 2009) | 1 line
  
  Bugfix for node enabling/disabling, which was previously allowing the player to walk through closed doors and into the walls
........
svn-id: r42165
77 files changed, 3549 insertions, 5675 deletions
| @@ -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 ¶ms);  	bool o1_getFreeMem(OpFuncParams ¶ms);  	bool o1_checkData(OpFuncParams ¶ms); -	bool o1_prepareStr(OpFuncParams ¶ms); +	bool o1_cleanupStr(OpFuncParams ¶ms);  	bool o1_insertStr(OpFuncParams ¶ms);  	bool o1_cutStr(OpFuncParams ¶ms);  	bool o1_strstr(OpFuncParams ¶ms); @@ -380,8 +380,8 @@ protected:  	bool o2_assign(OpFuncParams ¶ms);  	bool o2_printText(OpFuncParams ¶ms);  	bool o2_animPalInit(OpFuncParams ¶ms); -	bool o2_addCollision(OpFuncParams ¶ms); -	bool o2_freeCollision(OpFuncParams ¶ms); +	bool o2_addHotspot(OpFuncParams ¶ms); +	bool o2_removeHotspot(OpFuncParams ¶ms);  	bool o2_goblinFunc(OpFuncParams ¶ms);  	bool o2_stopSound(OpFuncParams ¶ms);  	bool o2_loadSound(OpFuncParams ¶ms); @@ -541,7 +541,7 @@ protected:  	bool o6_loadCursor(OpFuncParams ¶ms);  	bool o6_assign(OpFuncParams ¶ms);  	bool o6_palLoad(OpFuncParams ¶ms); -	bool o6_freeCollision(OpFuncParams ¶ms); +	bool o6_removeHotspot(OpFuncParams ¶ms);  	bool o6_fillRect(OpFuncParams ¶ms);  	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 ¶ms) {  	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 ¶ms) {  	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 ¶ms) {  void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) {  	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 ¶ms) {  			_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 ¶ms) {  	_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 ¶ms) {  	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 ¶ms) {  	return false;  } -bool Inter_v1::o1_prepareStr(OpFuncParams ¶ms) { +bool Inter_v1::o1_cleanupStr(OpFuncParams ¶ms) {  	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 ¶ms) {  	return false;  } -bool Inter_v2::o2_addCollision(OpFuncParams ¶ms) { -	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 ¶ms) { +	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 ¶ms) { -	int16 id; +bool Inter_v2::o2_removeHotspot(OpFuncParams ¶ms) { +	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 ¶ms) {  	return false;  } -bool Inter_v6::o6_freeCollision(OpFuncParams ¶ms) { +bool Inter_v6::o6_removeHotspot(OpFuncParams ¶ms) {  	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 >lName) : -	_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 >lName) : +	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 >lName); -	~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 >lName); +	~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(); | 
