diff options
author | Travis Howell | 2009-07-04 05:56:10 +0000 |
---|---|---|
committer | Travis Howell | 2009-07-04 05:56:10 +0000 |
commit | 4656019e8a2f92f708a685be6d3d95edd7ee8d6d (patch) | |
tree | 1370ceb14c98da5478d85f207ae421dbaff473c8 /engines/gob | |
parent | 6ef485f44896ad778d355bc1201f2f143cc9e770 (diff) | |
parent | df9570cb3265f4d81ac41d66d949355491e2df7e (diff) | |
download | scummvm-rg350-4656019e8a2f92f708a685be6d3d95edd7ee8d6d.tar.gz scummvm-rg350-4656019e8a2f92f708a685be6d3d95edd7ee8d6d.tar.bz2 scummvm-rg350-4656019e8a2f92f708a685be6d3d95edd7ee8d6d.zip |
Merged revisions 41219-41297,41299-41318,41322-41328,41331-41334,41336-41346,41348-41369,41372-41376,41379-41381,41384-41386,41389,41393,41395,41398,41400-41409,41419,41421,41423-41425,41428-41430,41432-41433,41452-41453,41458-41462,41465,41468,41470,41473-41474,41484-41490,41493,41496-41504,41506-41508,41516-41517,41519-41520,41528,41536-41538,41556-41557,41559-41560,41562-41576,41579,41584,41587-41592,41596,41598,41601-41603,41611,41618-41619,41630,41632-41635,41639,41641,41644-41647,41660,41663-41665,41668,41677,41679-41680,41683,41699-41705,41707-41709,41713-41715,41718-41727,41729-41736,41739-41763,41765-41766,41768-41774,41777-41778,41781-41799,41803,41806,41809-41813,41821-41823,41827,41833-41834,41836-41839,41841,41844-41848,41850-41853,41858-41860,41867-41871,41875-41887,41889-41893,41895-41897,41902-41903,41915-41917,41922,41929-41934,41938,41940-41964,41967-41968,41975,42007-42012,42020,42038-42041,42043-42044,42047-42050,42054-42056,42060,42062,42079,42081 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk
........
r41219 | drmccoy | 2009-06-06 21:34:11 +1000 (Sat, 06 Jun 2009) | 2 lines
Adding my German version of Playtoons 2 ("Rummelsdorf hoch zwei")
........
r41220 | wjpalenstijn | 2009-06-06 21:38:20 +1000 (Sat, 06 Jun 2009) | 3 lines
Store long-term pointers to object variables in a new ObjVarRef struct.
Storing them as reg_t* could cause the pointers to become invalid
when they pointed into CloneTable since CloneTable can be re-allocated.
........
r41221 | athrxx | 2009-06-06 22:18:39 +1000 (Sat, 06 Jun 2009) | 1 line
KYRA/LOL: fix input code for japanese game versions
........
r41222 | waltervn | 2009-06-06 22:30:13 +1000 (Sat, 06 Jun 2009) | 2 lines
SCI: Fix audio regression in KQ5CD, introduced in r41205.
........
r41223 | athrxx | 2009-06-07 00:14:07 +1000 (Sun, 07 Jun 2009) | 1 line
LOL: fixed vaelan's cube
........
r41224 | athrxx | 2009-06-07 00:42:03 +1000 (Sun, 07 Jun 2009) | 1 line
LOL: fixed level temp data size
........
r41225 | athrxx | 2009-06-07 01:32:42 +1000 (Sun, 07 Jun 2009) | 1 line
LOL: fix last commit
........
r41226 | djwillis | 2009-06-07 01:41:17 +1000 (Sun, 07 Jun 2009) | 1 line
GP2XWiz: Cleanup and start to work on virtual keyboard support for the backend.
........
r41227 | thebluegr | 2009-06-07 02:43:13 +1000 (Sun, 07 Jun 2009) | 1 line
Moved some more debug commands to ScummVM's coneole
........
r41228 | drmccoy | 2009-06-07 02:47:21 +1000 (Sun, 07 Jun 2009) | 2 lines
Adding a pause mode
........
r41229 | drmccoy | 2009-06-07 02:48:29 +1000 (Sun, 07 Jun 2009) | 2 lines
Adding a general coktelplayer.scn demo file
........
r41230 | djwillis | 2009-06-07 02:52:45 +1000 (Sun, 07 Jun 2009) | 2 lines
GP2X: Small cleanup of control code and start to work on virtual keyboard support for the backend.
........
r41231 | lordhoto | 2009-06-07 03:10:15 +1000 (Sun, 07 Jun 2009) | 2 lines
Fix unused variable warnings.
........
r41232 | djwillis | 2009-06-07 03:21:50 +1000 (Sun, 07 Jun 2009) | 1 line
Virtual Keyboard: Fix detection of v_align option when used in the keyboard definition.
........
r41233 | sev | 2009-06-07 03:36:06 +1000 (Sun, 07 Jun 2009) | 1 line
Implement feature request #1180217: "GUI: Mute option"
........
r41234 | sev | 2009-06-07 03:36:21 +1000 (Sun, 07 Jun 2009) | 1 line
Mention new hotkey in README
........
r41235 | sev | 2009-06-07 03:36:58 +1000 (Sun, 07 Jun 2009) | 1 line
Add Mute control to all themes
........
r41236 | sev | 2009-06-07 03:37:15 +1000 (Sun, 07 Jun 2009) | 1 line
Implement FR#1522626: "GUI: Friendlier "Add Game" session"
........
r41237 | sev | 2009-06-07 03:37:31 +1000 (Sun, 07 Jun 2009) | 1 line
Implement FR#2090830: "GUI: RTL should focus game list on the last game played"
........
r41238 | sev | 2009-06-07 03:37:51 +1000 (Sun, 07 Jun 2009) | 1 line
Decrease number of free memory pages to realistic value
........
r41239 | sev | 2009-06-07 03:39:13 +1000 (Sun, 07 Jun 2009) | 1 line
Whitespace fixes and C++ comments
........
r41240 | sev | 2009-06-07 03:39:42 +1000 (Sun, 07 Jun 2009) | 1 line
Fix bug #2434187: "SQ2: message not displayed, or vanishes too quickly"
........
r41241 | sev | 2009-06-07 03:40:09 +1000 (Sun, 07 Jun 2009) | 1 line
Fix implementation of prevent.input. This fixes SQ2 intro
........
r41242 | sev | 2009-06-07 03:40:27 +1000 (Sun, 07 Jun 2009) | 1 line
Fix bug #2026570: "SQ2: Prompt disappears when it shouldn't"
........
r41243 | sev | 2009-06-07 03:40:56 +1000 (Sun, 07 Jun 2009) | 1 line
Fix bug #2721940: "AGI: Gold Rush! Restart Option differs from original"
........
r41244 | sev | 2009-06-07 03:41:29 +1000 (Sun, 07 Jun 2009) | 1 line
Fix bug #1745954: "GR: Intro "jumpy" in parts (Amiga version)"
........
r41245 | sev | 2009-06-07 03:41:50 +1000 (Sun, 07 Jun 2009) | 1 line
Store and compare MD5s in the saves
........
r41246 | sev | 2009-06-07 03:42:12 +1000 (Sun, 07 Jun 2009) | 1 line
Disable save/load when original did not allow
........
r41247 | sev | 2009-06-07 03:42:37 +1000 (Sun, 07 Jun 2009) | 1 line
Stop abusing game flag.
........
r41248 | sev | 2009-06-07 03:43:04 +1000 (Sun, 07 Jun 2009) | 1 line
Remove duplicated amiga busy cursor
........
r41249 | sev | 2009-06-07 03:43:26 +1000 (Sun, 07 Jun 2009) | 1 line
Implement debug commands "room" and "bt"
........
r41250 | sev | 2009-06-07 03:43:51 +1000 (Sun, 07 Jun 2009) | 1 line
Fix bug #2026605: "SQ2: Have to wait after dying to do anything."
........
r41251 | sev | 2009-06-07 03:44:24 +1000 (Sun, 07 Jun 2009) | 1 line
Cleanup
........
r41252 | sev | 2009-06-07 03:44:46 +1000 (Sun, 07 Jun 2009) | 1 line
Implement scummvm.ini flag features for AGI engine
........
r41253 | sev | 2009-06-07 03:45:06 +1000 (Sun, 07 Jun 2009) | 1 line
Implement cancel.line. Consider obj.status.f implemented
........
r41254 | sev | 2009-06-07 03:45:52 +1000 (Sun, 07 Jun 2009) | 1 line
Cleanup
........
r41255 | sev | 2009-06-07 03:46:19 +1000 (Sun, 07 Jun 2009) | 1 line
Implement hold.key and release.key opcodes
........
r41256 | sev | 2009-06-07 03:46:38 +1000 (Sun, 07 Jun 2009) | 1 line
Implement allow.menu opcode
........
r41257 | sev | 2009-06-07 03:46:55 +1000 (Sun, 07 Jun 2009) | 1 line
Implement hide.mouse and show.mouse opcodes
........
r41258 | sev | 2009-06-07 03:47:29 +1000 (Sun, 07 Jun 2009) | 1 line
Implement fence.mouse opcode
........
r41259 | sev | 2009-06-07 03:48:09 +1000 (Sun, 07 Jun 2009) | 1 line
Correct implementation for set.key opcode. Fixes #2605104: "AGI: Manhunter, F3 hotkey dosent work", removed number of hacks
........
r41260 | sev | 2009-06-07 03:48:30 +1000 (Sun, 07 Jun 2009) | 1 line
Add guard check to set.key opcode.
........
r41261 | sev | 2009-06-07 03:48:46 +1000 (Sun, 07 Jun 2009) | 1 line
Make PopUp widget look more balanced
........
r41262 | sev | 2009-06-07 03:49:09 +1000 (Sun, 07 Jun 2009) | 1 line
Improved look of popup widget, buttons, checkbox and tab widget
........
r41263 | sev | 2009-06-07 03:49:59 +1000 (Sun, 07 Jun 2009) | 1 line
Implement FR#2707442: "GUI: Improve Mass Add dialog"
........
r41264 | sev | 2009-06-07 03:50:30 +1000 (Sun, 07 Jun 2009) | 1 line
Sync all themes with improvements of mass dialog. Fixed list positioning
........
r41265 | sev | 2009-06-07 03:51:41 +1000 (Sun, 07 Jun 2009) | 1 line
Implement widget property "textalign". Added it to all theme layouts
........
r41266 | sev | 2009-06-07 03:52:44 +1000 (Sun, 07 Jun 2009) | 4 lines
Implement FR#2507667: "GUI: Improve PopupWidget rendering / theme layouting".
- Split out label from PopUp widget
- Aligned every widget on all layouts so GUI becomes to look nice again
- Moved textHAlign to layout properties
........
r41267 | sev | 2009-06-07 03:53:25 +1000 (Sun, 07 Jun 2009) | 2 lines
Add to launcher not yet functional search widget.
Make EditableWidget CommandSender
........
r41268 | sev | 2009-06-07 03:54:08 +1000 (Sun, 07 Jun 2009) | 1 line
Implement FR#1970293: "LAUNCHER: Add "quick search" input field like in iTunes"
........
r41269 | sev | 2009-06-07 03:54:28 +1000 (Sun, 07 Jun 2009) | 5 lines
Improvements to laucher dialog
- Made quicksearch turned off in the launcher game list
- Turn ListWidget into CommandSender
- Turn quicksearch off in launcher game list
- Connect laucher list widget with search box so search is initiated by typing
........
r41270 | sev | 2009-06-07 03:54:43 +1000 (Sun, 07 Jun 2009) | 1 line
Fix font size in EditTextWidget on screen resolution change.
........
r41271 | sev | 2009-06-07 03:54:59 +1000 (Sun, 07 Jun 2009) | 1 line
Fix item selection on filtered out list in launcher
........
r41272 | sev | 2009-06-07 03:56:41 +1000 (Sun, 07 Jun 2009) | 1 line
Added game GUI options to advancedDetector and updated all engines
........
r41273 | sev | 2009-06-07 03:56:59 +1000 (Sun, 07 Jun 2009) | 1 line
Fix bug with GUI options not set when per-game setting is empty
........
r41274 | sev | 2009-06-07 03:57:39 +1000 (Sun, 07 Jun 2009) | 1 line
Add GUI options support to Sky, Queen and Sword1&2 engines (which do not use AD)
........
r41275 | sev | 2009-06-07 03:58:08 +1000 (Sun, 07 Jun 2009) | 2 lines
Implement FR#862150: "GUI: Show subtitles/speech options only for speech games"
Add generic per-game GUI options support along the way ;)
........
r41276 | sev | 2009-06-07 03:58:29 +1000 (Sun, 07 Jun 2009) | 1 line
Do not change list content if filter was not changed
........
r41277 | sev | 2009-06-07 03:59:04 +1000 (Sun, 07 Jun 2009) | 1 line
Disable load from the launcher button for AGOS and Gob games with use of GUI options
........
r41278 | sev | 2009-06-07 03:59:54 +1000 (Sun, 07 Jun 2009) | 1 line
Add support for GUI options to SCUMM engine
........
r41279 | thebluegr | 2009-06-07 04:02:16 +1000 (Sun, 07 Jun 2009) | 1 line
Removed unused variable
........
r41280 | sev | 2009-06-07 04:11:05 +1000 (Sun, 07 Jun 2009) | 2 lines
Add empty file to cheat git-svn
........
r41281 | sev | 2009-06-07 04:21:07 +1000 (Sun, 07 Jun 2009) | 1 line
Disable MIDI controls if GUIO_NOMIDI is set
........
r41282 | sev | 2009-06-07 04:21:49 +1000 (Sun, 07 Jun 2009) | 1 line
Patch #1365914: "SCUMM: CMS support." Disabled by default. Still plenty to do.
........
r41283 | sev | 2009-06-07 04:22:18 +1000 (Sun, 07 Jun 2009) | 1 line
Added couple of newly discovered fanmade AGI games.
........
r41284 | sev | 2009-06-07 04:22:43 +1000 (Sun, 07 Jun 2009) | 1 line
Added CoCo3 version of SQ1
........
r41285 | sev | 2009-06-07 04:23:05 +1000 (Sun, 07 Jun 2009) | 1 line
Added GUI options for newly added games
........
r41286 | sev | 2009-06-07 04:23:24 +1000 (Sun, 07 Jun 2009) | 1 line
Shut gcc warning.
........
r41287 | sev | 2009-06-07 04:27:25 +1000 (Sun, 07 Jun 2009) | 2 lines
Bump theme version to 0.5 due to number of recent changes.
........
r41288 | sev | 2009-06-07 04:32:33 +1000 (Sun, 07 Jun 2009) | 2 lines
Restore search.bmp which was lost
........
r41289 | lordhoto | 2009-06-07 04:33:20 +1000 (Sun, 07 Jun 2009) | 2 lines
Fix printf format argument related warnings.
........
r41290 | thebluegr | 2009-06-07 04:38:41 +1000 (Sun, 07 Jun 2009) | 1 line
Updated the MSVC project files of the SCUMM engine for commit #41282
........
r41291 | lordhoto | 2009-06-07 04:41:25 +1000 (Sun, 07 Jun 2009) | 2 lines
Flag all games without full voice over with GUIO_NOSPEECH.
........
r41292 | athrxx | 2009-06-07 04:46:07 +1000 (Sun, 07 Jun 2009) | 1 line
LOL: fix flying item hit processing
........
r41293 | thebluegr | 2009-06-07 05:04:09 +1000 (Sun, 07 Jun 2009) | 1 line
Fixed assertion when starting mass add and there are no games currently in the game list
........
r41294 | drmccoy | 2009-06-07 05:06:47 +1000 (Sun, 07 Jun 2009) | 4 lines
Demoplayer:
- Fixing the flawed double mode
- Adding an "auto" double mode, where the videos get scaled if possible
........
r41295 | lordhoto | 2009-06-07 05:10:25 +1000 (Sun, 07 Jun 2009) | 3 lines
- Flag Kyra3 detection entries with GUIO_NOMIDI
- Get rid of using directive
........
r41296 | sev | 2009-06-07 05:20:39 +1000 (Sun, 07 Jun 2009) | 2 lines
Bring old 'quick search' behavior of games list back.
........
r41297 | lordhoto | 2009-06-07 05:47:55 +1000 (Sun, 07 Jun 2009) | 2 lines
Use GameDescriptor::setGUIOptions instead of setting key "guioptions" directly.
........
r41299 | fingolfin | 2009-06-07 06:03:13 +1000 (Sun, 07 Jun 2009) | 1 line
GOB: Got rid of class ReferenceCounter; changed SurfaceDesc::Ptr to SurfaceDescPtr (a Common::SharedPtr); and changed many SurfaceDesc pointers to references
........
r41300 | djwillis | 2009-06-07 06:05:21 +1000 (Sun, 07 Jun 2009) | 1 line
Virtual Keyboard: 'Ab'use the console font to get a font small enough to be usable on 320*240 virtual keyboards for display_area (GUI and BigGUI take up far too much space).
........
r41301 | lordhoto | 2009-06-07 06:22:16 +1000 (Sun, 07 Jun 2009) | 2 lines
Made fix for empty game list on starting MassAdd a bit more robust.
........
r41302 | thebluegr | 2009-06-07 06:29:37 +1000 (Sun, 07 Jun 2009) | 1 line
Moved some more debug commands to ScummVM's coneole
........
r41303 | djwillis | 2009-06-07 06:36:12 +1000 (Sun, 07 Jun 2009) | 1 line
Virtual Keyboard: Add 320*240 support (in addition to 640*480) to the default keyboard pack. Also tweak vkeybd.xml to make it a little more like valid XML). New graphics still to come so excuse the ugly keyboard images for now.
........
r41304 | sev | 2009-06-07 06:58:36 +1000 (Sun, 07 Jun 2009) | 2 lines
Make script executable
........
r41305 | fingolfin | 2009-06-07 07:37:30 +1000 (Sun, 07 Jun 2009) | 1 line
GOB: Turned _spritesArray into a Common::Array (of fixed size) to detect out-of-bounds access to it (since access is controlled by scripts, this could (and does :/) easily happen. Also removed an obsolete swap() method, and fixed one case where _spritesArray was indeed accessed out of bounds
........
r41306 | drmccoy | 2009-06-07 07:41:22 +1000 (Sun, 07 Jun 2009) | 2 lines
Fixing the Woodruff intro: Using a flag that's /not/ already used be the scripts
........
r41307 | drmccoy | 2009-06-07 07:45:47 +1000 (Sun, 07 Jun 2009) | 2 lines
Fixing the demoplayer's auto double mode and added a REBASE0 option that sets the video's X and Y coordinates to 0,0
........
r41308 | drmccoy | 2009-06-07 07:54:12 +1000 (Sun, 07 Jun 2009) | 2 lines
Setting the game type of the generic demoplayer to Urban so it can make use of the initial palette
........
r41309 | fingolfin | 2009-06-07 09:22:22 +1000 (Sun, 07 Jun 2009) | 1 line
GUI: Simplified ThemeEngine::getImageSurface (this way it's easier to add more graphics in the future ;)
........
r41310 | fingolfin | 2009-06-07 09:22:35 +1000 (Sun, 07 Jun 2009) | 1 line
GUI: Pressing 'ESC' in the Launcher's quick search field now resets the search filter
........
r41311 | fingolfin | 2009-06-07 09:22:48 +1000 (Sun, 07 Jun 2009) | 1 line
GUI: Tweaked the launcher so that TAB switches focus between the list and the quick search field
........
r41312 | drmccoy | 2009-06-07 09:39:58 +1000 (Sun, 07 Jun 2009) | 1 line
Renamed the evaluateStore opcodes to assign, because that's what they are
........
r41313 | drmccoy | 2009-06-07 09:40:11 +1000 (Sun, 07 Jun 2009) | 1 line
Fascination needs o1_assign. o2_assign breaks the DOS floppy version
........
r41314 | athrxx | 2009-06-07 10:37:30 +1000 (Sun, 07 Jun 2009) | 1 line
LOL: implemented king richard healing sequence
........
r41315 | lordhoto | 2009-06-07 10:51:19 +1000 (Sun, 07 Jun 2009) | 2 lines
Fix WSA v2 code, now the automap remove WSA file in Lands of Lore plays correctly.
........
r41316 | lordhoto | 2009-06-07 10:58:14 +1000 (Sun, 07 Jun 2009) | 2 lines
Add support for "WF_NO_LAST_FRAME" in WSA v1 code too. Since so far every v1 WSA file played fine, it might be unneeded, but better safe than sorry.
........
r41317 | drmccoy | 2009-06-07 11:45:09 +1000 (Sun, 07 Jun 2009) | 1 line
Dropping the v1 parser functions in favour of the extended v2 ones
........
r41318 | waltervn | 2009-06-07 12:18:38 +1000 (Sun, 07 Jun 2009) | 2 lines
SCI: Resmgr cleanup and preparations for moving resource36 handling into resmgr.
........
r41322 | strangerke | 2009-06-07 18:33:46 +1000 (Sun, 07 Jun 2009) | 1 line
Suppress use of parse_v1 and parse_v2 as DrMcCoy got rid of them.
........
r41323 | strangerke | 2009-06-07 18:46:15 +1000 (Sun, 07 Jun 2009) | 1 line
Suppress inclusion of a not yet committed file
........
r41324 | sev | 2009-06-07 20:03:19 +1000 (Sun, 07 Jun 2009) | 2 lines
Mention recent improvements
........
r41325 | sev | 2009-06-07 20:04:41 +1000 (Sun, 07 Jun 2009) | 2 lines
Added MD5 from Bug #2796782: "SCI: LSL1 Russian MD5"
........
r41326 | sev | 2009-06-07 20:13:05 +1000 (Sun, 07 Jun 2009) | 2 lines
MD5 from bugreport #2797962: "SCI: Laura Bows 2 german, md5"
........
r41327 | athrxx | 2009-06-07 20:34:01 +1000 (Sun, 07 Jun 2009) | 1 line
LOL: implemented some missing monster animation code
........
r41328 | fingolfin | 2009-06-07 21:02:51 +1000 (Sun, 07 Jun 2009) | 1 line
Set svn:ignore
........
r41331 | fingolfin | 2009-06-07 22:37:16 +1000 (Sun, 07 Jun 2009) | 1 line
AGI: Fixed typo in game name ;)
........
r41332 | fingolfin | 2009-06-07 22:47:10 +1000 (Sun, 07 Jun 2009) | 1 line
Added an experimental '--upgrade-targets' option (to be refined; and possibly hooked to the GUI eventually). This updates the guioptions,platform and lang for all your targets (and with a source change, also the descriptions)
........
r41333 | fingolfin | 2009-06-07 23:04:03 +1000 (Sun, 07 Jun 2009) | 1 line
Added some new method variants to Common::String
........
r41334 | fingolfin | 2009-06-07 23:04:16 +1000 (Sun, 07 Jun 2009) | 1 line
Fix for bug #2802492 (GUI: search query causes game list scrollbar glitches)
........
r41336 | athrxx | 2009-06-07 23:07:16 +1000 (Sun, 07 Jun 2009) | 1 line
LOL: implemented two more opcodes for castle cimmeria
........
r41337 | fingolfin | 2009-06-07 23:14:34 +1000 (Sun, 07 Jun 2009) | 1 line
Fixed appending a (substring of a) string to itself
........
r41338 | thebluegr | 2009-06-08 01:53:30 +1000 (Mon, 08 Jun 2009) | 1 line
Replaced/removed KP_UINT, KP_SINT, SKPV and UKPV as well as the VIEW_PRIORITY and PRIORITY_BAND_FIRST wrappers
........
r41339 | thebluegr | 2009-06-08 02:44:57 +1000 (Mon, 08 Jun 2009) | 1 line
Init _opl to 0. This prevents a crash on exit when the Adlib driver is closed, if the game music driver doesn't support music for the currently playing game (e.g. Christmas 1998)
........
r41340 | thebluegr | 2009-06-08 02:50:34 +1000 (Mon, 08 Jun 2009) | 1 line
Replaced KP_ALT, SKPV_OR_ALT and UKPV_OR_ALT
........
r41341 | fingolfin | 2009-06-08 03:05:58 +1000 (Mon, 08 Jun 2009) | 1 line
cleanup
........
r41342 | fingolfin | 2009-06-08 03:06:32 +1000 (Mon, 08 Jun 2009) | 1 line
SCI: Renamed various song/songlib related structs and members
........
r41343 | fingolfin | 2009-06-08 03:06:51 +1000 (Mon, 08 Jun 2009) | 1 line
SCI: Objectified SongLibrary
........
r41344 | fingolfin | 2009-06-08 03:07:07 +1000 (Mon, 08 Jun 2009) | 1 line
SCI: Objectified Song struct 'a bit'
........
r41345 | fingolfin | 2009-06-08 03:07:25 +1000 (Mon, 08 Jun 2009) | 1 line
SCI: Simplified SongLibrary code a bit
........
r41346 | fingolfin | 2009-06-08 03:18:11 +1000 (Mon, 08 Jun 2009) | 1 line
SCI: Fixed the broken SciEngine::pauseEngineIntern code by ensuring that SciEngine::_gamestate is updated whenever the EngineState gets changed (due to loading a savestate)
........
r41348 | athrxx | 2009-06-08 04:51:03 +1000 (Mon, 08 Jun 2009) | 1 line
LOL: minor bug fix in battle system
........
r41349 | waltervn | 2009-06-08 05:15:55 +1000 (Mon, 08 Jun 2009) | 2 lines
SCI: Moved resource36 handling into resource manager.
........
r41350 | lordhoto | 2009-06-08 05:58:00 +1000 (Mon, 08 Jun 2009) | 2 lines
Avoid warning about missing SFX file in Lands of Lore (it seems the original misses some datafiles for certain effects).
........
r41351 | lordhoto | 2009-06-08 06:43:43 +1000 (Mon, 08 Jun 2009) | 2 lines
Remove LoLEngine::_gameFlags and convert all Lands of Lore code to use _flagsTable instead.
........
r41352 | sev | 2009-06-08 08:05:57 +1000 (Mon, 08 Jun 2009) | 3 lines
Added current keymapper dialog to all themes so it could be tested by other
devs.
........
r41353 | thebluegr | 2009-06-08 08:15:28 +1000 (Mon, 08 Jun 2009) | 1 line
Applied madmoose's patch from bug report #2794216 - "Loading large Smacker movies is slow"
........
r41354 | thebluegr | 2009-06-08 08:17:44 +1000 (Mon, 08 Jun 2009) | 1 line
Formatting
........
r41355 | sev | 2009-06-08 08:19:48 +1000 (Mon, 08 Jun 2009) | 3 lines
Added Clear button for search box. Looks a bit off, but we do not yet have
skinned buttons.
........
r41356 | thebluegr | 2009-06-08 08:34:03 +1000 (Mon, 08 Jun 2009) | 1 line
Changed the bitstream buffer used to initialize the big Huffman trees to be a normal byte array, instead of a Common::Array
........
r41357 | lordhoto | 2009-06-08 08:41:38 +1000 (Mon, 08 Jun 2009) | 2 lines
Remove unneeded functionality from Screen.
........
r41358 | athrxx | 2009-06-08 08:42:21 +1000 (Mon, 08 Jun 2009) | 1 line
LOL: minor bug fix
........
r41359 | fingolfin | 2009-06-08 09:04:34 +1000 (Mon, 08 Jun 2009) | 1 line
SCI: Got rid of g_EngineState
........
r41360 | fingolfin | 2009-06-08 09:05:11 +1000 (Mon, 08 Jun 2009) | 1 line
SCI: C++ified the song iterator code a little bit more
........
r41361 | thebluegr | 2009-06-08 09:29:11 +1000 (Mon, 08 Jun 2009) | 1 line
Hopefully fixed memory corruption when loading games
........
r41362 | lordhoto | 2009-06-08 12:26:33 +1000 (Mon, 08 Jun 2009) | 3 lines
- Fix Screen_v2::wsaFrameAnimationStep, now the MR album and LoL intro demo WSAs will be correctly played
- Made album page change in MR a bit slower, so it's visible at least
........
r41363 | djwillis | 2009-06-08 18:21:18 +1000 (Mon, 08 Jun 2009) | 1 line
Virtual Keyboard: Fix default keyboard pack to return correct events for ENTER and !.
........
r41364 | thebluegr | 2009-06-08 18:38:10 +1000 (Mon, 08 Jun 2009) | 1 line
Moved some more debug commands to ScummVM's console
........
r41365 | Kirben | 2009-06-08 18:56:32 +1000 (Mon, 08 Jun 2009) | 1 line
Update details for the Polish version of The Feeble Files.
........
r41366 | djwillis | 2009-06-08 19:10:12 +1000 (Mon, 08 Jun 2009) | 1 line
Virtual Keyboard: Add source files for the default keyboard pack seperate from ZIP archive (makes it easier to version the packs vkeybd.xml and track fixes) and add script to build keyboard pack(s) ZIP's from source files (based on /gui/themes/scummtheme.py).
........
r41367 | thebluegr | 2009-06-08 21:42:13 +1000 (Mon, 08 Jun 2009) | 1 line
Replaced GFXWARN with warning and GFXDEBUG with debugC
........
r41368 | waltervn | 2009-06-08 22:20:36 +1000 (Mon, 08 Jun 2009) | 2 lines
SCI: Cleanup
........
r41369 | Hkz | 2009-06-08 22:37:24 +1000 (Mon, 08 Jun 2009) | 1 line
sword1: add Broken Sword PSX demo support
........
r41372 | Kirben | 2009-06-09 00:21:43 +1000 (Tue, 09 Jun 2009) | 1 line
Add Polish font data for The Feeble Files.
........
r41373 | djwillis | 2009-06-09 00:47:38 +1000 (Tue, 09 Jun 2009) | 1 line
Virtual Keyboard: Move vkeybd.zip into packs folder and rename default keyboard pack to vkeybd_default(.zip) with updates to default-events.cpp. Also update vkeybdpack.py to use zlib compression if Python zlib is found. Update GP2X and GP2XWiz bundle files to get new vkeybd_default.zip.
........
r41374 | Kirben | 2009-06-09 00:50:34 +1000 (Tue, 09 Jun 2009) | 1 line
Add more Polish font data for The Feeble Files.
........
r41375 | Kirben | 2009-06-09 00:55:11 +1000 (Tue, 09 Jun 2009) | 1 line
Spacing.
........
r41376 | djwillis | 2009-06-09 01:45:03 +1000 (Tue, 09 Jun 2009) | 1 line
Virtual Keyboard: Fix slight error in earlier commit (failed to rename the XML to match the keyboard pack name).
........
r41379 | lordhoto | 2009-06-09 03:47:37 +1000 (Tue, 09 Jun 2009) | 2 lines
Fix out of bounds memory access in Screen::drawShape.
........
r41380 | Hkz | 2009-06-09 03:54:44 +1000 (Tue, 09 Jun 2009) | 1 line
sword1: slight cleanup of psx related sound code and comments
........
r41381 | lordhoto | 2009-06-09 04:30:28 +1000 (Tue, 09 Jun 2009) | 2 lines
Cleanup.
........
r41384 | lordhoto | 2009-06-09 06:11:07 +1000 (Tue, 09 Jun 2009) | 3 lines
- Cleanup
- Fix regression in Kyra1 outro
........
r41385 | djwillis | 2009-06-09 06:31:49 +1000 (Tue, 09 Jun 2009) | 1 line
Virtual Keyboard: Add some quick changes to the virtual keyboard to activate submit and cancel events from the default lowercase keyboards. This makes it possible to cancel and submit without having to call Common::KEYCODE_F7 again. Sorry for the nasty (temp) graphics.
........
r41386 | buddha_ | 2009-06-09 06:46:21 +1000 (Tue, 09 Jun 2009) | 3 lines
Convert FWRenderer and OSRenderer to use Cine::Palette.
Also fix some bugs that came up in testing of Cine::Palette.
........
r41389 | sev | 2009-06-09 07:52:32 +1000 (Tue, 09 Jun 2009) | 2 lines
Actually we /did not/ put periods at ends of the sentences in majority of past entries
........
r41393 | Kirben | 2009-06-09 10:00:24 +1000 (Tue, 09 Jun 2009) | 1 line
Correct check for font data table used in The Feeble Files.
........
r41395 | Kirben | 2009-06-09 16:37:42 +1000 (Tue, 09 Jun 2009) | 1 line
Remove unused old code.
........
r41398 | lordhoto | 2009-06-09 21:26:15 +1000 (Tue, 09 Jun 2009) | 5 lines
- Moved Screen_v2::copyWsaRect to Screen::copyWsaRect
- Made WSAMovie_v1::displayFrame code match the original
- Changed WSAMovieAmiga::displayFrame to use Screen::copyWsaRect too
- Got rid of '...' parameter usage in all WSA player classes
........
r41400 | wjpalenstijn | 2009-06-10 01:26:09 +1000 (Wed, 10 Jun 2009) | 1 line
Add (failing) hashmap test case for collision handling
........
r41401 | lordhoto | 2009-06-10 01:34:02 +1000 (Wed, 10 Jun 2009) | 2 lines
Changed some lines to tabs instead of whitespaces for identation.
........
r41402 | drmccoy | 2009-06-10 04:14:49 +1000 (Wed, 10 Jun 2009) | 1 line
Win Gob3 is multi-lingual (British, French, German)
........
r41403 | drmccoy | 2009-06-10 04:18:11 +1000 (Wed, 10 Jun 2009) | 1 line
Win Gob2 is multi-lingual (American, French, German)
........
r41404 | drmccoy | 2009-06-10 04:19:11 +1000 (Wed, 10 Jun 2009) | 1 line
Win Gob1 is multi-lingual (British, French, German, Italian, Spanish)
........
r41405 | drmccoy | 2009-06-10 04:52:55 +1000 (Wed, 10 Jun 2009) | 1 line
Multi-lingual Inca2 version (American, French, German, Italian, Spanish)
........
r41406 | drmccoy | 2009-06-10 04:53:17 +1000 (Wed, 10 Jun 2009) | 1 line
Win Lost in Time is multi-lingual (British, French, Spanish)
........
r41407 | drmccoy | 2009-06-10 04:53:35 +1000 (Wed, 10 Jun 2009) | 2 lines
Added a workaround for Win Lost in Time.
It's got VMD files which are still referenced as IMD
........
r41408 | waltervn | 2009-06-10 05:18:48 +1000 (Wed, 10 Jun 2009) | 2 lines
SCI: Moved SCI1 audio map handling into the resource manager.
........
r41409 | drmccoy | 2009-06-10 05:37:24 +1000 (Wed, 10 Jun 2009) | 1 line
Fixed CLEAR
........
r41419 | sev | 2009-06-10 18:18:44 +1000 (Wed, 10 Jun 2009) | 1 line
Clarify that Cygwin is not supported as building platform anymore
........
r41421 | sev | 2009-06-10 20:11:24 +1000 (Wed, 10 Jun 2009) | 1 line
Added debugCN() call which does not add newline automatically
........
r41423 | dreammaster | 2009-06-10 22:15:50 +1000 (Wed, 10 Jun 2009) | 1 line
Added variable to savegame format so that savegames can be correctly loaded from the ScummVM launcher
........
r41424 | dreammaster | 2009-06-10 22:16:30 +1000 (Wed, 10 Jun 2009) | 1 line
Added support for loading savegames from the launcher
........
r41425 | lordhoto | 2009-06-10 22:47:19 +1000 (Wed, 10 Jun 2009) | 2 lines
Fix documentation for debugC and debugCN, relying on special debug levels.
........
r41428 | lordhoto | 2009-06-11 01:01:20 +1000 (Thu, 11 Jun 2009) | 2 lines
Fix a bug in disableCursorPalette, where it never allowed the palette to be enabled properly again.
........
r41429 | strangerke | 2009-06-11 01:04:21 +1000 (Thu, 11 Jun 2009) | 3 lines
Gob detection :
- use GUIO_NOSPEECH and GUIO_NOSUBTITLES intensively, as there is no control other them even when they are present
- Replace non-ASCII characters by hex values
........
r41430 | lordhoto | 2009-06-11 01:11:17 +1000 (Thu, 11 Jun 2009) | 2 lines
Extend documentation for "kFeatureCursorHasPalette".
........
r41432 | lordhoto | 2009-06-11 01:20:52 +1000 (Thu, 11 Jun 2009) | 2 lines
Add a convenience wrapper to CursorMan for checking whether cursor palettes are supported.
........
r41433 | jvprat | 2009-06-11 01:33:37 +1000 (Thu, 11 Jun 2009) | 2 lines
Point to the Cursor and AudioCD Managers to help engine authors following the right path.
........
r41452 | sev | 2009-06-12 01:45:52 +1000 (Fri, 12 Jun 2009) | 1 line
Added set of CoCo3 AGI games
........
r41453 | buddha_ | 2009-06-12 04:32:35 +1000 (Fri, 12 Jun 2009) | 8 lines
Fix Operation Stealth's 2nd arcade sequence's revolving doors.
- Now the doors actually do revolve when before they didn't.
- The fix was to alias the 9th background with the collision
page directly when loading collision page data. This way
changes written to the 9th background go to the collision
page and vice versa (And there were changes in the labyrinth).
- Also converted _bgTable from a pure array to a Common::Array
........
r41458 | peres001 | 2009-06-12 15:03:18 +1000 (Fri, 12 Jun 2009) | 2 lines
* Final version of the IFF parsing code.
* Refactored ILBMDecoder usage from disk code.
........
r41459 | peres001 | 2009-06-12 16:20:11 +1000 (Fri, 12 Jun 2009) | 1 line
Removed a leftover printf().
........
r41460 | peres001 | 2009-06-12 17:18:01 +1000 (Fri, 12 Jun 2009) | 2 lines
* Replaced the A8SVXDecoder class with a function to return an AudioStream in trunk/sound/.
* Refactored sound code in Parallaction to use the new Audio::make8SVXStream.
........
r41461 | peres001 | 2009-06-12 17:55:44 +1000 (Fri, 12 Jun 2009) | 1 line
Cleanup of sound code.
........
r41462 | sev | 2009-06-12 18:00:26 +1000 (Fri, 12 Jun 2009) | 1 line
Rename KeyRemapper dialog to KeyMapper
........
r41465 | peres001 | 2009-06-12 18:51:05 +1000 (Fri, 12 Jun 2009) | 2 lines
* Moved the updated IFF code from Parallaction to common/
* Updated Parallaction and SAGA to use the new decoder infrastructure.
........
r41468 | peres001 | 2009-06-12 19:49:38 +1000 (Fri, 12 Jun 2009) | 3 lines
* Adapted Kyra to the new IFFParser interface.
* Adapted the new IFFParser to Kyra (slightly).
The Kyra1 demo on the website works.
........
r41470 | peres001 | 2009-06-12 19:56:07 +1000 (Fri, 12 Jun 2009) | 1 line
Finally fix build (extra qualifier removed).
........
r41473 | peres001 | 2009-06-12 20:26:15 +1000 (Fri, 12 Jun 2009) | 1 line
Added missing return statements.
........
r41474 | peres001 | 2009-06-12 20:26:58 +1000 (Fri, 12 Jun 2009) | 1 line
Fixed disposeStream initialization.
........
r41484 | strangerke | 2009-06-13 08:35:08 +1000 (Sat, 13 Jun 2009) | 1 line
Fix MSVC compilation : iff.h and iff.cpp were move from engines\parallaction\ to graphics\
........
r41485 | waltervn | 2009-06-13 09:29:27 +1000 (Sat, 13 Jun 2009) | 2 lines
SCI: Added detection entries for Japanese QFG.
........
r41486 | waltervn | 2009-06-13 09:46:23 +1000 (Sat, 13 Jun 2009) | 2 lines
SCI: Moved audio code from AudioResource to the sfx core.
........
r41487 | strangerke | 2009-06-13 17:54:25 +1000 (Sat, 13 Jun 2009) | 1 line
Oups. disk.cpp was also missing in MSVC files
........
r41488 | vinterstum | 2009-06-13 19:40:42 +1000 (Sat, 13 Jun 2009) | 1 line
Updated xcode project
........
r41489 | thebluegr | 2009-06-13 20:20:12 +1000 (Sat, 13 Jun 2009) | 1 line
Properly updated the MSVC project files of the parallaction engine, fixing compilation. Side note: please, don't include files outside the engine's directory (like files in /common) for engine project files - it's wrong, as the same code will be compiled twice
........
r41490 | thebluegr | 2009-06-13 20:23:23 +1000 (Sat, 13 Jun 2009) | 1 line
Removed duplicate entry of disk.cpp
........
r41493 | vinterstum | 2009-06-13 23:27:21 +1000 (Sat, 13 Jun 2009) | 1 line
Buildfix for gcc 3.3 (moved a template class member into the header file)
........
r41496 | wjpalenstijn | 2009-06-14 07:07:05 +1000 (Sun, 14 Jun 2009) | 3 lines
Fix erase() sometimes hiding other hash elements.
Like CPython, we now use a dummy node to mark nodes as erased,
so that lookup() can skip over it. All tests should now pass again.
........
r41497 | drmccoy | 2009-06-14 08:10:55 +1000 (Sun, 14 Jun 2009) | 1 line
Making TotTextData's item's offsets unsigned. This could fix the crash in the Polish Woodruff version (bug #2804962)
........
r41498 | strangerke | 2009-06-14 08:14:58 +1000 (Sun, 14 Jun 2009) | 1 line
Gob - *WIP* incomplete implementation of MDY/TBR
........
r41499 | drmccoy | 2009-06-14 08:35:22 +1000 (Sun, 14 Jun 2009) | 1 line
Warn when a sprite operation is to be performed on a nonexistent surface instead of crashing
........
r41500 | lordhoto | 2009-06-14 08:40:30 +1000 (Sun, 14 Jun 2009) | 2 lines
Strip trailing whitespaces.
........
r41501 | sev | 2009-06-14 08:48:16 +1000 (Sun, 14 Jun 2009) | 2 lines
Added sanity checking to stopSound() and a bit more debug output
........
r41502 | lordhoto | 2009-06-14 08:48:32 +1000 (Sun, 14 Jun 2009) | 2 lines
Added periods to every news entry (actually it seems like we always did that in the past, but were a bit lazier in the last time).
........
r41503 | lordhoto | 2009-06-14 09:04:26 +1000 (Sun, 14 Jun 2009) | 2 lines
Added yet another missing period at the end of a line. (I hope I catched all now)
........
r41504 | marcus_c | 2009-06-14 09:42:39 +1000 (Sun, 14 Jun 2009) | 5 lines
Detected games with different language or platform are now
no longer treated as duplicates, even if they have the same
target and directory. Also, pass these parameters to the
ConfMan, so that the correct version of the game is started.
........
r41506 | dreammaster | 2009-06-14 13:39:30 +1000 (Sun, 14 Jun 2009) | 1 line
Beginnings of music support for Cruise, based on the cine engine sound code (note that the music played isn't yet correct, though)
........
r41507 | lordhoto | 2009-06-14 21:08:35 +1000 (Sun, 14 Jun 2009) | 2 lines
Fix unused variable warning.
........
r41508 | drmccoy | 2009-06-14 22:19:42 +1000 (Sun, 14 Jun 2009) | 1 line
Fixed an animation speed regression that got introduced when I added a lag compensation for Woodruff
........
r41516 | lordhoto | 2009-06-15 00:05:42 +1000 (Mon, 15 Jun 2009) | 2 lines
Got rid of a needless "getEventManager" call. (Using Engine::_eventMan now instead)
........
r41517 | waltervn | 2009-06-15 00:11:21 +1000 (Mon, 15 Jun 2009) | 2 lines
SCI: Added detection entries for Japanese SQ4.
........
r41519 | lordhoto | 2009-06-15 00:24:28 +1000 (Mon, 15 Jun 2009) | 2 lines
Cleanup.
........
r41520 | cyx | 2009-06-15 01:07:34 +1000 (Mon, 15 Jun 2009) | 1 line
simplified .raw/.wav data files handling in introduction sequences
........
r41528 | jvprat | 2009-06-15 08:10:17 +1000 (Mon, 15 Jun 2009) | 2 lines
Fix groovie's GUI game options
........
r41536 | sev | 2009-06-15 17:06:52 +1000 (Mon, 15 Jun 2009) | 2 lines
Run AGIMOUSE hack as a side effect always
........
r41537 | thebluegr | 2009-06-15 18:24:01 +1000 (Mon, 15 Jun 2009) | 1 line
Added the missing pixelformat.h file
........
r41538 | thebluegr | 2009-06-15 18:44:35 +1000 (Mon, 15 Jun 2009) | 1 line
Added aliases for the script/breakpoint related commands and added the debugflag related commands to the help screen
........
r41556 | strangerke | 2009-06-16 05:46:00 +1000 (Tue, 16 Jun 2009) | 1 line
Add MD5 for Playtoons 4 FR
........
r41557 | athrxx | 2009-06-16 06:52:09 +1000 (Tue, 16 Jun 2009) | 4 lines
LOL: - started on the ingame menu code (death menu, load menu and main menu)
- fixed regression in kyra gui code (broken menu highlighting)
- fixed minor bug in animation code
........
r41559 | strangerke | 2009-06-16 07:28:11 +1000 (Tue, 16 Jun 2009) | 1 line
renamed playtoons target names to insult-free target names (maybe non-definitive names)
........
r41560 | athrxx | 2009-06-16 07:39:43 +1000 (Tue, 16 Jun 2009) | 1 line
LOL: implemented quit menu
........
r41562 | drmccoy | 2009-06-16 09:07:38 +1000 (Tue, 16 Jun 2009) | 1 line
Merging parseValExpr and parseExpr
........
r41563 | drmccoy | 2009-06-16 09:07:55 +1000 (Tue, 16 Jun 2009) | 1 line
Renamed varPos to varBase and split off getVarBase() from parseVarIndex() and parseExpr()
........
r41564 | drmccoy | 2009-06-16 09:08:09 +1000 (Tue, 16 Jun 2009) | 1 line
Renamed various variables to better reflect their meaning
........
r41565 | drmccoy | 2009-06-16 09:08:28 +1000 (Tue, 16 Jun 2009) | 1 line
Propagating variable name changes
........
r41566 | drmccoy | 2009-06-16 09:08:44 +1000 (Tue, 16 Jun 2009) | 1 line
Fixing the signness indicated by the OP_ enums
........
r41567 | drmccoy | 2009-06-16 09:09:04 +1000 (Tue, 16 Jun 2009) | 1 line
Adding a TYPE_ enum
........
r41568 | drmccoy | 2009-06-16 09:09:23 +1000 (Tue, 16 Jun 2009) | 1 line
Using the TYPE_ enum where applicable
........
r41569 | drmccoy | 2009-06-16 09:09:37 +1000 (Tue, 16 Jun 2009) | 1 line
Renaming some variables in o1_assign() and o2_assign() to mirror the structure in o6_assign()
........
r41570 | drmccoy | 2009-06-16 09:09:57 +1000 (Tue, 16 Jun 2009) | 1 line
Using cmpHelper for OP_NEQ too, since the original does a normal strcmp there as well. No idea where the stricmp came from
........
r41571 | drmccoy | 2009-06-16 09:10:10 +1000 (Tue, 16 Jun 2009) | 1 line
Remove some now superfluous comments
........
r41572 | drmccoy | 2009-06-16 09:10:27 +1000 (Tue, 16 Jun 2009) | 1 line
Splitting up parseExpr a bit
........
r41573 | drmccoy | 2009-06-16 09:10:51 +1000 (Tue, 16 Jun 2009) | 1 line
Moving _inter_resVal and _inter_resStr from Global to Parse
........
r41574 | drmccoy | 2009-06-16 09:11:08 +1000 (Tue, 16 Jun 2009) | 1 line
Renaming _inter_resVal to _resultInt
........
r41575 | drmccoy | 2009-06-16 09:11:29 +1000 (Tue, 16 Jun 2009) | 1 line
Renamed _inter_resStr to _resultStr
........
r41576 | athrxx | 2009-06-16 09:22:31 +1000 (Tue, 16 Jun 2009) | 1 line
KYRA: fixed regression (broken menu slide bars in HOF/MR)
........
r41579 | strangerke | 2009-06-16 17:14:07 +1000 (Tue, 16 Jun 2009) | 1 line
Add MD5 for Playtoons 3 (english)
........
r41584 | strangerke | 2009-06-16 22:25:53 +1000 (Tue, 16 Jun 2009) | 1 line
MDY/TBR : fix a thing or two. Still far from being OK, but in-game ambiance "music" is (a little) less buggy
........
r41587 | Hkz | 2009-06-17 04:58:21 +1000 (Wed, 17 Jun 2009) | 1 line
tinsel: check only english.txt for DW1 psx version detection, and use recursive "SearchMan.addDirectory()" to obtain subdirs for Discworld PSX datafiles
........
r41588 | lordhoto | 2009-06-17 05:26:44 +1000 (Wed, 17 Jun 2009) | 2 lines
Formatting.
........
r41589 | drmccoy | 2009-06-17 06:14:56 +1000 (Wed, 17 Jun 2009) | 1 line
Encapsulating stack adjustments
........
r41590 | drmccoy | 2009-06-17 06:15:19 +1000 (Wed, 17 Jun 2009) | 1 line
Encapsulating the Stack and StackFrame a bit
........
r41591 | drmccoy | 2009-06-17 06:15:49 +1000 (Wed, 17 Jun 2009) | 1 line
Properly initializing _soundMode, for ADLs too
........
r41592 | drmccoy | 2009-06-17 06:39:37 +1000 (Wed, 17 Jun 2009) | 1 line
Including scummsys.h and forward-declaring GobEngine
........
r41596 | athrxx | 2009-06-17 07:23:26 +1000 (Wed, 17 Jun 2009) | 1 line
LOL: implemented options menu (settings aren't saved yet)
........
r41598 | sev | 2009-06-17 07:59:20 +1000 (Wed, 17 Jun 2009) | 2 lines
Disable music for CoCo3 games. It has different format.
........
r41601 | drmccoy | 2009-06-17 14:15:45 +1000 (Wed, 17 Jun 2009) | 1 line
Changed opcodeDraw to be functor-based
........
r41602 | drmccoy | 2009-06-17 14:16:21 +1000 (Wed, 17 Jun 2009) | 1 line
Changed opcodeFunc to be functor-based
........
r41603 | drmccoy | 2009-06-17 14:16:51 +1000 (Wed, 17 Jun 2009) | 1 line
Changed opcodeGob to be functor-based
........
r41611 | strangerke | 2009-06-18 04:48:41 +1000 (Thu, 18 Jun 2009) | 2 lines
- Modify detection files for Playtoons CK Knights (CK2) as it wasn't making the difference with CK1
- Add Playtoons CK Monsters (CK1)
........
r41618 | sev | 2009-06-18 09:16:21 +1000 (Thu, 18 Jun 2009) | 2 lines
Preliminary support for CoCo3 music.
........
r41619 | dhewg | 2009-06-18 09:36:00 +1000 (Thu, 18 Jun 2009) | 1 line
Moved the wiidist target to ports.mk, cleaned it up and automated meta.xml generation.
........
r41630 | dreammaster | 2009-06-18 21:37:45 +1000 (Thu, 18 Jun 2009) | 1 line
Removed redundant code that isn't used
........
r41632 | drmccoy | 2009-06-18 23:27:14 +1000 (Thu, 18 Jun 2009) | 1 line
Replacing some #includes by forward declarations
........
r41633 | drmccoy | 2009-06-18 23:27:35 +1000 (Thu, 18 Jun 2009) | 1 line
Splitting an ADLPlayer and MDYPlayer from the AdLib class
........
r41634 | drmccoy | 2009-06-18 23:27:48 +1000 (Thu, 18 Jun 2009) | 1 line
Oops, forgot again that Fascination needs o1_assign
........
r41635 | Hkz | 2009-06-18 23:50:26 +1000 (Thu, 18 Jun 2009) | 1 line
scumm: added the missing word "version" in a comment
........
r41639 | dhewg | 2009-06-19 04:40:38 +1000 (Fri, 19 Jun 2009) | 1 line
added DIST_FILES_DOCS to Makefile.common, used by some dist targets now, incl. OSX bundles.
........
r41641 | vinterstum | 2009-06-19 04:57:17 +1000 (Fri, 19 Jun 2009) | 1 line
Improved the iphone swipe input handling
........
r41644 | dhewg | 2009-06-19 05:39:12 +1000 (Fri, 19 Jun 2009) | 1 line
added pred.dic to DIST_FILES_ENGINEDATA
........
r41645 | drmccoy | 2009-06-19 07:08:51 +1000 (Fri, 19 Jun 2009) | 1 line
Removing the useless _vm->_parse->
........
r41646 | lordhoto | 2009-06-19 07:47:10 +1000 (Fri, 19 Jun 2009) | 2 lines
Replaced "getRandomNumberSpecial" be RandomSource usage. (This is needed for proper event recording, also the probability for generated numbers is actually nearly the same)
........
r41647 | fingolfin | 2009-06-19 08:09:57 +1000 (Fri, 19 Jun 2009) | 1 line
Patch
........
r41660 | thebluegr | 2009-06-19 17:56:30 +1000 (Fri, 19 Jun 2009) | 1 line
Fixed a warning about an uninitialized variable
........
r41663 | drmccoy | 2009-06-19 19:42:41 +1000 (Fri, 19 Jun 2009) | 1 line
Ooops, forgot to change the array when copy-pasting the description function
........
r41664 | drmccoy | 2009-06-19 19:43:01 +1000 (Fri, 19 Jun 2009) | 1 line
Fixing The Last Dynasty again after the opcode dispatcher changes
........
r41665 | dreammaster | 2009-06-19 19:44:33 +1000 (Fri, 19 Jun 2009) | 1 line
Added myself to the CRUISE engine credits
........
r41668 | drmccoy | 2009-06-19 19:55:23 +1000 (Fri, 19 Jun 2009) | 1 line
Added my German version of The Last Dynasty
........
r41677 | athrxx | 2009-06-20 03:03:28 +1000 (Sat, 20 Jun 2009) | 2 lines
LOL: - implemented bezel cup opcode
- implemented font conversion for certain language specific characters in load game dialogue (only german atm)
........
r41679 | lordhoto | 2009-06-20 03:53:25 +1000 (Sat, 20 Jun 2009) | 2 lines
Fix some warnings.
........
r41680 | waltervn | 2009-06-20 04:07:45 +1000 (Sat, 20 Jun 2009) | 2 lines
SCI: Fix cel1 y-offset regression introduced in r40997.
........
r41683 | athrxx | 2009-06-20 04:46:19 +1000 (Sat, 20 Jun 2009) | 3 lines
LOL: - implemented delete menu
- fixed some bugs in the menu code
........
r41699 | dreammaster | 2009-06-20 16:20:12 +1000 (Sat, 20 Jun 2009) | 1 line
Added explicit casts to _fontConversionTableGerman for systems where char is signed
........
r41700 | dreammaster | 2009-06-20 16:48:47 +1000 (Sat, 20 Jun 2009) | 1 line
Finally tracked down the difference/bug in the music playing code - music playback now works
........
r41701 | dreammaster | 2009-06-20 17:36:12 +1000 (Sat, 20 Jun 2009) | 1 line
Bugfix to fade out any currently playing music when the game is restarted
........
r41702 | dreammaster | 2009-06-20 18:15:01 +1000 (Sat, 20 Jun 2009) | 1 line
Added proper saving of music state to savegames so music resumes when a savegame is loaded.
........
r41703 | dreammaster | 2009-06-20 18:15:39 +1000 (Sat, 20 Jun 2009) | 1 line
Implemented the library function Op_SongExist
........
r41704 | cyx | 2009-06-20 20:52:55 +1000 (Sat, 20 Jun 2009) | 2 lines
fixed OPL 0xB0 register write. the return value of findNote() already includes the octave, no need to readd it.
........
r41705 | dhewg | 2009-06-20 21:48:42 +1000 (Sat, 20 Jun 2009) | 2 lines
split loadKeyboardPack(), fallback to the current dir when searching for packs, and free memory in the case of an error.
........
r41707 | dhewg | 2009-06-20 21:50:15 +1000 (Sat, 20 Jun 2009) | 1 line
added vkeybd_default.zip to the Wii dist target.
........
r41708 | dhewg | 2009-06-20 21:53:31 +1000 (Sat, 20 Jun 2009) | 1 line
oups, wrong spot.
........
r41709 | dreammaster | 2009-06-20 22:02:08 +1000 (Sat, 20 Jun 2009) | 1 line
Changed many file reads and manual conversions from endian format to instead use file readSint16BE/readSint32BE calls
........
r41713 | athrxx | 2009-06-21 00:26:01 +1000 (Sun, 21 Jun 2009) | 1 line
LOL: implemented save menu
........
r41714 | athrxx | 2009-06-21 01:09:55 +1000 (Sun, 21 Jun 2009) | 1 line
LOL: cleanup
........
r41715 | athrxx | 2009-06-21 02:36:26 +1000 (Sun, 21 Jun 2009) | 1 line
LOL: minor fix for save menu
........
r41718 | lordhoto | 2009-06-21 11:14:57 +1000 (Sun, 21 Jun 2009) | 1 line
Prevent font code to draw characters not included in the font.
........
r41719 | lordhoto | 2009-06-21 11:15:09 +1000 (Sun, 21 Jun 2009) | 1 line
Fix drawing of sharp s.
........
r41720 | lordhoto | 2009-06-21 11:15:24 +1000 (Sun, 21 Jun 2009) | 1 line
Moved CP850<->ISO-8859-1 conversion to Util.
........
r41721 | lordhoto | 2009-06-21 11:15:37 +1000 (Sun, 21 Jun 2009) | 1 line
Enable proper umlaut handling in kyra 1-3.
........
r41722 | lordhoto | 2009-06-21 11:15:47 +1000 (Sun, 21 Jun 2009) | 1 line
Fix umlauts for original interpreter saves.
........
r41723 | lordhoto | 2009-06-21 11:22:23 +1000 (Sun, 21 Jun 2009) | 1 line
Cleanup.
........
r41724 | dreammaster | 2009-06-21 15:13:29 +1000 (Sun, 21 Jun 2009) | 1 line
Bugfixes to pre-loading and handling of resources such as sound files
........
r41725 | dreammaster | 2009-06-21 21:42:45 +1000 (Sun, 21 Jun 2009) | 1 line
Changed .SPL (sound effect) loading to load the Adlib version of sound effects - sound effects now work
........
r41726 | dreammaster | 2009-06-21 21:53:11 +1000 (Sun, 21 Jun 2009) | 1 line
Minor fixes to the individual note playing code
........
r41727 | thebluegr | 2009-06-21 23:06:08 +1000 (Sun, 21 Jun 2009) | 1 line
Cleanup
........
r41729 | athrxx | 2009-06-22 02:59:51 +1000 (Mon, 22 Jun 2009) | 3 lines
LOL: - implemented audio menu
- menu settings now get saved
- remove white spaces
........
r41730 | lordhoto | 2009-06-22 05:00:50 +1000 (Mon, 22 Jun 2009) | 1 line
Cleanup: Change LoL code to use KYRA volume handling.
........
r41731 | lordhoto | 2009-06-22 05:01:04 +1000 (Mon, 22 Jun 2009) | 1 line
Cleanup: Change LoL specific config entries to use underscores instead of whitespaces.
........
r41732 | lordhoto | 2009-06-22 05:49:20 +1000 (Mon, 22 Jun 2009) | 1 line
Fix slider buttons in LoL (and some minor cleanup).
........
r41733 | lordhoto | 2009-06-22 06:10:45 +1000 (Mon, 22 Jun 2009) | 1 line
Cleanup.
........
r41734 | athrxx | 2009-06-22 06:40:31 +1000 (Mon, 22 Jun 2009) | 2 lines
LOL: - implemented support for "floating cursors"
- prevent complete refresh for audio menu whenever a mouse button is pressed
........
r41735 | athrxx | 2009-06-22 07:05:06 +1000 (Mon, 22 Jun 2009) | 1 line
LOL: minor fix for floating cursors
........
r41736 | lordhoto | 2009-06-22 07:17:41 +1000 (Mon, 22 Jun 2009) | 1 line
Cleanup.
........
r41739 | lordhoto | 2009-06-22 12:34:35 +1000 (Mon, 22 Jun 2009) | 1 line
Start refactoring palette handling into new class "Palette".
........
r41740 | lordhoto | 2009-06-22 12:35:04 +1000 (Mon, 22 Jun 2009) | 1 line
Got rid of Screen::_currentPalette.
........
r41741 | lordhoto | 2009-06-22 12:35:45 +1000 (Mon, 22 Jun 2009) | 1 line
Changed Screen::getPalette to return a reference to a Palette object.
........
r41742 | lordhoto | 2009-06-22 12:36:16 +1000 (Mon, 22 Jun 2009) | 1 line
Add wrapper functionality for copying full palettes.
........
r41743 | lordhoto | 2009-06-22 12:36:54 +1000 (Mon, 22 Jun 2009) | 6 lines
- Changed the following Screen functions to take a reference to a Palette object:
-> setScreenPalette
-> fadePalette
-> getFadeParams
-> fadePalStep
- Fixed initialization of 256 color palettes
........
r41744 | lordhoto | 2009-06-22 12:37:20 +1000 (Mon, 22 Jun 2009) | 1 line
Changed Screen::loadBitmap and Movie::open to take an optional Palette pointer instead of an optional array pointer.
........
r41745 | lordhoto | 2009-06-22 12:37:41 +1000 (Mon, 22 Jun 2009) | 1 line
Changed Screen::loadPalette to take a reference to a Palette object instead of an array.
........
r41746 | lordhoto | 2009-06-22 12:37:57 +1000 (Mon, 22 Jun 2009) | 2 lines
- Fixed regression in Screen::fadeToBlack
- Fixed some palette regressions in Kyra1 Amiga (only the intro works currently)
........
r41747 | lordhoto | 2009-06-22 12:41:56 +1000 (Mon, 22 Jun 2009) | 1 line
Fix memory leak.
........
r41748 | dreammaster | 2009-06-22 16:17:50 +1000 (Mon, 22 Jun 2009) | 1 line
Implemented the Op_SetVolume method like the original, which simply set a dummy variable and never actually changed the volume
........
r41749 | dreammaster | 2009-06-22 16:35:08 +1000 (Mon, 22 Jun 2009) | 1 line
Added the dummy volume variable to the savegame format
........
r41750 | drmccoy | 2009-06-22 20:11:25 +1000 (Mon, 22 Jun 2009) | 1 line
Encapsulated access to Parse::_resultInt
........
r41751 | drmccoy | 2009-06-22 20:11:53 +1000 (Mon, 22 Jun 2009) | 1 line
Encapsulated access to _resultStr
........
r41752 | drmccoy | 2009-06-22 20:12:33 +1000 (Mon, 22 Jun 2009) | 1 line
Adding DataIO::existData()
........
r41753 | drmccoy | 2009-06-22 20:13:37 +1000 (Mon, 22 Jun 2009) | 1 line
Encapsulating script file access
........
r41754 | drmccoy | 2009-06-22 20:14:18 +1000 (Mon, 22 Jun 2009) | 1 line
Implemented a call stack
........
r41755 | drmccoy | 2009-06-22 20:14:49 +1000 (Mon, 22 Jun 2009) | 1 line
Removing debug output
........
r41756 | drmccoy | 2009-06-22 20:15:14 +1000 (Mon, 22 Jun 2009) | 1 line
Implemented loading TOTs from video file again
........
r41757 | drmccoy | 2009-06-22 20:15:52 +1000 (Mon, 22 Jun 2009) | 1 line
Giving CollisionArea a full-blown Script pointer instead the data pointer
........
r41758 | drmccoy | 2009-06-22 20:16:17 +1000 (Mon, 22 Jun 2009) | 1 line
Removing the now useless cuckoo function and shrink the call stack entries accordingly
........
r41759 | drmccoy | 2009-06-22 20:16:45 +1000 (Mon, 22 Jun 2009) | 1 line
Unwinding the call stack before unloading the script
........
r41760 | drmccoy | 2009-06-22 20:29:32 +1000 (Mon, 22 Jun 2009) | 1 line
Putting evalBoolResult() and evalExpr() into Script
........
r41761 | drmccoy | 2009-06-22 20:29:48 +1000 (Mon, 22 Jun 2009) | 1 line
Removing the Parse object from GobEngine
........
r41762 | drmccoy | 2009-06-22 20:30:09 +1000 (Mon, 22 Jun 2009) | 1 line
Pushing script.o down
........
r41763 | dreammaster | 2009-06-22 20:41:32 +1000 (Mon, 22 Jun 2009) | 1 line
Removed redundant variation of the routine to play sound effects
........
r41765 | drmccoy | 2009-06-22 21:53:46 +1000 (Mon, 22 Jun 2009) | 1 line
const correctness
........
r41766 | strangerke | 2009-06-22 22:03:58 +1000 (Mon, 22 Jun 2009) | 1 line
Include recently added script.h and script.cpp
........
r41768 | drmccoy | 2009-06-23 02:29:00 +1000 (Tue, 23 Jun 2009) | 1 line
Removing commented-out declarations
........
r41769 | drmccoy | 2009-06-23 02:29:16 +1000 (Tue, 23 Jun 2009) | 1 line
Adding some comments
........
r41770 | drmccoy | 2009-06-23 02:29:31 +1000 (Tue, 23 Jun 2009) | 1 line
Don't assert on pop when no script is loaded
........
r41771 | drmccoy | 2009-06-23 02:29:45 +1000 (Tue, 23 Jun 2009) | 1 line
More signess consistency on the reading and seeking methods
........
r41772 | drmccoy | 2009-06-23 02:30:06 +1000 (Tue, 23 Jun 2009) | 1 line
Renaming "Parse" to "Expression"
........
r41773 | drmccoy | 2009-06-23 02:30:35 +1000 (Tue, 23 Jun 2009) | 1 line
Renaming parse.h and parse.cpp to expression.h and expression.cpp
........
r41774 | drmccoy | 2009-06-23 02:30:51 +1000 (Tue, 23 Jun 2009) | 1 line
Renaming kDebugParser to kDebugExpression
........
r41777 | lordhoto | 2009-06-23 05:46:08 +1000 (Tue, 23 Jun 2009) | 1 line
Fix palette regression in Lands of Lore.
........
r41778 | strangerke | 2009-06-23 05:56:06 +1000 (Tue, 23 Jun 2009) | 1 line
rename parse.h and .cpp to expression.h and .cpp
........
r41781 | drmccoy | 2009-06-23 06:27:47 +1000 (Tue, 23 Jun 2009) | 1 line
Added stream-reading loading wrappers to MDYPlayer and added a workaround to fix TBR reading for the moment
........
r41782 | drmccoy | 2009-06-23 06:51:34 +1000 (Tue, 23 Jun 2009) | 1 line
Properly guarding Script::getOffset() and adding a reverse operation
........
r41783 | drmccoy | 2009-06-23 06:51:48 +1000 (Tue, 23 Jun 2009) | 1 line
Removing trailing spaces
........
r41784 | drmccoy | 2009-06-23 06:52:08 +1000 (Tue, 23 Jun 2009) | 1 line
Removing trailing tabs
........
r41785 | fingolfin | 2009-06-23 07:48:47 +1000 (Tue, 23 Jun 2009) | 1 line
Patch #2810483 (SCI: Convert gfx subsystem headers to Doxygen format), with @brief removed
........
r41786 | fingolfin | 2009-06-23 09:09:28 +1000 (Tue, 23 Jun 2009) | 1 line
Fixed NDS compilation when using older devkitpro versions (I accidentally broke that some time ago)
........
r41787 | dreammaster | 2009-06-23 11:01:16 +1000 (Tue, 23 Jun 2009) | 1 line
Bugfixes to keep sound effects to channel #4 like the original (it ignores the channel parameter to the given library routine)
........
r41788 | drmccoy | 2009-06-23 11:19:03 +1000 (Tue, 23 Jun 2009) | 1 line
Added Script methods to get the TOT major and minor version
........
r41789 | drmccoy | 2009-06-23 11:19:21 +1000 (Tue, 23 Jun 2009) | 1 line
Added Script methods to query commun file handling
........
r41790 | drmccoy | 2009-06-23 11:19:37 +1000 (Tue, 23 Jun 2009) | 1 line
Const correctness
........
r41791 | drmccoy | 2009-06-23 11:20:05 +1000 (Tue, 23 Jun 2009) | 1 line
Added a method to query the number of variables needed by a Script
........
r41792 | drmccoy | 2009-06-23 11:20:21 +1000 (Tue, 23 Jun 2009) | 1 line
Added Script::getTextsOffset()
........
r41793 | drmccoy | 2009-06-23 11:21:06 +1000 (Tue, 23 Jun 2009) | 1 line
Added Script::getResourcesOffset()
........
r41794 | drmccoy | 2009-06-23 11:21:51 +1000 (Tue, 23 Jun 2009) | 1 line
Added Script::getAnimDataSize()
........
r41795 | drmccoy | 2009-06-23 11:22:30 +1000 (Tue, 23 Jun 2009) | 1 line
Added Script::getStartOffset()
........
r41796 | drmccoy | 2009-06-23 11:22:51 +1000 (Tue, 23 Jun 2009) | 1 line
Added Script::getCenterOffset()
........
r41797 | drmccoy | 2009-06-23 11:23:14 +1000 (Tue, 23 Jun 2009) | 1 line
Replacing the 2 offset functions by a generic Script::getFunctionOffset()
........
r41798 | drmccoy | 2009-06-23 11:23:31 +1000 (Tue, 23 Jun 2009) | 1 line
Stopping the seek() going into the header
........
r41799 | drmccoy | 2009-06-23 11:23:51 +1000 (Tue, 23 Jun 2009) | 1 line
Also loading TOT properties when the TOT is found in a LOM
........
r41803 | drmccoy | 2009-06-23 18:51:55 +1000 (Tue, 23 Jun 2009) | 1 line
Changing the TBR FIXME into a warning in setVoice()
........
r41806 | Hkz | 2009-06-23 23:24:46 +1000 (Tue, 23 Jun 2009) | 1 line
tinsel: added some comments to psx palette mapper
........
r41809 | drmccoy | 2009-06-24 01:06:38 +1000 (Wed, 24 Jun 2009) | 1 line
Added German Fascination (3 disk version), as supplied by windlepoons in bug report #2809247
........
r41810 | drmccoy | 2009-06-24 01:08:56 +1000 (Wed, 24 Jun 2009) | 1 line
Added Hungarian versions of gob1-gob3 as supplied by goodoldgeorg in bug report #2810082
........
r41811 | drmccoy | 2009-06-24 03:37:18 +1000 (Wed, 24 Jun 2009) | 1 line
Binary, not logical ORing the GUIO flags (Strangerke, you fscked up there :P)
........
r41812 | drmccoy | 2009-06-24 03:55:09 +1000 (Wed, 24 Jun 2009) | 1 line
Added support for Hungarian
........
r41813 | drmccoy | 2009-06-24 03:55:27 +1000 (Wed, 24 Jun 2009) | 1 line
Proper support for Hungarian versions
........
r41821 | drmccoy | 2009-06-24 09:55:19 +1000 (Wed, 24 Jun 2009) | 1 line
Putting basic TOT handling into its own class
........
r41822 | drmccoy | 2009-06-24 09:55:35 +1000 (Wed, 24 Jun 2009) | 1 line
Putting TOT filename generation and LOM checking into TOTFile
........
r41823 | drmccoy | 2009-06-24 09:55:48 +1000 (Wed, 24 Jun 2009) | 1 line
Added methods to get the file base from a filename
........
r41827 | lordhoto | 2009-06-25 03:01:01 +1000 (Thu, 25 Jun 2009) | 1 line
Silence unsued variables warnings.
........
r41833 | waltervn | 2009-06-25 05:12:45 +1000 (Thu, 25 Jun 2009) | 2 lines
SCI: Partial support for dual-language games.
........
r41834 | waltervn | 2009-06-25 05:26:06 +1000 (Thu, 25 Jun 2009) | 2 lines
SCI: Fix regression in r41833.
........
r41836 | drmccoy | 2009-06-25 07:47:54 +1000 (Thu, 25 Jun 2009) | 1 line
Clarifying some warnings
........
r41837 | drmccoy | 2009-06-25 07:48:13 +1000 (Thu, 25 Jun 2009) | 1 line
Checking for the file's existence in DataIO::getDataStream()
........
r41838 | drmccoy | 2009-06-25 07:48:27 +1000 (Thu, 25 Jun 2009) | 1 line
Added the scriptEnd property
........
r41839 | drmccoy | 2009-06-25 07:49:37 +1000 (Thu, 25 Jun 2009) | 1 line
Wrapping resources (out of TOT, EXT, IM? and EX? files) loading into its own class
........
r41841 | mthreepwood | 2009-06-25 10:14:07 +1000 (Thu, 25 Jun 2009) | 1 line
After discussing with waltervn, committing my fix for the King's Quest I Demo (original from Patch #2795916). I'm also fixing the full game as well :)
........
r41844 | lordhoto | 2009-06-25 11:29:14 +1000 (Thu, 25 Jun 2009) | 1 line
Initial support for Kyrandia 1 PC-9801 Japanese 16 color.
........
r41845 | lordhoto | 2009-06-25 11:29:27 +1000 (Thu, 25 Jun 2009) | 1 line
Implement properly colored mouse cursors in 16 color version of Kyrandia 1.
........
r41846 | lordhoto | 2009-06-25 11:29:41 +1000 (Thu, 25 Jun 2009) | 1 line
Implement palette fading for 16 color version of Kyrandia 1.
........
r41847 | lordhoto | 2009-06-25 11:29:55 +1000 (Thu, 25 Jun 2009) | 1 line
Add config option for Kyra1 16 color, it'll only use dithering when "16_color" is set to true.
........
r41848 | lordhoto | 2009-06-25 11:30:12 +1000 (Thu, 25 Jun 2009) | 1 line
Strip trailing whitespaces and tabs.
........
r41850 | lordhoto | 2009-06-25 12:38:19 +1000 (Thu, 25 Jun 2009) | 1 line
Readd PC98 palette loading for LoL 16 color.
........
r41851 | lordhoto | 2009-06-25 12:39:00 +1000 (Thu, 25 Jun 2009) | 1 line
Implement proper VGA (a color component in [0, 63]) to our palette format (color component in [0, 255]) conversion.
........
r41852 | lordhoto | 2009-06-25 12:39:23 +1000 (Thu, 25 Jun 2009) | 1 line
Implement proper AMIGA to VGA color conversion.
........
r41853 | lordhoto | 2009-06-25 12:41:39 +1000 (Thu, 25 Jun 2009) | 1 line
Mention Kyra 1 PC98 16 color dithering support.
........
r41858 | strangerke | 2009-06-25 20:03:23 +1000 (Thu, 25 Jun 2009) | 1 line
Fix compilation issue for MSVC
........
r41859 | drmccoy | 2009-06-25 20:54:35 +1000 (Thu, 25 Jun 2009) | 1 line
Plugging some memory leaks
........
r41860 | drmccoy | 2009-06-25 20:55:01 +1000 (Thu, 25 Jun 2009) | 1 line
Giving the "backup" arrays their own class, Environments, and really plugging all related leaks
........
r41867 | lordhoto | 2009-06-26 01:22:08 +1000 (Fri, 26 Jun 2009) | 1 line
Implement proper color index conversion for Lands of Lore PC98. (The intro and menu screen work fine now)
........
r41868 | drmccoy | 2009-06-26 01:29:19 +1000 (Fri, 26 Jun 2009) | 1 line
Oops, used git commit --amend wrong, apparently. /This/ is the real Environments change I wanted to push
........
r41869 | drmccoy | 2009-06-26 01:37:46 +1000 (Fri, 26 Jun 2009) | 1 line
Adding more version entries for a Gob1 Win version, thanks to Hkz
........
r41870 | lordhoto | 2009-06-26 01:53:09 +1000 (Fri, 26 Jun 2009) | 1 line
Fix japanese font colors in Kyra 1 PC98 16 color.
........
r41871 | lordhoto | 2009-06-26 01:53:21 +1000 (Fri, 26 Jun 2009) | 1 line
Cleanup.
........
r41875 | drmccoy | 2009-06-26 04:53:36 +1000 (Fri, 26 Jun 2009) | 1 line
Making _numDataChunks unsigned
........
r41876 | lordhoto | 2009-06-26 05:52:49 +1000 (Fri, 26 Jun 2009) | 1 line
Cleanup.
........
r41877 | lordhoto | 2009-06-26 05:53:55 +1000 (Fri, 26 Jun 2009) | 1 line
Use Screen::loadPalette instead of Resource::loadFileToBuf.
........
r41878 | lordhoto | 2009-06-26 05:54:41 +1000 (Fri, 26 Jun 2009) | 1 line
Replace yet another palette from file loading with Screen::loadPalette.
........
r41879 | lordhoto | 2009-06-26 05:55:25 +1000 (Fri, 26 Jun 2009) | 1 line
Cleanup VQA player a bit.
........
r41880 | lordhoto | 2009-06-26 05:56:02 +1000 (Fri, 26 Jun 2009) | 1 line
Add a const "getData" access method to Palette.
........
r41881 | lordhoto | 2009-06-26 05:57:06 +1000 (Fri, 26 Jun 2009) | 1 line
Change Screen_v2::generateOverlay to take a const Palette reference instead of a pointer.
........
r41882 | lordhoto | 2009-06-26 05:57:35 +1000 (Fri, 26 Jun 2009) | 1 line
Change Screen_LoL::generateGrayOverlay to use a Palette object internally.
........
r41883 | lordhoto | 2009-06-26 05:58:17 +1000 (Fri, 26 Jun 2009) | 1 line
Change Screen_HoF::generateGrayOverlay to use a Palette object internally.
........
r41884 | lordhoto | 2009-06-26 05:59:06 +1000 (Fri, 26 Jun 2009) | 1 line
Change Screen_LoL genereta overlay functionallity to accept a Palette object as source.
........
r41885 | lordhoto | 2009-06-26 05:59:56 +1000 (Fri, 26 Jun 2009) | 1 line
Change Screen_HoF::generateGrayOverlay to accept a Palette object as source.
........
r41886 | lordhoto | 2009-06-26 06:00:52 +1000 (Fri, 26 Jun 2009) | 1 line
Change Screen_v2::findLeastDifferentColor to take a Palette object as source.
........
r41887 | athrxx | 2009-06-26 07:17:50 +1000 (Fri, 26 Jun 2009) | 2 lines
KYRA/LOL: - support speech/text settings in LOL intro
- fix possible pc98 music issue
........
r41889 | lordhoto | 2009-06-26 09:03:57 +1000 (Fri, 26 Jun 2009) | 1 line
Implement difference in PC98 version. (This actually breaks the text colors in the LoL intro for now...)
........
r41890 | lordhoto | 2009-06-26 09:04:08 +1000 (Fri, 26 Jun 2009) | 1 line
Cleanup palette setup.
........
r41891 | lordhoto | 2009-06-26 09:04:21 +1000 (Fri, 26 Jun 2009) | 1 line
Store palettes in a Common::Array instead of a fixed size array.
........
r41892 | lordhoto | 2009-06-26 09:04:32 +1000 (Fri, 26 Jun 2009) | 1 line
Only initialize palettes with 16 colors in (real) 16 color games.
........
r41893 | lordhoto | 2009-06-26 09:04:43 +1000 (Fri, 26 Jun 2009) | 1 line
For now always enable voices in PC98 version of LoL.
........
r41895 | lordhoto | 2009-06-26 10:11:56 +1000 (Fri, 26 Jun 2009) | 1 line
Implement PC98 text mode color palette.
........
r41896 | lordhoto | 2009-06-26 10:12:08 +1000 (Fri, 26 Jun 2009) | 1 line
Implement palette difference in Kanji drawing code for PC98.
........
r41897 | lordhoto | 2009-06-26 10:12:19 +1000 (Fri, 26 Jun 2009) | 1 line
Implement difference in TIM's displayText code for PC98, this should fix the font color in the intro.
........
r41902 | athrxx | 2009-06-27 03:58:27 +1000 (Sat, 27 Jun 2009) | 1 line
KYRA/LOL: fixed minor bug by adding reset() call to pc98 audio driver destructor
........
r41903 | drmccoy | 2009-06-27 05:03:37 +1000 (Sat, 27 Jun 2009) | 1 line
Fixing text strings embedded in the TOT
........
r41915 | buddha_ | 2009-06-27 22:26:26 +1000 (Sat, 27 Jun 2009) | 11 lines
Name Operation Stealth's global variables 251 and 252 and init them in main loop.
These are used as a sort of a backup for the
mouse position (x, y) variables 249 and 250.
Future Wars's VAR_MOUSE_Y_MODE and Operation Stealth's
VAR_MOUSE_X_POS_2ND (251) clash and that's possibly
why executePlayerInput currently works incorrectly
with Operation Stealth. More reverse engineering
is needed...
........
r41916 | athrxx | 2009-06-27 22:36:12 +1000 (Sat, 27 Jun 2009) | 1 line
LOL: cleanup
........
r41917 | athrxx | 2009-06-27 23:15:47 +1000 (Sat, 27 Jun 2009) | 1 line
LOL: fixed regression
........
r41922 | athrxx | 2009-06-28 02:48:47 +1000 (Sun, 28 Jun 2009) | 1 line
LOL: add workaround to fix map text display when the language is set to French
........
r41929 | joostp | 2009-06-29 03:51:53 +1000 (Mon, 29 Jun 2009) | 2 lines
change link order in .spec file to produce working binaries when building using the configure script
........
r41930 | fingolfin | 2009-06-29 05:56:58 +1000 (Mon, 29 Jun 2009) | 1 line
Silenced the reamining warnings reported in patch #2684986 (gcc warnings with -DFORTIFY_SOURCE=2 -fstack-protector)
........
r41931 | fingolfin | 2009-06-29 05:57:27 +1000 (Mon, 29 Jun 2009) | 1 line
GUI: Replaced ThemeParser::_drawFunction hashmap by a static function getDrawingFunctionCallback which maps strings to draw funcs
........
r41932 | fingolfin | 2009-06-29 05:58:11 +1000 (Mon, 29 Jun 2009) | 4 lines
Changed OSystem::setWindowCaption to expect ISO LATIN 1 encoded input;
also intentionally broke WinCE and Symbian ports (in an obvious way that
can be undo by commenting out some text) -- hopefully this will get the
maintainers' attention during the next release cycle, unlike my emails
........
r41933 | fingolfin | 2009-06-29 05:58:30 +1000 (Mon, 29 Jun 2009) | 1 line
PS2: Don't overload fillScreen with a dummy, just use the inherited version
........
r41934 | fingolfin | 2009-06-29 07:04:24 +1000 (Mon, 29 Jun 2009) | 1 line
Fix PSP port
........
r41938 | eriktorbjorn | 2009-06-29 08:20:28 +1000 (Mon, 29 Jun 2009) | 2 lines
For consistency, use upper-case letter in hex constant.
........
r41940 | lordhoto | 2009-06-29 22:33:47 +1000 (Mon, 29 Jun 2009) | 1 line
Indentation fix.
........
r41941 | lordhoto | 2009-06-30 02:05:50 +1000 (Tue, 30 Jun 2009) | 1 line
Modified Palette::load*Palette definition.
........
r41942 | lordhoto | 2009-06-30 02:06:02 +1000 (Tue, 30 Jun 2009) | 1 line
Change LoLEngine::processMagicIce to use Palette objects internally.
........
r41943 | lordhoto | 2009-06-30 02:06:18 +1000 (Tue, 30 Jun 2009) | 1 line
Changed LoLEngine::setPaletteBrightness to take an Palette object.
........
r41944 | lordhoto | 2009-06-30 02:06:31 +1000 (Tue, 30 Jun 2009) | 1 line
Change LoLEngine::generateBrightnessPalette to take Palette objects as parameters.
........
r41945 | lordhoto | 2009-06-30 02:07:46 +1000 (Tue, 30 Jun 2009) | 1 line
Chang Palette parameter of LolEngine::setPaletteBrightness to be const.
........
r41946 | lordhoto | 2009-06-30 02:08:00 +1000 (Tue, 30 Jun 2009) | 1 line
Change raw palette read to Screen::loadPalette call.
........
r41947 | lordhoto | 2009-06-30 02:08:16 +1000 (Tue, 30 Jun 2009) | 1 line
Change Screen_LoL::loadSpecialColors to take an Palette object as parameter.
........
r41948 | lordhoto | 2009-06-30 02:08:28 +1000 (Tue, 30 Jun 2009) | 1 line
Change LoLEngine::generateFlashPalette to take Palette objects as parameters.
........
r41949 | lordhoto | 2009-06-30 02:08:39 +1000 (Tue, 30 Jun 2009) | 1 line
Cleanup KyraEngine_MR::updateCharPal.
........
r41950 | lordhoto | 2009-06-30 02:49:14 +1000 (Tue, 30 Jun 2009) | 1 line
Cleanup GUI_HoF::setupPalette.
........
r41951 | lordhoto | 2009-06-30 02:49:26 +1000 (Tue, 30 Jun 2009) | 1 line
Replaced some raw palette loads.
........
r41952 | lordhoto | 2009-06-30 02:49:38 +1000 (Tue, 30 Jun 2009) | 1 line
Add a "fill" method to Palette.
........
r41953 | lordhoto | 2009-06-30 02:49:53 +1000 (Tue, 30 Jun 2009) | 1 line
Adapted various code parts to use Palette::fill.
........
r41954 | lordhoto | 2009-06-30 03:05:49 +1000 (Tue, 30 Jun 2009) | 1 line
Removed some obsolete TODOs.
........
r41955 | lordhoto | 2009-06-30 03:06:00 +1000 (Tue, 30 Jun 2009) | 1 line
Update the screen animations while dropping items in Hand of Fate.
........
r41956 | lordhoto | 2009-06-30 03:06:17 +1000 (Tue, 30 Jun 2009) | 1 line
Removed more obsolete TODO messages.
........
r41957 | lordhoto | 2009-06-30 03:26:43 +1000 (Tue, 30 Jun 2009) | 1 line
Resolved some TODOs in Kyra3 code.
........
r41958 | lordhoto | 2009-06-30 03:26:56 +1000 (Tue, 30 Jun 2009) | 1 line
Removed obsolete TODOs in HoF code.
........
r41959 | lordhoto | 2009-06-30 04:00:18 +1000 (Tue, 30 Jun 2009) | 3 lines
- Get rid of code duplication for mouse cursor setup
- Fix mouse cursor colors in LoL PC98
(This commit might introduce regressions, since it changes the key color the mouse cursor uses)
........
r41960 | lordhoto | 2009-06-30 04:49:17 +1000 (Tue, 30 Jun 2009) | 1 line
Fix kyra2/kyra3 mouse cursor related regressions, introduced with r41959.
........
r41961 | lordhoto | 2009-06-30 04:49:28 +1000 (Tue, 30 Jun 2009) | 1 line
Fix palette regression caused by r41949.
........
r41962 | lordhoto | 2009-06-30 05:02:15 +1000 (Tue, 30 Jun 2009) | 1 line
Fix bug in drawShape, which caused invisibility in Kyra1 to be displayed incorrectly.
........
r41963 | lordhoto | 2009-06-30 06:16:59 +1000 (Tue, 30 Jun 2009) | 1 line
Fix LoL cursor in DOS version.
........
r41964 | lordhoto | 2009-06-30 06:17:10 +1000 (Tue, 30 Jun 2009) | 1 line
Fix bug in drawShape.
........
r41967 | lordhoto | 2009-06-30 09:14:35 +1000 (Tue, 30 Jun 2009) | 1 line
Fix invisible mouse cursor, when picking up items.
........
r41968 | lordhoto | 2009-06-30 09:23:29 +1000 (Tue, 30 Jun 2009) | 1 line
Add some more explanation to Graphics::CursorManager::showMouse and OSystem::showMouse.
........
r41975 | dreammaster | 2009-06-30 20:36:50 +1000 (Tue, 30 Jun 2009) | 1 line
Made the music/sfx volume settings actually affect the in-game music/sfx volume
........
r42007 | anotherguest | 2009-07-02 06:02:33 +1000 (Thu, 02 Jul 2009) | 1 line
Move action inits to engineInit and engineDone callbacks.
........
r42008 | anotherguest | 2009-07-02 06:11:44 +1000 (Thu, 02 Jul 2009) | 1 line
Use MIN with correct template parameter.
........
r42009 | fingolfin | 2009-07-02 06:51:04 +1000 (Thu, 02 Jul 2009) | 4 lines
- Added GCC_PRINTF attribute to several funcs where it makes sense
- change some constants from double to float, to avoid "loss of precision due to implicit conversion" warnings
- removed duplicate prototypes for some funcs
- fixed some "increases required alignment of target type" warnings
........
r42010 | fingolfin | 2009-07-02 06:51:34 +1000 (Thu, 02 Jul 2009) | 1 line
Fixed some more warnings observed on buildbot
........
r42011 | fingolfin | 2009-07-02 06:51:47 +1000 (Thu, 02 Jul 2009) | 1 line
Flag what looks like a bug in the CMS player code -- somebody should verify and fix this properly
........
r42012 | fingolfin | 2009-07-02 06:53:47 +1000 (Thu, 02 Jul 2009) | 1 line
oops
........
r42020 | drmccoy | 2009-07-02 22:15:04 +1000 (Thu, 02 Jul 2009) | 1 line
Added support for compressed sample files (patch #2815426 by m_kiewitz)
........
r42038 | fingolfin | 2009-07-03 07:16:36 +1000 (Fri, 03 Jul 2009) | 1 line
Enhanced the quicksearch box in the launcher to match words in the search string individually
........
r42039 | fingolfin | 2009-07-03 07:37:13 +1000 (Fri, 03 Jul 2009) | 1 line
fixed indention (and trigger a reconfigure in buildbot)
........
r42040 | fingolfin | 2009-07-03 08:05:42 +1000 (Fri, 03 Jul 2009) | 1 line
cleanup
........
r42041 | fingolfin | 2009-07-03 08:21:33 +1000 (Fri, 03 Jul 2009) | 1 line
Added -Wmissing-format-attribute to build system
........
r42043 | thebluegr | 2009-07-03 09:16:40 +1000 (Fri, 03 Jul 2009) | 1 line
Moved all the debug state variables in a separate struct and re-enabled several places where they're used
........
r42044 | thebluegr | 2009-07-03 09:58:05 +1000 (Fri, 03 Jul 2009) | 1 line
Moved some more debug state related variables in the DebugState struct
........
r42047 | dreammaster | 2009-07-03 16:19:20 +1000 (Fri, 03 Jul 2009) | 1 line
Bugfix for loading savegames where the active resource file database isn't completely filled
........
r42048 | dreammaster | 2009-07-03 16:21:04 +1000 (Fri, 03 Jul 2009) | 1 line
Bugfix for displaying text messages when an auto tracking (cut-scene) changes to a user wait
........
r42049 | thebluegr | 2009-07-03 17:06:48 +1000 (Fri, 03 Jul 2009) | 1 line
Applied patch #2815937 - "SCI: ReadString fix to repair LSL5 password". This fixes the problems with the LSL5 password for good
........
r42050 | thebluegr | 2009-07-03 19:01:51 +1000 (Fri, 03 Jul 2009) | 1 line
Simplified the kernel name loading code: Merged the default SCI0 and SCI1 kernel name tables in one table. vocab.999 is only used in SCI0 and SCI01 games if it exists as an override to the default kernel name table (which works with SCI0/SCI01 demos with no vocab.999, like KQ1 and xmas1998). Removed GF_SCI0_SCI1VOCAB.
........
r42054 | fingolfin | 2009-07-03 20:40:49 +1000 (Fri, 03 Jul 2009) | 1 line
Added more GCC_PRINTF attributes, and fixed resulting warnings in format strings
........
r42055 | fingolfin | 2009-07-03 20:41:03 +1000 (Fri, 03 Jul 2009) | 1 line
SCI: Fixed warning
........
r42056 | fingolfin | 2009-07-03 21:05:59 +1000 (Fri, 03 Jul 2009) | 1 line
If NDEBUG is #defined, then assert does nothing, leading to warnings about 'old_size' not being used -> fix that
........
r42060 | thebluegr | 2009-07-04 00:18:20 +1000 (Sat, 04 Jul 2009) | 1 line
Replaced all calls for manipulating the mouse cursor to be made to the CursorManager instead of directly to the graphics backend
........
r42062 | thebluegr | 2009-07-04 00:22:50 +1000 (Sat, 04 Jul 2009) | 2 lines
- Pushed debugstate into debug.h
- When an error occurs, manipulate the execution stack before error() opens the console inside getDebugger(), like FreeSCI did. Added another method for obtaining the SCI console for use by the engine itself.
........
r42079 | thebluegr | 2009-07-04 07:59:07 +1000 (Sat, 04 Jul 2009) | 1 line
Replaced script_error and CORE_ERROR with error()
........
r42081 | thebluegr | 2009-07-04 09:37:08 +1000 (Sat, 04 Jul 2009) | 1 line
SCI0 games using older graphics functions are automatically detected now, from the presence of the "TimesSin" and "SinMult" kernel functions. Removed the GF_SCI0_OLDGFXFUNCS game flag
........
svn-id: r42085
Diffstat (limited to 'engines/gob')
90 files changed, 7980 insertions, 11351 deletions
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index a37586aee6..f59fa80e8d 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -239,7 +239,7 @@ int16 DataIO::getChunk(const char *chunkName) { } dataDesc = _dataFiles[file]; - for (int16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { + for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) continue; @@ -334,7 +334,6 @@ uint32 DataIO::getChunkPos(int16 handle) const { int32 DataIO::getChunkSize(const char *chunkName) { int16 file; - int16 chunk; struct ChunkDesc *dataDesc; int16 slot; int32 realSize; @@ -344,7 +343,7 @@ int32 DataIO::getChunkSize(const char *chunkName) { return -1; dataDesc = _dataFiles[file]; - for (chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { + for (uint16 chunk = 0; chunk < _numDataChunks[file]; chunk++, dataDesc++) { if (scumm_stricmp(chunkName, dataDesc->chunkName) != 0) continue; @@ -488,6 +487,16 @@ int16 DataIO::openData(const char *path) { return file_open(path); } +bool DataIO::existData(const char *path) { + int16 handle = openData(path); + + if (handle < 0) + return false; + + closeData(handle); + return true; +} + DataStream *DataIO::openAsStream(int16 handle, bool dispose) { uint32 curPos = getPos(handle); seekData(handle, 0, SEEK_END); @@ -575,6 +584,9 @@ byte *DataIO::getData(const char *path) { } DataStream *DataIO::getDataStream(const char *path) { + if (!path || (path[0] == '\0') || !existData(path)) + return 0; + uint32 size = getDataSize(path); byte *data = getData(path); diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h index c67dc89df8..1f55cac90d 100644 --- a/engines/gob/dataio.h +++ b/engines/gob/dataio.h @@ -80,6 +80,7 @@ public: byte *getUnpackedData(const char *name); void closeData(int16 handle); int16 openData(const char *path); + bool existData(const char *path); DataStream *openAsStream(int16 handle, bool dispose = false); int32 getDataSize(const char *name); @@ -92,7 +93,7 @@ public: protected: Common::File _filesHandles[MAX_FILES]; struct ChunkDesc *_dataFiles[MAX_DATA_FILES]; - int16 _numDataChunks[MAX_DATA_FILES]; + uint16 _numDataChunks[MAX_DATA_FILES]; int16 _dataFileHandles[MAX_DATA_FILES]; bool _dataFileItk[MAX_DATA_FILES]; int32 _chunkPos[MAX_SLOT_COUNT * MAX_DATA_FILES]; diff --git a/engines/gob/demos/demoplayer.cpp b/engines/gob/demos/demoplayer.cpp index eb7ca1ccb1..0229bb7515 100644 --- a/engines/gob/demos/demoplayer.cpp +++ b/engines/gob/demos/demoplayer.cpp @@ -50,11 +50,13 @@ DemoPlayer::Script DemoPlayer::_scripts[] = { "slide tumid.imd 1\nslide post.imd 1\nslide posta.imd 1\n" \ "slide postb.imd 1\nslide postc.imd 1\nslide xdome.imd 20\n" \ "slide xant.imd 20\nslide tum.imd 20\nslide voile.imd 20\n" \ - "slide int.imd 20\nslide voila.imd 1\nslide voilb.imd 1\n"} + "slide int.imd 20\nslide voila.imd 1\nslide voilb.imd 1\n"}, + {kScriptSourceFile, "coktelplayer.scn"}, }; DemoPlayer::DemoPlayer(GobEngine *vm) : _vm(vm) { _doubleMode = false; + _rebase0 = false; } DemoPlayer::~DemoPlayer() { @@ -121,7 +123,9 @@ void DemoPlayer::init() { void DemoPlayer::clearScreen() { debugC(1, kDebugDemo, "Clearing the screen"); - _vm->_video->clearScreen(); + _vm->_video->clearSurf(*_vm->_draw->_backSurface); + _vm->_draw->forceBlit(); + _vm->_video->retrace(); } void DemoPlayer::playVideo(const char *fileName) { @@ -148,10 +152,21 @@ void DemoPlayer::playVideo(const char *fileName) { debugC(1, kDebugDemo, "Playing video \"%s\"", file); - if (_vm->_vidPlayer->primaryOpen(file)) { + int16 x = _rebase0 ? 0 : -1; + int16 y = _rebase0 ? 0 : -1; + if (_vm->_vidPlayer->primaryOpen(file, x, y)) { bool videoSupportsDouble = ((_vm->_vidPlayer->getFeatures() & Graphics::CoktelVideo::kFeaturesSupportsDouble) != 0); + if (_autoDouble) { + int16 defX = _rebase0 ? 0 : _vm->_vidPlayer->getDefaultX(); + int16 defY = _rebase0 ? 0 : _vm->_vidPlayer->getDefaultY(); + int16 right = defX + _vm->_vidPlayer->getWidth() - 1; + int16 bottom = defY + _vm->_vidPlayer->getHeight() - 1; + + _doubleMode = ((right < 320) && (bottom < 200)); + } + if (_doubleMode) { if (videoSupportsDouble) { _vm->_vidPlayer->slotSetDoubleMode(-1, true); @@ -176,13 +191,16 @@ void DemoPlayer::playVideoNormal() { } void DemoPlayer::playVideoDoubled() { - const char *fileNameOpened = _vm->_vidPlayer->getFileName(); + Common::String fileNameOpened = _vm->_vidPlayer->getFileName(); _vm->_vidPlayer->primaryClose(); - if (_vm->_vidPlayer->primaryOpen(fileNameOpened, 0, -1, VideoPlayer::kFlagOtherSurface)) { + int16 x = _rebase0 ? 0 : -1; + int16 y = _rebase0 ? 0 : -1; + if (_vm->_vidPlayer->primaryOpen(fileNameOpened.c_str(), x, y, + VideoPlayer::kFlagScreenSurface)) { + for (int i = 0; i < _vm->_vidPlayer->getFramesCount(); i++) { - if (_vm->_vidPlayer->primaryPlay(i, i)) - break; + _vm->_vidPlayer->playFrame(i); Graphics::CoktelVideo::State state = _vm->_vidPlayer->getState(); @@ -191,11 +209,26 @@ void DemoPlayer::playVideoDoubled() { int16 wD = (state.left * 2) + (w * 2); int16 hD = (state.top * 2) + (h * 2); - _vm->_video->drawSpriteDouble(_vm->_draw->_spritesArray[0], _vm->_draw->_frontSurface, + _vm->_video->drawSpriteDouble(*_vm->_draw->_spritesArray[0], *_vm->_draw->_frontSurface, state.left, state.top, state.right, state.bottom, state.left, state.top, 0); _vm->_draw->dirtiedRect(_vm->_draw->_frontSurface, state.left * 2, state.top * 2, wD, hD); _vm->_video->retrace(); + + _vm->_util->processInput(); + if (_vm->shouldQuit()) + break; + + int16 key; + bool end = false; + while (_vm->_util->checkKey(key)) + if (key == 0x011B) + end = true; + if (end) + break; + + _vm->_vidPlayer->slotWaitEndFrame(); + } } } @@ -203,10 +236,16 @@ void DemoPlayer::playVideoDoubled() { void DemoPlayer::evaluateVideoMode(const char *mode) { debugC(2, kDebugDemo, "Video mode \"%s\"", mode); - if (!scumm_strnicmp(mode, "VESA", 4)) - _doubleMode = false; - else if (!scumm_strnicmp(mode, "VGA", 3) && _vm->is640()) - _doubleMode = true; + _autoDouble = false; + _doubleMode = false; + + // Only applicable when we actually can double + if (_vm->is640()) { + if (!scumm_strnicmp(mode, "AUTO", 4)) + _autoDouble = true; + else if (!scumm_strnicmp(mode, "VGA", 3) && _vm->is640()) + _doubleMode = true; + } } } // End of namespace Gob diff --git a/engines/gob/demos/demoplayer.h b/engines/gob/demos/demoplayer.h index 52c089c8f1..64c98b58c5 100644 --- a/engines/gob/demos/demoplayer.h +++ b/engines/gob/demos/demoplayer.h @@ -45,6 +45,8 @@ public: protected: GobEngine *_vm; bool _doubleMode; + bool _autoDouble; + bool _rebase0; virtual bool playStream(Common::SeekableReadStream &stream) = 0; diff --git a/engines/gob/demos/scnplayer.cpp b/engines/gob/demos/scnplayer.cpp index dc86652bd2..616da3272a 100644 --- a/engines/gob/demos/scnplayer.cpp +++ b/engines/gob/demos/scnplayer.cpp @@ -62,6 +62,10 @@ bool SCNPlayer::playStream(Common::SeekableReadStream &scn) { playVideo(line.c_str() + 4); } else if (lineStartsWith(line, "GOTO ")) { gotoLabel(scn, labels, line.c_str() + 5); + } else if (lineStartsWith(line, "REBASE0:ON")) { + _rebase0 = true; + } else if (lineStartsWith(line, "REBASE0:OFF")) { + _rebase0 = false; } // Mind user input diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 15e0f6ef6b..9426c01ef2 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -61,13 +61,14 @@ static const PlainGameDescriptor gobGames[] = { {"woodruff", "The Bizarre Adventures of Woodruff and the Schnibble"}, {"dynasty", "The Last Dynasty"}, {"urban", "Urban Runner"}, - {"archi", "Playtoon 1 - Uncle Archibald"}, - {"spirou", "Playtoon 2 - The Case of the Counterfeit Collaborator"}, - {"chato", "Playtoon 3 - The Secret of the Castle"}, - {"manda", "Playtoon 4 - The Mandarine Prince"}, - {"wakan", "Playtoon 5 - The Stone of Wakan"}, - {"playtnck2", "Playtoon Construction Kit 2 - Les chevaliers"}, - {"bambou", "Playtoon Limited Edition - Bambou le sauveur de la jungle"}, + {"playtoons1", "Playtoons 1 - Uncle Archibald"}, + {"playtoons2", "Playtoons 2 - The Case of the Counterfeit Collaborator"}, + {"playtoons3", "Playtoons 3 - The Secret of the Castle"}, + {"playtoons4", "Playtoons 4 - The Mandarine Prince"}, + {"playtoons5", "Playtoons 5 - The Stone of Wakan"}, + {"playtnck1", "Playtoons Construction Kit 1 - Monsters"}, + {"playtnck2", "Playtoons Construction Kit 2 - Knights"}, + {"bambou", "Playtoons Limited Edition - Bambou le sauveur de la jungle"}, {"fascination", "Fascination"}, {"geisha", "Geisha"}, {"adibou4", "Adibou v4"}, @@ -83,6 +84,10 @@ static const ADObsoleteGameID obsoleteGameIDsTable[] = { namespace Gob { +using Common::GUIO_NOSPEECH; +using Common::GUIO_NOSUBTITLES; +using Common::GUIO_NONE; + static const GOBGameDescription gameDescriptions[] = { { // Supplied by Florian Zeitz on scummvm-devel { @@ -91,7 +96,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "c65e9cc8ba23a38456242e1f2b1caad4"), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesEGA, @@ -104,7 +110,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "f9233283a0be2464248d83e14b95f09c"), RU_RUS, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesEGA, @@ -117,7 +124,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "26a9118c0770fa5ac93a9626761600b2"), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesNone, @@ -130,7 +138,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "e157cb59c6d330ca70d12ab0ef1dd12b", 288972), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, @@ -143,7 +152,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -156,7 +166,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -169,7 +180,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -182,7 +194,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -195,7 +208,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "2fbf4b5b82bbaee87eb45d4404c28998"), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -208,7 +222,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -221,7 +236,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -234,7 +250,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -247,7 +264,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -260,7 +278,64 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "8bd873137b6831c896ee8ad217a6a398"), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + HU_HUN, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob1cd", + "v1.02", + AD_ENTRY1s("intro.stk", "40d4a53818f4fce3f5997d02c3fafe73", 4049248), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -273,7 +348,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "972f22c6ff8144a6636423f0354ca549"), UNK_LANG, kPlatformAmiga, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesNone, @@ -286,7 +362,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "e72bd1e3828c7dec4c8a3e58c48bdfdb"), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesNone, @@ -299,7 +376,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "a796096280d5efd48cf8e7dfbe426eb5", 193595), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesNone, @@ -312,7 +390,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "35a098571af9a03c04e2303aec7c9249", 116582), FR_FRA, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesNone, @@ -325,7 +404,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6d837c6380d8f4d984c9f6cc0026df4f", 192712), EN_ANY, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesNone, @@ -338,7 +418,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), EN_ANY, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, @@ -351,7 +432,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), DE_DEU, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, @@ -364,7 +446,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), FR_FRA, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, @@ -377,7 +460,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), IT_ITA, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, @@ -390,13 +474,14 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "00a42a7d2d22e6b6ab1b8c673c4ed267"), ES_ESP, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, 0, 0, 0 }, - { + { // Supplied by Hkz on #scummvm { "gob1", "", @@ -407,7 +492,152 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { // Supplied by Hkz on #scummvm + { + "gob1", + "", + { + {"intro.stk", 0, "f5f028ee39c456fa51fa63b606583918", 313472}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob1, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob1", + "", + { + {"intro.stk", 0, "e157cb59c6d330ca70d12ab0ef1dd12b", 288972}, + {"musmac1.mid", 0, "4f66903b33df8a20edd4c748809c0b56", 8161}, + {0, 0, 0, 0} + }, + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, @@ -424,7 +654,8 @@ static const GOBGameDescription gameDescriptions[] = { }, DE_DEU, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesAdlib, @@ -437,7 +668,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "eebf2810122cfd17399260cd1468e994", 554014), EN_ANY, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesNone, @@ -450,7 +682,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "d28b9e9b41f31acfa58dcd12406c7b2c"), DE_DEU, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesNone, @@ -463,7 +696,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "686c88f7302a80b744aae9f8413e853d"), IT_ITA, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesNone, @@ -476,7 +710,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "4b13c02d1069b86bcfec80f4e474b98b", 554680), FR_FRA, kPlatformAtariST, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesNone, @@ -493,7 +728,8 @@ static const GOBGameDescription gameDescriptions[] = { }, UNK_LANG, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -510,7 +746,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -523,7 +760,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "b45b984ee8017efd6ea965b9becd4d66"), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -536,7 +774,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "dedb5d31d8c8050a8cf77abedcc53dae"), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -549,7 +788,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "25a99827cd59751a80bed9620fb677a0", 893302), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -562,7 +802,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "a13ecb4f6d8fd881ebbcc02e45cb5475", 837275), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -575,7 +816,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "3e4e7db0d201587dd2df4003b2993ef6"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -588,7 +830,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "a13892cdf4badda85a6f6fb47603a128"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -601,7 +844,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "c47faf1d406504e6ffe63243610bb1f4"), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -614,7 +858,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "cd3e1df8b273636ee32e34b7064f50e8"), RU_RUS, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -627,7 +872,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "5f53c56e3aa2f1e76c2e4f0caa15887f", 829232), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -640,7 +886,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "9de5fbb41cf97182109e5fecc9d90347"), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesCD, @@ -653,7 +900,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesCD, @@ -666,7 +914,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesCD, @@ -679,7 +928,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesCD, @@ -692,7 +942,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesCD, @@ -705,7 +956,78 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "24a6b32757752ccb1917ce92fd7c2a04"), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + HU_HUN, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob2cd", + "v1.02", + AD_ENTRY1s("intro.stk", "5ba85a4769a1ab03a283dd694588d526", 5006236), + IT_ITA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesCD, @@ -718,7 +1040,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "8b1c98ff2ab2e14f47a1b891e9b92217"), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -731,7 +1054,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "cf1c95b2939bd8ff58a25c756cb6125e"), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -744,7 +1068,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "4b278c2678ea01383fd5ca114d947eea"), UNK_LANG, kPlatformAmiga, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesNone, @@ -757,7 +1082,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "9fa85aea959fa8c582085855fbd99346", 553063), UNK_LANG, kPlatformAmiga, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesNone, @@ -774,7 +1100,44 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob2", + "", + { + {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + EN_USA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob2, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob2", + "", + { + {"intro.stk", 0, "25a99827cd59751a80bed9620fb677a0", 893302}, + {"musmac1.mid", 0, "834e55205b710d0af5f14a6f2320dd8e", 8661}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -791,7 +1154,8 @@ static const GOBGameDescription gameDescriptions[] = { }, DE_DEU, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -808,7 +1172,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_GRB, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesNone, @@ -821,7 +1186,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "257fe669705ac4971efdfd5656eef16a", 457719), FR_FRA, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesNone, @@ -834,7 +1200,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "dffd1ab98fe76150d6933329ca6f4cc4", 459458), FR_FRA, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesNone, @@ -847,7 +1214,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "af83debf2cbea21faa591c7b4608fe92", 458192), DE_DEU, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesNone, @@ -864,7 +1232,8 @@ static const GOBGameDescription gameDescriptions[] = { }, IT_ITA, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesNone, @@ -881,7 +1250,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_GRB, kPlatformAtariST, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesNone, @@ -894,7 +1264,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "e6d13fb3b858cb4f78a8780d184d5b2c"), FR_FRA, kPlatformAtariST, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesNone, @@ -907,7 +1278,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "2bb8878a8042244dd2b96ff682381baa"), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -920,7 +1292,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "de92e5c6a8c163007ffceebef6e67f7d", 7117568), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -933,7 +1306,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6d60f9205ecfbd8735da2ee7823a70dc", 7014426), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -946,7 +1320,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "4b10525a3782aa7ecd9d833b5c1d308b"), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -959,7 +1334,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "63170e71f04faba88673b3f510f9c4c8"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -972,7 +1348,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "8b57cd510da8a3bbd99e3a0297a8ebd1", 7018771), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -985,7 +1362,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "2e9c2898f6bf206ede801e3b2e7ee428"), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -998,7 +1376,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "15fb91a1b9b09684b28ac75edf66e504"), EN_USA, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWeen, kFeaturesAdlib, @@ -1011,7 +1390,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "da3c54be18ab73fbdb32db24624a9c23"), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -1024,7 +1404,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "2f54b330d21f65b04b7c1f8cca76426c", 262109), FR_FRA, kPlatformAtariST, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -1037,7 +1418,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "11103b304286c23945560b391fd37e7d", 3181890), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -1050,7 +1432,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "da3c54be18ab73fbdb32db24624a9c23", 3181825), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -1063,7 +1446,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "569d679fe41d49972d34c9fce5930dda", 269825), EN_ANY, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -1076,7 +1460,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "00f6b4e2ee26e5c40b488e2df5adcf03", 3975580), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -1089,7 +1474,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "da3c54be18ab73fbdb32db24624a9c23", 3181825), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -1102,7 +1488,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib | kFeaturesEGA, @@ -1115,7 +1502,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib | kFeaturesEGA, @@ -1128,7 +1516,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib | kFeaturesEGA, @@ -1141,7 +1530,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib | kFeaturesEGA, @@ -1154,7 +1544,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "0b72992f5d8b5e6e0330572a5753ea25", 256490), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib | kFeaturesEGA, @@ -1171,7 +1562,8 @@ static const GOBGameDescription gameDescriptions[] = { }, UNK_LANG, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesNone, @@ -1184,7 +1576,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "e453bea7b28a67c930764d945f64d898", 3913628), EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -1197,7 +1590,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "7b7f48490dedc8a7cb999388e2fadbe3", 3930674), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1210,7 +1604,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "e0767783ff662ed93665446665693aef", 4371238), HB_ISR, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1223,7 +1618,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "3712e7527ba8ce5637d2aadf62783005", 72318), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1236,7 +1632,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "f1f78b663893b58887add182a77df151", 3944090), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1249,7 +1646,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "cd322cb3c64ef2ba2f2134aa2122cfe9", 3936700), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1266,7 +1664,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1279,7 +1678,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1292,7 +1692,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1305,7 +1706,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1318,7 +1720,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1331,7 +1734,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1344,7 +1748,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6263d09e996c1b4e84ef2d650b820e57", 4831170), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1357,7 +1762,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1370,7 +1776,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1383,7 +1790,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1396,7 +1804,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1409,7 +1818,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1422,7 +1832,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "795be7011ec31bf5bb8ce4efdb9ee5d3", 4838904), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -1433,9 +1844,38 @@ static const GOBGameDescription gameDescriptions[] = { "lostintime", "", AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), - UNK_LANG, + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeLostInTime, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "lostintime", + "", + AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), + FR_FRA, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeLostInTime, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "lostintime", + "", + AD_ENTRY1s("intro.stk", "0ddf39cea1ec30ecc8bfe444ebd7b845", 4207330), + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1449,6 +1889,7 @@ static const GOBGameDescription gameDescriptions[] = { EN_ANY, kPlatformPC, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES }, kGameTypeFascination, kFeaturesCD, @@ -1462,6 +1903,7 @@ static const GOBGameDescription gameDescriptions[] = { UNK_LANG, kPlatformPC, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesAdlib, @@ -1475,13 +1917,13 @@ static const GOBGameDescription gameDescriptions[] = { HB_ISR, kPlatformPC, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesAdlib, "intro.stk", 0, 0 }, - //Provided by Sanguine - { + { // Supplied by sanguine { "fascination", "VGA 3 disks edition", @@ -1489,6 +1931,21 @@ static const GOBGameDescription gameDescriptions[] = { UNK_LANG, kPlatformPC, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeFascination, + kFeaturesAdlib, + "disk0.stk", 0, 0 + }, + { // Supplied by windlepoons in bug report #2809247 + { + "fascination", + "VGA 3 disks edition", + AD_ENTRY1s("disk0.stk", "3a24e60a035250189643c86a9ceafb97", 1062480), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesAdlib, @@ -1502,6 +1959,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformPC, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesAdlib, @@ -1515,6 +1973,7 @@ static const GOBGameDescription gameDescriptions[] = { DE_DEU, kPlatformAmiga, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesNone, @@ -1528,6 +1987,7 @@ static const GOBGameDescription gameDescriptions[] = { EN_ANY, kPlatformAmiga, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesNone, @@ -1541,6 +2001,7 @@ static const GOBGameDescription gameDescriptions[] = { FR_FRA, kPlatformAmiga, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesNone, @@ -1554,6 +2015,7 @@ static const GOBGameDescription gameDescriptions[] = { IT_ITA, kPlatformAmiga, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesNone, @@ -1567,6 +2029,7 @@ static const GOBGameDescription gameDescriptions[] = { UNK_LANG, kPlatformPC, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGeisha, kFeaturesNone, @@ -1580,6 +2043,7 @@ static const GOBGameDescription gameDescriptions[] = { UNK_LANG, kPlatformPC, ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGeisha, kFeaturesNone, @@ -1592,7 +2056,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("demo.stk", "c06f8cc20eb239d4c71f225ce3093edf"), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1605,7 +2070,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("demo.stk", "2eba8abd9e3878c57307576012dd2fec"), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -1618,7 +2084,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "32b0f57f5ae79a9ae97e8011df38af42", 157084), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1631,7 +2098,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "904fc32032295baa3efb3a41f17db611", 178582), HB_ISR, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1644,7 +2112,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "16b014bf32dbd6ab4c5163c44f56fed1", 445104), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1661,7 +2130,44 @@ static const GOBGameDescription gameDescriptions[] = { }, DE_DEU, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob3, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob3", + "", + { + {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob3, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "gob3", + "", + { + {"intro.stk", 0, "16b014bf32dbd6ab4c5163c44f56fed1", 445104}, + {"musmac1.mid", 0, "948c546cad3a9de5bff3fe4107c82bf1", 6404}, + {0, 0, 0, 0} + }, + EN_GRB, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1678,7 +2184,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_GRB, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1691,7 +2198,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "1e2f64ec8dfa89f42ee49936a27e66e7"), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1704,7 +2212,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "f6d225b25a180606fa5dbe6405c97380"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1717,7 +2226,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "e42a4f2337d6549487a80864d7826972"), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1730,7 +2240,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "fe8144daece35538085adb59c2d29613", 159402), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1743,7 +2254,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "4e3af248a48a2321364736afab868527"), RU_RUS, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1756,7 +2268,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "8d28ce1591b0e9cc79bf41cad0fc4c9c"), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1769,7 +2282,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "d3b72938fbbc8159198088811f9e6d19", 160382), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1782,7 +2296,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), EN_GRB, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesNone, @@ -1795,7 +2310,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "bd679eafde2084d8011f247e51b5a805"), DE_DEU, kPlatformAmiga, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesNone, @@ -1808,7 +2324,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "6f2c226c62dd7ab0ab6f850e89d3fc47"), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesCD, @@ -1821,7 +2338,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesCD, @@ -1834,7 +2352,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesCD, @@ -1847,7 +2366,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesCD, @@ -1860,7 +2380,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesCD, @@ -1873,7 +2394,64 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + HU_HUN, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeGob3, + kFeaturesCD, + 0, 0, 0 + }, + { // Supplied by goodoldgeorg in bug report #2810082 + { + "gob3cd", + "v1.02", + AD_ENTRY1s("intro.stk", "bfd7d4c6fedeb2cfcc8baa4d5ddb1f74", 616220), + ES_ESP, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesCD, @@ -1886,7 +2464,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "7aebd94e49c2c5c518c9e7b74f25de9d"), FR_FRA, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1899,7 +2478,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "e5dcbc9f6658ebb1e8fe26bc4da0806d"), FR_FRA, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1912,7 +2492,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1("intro.stk", "b9b898fccebe02b69c086052d5024a55"), UNK_LANG, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1925,7 +2506,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "9e20ad7b471b01f84db526da34eaf0a2", 395561), EN_ANY, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1942,7 +2524,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -1955,7 +2538,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesCD, @@ -1968,7 +2552,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesCD, @@ -1981,7 +2566,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesCD, @@ -1994,7 +2580,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesCD, @@ -2007,7 +2594,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "47c3b452767c4f49ea7b109143e77c30", 916828), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesCD, @@ -2020,7 +2608,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesAdlib, @@ -2033,7 +2622,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesAdlib, @@ -2046,7 +2636,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "1fa92b00fe80a20f34ec34a8e2fa869e", 923072), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesAdlib, @@ -2059,7 +2650,64 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), EN_USA, kPlatformWindows, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeInca2, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + DE_DEU, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeInca2, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + IT_ITA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeInca2, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + ES_ESP, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeInca2, + kFeaturesAdlib, + 0, 0, 0 + }, + { + { + "inca2", + "", + AD_ENTRY1s("intro.stk", "d33011df8758ac64ca3dca77c7719001", 908612), + FR_FRA, + kPlatformWindows, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesAdlib, @@ -2085,7 +2733,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeInca2, kFeaturesAdlib | kFeaturesBATDemo, @@ -2098,7 +2747,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2111,7 +2761,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2124,7 +2775,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2137,7 +2789,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2150,7 +2803,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "dccf9d31cb720b34d75487408821b77e", 20296390), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2163,7 +2817,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2176,7 +2831,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2189,7 +2845,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2202,7 +2859,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2215,7 +2873,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "b50fee012a5abcd0ac2963e1b4b56bec", 20298108), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2228,7 +2887,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "5f5f4e0a72c33391e67a47674b120cc6", 20296422), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2241,7 +2901,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2254,7 +2915,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2267,7 +2929,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2280,7 +2943,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2293,7 +2957,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "270529d9b8cce770b1575908a3800b52", 20296452), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2306,7 +2971,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2319,7 +2985,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2332,7 +2999,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "f4c344023b073782d2fddd9d8b515318", 7069736), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2345,7 +3013,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), EN_GRB, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2358,7 +3027,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2371,7 +3041,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2384,7 +3055,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2397,7 +3069,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "60348a87651f92e8492ee070556a96d8", 7069736), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2410,7 +3083,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "08a96bf061af1fa4f75c6a7cc56b60a4", 20734979), PL_POL, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -2427,7 +3101,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640 | kFeaturesSCNDemo, @@ -2440,7 +3115,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "6190e32404b672f4bbbc39cf76f41fda", 2511470), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, kFeatures640, @@ -2453,7 +3129,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "61e4069c16e27775a6cc6d20f529fb36", 2511300), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, kFeatures640, @@ -2466,7 +3143,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "61e4069c16e27775a6cc6d20f529fb36", 2511300), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, kFeatures640, @@ -2479,7 +3157,22 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "b3f8472484b7a1df94557b51e7b6fca0", 2322644), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypeDynasty, + kFeatures640, + 0, 0, 0 + }, + { + { + "dynasty", + "", + AD_ENTRY1s("intro.stk", "bdbdac8919200a5e71ffb9fb0709f704", 2446652), + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeDynasty, kFeatures640, @@ -2492,7 +3185,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "464538a17ed39755d7f1ba9c751af1bd", 1847864), EN_USA, kPlatformPC, - ADGF_DEMO + ADGF_DEMO, + GUIO_NONE }, kGameTypeDynasty, kFeatures640, @@ -2505,7 +3199,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("lda1.stk", "0e56a899357cbc0bf503260fd2dd634e", 15032774), UNK_LANG, kPlatformWindows, - ADGF_DEMO + ADGF_DEMO, + GUIO_NONE }, kGameTypeDynasty, kFeatures640, @@ -2518,7 +3213,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("lda1.stk", "8669ea2e9a8239c070dc73958fbc8753", 15567724), DE_DEU, kPlatformWindows, - ADGF_DEMO + ADGF_DEMO, + GUIO_NONE }, kGameTypeDynasty, kFeatures640, @@ -2531,7 +3227,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "3ab2c542bd9216ae5d02cc6f45701ae1", 1252436), EN_USA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, kFeatures640, @@ -2544,7 +3241,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "b991ed1d31c793e560edefdb349882ef", 1276408), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, kFeatures640, @@ -2557,7 +3255,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "4ec3c0864e2b54c5b4ccf9f6ad96528d", 1253328), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, kFeatures640, @@ -2570,7 +3269,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "4bd31979ea3d77a58a358c09000a85ed", 1253018), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, kFeatures640, @@ -2588,7 +3288,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeUrban, kFeatures640 | kFeaturesSCNDemo, @@ -2596,7 +3297,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "archi", + "playtoons1", "", { {"playtoon.stk", 0, "8c98e9a11be9bb203a55e8c6e68e519b", 25574338}, @@ -2605,7 +3306,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -2613,8 +3315,8 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "archi", - "Pack mes histoires animées", + "playtoons1", + "Pack mes histoires anim\xE9""es", { {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, {"archi.stk", 0, "8d44b2a0d4e3139471213f9f0ed21e81", 5524674}, @@ -2622,7 +3324,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -2630,7 +3333,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "archi", + "playtoons1", "", { {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, @@ -2639,7 +3342,8 @@ static const GOBGameDescription gameDescriptions[] = { }, DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -2647,7 +3351,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "archi", + "playtoons1", "Non-Interactive Demo", { {"play123.scn", 0, "4689a31f543915e488c3bc46ea358add", 258}, @@ -2661,7 +3365,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640 | kFeaturesSCNDemo, @@ -2669,7 +3374,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "archi", + "playtoons1", "Non-Interactive Demo", { {"e.scn", 0, "8a0db733c3f77be86e74e8242e5caa61", 124}, @@ -2678,7 +3383,8 @@ static const GOBGameDescription gameDescriptions[] = { }, EN_ANY, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640 | kFeaturesSCNDemo, @@ -2686,7 +3392,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "archi", + "playtoons1", "Non-Interactive Demo", { {"i.scn", 0, "8b3294474d39970463663edd22341730", 285}, @@ -2699,7 +3405,8 @@ static const GOBGameDescription gameDescriptions[] = { }, IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640 | kFeaturesSCNDemo, @@ -2707,7 +3414,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "archi", + "playtoons1", "Non-Interactive Demo", { {"s.scn", 0, "1f527010626b5490761f16ba7a6f639a", 251}, @@ -2719,7 +3426,8 @@ static const GOBGameDescription gameDescriptions[] = { }, ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640 | kFeaturesSCNDemo, @@ -2727,7 +3435,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "spirou", + "playtoons2", "", { {"playtoon.stk", 0, "55a85036dd93cce93532d8f743d90074", 17467154}, @@ -2736,7 +3444,26 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypePlaytoon, + kFeatures640, + "intro2.stk", 0, 0 + }, + { + { + "playtoons2", + "", + { + {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, + {"spirou.stk", 0, "91080dc148de1bbd6a97321c1a1facf3", 9817086}, + {0, 0, 0, 0} + }, + DE_DEU, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -2744,7 +3471,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "chato", + "playtoons3", "", { {"playtoon.stk", 0, "8c98e9a11be9bb203a55e8c6e68e519b", 25574338}, @@ -2753,7 +3480,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -2761,8 +3489,26 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "chato", - "Pack mes histoires animées", + "playtoons3", + "", + { + {"playtoon.stk", 0, "9e513e993a5b0e2496add3f50c08764b", 30448506}, + {"chato.stk", 0, "8fc8d0da5b3e758908d1d7298d497d0b", 6041026}, + {0, 0, 0, 0} + }, + EN_ANY, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypePlaytoon, + kFeatures640, + "intro2.stk", 0, 0 + }, + { + { + "playtoons3", + "Pack mes histoires anim\xE9""es", { {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, {"chato.stk", 0, "4fa4ed96a427c344e9f916f9f236598d", 6033793}, @@ -2770,7 +3516,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -2778,7 +3525,7 @@ static const GOBGameDescription gameDescriptions[] = { }, { { - "chato", + "playtoons3", "", { {"playtoon.stk", 0, "c5ca2a288cdaefca9556cd9ae4b579cf", 25158926}, @@ -2787,15 +3534,35 @@ static const GOBGameDescription gameDescriptions[] = { }, DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, "intro2.stk", 0, 0 }, + { { - "wakan", + "playtoons4", + "", + { + {"playtoon.stk", 0, "b7f5afa2dc1b0f75970b7c07d175db1b", 24340406}, + {"manda.stk", 0, "92529e0b927191d9898a34c2892e9a3a", 6485072}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypePlaytoon, + kFeatures640, + "intro2.stk", 0, 0 + }, + { + { + "playtoons5", "", { {"playtoon.stk", 0, "55f0293202963854192e39474e214f5f", 30448474}, @@ -2804,7 +3571,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -2821,11 +3589,30 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBambou, kFeatures640, - 0, 0, 0 + "intro.stk", "intro.tot", 0 + }, + { + { + "playtnck1", + "", + { + {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, + {"dan.itk", 0, "906d67b3e438d5e95ec7ea9e781a94f3", 3000320}, + {0, 0, 0, 0} + }, + FR_FRA, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH + }, + kGameTypePlaytnCk, + kFeatures640, + "intro2.stk", 0, 0 }, { { @@ -2833,11 +3620,13 @@ static const GOBGameDescription gameDescriptions[] = { "", { {"playtoon.stk", 0, "5f9aae29265f1f105ad8ec195dff81de", 68382024}, + {"dan.itk", 0, "74eeb075bd2cb47b243349730264af01", 3213312}, {0, 0, 0, 0} }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytnCk, kFeatures640, @@ -2850,7 +3639,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "a3c35d19b2d28ea261d96321d208cb5a", 6021466), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibou4, kFeatures640, @@ -2863,7 +3653,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "d2f0fb8909e396328dc85c0e29131ba8", 5847588), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibou4, kFeatures640, @@ -2876,7 +3667,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "367340e59c461b4fa36651cd74e32c4e", 5847378), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibou4, kFeatures640, @@ -2889,7 +3681,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "c5b9f6222c0b463f51dab47317c5b687", 5950490), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibou4, kFeaturesNone, @@ -2901,7 +3694,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "904a93f46687617bb34e672020fc17a4", 248724), FR_FRA, kPlatformAtariST, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -2914,7 +3708,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "1e49c39a4a3ce6032a84b712539c2d63", 8738134), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -2927,7 +3722,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("adi2.stk", "2a40bb48ccbd4e6fb3f7f0fc2f069d80", 17720132), ES_ESP, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -2940,7 +3736,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "94ae7004348dc8bf99c23a9a6ef81827", 956162), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -2953,7 +3750,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -2966,7 +3764,8 @@ static const GOBGameDescription gameDescriptions[] = { AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), DE_DEU, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -2975,11 +3774,12 @@ static const GOBGameDescription gameDescriptions[] = { { { "adibouunknown", - "ADIBÙ 2 Ambiente", + "ADIB\xD9 2 Ambiente", AD_ENTRY1s("intro.stk", "092707829555f27706920e4cacf1fada", 8737958), IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -2988,7 +3788,7 @@ static const GOBGameDescription gameDescriptions[] = { { { "adibouunknown", - "ADIBÙ prima elementare : Imparo a leggere e a contare", + "ADIB\xD9 prima elementare : Imparo a leggere e a contare", { {"intro.stk", 0, "092707829555f27706920e4cacf1fada", 8737958}, {"appbou2.itk", 0, "f7bf045f6bdce5a7607c720e36704f33", 200005632}, @@ -2996,7 +3796,8 @@ static const GOBGameDescription gameDescriptions[] = { }, IT_ITA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -3005,7 +3806,7 @@ static const GOBGameDescription gameDescriptions[] = { { { "adibouunknown", - "ADIBOU présente La Magie (STK2.1/OBC)", + "ADIBOU pr\xE9sente La Magie (STK2.1/OBC)", { {"adibou.stk", 0, "977d2449d398f3df23238d718fca35b5", 61097}, {"magic.stk", 0, "9776765dead3e338a32c43bf344b5819", 302664}, @@ -3013,7 +3814,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -3030,7 +3832,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -3047,7 +3850,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -3064,7 +3868,8 @@ static const GOBGameDescription gameDescriptions[] = { }, FR_FRA, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, kGameTypeAdibouUnknown, kFeaturesNone, @@ -3081,7 +3886,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesNone, @@ -3094,7 +3900,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob1, kFeaturesCD, @@ -3107,7 +3914,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -3120,7 +3928,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesAdlib, @@ -3133,7 +3942,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob2, kFeaturesCD, @@ -3146,7 +3956,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBargon, kFeaturesNone, @@ -3159,7 +3970,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesAdlib, @@ -3172,7 +3984,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGob3, kFeaturesCD, @@ -3185,7 +3998,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeWoodruff, kFeatures640, @@ -3198,7 +4012,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -3211,7 +4026,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformMacintosh, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesAdlib, @@ -3224,7 +4040,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeLostInTime, kFeaturesCD, @@ -3237,7 +4054,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeUrban, kFeaturesCD, @@ -3245,12 +4063,13 @@ static const GOBGameDescription fallbackDescs[] = { }, { { - "archi", + "playtoons1", "unknown", AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -3258,12 +4077,13 @@ static const GOBGameDescription fallbackDescs[] = { }, { { - "spirou", + "playtoons2", "unknown", AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -3271,12 +4091,13 @@ static const GOBGameDescription fallbackDescs[] = { }, { { - "chato", + "playtoons3", "unknown", AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -3284,12 +4105,13 @@ static const GOBGameDescription fallbackDescs[] = { }, { { - "manda", + "playtoons4", "unknown", AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -3297,12 +4119,13 @@ static const GOBGameDescription fallbackDescs[] = { }, { { - "wakan", + "playtoons5", "unknown", AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytoon, kFeatures640, @@ -3315,7 +4138,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypePlaytnCk, kFeatures640, @@ -3328,7 +4152,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeBambou, kFeatures640, @@ -3341,7 +4166,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeFascination, kFeaturesNone, @@ -3354,7 +4180,8 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeGeisha, kFeaturesNone, @@ -3367,12 +4194,27 @@ static const GOBGameDescription fallbackDescs[] = { AD_ENTRY1(0, 0), UNK_LANG, kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NOSUBTITLES | GUIO_NOSPEECH }, kGameTypeAdibou4, kFeatures640, "adif41.stk", 0, 0 }, + { + { + "coktelplayer", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + ADGF_NO_FLAGS, + GUIO_NONE + }, + kGameTypeUrban, + kFeatures640 | kFeaturesSCNDemo, + "", "", 8 + } }; static const ADFileBasedFallback fileBased[] = { @@ -3400,6 +4242,7 @@ static const ADFileBasedFallback fileBased[] = { { &fallbackDescs[20], { "disk0.stk", "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, { &fallbackDescs[21], { "disk1.stk", "disk2.stk", "disk3.stk", 0 } }, { &fallbackDescs[22], { "adif41.stk", "adim41.stk", 0 } }, + { &fallbackDescs[23], { "coktelplayer.scn", 0 } }, { 0, { 0 } } }; @@ -3421,7 +4264,9 @@ static const ADParams detectionParams = { // List of files for file-based fallback detection (optional) Gob::fileBased, // Flags - 0 + 0, + // Additional GUI options (for every game} + Common::GUIO_NOLAUNCHLOAD }; class GobMetaEngine : public AdvancedMetaEngine { diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index 73facb4ac3..b3e5e7418c 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -30,6 +30,7 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/game.h" +#include "gob/script.h" #include "gob/inter.h" #include "gob/video.h" #include "gob/palanim.h" @@ -62,8 +63,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { for (int i = 0; i < 8; i++) _fonts[i] = 0; - for (int i = 0; i < SPRITES_COUNT; i++) - _spritesArray[i] = 0; + _spritesArray.resize(SPRITES_COUNT); _invalidatedCount = 0; for (int i = 0; i < 30; i++) { @@ -78,9 +78,6 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _paletteCleared = false; _applyPal = false; - _backSurface = 0; - _frontSurface = 0; - for (int i = 0; i < 18; i++) _unusedPalette1[i] = 0; for (int i = 0; i < 16; i++) @@ -109,10 +106,6 @@ Draw::Draw(GobEngine *vm) : _vm(vm) { _cursorHotspotXVar = -1; _cursorHotspotYVar = -1; - _cursorSprites = 0; - _cursorSpritesBack = 0; - _scummvmCursor = 0; - _cursorAnim = 0; for (int i = 0; i < 40; i++) { _cursorAnimLow[i] = 0; @@ -265,7 +258,7 @@ void Draw::blitInvalidated() { _vm->_video->_doRangeClamp = false; for (int i = 0; i < _invalidatedCount; i++) { - _vm->_video->drawSprite(_backSurface, _frontSurface, + _vm->_video->drawSprite(*_backSurface, *_frontSurface, _invalidatedLefts[i], _invalidatedTops[i], _invalidatedRights[i], _invalidatedBottoms[i], _invalidatedLefts[i], _invalidatedTops[i], 0); @@ -302,7 +295,7 @@ void Draw::dirtiedRect(int16 surface, dirtiedRect(_spritesArray[surface], left, top, right, bottom); } -void Draw::dirtiedRect(SurfaceDesc::Ptr surface, +void Draw::dirtiedRect(SurfaceDescPtr surface, int16 left, int16 top, int16 right, int16 bottom) { if (surface == _backSurface) @@ -316,7 +309,7 @@ void Draw::initSpriteSurf(int16 index, int16 width, int16 height, _spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, flags); - _vm->_video->clearSurf(_spritesArray[index]); + _vm->_video->clearSurf(*_spritesArray[index]); } void Draw::adjustCoords(char adjust, int16 *coord1, int16 *coord2) { @@ -379,7 +372,7 @@ int Draw::stringLength(const char *str, int16 fontIndex) { } void Draw::drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, SurfaceDesc *dest, Video::FontDesc *font) { + int16 transp, SurfaceDesc &dest, Video::FontDesc *font) { while (*str != '\0') { _vm->_video->drawLetter(*str, x, y, font, transp, color1, color2, dest); @@ -397,11 +390,10 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, adjustCoords(1, &left, &top); adjustCoords(1, &right, &bottom); - if (READ_LE_UINT16(_vm->_game->_totFileData + 0x7E) != 0) { - byte *storedIP = _vm->_global->_inter_execPtr; + uint16 centerOffset = _vm->_game->_script->getFunctionOffset(TOTFile::kFunctionCenter); + if (centerOffset != 0) { + _vm->_game->_script->call(centerOffset); - _vm->_global->_inter_execPtr = _vm->_game->_totFileData + - READ_LE_UINT16(_vm->_game->_totFileData + 0x7E); WRITE_VAR(17, (uint32) id); WRITE_VAR(18, (uint32) left); WRITE_VAR(19, (uint32) top); @@ -409,7 +401,7 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right, WRITE_VAR(21, (uint32) (bottom - top + 1)); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = storedIP; + _vm->_game->_script->pop(); } if (str[0] == '\0') @@ -447,7 +439,7 @@ int32 Draw::getSpriteRectSize(int16 index) { } void Draw::forceBlit(bool backwards) { - if ((_frontSurface == 0) || (_backSurface == 0)) + if (!_frontSurface || !_backSurface) return; if (_frontSurface == _backSurface) return; @@ -457,12 +449,12 @@ void Draw::forceBlit(bool backwards) { return; if (!backwards) { - _vm->_video->drawSprite(_backSurface, _frontSurface, 0, 0, + _vm->_video->drawSprite(*_backSurface, *_frontSurface, 0, 0, _backSurface->getWidth() - 1, _backSurface->getHeight() - 1, 0, 0, 0); _vm->_video->dirtyRectsAll(); } else - _vm->_video->drawSprite(_frontSurface, _backSurface, 0, 0, + _vm->_video->drawSprite(*_frontSurface, *_backSurface, 0, 0, _frontSurface->getWidth() - 1, _frontSurface->getHeight() - 1, 0, 0, 0); @@ -511,7 +503,7 @@ const int16 Draw::_wobbleTable[360] = { -0x0A03, -0x08E8, -0x07CC, -0x06B0, -0x0593, -0x0476, -0x0359, -0x023B, -0x011D }; -void Draw::wobble(SurfaceDesc *surfDesc) { +void Draw::wobble(SurfaceDesc &surfDesc) { int16 amplitude = 32; uint16 curFrame = 0; uint16 frameWobble = 0; @@ -535,7 +527,7 @@ void Draw::wobble(SurfaceDesc *surfDesc) { amplitude--; for (uint16 y = 0; y < _vm->_height; y++) - _vm->_video->drawSprite(surfDesc, _frontSurface, + _vm->_video->drawSprite(surfDesc, *_frontSurface, 0, y, _vm->_width - 1, y, offsets[y], y, 0); _vm->_palAnim->fadeStep(0); @@ -543,7 +535,7 @@ void Draw::wobble(SurfaceDesc *surfDesc) { _vm->_video->waitRetrace(); } - _vm->_video->drawSprite(surfDesc, _frontSurface, + _vm->_video->drawSprite(surfDesc, *_frontSurface, 0, 0, _vm->_width - 1, _vm->_height - 1, 0, 0, 0); _applyPal = false; diff --git a/engines/gob/draw.h b/engines/gob/draw.h index ccdd91d1e4..26f78ce3b3 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -78,7 +78,7 @@ public: FontToSprite _fontToSprite[4]; Video::FontDesc *_fonts[8]; - SurfaceDesc::Ptr _spritesArray[SPRITES_COUNT]; + Common::Array<SurfaceDescPtr> _spritesArray; int16 _invalidatedCount; int16 _invalidatedTops[30]; @@ -92,8 +92,8 @@ public: bool _paletteCleared; bool _applyPal; - SurfaceDesc::Ptr _backSurface; - SurfaceDesc::Ptr _frontSurface; + SurfaceDescPtr _backSurface; + SurfaceDescPtr _frontSurface; int16 _unusedPalette1[18]; int16 _unusedPalette2[16]; @@ -117,9 +117,9 @@ public: int16 _cursorHotspotXVar; int16 _cursorHotspotYVar; - SurfaceDesc::Ptr _cursorSprites; - SurfaceDesc::Ptr _cursorSpritesBack; - SurfaceDesc::Ptr _scummvmCursor; + SurfaceDescPtr _cursorSprites; + SurfaceDescPtr _cursorSpritesBack; + SurfaceDescPtr _scummvmCursor; int16 _cursorAnim; int8 _cursorAnimLow[40]; @@ -139,12 +139,12 @@ public: void clearPalette(); void dirtiedRect(int16 surface, int16 left, int16 top, int16 right, int16 bottom); - void dirtiedRect(SurfaceDesc::Ptr surface, int16 left, int16 top, int16 right, int16 bottom); + void dirtiedRect(SurfaceDescPtr surface, int16 left, int16 top, int16 right, int16 bottom); void initSpriteSurf(int16 index, int16 width, int16 height, int16 flags); void freeSprite(int16 index) { assert(index < SPRITES_COUNT); - _spritesArray[index] = 0; + _spritesArray[index].reset(); } void adjustCoords(char adjust, int16 *coord1, int16 *coord2); void adjustCoords(char adjust, uint16 *coord1, uint16 *coord2) { @@ -152,14 +152,14 @@ public: } int stringLength(const char *str, int16 fontIndex); void drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2, - int16 transp, SurfaceDesc *dest, Video::FontDesc *font); + int16 transp, SurfaceDesc &dest, Video::FontDesc *font); void printTextCentered(int16 id, int16 left, int16 top, int16 right, int16 bottom, const char *str, int16 fontIndex, int16 color); int32 getSpriteRectSize(int16 index); void forceBlit(bool backwards = false); static const int16 _wobbleTable[360]; - void wobble(SurfaceDesc *surfDesc); + void wobble(SurfaceDesc &surfDesc); virtual void initScreen() = 0; virtual void closeScreen() = 0; diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 1943c327d8..94ee32a031 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -32,6 +32,7 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/game.h" +#include "gob/resources.h" #include "gob/scenery.h" #include "gob/inter.h" #include "gob/sound/sound.h" @@ -131,8 +132,8 @@ void Draw_v1::animateCursor(int16 cursor) { newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); } - _vm->_video->clearSurf(_scummvmCursor); - _vm->_video->drawSprite(_cursorSprites, _scummvmCursor, + _vm->_video->clearSurf(*_scummvmCursor); + _vm->_video->drawSprite(*_cursorSprites, *_scummvmCursor, cursorIndex * _cursorWidth, 0, (cursorIndex + 1) * _cursorWidth - 1, _cursorHeight - 1, 0, 0, 0); @@ -173,12 +174,12 @@ void Draw_v1::printTotText(int16 id) { _vm->_sound->cdPlayMultMusic(); - if (!_vm->_game->_totTextData || !_vm->_game->_totTextData->dataPtr) + TextItem *textItem = _vm->_game->_resources->getTextItem(id); + if (!textItem) return; - dataPtr = _vm->_game->_totTextData->dataPtr + - _vm->_game->_totTextData->items[id].offset; - ptr = dataPtr; + dataPtr = textItem->getData(); + ptr = dataPtr; destX = READ_LE_UINT16(ptr) & 0x7FFF; destY = READ_LE_UINT16(ptr + 2); @@ -312,7 +313,9 @@ void Draw_v1::printTotText(int16 id) { } } + delete textItem; _renderFlags = savedFlags; + if (_renderFlags & RENDERFLAG_COLLISIONS) _vm->_game->checkCollisions(0, 0, 0, 0); @@ -323,11 +326,10 @@ void Draw_v1::printTotText(int16 id) { } void Draw_v1::spriteOperation(int16 operation) { - uint16 id; - byte *dataBuf; int16 len; int16 x, y; int16 perLine; + Resource *resource; if (_sourceSurface >= 100) _sourceSurface -= 80; @@ -354,8 +356,8 @@ void Draw_v1::spriteOperation(int16 operation) { switch (operation) { case DRAW_BLITSURF: - _vm->_video->drawSprite(_spritesArray[_sourceSurface], - _spritesArray[_destSurface], + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], + *_spritesArray[_destSurface], _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, @@ -367,13 +369,13 @@ void Draw_v1::spriteOperation(int16 operation) { case DRAW_PUTPIXEL: _vm->_video->putPixel(_destSpriteX, _destSpriteY, - _frontColor, _spritesArray[_destSurface]); + _frontColor, *_spritesArray[_destSurface]); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); @@ -383,7 +385,7 @@ void Draw_v1::spriteOperation(int16 operation) { break; case DRAW_DRAWLINE: - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); @@ -396,30 +398,20 @@ void Draw_v1::spriteOperation(int16 operation) { break; case DRAW_LOADSPRITE: - id = _spriteLeft; - if (id >= 30000) { - dataBuf = - _vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom); - _vm->_video->drawPackedSprite(dataBuf, - _spriteRight, _spriteBottom, - _destSpriteX, _destSpriteY, - _transparency, _spritesArray[_destSurface]); - dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); - delete[] dataBuf; - break; - } + resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, + &_spriteRight, &_spriteBottom); - if (!(dataBuf = _vm->_game->loadTotResource(id, 0, &_spriteRight, &_spriteBottom))) + if (!resource) break; - _vm->_video->drawPackedSprite(dataBuf, - _spriteRight, _spriteBottom, - _destSpriteX, _destSpriteY, - _transparency, _spritesArray[_destSurface]); + _vm->_video->drawPackedSprite(resource->getData(), + _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, + _transparency, *_spritesArray[_destSurface]); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + + delete resource; break; case DRAW_PRINTTEXT: @@ -434,26 +426,26 @@ void Draw_v1::spriteOperation(int16 operation) { _fonts[_fontIndex], _transparency, _frontColor, _backColor, - _spritesArray[_destSurface]); + *_spritesArray[_destSurface]); _destSpriteX += _fonts[_fontIndex]->itemWidth; } break; case DRAW_DRAWBAR: - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); @@ -462,7 +454,7 @@ void Draw_v1::spriteOperation(int16 operation) { case DRAW_CLEARRECT: if (_backColor < 16) { - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); @@ -471,7 +463,7 @@ void Draw_v1::spriteOperation(int16 operation) { break; case DRAW_FILLRECTABS: - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); @@ -488,7 +480,7 @@ void Draw_v1::spriteOperation(int16 operation) { _fonts[_fontIndex], _transparency, _frontColor, _backColor, - _spritesArray[_destSurface]); + *_spritesArray[_destSurface]); break; } @@ -506,8 +498,8 @@ void Draw_v1::spriteOperation(int16 operation) { _destSpriteX + _fontToSprite[_fontIndex].width, _destSpriteY + _fontToSprite[_fontIndex].height); - _vm->_video->drawSprite(_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], - _spritesArray[_destSurface], x, y, + _vm->_video->drawSprite(*_spritesArray[(int16)_fontToSprite[_fontIndex].sprite], + *_spritesArray[_destSurface], x, y, x + _fontToSprite[_fontIndex].width, y + _fontToSprite[_fontIndex].height, _destSpriteX, _destSpriteY, _transparency); diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 852e0b51fb..2843456f42 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -32,6 +32,8 @@ #include "gob/global.h" #include "gob/util.h" #include "gob/game.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/scenery.h" #include "gob/inter.h" #include "gob/video.h" @@ -48,7 +50,7 @@ void Draw_v2::initScreen() { initSpriteSurf(21, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0); _backSurface = _spritesArray[21]; - _vm->_video->clearSurf(_backSurface); + _vm->_video->clearSurf(*_backSurface); if (!_spritesArray[23]) { initSpriteSurf(23, 32, 16, 2); @@ -162,8 +164,8 @@ void Draw_v2::animateCursor(int16 cursor) { newY -= hotspotY = (uint16) VAR(_cursorIndex + _cursorHotspotYVar); } - _vm->_video->clearSurf(_scummvmCursor); - _vm->_video->drawSprite(_cursorSprites, _scummvmCursor, + _vm->_video->clearSurf(*_scummvmCursor); + _vm->_video->drawSprite(*_cursorSprites, *_scummvmCursor, cursorIndex * _cursorWidth, 0, (cursorIndex + 1) * _cursorWidth - 1, _cursorHeight - 1, 0, 0, 0); @@ -205,12 +207,6 @@ void Draw_v2::printTotText(int16 id) { id &= 0xFFF; - if (!_vm->_game->_totTextData || !_vm->_game->_totTextData->dataPtr || - (id >= _vm->_game->_totTextData->itemsCount) || - (_vm->_game->_totTextData->items[id].offset == -1) || - (_vm->_game->_totTextData->items[id].size == 0)) - return; - _vm->validateLanguage(); // WORKAROUND: In the scripts of some Gobliins 2 versions, the dialog text IDs @@ -234,13 +230,18 @@ void Draw_v2::printTotText(int16 id) { } - size = _vm->_game->_totTextData->items[id].size; - dataPtr = _vm->_game->_totTextData->dataPtr + - _vm->_game->_totTextData->items[id].offset; - ptr = dataPtr; + TextItem *textItem = _vm->_game->_resources->getTextItem(id); + if (!textItem) + return; - if ((_renderFlags & RENDERFLAG_SKIPOPTIONALTEXT) && (ptr[1] & 0x80)) + size = textItem->getSize(); + dataPtr = textItem->getData(); + ptr = dataPtr; + + if ((_renderFlags & RENDERFLAG_SKIPOPTIONALTEXT) && (ptr[1] & 0x80)) { + delete textItem; return; + } if (_renderFlags & RENDERFLAG_DOUBLECOORDS) { destX = (READ_LE_UINT16(ptr) & 0x7FFF) * 2; @@ -328,7 +329,7 @@ void Draw_v2::printTotText(int16 id) { ptrEnd = ptr; while (((ptrEnd - dataPtr) < size) && (*ptrEnd != 1)) { // Converting to unknown commands/characters to spaces - if ((_vm->_game->_totFileData[0x29] < 0x32) && (*ptrEnd > 3) && (*ptrEnd < 32)) + if ((_vm->_game->_script->getVersionMinor() < 2) && (*ptrEnd > 3) && (*ptrEnd < 32)) *ptrEnd = 32; switch (*ptrEnd) { @@ -524,7 +525,7 @@ void Draw_v2::printTotText(int16 id) { case 10: str[0] = (char) 255; WRITE_LE_UINT16((uint16 *) (str + 1), - ptr - _vm->_game->_totTextData->dataPtr); + ptr - _vm->_game->_resources->getTexts()); str[3] = 0; ptr++; for (int i = *ptr++; i > 0; i--) { @@ -597,7 +598,9 @@ void Draw_v2::printTotText(int16 id) { } } + delete textItem; _renderFlags = savedFlags; + if (!(_renderFlags & RENDERFLAG_COLLISIONS)) return; @@ -610,14 +613,13 @@ void Draw_v2::printTotText(int16 id) { } void Draw_v2::spriteOperation(int16 operation) { - uint16 id; - byte *dataBuf; int16 len; int16 x, y; - SurfaceDesc *sourceSurf, *destSurf; + SurfaceDescPtr sourceSurf, destSurf; bool deltaVeto; int16 left; int16 ratio; + Resource *resource; // Always assigned to -1 in Game::loadTotFile() int16 someHandle = -1; @@ -705,14 +707,19 @@ void Draw_v2::spriteOperation(int16 operation) { sourceSurf = _spritesArray[_sourceSurface]; destSurf = _spritesArray[_destSurface]; + if (!destSurf) { + warning("Can't do operation %d on surface %d: nonexistent", operation, _destSurface); + return; + } + switch (operation) { case DRAW_BLITSURF: case DRAW_DRAWLETTER: if (!sourceSurf || !destSurf) break; - _vm->_video->drawSprite(_spritesArray[_sourceSurface], - _spritesArray[_destSurface], + _vm->_video->drawSprite(*_spritesArray[_sourceSurface], + *_spritesArray[_destSurface], _spriteLeft, spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, @@ -724,13 +731,13 @@ void Draw_v2::spriteOperation(int16 operation) { case DRAW_PUTPIXEL: _vm->_video->putPixel(_destSpriteX, _destSpriteY, _frontColor, - _spritesArray[_destSurface]); + *_spritesArray[_destSurface]); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX, _destSpriteY); break; case DRAW_FILLRECT: - _vm->_video->fillRect(_spritesArray[_destSurface], destSpriteX, + _vm->_video->fillRect(*_spritesArray[_destSurface], destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1, _backColor); @@ -739,7 +746,7 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_DRAWLINE: - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); @@ -747,7 +754,7 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_INVALIDATE: - _vm->_video->drawCircle(_spritesArray[_destSurface], _destSpriteX, + _vm->_video->drawCircle(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _frontColor); dirtiedRect(_destSurface, _destSpriteX - _spriteRight, _destSpriteY - _spriteBottom, @@ -755,41 +762,20 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_LOADSPRITE: - id = _spriteLeft; - - if ((id >= 30000) || (_vm->_game->_lomHandle >= 0)) { - dataBuf = 0; + resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, + &_spriteRight, &_spriteBottom); - if (_vm->_game->_lomHandle >= 0) - warning("Urban Stub: LOADSPRITE %d, LOM", id); - else - dataBuf = _vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom); - - if (!dataBuf) - break; - - _vm->_video->drawPackedSprite(dataBuf, - _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, - _transparency, _spritesArray[_destSurface]); - - dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, - _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); - - delete[] dataBuf; + if (!resource) break; - } - // Load from .TOT resources - if (!(dataBuf = _vm->_game->loadTotResource(id, 0, &_spriteRight, &_spriteBottom))) - break; - - _vm->_video->drawPackedSprite(dataBuf, - _spriteRight, _spriteBottom, - _destSpriteX, _destSpriteY, - _transparency, _spritesArray[_destSurface]); + _vm->_video->drawPackedSprite(resource->getData(), + _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY, + _transparency, *_spritesArray[_destSurface]); dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); + + delete resource; break; case DRAW_PRINTTEXT: @@ -802,16 +788,16 @@ void Draw_v2::spriteOperation(int16 operation) { if (((int8) _textToPrint[0]) == -1) { _vm->validateLanguage(); - dataBuf = _vm->_game->_totTextData->dataPtr + _textToPrint[1] + 1; + byte *dataBuf = _vm->_game->_resources->getTexts() + _textToPrint[1] + 1; len = *dataBuf++; for (int i = 0; i < len; i++, dataBuf += 2) { _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, _destSpriteY, _fonts[_fontIndex], _transparency, _frontColor, - _backColor, _spritesArray[_destSurface]); + _backColor, *_spritesArray[_destSurface]); } } else { drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor, - _backColor, _transparency, _spritesArray[_destSurface], + _backColor, _transparency, *_spritesArray[_destSurface], _fonts[_fontIndex]); _destSpriteX += len * _fonts[_fontIndex]->itemWidth; } @@ -820,7 +806,7 @@ void Draw_v2::spriteOperation(int16 operation) { if ((someHandle < 0) || (_textToPrint[i] != ' ')) { _vm->_video->drawLetter(_textToPrint[i], _destSpriteX, _destSpriteY, _fonts[_fontIndex], _transparency, - _frontColor, _backColor, _spritesArray[_destSurface]); + _frontColor, _backColor, *_spritesArray[_destSurface]); _destSpriteX += *(_fonts[_fontIndex]->extraData + (_textToPrint[i] - _fonts[_fontIndex]->startItem)); } @@ -839,8 +825,8 @@ void Draw_v2::spriteOperation(int16 operation) { * _fontToSprite[_fontIndex].height; x = ((_textToPrint[i] - _fontToSprite[_fontIndex].base) % ratio) * _fontToSprite[_fontIndex].width; - _vm->_video->drawSprite(_spritesArray[_fontToSprite[_fontIndex].sprite], - _spritesArray[_destSurface], x, y, + _vm->_video->drawSprite(*_spritesArray[_fontToSprite[_fontIndex].sprite], + *_spritesArray[_destSurface], x, y, x + _fontToSprite[_fontIndex].width - 1, y + _fontToSprite[_fontIndex].height - 1, _destSpriteX, _destSpriteY, _transparency); @@ -854,35 +840,35 @@ void Draw_v2::spriteOperation(int16 operation) { case DRAW_DRAWBAR: if (_needAdjust != 2) { - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _spriteBottom - 1, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _destSpriteX + 1, _spriteBottom, _frontColor); - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _spriteRight - 1, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY + 1, _frontColor); } else { - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _spriteBottom, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _destSpriteX, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _spriteRight, _destSpriteY, _spriteRight, _spriteBottom, _frontColor); - _vm->_video->drawLine(_spritesArray[_destSurface], + _vm->_video->drawLine(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _destSpriteY, _frontColor); } @@ -892,7 +878,7 @@ void Draw_v2::spriteOperation(int16 operation) { case DRAW_CLEARRECT: if ((_backColor != 16) && (_backColor != 144)) { - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); @@ -902,7 +888,7 @@ void Draw_v2::spriteOperation(int16 operation) { break; case DRAW_FILLRECTABS: - _vm->_video->fillRect(_spritesArray[_destSurface], + _vm->_video->fillRect(*_spritesArray[_destSurface], _destSpriteX, _destSpriteY, _spriteRight, _spriteBottom, _backColor); diff --git a/engines/gob/driver_vga.cpp b/engines/gob/driver_vga.cpp index 24c2d8e37b..aff971164f 100644 --- a/engines/gob/driver_vga.cpp +++ b/engines/gob/driver_vga.cpp @@ -38,26 +38,26 @@ static void plotPixel(int x, int y, int color, void *data) { dest->getVidMem()[(y * dest->getWidth()) + x] = color; } -void VGAVideoDriver::putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest) { - if ((x >= 0) && (x < dest->getWidth()) && - (y >= 0) && (y < dest->getHeight())) - dest->getVidMem()[(y * dest->getWidth()) + x] = color; +void VGAVideoDriver::putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest) { + if ((x >= 0) && (x < dest.getWidth()) && + (y >= 0) && (y < dest.getHeight())) + dest.getVidMem()[(y * dest.getWidth()) + x] = color; } -void VGAVideoDriver::drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, +void VGAVideoDriver::drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) { - Graphics::drawLine(x0, y0, x1, y1, color, &plotPixel, dest); + Graphics::drawLine(x0, y0, x1, y1, color, &plotPixel, &dest); } -void VGAVideoDriver::fillRect(SurfaceDesc *dest, int16 left, int16 top, +void VGAVideoDriver::fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color) { - if ((left >= dest->getWidth()) || (right >= dest->getWidth()) || - (top >= dest->getHeight()) || (bottom >= dest->getHeight())) + if ((left >= dest.getWidth()) || (right >= dest.getWidth()) || + (top >= dest.getHeight()) || (bottom >= dest.getHeight())) return; - byte *pos = dest->getVidMem() + (top * dest->getWidth()) + left; + byte *pos = dest.getVidMem() + (top * dest.getWidth()) + left; int16 width = (right - left) + 1; int16 height = (bottom - top) + 1; @@ -65,19 +65,19 @@ void VGAVideoDriver::fillRect(SurfaceDesc *dest, int16 left, int16 top, for (int16 i = 0; i < width; ++i) pos[i] = color; - pos += dest->getWidth(); + pos += dest.getWidth(); } } void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, - byte transp, SurfaceDesc *dest) { + byte transp, SurfaceDesc &dest) { byte *src, *dst; uint16 data; src = fontDesc->dataPtr + (item - fontDesc->startItem) * (fontDesc->itemSize & 0xFF); - dst = dest->getVidMem() + x + dest->getWidth() * y; + dst = dest.getVidMem() + x + dest.getWidth() * y; int nWidth = fontDesc->itemWidth; @@ -106,26 +106,26 @@ void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, } - dst += dest->getWidth() - fontDesc->itemWidth; + dst += dest.getWidth() - fontDesc->itemWidth; } } -void VGAVideoDriver::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, +void VGAVideoDriver::drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { - if ((x >= dest->getWidth()) || (x < 0) || - (y >= dest->getHeight()) || (y < 0)) + if ((x >= dest.getWidth()) || (x < 0) || + (y >= dest.getHeight()) || (y < 0)) return; - int16 width = MIN((right - left) + 1, (int) dest->getWidth()); - int16 height = MIN((bottom - top) + 1, (int) dest->getHeight()); + int16 width = MIN((right - left) + 1, (int) dest.getWidth()); + int16 height = MIN((bottom - top) + 1, (int) dest.getHeight()); if ((width < 1) || (height < 1)) return; - const byte *srcPos = source->getVidMem() + (top * source->getWidth()) + left; - byte *destPos = dest->getVidMem() + (y * dest->getWidth()) + x; + const byte *srcPos = source.getVidMem() + (top * source.getWidth()) + left; + byte *destPos = dest.getVidMem() + (y * dest.getWidth()) + x; uint32 size = width * height; @@ -137,8 +137,8 @@ void VGAVideoDriver::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, destPos[i] = srcPos[i]; } - srcPos += source->getWidth(); - destPos += dest->getWidth(); + srcPos += source.getWidth(); + destPos += dest.getWidth(); } } else if (((srcPos >= destPos) && (srcPos <= (destPos + size))) || @@ -147,8 +147,8 @@ void VGAVideoDriver::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, while (height--) { memmove(destPos, srcPos, width); - srcPos += source->getWidth(); - destPos += dest->getWidth(); + srcPos += source.getWidth(); + destPos += dest.getWidth(); } } else { @@ -156,29 +156,29 @@ void VGAVideoDriver::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, while (height--) { memcpy(destPos, srcPos, width); - srcPos += source->getWidth(); - destPos += dest->getWidth(); + srcPos += source.getWidth(); + destPos += dest.getWidth(); } } } -void VGAVideoDriver::drawSpriteDouble(SurfaceDesc *source, SurfaceDesc *dest, +void VGAVideoDriver::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { - if ((x >= dest->getWidth()) || (x < 0) || - (y >= dest->getHeight()) || (y < 0)) + if ((x >= dest.getWidth()) || (x < 0) || + (y >= dest.getHeight()) || (y < 0)) return; - int16 width = MIN<int>((right - left) + 1, dest->getWidth() / 2); - int16 height = MIN<int>((bottom - top) + 1, dest->getHeight() / 2); + int16 width = MIN<int>((right - left) + 1, dest.getWidth() / 2); + int16 height = MIN<int>((bottom - top) + 1, dest.getHeight() / 2); if ((width < 1) || (height < 1)) return; - const byte *srcPos = source->getVidMem() + (top * source->getWidth()) + left; - byte *destPos = dest->getVidMem() + ((y * 2) * dest->getWidth()) + (x * 2); + const byte *srcPos = source.getVidMem() + (top * source.getWidth()) + left; + byte *destPos = dest.getVidMem() + ((y * 2) * dest.getWidth()) + (x * 2); while (height--) { const byte *srcBak = srcPos; @@ -193,19 +193,19 @@ void VGAVideoDriver::drawSpriteDouble(SurfaceDesc *source, SurfaceDesc *dest, } } - destPos += dest->getWidth(); + destPos += dest.getWidth(); } - srcPos = srcBak + source->getWidth(); + srcPos = srcBak + source.getWidth(); } } void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, byte transp, SurfaceDesc *dest) { + int16 x, int16 y, byte transp, SurfaceDesc &dest) { int destRight = x + width; int destBottom = y + height; - byte *dst = dest->getVidMem() + x + dest->getWidth() * y; + byte *dst = dest.getVidMem() + x + dest.getWidth() * y; int curx = x; int cury = y; @@ -223,14 +223,14 @@ void VGAVideoDriver::drawPackedSprite(byte *sprBuf, int16 width, int16 height, val >>= 4; for (unsigned int i = 0; i < repeat; ++i) { - if (curx < dest->getWidth() && cury < dest->getHeight()) + if (curx < dest.getWidth() && cury < dest.getHeight()) if (!transp || val) *dst = val; dst++; curx++; if (curx == destRight) { - dst += dest->getWidth() + x - curx; + dst += dest.getWidth() + x - curx; curx = x; cury++; if (cury == destBottom) diff --git a/engines/gob/driver_vga.h b/engines/gob/driver_vga.h index c67fd1cb2f..c50ea5c475 100644 --- a/engines/gob/driver_vga.h +++ b/engines/gob/driver_vga.h @@ -35,20 +35,20 @@ public: VGAVideoDriver() {} virtual ~VGAVideoDriver() {} - void putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest); - void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, + void putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest); + void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color); - void fillRect(SurfaceDesc *dest, int16 left, int16 top, + void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color); void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, - byte transp, SurfaceDesc *dest); - void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, + byte transp, SurfaceDesc &dest); + void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void drawSpriteDouble(SurfaceDesc *source, SurfaceDesc *dest, int16 left, + void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); void drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, byte transp, SurfaceDesc *dest); + int16 x, int16 y, byte transp, SurfaceDesc &dest); }; } diff --git a/engines/gob/expression.cpp b/engines/gob/expression.cpp new file mode 100644 index 0000000000..61376b2212 --- /dev/null +++ b/engines/gob/expression.cpp @@ -0,0 +1,1144 @@ +/* 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/expression.h" +#include "gob/global.h" +#include "gob/game.h" +#include "gob/script.h" +#include "gob/inter.h" + +namespace Gob { + +Expression::Stack::Stack(size_t size) { + opers = new byte[size]; + values = new int32[size]; + memset(opers , 0, size * sizeof(byte )); + memset(values, 0, size * sizeof(int32)); +} + +Expression::Stack::~Stack() { + delete[] opers; + delete[] values; +} + +Expression::StackFrame::StackFrame(const Stack &stack) { + opers = stack.opers - 1; + values = stack.values - 1; + pos = -1; +} + +void Expression::StackFrame::push(int count) { + opers += count; + values += count; + pos += count; +} + +void Expression::StackFrame::pop(int count) { + opers -= count; + values -= count; + pos -= count; +} + +Expression::Expression(GobEngine *vm) : _vm(vm) { + _resultStr[0] = 0; + _resultInt = 0; +} + +int32 Expression::encodePtr(byte *ptr, int type) { + int32 offset = 0; + + switch (type) { + case kExecPtr: + offset = _vm->_game->_script->getOffset(ptr); + break; + case kInterVar: + offset = ptr - ((byte *) _vm->_inter->_variables->getAddressOff8(0)); + break; + case kResStr: + offset = ptr - ((byte *) _resultStr); + break; + default: + error("Expression::encodePtr(): Unknown pointer type"); + } + assert((offset & 0xF0000000) == 0); + return (type << 28) | offset; +} + +byte *Expression::decodePtr(int32 n) { + byte *ptr; + + switch (n >> 28) { + case kExecPtr: + return _vm->_game->_script->getData((n & 0x0FFFFFFF)); + case kInterVar: + ptr = (byte *) _vm->_inter->_variables->getAddressOff8(0); + break; + case kResStr: + ptr = (byte *) _resultStr; + break; + default: + error("Expression::decodePtr(): Unknown pointer type"); + } + return ptr + (n & 0x0FFFFFFF); +} + +void Expression::skipExpr(char stopToken) { + int16 dimCount; + byte operation; + int16 num; + int16 dim; + + num = 0; + while (true) { + operation = _vm->_game->_script->readByte(); + + if ((operation >= 14) && (operation <= OP_FUNC)) { + switch (operation) { + case 14: + _vm->_game->_script->skip(4); + if (_vm->_game->_script->peekByte() == 97) + _vm->_game->_script->skip(1); + break; + + case OP_LOAD_VAR_INT16: + case OP_LOAD_VAR_INT8: + case OP_LOAD_IMM_INT16: + case OP_LOAD_VAR_INT32: + case OP_LOAD_VAR_INT32_AS_INT16: + _vm->_game->_script->skip(2); + break; + + case OP_LOAD_IMM_INT32: + _vm->_game->_script->skip(4); + break; + + case OP_LOAD_IMM_INT8: + _vm->_game->_script->skip(1); + break; + + case OP_LOAD_IMM_STR: + _vm->_game->_script->skip(strlen(_vm->_game->_script->peekString()) + 1); + break; + + case OP_LOAD_VAR_STR: + _vm->_game->_script->skip(2); + if (_vm->_game->_script->peekByte() == 13) { + _vm->_game->_script->skip(1); + skipExpr(OP_END_MARKER); + } + break; + + case 15: + _vm->_game->_script->skip(2); + + case OP_ARRAY_INT8: + case OP_ARRAY_INT32: + case OP_ARRAY_INT16: + case OP_ARRAY_STR: + dimCount = _vm->_game->_script->peekByte(2); + // skip header and dimensions + _vm->_game->_script->skip(3 + dimCount); + // skip indices + for (dim = 0; dim < dimCount; dim++) + skipExpr(OP_END_MARKER); + + if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) { + _vm->_game->_script->skip(1); + skipExpr(OP_END_MARKER); + } + break; + + case OP_FUNC: + _vm->_game->_script->skip(1); + skipExpr(OP_END_EXPR); + } + continue; + } // if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) + + if (operation == OP_BEGIN_EXPR) { + num++; + continue; + } + + if ((operation == OP_NOT) || ((operation >= OP_NEG) && (operation <= 8))) + continue; + + if ((operation >= OP_OR) && (operation <= OP_NEQ)) + continue; + + if (operation == OP_END_EXPR) + num--; + + if (operation != stopToken) + continue; + + if ((stopToken != OP_END_EXPR) || (num < 0)) + return; + } +} + +void Expression::printExpr(char stopToken) { + // Expression printing disabled by default + return; + + int32 savedPos = _vm->_game->_script->pos(); + printExpr_internal(stopToken); + + // restore IP to start of expression + _vm->_game->_script->seek(savedPos); +} + +void Expression::printExpr_internal(char stopToken) { + int16 dimCount; + byte operation; + int16 num; + int16 dim; + byte *arrDesc; + byte func; + + num = 0; + while (true) { + operation = _vm->_game->_script->readByte(); + + if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) { + // operands + + switch (operation) { + case OP_LOAD_VAR_INT16: // int16 variable load + debugN(5, "var16_%d", _vm->_game->_script->readUint16()); + break; + + case OP_LOAD_VAR_INT8: // int8 variable load: + debugN(5, "var8_%d", _vm->_game->_script->readUint16()); + break; + + case OP_LOAD_IMM_INT32: // int32/uint32 immediate + debugN(5, "%d", _vm->_game->_script->readInt32()); + break; + + case OP_LOAD_IMM_INT16: // int16 immediate + debugN(5, "%d", _vm->_game->_script->readInt16()); + break; + + case OP_LOAD_IMM_INT8: // int8 immediate + debugN(5, "%d", _vm->_game->_script->readInt8()); + break; + + case OP_LOAD_IMM_STR: // string immediate + debugN(5, "\42%s\42", _vm->_game->_script->readString()); + break; + + case OP_LOAD_VAR_INT32: + case OP_LOAD_VAR_INT32_AS_INT16: + debugN(5, "var_%d", _vm->_game->_script->readUint16()); + break; + + case OP_LOAD_VAR_STR: // string variable load + debugN(5, "(&var_%d)", _vm->_game->_script->readUint16()); + if (_vm->_game->_script->peekByte() == 13) { + _vm->_game->_script->skip(1); + debugN(5, "{"); + printExpr_internal(OP_END_MARKER); // this also prints the closing } + } + break; + + case OP_ARRAY_INT8: // int8 array access + case OP_ARRAY_INT32: // int32 array access + case OP_ARRAY_INT16: // int16 array access + case OP_ARRAY_STR: // string array access + debugN(5, "\n"); + if (operation == OP_ARRAY_STR) + debugN(5, "(&"); + + debugN(5, "var_%d[", _vm->_game->_script->readInt16()); + dimCount = _vm->_game->_script->readByte(); + arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos(); + _vm->_game->_script->skip(dimCount); + for (dim = 0; dim < dimCount; dim++) { + printExpr_internal(OP_END_MARKER); + debugN(5, " of %d", (int16) arrDesc[dim]); + if (dim != dimCount - 1) + debugN(5, ","); + } + debugN(5, "]"); + if (operation == OP_ARRAY_STR) + debugN(5, ")"); + + if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) { + _vm->_game->_script->skip(1); + debugN(5, "{"); + printExpr_internal(OP_END_MARKER); // this also prints the closing } + } + break; + + case OP_FUNC: // function + func = _vm->_game->_script->readByte(); + if (func == FUNC_SQR) + debugN(5, "sqr("); + else if (func == FUNC_RAND) + debugN(5, "rand("); + else if (func == FUNC_ABS) + debugN(5, "abs("); + else if ((func == FUNC_SQRT1) || (func == FUNC_SQRT2) || (func == FUNC_SQRT3)) + debugN(5, "sqrt("); + else + debugN(5, "id("); + printExpr_internal(OP_END_EXPR); + break; + } + continue; + } // if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) + + // operators + switch (operation) { + case OP_BEGIN_EXPR: + debugN(5, "("); + break; + + case OP_NOT: + debugN(5, "!"); + break; + + case OP_END_EXPR: + debugN(5, ")"); + break; + + case OP_NEG: + debugN(5, "-"); + break; + + case OP_ADD: + debugN(5, "+"); + break; + + case OP_SUB: + debugN(5, "-"); + break; + + case OP_BITOR: + debugN(5, "|"); + break; + + case OP_MUL: + debugN(5, "*"); + break; + + case OP_DIV: + debugN(5, "/"); + break; + + case OP_MOD: + debugN(5, "%%"); + break; + + case OP_BITAND: + debugN(5, "&"); + break; + + case OP_OR: + debugN(5, "||"); + break; + + case 31: + debugN(5, "&&"); + break; + + case OP_LESS: + debugN(5, "<"); + break; + + case OP_LEQ: + debugN(5, "<="); + break; + + case OP_GREATER: + debugN(5, ">"); + break; + + case OP_GEQ: + debugN(5, ">="); + break; + + case OP_EQ: + debugN(5, "=="); + break; + + case OP_NEQ: + debugN(5, "!="); + break; + + case 99: + debugN(5, "\n"); + break; + + case OP_END_MARKER: + debugN(5, "}"); + if (stopToken != OP_END_MARKER) { + debugN(5, "Closing paren without opening?"); + } + break; + + default: + debugN(5, "<%d>", (int16) operation); + error("Expression::printExpr(): invalid operator in expression"); + break; + } + + if (operation == OP_BEGIN_EXPR) { + num++; + continue; + } + + if ((operation == OP_NOT) || ((operation >= OP_NEG) && (operation <= 8))) + continue; + + if ((operation >= OP_OR) && (operation <= OP_NEQ)) + continue; + + if (operation == OP_END_EXPR) + num--; + + if (operation == stopToken) { + if ((stopToken != OP_END_EXPR) || (num < 0)) { + return; + } + } + } +} + + +void Expression::printVarIndex() { + byte *arrDesc; + int16 dim; + int16 dimCount; + int16 operation; + int16 temp; + + int32 pos = _vm->_game->_script->pos(); + + operation = _vm->_game->_script->readByte(); + switch (operation) { + case OP_LOAD_VAR_INT32: + case OP_LOAD_VAR_STR: + temp = _vm->_game->_script->readUint16() * 4; + debugN(5, "&var_%d", temp); + if ((operation == OP_LOAD_VAR_STR) && (_vm->_game->_script->peekByte() == 13)) { + _vm->_game->_script->skip(1); + debugN(5, "+"); + printExpr(OP_END_MARKER); + } + break; + + case OP_ARRAY_INT32: + case OP_ARRAY_STR: + debugN(5, "&var_%d[", _vm->_game->_script->readUint16()); + dimCount = _vm->_game->_script->readByte(); + arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos(); + _vm->_game->_script->skip(dimCount); + for (dim = 0; dim < dimCount; dim++) { + printExpr(OP_END_MARKER); + debugN(5, " of %d", (int16) arrDesc[dim]); + if (dim != dimCount - 1) + debugN(5, ","); + } + debugN(5, "]"); + + if ((operation == OP_ARRAY_STR) && (_vm->_game->_script->peekByte() == 13)) { + _vm->_game->_script->skip(1); + debugN(5, "+"); + printExpr(OP_END_MARKER); + } + break; + + default: + debugN(5, "var_0"); + break; + } + debugN(5, "\n"); + + _vm->_game->_script->seek(pos); + return; +} + +int Expression::cmpHelper(const StackFrame &stackFrame) { + byte type = stackFrame.opers[-3]; + int cmpTemp = 0; + + if (type == OP_LOAD_IMM_INT16) { + cmpTemp = (int)stackFrame.values[-3] - (int)stackFrame.values[-1]; + } else if (type == OP_LOAD_IMM_STR) { + if ((char *)decodePtr(stackFrame.values[-3]) != _resultStr) { + strcpy(_resultStr, (char *)decodePtr(stackFrame.values[-3])); + stackFrame.values[-3] = encodePtr((byte *) _resultStr, kResStr); + } + cmpTemp = strcmp(_resultStr, (char *)decodePtr(stackFrame.values[-1])); + } + + return cmpTemp; +} + +bool Expression::getVarBase(uint32 &varBase, bool mindStop, + uint16 *size, uint16 *type) { + + varBase = 0; + + byte operation = _vm->_game->_script->peekByte(); + while ((operation == 14) || (operation == 15)) { + _vm->_game->_script->skip(1); + + if (operation == 14) { + // Add a direct offset + + varBase += _vm->_game->_script->readInt16() * 4; + + if (size) + *size = _vm->_game->_script->peekUint16(); + if (type) + *type = 14; + + _vm->_game->_script->skip(2); + + debugC(2, kDebugExpression, "varBase: %d, by %d", varBase, operation); + + if (_vm->_game->_script->peekByte() != 97) { + if (mindStop) + return true; + } else + _vm->_game->_script->skip(1); + + } else if (operation == 15) { + // Add an offset from an array + + varBase += _vm->_game->_script->readInt16() * 4; + + uint16 offset1 = _vm->_game->_script->readUint16(); + + if (size) + *size = offset1; + if (type) + *type = 15; + + uint8 dimCount = _vm->_game->_script->readByte(); + byte *dimArray = _vm->_game->_script->getData() + _vm->_game->_script->pos(); + + _vm->_game->_script->skip(dimCount); + + uint16 offset2 = 0; + for (int i = 0; i < dimCount; i++) { + int16 dim = CLIP<int>(parseValExpr(OP_END_MARKER), 0, dimArray[i] - 1); + + offset2 = offset2 * dimArray[i] + dim; + } + + varBase += offset2 * offset1 * 4; + + debugC(2, kDebugExpression, "varBase: %d, by %d", varBase, operation); + + if (_vm->_game->_script->peekByte() != 97) { + if (mindStop) + return true; + } else + _vm->_game->_script->skip(1); + } + + operation = _vm->_game->_script->peekByte(); + } + + return false; +} + +int16 Expression::parseVarIndex(uint16 *size, uint16 *type) { + int16 temp2; + byte *arrDesc; + int16 dim; + int16 dimCount; + int16 operation; + int16 temp; + int16 offset; + int16 val; + uint32 varBase; + + if (getVarBase(varBase, true, size, type)) + return varBase; + + operation = _vm->_game->_script->readByte(); + + if (size) + *size = 0; + if (type) + *type = operation; + + debugC(5, kDebugExpression, "var parse = %d", operation); + switch (operation) { + case OP_ARRAY_INT8: + case OP_ARRAY_INT32: + case OP_ARRAY_INT16: + case OP_ARRAY_STR: + temp = _vm->_game->_script->readInt16(); + dimCount = _vm->_game->_script->readByte(); + arrDesc = _vm->_game->_script->getData() + _vm->_game->_script->pos(); + _vm->_game->_script->skip(dimCount); + offset = 0; + for (dim = 0; dim < dimCount; dim++) { + temp2 = parseValExpr(OP_END_MARKER); + offset = arrDesc[dim] * offset + temp2; + } + if (operation == OP_ARRAY_INT8) + return varBase + temp + offset; + if (operation == OP_ARRAY_INT32) + return varBase + (temp + offset) * 4; + if (operation == OP_ARRAY_INT16) + return varBase + (temp + offset) * 2; + temp *= 4; + offset *= 4; + if (_vm->_game->_script->peekByte() == 13) { + _vm->_game->_script->skip(1); + temp += parseValExpr(OP_END_MARKER); + } + return varBase + offset * _vm->_global->_inter_animDataSize + temp; + + case OP_LOAD_VAR_INT16: + return varBase + _vm->_game->_script->readInt16() * 2; + + case OP_LOAD_VAR_INT8: + return varBase + _vm->_game->_script->readInt16(); + + case OP_LOAD_VAR_INT32: + case OP_LOAD_VAR_INT32_AS_INT16: + case OP_LOAD_VAR_STR: + temp = _vm->_game->_script->readInt16() * 4; + debugC(5, kDebugExpression, "oper = %d", _vm->_game->_script->peekInt16()); + if ((operation == OP_LOAD_VAR_STR) && (_vm->_game->_script->peekByte() == 13)) { + _vm->_game->_script->skip(1); + val = parseValExpr(OP_END_MARKER); + temp += val; + debugC(5, kDebugExpression, "parse subscript = %d", val); + } + return varBase + temp; + + default: + return 0; + } +} + +int16 Expression::parseValExpr(byte stopToken) { + parseExpr(stopToken, 0); + + return _resultInt; +} + +// Load a value according to the operation +void Expression::loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame) { + int16 dimCount; + int16 temp; + int16 temp2; + int16 offset; + int16 dim; + byte *arrDescPtr; + int32 prevPrevVal; + int32 prevVal; + int32 curVal; + + switch (operation) { + case OP_ARRAY_INT8: + case OP_ARRAY_INT32: + case OP_ARRAY_INT16: + case OP_ARRAY_STR: + *stackFrame.opers = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16; + temp = _vm->_game->_script->readInt16(); + dimCount = _vm->_game->_script->readByte(); + arrDescPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos(); + _vm->_game->_script->skip(dimCount); + offset = 0; + for (dim = 0; dim < dimCount; dim++) { + temp2 = parseValExpr(OP_END_MARKER); + offset = offset * arrDescPtr[dim] + temp2; + } + if (operation == OP_ARRAY_INT8) + *stackFrame.values = (int8) READ_VARO_UINT8(varBase + temp + offset); + else if (operation == OP_ARRAY_INT32) + *stackFrame.values = READ_VARO_UINT32(varBase + temp * 4 + offset * 4); + else if (operation == OP_ARRAY_INT16) + *stackFrame.values = (int16) READ_VARO_UINT16(varBase + temp * 2 + offset * 2); + else if (operation == OP_ARRAY_STR) { + *stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8( + varBase + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), + kInterVar); + if (_vm->_game->_script->peekByte() == 13) { + _vm->_game->_script->skip(1); + temp2 = parseValExpr(OP_END_MARKER); + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = READ_VARO_UINT8(varBase + temp * 4 + + offset * 4 * _vm->_global->_inter_animDataSize + temp2); + } + } + break; + + case OP_LOAD_VAR_INT16: + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readInt16() * 2); + break; + + case OP_LOAD_VAR_INT8: + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = (int8) READ_VARO_UINT8(varBase + _vm->_game->_script->readInt16()); + break; + + case OP_LOAD_IMM_INT32: + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = _vm->_game->_script->readInt32(); + break; + + case OP_LOAD_IMM_INT16: + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = _vm->_game->_script->readInt16(); + break; + + case OP_LOAD_IMM_INT8: + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = _vm->_game->_script->readInt8(); + break; + + case OP_LOAD_IMM_STR: + *stackFrame.opers = OP_LOAD_IMM_STR; + *stackFrame.values = encodePtr((byte *) _vm->_game->_script->readString(), kExecPtr); + break; + + case OP_LOAD_VAR_INT32: + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = READ_VARO_UINT32(varBase + _vm->_game->_script->readInt16() * 4); + break; + + case OP_LOAD_VAR_INT32_AS_INT16: + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = (int16) READ_VARO_UINT16(varBase + _vm->_game->_script->readInt16() * 4); + break; + + case OP_LOAD_VAR_STR: + *stackFrame.opers = OP_LOAD_IMM_STR; + temp = _vm->_game->_script->readInt16() * 4; + *stackFrame.values = encodePtr(_vm->_inter->_variables->getAddressOff8(varBase + temp), kInterVar); + if (_vm->_game->_script->peekByte() == 13) { + _vm->_game->_script->skip(1); + temp += parseValExpr(OP_END_MARKER); + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = READ_VARO_UINT8(varBase + temp); + } + break; + + case OP_FUNC: + operation = _vm->_game->_script->readByte(); + parseExpr(OP_END_EXPR, 0); + + switch (operation) { + case FUNC_SQRT1: + case FUNC_SQRT2: + case FUNC_SQRT3: + curVal = 1; + prevVal = 1; + + do { + prevPrevVal = prevVal; + prevVal = curVal; + curVal = (curVal + _resultInt / curVal) / 2; + } while ((curVal != prevVal) && (curVal != prevPrevVal)); + _resultInt = curVal; + break; + + case FUNC_SQR: + _resultInt = + _resultInt * _resultInt; + break; + + case FUNC_ABS: + if (_resultInt < 0) + _resultInt = -_resultInt; + break; + + case FUNC_RAND: + _resultInt = + _vm->_util->getRandom(_resultInt); + break; + } + + *stackFrame.opers = OP_LOAD_IMM_INT16; + *stackFrame.values = _resultInt; + break; + } +} + +void Expression::simpleArithmetic1(StackFrame &stackFrame) { + switch (stackFrame.opers[-1]) { + case OP_ADD: + if (stackFrame.opers[-2] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(stackFrame.values[-2]) != _resultStr) { + strcpy(_resultStr, (char *) decodePtr(stackFrame.values[-2])); + stackFrame.values[-2] = encodePtr((byte *) _resultStr, kResStr); + } + strcat(_resultStr, (char *) decodePtr(stackFrame.values[0])); + stackFrame.pop(2); + } + break; + + case OP_MUL: + stackFrame.values[-2] *= stackFrame.values[0]; + stackFrame.pop(2); + break; + + case OP_DIV: + stackFrame.values[-2] /= stackFrame.values[0]; + stackFrame.pop(2); + break; + + case OP_MOD: + stackFrame.values[-2] %= stackFrame.values[0]; + stackFrame.pop(2); + break; + + case OP_BITAND: + stackFrame.values[-2] &= stackFrame.values[0]; + stackFrame.pop(2); + break; + } +} + +void Expression::simpleArithmetic2(StackFrame &stackFrame) { + if (stackFrame.pos > 1) { + if (stackFrame.opers[-2] == OP_NEG) { + stackFrame.opers[-2] = OP_LOAD_IMM_INT16; + stackFrame.values[-2] = -stackFrame.values[-1]; + stackFrame.pop(); + } else if (stackFrame.opers[-2] == OP_NOT) { + stackFrame.opers[-2] = (stackFrame.opers[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; + stackFrame.pop(); + } + } + + if (stackFrame.pos > 2) { + switch (stackFrame.opers[-2]) { + case OP_MUL: + stackFrame.values[-3] *= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_DIV: + stackFrame.values[-3] /= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_MOD: + stackFrame.values[-3] %= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_BITAND: + stackFrame.values[-3] &= stackFrame.values[-1]; + stackFrame.pop(2); + break; + } + } + +} + +// Complex arithmetics with brackets +bool Expression::complexArithmetic(Stack &stack, StackFrame &stackFrame, int16 brackStart) { + switch (stackFrame.opers[-2]) { + case OP_ADD: + if (stack.opers[brackStart] == OP_LOAD_IMM_INT16) { + stack.values[brackStart] += stackFrame.values[-1]; + } else if (stack.opers[brackStart] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(stack.values[brackStart]) != _resultStr) { + strcpy(_resultStr, (char *) decodePtr(stack.values[brackStart])); + stack.values[brackStart] = + encodePtr((byte *) _resultStr, kResStr); + } + strcat(_resultStr, (char *) decodePtr(stackFrame.values[-1])); + } + stackFrame.pop(2); + break; + + case OP_SUB: + stack.values[brackStart] -= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_BITOR: + stack.values[brackStart] |= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_MUL: + stackFrame.values[-3] *= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_DIV: + stackFrame.values[-3] /= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_MOD: + stackFrame.values[-3] %= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_BITAND: + stackFrame.values[-3] &= stackFrame.values[-1]; + stackFrame.pop(2); + break; + + case OP_OR: + // (x OR false) == x + // (x OR true) == true + if (stackFrame.opers[-3] == GOB_FALSE) + stackFrame.opers[-3] = stackFrame.opers[-1]; + stackFrame.pop(2); + break; + + case OP_AND: + // (x AND false) == false + // (x AND true) == x + if (stackFrame.opers[-3] == GOB_TRUE) + stackFrame.opers[-3] = stackFrame.opers[-1]; + stackFrame.pop(2); + break; + + case OP_LESS: + stackFrame.opers[-3] = (cmpHelper(stackFrame) < 0) ? GOB_TRUE : GOB_FALSE; + stackFrame.pop(2); + break; + + case OP_LEQ: + stackFrame.opers[-3] = (cmpHelper(stackFrame) <= 0) ? GOB_TRUE : GOB_FALSE; + stackFrame.pop(2); + break; + + case OP_GREATER: + stackFrame.opers[-3] = (cmpHelper(stackFrame) > 0) ? GOB_TRUE : GOB_FALSE; + stackFrame.pop(2); + break; + + case OP_GEQ: + stackFrame.opers[-3] = (cmpHelper(stackFrame) >= 0) ? GOB_TRUE : GOB_FALSE; + stackFrame.pop(2); + break; + + case OP_EQ: + stackFrame.opers[-3] = (cmpHelper(stackFrame) == 0) ? GOB_TRUE : GOB_FALSE; + stackFrame.pop(2); + break; + + case OP_NEQ: + stackFrame.opers[-3] = (cmpHelper(stackFrame) != 0) ? GOB_TRUE : GOB_FALSE; + stackFrame.pop(2); + break; + + default: + return true; + } + + return false; +} + +// Assign the result to the appropriate _result variable +void Expression::getResult(byte operation, int32 value, byte *type) { + if (type != 0) + *type = operation; + + switch (operation) { + case OP_NOT: + if (type != 0) + *type ^= 1; + break; + + case OP_LOAD_IMM_INT16: + _resultInt = value; + break; + + case OP_LOAD_IMM_STR: + if ((char *) decodePtr(value) != _resultStr) + strcpy(_resultStr, (char *) decodePtr(value)); + break; + + case OP_LOAD_VAR_INT32: + case OP_LOAD_VAR_INT32_AS_INT16: + break; + + default: + _resultInt = 0; + if (type != 0) + *type = OP_LOAD_IMM_INT16; + break; + } +} + +int16 Expression::parseExpr(byte stopToken, byte *type) { + Stack stack; + StackFrame stackFrame(stack); + byte operation; + bool escape; + int16 brackStart; + uint32 varBase; + + while (true) { + getVarBase(varBase); + + stackFrame.push(); + + operation = _vm->_game->_script->readByte(); + if ((operation >= OP_ARRAY_INT8) && (operation <= OP_FUNC)) { + + loadValue(operation, varBase, stackFrame); + + if ((stackFrame.pos > 0) && ((stackFrame.opers[-1] == OP_NEG) || (stackFrame.opers[-1] == OP_NOT))) { + stackFrame.pop(); + + if (*stackFrame.opers == OP_NEG) { + *stackFrame.opers = OP_LOAD_IMM_INT16; + stackFrame.values[0] = -stackFrame.values[1]; + } else + *stackFrame.opers = (stackFrame.opers[1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; + } + + if (stackFrame.pos <= 0) + continue; + + simpleArithmetic1(stackFrame); + + continue; + } // (op >= OP_ARRAY_INT8) && (op <= OP_FUNC) + + if ((operation == stopToken) || (operation == OP_OR) || + (operation == OP_AND) || (operation == OP_END_EXPR)) { + while (stackFrame.pos >= 2) { + escape = false; + if ((stackFrame.opers[-2] == OP_BEGIN_EXPR) && + ((operation == OP_END_EXPR) || (operation == stopToken))) { + stackFrame.opers[-2] = stackFrame.opers[-1]; + if ((stackFrame.opers[-2] == OP_LOAD_IMM_INT16) || (stackFrame.opers[-2] == OP_LOAD_IMM_STR)) + stackFrame.values[-2] = stackFrame.values[-1]; + + stackFrame.pop(); + + simpleArithmetic2(stackFrame); + + if (operation != stopToken) + break; + } // if ((stackFrame.opers[-2] == OP_BEGIN_EXPR) && ...) + + for (brackStart = (stackFrame.pos - 2); (brackStart > 0) && + (stack.opers[brackStart] < OP_OR) && (stack.opers[brackStart] != OP_BEGIN_EXPR); + brackStart--) + ; + + if ((stack.opers[brackStart] >= OP_OR) || (stack.opers[brackStart] == OP_BEGIN_EXPR)) + brackStart++; + + if (complexArithmetic(stack, stackFrame, brackStart)) + break; + + } // while (stackFrame.pos >= 2) + + if ((operation == OP_OR) || (operation == OP_AND)) { + if (stackFrame.opers[-1] == OP_LOAD_IMM_INT16) { + if (stackFrame.values[-1] != 0) + stackFrame.opers[-1] = GOB_TRUE; + else + stackFrame.opers[-1] = GOB_FALSE; + } + + if (((operation == OP_OR) && (stackFrame.opers[-1] == GOB_TRUE)) || + ((operation == OP_AND) && (stackFrame.opers[-1] == GOB_FALSE))) { + if ((stackFrame.pos > 1) && (stackFrame.opers[-2] == OP_BEGIN_EXPR)) { + skipExpr(OP_END_EXPR); + stackFrame.opers[-2] = stackFrame.opers[-1]; + stackFrame.pop(2); + } else { + skipExpr(stopToken); + } + operation = _vm->_game->_script->peekByte(-1); + if ((stackFrame.pos > 0) && (stackFrame.opers[-1] == OP_NOT)) { + if (stackFrame.opers[0] == GOB_FALSE) + stackFrame.opers[-1] = GOB_TRUE; + else + stackFrame.opers[-1] = GOB_FALSE; + + stackFrame.pop(); + } + } else + stackFrame.opers[0] = operation; + } else + stackFrame.pop(); + + if (operation != stopToken) + continue; + + getResult(stack.opers[0], stack.values[0], type); + + return 0; + } // (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR) + + if ((operation < OP_NEG) || (operation > OP_NOT)) { + if ((operation < OP_LESS) || (operation > OP_NEQ)) + continue; + + if (stackFrame.pos > 2) { + if (stackFrame.opers[-2] == OP_ADD) { + if (stackFrame.opers[-3] == OP_LOAD_IMM_INT16) { + stackFrame.values[-3] += stackFrame.values[-1]; + } else if (stackFrame.opers[-3] == OP_LOAD_IMM_STR) { + if ((char *) decodePtr(stackFrame.values[-3]) != _resultStr) { + strcpy(_resultStr, (char *) decodePtr(stackFrame.values[-3])); + stackFrame.values[-3] = encodePtr((byte *) _resultStr, kResStr); + } + strcat(_resultStr, (char *) decodePtr(stackFrame.values[-1])); + } + stackFrame.pop(2); + + } else if (stackFrame.opers[-2] == OP_SUB) { + stackFrame.values[-3] -= stackFrame.values[-1]; + stackFrame.pop(2); + } else if (stackFrame.opers[-2] == OP_BITOR) { + stackFrame.values[-3] |= stackFrame.values[-1]; + stackFrame.pop(2); + } + } + } + *stackFrame.opers = operation; + } +} + +int32 Expression::getResultInt() { + return _resultInt; +} + +char *Expression::getResultStr() { + return _resultStr; +} + +} // End of namespace Gob diff --git a/engines/gob/expression.h b/engines/gob/expression.h new file mode 100644 index 0000000000..894704e2a9 --- /dev/null +++ b/engines/gob/expression.h @@ -0,0 +1,178 @@ +/* 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_EXPRESSION_H +#define GOB_EXPRESSION_H + +#include "common/scummsys.h" + +namespace Gob { + +class GobEngine; + +enum { + OP_NEG = 1, + OP_ADD = 2, + OP_SUB = 3, + OP_BITOR = 4, + OP_MUL = 5, + OP_DIV = 6, + OP_MOD = 7, + OP_BITAND = 8, + OP_BEGIN_EXPR = 9, + OP_END_EXPR = 10, + OP_NOT = 11, + + OP_END_MARKER = 12, // Marks end of an array or string + + + OP_ARRAY_INT8 = 16, + OP_LOAD_VAR_INT16 = 17, + OP_LOAD_VAR_INT8 = 18, + OP_LOAD_IMM_INT32 = 19, + OP_LOAD_IMM_INT16 = 20, + OP_LOAD_IMM_INT8 = 21, + OP_LOAD_IMM_STR = 22, + OP_LOAD_VAR_INT32 = 23, + OP_LOAD_VAR_INT32_AS_INT16 = 24, + OP_LOAD_VAR_STR = 25, + OP_ARRAY_INT32 = 26, + OP_ARRAY_INT16 = 27, + OP_ARRAY_STR = 28, + + OP_FUNC = 29, + + OP_OR = 30, // Logical OR + OP_AND = 31, // Logical AND + OP_LESS = 32, + OP_LEQ = 33, + OP_GREATER = 34, + OP_GEQ = 35, + OP_EQ = 36, + OP_NEQ = 37 +}; + +enum { + FUNC_SQRT1 = 0, + FUNC_SQRT2 = 1, + FUNC_SQRT3 = 6, + + FUNC_SQR = 5, + FUNC_ABS = 7, + FUNC_RAND = 10 +}; + +enum { + TYPE_IMM_INT8 = OP_LOAD_IMM_INT8, // 21 + TYPE_IMM_INT32 = OP_LOAD_IMM_INT32, // 19 + TYPE_IMM_INT16 = OP_LOAD_IMM_INT16, // 20 + TYPE_IMM_STR = OP_LOAD_IMM_STR, // 22 + TYPE_VAR_INT8 = OP_LOAD_VAR_INT8, // 18 + TYPE_VAR_INT16 = OP_LOAD_VAR_INT16, // 17 + TYPE_VAR_INT32 = OP_LOAD_VAR_INT32, // 23 + TYPE_VAR_STR = OP_LOAD_VAR_STR, // 25 + TYPE_ARRAY_INT8 = OP_ARRAY_INT8, // 16 + TYPE_ARRAY_INT16 = OP_ARRAY_INT16, // 27 + TYPE_ARRAY_INT32 = OP_ARRAY_INT32, // 26 + TYPE_ARRAY_STR = OP_ARRAY_STR, // 28 + TYPE_VAR_INT32_AS_INT16 = OP_LOAD_VAR_INT32_AS_INT16 // 24 +}; + +enum { + // FIXME: The following two 'truth values' are stored inside the list + // of "operators". So they somehow coincide with OP_LOAD_VAR_INT32 + // and OP_LOAD_VAR_INT32_AS_INT16. I haven't yet quite understood + // how, resp. what that means. You have been warned. + GOB_TRUE = 24, + GOB_FALSE = 23 +}; + +class Expression { +public: + Expression(GobEngine *vm); + virtual ~Expression() {} + + void skipExpr(char stopToken); + void printExpr(char stopToken); + void printVarIndex(void); + + int16 parseVarIndex(uint16 *size = 0, uint16 *type = 0); + int16 parseValExpr(byte stopToken = 99); + int16 parseExpr(byte stopToken, byte *type); + + int32 getResultInt(); + char *getResultStr(); + +private: + class Stack { + public: + byte *opers; + int32 *values; + + Stack(size_t size = 20); + ~Stack(); + }; + class StackFrame { + public: + byte *opers; + int32 *values; + int16 pos; + + StackFrame(const Stack &stack); + + void push(int count = 1); + void pop(int count = 1); + }; + + enum PointerType { + kExecPtr = 0, + kInterVar = 1, + kResStr = 2 + }; + + GobEngine *_vm; + + int32 _resultInt; + char _resultStr[200]; + + int32 encodePtr(byte *ptr, int type); + byte *decodePtr(int32 n); + + void printExpr_internal(char stopToken); + + bool getVarBase(uint32 &varBase, bool mindStop = false, + uint16 *size = 0, uint16 *type = 0); + int cmpHelper(const StackFrame &stackFrame); + void loadValue(byte operation, uint32 varBase, const StackFrame &stackFrame); + + void simpleArithmetic1(StackFrame &stackFrame); + void simpleArithmetic2(StackFrame &stackFrame); + bool complexArithmetic(Stack &stack, StackFrame &stackFrame, int16 brackStart); + void getResult(byte operation, int32 value, byte *type); +}; + +} // End of namespace Gob + +#endif // GOB_EXPRESSION_H diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index d5c81098cc..5771ee9f76 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -31,8 +31,10 @@ #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/inter.h" -#include "gob/parse.h" #include "gob/draw.h" #include "gob/mult.h" #include "gob/videoplayer.h" @@ -40,21 +42,139 @@ namespace Gob { +Environments::Environments(GobEngine *vm) : _vm(vm) { + _environments = new Environment[kEnvironmentCount]; + + for (uint i = 0; i < kEnvironmentCount; i++) { + Environment &e = _environments[i]; + + e.cursorHotspotX = 0; + e.cursorHotspotY = 0; + e.variables = 0; + e.script = 0; + e.resources = 0; + e.curTotFile[0] = '\0'; + } +} + +Environments::~Environments() { + clear(); + + delete[] _environments; +} + +void Environments::clear() { + // Deleting unique variables, script and resources + + for (uint i = 0; i < kEnvironmentCount; i++) { + if (_environments[i].variables == _vm->_inter->_variables) + continue; + + if (!has(_environments[i].variables, i + 1)) + delete _environments[i].variables; + } + + for (uint i = 0; i < kEnvironmentCount; i++) { + if (_environments[i].script == _vm->_game->_script) + continue; + + if (!has(_environments[i].script, i + 1)) + delete _environments[i].script; + } + + for (uint i = 0; i < kEnvironmentCount; i++) { + if (_environments[i].resources == _vm->_game->_resources) + continue; + + if (!has(_environments[i].resources, i + 1)) + delete _environments[i].resources; + } +} + +void Environments::set(uint8 env) { + if (env >= kEnvironmentCount) + return; + + Environment &e = _environments[env]; + + // If it already has a unique script or resource assigned, delete them + if ((e.script != _vm->_game->_script) && !has(e.script, 0, env)) + delete e.script; + if ((e.resources != _vm->_game->_resources) && !has(e.resources, 0, env)) + delete e.resources; + + e.cursorHotspotX = _vm->_draw->_cursorHotspotXVar; + e.cursorHotspotY = _vm->_draw->_cursorHotspotYVar; + e.script = _vm->_game->_script; + e.resources = _vm->_game->_resources; + e.variables = _vm->_inter->_variables; + strncpy(e.curTotFile, _vm->_game->_curTotFile, 14); +} + +void Environments::get(uint8 env) const { + if (env >= kEnvironmentCount) + return; + + const Environment &e = _environments[env]; + + _vm->_draw->_cursorHotspotXVar = e.cursorHotspotX; + _vm->_draw->_cursorHotspotYVar = e.cursorHotspotY; + _vm->_game->_script = e.script; + _vm->_game->_resources = e.resources; + _vm->_inter->_variables = e.variables; + strncpy(_vm->_game->_curTotFile, e.curTotFile, 14); +} + +const char *Environments::getTotFile(uint8 env) const { + if (env >= kEnvironmentCount) + return ""; + + return _environments[env].curTotFile; +} + +bool Environments::has(Variables *variables, uint8 startEnv, int16 except) const { + for (uint i = startEnv; i < kEnvironmentCount; i++) { + if ((except >= 0) && (((uint16) except) == i)) + continue; + + if (_environments[i].variables == variables) + return true; + } + + return false; +} + +bool Environments::has(Script *script, uint8 startEnv, int16 except) const { + for (uint i = startEnv; i < kEnvironmentCount; i++) { + if ((except >= 0) && (((uint16) except) == i)) + continue; + + if (_environments[i].script == script) + return true; + } + + return false; +} + +bool Environments::has(Resources *resources, uint8 startEnv, int16 except) const { + for (uint i = startEnv; i < kEnvironmentCount; i++) { + if ((except >= 0) && (((uint16) except) == i)) + continue; + + if (_environments[i].resources == resources) + return true; + } + + return false; +} + + Game::Game(GobEngine *vm) : _vm(vm) { - _extTable = 0; - _totFileData = 0; - _totResourceTable = 0; - _imFileData = 0; - _extHandle = 0; - _lomHandle = -1; _collisionAreas = 0; _shouldPushColls = 0; _captureCount = 0; - _foundTotLoc = false; - _totTextData = 0; - _collStackSize = 0; for (int i = 0; i < 5; i++) { @@ -63,7 +183,6 @@ Game::Game(GobEngine *vm) : _vm(vm) { } _curTotFile[0] = 0; - _curExtFile[0] = 0; _totToLoad[0] = 0; _startTimeKey = 0; @@ -85,138 +204,20 @@ Game::Game(GobEngine *vm) : _vm(vm) { _noCd = false; _tempStr[0] = 0; - _curImaFile[0] = 0; _collStr[0] = 0; - _backupedCount = 0; - _curBackupPos = 0; + _numEnvironments = 0; + _curEnvironment = 0; - for (int i = 0; i < 5; i++) { - _cursorHotspotXArray[i] = 0; - _cursorHotspotYArray[i] = 0; - _totTextDataArray[i] = 0; - _totFileDataArray[i] = 0; - _totResourceTableArray[i] = 0; - _extTableArray[i] = 0; - _extHandleArray[i] = 0; - _imFileDataArray[i] = 0; - _variablesArray[i] = 0; - _curTotFileArray[i][0] = 0; - } + _environments = new Environments(_vm); + _script = new Script(_vm); + _resources = new Resources(_vm); } Game::~Game() { - delete[] _vm->_game->_totFileData; - if (_vm->_game->_totTextData) { - if (_vm->_game->_totTextData->items) - delete[] _vm->_game->_totTextData->items; - delete _vm->_game->_totTextData; - } - if (_vm->_game->_totResourceTable) { - delete[] _vm->_game->_totResourceTable->items; - delete _vm->_game->_totResourceTable; - } -} - -byte *Game::loadExtData(int16 itemId, int16 *pResWidth, - int16 *pResHeight, uint32 *dataSize) { - int16 commonHandle; - int16 itemsCount; - int32 offset; - uint32 size; - uint32 realSize; - ExtItem *item; - bool isPacked; - int16 handle; - int32 tableSize; - char path[20]; - byte *dataBuf; - byte *packedBuf; - byte *dataPtr; - - itemId -= 30000; - if (_extTable == 0) - return 0; - - commonHandle = -1; - itemsCount = _extTable->itemsCount; - item = &_extTable->items[itemId]; - tableSize = szGame_ExtTable + szGame_ExtItem * itemsCount; - - offset = item->offset; - size = item->size; - isPacked = (item->width & 0x8000) != 0; - - if ((pResWidth != 0) && (pResHeight != 0)) { - *pResWidth = item->width & 0x7FFF; - - if (*pResWidth & 0x4000) - size += 1 << 16; - if (*pResWidth & 0x2000) - size += 2 << 16; - if (*pResWidth & 0x1000) - size += 4 << 16; - - *pResWidth &= 0xFFF; - - *pResHeight = item->height; - debugC(7, kDebugFileIO, "loadExtData(%d, %d, %d)", - itemId, *pResWidth, *pResHeight); - } - - debugC(7, kDebugFileIO, "loadExtData(%d, 0, 0)", itemId); - - if (item->height == 0) - size += (item->width & 0x7FFF) << 16; - - debugC(7, kDebugFileIO, "size: %d off: %d", size, offset); - if (offset < 0) { - offset = -(offset + 1); - tableSize = 0; - _vm->_dataIO->closeData(_extHandle); - strcpy(path, "commun.ex1"); - path[strlen(path) - 1] = *(_totFileData + 0x3C) + '0'; - commonHandle = _vm->_dataIO->openData(path); - handle = commonHandle; - } else - handle = _extHandle; - - DataStream *stream = _vm->_dataIO->openAsStream(handle); - - debugC(7, kDebugFileIO, "off: %d size: %d", offset, tableSize); - stream->seek(offset + tableSize); - realSize = size; - if (isPacked) - dataBuf = new byte[size + 2]; - else - dataBuf = new byte[size]; - - dataPtr = dataBuf; - while (size > 32000) { - // BUG: huge->far conversion. Need normalization? - stream->read(dataPtr, 32000); - size -= 32000; - dataPtr += 32000; - } - stream->read(dataPtr, size); - - delete stream; - if (commonHandle != -1) { - _vm->_dataIO->closeData(commonHandle); - _extHandle = _vm->_dataIO->openData(_curExtFile); - } - - if (isPacked) { - packedBuf = dataBuf; - realSize = READ_LE_UINT32(packedBuf); - dataBuf = new byte[realSize]; - _vm->_dataIO->unpackData(packedBuf, dataBuf); - delete[] packedBuf; - } - - if (dataSize) - *dataSize = realSize; - return dataBuf; + delete _environments; + delete _script; + delete _resources; } void Game::freeCollision(int16 id) { @@ -281,39 +282,9 @@ void Game::capturePop(char doDraw) { _vm->_draw->freeSprite(30 + _captureCount); } -byte *Game::loadTotResource(int16 id, - int16 *dataSize, int16 *width, int16 *height) { - - TotResItem *itemPtr; - int32 offset; - - if (id >= _vm->_game->_totResourceTable->itemsCount) { - warning("Trying to load non-existent TOT resource (%s, %d/%d)", - _curTotFile, id, _totResourceTable->itemsCount - 1); - return 0; - } - - itemPtr = &_totResourceTable->items[id]; - offset = itemPtr->offset; - - if (dataSize) - *dataSize = itemPtr->size; - if (width) - *width = itemPtr->width; - if (height) - *height = itemPtr->height; - - if (offset < 0) { - offset = (-offset - 1) * 4; - return _imFileData + (int32) READ_LE_UINT32(_imFileData + offset); - } else - return _totResourceTable->dataPtr + szGame_TotResTable + - szGame_TotResItem * _totResourceTable->itemsCount + offset; -} - void Game::freeSoundSlot(int16 slot) { if (slot == -1) - slot = _vm->_parse->parseValExpr(); + slot = _vm->_game->_script->readValExpr(); _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot)); } @@ -416,104 +387,6 @@ int16 Game::adjustKey(int16 key) { return key - 0x20; } -int32 Game::loadTotFile(const char *path) { - int16 handle; - int32 size; - - _lomHandle = -1; - - size = -1; - handle = _vm->_dataIO->openData(path); - if (handle >= 0) { - - if (!scumm_stricmp(path + strlen(path) - 3, "LOM")) { - warning("Urban Stub: loadTotFile %s", path); - - _lomHandle = handle; - - DataStream *stream = _vm->_dataIO->openAsStream(handle); - - stream->seek(48); - size = stream->readUint32LE(); - stream->seek(0); - - _totFileData = new byte[size]; - stream->read(_totFileData, size); - - delete stream; - } else { - _vm->_dataIO->closeData(handle); - size = _vm->_dataIO->getDataSize(path); - _totFileData = _vm->_dataIO->getData(path); - } - - } else { - Common::MemoryReadStream *videoExtraData = _vm->_vidPlayer->getExtraData(path); - - if (videoExtraData) { - warning("Found \"%s\" in video file", path); - - size = videoExtraData->size(); - _totFileData = new byte[size]; - videoExtraData->read(_totFileData, size); - delete videoExtraData; - } else - _totFileData = 0; - } - - return size; -} - -void Game::loadExtTable(void) { - int16 count; - - // Function is correct. [sev] - - _extHandle = _vm->_dataIO->openData(_curExtFile); - if (_extHandle < 0) - return; - - DataStream *stream = _vm->_dataIO->openAsStream(_extHandle); - count = stream->readUint16LE(); - - stream->seek(0); - _extTable = new ExtTable; - _extTable->items = 0; - if (count) - _extTable->items = new ExtItem[count]; - - _extTable->itemsCount = stream->readUint16LE(); - _extTable->unknown = stream->readByte(); - - for (int i = 0; i < count; i++) { - _extTable->items[i].offset = stream->readUint32LE(); - _extTable->items[i].size = stream->readUint16LE(); - _extTable->items[i].width = stream->readUint16LE(); - _extTable->items[i].height = stream->readUint16LE(); - } - - delete stream; -} - -void Game::loadImFile(void) { - char path[20]; - int16 handle; - - if ((_totFileData[0x3D] != 0) && (_totFileData[0x3B] == 0)) - return; - - strcpy(path, "commun.im1"); - if (_totFileData[0x3B] != 0) - path[strlen(path) - 1] = '0' + _totFileData[0x3B]; - - handle = _vm->_dataIO->openData(path); - if (handle < 0) - return; - - _vm->_dataIO->closeData(handle); - _imFileData = _vm->_dataIO->getData(path); -} - void Game::start(void) { _collisionAreas = new Collision[250]; memset(_collisionAreas, 0, 250 * sizeof(Collision)); @@ -526,34 +399,24 @@ void Game::start(void) { for (int i = 0; i < SPRITES_COUNT; i++) _vm->_draw->freeSprite(i); - _vm->_draw->_scummvmCursor = 0; + _vm->_draw->_scummvmCursor.reset(); } // flagbits: 0 = freeInterVariables, 1 = skipPlay void Game::totSub(int8 flags, const char *newTotFile) { int8 curBackupPos; - if (_backupedCount >= 5) + if (_numEnvironments >= Environments::kEnvironmentCount) return; - _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; - _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; - _totTextDataArray[_backupedCount] = _totTextData; - _totFileDataArray[_backupedCount] = _totFileData; - _totResourceTableArray[_backupedCount] = _totResourceTable; - _extTableArray[_backupedCount] = _extTable; - _extHandleArray[_backupedCount] = _extHandle; - _imFileDataArray[_backupedCount] = _imFileData; - _variablesArray[_backupedCount] = _vm->_inter->_variables; - strcpy(_curTotFileArray[_backupedCount], _curTotFile); - - curBackupPos = _curBackupPos; - _backupedCount++; - _curBackupPos = _backupedCount; - - _totTextData = 0; - _totFileData = 0; - _totResourceTable = 0; + _environments->set(_numEnvironments); + + curBackupPos = _curEnvironment; + _numEnvironments++; + _curEnvironment = _numEnvironments; + + _script = new Script(_vm); + _resources = new Resources(_vm); if (flags & 1) _vm->_inter->_variables = 0; @@ -563,8 +426,10 @@ void Game::totSub(int8 flags, const char *newTotFile) { // else strcat(_curTotFile, ".TOT"); - if (_vm->_inter->_terminate != 0) + if (_vm->_inter->_terminate != 0) { + clearUnusedEnvironment(); return; + } pushCollisions(0); @@ -582,197 +447,64 @@ void Game::totSub(int8 flags, const char *newTotFile) { _vm->_inter->delocateVars(); } - _backupedCount--; - _curBackupPos = curBackupPos; - - _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount]; - _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount]; - _totTextData = _totTextDataArray[_backupedCount]; - _totFileData = _totFileDataArray[_backupedCount]; - _totResourceTable = _totResourceTableArray[_backupedCount]; - _extTable = _extTableArray[_backupedCount]; - _extHandle = _extHandleArray[_backupedCount]; - _imFileData = _imFileDataArray[_backupedCount]; - _vm->_inter->_variables = _variablesArray[_backupedCount]; - strcpy(_curTotFile, _curTotFileArray[_backupedCount]); - strcpy(_curExtFile, _curTotFile); - _curExtFile[strlen(_curExtFile) - 4] = '\0'; - strcat(_curExtFile, ".EXT"); + clearUnusedEnvironment(); + + _numEnvironments--; + _curEnvironment = curBackupPos; + _environments->get(_numEnvironments); } void Game::switchTotSub(int16 index, int16 skipPlay) { int16 backupedCount; int16 curBackupPos; - if ((_backupedCount - index) < 1) + if ((_numEnvironments - index) < 1) + return; + + int16 newPos = _curEnvironment - index - ((index >= 0) ? 1 : 0); + if (newPos >= Environments::kEnvironmentCount) return; - int16 newPos = _curBackupPos - index - ((index >= 0) ? 1 : 0); // WORKAROUND: Some versions don't make the MOVEMENT menu item unselectable // in the dreamland screen, resulting in a crash when it's clicked. if ((_vm->getGameType() == kGameTypeGob2) && (index == -1) && (skipPlay == 7) && - !scumm_stricmp(_curTotFileArray[newPos], "gob06.tot")) + !scumm_stricmp(_environments->getTotFile(newPos), "gob06.tot")) return; - curBackupPos = _curBackupPos; - backupedCount = _backupedCount; - if (_curBackupPos == _backupedCount) { - _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; - _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; - _totTextDataArray[_backupedCount] = _totTextData; - _totFileDataArray[_backupedCount] = _totFileData; - _totResourceTableArray[_backupedCount] = _totResourceTable; - _extTableArray[_backupedCount] = _extTable; - _extHandleArray[_backupedCount] = _extHandle; - _imFileDataArray[_backupedCount] = _imFileData; - _variablesArray[_backupedCount] = _vm->_inter->_variables; - strcpy(_curTotFileArray[_backupedCount], _curTotFile); - _backupedCount++; - } - _curBackupPos -= index; - if (index >= 0) - _curBackupPos--; - - _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos]; - _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos]; - _totTextData = _totTextDataArray[_curBackupPos]; - _totFileData = _totFileDataArray[_curBackupPos]; - _totResourceTable = _totResourceTableArray[_curBackupPos]; - _imFileData = _imFileDataArray[_curBackupPos]; - _extTable = _extTableArray[_curBackupPos]; - _extHandle = _extHandleArray[_curBackupPos]; - _vm->_inter->_variables = _variablesArray[_curBackupPos]; - strcpy(_curTotFile, _curTotFileArray[_curBackupPos]); - strcpy(_curExtFile, _curTotFile); - _curExtFile[strlen(_curExtFile) - 4] = '\0'; - strcat(_curExtFile, ".EXT"); - - if (_vm->_inter->_terminate != 0) - return; + curBackupPos = _curEnvironment; + backupedCount = _numEnvironments; + if (_curEnvironment == _numEnvironments) + _environments->set(_numEnvironments++); - _vm->_game->pushCollisions(0); - _vm->_game->playTot(skipPlay); + _curEnvironment -= index; + if (index >= 0) + _curEnvironment--; - if (_vm->_inter->_terminate != 2) - _vm->_inter->_terminate = 0; + clearUnusedEnvironment(); - _vm->_game->popCollisions(); - - _curBackupPos = curBackupPos; - _backupedCount = backupedCount; - _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos]; - _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos]; - _totTextData = _totTextDataArray[_curBackupPos]; - _totFileData = _totFileDataArray[_curBackupPos]; - _totResourceTable = _totResourceTableArray[_curBackupPos]; - _extTable = _extTableArray[_curBackupPos]; - _extHandle = _extHandleArray[_curBackupPos]; - _imFileData = _imFileDataArray[_curBackupPos]; - _vm->_inter->_variables = _variablesArray[_curBackupPos]; - strcpy(_curTotFile, _curTotFileArray[_curBackupPos]); - strcpy(_curExtFile, _curTotFile); - _curExtFile[strlen(_curExtFile) - 4] = '\0'; - strcat(_curExtFile, ".EXT"); -} + _environments->get(_curEnvironment); -int16 Game::openLocTextFile(char *locTextFile, int language) { - int n; - - n = strlen(locTextFile); - if (n < 4) - return -1; - - locTextFile[n - 4] = 0; - switch (language) { - case 0: - strcat(locTextFile, ".dat"); - break; - case 1: - strcat(locTextFile, ".all"); - break; - case 3: - strcat(locTextFile, ".esp"); - break; - case 4: - strcat(locTextFile, ".ita"); - break; - case 5: - strcat(locTextFile, ".usa"); - break; - case 6: - strcat(locTextFile, ".ndl"); - break; - case 7: - strcat(locTextFile, ".kor"); - break; - case 8: - strcat(locTextFile, ".isr"); - break; - default: - strcat(locTextFile, ".ang"); - break; + if (_vm->_inter->_terminate != 0) { + clearUnusedEnvironment(); + return; } - return _vm->_dataIO->openData(locTextFile); -} - -byte *Game::loadLocTexts(int32 *dataSize) { - char locTextFile[20]; - int16 handle; - int i; - - strcpy(locTextFile, _curTotFile); - - handle = openLocTextFile(locTextFile, _vm->_global->_languageWanted); - if (handle >= 0) { - - _foundTotLoc = true; - _vm->_global->_language = _vm->_global->_languageWanted; - - } else if (!_foundTotLoc) { - bool found = false; - - if (_vm->_global->_languageWanted == 2) { - handle = openLocTextFile(locTextFile, 5); - if (handle >= 0) { - _vm->_global->_language = 5; - found = true; - } - } else if (_vm->_global->_languageWanted == 5) { - handle = openLocTextFile(locTextFile, 2); - if (handle >= 0) { - _vm->_global->_language = 2; - found = true; - } - } - if (!found) { - for (i = 0; i < 10; i++) { - handle = openLocTextFile(locTextFile, i); - if (handle >= 0) { - _vm->_global->_language = i; - break; - } - } - } - - } + pushCollisions(0); + playTot(skipPlay); - debugC(1, kDebugFileIO, "Using language %d for %s", - _vm->_global->_language, _curTotFile); + if (_vm->_inter->_terminate != 2) + _vm->_inter->_terminate = 0; - if (handle >= 0) { - _vm->_dataIO->closeData(handle); + popCollisions(); - if (dataSize) - *dataSize = _vm->_dataIO->getDataSize(locTextFile); + clearUnusedEnvironment(); - return _vm->_dataIO->getData(locTextFile); - } - return 0; + _curEnvironment = curBackupPos; + _numEnvironments = backupedCount; + _environments->get(_curEnvironment); } void Game::setCollisions(byte arg_0) { - byte *savedIP; uint16 left; uint16 top; uint16 width; @@ -783,12 +515,12 @@ void Game::setCollisions(byte arg_0) { if (((collArea->id & 0xC000) != 0x8000) || (collArea->funcSub == 0)) continue; - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + collArea->funcSub; - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + _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; @@ -807,16 +539,15 @@ void Game::setCollisions(byte arg_0) { collArea->top = top; collArea->right = left + width - 1; collArea->bottom = top + height - 1; - _vm->_global->_inter_execPtr = savedIP; + + _script->pop(); } } void Game::collSub(uint16 offset) { - byte *savedIP; int16 collStackSize; - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + offset; + _script->call(offset); _shouldPushColls = 1; collStackSize = _collStackSize; @@ -827,7 +558,9 @@ void Game::collSub(uint16 offset) { popCollisions(); _shouldPushColls = 0; - _vm->_global->_inter_execPtr = savedIP; + + _script->pop(); + setCollisions(); } @@ -852,4 +585,16 @@ void Game::collAreaSub(int16 index, int8 enter) { } } +void Game::clearUnusedEnvironment() { + if (!_environments->has(_script)) { + delete _script; + _script = 0; + } + if (!_environments->has(_resources)) { + delete _resources; + _resources = 0; + } + +} + } // End of namespace Gob diff --git a/engines/gob/game.h b/engines/gob/game.h index 3264288a32..ead4a56492 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -26,10 +26,45 @@ #ifndef GOB_GAME_H #define GOB_GAME_H -#include "gob/variables.h" - namespace Gob { +class Script; +class Resources; +class Variables; + +class Environments { +public: + static const uint8 kEnvironmentCount = 5; + + Environments(GobEngine *vm); + ~Environments(); + + void set(uint8 env); + void get(uint8 env) const; + + const char *getTotFile(uint8 env) const; + + bool has(Variables *variables, uint8 startEnv = 0, int16 except = -1) const; + bool has(Script *script , uint8 startEnv = 0, int16 except = -1) const; + bool has(Resources *resources, uint8 startEnv = 0, int16 except = -1) const; + + void clear(); + +private: + struct Environment { + int16 cursorHotspotX; + int16 cursorHotspotY; + char curTotFile[14]; + Variables *variables; + Script *script; + Resources *resources; + }; + + GobEngine *_vm; + + Environment *_environments; +}; + class Game { public: @@ -46,20 +81,7 @@ public: uint16 funcEnter; uint16 funcLeave; uint16 funcSub; - byte *totFileData; - } PACKED_STRUCT; - -#define szGame_TotTextItem (2 + 2) - struct TotTextItem { - int16 offset; - int16 size; - } PACKED_STRUCT; - -#define szGame_TotTextTable (2) - struct TotTextTable { - int16 itemsCount; - TotTextItem *items; - byte *dataPtr; + Script *script; } PACKED_STRUCT; struct InputDesc { @@ -74,18 +96,10 @@ public: Collision *_collisionAreas; Collision *_collStack[5]; - bool _foundTotLoc; - TotTextTable *_totTextData; + Script *_script; + Resources *_resources; char _curTotFile[14]; - char _curExtFile[14]; - - byte *_imFileData; - byte *_totFileData; - - int16 _extHandle; - int16 _lomHandle; - char _totToLoad[20]; int32 _startTimeKey; @@ -100,9 +114,6 @@ public: Game(GobEngine *vm); virtual ~Game(); - byte *loadExtData(int16 dataId, int16 *pResWidth, int16 *pResHeight, uint32 *dataSize = 0); - byte *loadTotResource(int16 id, int16 *dataSize = 0, int16 *width = 0, int16 *height = 0); - void capturePush(int16 left, int16 top, int16 width, int16 height); void capturePop(char doDraw); @@ -142,42 +153,6 @@ public: virtual void popCollisions(void) = 0; protected: -#include "common/pack-start.h" // START STRUCT PACKING - -#define szGame_TotResItem (4 + 2 + 2 + 2) - struct TotResItem { - int32 offset; // if > 0, then offset from end of resource table. - // If < 0, then -offset-1 is index in .IM file table - int16 size; - int16 width; - int16 height; - } PACKED_STRUCT; - -#define szGame_TotResTable (2 + 1) - struct TotResTable { - int16 itemsCount; - byte unknown; - TotResItem *items; - byte *dataPtr; - } PACKED_STRUCT; - -#define szGame_ExtItem (4 + 2 + 2 + 2) - struct ExtItem { - int32 offset; // offset from the table end - uint16 size; - int16 width; // width & 0x7FFF: width, width & 0x8000: pack flag - int16 height; // not zero - } PACKED_STRUCT; - -#define szGame_ExtTable (2 + 1) - struct ExtTable { - int16 itemsCount; - byte unknown; - ExtItem *items; - } PACKED_STRUCT; - -#include "common/pack-end.h" // END STRUCT PACKING - int16 _lastCollKey; int16 _lastCollAreaIndex; int16 _lastCollId; @@ -190,10 +165,6 @@ protected: char _tempStr[256]; - TotResTable *_totResourceTable; - ExtTable *_extTable; - char _curImaFile[18]; - int16 _collStackSize; int16 _collStackElemSizes[5]; @@ -206,35 +177,22 @@ protected: char _collStr[256]; // For totSub() - int8 _backupedCount; - int8 _curBackupPos; - int16 _cursorHotspotXArray[5]; - int16 _cursorHotspotYArray[5]; - TotTextTable *_totTextDataArray[5]; - byte *_totFileDataArray[5]; - TotResTable *_totResourceTableArray[5]; - ExtTable *_extTableArray[5]; - int16 _extHandleArray[5]; - byte *_imFileDataArray[5]; - Variables *_variablesArray[5]; - char _curTotFileArray[5][14]; + int8 _curEnvironment; + int8 _numEnvironments; + Environments *_environments; GobEngine *_vm; virtual int16 adjustKey(int16 key); - byte *loadLocTexts(int32 *dataSize = 0); - int32 loadTotFile(const char *path); - void loadExtTable(void); - void loadImFile(void); - void collAreaSub(int16 index, int8 enter); - int16 openLocTextFile(char *locTextFile, int language); 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 { diff --git a/engines/gob/game_fascin.cpp b/engines/gob/game_fascin.cpp index 8e77141ce6..38ad03f0f8 100644 --- a/engines/gob/game_fascin.cpp +++ b/engines/gob/game_fascin.cpp @@ -35,7 +35,6 @@ #include "gob/goblin.h" #include "gob/inter.h" #include "gob/mult.h" -#include "gob/parse.h" #include "gob/scenery.h" #include "gob/video.h" #include "gob/videoplayer.h" diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index b46cc00f90..87dc78e3b1 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -32,11 +32,12 @@ #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/parse.h" #include "gob/scenery.h" #include "gob/sound/sound.h" @@ -49,12 +50,12 @@ void Game_v1::playTot(int16 skipPlay) { int16 _captureCounter; int16 breakFrom; int16 nestLevel; - int32 variablesCount; int16 *oldNestLevel = _vm->_inter->_nestLevel; int16 *oldBreakFrom = _vm->_inter->_breakFromLevel; int16 *oldCaptureCounter = _vm->_scenery->_pCaptureCounter; - byte *savedIP = _vm->_global->_inter_execPtr; + + _script->push(); _vm->_inter->_nestLevel = &nestLevel; _vm->_inter->_breakFromLevel = &breakFrom; @@ -93,86 +94,23 @@ void Game_v1::playTot(int16 skipPlay) { for (int i = 0; i < 20; i++) freeSoundSlot(i); - _totTextData = 0; - _totResourceTable = 0; - _imFileData = 0; - _extTable = 0; - _extHandle = -1; - _totToLoad[0] = 0; - if ((_curTotFile[0] == 0) && (_totFileData == 0)) + if ((_curTotFile[0] == 0) && !_script->isLoaded()) break; - loadTotFile(_curTotFile); - if (_totFileData == 0) { + if (!_script->load(_curTotFile)) { _vm->_draw->blitCursor(); break; } - strcpy(_curImaFile, _curTotFile); - strcpy(_curExtFile, _curTotFile); - - _curImaFile[strlen(_curImaFile) - 4] = 0; - strcat(_curImaFile, ".ima"); - - _curExtFile[strlen(_curExtFile) - 4] = 0; - strcat(_curExtFile, ".ext"); - - debugC(4, kDebugFileIO, "IMA: %s", _curImaFile); - debugC(4, kDebugFileIO, "EXT: %s", _curExtFile); - - byte *filePtr = _totFileData + 0x30; - - _totTextData = 0; - if (READ_LE_UINT32(filePtr) != (uint32) -1) { - _totTextData = new TotTextTable; - _totTextData->dataPtr = - (_totFileData + READ_LE_UINT32(_totFileData + 0x30)); - Common::MemoryReadStream totTextData(_totTextData->dataPtr, - 4294967295U); - - _totTextData->itemsCount = totTextData.readSint16LE(); - - _totTextData->items = new TotTextItem[_totTextData->itemsCount]; - for (int i = 0; i < _totTextData->itemsCount; ++i) { - _totTextData->items[i].offset = totTextData.readSint16LE(); - _totTextData->items[i].size = totTextData.readSint16LE(); - } - } - - filePtr = _totFileData + 0x34; - _totResourceTable = 0; - if (READ_LE_UINT32(filePtr) != (uint32) -1) { - _totResourceTable = new TotResTable; - _totResourceTable->dataPtr = - _totFileData + READ_LE_UINT32( _totFileData + 0x34); - Common::MemoryReadStream totResTable(_totResourceTable->dataPtr, - 4294967295U); - - _totResourceTable->itemsCount = totResTable.readSint16LE(); - _totResourceTable->unknown = totResTable.readByte(); - - _totResourceTable->items = - new TotResItem[_totResourceTable->itemsCount]; - for (int i = 0; i < _totResourceTable->itemsCount; ++i) { - _totResourceTable->items[i].offset = totResTable.readSint32LE(); - _totResourceTable->items[i].size = totResTable.readSint16LE(); - _totResourceTable->items[i].width = totResTable.readSint16LE(); - _totResourceTable->items[i].height = totResTable.readSint16LE(); - } - } - - loadImFile(); - loadExtTable(); + _resources->load(_curTotFile); - _vm->_global->_inter_animDataSize = - READ_LE_UINT16(_totFileData + 0x38); + _vm->_global->_inter_animDataSize = _script->getAnimDataSize(); if (!_vm->_inter->_variables) - _vm->_inter->allocateVars(READ_LE_UINT16(_totFileData + 0x2C)); + _vm->_inter->allocateVars(_script->getVariablesCount() & 0xFFFF); - _vm->_global->_inter_execPtr = _totFileData; - _vm->_global->_inter_execPtr += READ_LE_UINT32(_totFileData + 0x64); + _script->seek(_script->getFunctionOffset(TOTFile::kFunctionStart)); _vm->_inter->renewTimeInVars(); @@ -182,39 +120,16 @@ void Game_v1::playTot(int16 skipPlay) { WRITE_VAR(16, _vm->_global->_language); _vm->_inter->callSub(2); + _script->setFinished(false); if (_totToLoad[0] != 0) _vm->_inter->_terminate = 0; - variablesCount = READ_LE_UINT32(_totFileData + 0x2C); _vm->_draw->blitInvalidated(); - delete[] _totFileData; - _totFileData = 0; - - if (_totTextData) { - delete[] _totTextData->items; - delete _totTextData; - } - _totTextData = 0; - - if (_totResourceTable) { - delete[] _totResourceTable->items; - delete _totResourceTable; - } - _totResourceTable = 0; - - delete[] _imFileData; - _imFileData = 0; - if (_extTable) - delete[] _extTable->items; - delete _extTable; - _extTable = 0; + _script->unload(); - if (_extHandle >= 0) - _vm->_dataIO->closeData(_extHandle); - - _extHandle = -1; + _resources->unload(); for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) capturePop(0); @@ -241,7 +156,8 @@ void Game_v1::playTot(int16 skipPlay) { _vm->_inter->_nestLevel = oldNestLevel; _vm->_inter->_breakFromLevel = oldBreakFrom; _vm->_scenery->_pCaptureCounter = oldCaptureCounter; - _vm->_global->_inter_execPtr = savedIP; + + _script->pop(); } void Game_v1::clearCollisions() { @@ -279,7 +195,7 @@ int16 Game_v1::addNewCollision(int16 id, uint16 left, uint16 top, ptr->funcEnter = funcEnter; ptr->funcLeave = funcLeave; ptr->funcSub = funcSub; - ptr->totFileData = 0; + ptr->script = 0; return i; } @@ -331,7 +247,6 @@ void Game_v1::popCollisions(void) { int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime, int16 *pResId, int16 *pResIndex) { - byte *savedIP; int16 resIndex; int16 key; int16 oldIndex; @@ -357,12 +272,9 @@ int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime, _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[_lastCollAreaIndex].funcEnter; - + _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); } } @@ -423,12 +335,10 @@ int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime, if ((_lastCollKey != 0) && (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[_lastCollAreaIndex].funcLeave; + _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); } _lastCollKey = 0; @@ -463,12 +373,11 @@ int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime, if ((_lastCollKey != 0) && (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[_lastCollAreaIndex].funcLeave; + _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); + } _lastCollKey = 0; return key; @@ -476,24 +385,22 @@ int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime, if ((_lastCollKey != 0) && (_collisionAreas[_lastCollAreaIndex].funcLeave != 0)) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[_lastCollAreaIndex].funcLeave; + _script->call(_collisionAreas[_lastCollAreaIndex].funcLeave); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); + } _lastCollKey = checkMousePoint(1, &_lastCollId, &_lastCollAreaIndex); if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[_lastCollAreaIndex].funcEnter; + _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); + } } else { @@ -507,23 +414,22 @@ int16 Game_v1::checkCollisions(byte handleMouse, int16 deltaTime, if (key != _lastCollKey) { if ((_lastCollKey != 0) && ((oldId & 0x8000) != 0)) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[oldIndex].funcLeave; + _script->call(_collisionAreas[oldIndex].funcLeave); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); + } _lastCollKey = key; if ((_lastCollKey != 0) && ((_lastCollId & 0x8000) != 0)) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[_lastCollAreaIndex].funcEnter; + _script->call(_collisionAreas[_lastCollAreaIndex].funcEnter); _vm->_inter->funcBlock(0); - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); + } + } } } @@ -549,9 +455,9 @@ void Game_v1::prepareStart(void) { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); _vm->_draw->initScreen(); - _vm->_video->fillRect(_vm->_draw->_backSurface, 0, 0, 319, 199, 1); + _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->_video->fillRect(*_vm->_draw->_frontSurface, 0, 0, 319, 199, 1); _vm->_util->setMousePos(152, 92); _vm->_draw->_cursorX = _vm->_global->_inter_mouseX = 152; @@ -588,7 +494,6 @@ void Game_v1::collisionsBlock(void) { int16 array[250]; byte count; int16 collResId; - byte *startIP; int16 curCmd; int16 cmd; int16 cmdHigh; @@ -615,27 +520,27 @@ void Game_v1::collisionsBlock(void) { int16 collStackPos; Collision *collPtr; uint32 timeKey; - byte *savedIP; if (_shouldPushColls) pushCollisions(1); collResId = -1; - _vm->_global->_inter_execPtr++; - count = *_vm->_global->_inter_execPtr++; - _handleMouse = _vm->_global->_inter_execPtr[0]; - deltaTime = 1000 * _vm->_global->_inter_execPtr[1]; - descIndex2 = _vm->_global->_inter_execPtr[2]; - stackPos2 = _vm->_global->_inter_execPtr[3]; - descIndex = _vm->_global->_inter_execPtr[4]; + _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; - _vm->_global->_inter_execPtr += 6; + _script->skip(1); + + uint32 startPos = _script->pos(); - startIP = _vm->_global->_inter_execPtr; WRITE_VAR(16, 0); var_22 = 0; index = 0; @@ -643,26 +548,25 @@ void Game_v1::collisionsBlock(void) { for (curCmd = 0; curCmd < count; curCmd++) { array[curCmd] = 0; - cmd = *_vm->_global->_inter_execPtr++; + cmd = _script->readByte(); if ((cmd & 0x40) != 0) { cmd -= 0x40; - cmdHigh = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr++; + cmdHigh = _script->readByte(); cmdHigh <<= 8; } else cmdHigh = 0; if ((cmd & 0x80) != 0) { - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + left = _script->readValExpr(); + top = _script->readValExpr(); + width = _script->readValExpr(); + height = _script->readValExpr(); } else { - left = _vm->_inter->load16(); - top = _vm->_inter->load16(); - width = _vm->_inter->load16(); - height = _vm->_inter->load16(); + left = _script->readUint16(); + top = _script->readUint16(); + width = _script->readUint16(); + height = _script->readUint16(); } cmd &= 0x7F; @@ -680,16 +584,16 @@ void Game_v1::collisionsBlock(void) { _vm->_util->clearKeyBuf(); var_22 = 1; - key = _vm->_parse->parseVarIndex(); - descArray[index].fontIndex = _vm->_inter->load16(); - descArray[index].backColor = *_vm->_global->_inter_execPtr++; - descArray[index].frontColor = *_vm->_global->_inter_execPtr++; + 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 = _vm->_global->_inter_execPtr + 2; - _vm->_global->_inter_execPtr += _vm->_inter->load16(); + descArray[index].ptr = _script->getData() + _script->pos() + 2; + _script->skip(_script->readInt16()); } if (left == 0xFFFF) @@ -698,12 +602,9 @@ void Game_v1::collisionsBlock(void) { 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, - _vm->_global->_inter_execPtr - _totFileData); + top + height - 1, cmd, key, 0, _script->pos()); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); } else { addNewCollision(curCmd + 0x8000, left, top, left + width * _vm->_draw->_fonts[descArray[index].fontIndex]->itemWidth - 1, @@ -713,18 +614,15 @@ void Game_v1::collisionsBlock(void) { break; case 21: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; + 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, - _vm->_global->_inter_execPtr - _totFileData, 0); + (flags << 4) + cmdHigh + 2, key, _script->pos(), 0); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 20: @@ -732,61 +630,48 @@ void Game_v1::collisionsBlock(void) { // Fall through to case 2 case 2: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; + 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, - _vm->_global->_inter_execPtr - _totFileData); + (flags << 4) + cmdHigh + 2, key, 0, _script->pos()); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 0: - _vm->_global->_inter_execPtr += 6; - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _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, - startIP - _totFileData, - _vm->_global->_inter_execPtr - _totFileData); + startPos, _script->pos()); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 1: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; - - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + 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, - startIP - _totFileData, - _vm->_global->_inter_execPtr - _totFileData); + startPos, _script->pos()); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; } } @@ -895,9 +780,11 @@ void Game_v1::collisionsBlock(void) { if (collPtr->funcLeave != 0) { timeKey = _vm->_util->getTimeKey(); - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = - _totFileData + collPtr->funcLeave; + + uint32 savedPos = _script->pos(); + + _script->seek(collPtr->funcLeave); + _shouldPushColls = 1; savedCollStackSize = _collStackSize; _vm->_inter->funcBlock(0); @@ -906,7 +793,8 @@ void Game_v1::collisionsBlock(void) { popCollisions(); _shouldPushColls = 0; - _vm->_global->_inter_execPtr = savedIP; + + _script->seek(savedPos); deltaTime = timeVal - (_vm->_util->getTimeKey() - timeKey); @@ -986,9 +874,9 @@ void Game_v1::collisionsBlock(void) { WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]); if (_collisionAreas[_activeCollIndex].funcEnter != 0) { - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + - _collisionAreas[_activeCollIndex].funcEnter; + uint32 savedPos = _script->pos(); + + _script->seek(_collisionAreas[_activeCollIndex].funcEnter); _shouldPushColls = 1; @@ -997,7 +885,8 @@ void Game_v1::collisionsBlock(void) { if (collStackPos != _collStackSize) popCollisions(); _shouldPushColls = 0; - _vm->_global->_inter_execPtr = savedIP; + + _script->seek(savedPos); } WRITE_VAR(16, 0); @@ -1071,10 +960,8 @@ void Game_v1::collisionsBlock(void) { WRITE_VAR(17, 1); } - savedIP = 0; if (!_vm->_inter->_terminate) { - savedIP = _totFileData + - _collisionAreas[_activeCollIndex].funcLeave; + _script->seek(_collisionAreas[_activeCollIndex].funcLeave); WRITE_VAR(2, _vm->_global->_inter_mouseX); WRITE_VAR(3, _vm->_global->_inter_mouseY); @@ -1082,12 +969,11 @@ void Game_v1::collisionsBlock(void) { if (VAR(16) == 0) WRITE_VAR(16, array[(uint16) _activeCollResId & ~0x8000]); - } + } else + _script->setFinished(true); for (curCmd = 0; curCmd < count; curCmd++) freeCollision(curCmd + 0x8000); - - _vm->_global->_inter_execPtr = savedIP; } int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 777eae14bc..08184e73d0 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -32,11 +32,12 @@ #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/parse.h" #include "gob/scenery.h" #include "gob/video.h" #include "gob/videoplayer.h" @@ -55,15 +56,12 @@ void Game_v2::playTot(int16 skipPlay) { int16 _captureCounter; int16 breakFrom; int16 nestLevel; - int32 totSize; - byte *filePtr; - byte *savedIP; - bool totTextLoc; oldNestLevel = _vm->_inter->_nestLevel; oldBreakFrom = _vm->_inter->_breakFromLevel; oldCaptureCounter = _vm->_scenery->_pCaptureCounter; - savedIP = _vm->_global->_inter_execPtr; + + _script->push(); _vm->_inter->_nestLevel = &nestLevel; _vm->_inter->_breakFromLevel = &breakFrom; @@ -94,125 +92,30 @@ void Game_v2::playTot(int16 skipPlay) { } else _vm->_inter->initControlVars(0); - _totTextData = 0; - _totResourceTable = 0; - _imFileData = 0; - _extTable = 0; - _extHandle = -1; - _vm->_draw->_cursorHotspotXVar = -1; _totToLoad[0] = 0; - if ((_curTotFile[0] == 0) && (_totFileData == 0)) + if ((_curTotFile[0] == 0) && (!_script->isLoaded())) break; - totSize = loadTotFile(_curTotFile); - if (skipPlay == -2) { _vm->_vidPlayer->primaryClose(); skipPlay = 0; } - if (_totFileData == 0) { + if (!_script->load(_curTotFile)) { _vm->_draw->blitCursor(); _vm->_inter->_terminate = 2; break; } - strcpy(_curImaFile, _curTotFile); - strcpy(_curExtFile, _curTotFile); - - _curImaFile[strlen(_curImaFile) - 4] = 0; - strcat(_curImaFile, ".ima"); - - _curExtFile[strlen(_curExtFile) - 4] = 0; - strcat(_curExtFile, ".ext"); - - debugC(4, kDebugFileIO, "IMA: %s", _curImaFile); - debugC(4, kDebugFileIO, "EXT: %s", _curExtFile); - - filePtr = _totFileData + 0x30; - - _totTextData = 0; - totTextLoc = false; - if (READ_LE_UINT32(filePtr) != (uint32) -1) { - _totTextData = new TotTextTable; - - int32 size; - - if (READ_LE_UINT32(filePtr) == 0) { - _totTextData->dataPtr = loadLocTexts(&size); - totTextLoc = true; - } else { - _totTextData->dataPtr = - (_totFileData + READ_LE_UINT32(_totFileData + 0x30)); - size = totSize; - _vm->_global->_language = _vm->_global->_languageWanted; - } - - _totTextData->items = 0; - if (_totTextData->dataPtr != 0) { - Common::MemoryReadStream totTextData(_totTextData->dataPtr, - 4294967295U); - _totTextData->itemsCount = totTextData.readSint16LE() & 0x3FFF; - - _totTextData->items = new TotTextItem[_totTextData->itemsCount]; - for (int i = 0; i < _totTextData->itemsCount; ++i) { - _totTextData->items[i].offset = totTextData.readSint16LE(); - _totTextData->items[i].size = totTextData.readSint16LE(); - } - } - } - - filePtr = _totFileData + 0x34; - _totResourceTable = 0; - int32 resSize; - if (READ_LE_UINT32(filePtr) != (uint32) -1) { - _totResourceTable = new TotResTable; - _totResourceTable->dataPtr = - _totFileData + READ_LE_UINT32(_totFileData + 0x34); - Common::MemoryReadStream totResTable(_totResourceTable->dataPtr, - 4294967295U); - - _totResourceTable->itemsCount = totResTable.readSint16LE(); - resSize = _totResourceTable->itemsCount * szGame_TotResItem + szGame_TotResTable; - if (totSize > (resSize + 0x34)) { - _totResourceTable->unknown = totResTable.readByte(); - - _totResourceTable->items = - new TotResItem[_totResourceTable->itemsCount]; - for (int i = 0; i < _totResourceTable->itemsCount; ++i) { - _totResourceTable->items[i].offset = totResTable.readSint32LE(); - _totResourceTable->items[i].size = totResTable.readSint16LE(); - _totResourceTable->items[i].width = totResTable.readSint16LE(); - _totResourceTable->items[i].height = totResTable.readSint16LE(); - } - } - else { - // WORKAROUND: In the original asm, _totResourceTable is - // only assigned in playTot and evaluated later, right - // before using it. In the Gobliins 2 demo, there is a - // dummy tot that loads another tot, overwriting the dummy - // pointer with the real one. - debugC(1, kDebugFileIO, - "Attempted to load invalid resource table (size = %d, totSize = %d)", - resSize, totSize); - delete _totResourceTable; - _totResourceTable = 0; - } - } - - loadImFile(); - loadExtTable(); + _resources->load(_curTotFile); - _vm->_global->_inter_animDataSize = - READ_LE_UINT16(_totFileData + 0x38); + _vm->_global->_inter_animDataSize = _script->getAnimDataSize(); if (!_vm->_inter->_variables) - _vm->_inter->allocateVars(READ_LE_UINT16(_totFileData + 0x2C)); + _vm->_inter->allocateVars(_script->getVariablesCount() & 0xFFFF); - _vm->_global->_inter_execPtr = _totFileData; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_totFileData + 0x64); + _script->seek(_script->getFunctionOffset(TOTFile::kFunctionStart)); _vm->_inter->renewTimeInVars(); @@ -227,35 +130,10 @@ void Game_v2::playTot(int16 skipPlay) { _vm->_inter->_terminate = 0; _vm->_draw->blitInvalidated(); - delete[] _totFileData; - _totFileData = 0; - - if (_totTextData) { - delete[] _totTextData->items; - if (totTextLoc) - delete[] _totTextData->dataPtr; - delete _totTextData; - } - _totTextData = 0; - if (_totResourceTable) { - delete[] _totResourceTable->items; - delete _totResourceTable; - } - _totResourceTable = 0; - - delete[] _imFileData; - _imFileData = 0; - - if (_extTable) - delete[] _extTable->items; - delete _extTable; - _extTable = 0; - - if (_extHandle >= 0) - _vm->_dataIO->closeData(_extHandle); + _script->unload(); - _extHandle = -1; + _resources->unload(); for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) capturePop(0); @@ -282,9 +160,7 @@ void Game_v2::playTot(int16 skipPlay) { } else { _vm->_inter->initControlVars(0); _vm->_scenery->_pCaptureCounter = oldCaptureCounter; - _vm->_global->_inter_execPtr = _totFileData; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_totFileData + (skipPlay << 1) + 0x66); + _script->seek(_script->getFunctionOffset(skipPlay + 1)); _menuLevel++; _vm->_inter->callSub(2); @@ -299,7 +175,8 @@ void Game_v2::playTot(int16 skipPlay) { _vm->_inter->_nestLevel = oldNestLevel; _vm->_inter->_breakFromLevel = oldBreakFrom; _vm->_scenery->_pCaptureCounter = oldCaptureCounter; - _vm->_global->_inter_execPtr = savedIP; + + _script->pop(); } void Game_v2::clearCollisions() { @@ -337,7 +214,7 @@ int16 Game_v2::addNewCollision(int16 id, uint16 left, uint16 top, ptr->funcEnter = funcEnter; ptr->funcLeave = funcLeave; ptr->funcSub = funcSub; - ptr->totFileData = 0; + ptr->script = 0; return i; } @@ -571,7 +448,7 @@ void Game_v2::prepareStart(void) { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); _vm->_draw->initScreen(); - _vm->_video->fillRect(_vm->_draw->_frontSurface, 0, 0, + _vm->_video->fillRect(*_vm->_draw->_frontSurface, 0, 0, _vm->_video->_surfWidth - 1, _vm->_video->_surfHeight - 1, 1); _vm->_util->setMousePos(152, 92); @@ -604,7 +481,6 @@ void Game_v2::collisionsBlock(void) { int16 array[250]; byte count; int16 collResId; - byte *startIP; int16 curCmd; int16 cmd; int16 cmdHigh; @@ -621,7 +497,6 @@ void Game_v2::collisionsBlock(void) { int16 stackPos2; int16 descIndex; int16 timeVal; - int16 offsetIP; char *str; int16 i; int16 counter; @@ -631,8 +506,9 @@ void Game_v2::collisionsBlock(void) { Collision *collPtr; Collision *collArea; int16 timeKey; - byte *savedIP; byte collAreaStart; + uint32 startPos; + uint32 offsetPos; if (_shouldPushColls) pushCollisions(0); @@ -645,21 +521,22 @@ void Game_v2::collisionsBlock(void) { _shouldPushColls = 0; collResId = -1; - _vm->_global->_inter_execPtr++; - count = *_vm->_global->_inter_execPtr++; + _script->skip(1); + count = _script->readByte(); - _handleMouse = _vm->_global->_inter_execPtr[0]; - deltaTime = 1000 * _vm->_global->_inter_execPtr[1]; - stackPos2 = _vm->_global->_inter_execPtr[3]; - descIndex = _vm->_global->_inter_execPtr[4]; + _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; - _vm->_global->_inter_execPtr += 6; + _script->skip(1); - startIP = _vm->_global->_inter_execPtr; + startPos = _script->pos(); WRITE_VAR(16, 0); var_1C = 0; @@ -668,28 +545,27 @@ void Game_v2::collisionsBlock(void) { for (curCmd = 0; curCmd < count; curCmd++) { array[curCmd] = 0; - cmd = *_vm->_global->_inter_execPtr++; + cmd = _script->readByte(); if ((cmd & 0x40) != 0) { cmd -= 0x40; - cmdHigh = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr++; + cmdHigh = _script->readByte(); cmdHigh <<= 8; } else cmdHigh = 0; if ((cmd & 0x80) != 0) { - offsetIP = _vm->_global->_inter_execPtr - _totFileData; - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + offsetPos = _script->pos(); + left = _script->readValExpr(); + top = _script->readValExpr(); + width = _script->readValExpr(); + height = _script->readValExpr(); } else { - offsetIP = 0; - left = _vm->_inter->load16(); - top = _vm->_inter->load16(); - width = _vm->_inter->load16(); - height = _vm->_inter->load16(); + offsetPos = 0; + left = _script->readUint16(); + top = _script->readUint16(); + width = _script->readUint16(); + height = _script->readUint16(); } if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) { @@ -712,46 +588,37 @@ void Game_v2::collisionsBlock(void) { switch (cmd) { case 0: - _vm->_global->_inter_execPtr += 6; - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _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, startIP - _totFileData, - _vm->_global->_inter_execPtr - _totFileData, offsetIP); + cmd + cmdHigh, key, startPos, + _script->pos(), offsetPos); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 1: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16(); + key = _script->readInt16(); + array[curCmd] = _script->readInt16(); + flags = _script->readInt16(); - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + 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, startIP - _totFileData, - _vm->_global->_inter_execPtr - _totFileData, offsetIP); - - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + (flags << 4) + cmd + cmdHigh, key, startPos, + _script->pos(), offsetPos); + _script->skip(_script->peekUint16(2) + 2); break; case 3: @@ -764,23 +631,20 @@ void Game_v2::collisionsBlock(void) { case 10: _vm->_util->clearKeyBuf(); var_1C = 1; - key = _vm->_parse->parseVarIndex(); - descArray[index].fontIndex = _vm->_inter->load16(); - descArray[index].backColor = *_vm->_global->_inter_execPtr++; - descArray[index].frontColor = *_vm->_global->_inter_execPtr++; + 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 = _vm->_global->_inter_execPtr + 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr) + 2; + 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) { - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); } break; } @@ -789,11 +653,9 @@ void Game_v2::collisionsBlock(void) { addNewCollision(curCmd + 0x8000, left, top, left + width * _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, top + height - 1, cmd, key, 0, - _vm->_global->_inter_execPtr - _totFileData); + _script->pos()); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); } else addNewCollision(curCmd + 0x8000, left, top, left + width * _vm->_draw->_fonts[descArray[index].fontIndex]-> itemWidth - 1, @@ -803,35 +665,31 @@ void Game_v2::collisionsBlock(void) { break; case 11: - _vm->_global->_inter_execPtr += 6; + _script->skip(6); for (i = 0; i < 150; i++) { if ((_collisionAreas[i].id & 0xF000) == 0xE000) { _collisionAreas[i].id &= 0xBFFF; _collisionAreas[i].funcEnter = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); _collisionAreas[i].funcLeave = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); } } - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 12: - _vm->_global->_inter_execPtr += 6; + _script->skip(6); for (i = 0; i < 150; i++) { if ((_collisionAreas[i].id & 0xF000) == 0xD000) { _collisionAreas[i].id &= 0xBFFF; _collisionAreas[i].funcEnter = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); _collisionAreas[i].funcLeave = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); } } - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 20: @@ -839,34 +697,30 @@ void Game_v2::collisionsBlock(void) { // Fall through to case 2 case 2: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16(); + 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, - _vm->_global->_inter_execPtr - _totFileData, offsetIP); + _script->pos(), offsetPos); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 21: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; + 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, - _vm->_global->_inter_execPtr - _totFileData, 0, offsetIP); + _script->pos(), 0, offsetPos); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; } @@ -1116,10 +970,8 @@ void Game_v2::collisionsBlock(void) { if (_handleMouse == 1) _vm->_draw->blitCursor(); - savedIP = 0; if (!_vm->_inter->_terminate) { - savedIP = _totFileData + - _collisionAreas[_activeCollIndex].funcLeave; + _script->seek(_collisionAreas[_activeCollIndex].funcLeave); _vm->_inter->storeMouse(); if (VAR(16) == 0) { @@ -1128,7 +980,8 @@ void Game_v2::collisionsBlock(void) { else WRITE_VAR(16, _activeCollResId & 0xFFF); } - } + } else + _script->setFinished(true); for (curCmd = 0; curCmd < count; curCmd++) freeCollision(curCmd + 0x8000); @@ -1138,8 +991,6 @@ void Game_v2::collisionsBlock(void) { ((_collisionAreas[i].id & 0xF000) == 0x9000)) _collisionAreas[i].id |= 0x4000; } - - _vm->_global->_inter_execPtr = savedIP; } int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, diff --git a/engines/gob/game_v6.cpp b/engines/gob/game_v6.cpp index 9d9bd1faa3..8d40d41acc 100644 --- a/engines/gob/game_v6.cpp +++ b/engines/gob/game_v6.cpp @@ -31,9 +31,10 @@ #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" -#include "gob/parse.h" namespace Gob { @@ -48,27 +49,17 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) { if ((flags == 16) || (flags == 17)) warning("Urban Stub: Game_v6::totSub(), flags == %d", flags); - if (_backupedCount >= 5) + if (_numEnvironments >= Environments::kEnvironmentCount) return; - _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; - _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; - _totTextDataArray[_backupedCount] = _totTextData; - _totFileDataArray[_backupedCount] = _totFileData; - _totResourceTableArray[_backupedCount] = _totResourceTable; - _extTableArray[_backupedCount] = _extTable; - _extHandleArray[_backupedCount] = _extHandle; - _imFileDataArray[_backupedCount] = _imFileData; - _variablesArray[_backupedCount] = _vm->_inter->_variables; - strcpy(_curTotFileArray[_backupedCount], _curTotFile); - - curBackupPos = _curBackupPos; - _backupedCount++; - _curBackupPos = _backupedCount; - - _totTextData = 0; - _totFileData = 0; - _totResourceTable = 0; + _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"); @@ -79,8 +70,10 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) { strncpy0(_curTotFile, newTotFile, 9); strcat(_curTotFile, ".TOT"); - if (_vm->_inter->_terminate != 0) + if (_vm->_inter->_terminate != 0) { + clearUnusedEnvironment(); return; + } pushCollisions(0); @@ -99,22 +92,11 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) { _vm->_inter->delocateVars(); } - _backupedCount--; - _curBackupPos = curBackupPos; - - _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount]; - _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount]; - _totTextData = _totTextDataArray[_backupedCount]; - _totFileData = _totFileDataArray[_backupedCount]; - _totResourceTable = _totResourceTableArray[_backupedCount]; - _extTable = _extTableArray[_backupedCount]; - _extHandle = _extHandleArray[_backupedCount]; - _imFileData = _imFileDataArray[_backupedCount]; - _vm->_inter->_variables = _variablesArray[_backupedCount]; - strcpy(_curTotFile, _curTotFileArray[_backupedCount]); - strcpy(_curExtFile, _curTotFile); - _curExtFile[strlen(_curExtFile) - 4] = '\0'; - strcat(_curExtFile, ".EXT"); + clearUnusedEnvironment(); + + _numEnvironments--; + _curEnvironment = curBackupPos; + _environments->get(_numEnvironments); } int16 Game_v6::addNewCollision(int16 id, uint16 left, uint16 top, @@ -148,7 +130,7 @@ int16 Game_v6::addNewCollision(int16 id, uint16 left, uint16 top, ptr->funcEnter = funcEnter; ptr->funcLeave = funcLeave; ptr->funcSub = funcSub; - ptr->totFileData = _totFileData; + ptr->script = _script; return i; } @@ -383,7 +365,6 @@ void Game_v6::collisionsBlock(void) { int16 array[300]; byte count; int16 collResId; - byte *startIP; int16 curCmd; int16 cmd; int16 cmdHigh; @@ -397,7 +378,6 @@ void Game_v6::collisionsBlock(void) { int16 stackPos2; int16 descIndex; int16 timeVal; - int16 offsetIP; char *str; int16 i; int16 counter; @@ -406,10 +386,11 @@ void Game_v6::collisionsBlock(void) { int16 collStackPos; Collision *collPtr; Collision *collArea; - byte *savedIP; byte collAreaStart; int16 activeCollResId = 0; int16 activeCollIndex = 0; + uint32 startPos; + uint32 offsetPos; if (_shouldPushColls) pushCollisions(0); @@ -422,25 +403,25 @@ void Game_v6::collisionsBlock(void) { _shouldPushColls = 0; collResId = -1; - _vm->_global->_inter_execPtr++; - count = *_vm->_global->_inter_execPtr++; + _script->skip(1); + count = _script->readByte(); - _handleMouse = _vm->_global->_inter_execPtr[0]; - deltaTime = 1000 * _vm->_global->_inter_execPtr[1]; - stackPos2 = _vm->_global->_inter_execPtr[3]; - descIndex = _vm->_global->_inter_execPtr[4]; - byte var_42 = _vm->_global->_inter_execPtr[5]; + _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 (_vm->_global->_inter_execPtr[1] == 100) + if (_script->peekByte(1) == 100) deltaTime = 2; } timeVal = deltaTime; - _vm->_global->_inter_execPtr += 6; + _script->skip(6); - startIP = _vm->_global->_inter_execPtr; + startPos = _script->pos(); WRITE_VAR(16, 0); byte var_41 = 0; @@ -452,28 +433,27 @@ void Game_v6::collisionsBlock(void) { for (curCmd = 0; curCmd < count; curCmd++) { array[curCmd] = 0; - cmd = *_vm->_global->_inter_execPtr++; + cmd = _script->readByte(); if ((cmd & 0x40) != 0) { cmd -= 0x40; - cmdHigh = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr++; + cmdHigh = _script->readByte(); cmdHigh <<= 8; } else cmdHigh = 0; if ((cmd & 0x80) != 0) { - offsetIP = _vm->_global->_inter_execPtr - _totFileData; - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + offsetPos = _script->pos(); + left = _script->readValExpr(); + top = _script->readValExpr(); + width = _script->readValExpr(); + height = _script->readValExpr(); } else { - offsetIP = 0; - left = _vm->_inter->load16(); - top = _vm->_inter->load16(); - width = _vm->_inter->load16(); - height = _vm->_inter->load16(); + offsetPos = 0; + left = _script->readUint16(); + top = _script->readUint16(); + width = _script->readUint16(); + height = _script->readUint16(); } if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != 0xFFFF)) { @@ -496,45 +476,37 @@ void Game_v6::collisionsBlock(void) { switch (cmd) { case 0: - _vm->_global->_inter_execPtr += 6; - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _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, startIP - _totFileData, - _vm->_global->_inter_execPtr - _totFileData, offsetIP); + cmd + cmdHigh, key, startPos, + _script->pos(), offsetPos); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 1: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16(); + key = _script->readInt16(); + array[curCmd] = _script->readInt16(); + flags = _script->readInt16(); - startIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + 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, startIP - _totFileData, - _vm->_global->_inter_execPtr - _totFileData, offsetIP); + (flags << 4) + cmd + cmdHigh, key, startPos, + _script->pos(), offsetPos); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; @@ -548,23 +520,20 @@ void Game_v6::collisionsBlock(void) { case 10: _vm->_util->clearKeyBuf(); var_1C = 1; - key = _vm->_parse->parseVarIndex(); - descArray[index].fontIndex = _vm->_inter->load16(); - descArray[index].backColor = *_vm->_global->_inter_execPtr++; - descArray[index].frontColor = *_vm->_global->_inter_execPtr++; + 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 = _vm->_global->_inter_execPtr + 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr) + 2; + 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) { - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); } break; } @@ -575,50 +544,44 @@ void Game_v6::collisionsBlock(void) { funcLeave = 0; if (!(cmd & 1)) - funcLeave = _vm->_global->_inter_execPtr - _totFileData; + funcLeave = _script->pos(); addNewCollision(curCmd + 0x8000, left, top, right, top + height - 1, cmd, key, 0, funcLeave, 0); if (!(cmd & 1)) { - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); } index++; break; case 11: - _vm->_global->_inter_execPtr += 6; + _script->skip(6); for (i = 0; i < 150; i++) { if ((_collisionAreas[i].id & 0xF000) == 0xE000) { _collisionAreas[i].id &= 0xBFFF; _collisionAreas[i].funcEnter = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); _collisionAreas[i].funcLeave = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); } } - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 12: - _vm->_global->_inter_execPtr += 6; + _script->skip(6); for (i = 0; i < 150; i++) { if ((_collisionAreas[i].id & 0xF000) == 0xD000) { _collisionAreas[i].id &= 0xBFFF; _collisionAreas[i].funcEnter = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); _collisionAreas[i].funcLeave = - _vm->_global->_inter_execPtr - _totFileData; + _script->pos(); } } - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 20: @@ -626,34 +589,30 @@ void Game_v6::collisionsBlock(void) { // Fall through to case 2 case 2: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16(); + 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, - _vm->_global->_inter_execPtr - _totFileData, offsetIP); + _script->pos(), offsetPos); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; case 21: - key = _vm->_inter->load16(); - array[curCmd] = _vm->_inter->load16(); - flags = _vm->_inter->load16() & 3; + 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, - _vm->_global->_inter_execPtr - _totFileData, 0, offsetIP); + _script->pos(), 0, offsetPos); - _vm->_global->_inter_execPtr += 2; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _script->skip(_script->peekUint16(2) + 2); break; } @@ -915,10 +874,8 @@ void Game_v6::collisionsBlock(void) { if (_handleMouse == 1) _vm->_draw->blitCursor(); - savedIP = 0; if (!_vm->_inter->_terminate && (var_41 == 0)) { - savedIP = _totFileData + - _collisionAreas[activeCollIndex].funcLeave; + _script->seek(_collisionAreas[activeCollIndex].funcLeave); _vm->_inter->storeMouse(); if (VAR(16) == 0) { @@ -927,7 +884,8 @@ void Game_v6::collisionsBlock(void) { else WRITE_VAR(16, activeCollResId & 0xFFF); } - } + } else + _script->setFinished(true); for (curCmd = 0; curCmd < count; curCmd++) freeCollision(curCmd + 0x8000); @@ -937,8 +895,6 @@ void Game_v6::collisionsBlock(void) { ((_collisionAreas[i].id & 0xF000) == 0x9000)) _collisionAreas[i].id |= 0x4000; } - - _vm->_global->_inter_execPtr = savedIP; } void Game_v6::setCollisions(byte arg_0) { @@ -950,23 +906,22 @@ void Game_v6::setCollisions(byte arg_0) { if (collArea->flags & 0x80) continue; - byte *totFileData = collArea->totFileData; - - if (!totFileData) - totFileData = _totFileData; + Script *curScript = _script; - byte *savedIP = _vm->_global->_inter_execPtr; + _script = collArea->script; + if (!_script) + _script = curScript; - _vm->_global->_inter_execPtr = totFileData + collArea->funcSub; + _script->call(collArea->funcSub); - int16 left = _vm->_parse->parseValExpr(); - int16 top = _vm->_parse->parseValExpr(); - int16 width = _vm->_parse->parseValExpr(); - int16 height = _vm->_parse->parseValExpr(); + 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 = _vm->_parse->parseValExpr(); + flags = _script->readValExpr(); if ((_vm->_draw->_renderFlags & RENDERFLAG_CAPTUREPOP) && (left != -1)) { @@ -1001,16 +956,18 @@ void Game_v6::setCollisions(byte arg_0) { if ((collArea->id & 0xF000) == 0xA000) collArea->flags = flags; - _vm->_global->_inter_execPtr = savedIP; + _script->pop(); + + _script = curScript; } } void Game_v6::collSub(uint16 offset) { - byte *savedIP; int16 collStackSize; - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _totFileData + offset; + uint32 savedPos = _script->pos(); + + _script->seek(offset); _shouldPushColls = 1; collStackSize = _collStackSize; @@ -1021,7 +978,8 @@ void Game_v6::collSub(uint16 offset) { popCollisions(); _shouldPushColls = 0; - _vm->_global->_inter_execPtr = savedIP; + + _script->seek(savedPos); if ((_vm->_util->getTimeKey() - _someTimeDly) > 500) setCollisions(0); diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp index 8283552f2c..4165938966 100644 --- a/engines/gob/global.cpp +++ b/engines/gob/global.cpp @@ -37,35 +37,36 @@ Global::Global(GobEngine *vm) : _vm(vm) { _presentVGA = UNDEF; _presentHER = UNDEF; - _videoMode = 0; + _videoMode = 0; _fakeVideoMode = 0; - _oldMode = 3; + _oldMode = 3; _soundFlags = 0; - _language = 0x8000; + _language = 0x8000; _languageWanted = 0x8000; + _foundLanguage = false; - _useMouse = UNDEF; + _useMouse = UNDEF; _mousePresent = UNDEF; - _mouseXShift = 3; - _mouseYShift = 3; + _mouseXShift = 3; + _mouseYShift = 3; - _mouseMinX = 0; - _mouseMinY = 0; + _mouseMinX = 0; + _mouseMinY = 0; _mouseMaxX = 320; _mouseMaxY = 200; _useJoystick = 1; - _primaryWidth = 0; + _primaryWidth = 0; _primaryHeight = 0; _colorCount = 16; for (int i = 0; i < 256; i++) { - _redPalette[i] = 0; + _redPalette [i] = 0; _greenPalette[i] = 0; - _bluePalette[i] = 0; + _bluePalette [i] = 0; } _unusedPalette1[ 0] = (int16) 0x0000; @@ -109,17 +110,12 @@ Global::Global(GobEngine *vm) : _vm(vm) { _pPaletteDesc = 0; - _setAllPalette = false; + _setAllPalette = false; _dontSetPalette = false; - _primarySurfDesc = 0; - _debugFlag = 0; _inVM = 0; - _inter_resStr[0] = 0; - _inter_resVal = 0; - _inter_execPtr = 0; _inter_animDataSize = 10; diff --git a/engines/gob/global.h b/engines/gob/global.h index 5c63f2b68a..982ce113cb 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -33,37 +33,51 @@ namespace Gob { -#define VIDMODE_CGA 0x05 -#define VIDMODE_EGA 0x0D -#define VIDMODE_VGA 0x13 -#define VIDMODE_HER 7 - -#define PROAUDIO_FLAG 0x10 -#define ADLIB_FLAG 0x08 -#define BLASTER_FLAG 0x04 -#define INTERSOUND_FLAG 0x02 -#define SPEAKER_FLAG 0x01 -#define MIDI_FLAG 0x4000 - -#define NO 0 -#define YES 1 -#define UNDEF 2 - -#define F1_KEY 0x3B00 -#define F2_KEY 0x3C00 -#define F3_KEY 0x3D00 -#define F4_KEY 0x3E00 -#define F5_KEY 0x3F00 -#define F6_KEY 0x4000 -#define ESCAPE 0x001B -#define ENTER 0x000D +#define VIDMODE_CGA 0x05 +#define VIDMODE_EGA 0x0D +#define VIDMODE_VGA 0x13 +#define VIDMODE_HER 0x07 + +#define MIDI_FLAG 0x4000 +#define PROAUDIO_FLAG 0x0010 +#define ADLIB_FLAG 0x0008 +#define BLASTER_FLAG 0x0004 +#define INTERSOUND_FLAG 0x0002 +#define SPEAKER_FLAG 0x0001 + +#define NO 0 +#define YES 1 +#define UNDEF 2 + +#define F1_KEY 0x3B00 +#define F2_KEY 0x3C00 +#define F3_KEY 0x3D00 +#define F4_KEY 0x3E00 +#define F5_KEY 0x3F00 +#define F6_KEY 0x4000 +#define ESCAPE 0x001B +#define ENTER 0x000D /* Video drivers */ -#define UNK_DRIVER 0 -#define VGA_DRIVER 1 -#define EGA_DRIVER 2 -#define CGA_DRIVER 3 -#define HER_DRIVER 4 +#define UNK_DRIVER 0 +#define VGA_DRIVER 1 +#define EGA_DRIVER 2 +#define CGA_DRIVER 3 +#define HER_DRIVER 4 + +enum Language { + kLanguageFrench = 0, + kLanguageGerman = 1, + kLanguageBritish = 2, + kLanguageSpanish = 3, + kLanguageItalian = 4, + kLanguageAmerican = 5, + kLanguageDutch = 6, + kLanguageKorean = 7, + kLanguageHebrew = 8, + kLanguagePortuguese = 9, + kLanguageJapanese = 10 +}; class Global { public: @@ -82,6 +96,7 @@ public: uint16 _language; uint16 _languageWanted; + bool _foundLanguage; char _useMouse; int16 _mousePresent; @@ -112,14 +127,11 @@ public: bool _setAllPalette; bool _dontSetPalette; - SurfaceDesc::Ptr _primarySurfDesc; + SurfaceDescPtr _primarySurfDesc; int16 _debugFlag; int16 _inVM; - char _inter_resStr[200]; - int32 _inter_resVal; - byte *_inter_execPtr; int16 _inter_animDataSize; diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 436a1bf1f3..e534464cce 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -31,6 +31,9 @@ #include "common/md5.h" #include "sound/mididrv.h" +#include "gui/GuiManager.h" +#include "gui/widget.h" + #include "gob/gob.h" #include "gob/global.h" #include "gob/util.h" @@ -44,7 +47,6 @@ #include "gob/map.h" #include "gob/mult.h" #include "gob/palanim.h" -#include "gob/parse.h" #include "gob/scenery.h" #include "gob/videoplayer.h" #include "gob/save/saveload.h" @@ -67,13 +69,44 @@ const Common::Language GobEngine::_gobToScummVMLang[] = { Common::JA_JPN }; + +PauseDialog::PauseDialog() : GUI::Dialog("PauseDialog") { + _backgroundType = GUI::ThemeEngine::kDialogBackgroundSpecial; + + _message = "Game paused. Press Ctrl+p again to continue."; + _text = new GUI::StaticTextWidget(this, 4, 0, 10, 10, + _message, Graphics::kTextAlignCenter); +} + +void PauseDialog::reflowLayout() { + const int screenW = g_system->getOverlayWidth(); + const int screenH = g_system->getOverlayHeight(); + + int width = g_gui.getStringWidth(_message) + 16; + int height = g_gui.getFontHeight() + 8; + + _w = width; + _h = height; + _x = (screenW - width) / 2; + _y = (screenH - height) / 2; + + _text->setSize(_w - 8, _h); +} + +void PauseDialog::handleKeyDown(Common::KeyState state) { + // Close on CTRL+p + if ((state.flags == Common::KBD_CTRL) && (state.keycode == Common::KEYCODE_p)) + close(); +} + + GobEngine::GobEngine(OSystem *syst) : Engine(syst) { - _sound = 0; _mult = 0; _game = 0; - _global = 0; _dataIO = 0; _goblin = 0; - _vidPlayer = 0; _init = 0; _inter = 0; - _map = 0; _palAnim = 0; _parse = 0; - _scenery = 0; _draw = 0; _util = 0; - _video = 0; _saveLoad = 0; + _sound = 0; _mult = 0; _game = 0; + _global = 0; _dataIO = 0; _goblin = 0; + _vidPlayer = 0; _init = 0; _inter = 0; + _map = 0; _palAnim = 0; _scenery = 0; + _draw = 0; _util = 0; _video = 0; + _saveLoad = 0; _pauseStart = 0; @@ -87,7 +120,7 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst) { Common::addDebugChannel(kDebugDrawOp, "DrawOpcodes", "Script DrawOpcodes debug level"); Common::addDebugChannel(kDebugGobOp, "GoblinOpcodes", "Script GoblinOpcodes debug level"); Common::addDebugChannel(kDebugSound, "Sound", "Sound output debug level"); - Common::addDebugChannel(kDebugParser, "Parser", "Parser debug level"); + Common::addDebugChannel(kDebugExpression, "Expression", "Expression parser debug level"); Common::addDebugChannel(kDebugGameFlow, "Gameflow", "Gameflow debug level"); Common::addDebugChannel(kDebugFileIO, "FileIO", "File Input/Output debug level"); Common::addDebugChannel(kDebugSaveLoad, "SaveLoad", "Saving/Loading debug level"); @@ -214,42 +247,42 @@ Common::Error GobEngine::run() { switch (_language) { case Common::FR_FRA: case Common::RU_RUS: - _global->_language = 0; + _global->_language = kLanguageFrench; break; case Common::DE_DEU: - _global->_language = 1; + _global->_language = kLanguageGerman; break; case Common::EN_ANY: case Common::EN_GRB: - _global->_language = 2; + case Common::HU_HUN: + _global->_language = kLanguageBritish; break; case Common::ES_ESP: - _global->_language = 3; + _global->_language = kLanguageSpanish; break; case Common::IT_ITA: - _global->_language = 4; + _global->_language = kLanguageItalian; break; case Common::EN_USA: - _global->_language = 5; + _global->_language = kLanguageAmerican; break; case Common::NL_NLD: - _global->_language = 6; + _global->_language = kLanguageDutch; break; case Common::KO_KOR: - _global->_language = 7; + _global->_language = kLanguageKorean; break; case Common::HB_ISR: - _global->_language = 8; + _global->_language = kLanguageHebrew; break; case Common::PT_BRA: - _global->_language = 9; + _global->_language = kLanguagePortuguese; break; case Common::JA_JPN: - _global->_language = 10; + _global->_language = kLanguageJapanese; break; default: - // Default to English - _global->_language = 2; + _global->_language = kLanguageBritish; break; } _global->_languageWanted = _global->_language; @@ -277,6 +310,16 @@ void GobEngine::pauseEngineIntern(bool pause) { _mixer->pauseAll(pause); } +void GobEngine::pauseGame() { + pauseEngineIntern(true); + + PauseDialog pauseDialog; + + pauseDialog.runModal(); + + pauseEngineIntern(false); +} + bool GobEngine::initGameParts() { _noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL; @@ -296,7 +339,6 @@ bool GobEngine::initGameParts() { _init = new Init_v1(this); _video = new Video_v1(this); _inter = new Inter_v1(this); - _parse = new Parse_v1(this); _mult = new Mult_v1(this); _draw = new Draw_v1(this); _game = new Game_v1(this); @@ -309,7 +351,6 @@ bool GobEngine::initGameParts() { _init = new Init_v2(this); _video = new Video_v2(this); _inter = new Inter_Fascination(this); - _parse = new Parse_v1(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_Fascination(this); @@ -324,7 +365,6 @@ bool GobEngine::initGameParts() { _init = new Init_v2(this); _video = new Video_v2(this); _inter = new Inter_v2(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -338,7 +378,6 @@ bool GobEngine::initGameParts() { _init = new Init_v2(this); _video = new Video_v2(this); _inter = new Inter_Bargon(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_Bargon(this); _game = new Game_v2(this); @@ -353,7 +392,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v3(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -367,7 +405,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v3(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -381,7 +418,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v4(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -398,7 +434,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v2(this); _inter = new Inter_v5(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v2(this); @@ -413,7 +448,6 @@ bool GobEngine::initGameParts() { _init = new Init_v3(this); _video = new Video_v6(this); _inter = new Inter_v6(this); - _parse = new Parse_v2(this); _mult = new Mult_v2(this); _draw = new Draw_v2(this); _game = new Game_v6(this); @@ -429,20 +463,22 @@ bool GobEngine::initGameParts() { break; } + _inter->setupOpcodes(); + if (is640()) { _video->_surfWidth = _width = 640; _video->_surfHeight = _video->_splitHeight1 = _height = 480; _global->_mouseMaxX = 640; _global->_mouseMaxY = 480; _mode = 0x18; - _global->_primarySurfDesc = new SurfaceDesc(0x18, 640, 480); + _global->_primarySurfDesc = SurfaceDescPtr(new SurfaceDesc(0x18, 640, 480)); } else { _video->_surfWidth = _width = 320; _video->_surfHeight = _video->_splitHeight1 = _height = 200; _global->_mouseMaxX = 320; _global->_mouseMaxY = 200; _mode = 0x14; - _global->_primarySurfDesc = new SurfaceDesc(0x14, 320, 200); + _global->_primarySurfDesc = SurfaceDescPtr(new SurfaceDesc(0x14, 320, 200)); } return true; @@ -459,7 +495,6 @@ void GobEngine::deinitGameParts() { delete _inter; _inter = 0; delete _map; _map = 0; delete _palAnim; _palAnim = 0; - delete _parse; _parse = 0; delete _scenery; _scenery = 0; delete _draw; _draw = 0; delete _util; _util = 0; diff --git a/engines/gob/gob.h b/engines/gob/gob.h index 65d6ffeced..5d1cb3ecf2 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -29,8 +29,14 @@ #include "common/system.h" #include "common/savefile.h" +#include "gui/dialog.h" + #include "engines/engine.h" +namespace GUI { + class StaticTextWidget; +} + namespace Gob { class Game; @@ -46,7 +52,6 @@ class Inter; class Map; class Mult; class PalAnim; -class Parse; class Scenery; class Util; class SaveLoad; @@ -122,7 +127,7 @@ enum { kDebugDrawOp = 1 << 1, kDebugGobOp = 1 << 2, kDebugSound = 1 << 3, - kDebugParser = 1 << 4, + kDebugExpression = 1 << 4, kDebugGameFlow = 1 << 5, kDebugFileIO = 1 << 6, kDebugSaveLoad = 1 << 7, @@ -134,6 +139,18 @@ enum { struct GOBGameDescription; +class PauseDialog : public GUI::Dialog { +public: + PauseDialog(); + + virtual void reflowLayout(); + virtual void handleKeyDown(Common::KeyState state); + +private: + Common::String _message; + GUI::StaticTextWidget *_text; +}; + class GobEngine : public Engine { private: GameType _gameType; @@ -179,7 +196,6 @@ public: Map *_map; Mult *_mult; PalAnim *_palAnim; - Parse *_parse; Scenery *_scenery; Inter *_inter; SaveLoad *_saveLoad; @@ -189,6 +205,8 @@ public: void validateLanguage(); void validateVideoMode(int16 videoMode); + void pauseGame(); + Endianness getEndianness() const; Common::Platform getPlatform() const; GameType getGameType() const; diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp index 90303e46a7..45fb643166 100644 --- a/engines/gob/goblin.cpp +++ b/engines/gob/goblin.cpp @@ -233,7 +233,7 @@ void Goblin::drawObjects(void) { if (objDesc->toRedraw == 0) continue; - _vm->_video->drawSprite(_vm->_mult->_animSurf, _vm->_draw->_backSurface, + _vm->_video->drawSprite(*_vm->_mult->_animSurf, *_vm->_draw->_backSurface, objDesc->left, objDesc->top, objDesc->right, objDesc->bottom, objDesc->left, objDesc->top, 0); diff --git a/engines/gob/helper.h b/engines/gob/helper.h index fbb5ae7ec8..d1f24792a5 100644 --- a/engines/gob/helper.h +++ b/engines/gob/helper.h @@ -35,58 +35,6 @@ inline char *strncpy0(char *dest, const char *src, size_t n) { return dest; } -/** A "smart" reference counting templated class. */ -template<typename T> -class ReferenceCounter { -public: - class Ptr { - public: - bool operator==(const Ptr &p) const { return _p == p._p; } - bool operator==(const ReferenceCounter *p) const { return _p == p; } - - T *operator-> () { return _p; } - T &operator* () { return *_p; } - operator T*() { return _p; } - - Ptr(T *p) : _p(p) { ++_p->_references; } - Ptr() : _p(0) { } - - ~Ptr() { - if (_p && (--_p->_references == 0)) - delete _p; - } - - Ptr(const Ptr &p) : _p(p._p) { ++_p->_references; } - - Ptr &operator= (const Ptr &p) { - ++p._p->_references; - if (_p && (--_p->_references == 0)) - delete _p; - _p = p._p; - return *this; - } - Ptr *operator= (const Ptr *p) { - if (p) - ++p->_p->_references; - if (_p && (--_p->_references == 0)) - delete _p; - - _p = p ? p->_p : 0; - return this; - } - - private: - T *_p; - }; - - ReferenceCounter() : _references(0) { } - virtual ~ReferenceCounter() {} - -private: - unsigned _references; - friend class Ptr; -}; - } // End of namespace Gob #endif // GOB_HELPER_H diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index be14b71661..f9a22f52fb 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -32,6 +32,7 @@ #include "gob/dataio.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/script.h" #include "gob/palanim.h" #include "gob/inter.h" #include "gob/video.h" @@ -50,7 +51,7 @@ Init::Init(GobEngine *vm) : _vm(vm) { void Init::cleanup() { _vm->_video->freeDriver(); - _vm->_global->_primarySurfDesc = 0; + _vm->_global->_primarySurfDesc.reset(); _vm->_sound->speakerOff(); _vm->_sound->blasterStop(0); @@ -80,9 +81,6 @@ void Init::doDemo() { } void Init::initGame() { - int16 handle2; - int16 handle; - int16 imdHandle; byte *infBuf; char *infPtr; char *infEnd; @@ -91,11 +89,8 @@ void Init::initGame() { initVideo(); if (!_vm->isDemo()) { - handle2 = _vm->_dataIO->openData(_vm->_startStk.c_str()); - if (handle2 >= 0) { - _vm->_dataIO->closeData(handle2); + if (_vm->_dataIO->existData(_vm->_startStk.c_str())) _vm->_dataIO->openDataFile(_vm->_startStk.c_str()); - } } _vm->_util->initInput(); @@ -104,8 +99,6 @@ void Init::initGame() { _vm->_global->_mouseXShift = 1; _vm->_global->_mouseYShift = 1; - _vm->_game->_totTextData = 0; - _vm->_game->_totFileData = 0; _palDesc = new Video::PalDesc; _vm->validateVideoMode(_vm->_global->_videoMode); @@ -127,19 +120,13 @@ void Init::initGame() { return; } - handle = _vm->_dataIO->openData("intro.inf"); + if (!_vm->_dataIO->existData("intro.inf")) { - if (handle < 0) { - for (int i = 0; i < 4; i++) { - handle2 = _vm->_dataIO->openData(_fontNames[i]); - if (handle2 >= 0) { - _vm->_dataIO->closeData(handle2); + for (int i = 0; i < 4; i++) + if (_vm->_dataIO->existData(_fontNames[i])) _vm->_draw->_fonts[i] = _vm->_util->loadFont(_fontNames[i]); - } - } - } else { - _vm->_dataIO->closeData(handle); + } else { infBuf = _vm->_dataIO->getData("intro.inf"); infPtr = (char *) infBuf; @@ -153,11 +140,8 @@ void Init::initGame() { buffer[j] = 0; strcat(buffer, ".let"); - handle2 = _vm->_dataIO->openData(buffer); - if (handle2 >= 0) { - _vm->_dataIO->closeData(handle2); + if (_vm->_dataIO->existData(buffer)) _vm->_draw->_fonts[i] = _vm->_util->loadFont(buffer); - } if ((infPtr + 1) >= infEnd) break; @@ -167,26 +151,16 @@ void Init::initGame() { delete[] infBuf; } - strcpy(buffer, _vm->_startTot.c_str()); - handle = _vm->_dataIO->openData(buffer); + if (_vm->_dataIO->existData(_vm->_startTot.c_str())) { + _vm->_inter->allocateVars(Script::getVariablesCount(_vm->_startTot.c_str(), _vm)); - if (handle >= 0) { - DataStream *stream = _vm->_dataIO->openAsStream(handle, true); - - stream->seek(0x2C); - _vm->_inter->allocateVars(stream->readUint16LE()); - - delete stream; - - strcpy(_vm->_game->_curTotFile, buffer); + strcpy(_vm->_game->_curTotFile, _vm->_startTot.c_str()); _vm->_sound->cdTest(1, "GOB"); _vm->_sound->cdLoadLIC("gob.lic"); // Search for a Coktel logo animation or image to display - imdHandle = _vm->_dataIO->openData("coktel.imd"); - if (imdHandle >= 0) { - _vm->_dataIO->closeData(imdHandle); + if (_vm->_dataIO->existData("coktel.imd")) { _vm->_draw->initScreen(); _vm->_draw->_cursorIndex = -1; @@ -198,22 +172,20 @@ void Init::initGame() { } _vm->_draw->closeScreen(); - } else if ((imdHandle = _vm->_dataIO->openData("coktel.clt")) >= 0) { + } else if (_vm->_dataIO->existData("coktel.clt")) { _vm->_draw->initScreen(); - - stream = _vm->_dataIO->openAsStream(imdHandle, true); _vm->_util->clearPalette(); + + DataStream *stream = _vm->_dataIO->getDataStream("coktel.clt"); stream->read((byte *) _vm->_draw->_vgaPalette, 768); delete stream; - imdHandle = _vm->_dataIO->openData("coktel.ims"); - if (imdHandle >= 0) { + if (_vm->_dataIO->existData("coktel.ims")) { byte *sprBuf; - _vm->_dataIO->closeData(imdHandle); sprBuf = _vm->_dataIO->getData("coktel.ims"); _vm->_video->drawPackedSprite(sprBuf, 320, 200, 0, 0, 0, - _vm->_draw->_frontSurface); + *_vm->_draw->_frontSurface); _vm->_palAnim->fade(_palDesc, 0, 0); _vm->_util->delay(500); diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp index 9c52bd2eea..4c65b8102c 100644 --- a/engines/gob/init_v2.cpp +++ b/engines/gob/init_v2.cpp @@ -42,7 +42,7 @@ void Init_v2::initVideo() { _vm->_draw->_frontSurface = _vm->_global->_primarySurfDesc; _vm->_video->initSurfDesc(_vm->_global->_videoMode, - _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0x80); + _vm->_video->_surfWidth, _vm->_video->_surfHeight, PRIMARY_SURFACE); _vm->_global->_mousePresent = 1; diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index ce7f2ba319..8be07034c6 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -33,7 +33,8 @@ #include "gob/util.h" #include "gob/draw.h" #include "gob/game.h" -#include "gob/parse.h" +#include "gob/expression.h" +#include "gob/script.h" #include "gob/scenery.h" #include "gob/sound/sound.h" @@ -67,65 +68,93 @@ Inter::~Inter() { delocateVars(); } -void Inter::initControlVars(char full) { - *_nestLevel = 0; - *_breakFromLevel = -1; +void Inter::setupOpcodes() { + setupOpcodesDraw(); + setupOpcodesFunc(); + setupOpcodesGob(); +} - *_vm->_scenery->_pCaptureCounter = 0; +void Inter::executeOpcodeDraw(byte i) { + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", i, i, getDescOpcodeDraw(i)); - _break = false; - _terminate = 0; + if (_opcodesDraw[i].proc && _opcodesDraw[i].proc->isValid()) + (*_opcodesDraw[i].proc)(); + else + warning("unimplemented opcodeDraw: %d [0x%X]", i, i); +} - if (full == 1) { - for (int i = 0; i < 8; i++) - _animPalDir[i] = 0; - _soundEndTimeKey = 0; +bool Inter::executeOpcodeFunc(byte i, byte j, OpFuncParams ¶ms) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", + i, j, i, j, getDescOpcodeFunc(i, j)); + + if ((i > 4) || (j > 15)) { + warning("unimplemented opcodeFunc: %d.%d [0x%X.0x%X]", i, j, i, j); + return false; } + + i = i * 16 + j; + if (_opcodesFunc[i].proc && _opcodesFunc[i].proc->isValid()) + return (*_opcodesFunc[i].proc)(params); + else + warning("unimplemented opcodeFunc: %d.%d [0x%X.0x%X]", i, j, i, j); + + return false; } -int16 Inter::load16() { - int16 tmp = (int16) READ_LE_UINT16(_vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 2; - return tmp; +void Inter::executeOpcodeGob(int i, OpGobParams ¶ms) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", + i, i, getDescOpcodeGob(i)); + + OpcodeEntry<OpcodeGob> *op = 0; + + if (_opcodesGob.contains(i)) + op = &_opcodesGob.getVal(i); + + if (op && op->proc && op->proc->isValid()) { + (*op->proc)(params); + return; + } + + _vm->_game->_script->skip(params.paramCount << 1); + warning("unimplemented opcodeGob: %d [0x%X]", i, i); } -char Inter::evalExpr(int16 *pRes) { - byte token; +const char *Inter::getDescOpcodeDraw(byte i) { + const char *desc = _opcodesDraw[i].desc; - _vm->_parse->printExpr(99); + return ((desc) ? desc : ""); +} - _vm->_parse->parseExpr(99, &token); - if (!pRes) - return token; +const char *Inter::getDescOpcodeFunc(byte i, byte j) { + if ((i > 4) || (j > 15)) + return ""; - switch (token) { - case 20: - *pRes = _vm->_global->_inter_resVal; - break; + const char *desc = _opcodesFunc[i * 16 + j].desc; - case 22: - case 23: - *pRes = 0; - break; + return ((desc) ? desc : ""); +} - case 24: - *pRes = 1; - break; - } +const char *Inter::getDescOpcodeGob(int i) { + if (_opcodesGob.contains(i)) + return _opcodesGob.getVal(i).desc; - return token; + return ""; } -bool Inter::evalBoolResult() { - byte token; +void Inter::initControlVars(char full) { + *_nestLevel = 0; + *_breakFromLevel = -1; + + *_vm->_scenery->_pCaptureCounter = 0; - _vm->_parse->printExpr(99); + _break = false; + _terminate = 0; - _vm->_parse->parseExpr(99, &token); - if ((token == 24) || ((token == 20) && _vm->_global->_inter_resVal)) - return true; - else - return false; + if (full == 1) { + for (int i = 0; i < 8; i++) + _animPalDir[i] = 0; + _soundEndTimeKey = 0; + } } void Inter::renewTimeInVars() { @@ -185,14 +214,14 @@ void Inter::storeKey(int16 key) { void Inter::writeVar(uint32 offset, uint16 type, uint32 value) { switch (type) { - case 16: - case 18: + case TYPE_VAR_INT8: + case TYPE_ARRAY_INT8: WRITE_VARO_UINT8(offset, value); break; - case 17: - case 24: - case 27: + case TYPE_VAR_INT16: + case TYPE_VAR_INT32_AS_INT16: + case TYPE_ARRAY_INT16: WRITE_VARO_UINT16(offset, value); break; @@ -209,20 +238,20 @@ void Inter::funcBlock(int16 retFlag) { params.retFlag = retFlag; - if (!_vm->_global->_inter_execPtr) + if (_vm->_game->_script->isFinished()) return; _break = false; - _vm->_global->_inter_execPtr++; - params.cmdCount = *_vm->_global->_inter_execPtr++; - _vm->_global->_inter_execPtr += 2; + _vm->_game->_script->skip(1); + params.cmdCount = _vm->_game->_script->readByte(); + _vm->_game->_script->skip(2); if (params.cmdCount == 0) { - _vm->_global->_inter_execPtr = 0; + _vm->_game->_script->setFinished(true); return; } - int startaddr = _vm->_global->_inter_execPtr - _vm->_game->_totFileData; + int startaddr = _vm->_game->_script->pos(); params.counter = 0; do { @@ -237,7 +266,7 @@ void Inter::funcBlock(int16 retFlag) { (_vm->getPlatform() == Common::kPlatformMacintosh) || (_vm->getPlatform() == Common::kPlatformWindows))) { - int addr = _vm->_global->_inter_execPtr-_vm->_game->_totFileData; + int addr = _vm->_game->_script->pos(); if ((startaddr == 0x18B4 && addr == 0x1A7F && // Zombie, EGA !strncmp(_vm->_game->_curTotFile, "avt005.tot", 10)) || @@ -263,20 +292,19 @@ void Inter::funcBlock(int16 retFlag) { } // End of workaround - cmd = *_vm->_global->_inter_execPtr; + cmd = _vm->_game->_script->readByte(); if ((cmd >> 4) >= 12) { cmd2 = 16 - (cmd >> 4); cmd &= 0xF; } else cmd2 = 0; - _vm->_global->_inter_execPtr++; params.counter++; if (cmd2 == 0) cmd >>= 4; - if (executeFuncOpcode(cmd2, cmd, params)) + if (executeOpcodeFunc(cmd2, cmd, params)) return; if (_vm->shouldQuit()) @@ -292,17 +320,17 @@ void Inter::funcBlock(int16 retFlag) { } } while (params.counter != params.cmdCount); - _vm->_global->_inter_execPtr = 0; + _vm->_game->_script->setFinished(true); return; } void Inter::callSub(int16 retFlag) { byte block; - while (!_vm->shouldQuit() && _vm->_global->_inter_execPtr && - (_vm->_global->_inter_execPtr != _vm->_game->_totFileData)) { + while (!_vm->shouldQuit() && !_vm->_game->_script->isFinished() && + (_vm->_game->_script->pos() != 0)) { - block = *_vm->_global->_inter_execPtr; + block = _vm->_game->_script->peekByte(); if (block == 1) funcBlock(retFlag); else if (block == 2) @@ -311,7 +339,7 @@ void Inter::callSub(int16 retFlag) { error("Unknown block type %d in Inter::callSub()", block); } - if (_vm->_global->_inter_execPtr == _vm->_game->_totFileData) + if (!_vm->_game->_script->isFinished() && (_vm->_game->_script->pos() == 0)) _terminate = 1; } diff --git a/engines/gob/inter.h b/engines/gob/inter.h index ee49658318..d4ed2d3240 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -26,6 +26,9 @@ #ifndef GOB_INTER_H #define GOB_INTER_H +#include "common/func.h" +#include "common/hashmap.h" + #include "gob/goblin.h" #include "gob/variables.h" @@ -34,11 +37,54 @@ namespace Gob { // This is to help devices with small memory (PDA, smartphones, ...) // to save abit of memory used by opcode names in the Scumm engine. #ifndef REDUCE_MEMORY_USAGE -# define _OPCODE(ver, x) { &ver::x, #x } + #define _OPCODEDRAW(ver, x) setProc(new Common::Functor0Mem<void, ver>(this, &ver::x), #x) + #define _OPCODEFUNC(ver, x) setProc(new Common::Functor1Mem<OpFuncParams &, bool, ver>(this, &ver::x), #x) + #define _OPCODEGOB(ver, x) setProc(new Common::Functor1Mem<OpGobParams &, void, ver>(this, &ver::x), #x) #else -# define _OPCODE(ver, x) { &ver::x, "" } + #define _OPCODEDRAW(ver, x) setProc(new Common::Functor0Mem<void, ver>(this, &ver::x), "") + #define _OPCODEFUNC(ver, x) setProc(new Common::Functor1Mem<OpFuncParams &, bool, ver>(this, &ver::x), "") + #define _OPCODEGOB(ver, x) setProc(new Common::Functor1Mem<OpGobParams &, void, ver>(this, &ver::x), "") #endif +#define CLEAROPCODEDRAW(i) _opcodesDraw[i].setProc(0, 0) +#define CLEAROPCODEFUNC(i) _opcodesFunc[i].setProc(0, 0) +#define CLEAROPCODEGOB(i) _opcodesGob.erase(i) + +typedef Common::Functor0<void> OpcodeDraw; +typedef Common::Functor1<struct OpFuncParams &, bool> OpcodeFunc; +typedef Common::Functor1<struct OpGobParams &, void> OpcodeGob; + +struct OpFuncParams { + byte cmdCount; + byte counter; + int16 retFlag; +}; +struct OpGobParams { + int16 extraData; + int16 paramCount; + VariableReference retVarPtr; + Goblin::Gob_Object *objDesc; +}; + +template<typename T> +struct OpcodeEntry : Common::NonCopyable { + T *proc; + const char *desc; + + OpcodeEntry() : proc(0), desc(0) {} + ~OpcodeEntry() { + setProc(0, 0); + } + + void setProc(T *p, const char *d) { + if (proc != p) { + delete proc; + proc = p; + } + desc = d; + } +}; + class Inter { public: uint8 _terminate; @@ -51,10 +97,9 @@ public: Variables *_variables; + void setupOpcodes(); + void initControlVars(char full); - int16 load16(); - char evalExpr(int16 *pRes); - bool evalBoolResult(); void renewTimeInVars(); void storeMouse(); void storeKey(int16 key); @@ -74,16 +119,9 @@ public: virtual ~Inter(); protected: - struct OpFuncParams { - byte cmdCount; - byte counter; - int16 retFlag; - }; - struct OpGobParams { - int16 extraData; - VariableReference retVarPtr; - Goblin::Gob_Object *objDesc; - }; + OpcodeEntry<OpcodeDraw> _opcodesDraw[256]; + OpcodeEntry<OpcodeFunc> _opcodesFunc[256]; + Common::HashMap<int, OpcodeEntry<OpcodeGob> > _opcodesGob; bool _break; @@ -99,15 +137,19 @@ protected: GobEngine *_vm; - virtual void setupOpcodes() = 0; - virtual void executeDrawOpcode(byte i) = 0; - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) = 0; - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms) = 0; - virtual const char *getOpcodeDrawDesc(byte i) = 0; - virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0; - virtual const char *getOpcodeGoblinDesc(int i) = 0; + void executeOpcodeDraw(byte i); + bool executeOpcodeFunc(byte i, byte j, OpFuncParams ¶ms); + void executeOpcodeGob(int i, OpGobParams ¶ms); + + const char *getDescOpcodeDraw(byte i); + const char *getDescOpcodeFunc(byte i, byte j); + const char *getDescOpcodeGob(int i); - virtual void checkSwitchTable(byte **ppExec) = 0; + virtual void setupOpcodesDraw() = 0; + virtual void setupOpcodesFunc() = 0; + virtual void setupOpcodesGob() = 0; + + virtual void checkSwitchTable(uint32 &offset) = 0; void o_drawNOP() {} bool o_funcNOP(OpFuncParams ¶ms) { return false; } @@ -123,35 +165,11 @@ public: virtual void animPalette(); protected: - typedef void (Inter_v1::*OpcodeDrawProcV1)(); - typedef bool (Inter_v1::*OpcodeFuncProcV1)(OpFuncParams &); - typedef void (Inter_v1::*OpcodeGoblinProcV1)(OpGobParams &); - struct OpcodeDrawEntryV1 { - OpcodeDrawProcV1 proc; - const char *desc; - }; - struct OpcodeFuncEntryV1 { - OpcodeFuncProcV1 proc; - const char *desc; - }; - struct OpcodeGoblinEntryV1 { - OpcodeGoblinProcV1 proc; - const char *desc; - }; - const OpcodeDrawEntryV1 *_opcodesDrawV1; - const OpcodeFuncEntryV1 *_opcodesFuncV1; - const OpcodeGoblinEntryV1 *_opcodesGoblinV1; - static const int _goblinFuncLookUp[][2]; - - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); - - virtual void checkSwitchTable(byte **ppExec); + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); + + virtual void checkSwitchTable(uint32 &offset); void o1_loadMult(); void o1_playMult(); @@ -185,7 +203,7 @@ protected: bool o1_repeatUntil(OpFuncParams ¶ms); bool o1_whileDo(OpFuncParams ¶ms); bool o1_if(OpFuncParams ¶ms); - bool o1_evaluateStore(OpFuncParams ¶ms); + bool o1_assign(OpFuncParams ¶ms); bool o1_loadSpriteToPos(OpFuncParams ¶ms); bool o1_printText(OpFuncParams ¶ms); bool o1_loadTot(OpFuncParams ¶ms); @@ -318,35 +336,11 @@ public: virtual void animPalette(); protected: - typedef void (Inter_v2::*OpcodeDrawProcV2)(); - typedef bool (Inter_v2::*OpcodeFuncProcV2)(OpFuncParams &); - typedef void (Inter_v2::*OpcodeGoblinProcV2)(OpGobParams &); - struct OpcodeDrawEntryV2 { - OpcodeDrawProcV2 proc; - const char *desc; - }; - struct OpcodeFuncEntryV2 { - OpcodeFuncProcV2 proc; - const char *desc; - }; - struct OpcodeGoblinEntryV2 { - OpcodeGoblinProcV2 proc; - const char *desc; - }; - const OpcodeDrawEntryV2 *_opcodesDrawV2; - const OpcodeFuncEntryV2 *_opcodesFuncV2; - const OpcodeGoblinEntryV2 *_opcodesGoblinV2; - static const int _goblinFuncLookUp[][2]; - - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); - - virtual void checkSwitchTable(byte **ppExec); + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); + + virtual void checkSwitchTable(uint32 &offset); void o2_playMult(); void o2_freeMultKeys(); @@ -383,7 +377,7 @@ protected: void o2_closeItk(); void o2_setImdFrontSurf(); void o2_resetImdFrontSurf(); - bool o2_evaluateStore(OpFuncParams ¶ms); + bool o2_assign(OpFuncParams ¶ms); bool o2_printText(OpFuncParams ¶ms); bool o2_animPalInit(OpFuncParams ¶ms); bool o2_addCollision(OpFuncParams ¶ms); @@ -410,33 +404,9 @@ public: virtual ~Inter_Bargon() {} protected: - typedef void (Inter_Bargon::*OpcodeDrawProcBargon)(); - typedef bool (Inter_Bargon::*OpcodeFuncProcBargon)(OpFuncParams &); - typedef void (Inter_Bargon::*OpcodeGoblinProcBargon)(OpGobParams &); - struct OpcodeDrawEntryBargon { - OpcodeDrawProcBargon proc; - const char *desc; - }; - struct OpcodeFuncEntryBargon { - OpcodeFuncProcBargon proc; - const char *desc; - }; - struct OpcodeGoblinEntryBargon { - OpcodeGoblinProcBargon proc; - const char *desc; - }; - const OpcodeDrawEntryBargon *_opcodesDrawBargon; - const OpcodeFuncEntryBargon *_opcodesFuncBargon; - const OpcodeGoblinEntryBargon *_opcodesGoblinBargon; - static const int _goblinFuncLookUp[][2]; - - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); void oBargon_intro0(OpGobParams ¶ms); void oBargon_intro1(OpGobParams ¶ms); @@ -456,33 +426,9 @@ public: virtual ~Inter_Fascination() {} protected: - typedef void (Inter_Fascination::*OpcodeDrawProcFascination)(); - typedef bool (Inter_Fascination::*OpcodeFuncProcFascination)(OpFuncParams &); - typedef void (Inter_Fascination::*OpcodeGoblinProcFascination)(OpGobParams &); - struct OpcodeDrawEntryFascination { - OpcodeDrawProcFascination proc; - const char *desc; - }; - struct OpcodeFuncEntryFascination { - OpcodeFuncProcFascination proc; - const char *desc; - }; - struct OpcodeGoblinEntryFascination { - OpcodeGoblinProcFascination proc; - const char *desc; - }; - const OpcodeDrawEntryFascination *_opcodesDrawFascination; - const OpcodeFuncEntryFascination *_opcodesFuncFascination; - const OpcodeGoblinEntryFascination *_opcodesGoblinFascination; - static const int _goblinFuncLookUp[][2]; - - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); void oFascin_playProtracker(OpGobParams ¶ms); @@ -517,39 +463,12 @@ public: virtual ~Inter_v3() {} protected: - typedef void (Inter_v3::*OpcodeDrawProcV3)(); - typedef bool (Inter_v3::*OpcodeFuncProcV3)(OpFuncParams &); - typedef void (Inter_v3::*OpcodeGoblinProcV3)(OpGobParams &); - struct OpcodeDrawEntryV3 { - OpcodeDrawProcV3 proc; - const char *desc; - }; - struct OpcodeFuncEntryV3 { - OpcodeFuncProcV3 proc; - const char *desc; - }; - struct OpcodeGoblinEntryV3 { - OpcodeGoblinProcV3 proc; - const char *desc; - }; - const OpcodeDrawEntryV3 *_opcodesDrawV3; - const OpcodeFuncEntryV3 *_opcodesFuncV3; - const OpcodeGoblinEntryV3 *_opcodesGoblinV3; - static const int _goblinFuncLookUp[][2]; - - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); bool o3_getTotTextItemPart(OpFuncParams ¶ms); bool o3_copySprite(OpFuncParams ¶ms); - bool o3_checkData(OpFuncParams ¶ms); - bool o3_readData(OpFuncParams ¶ms); - bool o3_writeData(OpFuncParams ¶ms); void o3_wobble(OpGobParams ¶ms); }; @@ -560,33 +479,9 @@ public: virtual ~Inter_v4() {} protected: - typedef void (Inter_v4::*OpcodeDrawProcV4)(); - typedef bool (Inter_v4::*OpcodeFuncProcV4)(OpFuncParams &); - typedef void (Inter_v4::*OpcodeGoblinProcV4)(OpGobParams &); - struct OpcodeDrawEntryV4 { - OpcodeDrawProcV4 proc; - const char *desc; - }; - struct OpcodeFuncEntryV4 { - OpcodeFuncProcV4 proc; - const char *desc; - }; - struct OpcodeGoblinEntryV4 { - OpcodeGoblinProcV4 proc; - const char *desc; - }; - const OpcodeDrawEntryV4 *_opcodesDrawV4; - const OpcodeFuncEntryV4 *_opcodesFuncV4; - const OpcodeGoblinEntryV4 *_opcodesGoblinV4; - static const int _goblinFuncLookUp[][2]; - - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); void o4_initScreen(); void o4_playVmdOrMusic(); @@ -598,36 +493,12 @@ public: virtual ~Inter_v5() {} protected: - typedef void (Inter_v5::*OpcodeDrawProcV5)(); - typedef bool (Inter_v5::*OpcodeFuncProcV5)(OpFuncParams &); - typedef void (Inter_v5::*OpcodeGoblinProcV5)(OpGobParams &); - struct OpcodeDrawEntryV5 { - OpcodeDrawProcV5 proc; - const char *desc; - }; - struct OpcodeFuncEntryV5 { - OpcodeFuncProcV5 proc; - const char *desc; - }; - struct OpcodeGoblinEntryV5 { - OpcodeGoblinProcV5 proc; - const char *desc; - }; - const OpcodeDrawEntryV5 *_opcodesDrawV5; - const OpcodeFuncEntryV5 *_opcodesFuncV5; - const OpcodeGoblinEntryV5 *_opcodesGoblinV5; - static const int _goblinFuncLookUp[][2]; - - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); - byte _gob_97_98_val; + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); + void o5_deleteFile(); void o5_initScreen(); @@ -657,42 +528,18 @@ public: virtual ~Inter_v6() {} protected: - typedef void (Inter_v6::*OpcodeDrawProcV6)(); - typedef bool (Inter_v6::*OpcodeFuncProcV6)(OpFuncParams &); - typedef void (Inter_v6::*OpcodeGoblinProcV6)(OpGobParams &); - struct OpcodeDrawEntryV6 { - OpcodeDrawProcV6 proc; - const char *desc; - }; - struct OpcodeFuncEntryV6 { - OpcodeFuncProcV6 proc; - const char *desc; - }; - struct OpcodeGoblinEntryV6 { - OpcodeGoblinProcV6 proc; - const char *desc; - }; - const OpcodeDrawEntryV6 *_opcodesDrawV6; - const OpcodeFuncEntryV6 *_opcodesFuncV6; - const OpcodeGoblinEntryV6 *_opcodesGoblinV6; - static const int _goblinFuncLookUp[][2]; - bool _gotFirstPalette; - virtual void setupOpcodes(); - virtual void executeDrawOpcode(byte i); - virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); - virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); - virtual const char *getOpcodeDrawDesc(byte i); - virtual const char *getOpcodeFuncDesc(byte i, byte j); - virtual const char *getOpcodeGoblinDesc(int i); + virtual void setupOpcodesDraw(); + virtual void setupOpcodesFunc(); + virtual void setupOpcodesGob(); void o6_totSub(); void o6_playVmdOrMusic(); void o6_openItk(); bool o6_loadCursor(OpFuncParams ¶ms); - bool o6_evaluateStore(OpFuncParams ¶ms); + bool o6_assign(OpFuncParams ¶ms); bool o6_palLoad(OpFuncParams ¶ms); bool o6_freeCollision(OpFuncParams ¶ms); bool o6_fillRect(OpFuncParams ¶ms); diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index c729bf3c4c..12079600c0 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -39,680 +39,36 @@ namespace Gob { -#define OPCODE(x) _OPCODE(Inter_Bargon, x) - -const int Inter_Bargon::_goblinFuncLookUp[][2] = { - {1, 0}, - {2, 1}, - {3, 2}, - {4, 3}, - {5, 4}, - {6, 5}, - {7, 6}, - {8, 7}, - {9, 8}, - {10, 9}, - {11, 10}, - {13, 11}, - {14, 12}, - {15, 13}, - {16, 14}, - {21, 15}, - {22, 16}, - {23, 17}, - {24, 18}, - {25, 19}, - {26, 20}, - {27, 21}, - {28, 22}, - {29, 23}, - {30, 24}, - {32, 25}, - {33, 26}, - {34, 27}, - {35, 28}, - {36, 29}, - {37, 30}, - {40, 31}, - {41, 32}, - {42, 33}, - {43, 34}, - {44, 35}, - {50, 36}, - {52, 37}, - {53, 38}, - {100, 39}, - {152, 40}, - {200, 41}, - {201, 42}, - {202, 43}, - {203, 44}, - {204, 45}, - {250, 46}, - {251, 47}, - {252, 48}, - {500, 49}, - {502, 50}, - {503, 51}, - {600, 52}, - {601, 53}, - {602, 54}, - {603, 55}, - {604, 56}, - {605, 57}, - {1000, 58}, - {1001, 59}, - {1002, 60}, - {1003, 61}, - {1004, 62}, - {1005, 63}, - {1006, 64}, - {1008, 65}, - {1009, 66}, - {1010, 67}, - {1011, 68}, - {1015, 69}, - {2005, 70} -}; +#define OPCODEVER Inter_Bargon +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_Bargon::Inter_Bargon(GobEngine *vm) : Inter_v2(vm) { - setupOpcodes(); } -void Inter_Bargon::setupOpcodes() { - static const OpcodeDrawEntryBargon opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o2_playMult), - OPCODE(o1_freeMultKeys), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(o2_setRenderFlags), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - OPCODE(o2_multSub), - /* 14 */ - OPCODE(o2_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o2_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o2_renderStatic), - OPCODE(o2_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o2_playCDTrack), - OPCODE(o2_waitCDTrackEnd), - OPCODE(o2_stopCD), - OPCODE(o2_readLIC), - /* 24 */ - OPCODE(o2_freeLIC), - OPCODE(o2_getCDTrackPos), - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o2_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - OPCODE(o2_totSub), - OPCODE(o2_switchTotSub), - OPCODE(o2_pushVars), - OPCODE(o2_popVars), - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - OPCODE(o2_loadMapObjects), - OPCODE(o2_freeGoblins), - OPCODE(o2_moveGoblin), - OPCODE(o2_writeGoblinPos), - /* 54 */ - OPCODE(o2_stopGoblin), - OPCODE(o2_setGoblinState), - OPCODE(o2_placeGoblin), - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - OPCODE(o2_initScreen), - OPCODE(o2_scroll), - OPCODE(o2_setScrollOffset), - OPCODE(o2_playImd), - /* 84 */ - OPCODE(o2_getImdInfo), - OPCODE(o2_openItk), - OPCODE(o2_closeItk), - OPCODE(o2_setImdFrontSurf), - /* 88 */ - OPCODE(o2_resetImdFrontSurf), - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryBargon opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o1_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o2_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o2_printText), - OPCODE(o1_loadTot), - OPCODE(o1_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o2_animPalInit), - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o2_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o1_copySprite), - OPCODE(o1_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o2_stopSound), - OPCODE(o2_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o2_getFreeMem), - OPCODE(o2_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o1_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o2_readData), - OPCODE(o2_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryBargon opcodesGoblin[71] = { - /* 00 */ - OPCODE(oBargon_intro0), - OPCODE(oBargon_intro1), - OPCODE(oBargon_intro2), - OPCODE(oBargon_intro3), - /* 04 */ - OPCODE(oBargon_intro4), - OPCODE(oBargon_intro5), - OPCODE(oBargon_intro6), - OPCODE(oBargon_intro7), - /* 08 */ - OPCODE(oBargon_intro8), - OPCODE(oBargon_intro9), - OPCODE(o_gobNOP), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 14 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 20 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 24 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - }; - - _opcodesDrawBargon = opcodesDraw; - _opcodesFuncBargon = opcodesFunc; - _opcodesGoblinBargon = opcodesGoblin; +void Inter_Bargon::setupOpcodesDraw() { + Inter_v2::setupOpcodesDraw(); } -void Inter_Bargon::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); - - OpcodeDrawProcBargon op = _opcodesDrawBargon[i].proc; - - if (op == 0) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); +void Inter_Bargon::setupOpcodesFunc() { + Inter_v2::setupOpcodesFunc(); } -bool Inter_Bargon::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", - i, j, i, j, getOpcodeFuncDesc(i, j)); +void Inter_Bargon::setupOpcodesGob() { + OPCODEGOB( 1, oBargon_intro0); + OPCODEGOB( 2, oBargon_intro1); + OPCODEGOB( 3, oBargon_intro2); + OPCODEGOB( 4, oBargon_intro3); - if ((i > 4) || (j > 15)) { - warning("unimplemented opcodeFunc: %d.%d", i, j); - return false; - } + OPCODEGOB( 5, oBargon_intro4); + OPCODEGOB( 6, oBargon_intro5); + OPCODEGOB( 7, oBargon_intro6); + OPCODEGOB( 8, oBargon_intro7); - OpcodeFuncProcBargon op = _opcodesFuncBargon[i*16 + j].proc; - - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); - - return false; -} - -void Inter_Bargon::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); - - OpcodeGoblinProcBargon op = 0; - - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinBargon[_goblinFuncLookUp[j][1]].proc; - break; - } - - if (op == 0) { - int16 val; - - _vm->_global->_inter_execPtr -= 2; - val = load16(); - _vm->_global->_inter_execPtr += val << 1; - warning("unimplemented opcodeGob: %d", i); - } else - (this->*op) (params); -} - -const char *Inter_Bargon::getOpcodeDrawDesc(byte i) { - return _opcodesDrawBargon[i].desc; -} - -const char *Inter_Bargon::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; - - return _opcodesFuncBargon[i*16 + j].desc; -} - -const char *Inter_Bargon::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinBargon[_goblinFuncLookUp[j][1]].desc; - return ""; + OPCODEGOB( 9, oBargon_intro8); + OPCODEGOB(10, oBargon_intro9); + OPCODEGOB(11, o_gobNOP); } void Inter_Bargon::oBargon_intro0(OpGobParams ¶ms) { @@ -734,16 +90,16 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { int16 mouseX; int16 mouseY; int16 buttons; - SurfaceDesc *surface; + SurfaceDescPtr surface; SoundDesc samples[4]; int16 comp[5] = { 0, 1, 2, 3, -1 }; static const char *sndFiles[] = {"1INTROII.snd", "2INTROII.snd", "1INTRO3.snd", "2INTRO3.snd"}; surface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); - _vm->_video->drawPackedSprite("2ille.ims", surface); - _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 0, 0, 0); - _vm->_video->drawPackedSprite("2ille4.ims", surface); - _vm->_video->drawSprite(surface, _vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); + _vm->_video->drawPackedSprite("2ille.ims", *surface); + _vm->_video->drawSprite(*surface, *_vm->_draw->_frontSurface, 0, 0, 319, 199, 0, 0, 0); + _vm->_video->drawPackedSprite("2ille4.ims", *surface); + _vm->_video->drawSprite(*surface, *_vm->_draw->_frontSurface, 0, 0, 319, 199, 320, 0, 0); _vm->_util->setScrollOffset(320, 0); _vm->_video->dirtyRectsAll(); _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); @@ -754,7 +110,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { if ((_vm->_game->checkKeys(&mouseX, &mouseY, &buttons, 0) == 0x11B) || _vm->shouldQuit()) { _vm->_palAnim->fade(0, -2, 0); - _vm->_video->clearSurf(_vm->_draw->_frontSurface); + _vm->_video->clearSurf(*_vm->_draw->_frontSurface); memset((char *) _vm->_draw->_vgaPalette, 0, 768); WRITE_VAR(4, buttons); WRITE_VAR(0, 0x11B); @@ -766,7 +122,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { _vm->_util->setScrollOffset(0, 0); _vm->_video->dirtyRectsAll(); } - surface = 0; + surface.reset(); if (VAR(57) == ((uint32) -1)) return; @@ -775,7 +131,7 @@ void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { _vm->_sound->blasterPlayComposition(comp, 0, samples, 4); _vm->_sound->blasterWaitEndPlay(true, false); _vm->_palAnim->fade(0, 0, 0); - _vm->_video->clearSurf(_vm->_draw->_frontSurface); + _vm->_video->clearSurf(*_vm->_draw->_frontSurface); } void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { @@ -806,8 +162,8 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { _vm->shouldQuit()) { _vm->_sound->blasterStop(10); _vm->_palAnim->fade(0, -2, 0); - _vm->_video->clearSurf(_vm->_draw->_frontSurface); - memset((char *) _vm->_draw->_vgaPalette, 0, 768); + _vm->_video->clearSurf(*_vm->_draw->_frontSurface); + memset(_vm->_draw->_vgaPalette, 0, 768); WRITE_VAR(4, buttons); WRITE_VAR(0, 0x11B); WRITE_VAR(57, (uint32) -1); diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp index 58c3e703ff..3c4713f9eb 100644 --- a/engines/gob/inter_fascin.cpp +++ b/engines/gob/inter_fascin.cpp @@ -31,8 +31,8 @@ #include "gob/util.h" #include "gob/dataio.h" #include "gob/draw.h" -#include "gob/parse.h" #include "gob/game.h" +#include "gob/script.h" #include "gob/palanim.h" #include "gob/video.h" #include "gob/videoplayer.h" @@ -40,494 +40,73 @@ namespace Gob { -#define OPCODE(x) _OPCODE(Inter_Fascination, x) - -const int Inter_Fascination::_goblinFuncLookUp[][2] = { - {1, 0}, - {2, 1}, - {3, 2}, - {4, 3}, - {5, 4}, - {6, 5}, - {7, 6}, - {8, 7}, - {9, 8}, - {10, 9}, - {11, 10}, - {12, 11}, - {1000, 12}, - {1001, 13}, - {1002, 14} -}; +#define OPCODEVER Inter_Fascination +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_Fascination::Inter_Fascination(GobEngine *vm) : Inter_v2(vm) { - setupOpcodes(); } -void Inter_Fascination::setupOpcodes() { - static const OpcodeDrawEntryFascination opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o2_playMult), - OPCODE(o1_freeMultKeys), - OPCODE(oFascin_cdUnknown3), - /* 04 */ - OPCODE(oFascin_cdUnknown4), - OPCODE(oFascin_cdUnknown5), - OPCODE(oFascin_cdUnknown6), - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(oFascin_setRenderFlags), - OPCODE(oFascin_cdUnknown11), - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - OPCODE(o2_multSub), - /* 14 */ - OPCODE(o2_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o2_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o2_renderStatic), - OPCODE(o2_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o2_playCDTrack), - OPCODE(o2_waitCDTrackEnd), - OPCODE(o2_stopCD), - OPCODE(o2_readLIC), - /* 24 */ - OPCODE(o2_freeLIC), - OPCODE(o2_getCDTrackPos), - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o2_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - OPCODE(o2_totSub), - OPCODE(o2_switchTotSub), - OPCODE(o2_pushVars), - OPCODE(o2_popVars), - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - {0, ""},//OPCODE(o2_loadMapObjects), - {0, ""},//OPCODE(o2_freeGoblins), - {0, ""},//OPCODE(o2_moveGoblin), - {0, ""},//OPCODE(o2_writeGoblinPos), - /* 54 */ - {0, ""},//OPCODE(o2_stopGoblin), - {0, ""},//OPCODE(o2_setGoblinState), - {0, ""},//OPCODE(o2_placeGoblin), - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - {0, ""},//OPCODE(o2_initScreen), - {0, ""},//OPCODE(o2_scroll), - {0, ""},//OPCODE(o2_setScrollOffset), - {0, ""},//OPCODE(o2_playImd), - /* 84 */ - {0, ""},//OPCODE(o2_getImdInfo), - {0, ""},//OPCODE(o2_openItk), - {0, ""},//OPCODE(o2_closeItk), - {0, ""},//OPCODE(o2_setImdFrontSurf), - /* 88 */ - {0, ""},//OPCODE(o2_resetImdFrontSurf), - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryFascination opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o1_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o2_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o2_printText), - OPCODE(o1_loadTot), - OPCODE(o1_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o1_animPalInit), - /* 18 */ - OPCODE(o2_addCollision), - OPCODE(o2_freeCollision), - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o2_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o1_copySprite), - OPCODE(o1_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o2_stopSound), - OPCODE(o2_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o2_getFreeMem), - OPCODE(o2_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o1_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o2_readData), - OPCODE(o2_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryFascination opcodesGoblin[15] = { - /* 00 */ - OPCODE(oFascin_geUnknown0), - OPCODE(oFascin_geUnknown1), - OPCODE(oFascin_geUnknown2), - OPCODE(oFascin_geUnknown3), - /* 04 */ - OPCODE(oFascin_geUnknown4), - OPCODE(oFascin_geUnknown5), - OPCODE(oFascin_geUnknown6), - OPCODE(oFascin_geUnknown7), - /* 08 */ - OPCODE(oFascin_geUnknown8), - OPCODE(oFascin_geUnknown9), - OPCODE(oFascin_geUnknown10), - OPCODE(oFascin_geUnknown11), - /* 0C */ - OPCODE(oFascin_geUnknown1000), - OPCODE(oFascin_geUnknown1001), //protrackerPlay doesn't play correctly "mod.extasy" - OPCODE(oFascin_geUnknown1002), //to be replaced by o2_stopProtracker when protrackerPlay is fixed - }; - - _opcodesDrawFascination = opcodesDraw; - _opcodesFuncFascination = opcodesFunc; - _opcodesGoblinFascination = opcodesGoblin; +void Inter_Fascination::setupOpcodesDraw() { + Inter_v2::setupOpcodesDraw(); + + OPCODEDRAW(0x03, oFascin_cdUnknown3); + + OPCODEDRAW(0x04, oFascin_cdUnknown4); + OPCODEDRAW(0x05, oFascin_cdUnknown5); + OPCODEDRAW(0x06, oFascin_cdUnknown6); + + OPCODEDRAW(0x0A, oFascin_setRenderFlags); + OPCODEDRAW(0x0B, oFascin_cdUnknown11); + + CLEAROPCODEDRAW(0x50); + CLEAROPCODEDRAW(0x51); + CLEAROPCODEDRAW(0x52); + CLEAROPCODEDRAW(0x53); + + CLEAROPCODEDRAW(0x54); + CLEAROPCODEDRAW(0x55); + CLEAROPCODEDRAW(0x56); + + CLEAROPCODEDRAW(0x80); + CLEAROPCODEDRAW(0x81); + CLEAROPCODEDRAW(0x82); + CLEAROPCODEDRAW(0x83); + + CLEAROPCODEDRAW(0x84); + CLEAROPCODEDRAW(0x85); + CLEAROPCODEDRAW(0x86); + CLEAROPCODEDRAW(0x87); + + CLEAROPCODEDRAW(0x88); } -void Inter_Fascination::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); +void Inter_Fascination::setupOpcodesFunc() { + Inter_v2::setupOpcodesFunc(); - OpcodeDrawProcFascination op = _opcodesDrawFascination[i].proc; + OPCODEFUNC(0x09, o1_assign); +} + +void Inter_Fascination::setupOpcodesGob() { + OPCODEGOB( 1, oFascin_geUnknown0); + OPCODEGOB( 2, oFascin_geUnknown1); + OPCODEGOB( 3, oFascin_geUnknown2); + OPCODEGOB( 4, oFascin_geUnknown3); + + OPCODEGOB( 5, oFascin_geUnknown4); + OPCODEGOB( 6, oFascin_geUnknown5); + OPCODEGOB( 7, oFascin_geUnknown6); + OPCODEGOB( 8, oFascin_geUnknown7); + + OPCODEGOB( 9, oFascin_geUnknown8); + OPCODEGOB( 10, oFascin_geUnknown9); + OPCODEGOB( 11, oFascin_geUnknown10); + OPCODEGOB( 12, oFascin_geUnknown11); - if (op == 0) - warning("Not yet implemented Fascination opcodeDraw: %d", i); - else - (this->*op) (); + OPCODEGOB(1000, oFascin_geUnknown1000); + OPCODEGOB(1001, oFascin_geUnknown1001); //protrackerPlay doesn't play correctly "mod.extasy" + OPCODEGOB(1002, oFascin_geUnknown1002); //to be replaced by o2_stopProtracker when protrackerPlay is fixed } void Inter_Fascination::oFascin_geUnknown0(OpGobParams ¶ms) { @@ -552,70 +131,58 @@ void Inter_Fascination::oFascin_geUnknown1(OpGobParams ¶ms) { } void Inter_Fascination::oFascin_geUnknown2(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 2"); - warning("funcLoadInstruments with parameter : 'extasy.tbr'. (Guess)"); - warning("funcLoadMusic with parameter : 'extasy.mdy'. (Guess)"); + _vm->_sound->adlibLoadTBR("extasy.tbr"); + _vm->_sound->adlibLoadMDY("extasy.mdy"); } void Inter_Fascination::oFascin_geUnknown3(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 3"); - warning("Verify if 'Guess music' is loaded. If yes, call funcPlayMusic. (Guess)"); + _vm->_sound->adlibPlay(); } void Inter_Fascination::oFascin_geUnknown4(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 4"); - warning("Verify if 'Guess music' is loaded. If yes, call funcStopMusic. (Guess)"); + _vm->_sound->adlibStop(); } void Inter_Fascination::oFascin_geUnknown5(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 5"); - warning("Verify if 'instruments' are loaded, If so, call mem_free"); - warning("Verify if 'Guess music' is loaded. If yes, call _cleanupMdy"); - warning("Then set _ptrTbr and _ptrMdy to 0"); + _vm->_sound->adlibUnload(); } void Inter_Fascination::oFascin_geUnknown6(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 6"); - warning("funcLoadInstruments with parameter : 'music1.tbr'. (Guess)"); - warning("funcLoadMusic with parameter : 'music1.mdy'. (Guess)"); + _vm->_sound->adlibLoadTBR("music1.tbr"); + _vm->_sound->adlibLoadMDY("music1.mdy"); } void Inter_Fascination::oFascin_geUnknown7(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 7"); - warning("funcLoadInstruments with parameter : 'music2.tbr'. (Guess)"); - warning("funcLoadMusic with parameter : 'music2.mdy'. (Guess)"); + _vm->_sound->adlibLoadTBR("music2.tbr"); + _vm->_sound->adlibLoadMDY("music2.mdy"); } void Inter_Fascination::oFascin_geUnknown8(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 8"); - warning("funcLoadInstruments with parameter : 'music3.tbr'. (Guess)"); - warning("funcLoadMusic with parameter : 'music3.mdy'. (Guess)"); + _vm->_sound->adlibLoadTBR("music3.tbr"); + _vm->_sound->adlibLoadMDY("music3.mdy"); } void Inter_Fascination::oFascin_geUnknown9(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 9"); - warning("funcLoadInstruments with parameter : 'batt1.tbr'. (Guess)"); - warning("funcLoadMusic with parameter : 'batt1.mdy'. (Guess)"); + _vm->_sound->adlibLoadTBR("batt1.tbr"); + _vm->_sound->adlibLoadMDY("batt1.mdy"); } void Inter_Fascination::oFascin_geUnknown10(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 10"); - warning("funcLoadInstruments with parameter : 'batt2.tbr'. (Guess)"); - warning("funcLoadMusic with parameter : 'batt2.mdy'. (Guess)"); + _vm->_sound->adlibLoadTBR("batt2.tbr"); + _vm->_sound->adlibLoadMDY("batt2.mdy"); } void Inter_Fascination::oFascin_geUnknown11(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 11"); - warning("funcLoadInstruments with parameter : 'batt3.tbr'. (Guess)"); - warning("funcLoadMusic with parameter : 'batt3.mdy'. (Guess)"); + _vm->_sound->adlibLoadTBR("batt3.tbr"); + _vm->_sound->adlibLoadMDY("batt3.mdy"); } void Inter_Fascination::oFascin_geUnknown1000(OpGobParams ¶ms) { - warning("Fascination Unknown GE Function 1000 - Load music ?"); + warning("Fascination Unknown GE Function 1000 - Load MOD music"); } void Inter_Fascination::oFascin_geUnknown1001(OpGobParams ¶ms) { - warning("Fascination oFascin_playProtracker - MOD not compatible, ToBeFixed"); + warning("Fascination oFascin_playProtracker - MOD not compatible (sample > 32768), To Be Fixed"); } void Inter_Fascination::oFascin_geUnknown1002(OpGobParams ¶ms) { @@ -638,15 +205,15 @@ void Inter_Fascination::oFascin_cdUnknown3() { warning("Fascination oFascin_cdUnknown3 - Variables initialisations"); - resVar = (uint16) load16(); - resVar2 = (uint16) load16(); - retVal1 = _vm->_parse->parseVarIndex(); - retVal2 = _vm->_parse->parseVarIndex(); - retVal3 = _vm->_parse->parseVarIndex(); - retVal4 = _vm->_parse->parseVarIndex(); - retVal5 = _vm->_parse->parseVarIndex(); - retVal6 = _vm->_parse->parseVarIndex(); - retVal7 = _vm->_parse->parseVarIndex(); + resVar = _vm->_game->_script->readUint16(); + resVar2 = _vm->_game->_script->readUint16(); + retVal1 = _vm->_game->_script->readVarIndex(); + retVal2 = _vm->_game->_script->readVarIndex(); + retVal3 = _vm->_game->_script->readVarIndex(); + retVal4 = _vm->_game->_script->readVarIndex(); + retVal5 = _vm->_game->_script->readVarIndex(); + retVal6 = _vm->_game->_script->readVarIndex(); + retVal7 = _vm->_game->_script->readVarIndex(); warning ("Width? :%d Height? :%d",resVar, resVar2); warning ("Fetched variables 1:%d 2:%d 3:%d 4:%d 5:%d 6:%d 7:%d", retVal1, retVal2, retVal3, retVal4, retVal5, retVal6, retVal7); } @@ -654,98 +221,37 @@ void Inter_Fascination::oFascin_cdUnknown3() { void Inter_Fascination::oFascin_cdUnknown4() { int16 expr; warning("Fascination oFascin_cdUnknown4"); - evalExpr(&expr); - warning ("evalExpr: %d, the rest is not yet implemented",expr); + _vm->_game->_script->evalExpr(&expr); + warning ("_vm->_game->_script->evalExpr: %d, the rest is not yet implemented",expr); } void Inter_Fascination::oFascin_cdUnknown5() { int16 retVal1,expr; warning("Fascination oFascin_cdUnknown5"); - evalExpr(&expr); - retVal1 = _vm->_parse->parseVarIndex(); - warning ("evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1); + _vm->_game->_script->evalExpr(&expr); + retVal1 = _vm->_game->_script->readVarIndex(); + warning ("_vm->_game->_script->evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1); } void Inter_Fascination::oFascin_cdUnknown6() { int16 retVal1,expr; warning("Fascination oFascin_cdUnknown6"); - evalExpr(&expr); - retVal1 = _vm->_parse->parseVarIndex(); - warning ("evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1); + _vm->_game->_script->evalExpr(&expr); + retVal1 = _vm->_game->_script->readVarIndex(); + warning ("_vm->_game->_script->evalExpr: %d Variable index %d, the rest is not yet implemented",expr, retVal1); } void Inter_Fascination::oFascin_setRenderFlags() { int16 expr; // warning("Fascination oFascin_cdUnknown10 (set render flags)"); - evalExpr(&expr); + _vm->_game->_script->evalExpr(&expr); warning("_draw_renderFlags <- %d",expr); _vm->_draw->_renderFlags = expr; } void Inter_Fascination::oFascin_cdUnknown11() { // warning("Fascination oFascin_cdUnknown11 (set variable)"); - evalExpr(0); -} - -bool Inter_Fascination::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", - i, j, i, j, getOpcodeFuncDesc(i, j)); - - if ((i > 4) || (j > 16)) { - warning("Invalid opcodeFunc: %d.%d", i, j); - return false; - } - - OpcodeFuncProcFascination op = _opcodesFuncFascination[i*16 + j].proc; - - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); - - return false; -} - -void Inter_Fascination::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); - - OpcodeGoblinProcFascination op = 0; - - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinFascination[_goblinFuncLookUp[j][1]].proc; - break; - } - - if (op == 0) { - int16 val; - - _vm->_global->_inter_execPtr -= 2; - val = load16(); - _vm->_global->_inter_execPtr += val << 1; - warning("unimplemented opcodeGob: %d", i); - } else - (this->*op) (params); -} - -const char *Inter_Fascination::getOpcodeDrawDesc(byte i) { - return _opcodesDrawFascination[i].desc; -} - -const char *Inter_Fascination::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; - - return _opcodesFuncFascination[i*16 + j].desc; -} - -const char *Inter_Fascination::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinFascination[_goblinFuncLookUp[j][1]].desc; - warning("Error in getOpcodeGoblinDesc %d",i); - return ""; + _vm->_game->_script->evalExpr(0); } void Inter_Fascination::oFascin_playProtracker(OpGobParams ¶ms) { diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 37e31b95e8..96ecfc6b25 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -34,692 +34,214 @@ #include "gob/dataio.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/expression.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/goblin.h" #include "gob/inter.h" #include "gob/map.h" #include "gob/mult.h" #include "gob/palanim.h" -#include "gob/parse.h" #include "gob/scenery.h" #include "gob/video.h" #include "gob/sound/sound.h" namespace Gob { -#define OPCODE(x) _OPCODE(Inter_v1, x) - -const int Inter_v1::_goblinFuncLookUp[][2] = { - {1, 0}, - {2, 1}, - {3, 2}, - {4, 3}, - {5, 4}, - {6, 5}, - {7, 6}, - {8, 7}, - {9, 8}, - {10, 9}, - {12, 10}, - {13, 11}, - {14, 12}, - {15, 13}, - {16, 14}, - {21, 15}, - {22, 16}, - {23, 17}, - {24, 18}, - {25, 19}, - {26, 20}, - {27, 21}, - {28, 22}, - {29, 23}, - {30, 24}, - {32, 25}, - {33, 26}, - {34, 27}, - {35, 28}, - {36, 29}, - {37, 30}, - {40, 31}, - {41, 32}, - {42, 33}, - {43, 34}, - {44, 35}, - {50, 36}, - {52, 37}, - {53, 38}, - {150, 39}, - {152, 40}, - {200, 41}, - {201, 42}, - {202, 43}, - {203, 44}, - {204, 45}, - {250, 46}, - {251, 47}, - {252, 48}, - {500, 49}, - {502, 50}, - {503, 51}, - {600, 52}, - {601, 53}, - {602, 54}, - {603, 55}, - {604, 56}, - {605, 57}, - {1000, 58}, - {1001, 59}, - {1002, 60}, - {1003, 61}, - {1004, 62}, - {1005, 63}, - {1006, 64}, - {1008, 65}, - {1009, 66}, - {1010, 67}, - {1011, 68}, - {1015, 69}, - {2005, 70} -}; +#define OPCODEVER Inter_v1 +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_v1::Inter_v1(GobEngine *vm) : Inter(vm) { - setupOpcodes(); -} - -void Inter_v1::setupOpcodes() { - static const OpcodeDrawEntryV1 opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o1_playMult), - OPCODE(o1_freeMultKeys), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(o1_setRenderFlags), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - {0, ""}, - /* 14 */ - OPCODE(o1_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o1_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o1_renderStatic), - OPCODE(o1_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o1_playCDTrack), - OPCODE(o1_getCDTrackPos), - OPCODE(o1_stopCD), - {0, ""}, - /* 24 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 54 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 84 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 88 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryV1 opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o1_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o1_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o1_printText), - OPCODE(o1_loadTot), - OPCODE(o1_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o1_animPalInit), - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o1_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o1_copySprite), - OPCODE(o1_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o1_stopSound), - OPCODE(o1_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o1_getFreeMem), - OPCODE(o1_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o1_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o1_readData), - OPCODE(o1_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryV1 opcodesGoblin[71] = { - /* 00 */ - OPCODE(o1_setState), - OPCODE(o1_setCurFrame), - OPCODE(o1_setNextState), - OPCODE(o1_setMultState), - /* 04 */ - OPCODE(o1_setOrder), - OPCODE(o1_setActionStartState), - OPCODE(o1_setCurLookDir), - OPCODE(o1_setType), - /* 08 */ - OPCODE(o1_setNoTick), - OPCODE(o1_setPickable), - OPCODE(o1_setXPos), - OPCODE(o1_setYPos), - /* 0C */ - OPCODE(o1_setDoAnim), - OPCODE(o1_setRelaxTime), - OPCODE(o1_setMaxTick), - OPCODE(o1_getState), - /* 10 */ - OPCODE(o1_getCurFrame), - OPCODE(o1_getNextState), - OPCODE(o1_getMultState), - OPCODE(o1_getOrder), - /* 14 */ - OPCODE(o1_getActionStartState), - OPCODE(o1_getCurLookDir), - OPCODE(o1_getType), - OPCODE(o1_getNoTick), - /* 18 */ - OPCODE(o1_getPickable), - OPCODE(o1_getObjMaxFrame), - OPCODE(o1_getXPos), - OPCODE(o1_getYPos), - /* 1C */ - OPCODE(o1_getDoAnim), - OPCODE(o1_getRelaxTime), - OPCODE(o1_getMaxTick), - OPCODE(o1_manipulateMap), - /* 20 */ - OPCODE(o1_getItem), - OPCODE(o1_manipulateMapIndirect), - OPCODE(o1_getItemIndirect), - OPCODE(o1_setPassMap), - /* 24 */ - OPCODE(o1_setGoblinPosH), - OPCODE(o1_getGoblinPosXH), - OPCODE(o1_getGoblinPosYH), - OPCODE(o1_setGoblinMultState), - /* 28 */ - OPCODE(o1_setGoblinUnk14), - OPCODE(o1_setItemIdInPocket), - OPCODE(o1_setItemIndInPocket), - OPCODE(o1_getItemIdInPocket), - /* 2C */ - OPCODE(o1_getItemIndInPocket), - OPCODE(o1_setItemPos), - OPCODE(o1_setGoblinPos), - OPCODE(o1_setGoblinState), - /* 30 */ - OPCODE(o1_setGoblinStateRedraw), - OPCODE(o1_decRelaxTime), - OPCODE(o1_getGoblinPosX), - OPCODE(o1_getGoblinPosY), - /* 34 */ - OPCODE(o1_clearPathExistence), - OPCODE(o1_setGoblinVisible), - OPCODE(o1_setGoblinInvisible), - OPCODE(o1_getObjectIntersect), - /* 38 */ - OPCODE(o1_getGoblinIntersect), - OPCODE(o1_setItemPos), - OPCODE(o1_loadObjects), - OPCODE(o1_freeObjects), - /* 3C */ - OPCODE(o1_animateObjects), - OPCODE(o1_drawObjects), - OPCODE(o1_loadMap), - OPCODE(o1_moveGoblin), - /* 40 */ - OPCODE(o1_switchGoblin), - OPCODE(o1_loadGoblin), - OPCODE(o1_writeTreatItem), - OPCODE(o1_moveGoblin0), - /* 44 */ - OPCODE(o1_setGoblinTarget), - OPCODE(o1_setGoblinObjectsPos), - OPCODE(o1_initGoblin) - }; - - _opcodesDrawV1 = opcodesDraw; - _opcodesFuncV1 = opcodesFunc; - _opcodesGoblinV1 = opcodesGoblin; -} - -void Inter_v1::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); - - OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc; - - if (op == 0) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); -} - -bool Inter_v1::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", - i, j, i, j, getOpcodeFuncDesc(i, j)); - - if ((i > 4) || (j > 15)) { - warning("unimplemented opcodeFunc: %d.%d", i, j); - return false; - } - - OpcodeFuncProcV1 op = _opcodesFuncV1[i*16 + j].proc; - - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); - return false; } -void Inter_v1::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); +void Inter_v1::setupOpcodesDraw() { + OPCODEDRAW(0x00, o1_loadMult); + OPCODEDRAW(0x01, o1_playMult); + OPCODEDRAW(0x02, o1_freeMultKeys); - OpcodeGoblinProcV1 op = 0; + OPCODEDRAW(0x07, o1_initCursor); + + OPCODEDRAW(0x08, o1_initCursorAnim); + OPCODEDRAW(0x09, o1_clearCursorAnim); + OPCODEDRAW(0x0A, o1_setRenderFlags); - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinV1[_goblinFuncLookUp[j][1]].proc; - break; - } - - if (op == 0) { - warning("unimplemented opcodeGoblin: %d", i); - _vm->_global->_inter_execPtr -= 2; - int16 cmd = load16(); - _vm->_global->_inter_execPtr += cmd * 2; - } else - (this->*op) (params); -} - -const char *Inter_v1::getOpcodeDrawDesc(byte i) { - return _opcodesDrawV1[i].desc; -} - -const char *Inter_v1::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; - - return _opcodesFuncV1[i*16 + j].desc; -} - -const char *Inter_v1::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinV1[_goblinFuncLookUp[j][1]].desc; - return ""; -} - -void Inter_v1::checkSwitchTable(byte **ppExec) { + OPCODEDRAW(0x10, o1_loadAnim); + OPCODEDRAW(0x11, o1_freeAnim); + OPCODEDRAW(0x12, o1_updateAnim); + + OPCODEDRAW(0x14, o1_initMult); + OPCODEDRAW(0x15, o1_freeMult); + OPCODEDRAW(0x16, o1_animate); + OPCODEDRAW(0x17, o1_loadMultObject); + + OPCODEDRAW(0x18, o1_getAnimLayerInfo); + OPCODEDRAW(0x19, o1_getObjAnimSize); + OPCODEDRAW(0x1A, o1_loadStatic); + OPCODEDRAW(0x1B, o1_freeStatic); + + OPCODEDRAW(0x1C, o1_renderStatic); + OPCODEDRAW(0x1D, o1_loadCurLayer); + + OPCODEDRAW(0x20, o1_playCDTrack); + OPCODEDRAW(0x21, o1_getCDTrackPos); + OPCODEDRAW(0x22, o1_stopCD); + + OPCODEDRAW(0x30, o1_loadFontToSprite); + OPCODEDRAW(0x31, o1_freeFontToSprite); +} + +void Inter_v1::setupOpcodesFunc() { + OPCODEFUNC(0x00, o1_callSub); + OPCODEFUNC(0x01, o1_callSub); + OPCODEFUNC(0x02, o1_printTotText); + OPCODEFUNC(0x03, o1_loadCursor); + + OPCODEFUNC(0x05, o1_switch); + OPCODEFUNC(0x06, o1_repeatUntil); + OPCODEFUNC(0x07, o1_whileDo); + + OPCODEFUNC(0x08, o1_if); + OPCODEFUNC(0x09, o1_assign); + OPCODEFUNC(0x0A, o1_loadSpriteToPos); + OPCODEFUNC(0x11, o1_printText); + OPCODEFUNC(0x12, o1_loadTot); + OPCODEFUNC(0x13, o1_palLoad); + + OPCODEFUNC(0x14, o1_keyFunc); + OPCODEFUNC(0x15, o1_capturePush); + OPCODEFUNC(0x16, o1_capturePop); + OPCODEFUNC(0x17, o1_animPalInit); + + OPCODEFUNC(0x1E, o1_drawOperations); + OPCODEFUNC(0x1F, o1_setcmdCount); + + OPCODEFUNC(0x20, o1_return); + OPCODEFUNC(0x21, o1_renewTimeInVars); + OPCODEFUNC(0x22, o1_speakerOn); + OPCODEFUNC(0x23, o1_speakerOff); + + OPCODEFUNC(0x24, o1_putPixel); + OPCODEFUNC(0x25, o1_goblinFunc); + OPCODEFUNC(0x26, o1_createSprite); + OPCODEFUNC(0x27, o1_freeSprite); + + OPCODEFUNC(0x30, o1_returnTo); + OPCODEFUNC(0x31, o1_loadSpriteContent); + OPCODEFUNC(0x32, o1_copySprite); + OPCODEFUNC(0x33, o1_fillRect); + + OPCODEFUNC(0x34, o1_drawLine); + OPCODEFUNC(0x35, o1_strToLong); + OPCODEFUNC(0x36, o1_invalidate); + OPCODEFUNC(0x37, o1_setBackDelta); + + OPCODEFUNC(0x38, o1_playSound); + OPCODEFUNC(0x39, o1_stopSound); + OPCODEFUNC(0x3A, o1_loadSound); + OPCODEFUNC(0x3B, o1_freeSoundSlot); + + OPCODEFUNC(0x3C, o1_waitEndPlay); + OPCODEFUNC(0x3D, o1_playComposition); + OPCODEFUNC(0x3E, o1_getFreeMem); + OPCODEFUNC(0x3F, o1_checkData); + + OPCODEFUNC(0x41, o1_prepareStr); + OPCODEFUNC(0x42, o1_insertStr); + OPCODEFUNC(0x43, o1_cutStr); + + OPCODEFUNC(0x44, o1_strstr); + OPCODEFUNC(0x45, o1_istrlen); + OPCODEFUNC(0x46, o1_setMousePos); + OPCODEFUNC(0x47, o1_setFrameRate); + + OPCODEFUNC(0x48, o1_animatePalette); + OPCODEFUNC(0x49, o1_animateCursor); + OPCODEFUNC(0x4A, o1_blitCursor); + OPCODEFUNC(0x4B, o1_loadFont); + + OPCODEFUNC(0x4C, o1_freeFont); + OPCODEFUNC(0x4D, o1_readData); + OPCODEFUNC(0x4E, o1_writeData); + OPCODEFUNC(0x4F, o1_manageDataFile); +} + +void Inter_v1::setupOpcodesGob() { + OPCODEGOB( 1, o1_setState); + OPCODEGOB( 2, o1_setCurFrame); + OPCODEGOB( 3, o1_setNextState); + OPCODEGOB( 4, o1_setMultState); + OPCODEGOB( 5, o1_setOrder); + OPCODEGOB( 6, o1_setActionStartState); + OPCODEGOB( 7, o1_setCurLookDir); + OPCODEGOB( 8, o1_setType); + OPCODEGOB( 9, o1_setNoTick); + OPCODEGOB( 10, o1_setPickable); + OPCODEGOB( 12, o1_setXPos); + OPCODEGOB( 13, o1_setYPos); + OPCODEGOB( 14, o1_setDoAnim); + OPCODEGOB( 15, o1_setRelaxTime); + OPCODEGOB( 16, o1_setMaxTick); + OPCODEGOB( 21, o1_getState); + OPCODEGOB( 22, o1_getCurFrame); + OPCODEGOB( 23, o1_getNextState); + OPCODEGOB( 24, o1_getMultState); + OPCODEGOB( 25, o1_getOrder); + OPCODEGOB( 26, o1_getActionStartState); + OPCODEGOB( 27, o1_getCurLookDir); + OPCODEGOB( 28, o1_getType); + OPCODEGOB( 29, o1_getNoTick); + OPCODEGOB( 30, o1_getPickable); + OPCODEGOB( 32, o1_getObjMaxFrame); + OPCODEGOB( 33, o1_getXPos); + OPCODEGOB( 34, o1_getYPos); + OPCODEGOB( 35, o1_getDoAnim); + OPCODEGOB( 36, o1_getRelaxTime); + OPCODEGOB( 37, o1_getMaxTick); + OPCODEGOB( 40, o1_manipulateMap); + OPCODEGOB( 41, o1_getItem); + OPCODEGOB( 42, o1_manipulateMapIndirect); + OPCODEGOB( 43, o1_getItemIndirect); + OPCODEGOB( 44, o1_setPassMap); + OPCODEGOB( 50, o1_setGoblinPosH); + OPCODEGOB( 52, o1_getGoblinPosXH); + OPCODEGOB( 53, o1_getGoblinPosYH); + OPCODEGOB( 150, o1_setGoblinMultState); + OPCODEGOB( 152, o1_setGoblinUnk14); + OPCODEGOB( 200, o1_setItemIdInPocket); + OPCODEGOB( 201, o1_setItemIndInPocket); + OPCODEGOB( 202, o1_getItemIdInPocket); + OPCODEGOB( 203, o1_getItemIndInPocket); + OPCODEGOB( 204, o1_setItemPos); + OPCODEGOB( 250, o1_setGoblinPos); + OPCODEGOB( 251, o1_setGoblinState); + OPCODEGOB( 252, o1_setGoblinStateRedraw); + OPCODEGOB( 500, o1_decRelaxTime); + OPCODEGOB( 502, o1_getGoblinPosX); + OPCODEGOB( 503, o1_getGoblinPosY); + OPCODEGOB( 600, o1_clearPathExistence); + OPCODEGOB( 601, o1_setGoblinVisible); + OPCODEGOB( 602, o1_setGoblinInvisible); + OPCODEGOB( 603, o1_getObjectIntersect); + OPCODEGOB( 604, o1_getGoblinIntersect); + OPCODEGOB( 605, o1_setItemPos); + OPCODEGOB(1000, o1_loadObjects); + OPCODEGOB(1001, o1_freeObjects); + OPCODEGOB(1002, o1_animateObjects); + OPCODEGOB(1003, o1_drawObjects); + OPCODEGOB(1004, o1_loadMap); + OPCODEGOB(1005, o1_moveGoblin); + OPCODEGOB(1006, o1_switchGoblin); + OPCODEGOB(1008, o1_loadGoblin); + OPCODEGOB(1009, o1_writeTreatItem); + OPCODEGOB(1010, o1_moveGoblin0); + OPCODEGOB(1011, o1_setGoblinTarget); + OPCODEGOB(1015, o1_setGoblinObjectsPos); + OPCODEGOB(2005, o1_initGoblin); +} + +void Inter_v1::checkSwitchTable(uint32 &offset) { int16 len; int32 value; bool found; @@ -727,56 +249,54 @@ void Inter_v1::checkSwitchTable(byte **ppExec) { found = false; notFound = true; - *ppExec = 0; - value = VAR_OFFSET(_vm->_parse->parseVarIndex()); + offset = 0; + value = VAR_OFFSET(_vm->_game->_script->readVarIndex()); - len = (int8) *_vm->_global->_inter_execPtr++; + len = _vm->_game->_script->readInt8(); while (len != -5) { for (int i = 0; i < len; i++) { - evalExpr(0); + _vm->_game->_script->evalExpr(0); if (_terminate) return; - if (_vm->_global->_inter_resVal == value) { + if (_vm->_game->_script->getResultInt() == value) { found = true; notFound = false; } } if (found) - *ppExec = _vm->_global->_inter_execPtr; + offset = _vm->_game->_script->pos(); - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); found = false; - len = (int8) *_vm->_global->_inter_execPtr++; + len = _vm->_game->_script->readInt8(); } - if ((*_vm->_global->_inter_execPtr >> 4) != 4) + if ((_vm->_game->_script->peekByte() >> 4) != 4) return; - _vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(1); if (notFound) - *ppExec = _vm->_global->_inter_execPtr; + offset = _vm->_game->_script->pos(); - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); } void Inter_v1::o1_loadMult() { - _vm->_mult->loadMult(load16()); + _vm->_mult->loadMult(_vm->_game->_script->readInt16()); } void Inter_v1::o1_playMult() { int16 checkEscape; - checkEscape = load16(); + checkEscape = _vm->_game->_script->readInt16(); _vm->_mult->playMult(VAR(57), -1, checkEscape, 0); } void Inter_v1::o1_freeMultKeys() { - load16(); + _vm->_game->_script->readInt16(); _vm->_mult->freeMultKeys(); } @@ -785,20 +305,20 @@ void Inter_v1::o1_initCursor() { int16 height; int16 count; - _vm->_draw->_cursorHotspotXVar = _vm->_parse->parseVarIndex() / 4; - _vm->_draw->_cursorHotspotYVar = _vm->_parse->parseVarIndex() / 4; + _vm->_draw->_cursorHotspotXVar = _vm->_game->_script->readVarIndex() / 4; + _vm->_draw->_cursorHotspotYVar = _vm->_game->_script->readVarIndex() / 4; - width = load16(); + width = _vm->_game->_script->readInt16(); if (width < 16) width = 16; - height = load16(); + height = _vm->_game->_script->readInt16(); if (height < 16) height = 16; _vm->_draw->adjustCoords(0, &width, &height); - count = load16(); + count = _vm->_game->_script->readInt16(); if (count < 2) count = 2; @@ -808,9 +328,9 @@ void Inter_v1::o1_initCursor() { (_vm->_draw->_cursorSprites->getWidth() != (width * count))) { _vm->_draw->freeSprite(23); - _vm->_draw->_cursorSprites = 0; - _vm->_draw->_cursorSpritesBack = 0; - _vm->_draw->_scummvmCursor = 0; + _vm->_draw->_cursorSprites.reset(); + _vm->_draw->_cursorSpritesBack.reset(); + _vm->_draw->_scummvmCursor.reset(); _vm->_draw->_cursorWidth = width; _vm->_draw->_cursorHeight = height; @@ -846,24 +366,24 @@ void Inter_v1::o1_initCursorAnim() { int16 ind; _vm->_draw->_showCursor = 3; - ind = _vm->_parse->parseValExpr(); - _vm->_draw->_cursorAnimLow[ind] = load16(); - _vm->_draw->_cursorAnimHigh[ind] = load16(); - _vm->_draw->_cursorAnimDelays[ind] = load16(); + ind = _vm->_game->_script->readValExpr(); + _vm->_draw->_cursorAnimLow[ind] = _vm->_game->_script->readInt16(); + _vm->_draw->_cursorAnimHigh[ind] = _vm->_game->_script->readInt16(); + _vm->_draw->_cursorAnimDelays[ind] = _vm->_game->_script->readInt16(); } void Inter_v1::o1_clearCursorAnim() { int16 ind; _vm->_draw->_showCursor = 0; - ind = _vm->_parse->parseValExpr(); + ind = _vm->_game->_script->readValExpr(); _vm->_draw->_cursorAnimLow[ind] = -1; _vm->_draw->_cursorAnimHigh[ind] = 0; _vm->_draw->_cursorAnimDelays[ind] = 0; } void Inter_v1::o1_setRenderFlags() { - _vm->_draw->_renderFlags = _vm->_parse->parseValExpr(); + _vm->_draw->_renderFlags = _vm->_game->_script->readValExpr(); } void Inter_v1::o1_loadAnim() { @@ -882,12 +402,12 @@ void Inter_v1::o1_updateAnim() { int16 layer; int16 animation; - evalExpr(&deltaX); - evalExpr(&deltaY); - evalExpr(&animation); - evalExpr(&layer); - evalExpr(&frame); - flags = load16(); + _vm->_game->_script->evalExpr(&deltaX); + _vm->_game->_script->evalExpr(&deltaY); + _vm->_game->_script->evalExpr(&animation); + _vm->_game->_script->evalExpr(&layer); + _vm->_game->_script->evalExpr(&frame); + flags = _vm->_game->_script->readInt16(); _vm->_scenery->updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1); } @@ -904,14 +424,14 @@ void Inter_v1::o1_initMult() { oldAnimHeight = _vm->_mult->_animHeight; oldObjCount = _vm->_mult->_objCount; - _vm->_mult->_animLeft = load16(); - _vm->_mult->_animTop = load16(); - _vm->_mult->_animWidth = load16(); - _vm->_mult->_animHeight = load16(); - _vm->_mult->_objCount = load16(); - posXVar = _vm->_parse->parseVarIndex(); - posYVar = _vm->_parse->parseVarIndex(); - animDataVar = _vm->_parse->parseVarIndex(); + _vm->_mult->_animLeft = _vm->_game->_script->readInt16(); + _vm->_mult->_animTop = _vm->_game->_script->readInt16(); + _vm->_mult->_animWidth = _vm->_game->_script->readInt16(); + _vm->_mult->_animHeight = _vm->_game->_script->readInt16(); + _vm->_mult->_objCount = _vm->_game->_script->readInt16(); + posXVar = _vm->_game->_script->readVarIndex(); + posYVar = _vm->_game->_script->readVarIndex(); + animDataVar = _vm->_game->_script->readVarIndex(); if (_vm->_mult->_objects && (oldObjCount != _vm->_mult->_objCount)) { @@ -944,8 +464,8 @@ void Inter_v1::o1_initMult() { uint32 offPosY = i * 4 + (posYVar / 4) * 4; uint32 offAnim = animDataVar + i * 4 * _vm->_global->_inter_animDataSize; - _vm->_mult->_objects[i].pPosX = new VariableReference(*_vm->_inter->_variables, offPosX); - _vm->_mult->_objects[i].pPosY = new VariableReference(*_vm->_inter->_variables, offPosY); + _vm->_mult->_objects[i].pPosX = new VariableReference(*_variables, offPosX); + _vm->_mult->_objects[i].pPosY = new VariableReference(*_variables, offPosY); _vm->_mult->_objects[i].pAnimData = (Mult::Mult_AnimData *) _variables->getAddressOff8(offAnim); @@ -963,7 +483,7 @@ void Inter_v1::o1_initMult() { ((oldAnimWidth != _vm->_mult->_animWidth) || (oldAnimHeight != _vm->_mult->_animHeight))) { _vm->_draw->freeSprite(22); - _vm->_mult->_animSurf = 0; + _vm->_mult->_animSurf.reset(); } if (!_vm->_mult->_animSurf) { @@ -972,7 +492,7 @@ void Inter_v1::o1_initMult() { _vm->_mult->_animSurf = _vm->_draw->_spritesArray[22]; } - _vm->_video->drawSprite(_vm->_draw->_backSurface, _vm->_mult->_animSurf, + _vm->_video->drawSprite(*_vm->_draw->_backSurface, *_vm->_mult->_animSurf, _vm->_mult->_animLeft, _vm->_mult->_animTop, _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1, _vm->_mult->_animTop + _vm->_mult->_animHeight - 1, 0, 0, 0); @@ -998,21 +518,21 @@ void Inter_v1::o1_loadMultObject() { int16 objIndex; byte *multData; - evalExpr(&objIndex); - evalExpr(&val); + _vm->_game->_script->evalExpr(&objIndex); + _vm->_game->_script->evalExpr(&val); *_vm->_mult->_objects[objIndex].pPosX = val; - evalExpr(&val); + _vm->_game->_script->evalExpr(&val); *_vm->_mult->_objects[objIndex].pPosY = val; debugC(4, kDebugGameFlow, "Loading mult object %d", objIndex); multData = (byte *) _vm->_mult->_objects[objIndex].pAnimData; for (int i = 0; i < 11; i++) { - if (READ_LE_UINT16(_vm->_global->_inter_execPtr) != 99) { - evalExpr(&val); + if (_vm->_game->_script->peekUint16() != 99) { + _vm->_game->_script->evalExpr(&val); multData[i] = val; } else - _vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(1); } } @@ -1023,13 +543,13 @@ void Inter_v1::o1_getAnimLayerInfo() { int16 varUnk0; int16 varFrames; - evalExpr(&anim); - evalExpr(&layer); + _vm->_game->_script->evalExpr(&anim); + _vm->_game->_script->evalExpr(&layer); - varDX = _vm->_parse->parseVarIndex(); - varDY = _vm->_parse->parseVarIndex(); - varUnk0 = _vm->_parse->parseVarIndex(); - varFrames = _vm->_parse->parseVarIndex(); + varDX = _vm->_game->_script->readVarIndex(); + varDY = _vm->_game->_script->readVarIndex(); + varUnk0 = _vm->_game->_script->readVarIndex(); + varFrames = _vm->_game->_script->readVarIndex(); _vm->_scenery->writeAnimLayerInfo(anim, layer, varDX, varDY, varUnk0, varFrames); @@ -1038,7 +558,7 @@ void Inter_v1::o1_getAnimLayerInfo() { void Inter_v1::o1_getObjAnimSize() { int16 objIndex; - evalExpr(&objIndex); + _vm->_game->_script->evalExpr(&objIndex); Mult::Mult_AnimData &animData = *(_vm->_mult->_objects[objIndex].pAnimData); if (animData.isStatic == 0) @@ -1048,10 +568,10 @@ void Inter_v1::o1_getObjAnimSize() { _vm->_scenery->_toRedrawLeft = MAX(_vm->_scenery->_toRedrawLeft, (int16) 0); _vm->_scenery->_toRedrawTop = MAX(_vm->_scenery->_toRedrawTop, (int16) 0); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawLeft); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawTop); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawRight); - WRITE_VAR_OFFSET(_vm->_parse->parseVarIndex(), _vm->_scenery->_toRedrawBottom); + WRITE_VAR_OFFSET(_vm->_game->_script->readVarIndex(), _vm->_scenery->_toRedrawLeft); + WRITE_VAR_OFFSET(_vm->_game->_script->readVarIndex(), _vm->_scenery->_toRedrawTop); + WRITE_VAR_OFFSET(_vm->_game->_script->readVarIndex(), _vm->_scenery->_toRedrawRight); + WRITE_VAR_OFFSET(_vm->_game->_script->readVarIndex(), _vm->_scenery->_toRedrawBottom); } void Inter_v1::o1_loadStatic() { @@ -1066,20 +586,20 @@ void Inter_v1::o1_renderStatic() { int16 layer; int16 index; - _vm->_inter->evalExpr(&index); - _vm->_inter->evalExpr(&layer); + _vm->_game->_script->evalExpr(&index); + _vm->_game->_script->evalExpr(&layer); _vm->_scenery->renderStatic(index, layer); } void Inter_v1::o1_loadCurLayer() { - evalExpr(&_vm->_scenery->_curStatic); - evalExpr(&_vm->_scenery->_curStaticLayer); + _vm->_game->_script->evalExpr(&_vm->_scenery->_curStatic); + _vm->_game->_script->evalExpr(&_vm->_scenery->_curStaticLayer); } void Inter_v1::o1_playCDTrack() { - evalExpr(0); + _vm->_game->_script->evalExpr(0); _vm->_sound->adlibPlayBgMusic(); // Mac version - _vm->_sound->cdPlay(_vm->_global->_inter_resStr); // PC CD version + _vm->_sound->cdPlay(_vm->_game->_script->getResultStr()); // PC CD version } void Inter_v1::o1_getCDTrackPos() { @@ -1103,15 +623,15 @@ void Inter_v1::o1_stopCD() { } void Inter_v1::o1_loadFontToSprite() { - int16 i = load16(); - _vm->_draw->_fontToSprite[i].sprite = load16(); - _vm->_draw->_fontToSprite[i].base = load16(); - _vm->_draw->_fontToSprite[i].width = load16(); - _vm->_draw->_fontToSprite[i].height = load16(); + int16 i = _vm->_game->_script->readInt16(); + _vm->_draw->_fontToSprite[i].sprite = _vm->_game->_script->readInt16(); + _vm->_draw->_fontToSprite[i].base = _vm->_game->_script->readInt16(); + _vm->_draw->_fontToSprite[i].width = _vm->_game->_script->readInt16(); + _vm->_draw->_fontToSprite[i].height = _vm->_game->_script->readInt16(); } void Inter_v1::o1_freeFontToSprite() { - int16 i = load16(); + int16 i = _vm->_game->_script->readInt16(); _vm->_draw->_fontToSprite[i].sprite = -1; _vm->_draw->_fontToSprite[i].base = -1; _vm->_draw->_fontToSprite[i].width = -1; @@ -1119,11 +639,7 @@ void Inter_v1::o1_freeFontToSprite() { } bool Inter_v1::o1_callSub(OpFuncParams ¶ms) { - byte *storedIP; - uint16 offset; - - offset = load16(); - storedIP = _vm->_global->_inter_execPtr; + uint16 offset = _vm->_game->_script->readUint16(); debugC(5, kDebugGameFlow, "tot = \"%s\", offset = %d", _vm->_game->_curTotFile, offset); @@ -1147,79 +663,89 @@ bool Inter_v1::o1_callSub(OpFuncParams ¶ms) { return false; } - _vm->_global->_inter_execPtr = _vm->_game->_totFileData + offset; + _vm->_game->_script->call(offset); - if ((params.counter == params.cmdCount) && (params.retFlag == 2)) + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) { + _vm->_game->_script->pop(false); return true; + } callSub(2); - _vm->_global->_inter_execPtr = storedIP; + + _vm->_game->_script->pop(); return false; } bool Inter_v1::o1_printTotText(OpFuncParams ¶ms) { - _vm->_draw->printTotText(load16()); + _vm->_draw->printTotText(_vm->_game->_script->readInt16()); return false; } bool Inter_v1::o1_loadCursor(OpFuncParams ¶ms) { - int16 width, height; - byte *dataBuf; - int16 id; - int8 index; - - id = load16(); - index = (int8) *_vm->_global->_inter_execPtr++; + int16 id = _vm->_game->_script->readInt16(); + int8 index = _vm->_game->_script->readInt8(); if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth()) return false; - dataBuf = _vm->_game->loadTotResource(id, 0, &width, &height); + Resource *resource = _vm->_game->_resources->getResource(id); + if (!resource) + return false; - _vm->_video->fillRect(_vm->_draw->_cursorSprites, + _vm->_video->fillRect(*_vm->_draw->_cursorSprites, index * _vm->_draw->_cursorWidth, 0, index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, _vm->_draw->_cursorHeight - 1, 0); - _vm->_video->drawPackedSprite(dataBuf, width, height, - index * _vm->_draw->_cursorWidth, 0, 0, _vm->_draw->_cursorSprites); + _vm->_video->drawPackedSprite(resource->getData(), + resource->getWidth(), resource->getHeight(), + index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites); _vm->_draw->_cursorAnimLow[index] = 0; + delete resource; return false; } bool Inter_v1::o1_switch(OpFuncParams ¶ms) { - byte *callAddr; + uint32 offset; + + checkSwitchTable(offset); - checkSwitchTable(&callAddr); - byte *storedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = callAddr; + _vm->_game->_script->call(offset); - if ((params.counter == params.cmdCount) && (params.retFlag == 2)) + if (offset == 0) + _vm->_game->_script->setFinished(true); + + if ((params.counter == params.cmdCount) && (params.retFlag == 2)) { + _vm->_game->_script->pop(false); return true; + } funcBlock(0); - _vm->_global->_inter_execPtr = storedIP; + + _vm->_game->_script->pop(); return false; } bool Inter_v1::o1_repeatUntil(OpFuncParams ¶ms) { - byte *blockPtr; int16 size; bool flag; _nestLevel[0]++; - blockPtr = _vm->_global->_inter_execPtr; + + uint32 blockPos = _vm->_game->_script->pos(); do { - _vm->_global->_inter_execPtr = blockPtr; - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->seek(blockPos); + size = _vm->_game->_script->peekUint16(2) + 2; funcBlock(1); - _vm->_global->_inter_execPtr = blockPtr + size + 1; - flag = evalBoolResult(); + + _vm->_game->_script->seek(blockPos + size + 1); + + flag = _vm->_game->_script->evalBoolResult(); } while (!flag && !_break && !_terminate && !_vm->shouldQuit()); _nestLevel[0]--; @@ -1232,32 +758,31 @@ bool Inter_v1::o1_repeatUntil(OpFuncParams ¶ms) { } bool Inter_v1::o1_whileDo(OpFuncParams ¶ms) { - byte *blockPtr; - byte *savedIP; bool flag; int16 size; _nestLevel[0]++; do { - savedIP = _vm->_global->_inter_execPtr; - flag = evalBoolResult(); + uint32 startPos = _vm->_game->_script->pos(); + + flag = _vm->_game->_script->evalBoolResult(); if (_terminate) return false; - blockPtr = _vm->_global->_inter_execPtr; + uint32 blockPos = _vm->_game->_script->pos(); - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + size = _vm->_game->_script->peekUint16(2) + 2; if (flag) { funcBlock(1); - _vm->_global->_inter_execPtr = savedIP; + _vm->_game->_script->seek(startPos); } else - _vm->_global->_inter_execPtr += size; + _vm->_game->_script->skip(size); if (_break || _terminate || _vm->shouldQuit()) { - _vm->_global->_inter_execPtr = blockPtr; - _vm->_global->_inter_execPtr += size; + _vm->_game->_script->seek(blockPos); + _vm->_game->_script->skip(size); break; } } while (flag); @@ -1273,76 +798,65 @@ bool Inter_v1::o1_whileDo(OpFuncParams ¶ms) { bool Inter_v1::o1_if(OpFuncParams ¶ms) { byte cmd; bool boolRes; - byte *storedIP; - boolRes = evalBoolResult(); + boolRes = _vm->_game->_script->evalBoolResult(); if (boolRes) { if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; - storedIP = _vm->_global->_inter_execPtr; + _vm->_game->_script->push(); funcBlock(0); - _vm->_global->_inter_execPtr = storedIP; + _vm->_game->_script->pop(); - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); - debugC(5, kDebugGameFlow, "cmd = %d", - (int16) *_vm->_global->_inter_execPtr); + debugC(5, kDebugGameFlow, "cmd = %d", (int16) _vm->_game->_script->peekByte()); - cmd = *_vm->_global->_inter_execPtr >> 4; - _vm->_global->_inter_execPtr++; + cmd = _vm->_game->_script->readByte() >> 4; if (cmd != 12) return false; - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); } else { - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); - debugC(5, kDebugGameFlow, "cmd = %d", - (int16) *_vm->_global->_inter_execPtr); + debugC(5, kDebugGameFlow, "cmd = %d", (int16) _vm->_game->_script->peekByte()); - cmd = *_vm->_global->_inter_execPtr >> 4; - _vm->_global->_inter_execPtr++; + cmd = _vm->_game->_script->readByte() >> 4; if (cmd != 12) return false; if ((params.counter == params.cmdCount) && (params.retFlag == 2)) return true; - storedIP = _vm->_global->_inter_execPtr; + _vm->_game->_script->push(); funcBlock(0); - _vm->_global->_inter_execPtr = storedIP; + _vm->_game->_script->pop(); - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); } return false; } -bool Inter_v1::o1_evaluateStore(OpFuncParams ¶ms) { - byte *savedPos; - int16 token; +bool Inter_v1::o1_assign(OpFuncParams ¶ms) { + byte destType = _vm->_game->_script->peekByte(); + int16 dest = _vm->_game->_script->readVarIndex(); + int16 result; - int16 varOff; + int16 srcType = _vm->_game->_script->evalExpr(&result); - savedPos = _vm->_global->_inter_execPtr; - varOff = _vm->_parse->parseVarIndex(); - token = evalExpr(&result); - switch (savedPos[0]) { - case 23: - case 26: - WRITE_VAR_OFFSET(varOff, _vm->_global->_inter_resVal); + switch (destType) { + case TYPE_VAR_INT32: + case TYPE_ARRAY_INT32: + WRITE_VAR_OFFSET(dest, _vm->_game->_script->getResultInt()); break; - case 25: - case 28: - if (token == 20) - WRITE_VARO_UINT8(varOff, result); + case TYPE_VAR_STR: + case TYPE_ARRAY_STR: + if (srcType == TYPE_IMM_INT16) + WRITE_VARO_UINT8(dest, result); else - WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); + WRITE_VARO_STR(dest, _vm->_game->_script->getResultStr()); break; } @@ -1350,17 +864,17 @@ bool Inter_v1::o1_evaluateStore(OpFuncParams ¶ms) { } bool Inter_v1::o1_loadSpriteToPos(OpFuncParams ¶ms) { - _vm->_draw->_spriteLeft = load16(); + _vm->_draw->_spriteLeft = _vm->_game->_script->readInt16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); - _vm->_draw->_transparency = *_vm->_global->_inter_execPtr & 1; - _vm->_draw->_destSurface = ((int16) (*_vm->_global->_inter_execPtr >> 1)) - 1; + _vm->_draw->_transparency = _vm->_game->_script->peekByte() & 1; + _vm->_draw->_destSurface = ((int16) (_vm->_game->_script->peekByte() >> 1)) - 1; if (_vm->_draw->_destSurface < 0) _vm->_draw->_destSurface = 101; - _vm->_global->_inter_execPtr += 2; + _vm->_game->_script->skip(2); _vm->_draw->spriteOperation(DRAW_LOADSPRITE); @@ -1371,12 +885,12 @@ bool Inter_v1::o1_printText(OpFuncParams ¶ms) { char buf[60]; int i; - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); - _vm->_draw->_backColor = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->_fontIndex = _vm->_parse->parseValExpr(); + _vm->_draw->_backColor = _vm->_game->_script->readValExpr(); + _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); + _vm->_draw->_fontIndex = _vm->_game->_script->readValExpr(); _vm->_draw->_destSurface = 21; _vm->_draw->_textToPrint = buf; _vm->_draw->_transparency = 0; @@ -1387,35 +901,35 @@ bool Inter_v1::o1_printText(OpFuncParams ¶ms) { } do { - for (i = 0; (((char) *_vm->_global->_inter_execPtr) != '.') && - (*_vm->_global->_inter_execPtr != 200); - i++, _vm->_global->_inter_execPtr++) { - buf[i] = (char) *_vm->_global->_inter_execPtr; + for (i = 0; ((_vm->_game->_script->peekChar()) != '.') && + (_vm->_game->_script->peekByte() != 200); + i++, _vm->_game->_script->skip(1)) { + buf[i] = _vm->_game->_script->peekChar(); } - if (*_vm->_global->_inter_execPtr != 200) { - _vm->_global->_inter_execPtr++; - switch (*_vm->_global->_inter_execPtr) { - case 23: - case 26: + if (_vm->_game->_script->peekByte() != 200) { + _vm->_game->_script->skip(1); + switch (_vm->_game->_script->peekByte()) { + case TYPE_VAR_INT32: + case TYPE_ARRAY_INT32: sprintf(buf + i, "%d", - VAR_OFFSET(_vm->_parse->parseVarIndex())); + VAR_OFFSET(_vm->_game->_script->readVarIndex())); break; - case 25: - case 28: + case TYPE_VAR_STR: + case TYPE_ARRAY_STR: sprintf(buf + i, "%s", - GET_VARO_STR(_vm->_parse->parseVarIndex())); + GET_VARO_STR(_vm->_game->_script->readVarIndex())); break; } - _vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(1); } else buf[i] = 0; _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - } while (*_vm->_global->_inter_execPtr != 200); + } while (_vm->_game->_script->peekByte() != 200); - _vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(1); return false; } @@ -1424,16 +938,14 @@ bool Inter_v1::o1_loadTot(OpFuncParams ¶ms) { char buf[20]; int8 size; - if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { - _vm->_global->_inter_execPtr++; - evalExpr(0); - strncpy0(buf, _vm->_global->_inter_resStr, 15); + if ((_vm->_game->_script->peekByte() & 0x80) != 0) { + _vm->_game->_script->skip(1); + _vm->_game->_script->evalExpr(0); + strncpy0(buf, _vm->_game->_script->getResultStr(), 15); } else { - size = (int8) *_vm->_global->_inter_execPtr++; - for (int i = 0; i < size; i++) - buf[i] = *_vm->_global->_inter_execPtr++; - - buf[size] = 0; + size = _vm->_game->_script->readInt8(); + memcpy(buf, _vm->_game->_script->readString(size), size); + buf[size] = '\0'; } // if (_vm->getGameType() == kGameTypeGeisha) @@ -1450,15 +962,15 @@ bool Inter_v1::o1_loadTot(OpFuncParams ¶ms) { bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { int index1, index2; - byte *palPtr; byte cmd; + Resource *resource; - cmd = *_vm->_global->_inter_execPtr++; + cmd = _vm->_game->_script->readByte(); switch (cmd & 0x7F) { case 48: if ((_vm->_global->_fakeVideoMode < 0x32) || (_vm->_global->_fakeVideoMode > 0x63)) { - _vm->_global->_inter_execPtr += 48; + _vm->_game->_script->skip(48); return false; } break; @@ -1466,35 +978,35 @@ bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { case 49: if ((_vm->_global->_fakeVideoMode != 5) && (_vm->_global->_fakeVideoMode != 7)) { - _vm->_global->_inter_execPtr += 18; + _vm->_game->_script->skip(18); return false; } break; case 50: if (_vm->_global->_colorCount == 256) { - _vm->_global->_inter_execPtr += 16; + _vm->_game->_script->skip(16); return false; } break; case 51: if (_vm->_global->_fakeVideoMode < 0x64) { - _vm->_global->_inter_execPtr += 2; + _vm->_game->_script->skip(2); return false; } break; case 52: if (_vm->_global->_colorCount == 256) { - _vm->_global->_inter_execPtr += 48; + _vm->_game->_script->skip(48); return false; } break; case 53: if (_vm->_global->_colorCount != 256) { - _vm->_global->_inter_execPtr += 2; + _vm->_game->_script->skip(2); return false; } break; @@ -1507,14 +1019,14 @@ bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { case 61: if (_vm->_global->_fakeVideoMode < 0x13) { - _vm->_global->_inter_execPtr += 4; + _vm->_game->_script->skip(4); return false; } break; } if ((cmd & 0x7F) == 0x30) { - _vm->_global->_inter_execPtr += 48; + _vm->_game->_script->skip(48); return false; } @@ -1525,36 +1037,38 @@ bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { bool allZero = true; for (int i = 2; i < 18; i++) { - if (_vm->_global->_inter_execPtr[i] != 0) { + if (_vm->_game->_script->peekByte(i) != 0) { allZero = false; break; } } if (!allZero) { - _vm->_video->clearSurf(_vm->_draw->_frontSurface); + _vm->_video->clearSurf(*_vm->_draw->_frontSurface); _vm->_draw->_noInvalidated57 = true; - _vm->_global->_inter_execPtr += 18; + _vm->_game->_script->skip(48); return false; } _vm->_draw->_noInvalidated57 = false; - for (int i = 0; i < 18; i++, _vm->_global->_inter_execPtr++) { + for (int i = 0; i < 18; i++) { if (i < 2) { if (!_vm->_draw->_applyPal) continue; - _vm->_draw->_unusedPalette1[i] = *_vm->_global->_inter_execPtr; + _vm->_draw->_unusedPalette1[i] = _vm->_game->_script->peekByte(); continue; } - index1 = *_vm->_global->_inter_execPtr >> 4; - index2 = (*_vm->_global->_inter_execPtr & 0xF); + index1 = _vm->_game->_script->peekByte() >> 4; + index2 = _vm->_game->_script->peekByte() & 0xF; _vm->_draw->_unusedPalette1[i] = ((_vm->_draw->_palLoadData1[index1] + _vm->_draw->_palLoadData2[index2]) << 8) + (_vm->_draw->_palLoadData2[index1] + _vm->_draw->_palLoadData1[index2]); + + _vm->_game->_script->skip(1); } _vm->_global->_pPaletteDesc->unused1 = _vm->_draw->_unusedPalette1; @@ -1564,21 +1078,25 @@ bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { switch (cmd) { case 50: - for (int i = 0; i < 16; i++, _vm->_global->_inter_execPtr++) - _vm->_draw->_unusedPalette2[i] = *_vm->_global->_inter_execPtr; + for (int i = 0; i < 16; i++) + _vm->_draw->_unusedPalette2[i] = _vm->_game->_script->readByte(); break; case 52: - for (int i = 0; i < 16; i++, _vm->_global->_inter_execPtr += 3) { - _vm->_draw->_vgaPalette[i].red = _vm->_global->_inter_execPtr[0]; - _vm->_draw->_vgaPalette[i].green = _vm->_global->_inter_execPtr[1]; - _vm->_draw->_vgaPalette[i].blue = _vm->_global->_inter_execPtr[2]; + for (int i = 0; i < 16; i++) { + _vm->_draw->_vgaPalette[i].red = _vm->_game->_script->readByte(); + _vm->_draw->_vgaPalette[i].green = _vm->_game->_script->readByte(); + _vm->_draw->_vgaPalette[i].blue = _vm->_game->_script->readByte(); } break; case 53: - palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); - memcpy((char *) _vm->_draw->_vgaPalette, palPtr, 768); + resource = _vm->_game->_resources->getResource(_vm->_game->_script->readInt16()); + if (!resource) + break; + + memcpy((char *) _vm->_draw->_vgaPalette, resource->getData(), MIN<int>(768, resource->getSize())); + delete resource; break; case 54: @@ -1586,11 +1104,15 @@ bool Inter_v1::o1_palLoad(OpFuncParams ¶ms) { break; case 61: - index1 = *_vm->_global->_inter_execPtr++; - index2 = (*_vm->_global->_inter_execPtr++ - index1 + 1) * 3; - palPtr = _vm->_game->loadTotResource(_vm->_inter->load16()); + index1 = _vm->_game->_script->readByte(); + index2 = (_vm->_game->_script->readByte() - index1 + 1) * 3; + resource = _vm->_game->_resources->getResource(_vm->_game->_script->readInt16()); + if (!resource) + break; + memcpy((char *) _vm->_draw->_vgaPalette + index1 * 3, - palPtr + index1 * 3, index2); + resource->getData() + index1 * 3, index2); + delete resource; if (_vm->_draw->_applyPal) { _vm->_draw->_applyPal = false; @@ -1628,7 +1150,7 @@ bool Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { int16 key; uint32 now; - cmd = load16(); + cmd = _vm->_game->_script->readInt16(); animPalette(); _vm->_draw->blitInvalidated(); @@ -1643,7 +1165,7 @@ bool Inter_v1::o1_keyFunc(OpFuncParams ¶ms) { // to become 5000. We deliberately slow down busy-waiting, so we shorten // the counting, too. if ((_vm->getGameType() == kGameTypeWeen) && (VAR(59) < 4000) && - ((_vm->_global->_inter_execPtr - _vm->_game->_totFileData) == 729) && + (_vm->_game->_script->pos() == 729) && !scumm_stricmp(_vm->_game->_curTotFile, "intro5.tot")) WRITE_VAR(59, 4000); @@ -1689,10 +1211,10 @@ bool Inter_v1::o1_capturePush(OpFuncParams ¶ms) { int16 left, top; int16 width, height; - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + left = _vm->_game->_script->readValExpr(); + top = _vm->_game->_script->readValExpr(); + width = _vm->_game->_script->readValExpr(); + height = _vm->_game->_script->readValExpr(); if ((width < 0) || (height < 0)) return false; @@ -1711,24 +1233,24 @@ bool Inter_v1::o1_capturePop(OpFuncParams ¶ms) { } bool Inter_v1::o1_animPalInit(OpFuncParams ¶ms) { - _animPalDir[0] = load16(); - _animPalLowIndex[0] = _vm->_parse->parseValExpr(); - _animPalHighIndex[0] = _vm->_parse->parseValExpr(); + _animPalDir[0] = _vm->_game->_script->readInt16(); + _animPalLowIndex[0] = _vm->_game->_script->readValExpr(); + _animPalHighIndex[0] = _vm->_game->_script->readValExpr(); return false; } bool Inter_v1::o1_drawOperations(OpFuncParams ¶ms) { byte cmd; - cmd = *_vm->_global->_inter_execPtr++; + cmd = _vm->_game->_script->readByte(); - executeDrawOpcode(cmd); + executeOpcodeDraw(cmd); return false; } bool Inter_v1::o1_setcmdCount(OpFuncParams ¶ms) { - params.cmdCount = *_vm->_global->_inter_execPtr++; + params.cmdCount = _vm->_game->_script->readByte(); params.counter = 0; return false; } @@ -1737,7 +1259,7 @@ bool Inter_v1::o1_return(OpFuncParams ¶ms) { if (params.retFlag != 2) _break = true; - _vm->_global->_inter_execPtr = 0; + _vm->_game->_script->setFinished(true); return true; } @@ -1747,7 +1269,7 @@ bool Inter_v1::o1_renewTimeInVars(OpFuncParams ¶ms) { } bool Inter_v1::o1_speakerOn(OpFuncParams ¶ms) { - _vm->_sound->speakerOn(_vm->_parse->parseValExpr(), -1); + _vm->_sound->speakerOn(_vm->_game->_script->readValExpr(), -1); return false; } @@ -1757,11 +1279,11 @@ bool Inter_v1::o1_speakerOff(OpFuncParams ¶ms) { } bool Inter_v1::o1_putPixel(OpFuncParams ¶ms) { - _vm->_draw->_destSurface = load16(); + _vm->_draw->_destSurface = _vm->_game->_script->readInt16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); + _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); _vm->_draw->spriteOperation(DRAW_PUTPIXEL); return false; } @@ -1773,33 +1295,33 @@ bool Inter_v1::o1_goblinFunc(OpFuncParams ¶ms) { gobParams.extraData = 0; gobParams.objDesc = 0; - gobParams.retVarPtr.set(*_vm->_inter->_variables, 236); + gobParams.retVarPtr.set(*_variables, 236); - cmd = load16(); - _vm->_global->_inter_execPtr += 2; + cmd = _vm->_game->_script->readInt16(); + _vm->_game->_script->skip(2); if ((cmd > 0) && (cmd < 17)) { objDescSet = true; - gobParams.extraData = load16(); + gobParams.extraData = _vm->_game->_script->readInt16(); gobParams.objDesc = _vm->_goblin->_objects[gobParams.extraData]; - gobParams.extraData = load16(); + gobParams.extraData = _vm->_game->_script->readInt16(); } if ((cmd > 90) && (cmd < 107)) { objDescSet = true; - gobParams.extraData = load16(); + gobParams.extraData = _vm->_game->_script->readInt16(); gobParams.objDesc = _vm->_goblin->_goblins[gobParams.extraData]; - gobParams.extraData = load16(); + gobParams.extraData = _vm->_game->_script->readInt16(); cmd -= 90; } if ((cmd > 110) && (cmd < 128)) { objDescSet = true; - gobParams.extraData = load16(); + gobParams.extraData = _vm->_game->_script->readInt16(); gobParams.objDesc = _vm->_goblin->_goblins[gobParams.extraData]; cmd -= 90; } else if ((cmd > 20) && (cmd < 38)) { objDescSet = true; - gobParams.extraData = load16(); + gobParams.extraData = _vm->_game->_script->readInt16(); gobParams.objDesc = _vm->_goblin->_objects[gobParams.extraData]; } @@ -1815,7 +1337,7 @@ bool Inter_v1::o1_goblinFunc(OpFuncParams ¶ms) { if ((cmd < 40) && objDescSet && !gobParams.objDesc) return false; - executeGoblinOpcode(cmd, gobParams); + executeOpcodeGob(cmd, gobParams); return false; } @@ -1825,31 +1347,31 @@ bool Inter_v1::o1_createSprite(OpFuncParams ¶ms) { int16 width, height; int16 flag; - if (_vm->_global->_inter_execPtr[1] == 0) { - index = load16(); - width = load16(); - height = load16(); + if (_vm->_game->_script->peekByte(1) == 0) { + index = _vm->_game->_script->readInt16(); + width = _vm->_game->_script->readInt16(); + height = _vm->_game->_script->readInt16(); } else { - index = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + index = _vm->_game->_script->readValExpr(); + width = _vm->_game->_script->readValExpr(); + height = _vm->_game->_script->readValExpr(); } - flag = load16(); + flag = _vm->_game->_script->readInt16(); _vm->_draw->initSpriteSurf(index, width, height, flag ? 2 : 0); return false; } bool Inter_v1::o1_freeSprite(OpFuncParams ¶ms) { - _vm->_draw->freeSprite(load16()); + _vm->_draw->freeSprite(_vm->_game->_script->readInt16()); return false; } bool Inter_v1::o1_returnTo(OpFuncParams ¶ms) { if (params.retFlag == 1) { _break = true; - _vm->_global->_inter_execPtr = 0; + _vm->_game->_script->setFinished(true); return true; } @@ -1858,14 +1380,14 @@ bool Inter_v1::o1_returnTo(OpFuncParams ¶ms) { *_breakFromLevel = *_nestLevel; _break = true; - _vm->_global->_inter_execPtr = 0; + _vm->_game->_script->setFinished(true); return true; } bool Inter_v1::o1_loadSpriteContent(OpFuncParams ¶ms) { - _vm->_draw->_spriteLeft = load16(); - _vm->_draw->_destSurface = load16(); - _vm->_draw->_transparency = load16(); + _vm->_draw->_spriteLeft = _vm->_game->_script->readInt16(); + _vm->_draw->_destSurface = _vm->_game->_script->readInt16(); + _vm->_draw->_transparency = _vm->_game->_script->readInt16(); _vm->_draw->_destSpriteX = 0; _vm->_draw->_destSpriteY = 0; @@ -1874,25 +1396,25 @@ bool Inter_v1::o1_loadSpriteContent(OpFuncParams ¶ms) { } bool Inter_v1::o1_copySprite(OpFuncParams ¶ms) { - if (_vm->_global->_inter_execPtr[1] == 0) - _vm->_draw->_sourceSurface = load16(); + if (_vm->_game->_script->peekByte(1) == 0) + _vm->_draw->_sourceSurface = _vm->_game->_script->readInt16(); else - _vm->_draw->_sourceSurface = _vm->_parse->parseValExpr(); + _vm->_draw->_sourceSurface = _vm->_game->_script->readValExpr(); - if (_vm->_global->_inter_execPtr[1] == 0) - _vm->_draw->_destSurface = load16(); + if (_vm->_game->_script->peekByte(1) == 0) + _vm->_draw->_destSurface = _vm->_game->_script->readInt16(); else - _vm->_draw->_destSurface = _vm->_parse->parseValExpr(); + _vm->_draw->_destSurface = _vm->_game->_script->readValExpr(); - _vm->_draw->_spriteLeft = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteTop = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + _vm->_draw->_spriteLeft = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteTop = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteRight = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteBottom = _vm->_game->_script->readValExpr(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); - _vm->_draw->_transparency = load16(); + _vm->_draw->_transparency = _vm->_game->_script->readInt16(); _vm->_draw->spriteOperation(DRAW_BLITSURF); return false; @@ -1901,16 +1423,16 @@ bool Inter_v1::o1_copySprite(OpFuncParams ¶ms) { bool Inter_v1::o1_fillRect(OpFuncParams ¶ms) { int16 destSurf; - _vm->_draw->_destSurface = destSurf = load16(); + _vm->_draw->_destSurface = destSurf = _vm->_game->_script->readInt16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteRight = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteBottom = _vm->_game->_script->readValExpr(); - _vm->_draw->_backColor = _vm->_parse->parseValExpr(); + _vm->_draw->_backColor = _vm->_game->_script->readValExpr(); - if (!_vm->_draw->_spritesArray[(destSurf > 100) ? (destSurf - 80) : destSurf]) + if (!_vm->_draw->_spritesArray[(destSurf >= 100) ? (destSurf - 80) : destSurf]) return false; if (_vm->_draw->_spriteRight < 0) { @@ -1927,14 +1449,14 @@ bool Inter_v1::o1_fillRect(OpFuncParams ¶ms) { } bool Inter_v1::o1_drawLine(OpFuncParams ¶ms) { - _vm->_draw->_destSurface = load16(); + _vm->_draw->_destSurface = _vm->_game->_script->readInt16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteRight = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteBottom = _vm->_game->_script->readValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); _vm->_draw->spriteOperation(DRAW_DRAWLINE); return false; } @@ -1945,28 +1467,28 @@ bool Inter_v1::o1_strToLong(OpFuncParams ¶ms) { int16 destVar; int32 res; - strVar = _vm->_parse->parseVarIndex(); + strVar = _vm->_game->_script->readVarIndex(); strncpy0(str, GET_VARO_STR(strVar), 19); res = atoi(str); - destVar = _vm->_parse->parseVarIndex(); + destVar = _vm->_game->_script->readVarIndex(); WRITE_VAR_OFFSET(destVar, res); return false; } bool Inter_v1::o1_invalidate(OpFuncParams ¶ms) { - _vm->_draw->_destSurface = load16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->_destSurface = _vm->_game->_script->readInt16(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteRight = _vm->_game->_script->readValExpr(); + _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); _vm->_draw->spriteOperation(DRAW_INVALIDATE); return false; } bool Inter_v1::o1_setBackDelta(OpFuncParams ¶ms) { - _vm->_draw->_backDeltaX = _vm->_parse->parseValExpr(); - _vm->_draw->_backDeltaY = _vm->_parse->parseValExpr(); + _vm->_draw->_backDeltaX = _vm->_game->_script->readValExpr(); + _vm->_draw->_backDeltaY = _vm->_game->_script->readValExpr(); return false; } @@ -1977,9 +1499,9 @@ bool Inter_v1::o1_playSound(OpFuncParams ¶ms) { int16 index; int16 endRep; - index = _vm->_parse->parseValExpr(); - repCount = _vm->_parse->parseValExpr(); - frequency = _vm->_parse->parseValExpr(); + index = _vm->_game->_script->readValExpr(); + repCount = _vm->_game->_script->readValExpr(); + frequency = _vm->_game->_script->readValExpr(); SoundDesc *sample = _vm->_sound->sampleGetBySlot(index); @@ -2002,7 +1524,7 @@ bool Inter_v1::o1_playSound(OpFuncParams ¶ms) { } if (sample->getType() == SOUND_ADL) { - _vm->_sound->adlibLoad(sample->getData(), sample->size(), index); + _vm->_sound->adlibLoadADL(sample->getData(), sample->size(), index); _vm->_sound->adlibSetRepeating(repCount - 1); _vm->_sound->adlibPlay(); } else { @@ -2015,7 +1537,7 @@ bool Inter_v1::o1_playSound(OpFuncParams ¶ms) { bool Inter_v1::o1_stopSound(OpFuncParams ¶ms) { _vm->_sound->adlibStop(); - _vm->_sound->blasterStop(_vm->_parse->parseValExpr()); + _vm->_sound->blasterStop(_vm->_game->_script->readValExpr()); _soundEndTimeKey = 0; return false; @@ -2041,8 +1563,8 @@ bool Inter_v1::o1_playComposition(OpFuncParams ¶ms) { int16 dataVar; int16 freqVal; - dataVar = _vm->_parse->parseVarIndex(); - freqVal = _vm->_parse->parseValExpr(); + dataVar = _vm->_game->_script->readVarIndex(); + freqVal = _vm->_game->_script->readValExpr(); for (int i = 0; i < 50; i++) composition[i] = (int16) VAR_OFFSET(dataVar + i * 4); @@ -2054,8 +1576,8 @@ bool Inter_v1::o1_getFreeMem(OpFuncParams ¶ms) { int16 freeVar; int16 maxFreeVar; - freeVar = _vm->_parse->parseVarIndex(); - maxFreeVar = _vm->_parse->parseVarIndex(); + freeVar = _vm->_game->_script->readVarIndex(); + maxFreeVar = _vm->_game->_script->readVarIndex(); // HACK WRITE_VAR_OFFSET(freeVar, 1000000); @@ -2067,22 +1589,22 @@ bool Inter_v1::o1_checkData(OpFuncParams ¶ms) { int16 handle; int16 varOff; - evalExpr(0); - varOff = _vm->_parse->parseVarIndex(); - handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); + _vm->_game->_script->evalExpr(0); + varOff = _vm->_game->_script->readVarIndex(); + handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr()); WRITE_VAR_OFFSET(varOff, handle); if (handle >= 0) _vm->_dataIO->closeData(handle); else - warning("File \"%s\" not found", _vm->_global->_inter_resStr); + warning("File \"%s\" not found", _vm->_game->_script->getResultStr()); return false; } bool Inter_v1::o1_prepareStr(OpFuncParams ¶ms) { int16 strVar; - strVar = _vm->_parse->parseVarIndex(); + strVar = _vm->_game->_script->readVarIndex(); _vm->_util->prepareStr(GET_VARO_FSTR(strVar)); return false; } @@ -2091,12 +1613,12 @@ bool Inter_v1::o1_insertStr(OpFuncParams ¶ms) { int16 pos; int16 strVar; - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - pos = _vm->_parse->parseValExpr(); + strVar = _vm->_game->_script->readVarIndex(); + _vm->_game->_script->evalExpr(0); + pos = _vm->_game->_script->readValExpr(); char *str = GET_VARO_FSTR(strVar); - _vm->_util->insertStr(_vm->_global->_inter_resStr, str, pos); + _vm->_util->insertStr(_vm->_game->_script->getResultStr(), str, pos); return false; } @@ -2105,9 +1627,9 @@ bool Inter_v1::o1_cutStr(OpFuncParams ¶ms) { int16 pos; int16 size; - strVar = _vm->_parse->parseVarIndex(); - pos = _vm->_parse->parseValExpr(); - size = _vm->_parse->parseValExpr(); + strVar = _vm->_game->_script->readVarIndex(); + pos = _vm->_game->_script->readValExpr(); + size = _vm->_game->_script->readValExpr(); _vm->_util->cutFromStr(GET_VARO_STR(strVar), pos, size); return false; } @@ -2117,11 +1639,11 @@ bool Inter_v1::o1_strstr(OpFuncParams ¶ms) { int16 resVar; int16 pos; - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - resVar = _vm->_parse->parseVarIndex(); + strVar = _vm->_game->_script->readVarIndex(); + _vm->_game->_script->evalExpr(0); + resVar = _vm->_game->_script->readVarIndex(); - char *res = strstr(GET_VARO_STR(strVar), _vm->_global->_inter_resStr); + char *res = strstr(GET_VARO_STR(strVar), _vm->_game->_script->getResultStr()); pos = res ? (res - (GET_VARO_STR(strVar))) : -1; WRITE_VAR_OFFSET(resVar, pos); return false; @@ -2131,17 +1653,17 @@ bool Inter_v1::o1_istrlen(OpFuncParams ¶ms) { int16 len; int16 strVar; - strVar = _vm->_parse->parseVarIndex(); + strVar = _vm->_game->_script->readVarIndex(); len = strlen(GET_VARO_STR(strVar)); - strVar = _vm->_parse->parseVarIndex(); + strVar = _vm->_game->_script->readVarIndex(); WRITE_VAR_OFFSET(strVar, len); return false; } bool Inter_v1::o1_setMousePos(OpFuncParams ¶ms) { - _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); - _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); + _vm->_global->_inter_mouseX = _vm->_game->_script->readValExpr(); + _vm->_global->_inter_mouseY = _vm->_game->_script->readValExpr(); _vm->_global->_inter_mouseX -= _vm->_video->_scrollOffsetX; _vm->_global->_inter_mouseY -= _vm->_video->_scrollOffsetY; if (_vm->_global->_useMouse != 0) @@ -2151,7 +1673,7 @@ bool Inter_v1::o1_setMousePos(OpFuncParams ¶ms) { } bool Inter_v1::o1_setFrameRate(OpFuncParams ¶ms) { - _vm->_util->setFrameRate(_vm->_parse->parseValExpr()); + _vm->_util->setFrameRate(_vm->_game->_script->readValExpr()); return false; } @@ -2177,27 +1699,23 @@ bool Inter_v1::o1_blitCursor(OpFuncParams ¶ms) { bool Inter_v1::o1_loadFont(OpFuncParams ¶ms) { int16 index; - evalExpr(0); - index = load16(); + _vm->_game->_script->evalExpr(0); + index = _vm->_game->_script->readInt16(); delete _vm->_draw->_fonts[index]; _vm->_draw->animateCursor(4); - if (_vm->_game->_extHandle >= 0) - _vm->_dataIO->closeData(_vm->_game->_extHandle); _vm->_draw->_fonts[index] = - _vm->_util->loadFont(_vm->_global->_inter_resStr); + _vm->_util->loadFont(_vm->_game->_script->getResultStr()); - if (_vm->_game->_extHandle >= 0) - _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); return false; } bool Inter_v1::o1_freeFont(OpFuncParams ¶ms) { int16 index; - index = load16(); + index = _vm->_game->_script->readInt16(); delete _vm->_draw->_fonts[index]; _vm->_draw->_fonts[index] = 0; return false; @@ -2210,17 +1728,14 @@ bool Inter_v1::o1_readData(OpFuncParams ¶ms) { int16 offset; int16 handle; - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); + _vm->_game->_script->evalExpr(0); + dataVar = _vm->_game->_script->readVarIndex(); + size = _vm->_game->_script->readValExpr(); + offset = _vm->_game->_script->readValExpr(); retSize = 0; - if (_vm->_game->_extHandle >= 0) - _vm->_dataIO->closeData(_vm->_game->_extHandle); - WRITE_VAR(1, 1); - handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); + handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr()); if (handle >= 0) { DataStream *stream = _vm->_dataIO->openAsStream(handle, true); @@ -2241,8 +1756,6 @@ bool Inter_v1::o1_readData(OpFuncParams ¶ms) { delete stream; } - if (_vm->_game->_extHandle >= 0) - _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); return false; } @@ -2255,22 +1768,22 @@ bool Inter_v1::o1_writeData(OpFuncParams ¶ms) { // (Gobliiins 1 doesn't use save file), so we just warn should it be // called regardless. - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); + _vm->_game->_script->evalExpr(0); + dataVar = _vm->_game->_script->readVarIndex(); + size = _vm->_game->_script->readValExpr(); + offset = _vm->_game->_script->readValExpr(); - warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr); + warning("Attempted to write to file \"%s\"", _vm->_game->_script->getResultStr()); WRITE_VAR(1, 0); return false; } bool Inter_v1::o1_manageDataFile(OpFuncParams ¶ms) { - evalExpr(0); + _vm->_game->_script->evalExpr(0); - if (_vm->_global->_inter_resStr[0] != 0) - _vm->_dataIO->openDataFile(_vm->_global->_inter_resStr); + if (_vm->_game->_script->getResultStr()[0] != 0) + _vm->_dataIO->openDataFile(_vm->_game->_script->getResultStr()); else _vm->_dataIO->closeDataFile(); return false; @@ -2434,16 +1947,16 @@ void Inter_v1::o1_getMaxTick(OpGobParams ¶ms) { } void Inter_v1::o1_manipulateMap(OpGobParams ¶ms) { - int16 xPos = load16(); - int16 yPos = load16(); - int16 item = load16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); + int16 item = _vm->_game->_script->readInt16(); manipulateMap(xPos, yPos, item); } void Inter_v1::o1_getItem(OpGobParams ¶ms) { - int16 xPos = load16(); - int16 yPos = load16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); if ((_vm->_map->getItem(xPos, yPos) & 0xFF00) != 0) params.retVarPtr = (uint32) ((_vm->_map->getItem(xPos, yPos) & 0xFF00) >> 8); @@ -2452,9 +1965,9 @@ void Inter_v1::o1_getItem(OpGobParams ¶ms) { } void Inter_v1::o1_manipulateMapIndirect(OpGobParams ¶ms) { - int16 xPos = load16(); - int16 yPos = load16(); - int16 item = load16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); + int16 item = _vm->_game->_script->readInt16(); xPos = VAR(xPos); yPos = VAR(yPos); @@ -2464,8 +1977,8 @@ void Inter_v1::o1_manipulateMapIndirect(OpGobParams ¶ms) { } void Inter_v1::o1_getItemIndirect(OpGobParams ¶ms) { - int16 xPos = load16(); - int16 yPos = load16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); xPos = VAR(xPos); yPos = VAR(yPos); @@ -2477,17 +1990,17 @@ void Inter_v1::o1_getItemIndirect(OpGobParams ¶ms) { } void Inter_v1::o1_setPassMap(OpGobParams ¶ms) { - int16 xPos = load16(); - int16 yPos = load16(); - int16 val = load16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); + int16 val = _vm->_game->_script->readInt16(); _vm->_map->setPass(xPos, yPos, val); } void Inter_v1::o1_setGoblinPosH(OpGobParams ¶ms) { int16 layer; - int16 item = load16(); - int16 xPos = load16(); - int16 yPos = load16(); + int16 item = _vm->_game->_script->readInt16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); _vm->_goblin->_gobPositions[item].x = xPos * 2; _vm->_goblin->_gobPositions[item].y = yPos * 2; @@ -2522,20 +2035,20 @@ void Inter_v1::o1_setGoblinPosH(OpGobParams ¶ms) { } void Inter_v1::o1_getGoblinPosXH(OpGobParams ¶ms) { - int16 item = load16(); + int16 item = _vm->_game->_script->readInt16(); params.retVarPtr = (uint32) (_vm->_goblin->_gobPositions[item].x >> 1); } void Inter_v1::o1_getGoblinPosYH(OpGobParams ¶ms) { - int16 item = load16(); + int16 item = _vm->_game->_script->readInt16(); params.retVarPtr = (uint32) (_vm->_goblin->_gobPositions[item].y >> 1); } void Inter_v1::o1_setGoblinMultState(OpGobParams ¶ms) { int16 layer; - int16 item = load16(); - int16 xPos = load16(); - int16 yPos = load16(); + int16 item = _vm->_game->_script->readInt16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); params.objDesc = _vm->_goblin->_goblins[item]; if (yPos == 0) { @@ -2594,18 +2107,18 @@ void Inter_v1::o1_setGoblinMultState(OpGobParams ¶ms) { } void Inter_v1::o1_setGoblinUnk14(OpGobParams ¶ms) { - int16 item = load16(); - int16 val = load16(); + int16 item = _vm->_game->_script->readInt16(); + int16 val = _vm->_game->_script->readInt16(); params.objDesc = _vm->_goblin->_objects[item]; params.objDesc->unk14 = val; } void Inter_v1::o1_setItemIdInPocket(OpGobParams ¶ms) { - _vm->_goblin->_itemIdInPocket = load16(); + _vm->_goblin->_itemIdInPocket = _vm->_game->_script->readInt16(); } void Inter_v1::o1_setItemIndInPocket(OpGobParams ¶ms) { - _vm->_goblin->_itemIndInPocket = load16(); + _vm->_goblin->_itemIndInPocket = _vm->_game->_script->readInt16(); } void Inter_v1::o1_getItemIdInPocket(OpGobParams ¶ms) { @@ -2618,9 +2131,9 @@ void Inter_v1::o1_getItemIndInPocket(OpGobParams ¶ms) { void Inter_v1::o1_setGoblinPos(OpGobParams ¶ms) { int16 layer; - int16 item = load16(); - int16 xPos = load16(); - int16 yPos = load16(); + int16 item = _vm->_game->_script->readInt16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); _vm->_goblin->_gobPositions[item].x = xPos; _vm->_goblin->_gobPositions[item].y = yPos; @@ -2655,8 +2168,8 @@ void Inter_v1::o1_setGoblinPos(OpGobParams ¶ms) { void Inter_v1::o1_setGoblinState(OpGobParams ¶ms) { int16 layer; - int16 item = load16(); - int16 state = load16(); + int16 item = _vm->_game->_script->readInt16(); + int16 state = _vm->_game->_script->readInt16(); params.objDesc = _vm->_goblin->_goblins[item]; params.objDesc->nextState = state; @@ -2680,8 +2193,8 @@ void Inter_v1::o1_setGoblinState(OpGobParams ¶ms) { void Inter_v1::o1_setGoblinStateRedraw(OpGobParams ¶ms) { int16 layer; - int16 item = load16(); - int16 state = load16(); + int16 item = _vm->_game->_script->readInt16(); + int16 state = _vm->_game->_script->readInt16(); params.objDesc = _vm->_goblin->_objects[item]; params.objDesc->nextState = state; @@ -2708,7 +2221,7 @@ void Inter_v1::o1_setGoblinStateRedraw(OpGobParams ¶ms) { } void Inter_v1::o1_decRelaxTime(OpGobParams ¶ms) { - params.extraData = load16(); + params.extraData = _vm->_game->_script->readInt16(); params.objDesc = _vm->_goblin->_objects[params.extraData]; params.objDesc->relaxTime--; @@ -2722,12 +2235,12 @@ void Inter_v1::o1_decRelaxTime(OpGobParams ¶ms) { } void Inter_v1::o1_getGoblinPosX(OpGobParams ¶ms) { - int16 item = load16(); + int16 item = _vm->_game->_script->readInt16(); params.retVarPtr = (uint32) _vm->_goblin->_gobPositions[item].x; } void Inter_v1::o1_getGoblinPosY(OpGobParams ¶ms) { - int16 item = load16(); + int16 item = _vm->_game->_script->readInt16(); params.retVarPtr = (uint32) _vm->_goblin->_gobPositions[item].y; } @@ -2736,18 +2249,18 @@ void Inter_v1::o1_clearPathExistence(OpGobParams ¶ms) { } void Inter_v1::o1_setGoblinVisible(OpGobParams ¶ms) { - params.extraData = load16(); + params.extraData = _vm->_game->_script->readInt16(); _vm->_goblin->_goblins[params.extraData]->visible = 1; } void Inter_v1::o1_setGoblinInvisible(OpGobParams ¶ms) { - params.extraData = load16(); + params.extraData = _vm->_game->_script->readInt16(); _vm->_goblin->_goblins[params.extraData]->visible = 0; } void Inter_v1::o1_getObjectIntersect(OpGobParams ¶ms) { - params.extraData = load16(); - int16 item = load16(); + params.extraData = _vm->_game->_script->readInt16(); + int16 item = _vm->_game->_script->readInt16(); params.objDesc = _vm->_goblin->_objects[params.extraData]; if (_vm->_goblin->objIntersected(params.objDesc, @@ -2758,8 +2271,8 @@ void Inter_v1::o1_getObjectIntersect(OpGobParams ¶ms) { } void Inter_v1::o1_getGoblinIntersect(OpGobParams ¶ms) { - params.extraData = load16(); - int16 item = load16(); + params.extraData = _vm->_game->_script->readInt16(); + int16 item = _vm->_game->_script->readInt16(); params.objDesc = _vm->_goblin->_goblins[params.extraData]; if (_vm->_goblin->objIntersected(params.objDesc, @@ -2770,10 +2283,10 @@ void Inter_v1::o1_getGoblinIntersect(OpGobParams ¶ms) { } void Inter_v1::o1_setItemPos(OpGobParams ¶ms) { - int16 item = load16(); - int16 xPos = load16(); - int16 yPos = load16(); - int16 val = load16(); + int16 item = _vm->_game->_script->readInt16(); + int16 xPos = _vm->_game->_script->readInt16(); + int16 yPos = _vm->_game->_script->readInt16(); + int16 val = _vm->_game->_script->readInt16(); _vm->_map->_itemPoses[item].x = xPos; _vm->_map->_itemPoses[item].y = yPos; @@ -2781,12 +2294,9 @@ void Inter_v1::o1_setItemPos(OpGobParams ¶ms) { } void Inter_v1::o1_loadObjects(OpGobParams ¶ms) { - params.extraData = load16(); - if (_vm->_game->_extHandle >= 0) - _vm->_dataIO->closeData(_vm->_game->_extHandle); + params.extraData = _vm->_game->_script->readInt16(); _vm->_goblin->loadObjects((char *) VAR_ADDRESS(params.extraData)); - _vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile); } void Inter_v1::o1_freeObjects(OpGobParams ¶ms) { @@ -2811,8 +2321,8 @@ void Inter_v1::o1_loadMap(OpGobParams ¶ms) { void Inter_v1::o1_moveGoblin(OpGobParams ¶ms) { int16 item; - params.extraData = load16(); - int16 xPos = load16(); + params.extraData = _vm->_game->_script->readInt16(); + int16 xPos = _vm->_game->_script->readInt16(); if ((uint16) VAR(xPos) == 0) { item = @@ -2837,9 +2347,9 @@ void Inter_v1::o1_loadGoblin(OpGobParams ¶ms) { } void Inter_v1::o1_writeTreatItem(OpGobParams ¶ms) { - params.extraData = load16(); - int16 cmd = load16(); - int16 xPos = load16(); + params.extraData = _vm->_game->_script->readInt16(); + int16 cmd = _vm->_game->_script->readInt16(); + int16 xPos = _vm->_game->_script->readInt16(); if ((uint16) VAR(xPos) == 0) { WRITE_VAR(cmd, _vm->_goblin->treatItem((uint16) VAR(params.extraData))); @@ -2855,7 +2365,7 @@ void Inter_v1::o1_moveGoblin0(OpGobParams ¶ms) { } void Inter_v1::o1_setGoblinTarget(OpGobParams ¶ms) { - params.extraData = load16(); + params.extraData = _vm->_game->_script->readInt16(); if (VAR(params.extraData) != 0) _vm->_goblin->_goesAtTarget = 1; else @@ -2863,11 +2373,11 @@ void Inter_v1::o1_setGoblinTarget(OpGobParams ¶ms) { } void Inter_v1::o1_setGoblinObjectsPos(OpGobParams ¶ms) { - params.extraData = load16(); + params.extraData = _vm->_game->_script->readInt16(); params.extraData = VAR(params.extraData); _vm->_goblin->_objects[10]->xPos = params.extraData; - params.extraData = load16(); + params.extraData = _vm->_game->_script->readInt16(); params.extraData = VAR(params.extraData); _vm->_goblin->_objects[10]->yPos = params.extraData; } @@ -2961,38 +2471,24 @@ void Inter_v1::o1_initGoblin(OpGobParams ¶ms) { } int16 Inter_v1::loadSound(int16 slot) { - byte *dataPtr; - int16 id; - uint32 dataSize; - SoundSource source; - if (slot == -1) - slot = _vm->_parse->parseValExpr(); + slot = _vm->_game->_script->readValExpr(); - id = load16(); - if (id == -1) { - _vm->_global->_inter_execPtr += 9; + uint16 id = _vm->_game->_script->readUint16(); + if (id == 0xFFFF) { + _vm->_game->_script->skip(9); return 0; } - if (id >= 30000) { - source = SOUND_EXT; - - dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); - } else { - int16 totSize; - - source = SOUND_TOT; + Resource *resource = _vm->_game->_resources->getResource(id); + if (!resource) + return 0; - dataPtr = (byte *) _vm->_game->loadTotResource(id, &totSize); - dataSize = (uint32) ((int32) totSize); - } + SoundDesc *sample = _vm->_sound->sampleGetBySlot(slot); + if (!sample) + return 0; - if (dataPtr) { - SoundDesc *sample = _vm->_sound->sampleGetBySlot(slot); - if (sample) - sample->load(SOUND_SND, source, dataPtr, dataSize); - } + sample->load(SOUND_SND, resource); return 0; } diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 2c6a9e373c..82822330b1 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -36,10 +36,12 @@ #include "gob/dataio.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/expression.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/goblin.h" #include "gob/map.h" #include "gob/mult.h" -#include "gob/parse.h" #include "gob/scenery.h" #include "gob/video.h" #include "gob/save/saveload.h" @@ -48,673 +50,126 @@ namespace Gob { -#define OPCODE(x) _OPCODE(Inter_v2, x) - -const int Inter_v2::_goblinFuncLookUp[][2] = { - {0, 0}, - {1, 1}, - {2, 2}, - {4, 3}, - {5, 4}, - {6, 5}, - {7, 6}, - {8, 7}, - {9, 8}, - {10, 9}, - {12, 10}, - {13, 11}, - {14, 12}, - {15, 13}, - {16, 14}, - {21, 15}, - {22, 16}, - {23, 17}, - {24, 18}, - {25, 19}, - {26, 20}, - {27, 21}, - {28, 22}, - {29, 23}, - {30, 24}, - {32, 25}, - {33, 26}, - {34, 27}, - {35, 28}, - {36, 29}, - {37, 30}, - {40, 31}, - {41, 32}, - {42, 33}, - {43, 34}, - {44, 35}, - {50, 36}, - {52, 37}, - {53, 38}, - {100, 39}, - {500, 40}, - {501, 41} -}; +#define OPCODEVER Inter_v2 +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_v2::Inter_v2(GobEngine *vm) : Inter_v1(vm) { - setupOpcodes(); } -void Inter_v2::setupOpcodes() { - static const OpcodeDrawEntryV2 opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o2_playMult), - OPCODE(o2_freeMultKeys), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(o2_setRenderFlags), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - OPCODE(o2_multSub), - /* 14 */ - OPCODE(o2_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o2_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o2_renderStatic), - OPCODE(o2_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o2_playCDTrack), - OPCODE(o2_waitCDTrackEnd), - OPCODE(o2_stopCD), - OPCODE(o2_readLIC), - /* 24 */ - OPCODE(o2_freeLIC), - OPCODE(o2_getCDTrackPos), - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o2_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - OPCODE(o2_totSub), - OPCODE(o2_switchTotSub), - OPCODE(o2_pushVars), - OPCODE(o2_popVars), - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - OPCODE(o2_loadMapObjects), - OPCODE(o2_freeGoblins), - OPCODE(o2_moveGoblin), - OPCODE(o2_writeGoblinPos), - /* 54 */ - OPCODE(o2_stopGoblin), - OPCODE(o2_setGoblinState), - OPCODE(o2_placeGoblin), - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - OPCODE(o2_initScreen), - OPCODE(o2_scroll), - OPCODE(o2_setScrollOffset), - OPCODE(o2_playImd), - /* 84 */ - OPCODE(o2_getImdInfo), - OPCODE(o2_openItk), - OPCODE(o2_closeItk), - OPCODE(o2_setImdFrontSurf), - /* 88 */ - OPCODE(o2_resetImdFrontSurf), - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryV2 opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o1_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o2_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o2_printText), - OPCODE(o1_loadTot), - OPCODE(o1_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o2_animPalInit), - /* 18 */ - OPCODE(o2_addCollision), - OPCODE(o2_freeCollision), - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o2_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o1_copySprite), - OPCODE(o1_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o2_stopSound), - OPCODE(o2_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o2_getFreeMem), - OPCODE(o2_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o1_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o2_readData), - OPCODE(o2_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryV2 opcodesGoblin[71] = { - /* 00 */ - OPCODE(o2_loadInfogramesIns), - OPCODE(o2_startInfogrames), - OPCODE(o2_stopInfogrames), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 08 */ - {0, ""}, - OPCODE(o2_playInfogrames), - {0, ""}, - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 14 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 20 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 24 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o2_handleGoblins), - /* 28 */ - OPCODE(o2_playProtracker), - OPCODE(o2_stopProtracker), - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - }; - - _opcodesDrawV2 = opcodesDraw; - _opcodesFuncV2 = opcodesFunc; - _opcodesGoblinV2 = opcodesGoblin; -} +void Inter_v2::setupOpcodesDraw() { + Inter_v1::setupOpcodesDraw(); -void Inter_v2::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); + OPCODEDRAW(0x01, o2_playMult); + OPCODEDRAW(0x02, o2_freeMultKeys); - OpcodeDrawProcV2 op = _opcodesDrawV2[i].proc; + OPCODEDRAW(0x0A, o2_setRenderFlags); - if (op == 0) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); -} + OPCODEDRAW(0x13, o2_multSub); -bool Inter_v2::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", - i, j, i, j, getOpcodeFuncDesc(i, j)); + OPCODEDRAW(0x14, o2_initMult); - if ((i > 4) || (j > 15)) { - warning("unimplemented opcodeFunc: %d.%d", i, j); - return false; - } + OPCODEDRAW(0x17, o2_loadMultObject); - OpcodeFuncProcV2 op = _opcodesFuncV2[i*16 + j].proc; + OPCODEDRAW(0x1C, o2_renderStatic); + OPCODEDRAW(0x1D, o2_loadCurLayer); - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); + OPCODEDRAW(0x20, o2_playCDTrack); + OPCODEDRAW(0x21, o2_waitCDTrackEnd); + OPCODEDRAW(0x22, o2_stopCD); + OPCODEDRAW(0x23, o2_readLIC); - return false; -} + OPCODEDRAW(0x24, o2_freeLIC); + OPCODEDRAW(0x25, o2_getCDTrackPos); -void Inter_v2::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); + OPCODEDRAW(0x30, o2_loadFontToSprite); - OpcodeGoblinProcV2 op = 0; + OPCODEDRAW(0x40, o2_totSub); + OPCODEDRAW(0x41, o2_switchTotSub); + OPCODEDRAW(0x42, o2_pushVars); + OPCODEDRAW(0x43, o2_popVars); - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinV2[_goblinFuncLookUp[j][1]].proc; - break; - } + OPCODEDRAW(0x50, o2_loadMapObjects); + OPCODEDRAW(0x51, o2_freeGoblins); + OPCODEDRAW(0x52, o2_moveGoblin); + OPCODEDRAW(0x53, o2_writeGoblinPos); - if (op == 0) { - int16 val; + OPCODEDRAW(0x54, o2_stopGoblin); + OPCODEDRAW(0x55, o2_setGoblinState); + OPCODEDRAW(0x56, o2_placeGoblin); - _vm->_global->_inter_execPtr -= 2; - val = load16(); - _vm->_global->_inter_execPtr += val << 1; - } else - (this->*op) (params); -} + OPCODEDRAW(0x80, o2_initScreen); + OPCODEDRAW(0x81, o2_scroll); + OPCODEDRAW(0x82, o2_setScrollOffset); + OPCODEDRAW(0x83, o2_playImd); + + OPCODEDRAW(0x84, o2_getImdInfo); + OPCODEDRAW(0x85, o2_openItk); + OPCODEDRAW(0x86, o2_closeItk); + OPCODEDRAW(0x87, o2_setImdFrontSurf); -const char *Inter_v2::getOpcodeDrawDesc(byte i) { - return _opcodesDrawV2[i].desc; + OPCODEDRAW(0x88, o2_resetImdFrontSurf); } -const char *Inter_v2::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; +void Inter_v2::setupOpcodesFunc() { + Inter_v1::setupOpcodesFunc(); + + OPCODEFUNC(0x09, o2_assign); + + OPCODEFUNC(0x11, o2_printText); + + OPCODEFUNC(0x17, o2_animPalInit); - return _opcodesFuncV2[i*16 + j].desc; + OPCODEFUNC(0x18, o2_addCollision); + OPCODEFUNC(0x19, o2_freeCollision); + + OPCODEFUNC(0x25, o2_goblinFunc); + + OPCODEFUNC(0x39, o2_stopSound); + OPCODEFUNC(0x3A, o2_loadSound); + + OPCODEFUNC(0x3E, o2_getFreeMem); + OPCODEFUNC(0x3F, o2_checkData); + + OPCODEFUNC(0x4D, o2_readData); + OPCODEFUNC(0x4E, o2_writeData); } -const char *Inter_v2::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinV2[_goblinFuncLookUp[j][1]].desc; - return ""; +void Inter_v2::setupOpcodesGob() { + OPCODEGOB( 0, o2_loadInfogramesIns); + OPCODEGOB( 1, o2_startInfogrames); + OPCODEGOB( 2, o2_stopInfogrames); + + OPCODEGOB( 10, o2_playInfogrames); + + OPCODEGOB(100, o2_handleGoblins); + + OPCODEGOB(500, o2_playProtracker); + OPCODEGOB(501, o2_stopProtracker); } -void Inter_v2::checkSwitchTable(byte **ppExec) { - byte cmd; +void Inter_v2::checkSwitchTable(uint32 &offset) { + byte type; int16 len; int32 value; bool found; found = false; - *ppExec = 0; + offset = 0; - cmd = *_vm->_global->_inter_execPtr; + type = _vm->_game->_script->peekByte(); - value = _vm->_parse->parseVarIndex(); + value = _vm->_game->_script->readVarIndex(); - switch (cmd) { - case 16: - case 18: + switch (type) { + case TYPE_VAR_INT8: + case TYPE_ARRAY_INT8: value = (int8) READ_VARO_UINT8(value); break; - case 23: - case 26: + case TYPE_VAR_INT32: + case TYPE_ARRAY_INT32: value = READ_VARO_UINT32(value); break; @@ -726,78 +181,74 @@ void Inter_v2::checkSwitchTable(byte **ppExec) { if (_terminate) return; - len = (int8) *_vm->_global->_inter_execPtr++; + len = _vm->_game->_script->readInt8(); while (len != -5) { for (int i = 0; i < len; i++) { - cmd = *_vm->_global->_inter_execPtr; + type = _vm->_game->_script->peekByte(); - switch (cmd) { - case 19: - _vm->_global->_inter_execPtr++; + switch (type) { + case TYPE_IMM_INT32: + _vm->_game->_script->skip(1); if (!found && - (value == - (int32) (READ_LE_UINT32(_vm->_global->_inter_execPtr)))) + (value == _vm->_game->_script->peekInt32())) found = true; - _vm->_global->_inter_execPtr += 5; + _vm->_game->_script->skip(5); break; - case 20: - _vm->_global->_inter_execPtr++; + case TYPE_IMM_INT16: + _vm->_game->_script->skip(1); if (!found && - (value == - (int16) (READ_LE_UINT16(_vm->_global->_inter_execPtr)))) + (value == _vm->_game->_script->peekInt16())) found = true; - _vm->_global->_inter_execPtr += 3; + _vm->_game->_script->skip(3); break; - case 21: - _vm->_global->_inter_execPtr++; - if (!found && (value == (int8) *_vm->_global->_inter_execPtr)) + case TYPE_IMM_INT8: + _vm->_game->_script->skip(1); + if (!found && (value == _vm->_game->_script->peekInt8())) found = true; - _vm->_global->_inter_execPtr += 2; + _vm->_game->_script->skip(2); break; default: if (!found) { - evalExpr(0); - if (value == _vm->_global->_inter_resVal) + _vm->_game->_script->evalExpr(0); + if (value == _vm->_game->_script->getResultInt()) found = true; } else - _vm->_parse->skipExpr(99); + _vm->_game->_script->skipExpr(99); break; } } - if (found && !*ppExec) - *ppExec = _vm->_global->_inter_execPtr; + if (found && (offset == 0)) + offset = _vm->_game->_script->pos(); - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - len = (int8) *_vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); + len = _vm->_game->_script->readInt8(); } - if ((*_vm->_global->_inter_execPtr >> 4) != 4) + if ((_vm->_game->_script->peekByte() >> 4) != 4) return; - _vm->_global->_inter_execPtr++; - if (!*ppExec) - *ppExec = _vm->_global->_inter_execPtr; + _vm->_game->_script->skip(1); + if (offset == 0) + offset = _vm->_game->_script->pos(); - _vm->_global->_inter_execPtr += - READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + _vm->_game->_script->skip(_vm->_game->_script->peekUint16(2) + 2); } void Inter_v2::o2_playMult() { int16 checkEscape; - checkEscape = load16(); + checkEscape = _vm->_game->_script->readInt16(); _vm->_mult->setMultData(checkEscape >> 1); _vm->_mult->playMult(VAR(57), -1, checkEscape & 0x1, 0); } void Inter_v2::o2_freeMultKeys() { - uint16 index = load16(); + uint16 index = _vm->_game->_script->readUint16(); if (!_vm->_mult->hasMultData(index)) return; @@ -810,7 +261,7 @@ void Inter_v2::o2_freeMultKeys() { void Inter_v2::o2_setRenderFlags() { int16 expr; - expr = _vm->_parse->parseValExpr(); + expr = _vm->_game->_script->readValExpr(); if (expr & 0x8000) { _vm->_draw->_renderFlags |= expr & 0x3FFF; @@ -823,7 +274,7 @@ void Inter_v2::o2_setRenderFlags() { } void Inter_v2::o2_multSub() { - _vm->_mult->multSub(_vm->_parse->parseValExpr()); + _vm->_mult->multSub(_vm->_game->_script->readValExpr()); } void Inter_v2::o2_initMult() { @@ -838,14 +289,14 @@ void Inter_v2::o2_initMult() { oldAnimHeight = _vm->_mult->_animHeight; oldObjCount = _vm->_mult->_objCount; - _vm->_mult->_animLeft = load16(); - _vm->_mult->_animTop = load16(); - _vm->_mult->_animWidth = load16(); - _vm->_mult->_animHeight = load16(); - _vm->_mult->_objCount = load16(); - posXVar = _vm->_parse->parseVarIndex(); - posYVar = _vm->_parse->parseVarIndex(); - animDataVar = _vm->_parse->parseVarIndex(); + _vm->_mult->_animLeft = _vm->_game->_script->readInt16(); + _vm->_mult->_animTop = _vm->_game->_script->readInt16(); + _vm->_mult->_animWidth = _vm->_game->_script->readInt16(); + _vm->_mult->_animHeight = _vm->_game->_script->readInt16(); + _vm->_mult->_objCount = _vm->_game->_script->readInt16(); + posXVar = _vm->_game->_script->readVarIndex(); + posYVar = _vm->_game->_script->readVarIndex(); + animDataVar = _vm->_game->_script->readVarIndex(); if (_vm->_mult->_objects && (oldObjCount != _vm->_mult->_objCount)) { warning("Initializing new objects without having " @@ -907,12 +358,12 @@ void Inter_v2::o2_initMult() { ((oldAnimWidth != _vm->_mult->_animWidth) || (oldAnimHeight != _vm->_mult->_animHeight))) { _vm->_draw->freeSprite(22); - _vm->_mult->_animSurf = 0; + _vm->_mult->_animSurf.reset(); } _vm->_draw->adjustCoords(0, &_vm->_mult->_animWidth, &_vm->_mult->_animHeight); - if (_vm->_mult->_animSurf == 0) { + if (!_vm->_mult->_animSurf) { _vm->_draw->initSpriteSurf(22, _vm->_mult->_animWidth, _vm->_mult->_animHeight, 0); _vm->_mult->_animSurf = _vm->_draw->_spritesArray[22]; @@ -947,20 +398,20 @@ void Inter_v2::o2_loadMultObject() { int16 layer; byte *multData; - objIndex = _vm->_parse->parseValExpr(); - val = _vm->_parse->parseValExpr(); + objIndex = _vm->_game->_script->readValExpr(); + val = _vm->_game->_script->readValExpr(); *_vm->_mult->_objects[objIndex].pPosX = val; - val = _vm->_parse->parseValExpr(); + val = _vm->_game->_script->readValExpr(); *_vm->_mult->_objects[objIndex].pPosY = val; debugC(4, kDebugGameFlow, "Loading mult object %d", objIndex); multData = (byte *) _vm->_mult->_objects[objIndex].pAnimData; for (int i = 0; i < 11; i++) { - if (*_vm->_global->_inter_execPtr != 99) - multData[i] = _vm->_parse->parseValExpr(); + if (_vm->_game->_script->peekByte() != 99) + multData[i] = _vm->_game->_script->readValExpr(); else - _vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(1); } Mult::Mult_Object &obj = _vm->_mult->_objects[objIndex]; @@ -1043,22 +494,22 @@ void Inter_v2::o2_renderStatic() { int16 layer; int16 index; - index = _vm->_parse->parseValExpr(); - layer = _vm->_parse->parseValExpr(); + index = _vm->_game->_script->readValExpr(); + layer = _vm->_game->_script->readValExpr(); _vm->_scenery->renderStatic(index, layer); } void Inter_v2::o2_loadCurLayer() { - _vm->_scenery->_curStatic = _vm->_parse->parseValExpr(); - _vm->_scenery->_curStaticLayer = _vm->_parse->parseValExpr(); + _vm->_scenery->_curStatic = _vm->_game->_script->readValExpr(); + _vm->_scenery->_curStaticLayer = _vm->_game->_script->readValExpr(); } void Inter_v2::o2_playCDTrack() { if (!(_vm->_draw->_renderFlags & RENDERFLAG_NOBLITINVALIDATED)) _vm->_draw->blitInvalidated(); - evalExpr(0); - _vm->_sound->cdPlay(_vm->_global->_inter_resStr); + _vm->_game->_script->evalExpr(0); + _vm->_sound->cdPlay(_vm->_game->_script->getResultStr()); } void Inter_v2::o2_waitCDTrackEnd() { @@ -1075,8 +526,8 @@ void Inter_v2::o2_stopCD() { void Inter_v2::o2_readLIC() { char path[40]; - evalExpr(0); - strncpy0(path, _vm->_global->_inter_resStr, 35); + _vm->_game->_script->evalExpr(0); + strncpy0(path, _vm->_game->_script->getResultStr(), 35); strcat(path, ".LIC"); _vm->_sound->cdLoadLIC(path); @@ -1092,24 +543,24 @@ void Inter_v2::o2_getCDTrackPos() { _vm->_util->longDelay(1); - varPos = _vm->_parse->parseVarIndex(); - varName = _vm->_parse->parseVarIndex(); + varPos = _vm->_game->_script->readVarIndex(); + varName = _vm->_game->_script->readVarIndex(); WRITE_VAR_OFFSET(varPos, _vm->_sound->cdGetTrackPos(GET_VARO_STR(varName))); WRITE_VARO_STR(varName, _vm->_sound->cdGetCurrentTrack()); } void Inter_v2::o2_loadFontToSprite() { - int16 i = load16(); - - _vm->_draw->_fontToSprite[i].sprite = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_draw->_fontToSprite[i].base = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_draw->_fontToSprite[i].width = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; - _vm->_draw->_fontToSprite[i].height = *_vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += 2; + int16 i = _vm->_game->_script->readInt16(); + + _vm->_draw->_fontToSprite[i].sprite = _vm->_game->_script->readByte(); + _vm->_game->_script->skip(1); + _vm->_draw->_fontToSprite[i].base = _vm->_game->_script->readByte(); + _vm->_game->_script->skip(1); + _vm->_draw->_fontToSprite[i].width = _vm->_game->_script->readByte(); + _vm->_game->_script->skip(1); + _vm->_draw->_fontToSprite[i].height = _vm->_game->_script->readByte(); + _vm->_game->_script->skip(1); } void Inter_v2::o2_totSub() { @@ -1118,16 +569,16 @@ void Inter_v2::o2_totSub() { int flags; int i; - length = *_vm->_global->_inter_execPtr++; + length = _vm->_game->_script->readByte(); if ((length & 0x7F) > 13) error("Length in o2_totSub is greater than 13 (%d)", length); if (length & 0x80) { - evalExpr(0); - strcpy(totFile, _vm->_global->_inter_resStr); + _vm->_game->_script->evalExpr(0); + strcpy(totFile, _vm->_game->_script->getResultStr()); } else { for (i = 0; i < length; i++) - totFile[i] = (char) *_vm->_global->_inter_execPtr++; + totFile[i] = _vm->_game->_script->readChar(); totFile[i] = 0; } @@ -1135,7 +586,7 @@ void Inter_v2::o2_totSub() { if (!scumm_stricmp(totFile, "edit")) _vm->_util->forceMouseUp(); - flags = *_vm->_global->_inter_execPtr++; + flags = _vm->_game->_script->readByte(); _vm->_game->totSub(flags, totFile); } @@ -1143,8 +594,8 @@ void Inter_v2::o2_switchTotSub() { int16 index; int16 skipPlay; - index = load16(); - skipPlay = load16(); + index = _vm->_game->_script->readInt16(); + skipPlay = _vm->_game->_script->readInt16(); _vm->_game->switchTotSub(index, skipPlay); } @@ -1153,13 +604,13 @@ void Inter_v2::o2_pushVars() { byte count; int16 varOff; - count = *_vm->_global->_inter_execPtr++; + count = _vm->_game->_script->readByte(); for (int i = 0; i < count; i++, _varStackPos++) { - if ((*_vm->_global->_inter_execPtr == 25) || - (*_vm->_global->_inter_execPtr == 28)) { + if ((_vm->_game->_script->peekByte() == 25) || + (_vm->_game->_script->peekByte() == 28)) { - varOff = _vm->_parse->parseVarIndex(); - _vm->_global->_inter_execPtr++; + varOff = _vm->_game->_script->readVarIndex(); + _vm->_game->_script->skip(1); _variables->copyTo(varOff, _varStack + _varStackPos, _vm->_global->_inter_animDataSize * 4); @@ -1167,10 +618,12 @@ void Inter_v2::o2_pushVars() { _varStack[_varStackPos] = _vm->_global->_inter_animDataSize * 4; } else { - if (evalExpr(&varOff) != 20) - _vm->_global->_inter_resVal = 0; + int32 n = _vm->_game->_script->getResultInt(); + + if (_vm->_game->_script->evalExpr(&varOff) != 20) + n = 0; - memcpy(_varStack + _varStackPos, &_vm->_global->_inter_resVal, 4); + memcpy(_varStack + _varStackPos, &n, 4); _varStackPos += 4; _varStack[_varStackPos] = 4; } @@ -1182,9 +635,9 @@ void Inter_v2::o2_popVars() { int16 varOff; int16 size; - count = *_vm->_global->_inter_execPtr++; + count = _vm->_game->_script->readByte(); for (int i = 0; i < count; i++) { - varOff = _vm->_parse->parseVarIndex(); + varOff = _vm->_game->_script->readVarIndex(); size = _varStack[--_varStackPos]; _varStackPos -= size; @@ -1204,9 +657,9 @@ void Inter_v2::o2_moveGoblin() { int16 destX, destY; int16 index; - destX = _vm->_parse->parseValExpr(); - destY = _vm->_parse->parseValExpr(); - index = _vm->_parse->parseValExpr(); + destX = _vm->_game->_script->readValExpr(); + destY = _vm->_game->_script->readValExpr(); + index = _vm->_game->_script->readValExpr(); _vm->_goblin->move(destX, destY, index); } @@ -1214,15 +667,15 @@ void Inter_v2::o2_writeGoblinPos() { int16 varX, varY; int16 index; - varX = _vm->_parse->parseVarIndex(); - varY = _vm->_parse->parseVarIndex(); - index = _vm->_parse->parseValExpr(); + varX = _vm->_game->_script->readVarIndex(); + varY = _vm->_game->_script->readVarIndex(); + index = _vm->_game->_script->readValExpr(); WRITE_VAR_OFFSET(varX, _vm->_mult->_objects[index].goblinX); WRITE_VAR_OFFSET(varY, _vm->_mult->_objects[index].goblinY); } void Inter_v2::o2_stopGoblin() { - int16 index = _vm->_parse->parseValExpr(); + int16 index = _vm->_game->_script->readValExpr(); _vm->_mult->_objects[index].pAnimData->pathExistence = 4; } @@ -1236,9 +689,9 @@ void Inter_v2::o2_setGoblinState() { int16 deltaX, deltaY; int16 deltaWidth, deltaHeight; - index = _vm->_parse->parseValExpr(); - state = _vm->_parse->parseValExpr(); - type = _vm->_parse->parseValExpr(); + index = _vm->_game->_script->readValExpr(); + state = _vm->_game->_script->readValExpr(); + type = _vm->_game->_script->readValExpr(); Mult::Mult_Object &obj = _vm->_mult->_objects[index]; Mult::Mult_AnimData &objAnim = *(obj.pAnimData); @@ -1334,10 +787,10 @@ void Inter_v2::o2_placeGoblin() { int16 x, y; int16 state; - index = _vm->_parse->parseValExpr(); - x = _vm->_parse->parseValExpr(); - y = _vm->_parse->parseValExpr(); - state = _vm->_parse->parseValExpr(); + index = _vm->_game->_script->readValExpr(); + x = _vm->_game->_script->readValExpr(); + y = _vm->_game->_script->readValExpr(); + state = _vm->_game->_script->readValExpr(); _vm->_goblin->placeObject(0, 0, index, x, y, state); } @@ -1347,13 +800,13 @@ void Inter_v2::o2_initScreen() { int16 videoMode; int16 width, height; - offY = load16(); + offY = _vm->_game->_script->readInt16(); videoMode = offY & 0xFF; offY = (offY >> 8) & 0xFF; - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + width = _vm->_game->_script->readValExpr(); + height = _vm->_game->_script->readValExpr(); _vm->_video->clearScreen(); @@ -1441,16 +894,16 @@ void Inter_v2::o2_scroll() { int16 curX; int16 curY; - startX = CLIP((int) _vm->_parse->parseValExpr(), 0, + startX = CLIP((int) _vm->_game->_script->readValExpr(), 0, _vm->_video->_surfWidth - _vm->_width); - startY = CLIP((int) _vm->_parse->parseValExpr(), 0, + startY = CLIP((int) _vm->_game->_script->readValExpr(), 0, _vm->_video->_surfHeight - _vm->_height); - endX = CLIP((int) _vm->_parse->parseValExpr(), 0, + endX = CLIP((int) _vm->_game->_script->readValExpr(), 0, _vm->_video->_surfWidth - _vm->_width); - endY = CLIP((int) _vm->_parse->parseValExpr(), 0, + endY = CLIP((int) _vm->_game->_script->readValExpr(), 0, _vm->_video->_surfHeight - _vm->_height); - stepX = _vm->_parse->parseValExpr(); - stepY = _vm->_parse->parseValExpr(); + stepX = _vm->_game->_script->readValExpr(); + stepY = _vm->_game->_script->readValExpr(); curX = startX; curY = startY; @@ -1470,8 +923,8 @@ void Inter_v2::o2_scroll() { void Inter_v2::o2_setScrollOffset() { int16 offsetX, offsetY; - offsetX = _vm->_parse->parseValExpr(); - offsetY = _vm->_parse->parseValExpr(); + offsetX = _vm->_game->_script->readValExpr(); + offsetY = _vm->_game->_script->readValExpr(); if (offsetX == -1) { WRITE_VAR(2, _vm->_draw->_scrollOffsetX); @@ -1506,22 +959,22 @@ void Inter_v2::o2_playImd() { uint16 palCmd; bool close; - evalExpr(0); - _vm->_global->_inter_resStr[8] = 0; - strncpy0(imd, _vm->_global->_inter_resStr, 127); - - x = _vm->_parse->parseValExpr(); - y = _vm->_parse->parseValExpr(); - startFrame = _vm->_parse->parseValExpr(); - lastFrame = _vm->_parse->parseValExpr(); - breakKey = _vm->_parse->parseValExpr(); - flags = _vm->_parse->parseValExpr(); - palStart = _vm->_parse->parseValExpr(); - palEnd = _vm->_parse->parseValExpr(); + _vm->_game->_script->evalExpr(0); + _vm->_game->_script->getResultStr()[8] = 0; + strncpy0(imd, _vm->_game->_script->getResultStr(), 127); + + x = _vm->_game->_script->readValExpr(); + y = _vm->_game->_script->readValExpr(); + startFrame = _vm->_game->_script->readValExpr(); + lastFrame = _vm->_game->_script->readValExpr(); + breakKey = _vm->_game->_script->readValExpr(); + flags = _vm->_game->_script->readValExpr(); + palStart = _vm->_game->_script->readValExpr(); + palEnd = _vm->_game->_script->readValExpr(); palCmd = 1 << (flags & 0x3F); debugC(1, kDebugVideo, "Playing video \"%s\" @ %d+%d, frames %d - %d, " - "paletteCmd %d (%d - %d), flags %X", _vm->_global->_inter_resStr, x, y, + "paletteCmd %d (%d - %d), flags %X", _vm->_game->_script->getResultStr(), x, y, startFrame, lastFrame, palCmd, palStart, palEnd, flags); if ((imd[0] != 0) && !_vm->_vidPlayer->primaryOpen(imd, x, y, flags)) { @@ -1550,28 +1003,28 @@ void Inter_v2::o2_getImdInfo() { int16 varFrames; int16 varWidth, varHeight; - evalExpr(0); - varX = _vm->_parse->parseVarIndex(); - varY = _vm->_parse->parseVarIndex(); - varFrames = _vm->_parse->parseVarIndex(); - varWidth = _vm->_parse->parseVarIndex(); - varHeight = _vm->_parse->parseVarIndex(); + _vm->_game->_script->evalExpr(0); + varX = _vm->_game->_script->readVarIndex(); + varY = _vm->_game->_script->readVarIndex(); + varFrames = _vm->_game->_script->readVarIndex(); + varWidth = _vm->_game->_script->readVarIndex(); + varHeight = _vm->_game->_script->readVarIndex(); // WORKAROUND: The nut rolling animation in the administration center // in Woodruff is called "noixroul", but the scripts think it's "noixroule". if ((_vm->getGameType() == kGameTypeWoodruff) && - (!scumm_stricmp(_vm->_global->_inter_resStr, "noixroule"))) - strcpy(_vm->_global->_inter_resStr, "noixroul"); + (!scumm_stricmp(_vm->_game->_script->getResultStr(), "noixroule"))) + strcpy(_vm->_game->_script->getResultStr(), "noixroul"); - _vm->_vidPlayer->writeVideoInfo(_vm->_global->_inter_resStr, varX, varY, + _vm->_vidPlayer->writeVideoInfo(_vm->_game->_script->getResultStr(), varX, varY, varFrames, varWidth, varHeight); } void Inter_v2::o2_openItk() { char fileName[32]; - evalExpr(0); - strncpy0(fileName, _vm->_global->_inter_resStr, 27); + _vm->_game->_script->evalExpr(0); + strncpy0(fileName, _vm->_game->_script->getResultStr(), 27); if (!strchr(fileName, '.')) strcat(fileName, ".ITK"); @@ -1588,50 +1041,47 @@ void Inter_v2::o2_setImdFrontSurf() { void Inter_v2::o2_resetImdFrontSurf() { } -bool Inter_v2::o2_evaluateStore(OpFuncParams ¶ms) { - byte *savedPos; - int16 varOff; - int16 token; - int16 result; - byte loopCount; - - savedPos = _vm->_global->_inter_execPtr; - varOff = _vm->_parse->parseVarIndex(); +bool Inter_v2::o2_assign(OpFuncParams ¶ms) { + byte destType = _vm->_game->_script->peekByte(); + int16 dest = _vm->_game->_script->readVarIndex(); - if (*_vm->_global->_inter_execPtr == 99) { - _vm->_global->_inter_execPtr++; - loopCount = *_vm->_global->_inter_execPtr++; + byte loopCount; + if (_vm->_game->_script->peekByte() == 99) { + _vm->_game->_script->skip(1); + loopCount = _vm->_game->_script->readByte(); } else loopCount = 1; for (int i = 0; i < loopCount; i++) { - token = evalExpr(&result); - switch (savedPos[0]) { - case 16: - case 18: - WRITE_VARO_UINT8(varOff + i, _vm->_global->_inter_resVal); + int16 result; + int16 srcType = _vm->_game->_script->evalExpr(&result); + + switch (destType) { + case TYPE_VAR_INT8: + case TYPE_ARRAY_INT8: + WRITE_VARO_UINT8(dest + i, _vm->_game->_script->getResultInt()); break; - case 17: - case 27: - WRITE_VARO_UINT16(varOff + i * 2, _vm->_global->_inter_resVal); + case TYPE_VAR_INT16: + case TYPE_ARRAY_INT16: + WRITE_VARO_UINT16(dest + i * 2, _vm->_game->_script->getResultInt()); break; - case 23: - case 26: - WRITE_VAR_OFFSET(varOff + i * 4, _vm->_global->_inter_resVal); + case TYPE_VAR_INT32: + case TYPE_ARRAY_INT32: + WRITE_VAR_OFFSET(dest + i * 4, _vm->_game->_script->getResultInt()); break; - case 24: - WRITE_VARO_UINT16(varOff + i * 4, _vm->_global->_inter_resVal); + case TYPE_VAR_INT32_AS_INT16: + WRITE_VARO_UINT16(dest + i * 4, _vm->_game->_script->getResultInt()); break; - case 25: - case 28: - if (token == 20) - WRITE_VARO_UINT8(varOff, result); + case TYPE_VAR_STR: + case TYPE_ARRAY_STR: + if (srcType == TYPE_IMM_INT16) + WRITE_VARO_UINT8(dest, result); else - WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); + WRITE_VARO_STR(dest, _vm->_game->_script->getResultStr()); break; } } @@ -1643,12 +1093,12 @@ bool Inter_v2::o2_printText(OpFuncParams ¶ms) { char buf[60]; int i; - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); - _vm->_draw->_backColor = _vm->_parse->parseValExpr(); - _vm->_draw->_frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->_fontIndex = _vm->_parse->parseValExpr(); + _vm->_draw->_backColor = _vm->_game->_script->readValExpr(); + _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); + _vm->_draw->_fontIndex = _vm->_game->_script->readValExpr(); _vm->_draw->_destSurface = 21; _vm->_draw->_textToPrint = buf; _vm->_draw->_transparency = 0; @@ -1659,48 +1109,47 @@ bool Inter_v2::o2_printText(OpFuncParams ¶ms) { } do { - for (i = 0; (((char) *_vm->_global->_inter_execPtr) != '.') && - (*_vm->_global->_inter_execPtr != 200); - i++, _vm->_global->_inter_execPtr++) { - buf[i] = (char) *_vm->_global->_inter_execPtr; + for (i = 0; (_vm->_game->_script->peekChar() != '.') && + (_vm->_game->_script->peekByte() != 200); i++) { + buf[i] = _vm->_game->_script->readChar(); } - if (*_vm->_global->_inter_execPtr != 200) { - _vm->_global->_inter_execPtr++; - switch (*_vm->_global->_inter_execPtr) { - case 16: - case 18: + if (_vm->_game->_script->peekByte() != 200) { + _vm->_game->_script->skip(1); + switch (_vm->_game->_script->peekByte()) { + case TYPE_VAR_INT8: + case TYPE_ARRAY_INT8: sprintf(buf + i, "%d", - (int8) READ_VARO_UINT8(_vm->_parse->parseVarIndex())); + (int8) READ_VARO_UINT8(_vm->_game->_script->readVarIndex())); break; - case 17: - case 24: - case 27: + case TYPE_VAR_INT16: + case TYPE_VAR_INT32_AS_INT16: + case TYPE_ARRAY_INT16: sprintf(buf + i, "%d", - (int16) READ_VARO_UINT16(_vm->_parse->parseVarIndex())); + (int16) READ_VARO_UINT16(_vm->_game->_script->readVarIndex())); break; - case 23: - case 26: + case TYPE_VAR_INT32: + case TYPE_ARRAY_INT32: sprintf(buf + i, "%d", - VAR_OFFSET(_vm->_parse->parseVarIndex())); + VAR_OFFSET(_vm->_game->_script->readVarIndex())); break; - case 25: - case 28: + case TYPE_VAR_STR: + case TYPE_ARRAY_STR: sprintf(buf + i, "%s", - GET_VARO_STR(_vm->_parse->parseVarIndex())); + GET_VARO_STR(_vm->_game->_script->readVarIndex())); break; } - _vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(1); } else buf[i] = 0; _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - } while (*_vm->_global->_inter_execPtr != 200); + } while (_vm->_game->_script->peekByte() != 200); - _vm->_global->_inter_execPtr++; + _vm->_game->_script->skip(1); return false; } @@ -1708,20 +1157,20 @@ bool Inter_v2::o2_printText(OpFuncParams ¶ms) { bool Inter_v2::o2_animPalInit(OpFuncParams ¶ms) { int16 index; - index = load16(); + index = _vm->_game->_script->readInt16(); if (index > 0) { index--; - _animPalLowIndex[index] = _vm->_parse->parseValExpr(); - _animPalHighIndex[index] = _vm->_parse->parseValExpr(); + _animPalLowIndex[index] = _vm->_game->_script->readValExpr(); + _animPalHighIndex[index] = _vm->_game->_script->readValExpr(); _animPalDir[index] = 1; } else if (index == 0) { memset(_animPalDir, 0, 8 * sizeof(int16)); - _vm->_parse->parseValExpr(); - _vm->_parse->parseValExpr(); + _vm->_game->_script->readValExpr(); + _vm->_game->_script->readValExpr(); } else { index = -index - 1; - _animPalLowIndex[index] = _vm->_parse->parseValExpr(); - _animPalHighIndex[index] = _vm->_parse->parseValExpr(); + _animPalLowIndex[index] = _vm->_game->_script->readValExpr(); + _animPalHighIndex[index] = _vm->_game->_script->readValExpr(); _animPalDir[index] = -1; } return false; @@ -1734,14 +1183,14 @@ bool Inter_v2::o2_addCollision(OpFuncParams ¶ms) { int16 key; int16 funcSub; - id = _vm->_parse->parseValExpr(); - funcSub = _vm->_global->_inter_execPtr - _vm->_game->_totFileData; - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); - flags = _vm->_parse->parseValExpr(); - key = load16(); + 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(); if (key == 0) key = ABS(id) + 41960; @@ -1775,7 +1224,7 @@ bool Inter_v2::o2_addCollision(OpFuncParams ¶ms) { bool Inter_v2::o2_freeCollision(OpFuncParams ¶ms) { int16 id; - id = _vm->_parse->parseValExpr(); + id = _vm->_game->_script->readValExpr(); if (id == -2) { for (int i = 0; i < 150; i++) { if ((_vm->_game->_collisionAreas[i].id & 0xF000) == 0xD000) @@ -1797,9 +1246,9 @@ bool Inter_v2::o2_goblinFunc(OpFuncParams ¶ms) { // It's not yet implemented, so we fudge our way through // and pretend we've won. if (_vm->getGameType() == kGameTypeInca2) { - _vm->_global->_inter_execPtr += 4; - uint16 resVar = (uint16) load16(); - _vm->_global->_inter_execPtr += 4; + _vm->_game->_script->skip(4); + uint16 resVar = _vm->_game->_script->readUint16(); + _vm->_game->_script->skip(4); WRITE_VAR(resVar, 1); return false; @@ -1808,18 +1257,20 @@ bool Inter_v2::o2_goblinFunc(OpFuncParams ¶ms) { OpGobParams gobParams; int16 cmd; - cmd = load16(); - _vm->_global->_inter_execPtr += 2; + cmd = _vm->_game->_script->readInt16(); + + gobParams.paramCount = _vm->_game->_script->readInt16(); + gobParams.extraData = cmd; if (cmd != 101) - executeGoblinOpcode(cmd, gobParams); + executeOpcodeGob(cmd, gobParams); return false; } bool Inter_v2::o2_stopSound(OpFuncParams ¶ms) { int16 expr; - expr = _vm->_parse->parseValExpr(); + expr = _vm->_game->_script->readValExpr(); if (expr < 0) { _vm->_sound->adlibStop(); @@ -1839,13 +1290,13 @@ bool Inter_v2::o2_getFreeMem(OpFuncParams ¶ms) { int16 freeVar; int16 maxFreeVar; - freeVar = _vm->_parse->parseVarIndex(); - maxFreeVar = _vm->_parse->parseVarIndex(); + freeVar = _vm->_game->_script->readVarIndex(); + maxFreeVar = _vm->_game->_script->readVarIndex(); // HACK WRITE_VAR_OFFSET(freeVar, 1000000); WRITE_VAR_OFFSET(maxFreeVar, 1000000); - WRITE_VAR(16, READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4); + WRITE_VAR(16, _vm->_game->_script->getVariablesCount() * 4); return false; } @@ -1855,23 +1306,22 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { int32 size; SaveLoad::SaveMode mode; - evalExpr(0); - varOff = _vm->_parse->parseVarIndex(); + _vm->_game->_script->evalExpr(0); + varOff = _vm->_game->_script->readVarIndex(); size = -1; handle = 1; - mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr); + mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr()); if (mode == SaveLoad::kSaveModeNone) { - handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); - if (handle >= 0) { - _vm->_dataIO->closeData(handle); - size = _vm->_dataIO->getDataSize(_vm->_global->_inter_resStr); - } else - warning("File \"%s\" not found", _vm->_global->_inter_resStr); + if (_vm->_dataIO->existData(_vm->_game->_script->getResultStr())) + size = _vm->_dataIO->getDataSize(_vm->_game->_script->getResultStr()); + else + warning("File \"%s\" not found", _vm->_game->_script->getResultStr()); + } else if (mode == SaveLoad::kSaveModeSave) - size = _vm->_saveLoad->getSize(_vm->_global->_inter_resStr); + size = _vm->_saveLoad->getSize(_vm->_game->_script->getResultStr()); else if (mode == SaveLoad::kSaveModeExists) size = 23; @@ -1879,7 +1329,7 @@ bool Inter_v2::o2_checkData(OpFuncParams ¶ms) { handle = -1; debugC(2, kDebugFileIO, "Requested size of file \"%s\": %d", - _vm->_global->_inter_resStr, size); + _vm->_game->_script->getResultStr(), size); WRITE_VAR_OFFSET(varOff, handle); WRITE_VAR(16, (uint32) size); @@ -1896,20 +1346,20 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) { byte *buf; SaveLoad::SaveMode mode; - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - evalExpr(0); - offset = _vm->_global->_inter_resVal; + _vm->_game->_script->evalExpr(0); + dataVar = _vm->_game->_script->readVarIndex(); + size = _vm->_game->_script->readValExpr(); + _vm->_game->_script->evalExpr(0); + offset = _vm->_game->_script->getResultInt(); retSize = 0; debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)", - _vm->_global->_inter_resStr, dataVar, size, offset); + _vm->_game->_script->getResultStr(), dataVar, size, offset); - mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr); + mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr()); if (mode == SaveLoad::kSaveModeSave) { WRITE_VAR(1, 1); - if (_vm->_saveLoad->load(_vm->_global->_inter_resStr, dataVar, size, offset)) + if (_vm->_saveLoad->load(_vm->_game->_script->getResultStr(), dataVar, size, offset)) WRITE_VAR(1, 0); return false; } else if (mode == SaveLoad::kSaveModeIgnore) @@ -1917,22 +1367,22 @@ bool Inter_v2::o2_readData(OpFuncParams ¶ms) { if (size < 0) { warning("Attempted to read a raw sprite from file \"%s\"", - _vm->_global->_inter_resStr); + _vm->_game->_script->getResultStr()); return false ; } else if (size == 0) { dataVar = 0; - size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4; + size = _vm->_game->_script->getVariablesCount() * 4; } buf = _variables->getAddressOff8(dataVar); - if (_vm->_global->_inter_resStr[0] == 0) { + if (_vm->_game->_script->getResultStr()[0] == 0) { WRITE_VAR(1, size); return false; } WRITE_VAR(1, 1); - handle = _vm->_dataIO->openData(_vm->_global->_inter_resStr); + handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr()); if (handle < 0) return false; @@ -1967,23 +1417,23 @@ bool Inter_v2::o2_writeData(OpFuncParams ¶ms) { int16 dataVar; SaveLoad::SaveMode mode; - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - evalExpr(0); - offset = _vm->_global->_inter_resVal; + _vm->_game->_script->evalExpr(0); + dataVar = _vm->_game->_script->readVarIndex(); + size = _vm->_game->_script->readValExpr(); + _vm->_game->_script->evalExpr(0); + offset = _vm->_game->_script->getResultInt(); debugC(2, kDebugFileIO, "Write to file \"%s\" (%d, %d bytes at %d)", - _vm->_global->_inter_resStr, dataVar, size, offset); + _vm->_game->_script->getResultStr(), dataVar, size, offset); WRITE_VAR(1, 1); - mode = _vm->_saveLoad->getSaveMode(_vm->_global->_inter_resStr); + mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr()); if (mode == SaveLoad::kSaveModeSave) { - if (_vm->_saveLoad->save(_vm->_global->_inter_resStr, dataVar, size, offset)) + if (_vm->_saveLoad->save(_vm->_game->_script->getResultStr(), dataVar, size, offset)) WRITE_VAR(1, 0); } else if (mode == SaveLoad::kSaveModeNone) - warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr); + warning("Attempted to write to file \"%s\"", _vm->_game->_script->getResultStr()); return false; } @@ -1992,7 +1442,7 @@ void Inter_v2::o2_loadInfogramesIns(OpGobParams ¶ms) { int16 varName; char fileName[20]; - varName = load16(); + varName = _vm->_game->_script->readInt16(); strncpy0(fileName, GET_VAR_STR(varName), 15); strcat(fileName, ".INS"); @@ -2004,7 +1454,7 @@ void Inter_v2::o2_playInfogrames(OpGobParams ¶ms) { int16 varName; char fileName[20]; - varName = load16(); + varName = _vm->_game->_script->readInt16(); strncpy0(fileName, GET_VAR_STR(varName), 15); strcat(fileName, ".DUM"); @@ -2014,13 +1464,13 @@ void Inter_v2::o2_playInfogrames(OpGobParams ¶ms) { } void Inter_v2::o2_startInfogrames(OpGobParams ¶ms) { - load16(); + _vm->_game->_script->readInt16(); _vm->_sound->infogramesPlay(); } void Inter_v2::o2_stopInfogrames(OpGobParams ¶ms) { - load16(); + _vm->_game->_script->readInt16(); _vm->_sound->infogramesStop(); } @@ -2034,12 +1484,12 @@ void Inter_v2::o2_stopProtracker(OpGobParams ¶ms) { } void Inter_v2::o2_handleGoblins(OpGobParams ¶ms) { - _vm->_goblin->_gob1NoTurn = VAR(load16()) != 0; - _vm->_goblin->_gob2NoTurn = VAR(load16()) != 0; - _vm->_goblin->_gob1RelaxTimeVar = load16(); - _vm->_goblin->_gob2RelaxTimeVar = load16(); - _vm->_goblin->_gob1Busy = VAR(load16()) != 0; - _vm->_goblin->_gob2Busy = VAR(load16()) != 0; + _vm->_goblin->_gob1NoTurn = VAR(_vm->_game->_script->readInt16()) != 0; + _vm->_goblin->_gob2NoTurn = VAR(_vm->_game->_script->readInt16()) != 0; + _vm->_goblin->_gob1RelaxTimeVar = _vm->_game->_script->readInt16(); + _vm->_goblin->_gob2RelaxTimeVar = _vm->_game->_script->readInt16(); + _vm->_goblin->_gob1Busy = VAR(_vm->_game->_script->readInt16()) != 0; + _vm->_goblin->_gob2Busy = VAR(_vm->_game->_script->readInt16()) != 0; _vm->_goblin->handleGoblins(); } @@ -2050,21 +1500,20 @@ int16 Inter_v2::loadSound(int16 search) { uint16 slotIdMask; uint32 dataSize; SoundType type; - SoundSource source; type = SOUND_SND; slotIdMask = 0; dataSize = 0; if (!search) { - slot = _vm->_parse->parseValExpr(); + slot = _vm->_game->_script->readValExpr(); if (slot < 0) { type = SOUND_ADL; slot = -slot; } - id = load16(); + id = _vm->_game->_script->readInt16(); } else { - id = load16(); + id = _vm->_game->_script->readInt16(); for (slot = 0; slot < Sound::kSoundsCount; slot++) if (_vm->_sound->sampleGetBySlot(slot)->isId(id)) { @@ -2093,37 +1542,37 @@ int16 Inter_v2::loadSound(int16 search) { if (id == -1) { char sndfile[14]; - source = SOUND_FILE; - - strncpy0(sndfile, (const char *) _vm->_global->_inter_execPtr, 9); - _vm->_global->_inter_execPtr += 9; + strncpy0(sndfile, _vm->_game->_script->readString(9), 9); if (type == SOUND_ADL) strcat(sndfile, ".ADL"); else strcat(sndfile, ".SND"); - dataPtr = (byte *) _vm->_dataIO->getData(sndfile); - if (dataPtr) - dataSize = _vm->_dataIO->getDataSize(sndfile); - } else if (id >= 30000) { - source = SOUND_EXT; - - dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); - } else { - int16 totSize; + dataPtr = _vm->_dataIO->getData(sndfile); + dataSize = _vm->_dataIO->getDataSize(sndfile); + if (!dataPtr) + return 0; - source = SOUND_TOT; + if (!sample->load(type, dataPtr, dataSize)) { + delete[] dataPtr; + return 0; + } - dataPtr = (byte *) _vm->_game->loadTotResource(id, &totSize); - dataSize = (uint32) ((int32) totSize); + sample->_id = id; + return slot | slotIdMask; } - if (dataPtr) { - sample->load(type, source, dataPtr, dataSize); - sample->_id = id; + Resource *resource = _vm->_game->_resources->getResource(id); + if (!resource) + return 0; + + if (!sample->load(type, resource)) { + delete resource; + return 0; } + sample->_id = id; return slot | slotIdMask; } diff --git a/engines/gob/inter_v3.cpp b/engines/gob/inter_v3.cpp index 000639e784..17ce7feafa 100644 --- a/engines/gob/inter_v3.cpp +++ b/engines/gob/inter_v3.cpp @@ -32,683 +32,38 @@ #include "gob/dataio.h" #include "gob/draw.h" #include "gob/game.h" -#include "gob/parse.h" +#include "gob/script.h" +#include "gob/resources.h" namespace Gob { -#define OPCODE(x) _OPCODE(Inter_v3, x) - -const int Inter_v3::_goblinFuncLookUp[][2] = { - {0, 0}, - {1, 1}, - {2, 2}, - {4, 3}, - {5, 4}, - {6, 5}, - {7, 6}, - {8, 7}, - {9, 8}, - {10, 9}, - {12, 10}, - {13, 11}, - {14, 12}, - {15, 13}, - {16, 14}, - {21, 15}, - {22, 16}, - {23, 17}, - {24, 18}, - {25, 19}, - {26, 20}, - {27, 21}, - {28, 22}, - {29, 23}, - {30, 24}, - {32, 25}, - {33, 26}, - {34, 27}, - {35, 28}, - {36, 29}, - {37, 30}, - {40, 31}, - {41, 32}, - {42, 33}, - {43, 34}, - {44, 35}, - {50, 36}, - {52, 37}, - {53, 38}, - {100, 39}, - {152, 40}, - {200, 41}, - {201, 42}, - {202, 43}, - {203, 44}, - {204, 45}, - {250, 46}, - {251, 47}, - {252, 48}, - {500, 49}, - {502, 50}, - {503, 51}, - {600, 52}, - {601, 53}, - {602, 54}, - {603, 55}, - {604, 56}, - {605, 57}, - {1000, 58}, - {1001, 59}, - {1002, 60}, - {1003, 61}, - {1004, 62}, - {1005, 63}, - {1006, 64}, - {1008, 65}, - {1009, 66}, - {1010, 67}, - {1011, 68}, - {1015, 69}, - {2005, 70} -}; +#define OPCODEVER Inter_v3 +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_v3::Inter_v3(GobEngine *vm) : Inter_v2(vm) { - setupOpcodes(); } -void Inter_v3::setupOpcodes() { - static const OpcodeDrawEntryV3 opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o2_playMult), - OPCODE(o2_freeMultKeys), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(o2_setRenderFlags), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - OPCODE(o2_multSub), - /* 14 */ - OPCODE(o2_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o2_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o2_renderStatic), - OPCODE(o2_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o2_playCDTrack), - OPCODE(o2_waitCDTrackEnd), - OPCODE(o2_stopCD), - OPCODE(o2_readLIC), - /* 24 */ - OPCODE(o2_freeLIC), - OPCODE(o2_getCDTrackPos), - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o2_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - OPCODE(o2_totSub), - OPCODE(o2_switchTotSub), - OPCODE(o2_pushVars), - OPCODE(o2_popVars), - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - OPCODE(o2_loadMapObjects), - OPCODE(o2_freeGoblins), - OPCODE(o2_moveGoblin), - OPCODE(o2_writeGoblinPos), - /* 54 */ - OPCODE(o2_stopGoblin), - OPCODE(o2_setGoblinState), - OPCODE(o2_placeGoblin), - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - OPCODE(o2_initScreen), - OPCODE(o2_scroll), - OPCODE(o2_setScrollOffset), - OPCODE(o2_playImd), - /* 84 */ - OPCODE(o2_getImdInfo), - OPCODE(o2_openItk), - OPCODE(o2_closeItk), - OPCODE(o2_setImdFrontSurf), - /* 88 */ - OPCODE(o2_resetImdFrontSurf), - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryV3 opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o1_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o2_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o2_printText), - OPCODE(o1_loadTot), - OPCODE(o1_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o2_animPalInit), - /* 18 */ - OPCODE(o2_addCollision), - OPCODE(o2_freeCollision), - OPCODE(o3_getTotTextItemPart), - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o2_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o3_copySprite), - OPCODE(o1_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o2_stopSound), - OPCODE(o2_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o2_getFreeMem), - OPCODE(o2_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o1_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o2_readData), - OPCODE(o2_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryV3 opcodesGoblin[71] = { - /* 00 */ - OPCODE(o2_loadInfogramesIns), - OPCODE(o2_startInfogrames), - OPCODE(o2_stopInfogrames), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 08 */ - {0, ""}, - OPCODE(o2_playInfogrames), - {0, ""}, - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 14 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 20 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 24 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o3_wobble), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - }; - - _opcodesDrawV3 = opcodesDraw; - _opcodesFuncV3 = opcodesFunc; - _opcodesGoblinV3 = opcodesGoblin; +void Inter_v3::setupOpcodesDraw() { + Inter_v2::setupOpcodesDraw(); } -void Inter_v3::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); +void Inter_v3::setupOpcodesFunc() { + Inter_v2::setupOpcodesFunc(); - OpcodeDrawProcV3 op = _opcodesDrawV3[i].proc; - - if (op == 0) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); -} - -bool Inter_v3::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", - i, j, i, j, getOpcodeFuncDesc(i, j)); - - if ((i > 4) || (j > 15)) { - warning("unimplemented opcodeFunc: %d.%d", i, j); - return false; - } - - OpcodeFuncProcV3 op = _opcodesFuncV3[i*16 + j].proc; - - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); - - return false; -} - -void Inter_v3::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); - - OpcodeGoblinProcV3 op = 0; - - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinV3[_goblinFuncLookUp[j][1]].proc; - break; - } - - if (op == 0) { - int16 val; - - _vm->_global->_inter_execPtr -= 2; - val = load16(); - _vm->_global->_inter_execPtr += val << 1; - } else - (this->*op) (params); + OPCODEFUNC(0x1A, o3_getTotTextItemPart); + OPCODEFUNC(0x32, o3_copySprite); } -const char *Inter_v3::getOpcodeDrawDesc(byte i) { - return _opcodesDrawV3[i].desc; -} +void Inter_v3::setupOpcodesGob() { + OPCODEGOB( 0, o2_loadInfogramesIns); + OPCODEGOB( 1, o2_startInfogrames); + OPCODEGOB( 2, o2_stopInfogrames); -const char *Inter_v3::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; + OPCODEGOB( 10, o2_playInfogrames); - return _opcodesFuncV3[i*16 + j].desc; -} - -const char *Inter_v3::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinV3[_goblinFuncLookUp[j][1]].desc; - return ""; + OPCODEGOB(100, o3_wobble); } bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { @@ -720,18 +75,18 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { uint32 stringStartVar, stringVar; bool end; - totTextItem = load16(); - stringStartVar = _vm->_parse->parseVarIndex(); - part = _vm->_parse->parseValExpr(); + totTextItem = _vm->_game->_script->readInt16(); + stringStartVar = _vm->_game->_script->readVarIndex(); + part = _vm->_game->_script->readValExpr(); stringVar = stringStartVar; WRITE_VARO_UINT8(stringVar, 0); - if (!_vm->_game->_totTextData) + TextItem *textItem = _vm->_game->_resources->getTextItem(totTextItem); + if (!textItem) return false; - totData = _vm->_game->_totTextData->dataPtr + - _vm->_game->_totTextData->items[totTextItem].offset; + totData = textItem->getData(); // Skip background rectangles while (((int16) READ_LE_UINT16(totData)) != -1) @@ -782,6 +137,7 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { if ((n != 0) || (*totData == 1) || (*totData == 6) || (*totData == 7)) { WRITE_VARO_UINT8(stringVar, 0); + delete textItem; return false; } @@ -813,8 +169,9 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { WRITE_VARO_UINT16(stringVar, offX); WRITE_VARO_UINT16(stringVar + 2, offY); WRITE_VARO_UINT16(stringVar + 4, - totData - _vm->_game->_totTextData->dataPtr); + totData - _vm->_game->_resources->getTexts()); WRITE_VARO_UINT8(stringVar + 6, 0); + delete textItem; return false; } @@ -860,8 +217,10 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { if (((*totData != 2) && (*totData != 5)) || (ABS(offY - READ_LE_UINT16(totData + 3)) > 1)) { - if (curPart == part) + if (curPart == part) { + delete textItem; return false; + } stringVar = stringStartVar; WRITE_VARO_UINT8(stringVar, 0); @@ -881,6 +240,7 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { } } + delete textItem; return false; } @@ -894,7 +254,7 @@ bool Inter_v3::o3_copySprite(OpFuncParams ¶ms) { } void Inter_v3::o3_wobble(OpGobParams ¶ms) { - _vm->_draw->wobble(_vm->_draw->_backSurface); + _vm->_draw->wobble(*_vm->_draw->_backSurface); } } // End of namespace Gob diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp index 19e813ce1d..48378a5987 100644 --- a/engines/gob/inter_v4.cpp +++ b/engines/gob/inter_v4.cpp @@ -32,689 +32,32 @@ #include "gob/global.h" #include "gob/draw.h" #include "gob/game.h" -#include "gob/parse.h" +#include "gob/script.h" #include "gob/videoplayer.h" #include "gob/sound/sound.h" namespace Gob { -#define OPCODE(x) _OPCODE(Inter_v4, x) - -const int Inter_v4::_goblinFuncLookUp[][2] = { - {0, 0}, - {1, 1}, - {2, 2}, - {4, 3}, - {5, 4}, - {6, 5}, - {7, 6}, - {8, 7}, - {9, 8}, - {10, 9}, - {12, 10}, - {13, 11}, - {14, 12}, - {15, 13}, - {16, 14}, - {21, 15}, - {22, 16}, - {23, 17}, - {24, 18}, - {25, 19}, - {26, 20}, - {27, 21}, - {28, 22}, - {29, 23}, - {30, 24}, - {32, 25}, - {33, 26}, - {34, 27}, - {35, 28}, - {36, 29}, - {37, 30}, - {40, 31}, - {41, 32}, - {42, 33}, - {43, 34}, - {44, 35}, - {50, 36}, - {52, 37}, - {53, 38}, - {100, 39}, - {152, 40}, - {200, 41}, - {201, 42}, - {202, 43}, - {203, 44}, - {204, 45}, - {250, 46}, - {251, 47}, - {252, 48}, - {500, 49}, - {502, 50}, - {503, 51}, - {600, 52}, - {601, 53}, - {602, 54}, - {603, 55}, - {604, 56}, - {605, 57}, - {1000, 58}, - {1001, 59}, - {1002, 60}, - {1003, 61}, - {1004, 62}, - {1005, 63}, - {1006, 64}, - {1008, 65}, - {1009, 66}, - {1010, 67}, - {1011, 68}, - {1015, 69}, - {2005, 70} -}; +#define OPCODEVER Inter_v4 +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_v4::Inter_v4(GobEngine *vm) : Inter_v3(vm) { - setupOpcodes(); } -void Inter_v4::setupOpcodes() { - static const OpcodeDrawEntryV4 opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o2_playMult), - OPCODE(o2_freeMultKeys), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(o2_setRenderFlags), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - OPCODE(o2_multSub), - /* 14 */ - OPCODE(o2_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o2_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o2_renderStatic), - OPCODE(o2_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o2_playCDTrack), - OPCODE(o2_waitCDTrackEnd), - OPCODE(o2_stopCD), - OPCODE(o2_readLIC), - /* 24 */ - OPCODE(o2_freeLIC), - OPCODE(o2_getCDTrackPos), - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o2_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - OPCODE(o2_totSub), - OPCODE(o2_switchTotSub), - OPCODE(o2_pushVars), - OPCODE(o2_popVars), - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - OPCODE(o2_loadMapObjects), - OPCODE(o2_freeGoblins), - OPCODE(o2_moveGoblin), - OPCODE(o2_writeGoblinPos), - /* 54 */ - OPCODE(o2_stopGoblin), - OPCODE(o2_setGoblinState), - OPCODE(o2_placeGoblin), - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - OPCODE(o4_initScreen), - OPCODE(o2_scroll), - OPCODE(o2_setScrollOffset), - OPCODE(o4_playVmdOrMusic), - /* 84 */ - OPCODE(o2_getImdInfo), - OPCODE(o2_openItk), - OPCODE(o2_closeItk), - OPCODE(o2_setImdFrontSurf), - /* 88 */ - OPCODE(o2_resetImdFrontSurf), - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryV4 opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o1_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o2_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o2_printText), - OPCODE(o1_loadTot), - OPCODE(o1_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o2_animPalInit), - /* 18 */ - OPCODE(o2_addCollision), - OPCODE(o2_freeCollision), - OPCODE(o3_getTotTextItemPart), - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o2_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o1_copySprite), - OPCODE(o1_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o2_stopSound), - OPCODE(o2_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o2_getFreeMem), - OPCODE(o2_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o1_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o2_readData), - OPCODE(o2_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryV4 opcodesGoblin[71] = { - /* 00 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 08 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 14 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 20 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 24 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - }; - - _opcodesDrawV4 = opcodesDraw; - _opcodesFuncV4 = opcodesFunc; - _opcodesGoblinV4 = opcodesGoblin; -} - -void Inter_v4::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); - - OpcodeDrawProcV4 op = _opcodesDrawV4[i].proc; - - if (op == 0) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); -} - -bool Inter_v4::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s) - %s, %d, %d", - i, j, i, j, getOpcodeFuncDesc(i, j), _vm->_game->_curTotFile, - (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData), - (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData - params.counter - 4)); - - if ((i > 4) || (j > 15)) { - warning("unimplemented opcodeFunc: %d.%d", i, j); - return false; - } - - OpcodeFuncProcV4 op = _opcodesFuncV4[i*16 + j].proc; - - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); +void Inter_v4::setupOpcodesDraw() { + Inter_v3::setupOpcodesDraw(); - return false; + OPCODEDRAW(0x80, o4_initScreen); + OPCODEDRAW(0x83, o4_playVmdOrMusic); } -void Inter_v4::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); - - OpcodeGoblinProcV4 op = 0; - - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinV4[_goblinFuncLookUp[j][1]].proc; - break; - } - - if (op == 0) { - warning("unimplemented opcodeGoblin: %d", i); - - int16 val; - - _vm->_global->_inter_execPtr -= 2; - val = load16(); - _vm->_global->_inter_execPtr += val << 1; - } else - (this->*op) (params); -} - -const char *Inter_v4::getOpcodeDrawDesc(byte i) { - return _opcodesDrawV4[i].desc; -} - -const char *Inter_v4::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; - - return _opcodesFuncV4[i*16 + j].desc; +void Inter_v4::setupOpcodesFunc() { + Inter_v3::setupOpcodesFunc(); } -const char *Inter_v4::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinV4[_goblinFuncLookUp[j][1]].desc; - return ""; +void Inter_v4::setupOpcodesGob() { } void Inter_v4::o4_initScreen() { @@ -722,13 +65,13 @@ void Inter_v4::o4_initScreen() { int16 videoMode; int16 width, height; - offY = load16(); + offY = _vm->_game->_script->readInt16(); videoMode = offY & 0xFF; offY = (offY >> 8) & 0xFF; - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + width = _vm->_game->_script->readValExpr(); + height = _vm->_game->_script->readValExpr(); _vm->_video->clearScreen(); @@ -772,9 +115,9 @@ void Inter_v4::o4_initScreen() { memset(_vm->_global->_greenPalette, 0, 256); memset(_vm->_global->_bluePalette, 0, 256); - _vm->_video->_splitSurf = 0; - _vm->_draw->_spritesArray[24] = 0; - _vm->_draw->_spritesArray[25] = 0; + _vm->_video->_splitSurf.reset(); + _vm->_draw->_spritesArray[24].reset(); + _vm->_draw->_spritesArray[25].reset(); _vm->_global->_videoMode = videoMode; _vm->_video->initPrimary(videoMode); @@ -791,8 +134,8 @@ void Inter_v4::o4_initScreen() { _vm->_util->setScrollOffset(); if (offY > 0) { - _vm->_draw->_spritesArray[24] = new SurfaceDesc(videoMode, _vm->_width, offY); - _vm->_draw->_spritesArray[25] = new SurfaceDesc(videoMode, _vm->_width, offY); + _vm->_draw->_spritesArray[24] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); + _vm->_draw->_spritesArray[25] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); _vm->_video->_splitSurf = _vm->_draw->_spritesArray[25]; } } @@ -809,8 +152,8 @@ void Inter_v4::o4_playVmdOrMusic() { uint16 palCmd; bool close; - evalExpr(0); - strncpy0(fileName, _vm->_global->_inter_resStr, 127); + _vm->_game->_script->evalExpr(0); + strncpy0(fileName, _vm->_game->_script->getResultStr(), 127); // WORKAROUND: The nut rolling animation in the administration center // in Woodruff is called "noixroul", but the scripts think it's "noixroule". @@ -818,14 +161,14 @@ void Inter_v4::o4_playVmdOrMusic() { (!scumm_stricmp(fileName, "noixroule"))) strcpy(fileName, "noixroul"); - x = _vm->_parse->parseValExpr(); - y = _vm->_parse->parseValExpr(); - startFrame = _vm->_parse->parseValExpr(); - lastFrame = _vm->_parse->parseValExpr(); - breakKey = _vm->_parse->parseValExpr(); - flags = _vm->_parse->parseValExpr(); - palStart = _vm->_parse->parseValExpr(); - palEnd = _vm->_parse->parseValExpr(); + x = _vm->_game->_script->readValExpr(); + y = _vm->_game->_script->readValExpr(); + startFrame = _vm->_game->_script->readValExpr(); + lastFrame = _vm->_game->_script->readValExpr(); + breakKey = _vm->_game->_script->readValExpr(); + flags = _vm->_game->_script->readValExpr(); + palStart = _vm->_game->_script->readValExpr(); + palEnd = _vm->_game->_script->readValExpr(); palCmd = 1 << (flags & 0x3F); debugC(1, kDebugVideo, "Playing video \"%s\" @ %d+%d, frames %d - %d, " diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp index 488c2052eb..1c20851c8d 100644 --- a/engines/gob/inter_v5.cpp +++ b/engines/gob/inter_v5.cpp @@ -30,652 +30,73 @@ #include "gob/inter.h" #include "gob/global.h" #include "gob/game.h" -#include "gob/parse.h" +#include "gob/script.h" #include "gob/draw.h" namespace Gob { -#define OPCODE(x) _OPCODE(Inter_v5, x) - -const int Inter_v5::_goblinFuncLookUp[][2] = { - {0, 0}, - {1, 0}, - {3, 0}, - {2, 0}, - {33, 0}, - {80, 1}, - {81, 2}, - {82, 3}, - {83, 4}, - {84, 5}, - {85, 6}, - {86, 7}, - {87, 0}, - {88, 0}, - {89, 0}, - {90, 0}, - {91, 0}, - {92, 8}, - {93, 0}, - {94, 0}, - {95, 9}, - {96, 10}, - {97, 11}, - {98, 12}, - {99, 0}, - {100, 13}, - {200, 14} -}; +#define OPCODEVER Inter_v5 +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_v5::Inter_v5(GobEngine *vm) : Inter_v4(vm) { - setupOpcodes(); } -void Inter_v5::setupOpcodes() { - static const OpcodeDrawEntryV5 opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o2_playMult), - OPCODE(o2_freeMultKeys), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(o2_setRenderFlags), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - OPCODE(o2_multSub), - /* 14 */ - OPCODE(o2_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o2_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o2_renderStatic), - OPCODE(o2_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o2_playCDTrack), - OPCODE(o2_waitCDTrackEnd), - OPCODE(o2_stopCD), - OPCODE(o2_readLIC), - /* 24 */ - OPCODE(o2_freeLIC), - OPCODE(o2_getCDTrackPos), - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o2_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - OPCODE(o2_totSub), - OPCODE(o2_switchTotSub), - OPCODE(o2_pushVars), - OPCODE(o2_popVars), - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - OPCODE(o2_loadMapObjects), - OPCODE(o2_freeGoblins), - OPCODE(o2_moveGoblin), - OPCODE(o2_writeGoblinPos), - /* 54 */ - OPCODE(o2_stopGoblin), - OPCODE(o2_setGoblinState), - OPCODE(o2_placeGoblin), - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - OPCODE(o5_deleteFile), - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - OPCODE(o5_initScreen), - OPCODE(o2_scroll), - OPCODE(o2_setScrollOffset), - OPCODE(o4_playVmdOrMusic), - /* 84 */ - OPCODE(o2_getImdInfo), - OPCODE(o2_openItk), - OPCODE(o2_closeItk), - OPCODE(o2_setImdFrontSurf), - /* 88 */ - OPCODE(o2_resetImdFrontSurf), - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryV5 opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o1_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o2_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o2_printText), - OPCODE(o1_loadTot), - OPCODE(o1_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o2_animPalInit), - /* 18 */ - OPCODE(o2_addCollision), - OPCODE(o2_freeCollision), - OPCODE(o3_getTotTextItemPart), - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o2_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o1_copySprite), - OPCODE(o1_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o2_stopSound), - OPCODE(o2_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o2_getFreeMem), - OPCODE(o2_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o5_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o2_readData), - OPCODE(o2_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryV5 opcodesGoblin[71] = { - /* 00 */ - OPCODE(o5_spaceShooter), - OPCODE(o5_getSystemCDSpeed), - OPCODE(o5_getSystemRAM), - OPCODE(o5_getSystemCPUSpeed), - /* 04 */ - OPCODE(o5_getSystemDrawSpeed), - OPCODE(o5_totalSystemSpecs), - OPCODE(o5_saveSystemSpecs), - OPCODE(o5_loadSystemSpecs), - /* 08 */ - OPCODE(o5_gob92), - OPCODE(o5_gob95), - OPCODE(o5_gob96), - OPCODE(o5_gob97), - /* 0C */ - OPCODE(o5_gob98), - OPCODE(o5_gob100), - OPCODE(o5_gob200), - {0, ""}, - /* 10 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 14 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 20 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 24 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - }; - - _opcodesDrawV5 = opcodesDraw; - _opcodesFuncV5 = opcodesFunc; - _opcodesGoblinV5 = opcodesGoblin; -} - -void Inter_v5::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); - - OpcodeDrawProcV5 op = _opcodesDrawV5[i].proc; +void Inter_v5::setupOpcodesDraw() { + Inter_v4::setupOpcodesDraw(); - if (op == 0) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); + OPCODEDRAW(0x61, o5_deleteFile); + OPCODEDRAW(0x80, o5_initScreen); } -bool Inter_v5::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s) - %s, %d, %d", - i, j, i, j, getOpcodeFuncDesc(i, j), _vm->_game->_curTotFile, - (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData), - (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData - params.counter - 4)); - - if ((i > 4) || (j > 15)) { - warning("unimplemented opcodeFunc: %d.%d", i, j); - return false; - } +void Inter_v5::setupOpcodesFunc() { + Inter_v4::setupOpcodesFunc(); - OpcodeFuncProcV5 op = _opcodesFuncV5[i*16 + j].proc; - - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); - - return false; -} - -void Inter_v5::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); - - OpcodeGoblinProcV5 op = 0; - - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinV5[_goblinFuncLookUp[j][1]].proc; - break; - } - - _vm->_global->_inter_execPtr -= 2; - - if (op == 0) { - warning("unimplemented opcodeGoblin: %d", i); - - int16 paramCount = load16(); - _vm->_global->_inter_execPtr += paramCount * 2; - } else { - params.extraData = i; - - (this->*op) (params); - } + OPCODEFUNC(0x45, o5_istrlen); } -const char *Inter_v5::getOpcodeDrawDesc(byte i) { - return _opcodesDrawV5[i].desc; -} - -const char *Inter_v5::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; - - return _opcodesFuncV5[i*16 + j].desc; -} - -const char *Inter_v5::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinV5[_goblinFuncLookUp[j][1]].desc; - return ""; +void Inter_v5::setupOpcodesGob() { + OPCODEGOB( 0, o5_spaceShooter); + OPCODEGOB( 1, o5_spaceShooter); + OPCODEGOB( 2, o5_spaceShooter); + OPCODEGOB( 3, o5_spaceShooter); + + OPCODEGOB( 33, o5_spaceShooter); + + OPCODEGOB( 80, o5_getSystemCDSpeed); + OPCODEGOB( 81, o5_getSystemRAM); + OPCODEGOB( 82, o5_getSystemCPUSpeed); + OPCODEGOB( 83, o5_getSystemDrawSpeed); + OPCODEGOB( 84, o5_totalSystemSpecs); + + OPCODEGOB( 85, o5_saveSystemSpecs); + OPCODEGOB( 86, o5_loadSystemSpecs); + + OPCODEGOB( 87, o5_spaceShooter); + OPCODEGOB( 88, o5_spaceShooter); + OPCODEGOB( 89, o5_spaceShooter); + OPCODEGOB( 90, o5_spaceShooter); + + OPCODEGOB( 91, o5_spaceShooter); + OPCODEGOB( 92, o5_gob92); + OPCODEGOB( 93, o5_spaceShooter); + OPCODEGOB( 94, o5_spaceShooter); + + OPCODEGOB( 95, o5_gob95); + OPCODEGOB( 96, o5_gob96); + OPCODEGOB( 97, o5_gob97); + OPCODEGOB( 98, o5_gob98); + + OPCODEGOB( 99, o5_spaceShooter); + OPCODEGOB(100, o5_gob100); + OPCODEGOB(200, o5_gob200); } void Inter_v5::o5_deleteFile() { - evalExpr(0); + _vm->_game->_script->evalExpr(0); - warning("Dynasty Stub: deleteFile \"%s\"", _vm->_global->_inter_resStr); + warning("Dynasty Stub: deleteFile \"%s\"", _vm->_game->_script->getResultStr()); } void Inter_v5::o5_initScreen() { @@ -683,13 +104,13 @@ void Inter_v5::o5_initScreen() { int16 videoMode; int16 width, height; - offY = load16(); + offY = _vm->_game->_script->readInt16(); videoMode = offY & 0xFF; offY = (offY >> 8) & 0xFF; - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); + width = _vm->_game->_script->readValExpr(); + height = _vm->_game->_script->readValExpr(); warning("initScreen: %d, %d, %d, %d", width, height, offY, videoMode); @@ -754,9 +175,9 @@ void Inter_v5::o5_initScreen() { memset(_vm->_global->_greenPalette, 0, 256); memset(_vm->_global->_bluePalette, 0, 256); - _vm->_video->_splitSurf = 0; - _vm->_draw->_spritesArray[24] = 0; - _vm->_draw->_spritesArray[25] = 0; + _vm->_video->_splitSurf.reset(); + _vm->_draw->_spritesArray[24].reset(); + _vm->_draw->_spritesArray[25].reset(); _vm->_global->_videoMode = videoMode; _vm->_video->initPrimary(videoMode); @@ -773,8 +194,8 @@ void Inter_v5::o5_initScreen() { _vm->_util->setScrollOffset(); if (offY > 0) { - _vm->_draw->_spritesArray[24] = new SurfaceDesc(videoMode, _vm->_width, offY); - _vm->_draw->_spritesArray[25] = new SurfaceDesc(videoMode, _vm->_width, offY); + _vm->_draw->_spritesArray[24] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); + _vm->_draw->_spritesArray[25] = SurfaceDescPtr(new SurfaceDesc(videoMode, _vm->_width, offY)); _vm->_video->_splitSurf = _vm->_draw->_spritesArray[25]; } } @@ -784,18 +205,18 @@ bool Inter_v5::o5_istrlen(OpFuncParams ¶ms) { int16 len; uint16 type; - if (*_vm->_global->_inter_execPtr == 0x80) { - _vm->_global->_inter_execPtr++; + if (_vm->_game->_script->peekByte() == 0x80) { + _vm->_game->_script->skip(1); - strVar1 = _vm->_parse->parseVarIndex(); - strVar2 = _vm->_parse->parseVarIndex(0, &type); + strVar1 = _vm->_game->_script->readVarIndex(); + strVar2 = _vm->_game->_script->readVarIndex(0, &type); len = _vm->_draw->stringLength(GET_VARO_STR(strVar1), READ_VARO_UINT16(strVar2)); } else { - strVar1 = _vm->_parse->parseVarIndex(); - strVar2 = _vm->_parse->parseVarIndex(0, &type); + strVar1 = _vm->_game->_script->readVarIndex(); + strVar2 = _vm->_game->_script->readVarIndex(0, &type); if (_vm->_global->_language == 10) { // Extra handling for Japanese strings @@ -814,44 +235,40 @@ bool Inter_v5::o5_istrlen(OpFuncParams ¶ms) { } void Inter_v5::o5_spaceShooter(OpGobParams ¶ms) { - int16 paramCount = load16(); - warning("Dynasty Stub: Space shooter: %d, %d, %s", - params.extraData, paramCount, _vm->_game->_curTotFile); + params.extraData, params.paramCount, _vm->_game->_curTotFile); - if (paramCount < 4) { + if (params.paramCount < 4) { warning("Space shooter variable counter < 4"); - _vm->_global->_inter_execPtr += paramCount * 2; + _vm->_game->_script->skip(params.paramCount * 2); return; } - uint32 var1 = load16() * 4; - uint32 var2 = load16() * 4; + uint32 var1 = _vm->_game->_script->readInt16() * 4; + uint32 var2 = _vm->_game->_script->readInt16() * 4; - load16(); - load16(); + _vm->_game->_script->readInt16(); + _vm->_game->_script->readInt16(); if (params.extraData != 0) { WRITE_VARO_UINT32(var1, 2); WRITE_VARO_UINT32(var2, 0); } else { - if (paramCount < 5) { + if (params.paramCount < 5) { warning("Space shooter variable counter < 5"); return; } - _vm->_global->_inter_execPtr += (paramCount - 4) * 2; + _vm->_game->_script->skip((params.paramCount - 4) * 2); } } void Inter_v5::o5_getSystemCDSpeed(OpGobParams ¶ms) { - _vm->_global->_inter_execPtr += 2; - - WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% Video::FontDesc *font; if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface, font); _vm->_draw->forceBlit(); delete font; @@ -859,13 +276,11 @@ void Inter_v5::o5_getSystemCDSpeed(OpGobParams ¶ms) { } void Inter_v5::o5_getSystemRAM(OpGobParams ¶ms) { - _vm->_global->_inter_execPtr += 2; - - WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% Video::FontDesc *font; if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface, font); _vm->_draw->forceBlit(); delete font; @@ -873,13 +288,11 @@ void Inter_v5::o5_getSystemRAM(OpGobParams ¶ms) { } void Inter_v5::o5_getSystemCPUSpeed(OpGobParams ¶ms) { - _vm->_global->_inter_execPtr += 2; - - WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% Video::FontDesc *font; if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface, font); _vm->_draw->forceBlit(); delete font; @@ -887,13 +300,11 @@ void Inter_v5::o5_getSystemCPUSpeed(OpGobParams ¶ms) { } void Inter_v5::o5_getSystemDrawSpeed(OpGobParams ¶ms) { - _vm->_global->_inter_execPtr += 2; - - WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% Video::FontDesc *font; if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface, font); _vm->_draw->forceBlit(); delete font; @@ -901,13 +312,11 @@ void Inter_v5::o5_getSystemDrawSpeed(OpGobParams ¶ms) { } void Inter_v5::o5_totalSystemSpecs(OpGobParams ¶ms) { - _vm->_global->_inter_execPtr += 2; - - WRITE_VAR_UINT32(load16(), 100); // Fudging 100% + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100% Video::FontDesc *font; if ((font = _vm->_util->loadFont("SPEED.LET"))) { - _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, _vm->_draw->_backSurface, font); + _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface, font); _vm->_draw->forceBlit(); delete font; @@ -917,8 +326,6 @@ void Inter_v5::o5_totalSystemSpecs(OpGobParams ¶ms) { void Inter_v5::o5_saveSystemSpecs(OpGobParams ¶ms) { warning("Dynasty Stub: Saving system specifications"); - _vm->_global->_inter_execPtr += 2; - /* FILE *f = fopen("SAVE\\SPEED.INF", w); fwrite(&_cdSpeed, sizeof(_cdSpeed), 1, f); @@ -933,8 +340,6 @@ void Inter_v5::o5_saveSystemSpecs(OpGobParams ¶ms) { void Inter_v5::o5_loadSystemSpecs(OpGobParams ¶ms) { warning("Dynasty Stub: Loading system specifications"); - _vm->_global->_inter_execPtr += 2; - /* FILE *f = fopen("SAVE\\SPEED.INF", r); fread(&_cdSpeed, sizeof(_cdSpeed), 1, f); @@ -971,32 +376,26 @@ void Inter_v5::o5_loadSystemSpecs(OpGobParams ¶ms) { void Inter_v5::o5_gob92(OpGobParams ¶ms) { warning("Dynasty Stub: GobFunc 92"); - _vm->_global->_inter_execPtr += 2; - - WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int8) _gob92_1)) */); + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int8) _gob92_1)) */); } void Inter_v5::o5_gob95(OpGobParams ¶ms) { warning("Dynasty Stub: GobFunc 95"); - _vm->_global->_inter_execPtr += 2; - - WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int16) speedThrottle4)) */); - WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int8) speedThrottle3)) */); - WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int8) speedThrottle2)) */); - WRITE_VAR_UINT32(load16(), 0 /* (uint32) ((int32) ((int16) speedThrottle1)) */); + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int16) speedThrottle4)) */); + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int8) speedThrottle3)) */); + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int8) speedThrottle2)) */); + WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 0 /* (uint32) ((int32) ((int16) speedThrottle1)) */); } void Inter_v5::o5_gob96(OpGobParams ¶ms) { int16 speedThrottle4, speedThrottle1; byte speedThrottle3, speedThrottle2; - _vm->_global->_inter_execPtr += 2; - - speedThrottle4 = READ_VAR_UINT16(load16()); - speedThrottle3 = READ_VAR_UINT8(load16()); - speedThrottle2 = READ_VAR_UINT8(load16()); - speedThrottle1 = READ_VAR_UINT16(load16()); + speedThrottle4 = READ_VAR_UINT16(_vm->_game->_script->readInt16()); + speedThrottle3 = READ_VAR_UINT8(_vm->_game->_script->readInt16()); + speedThrottle2 = READ_VAR_UINT8(_vm->_game->_script->readInt16()); + speedThrottle1 = READ_VAR_UINT16(_vm->_game->_script->readInt16()); warning("Dynasty Stub: GobFunc 96: %d, %d, %d, %d", speedThrottle4, speedThrottle3, speedThrottle2, speedThrottle1); @@ -1006,23 +405,17 @@ void Inter_v5::o5_gob96(OpGobParams ¶ms) { void Inter_v5::o5_gob97(OpGobParams ¶ms) { _gob_97_98_val = 1; - - _vm->_global->_inter_execPtr += 2; } void Inter_v5::o5_gob98(OpGobParams ¶ms) { _gob_97_98_val = 0; - - _vm->_global->_inter_execPtr += 2; } void Inter_v5::o5_gob100(OpGobParams ¶ms) { - _vm->_global->_inter_execPtr += 2; - - uint16 var1 = READ_VAR_UINT16(load16()); - uint16 var2 = READ_VAR_UINT16(load16()); - uint16 var3 = READ_VAR_UINT16(load16()); - uint16 var4 = READ_VAR_UINT16(load16()); + uint16 var1 = READ_VAR_UINT16(_vm->_game->_script->readInt16()); + uint16 var2 = READ_VAR_UINT16(_vm->_game->_script->readInt16()); + uint16 var3 = READ_VAR_UINT16(_vm->_game->_script->readInt16()); + uint16 var4 = READ_VAR_UINT16(_vm->_game->_script->readInt16()); warning("Dynasty Stub: GobFunc 100: %d, %d, %d, %d", var1, var2, var3, var4); @@ -1031,11 +424,9 @@ void Inter_v5::o5_gob100(OpGobParams ¶ms) { } void Inter_v5::o5_gob200(OpGobParams ¶ms) { - _vm->_global->_inter_execPtr += 2; - - uint16 var1 = load16(); // index into the spritesArray - uint16 var2 = load16(); - uint16 var3 = load16(); + uint16 var1 = _vm->_game->_script->readUint16(); // index into the spritesArray + uint16 var2 = _vm->_game->_script->readUint16(); + uint16 var3 = _vm->_game->_script->readUint16(); warning("Dynasty Stub: GobFunc 200: %d, %d, %d", var1, var2, var3); } diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp index 04db46c643..506de821d4 100644 --- a/engines/gob/inter_v6.cpp +++ b/engines/gob/inter_v6.cpp @@ -32,626 +32,43 @@ #include "gob/helper.h" #include "gob/global.h" #include "gob/game.h" -#include "gob/parse.h" +#include "gob/expression.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/draw.h" #include "gob/sound/sound.h" #include "gob/videoplayer.h" namespace Gob { -#define OPCODE(x) _OPCODE(Inter_v6, x) - -const int Inter_v6::_goblinFuncLookUp[][2] = { - {0, 0}, -}; +#define OPCODEVER Inter_v6 +#define OPCODEDRAW(i, x) _opcodesDraw[i]._OPCODEDRAW(OPCODEVER, x) +#define OPCODEFUNC(i, x) _opcodesFunc[i]._OPCODEFUNC(OPCODEVER, x) +#define OPCODEGOB(i, x) _opcodesGob[i]._OPCODEGOB(OPCODEVER, x) Inter_v6::Inter_v6(GobEngine *vm) : Inter_v5(vm) { _gotFirstPalette = false; - - setupOpcodes(); -} - -void Inter_v6::setupOpcodes() { - static const OpcodeDrawEntryV6 opcodesDraw[256] = { - /* 00 */ - OPCODE(o1_loadMult), - OPCODE(o2_playMult), - OPCODE(o2_freeMultKeys), - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - OPCODE(o1_initCursor), - /* 08 */ - OPCODE(o1_initCursorAnim), - OPCODE(o1_clearCursorAnim), - OPCODE(o2_setRenderFlags), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - OPCODE(o1_loadAnim), - OPCODE(o1_freeAnim), - OPCODE(o1_updateAnim), - OPCODE(o2_multSub), - /* 14 */ - OPCODE(o2_initMult), - OPCODE(o1_freeMult), - OPCODE(o1_animate), - OPCODE(o2_loadMultObject), - /* 18 */ - OPCODE(o1_getAnimLayerInfo), - OPCODE(o1_getObjAnimSize), - OPCODE(o1_loadStatic), - OPCODE(o1_freeStatic), - /* 1C */ - OPCODE(o2_renderStatic), - OPCODE(o2_loadCurLayer), - {0, ""}, - {0, ""}, - /* 20 */ - OPCODE(o2_playCDTrack), - OPCODE(o2_waitCDTrackEnd), - OPCODE(o2_stopCD), - OPCODE(o2_readLIC), - /* 24 */ - OPCODE(o2_freeLIC), - OPCODE(o2_getCDTrackPos), - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o2_loadFontToSprite), - OPCODE(o1_freeFontToSprite), - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - OPCODE(o6_totSub), - OPCODE(o2_switchTotSub), - OPCODE(o2_pushVars), - OPCODE(o2_popVars), - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 48 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 4C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 50 */ - OPCODE(o2_loadMapObjects), - OPCODE(o2_freeGoblins), - OPCODE(o2_moveGoblin), - OPCODE(o2_writeGoblinPos), - /* 54 */ - OPCODE(o2_stopGoblin), - OPCODE(o2_setGoblinState), - OPCODE(o2_placeGoblin), - {0, ""}, - /* 58 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 5C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 60 */ - {0, ""}, - OPCODE(o5_deleteFile), - {0, ""}, - {0, ""}, - /* 64 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 68 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 6C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 70 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 74 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 78 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 7C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 80 */ - OPCODE(o5_initScreen), - OPCODE(o2_scroll), - OPCODE(o2_setScrollOffset), - OPCODE(o6_playVmdOrMusic), - /* 84 */ - OPCODE(o2_getImdInfo), - OPCODE(o6_openItk), - OPCODE(o2_closeItk), - OPCODE(o2_setImdFrontSurf), - /* 88 */ - OPCODE(o2_resetImdFrontSurf), - {0, ""}, - {0, ""}, - {0, ""}, - /* 8C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 90 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 94 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 98 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 9C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* A8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* AC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* B8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* BC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* C8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* CC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* D8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* DC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* E8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* EC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F0 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F4 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* F8 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* FC */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""} - }; - - static const OpcodeFuncEntryV6 opcodesFunc[80] = { - /* 00 */ - OPCODE(o1_callSub), - OPCODE(o1_callSub), - OPCODE(o1_printTotText), - OPCODE(o6_loadCursor), - /* 04 */ - {0, ""}, - OPCODE(o1_switch), - OPCODE(o1_repeatUntil), - OPCODE(o1_whileDo), - /* 08 */ - OPCODE(o1_if), - OPCODE(o6_evaluateStore), - OPCODE(o1_loadSpriteToPos), - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - OPCODE(o2_printText), - OPCODE(o1_loadTot), - OPCODE(o6_palLoad), - /* 14 */ - OPCODE(o1_keyFunc), - OPCODE(o1_capturePush), - OPCODE(o1_capturePop), - OPCODE(o2_animPalInit), - /* 18 */ - OPCODE(o2_addCollision), - OPCODE(o6_freeCollision), - OPCODE(o3_getTotTextItemPart), - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - OPCODE(o1_drawOperations), - OPCODE(o1_setcmdCount), - /* 20 */ - OPCODE(o1_return), - OPCODE(o1_renewTimeInVars), - OPCODE(o1_speakerOn), - OPCODE(o1_speakerOff), - /* 24 */ - OPCODE(o1_putPixel), - OPCODE(o2_goblinFunc), - OPCODE(o1_createSprite), - OPCODE(o1_freeSprite), - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - OPCODE(o1_returnTo), - OPCODE(o1_loadSpriteContent), - OPCODE(o1_copySprite), - OPCODE(o6_fillRect), - /* 34 */ - OPCODE(o1_drawLine), - OPCODE(o1_strToLong), - OPCODE(o1_invalidate), - OPCODE(o1_setBackDelta), - /* 38 */ - OPCODE(o1_playSound), - OPCODE(o2_stopSound), - OPCODE(o2_loadSound), - OPCODE(o1_freeSoundSlot), - /* 3C */ - OPCODE(o1_waitEndPlay), - OPCODE(o1_playComposition), - OPCODE(o2_getFreeMem), - OPCODE(o2_checkData), - /* 40 */ - {0, ""}, - OPCODE(o1_prepareStr), - OPCODE(o1_insertStr), - OPCODE(o1_cutStr), - /* 44 */ - OPCODE(o1_strstr), - OPCODE(o5_istrlen), - OPCODE(o1_setMousePos), - OPCODE(o1_setFrameRate), - /* 48 */ - OPCODE(o1_animatePalette), - OPCODE(o1_animateCursor), - OPCODE(o1_blitCursor), - OPCODE(o1_loadFont), - /* 4C */ - OPCODE(o1_freeFont), - OPCODE(o2_readData), - OPCODE(o2_writeData), - OPCODE(o1_manageDataFile), - }; - - static const OpcodeGoblinEntryV6 opcodesGoblin[71] = { - /* 00 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 04 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 08 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 0C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 10 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 14 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 18 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 1C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 20 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 24 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 28 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 2C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 30 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 34 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 38 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 3C */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 40 */ - {0, ""}, - {0, ""}, - {0, ""}, - {0, ""}, - /* 44 */ - {0, ""}, - {0, ""}, - {0, ""}, - }; - - _opcodesDrawV6 = opcodesDraw; - _opcodesFuncV6 = opcodesFunc; - _opcodesGoblinV6 = opcodesGoblin; -} - -void Inter_v6::executeDrawOpcode(byte i) { - debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", - i, i, getOpcodeDrawDesc(i)); - - OpcodeDrawProcV6 op = _opcodesDrawV6[i].proc; - - if (op == 0) - warning("unimplemented opcodeDraw: %d", i); - else - (this->*op) (); -} - -bool Inter_v6::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { - _vm->_video->_palLUT->buildNext(); - - debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s) - %s, %d, %d", - i, j, i, j, getOpcodeFuncDesc(i, j), _vm->_game->_curTotFile, - (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData), - (uint) (_vm->_global->_inter_execPtr - _vm->_game->_totFileData - params.counter - 4)); - - if ((i > 4) || (j > 15)) { - warning("unimplemented opcodeFunc: %d.%d", i, j); - return false; - } - - OpcodeFuncProcV6 op = _opcodesFuncV6[i*16 + j].proc; - - if (op == 0) - warning("unimplemented opcodeFunc: %d.%d", i, j); - else - return (this->*op) (params); - - return false; } -void Inter_v6::executeGoblinOpcode(int i, OpGobParams ¶ms) { - debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", - i, i, getOpcodeGoblinDesc(i)); - - OpcodeGoblinProcV6 op = 0; - - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) { - op = _opcodesGoblinV6[_goblinFuncLookUp[j][1]].proc; - break; - } - - _vm->_global->_inter_execPtr -= 2; - - if (op == 0) { - warning("unimplemented opcodeGoblin: %d", i); - - int16 paramCount = load16(); - _vm->_global->_inter_execPtr += paramCount * 2; - } else { - params.extraData = i; +void Inter_v6::setupOpcodesDraw() { + Inter_v5::setupOpcodesDraw(); - (this->*op) (params); - } -} - -const char *Inter_v6::getOpcodeDrawDesc(byte i) { - return _opcodesDrawV6[i].desc; + OPCODEDRAW(0x40, o6_totSub); + OPCODEDRAW(0x83, o6_playVmdOrMusic); + OPCODEDRAW(0x85, o6_openItk); } -const char *Inter_v6::getOpcodeFuncDesc(byte i, byte j) { - if ((i > 4) || (j > 15)) - return ""; +void Inter_v6::setupOpcodesFunc() { + Inter_v5::setupOpcodesFunc(); - return _opcodesFuncV6[i*16 + j].desc; + OPCODEFUNC(0x03, o6_loadCursor); + OPCODEFUNC(0x09, o6_assign); + OPCODEFUNC(0x13, o6_palLoad); + OPCODEFUNC(0x19, o6_freeCollision); + OPCODEFUNC(0x33, o6_fillRect); } -const char *Inter_v6::getOpcodeGoblinDesc(int i) { - for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) - if (_goblinFuncLookUp[j][0] == i) - return _opcodesGoblinV6[_goblinFuncLookUp[j][1]].desc; - return ""; +void Inter_v6::setupOpcodesGob() { } void Inter_v6::o6_totSub() { @@ -660,20 +77,20 @@ void Inter_v6::o6_totSub() { int flags; int i; - length = *_vm->_global->_inter_execPtr++; + length = _vm->_game->_script->readByte(); if ((length & 0x7F) > 13) error("Length in o2_totSub is greater than 13 (%d)", length); if (length & 0x80) { - evalExpr(0); - strcpy(totFile, _vm->_global->_inter_resStr); + _vm->_game->_script->evalExpr(0); + strcpy(totFile, _vm->_game->_script->getResultStr()); } else { for (i = 0; i < length; i++) - totFile[i] = (char) *_vm->_global->_inter_execPtr++; + totFile[i] = _vm->_game->_script->readChar(); totFile[i] = 0; } - flags = *_vm->_global->_inter_execPtr++; + flags = _vm->_game->_script->readByte(); if (flags & 0x40) warning("Urban Stub: o6_totSub(), flags & 0x40"); @@ -693,17 +110,17 @@ void Inter_v6::o6_playVmdOrMusic() { uint16 palCmd; bool close; - evalExpr(0); - strncpy0(fileName, _vm->_global->_inter_resStr, 127); - - x = _vm->_parse->parseValExpr(); - y = _vm->_parse->parseValExpr(); - startFrame = _vm->_parse->parseValExpr(); - lastFrame = _vm->_parse->parseValExpr(); - breakKey = _vm->_parse->parseValExpr(); - flags = _vm->_parse->parseValExpr(); - palStart = _vm->_parse->parseValExpr(); - palEnd = _vm->_parse->parseValExpr(); + _vm->_game->_script->evalExpr(0); + strncpy0(fileName, _vm->_game->_script->getResultStr(), 127); + + x = _vm->_game->_script->readValExpr(); + y = _vm->_game->_script->readValExpr(); + startFrame = _vm->_game->_script->readValExpr(); + lastFrame = _vm->_game->_script->readValExpr(); + breakKey = _vm->_game->_script->readValExpr(); + flags = _vm->_game->_script->readValExpr(); + palStart = _vm->_game->_script->readValExpr(); + palEnd = _vm->_game->_script->readValExpr(); palCmd = 1 << (flags & 0x3F); debugC(1, kDebugVideo, "Playing video \"%s\" @ %d+%d, frames %d - %d, " @@ -759,8 +176,8 @@ void Inter_v6::o6_playVmdOrMusic() { void Inter_v6::o6_openItk() { char fileName[32]; - evalExpr(0); - strncpy0(fileName, _vm->_global->_inter_resStr, 27); + _vm->_game->_script->evalExpr(0); + strncpy0(fileName, _vm->_game->_script->getResultStr(), 27); if (!strchr(fileName, '.')) strcat(fileName, ".ITK"); @@ -778,21 +195,21 @@ void Inter_v6::o6_openItk() { } bool Inter_v6::o6_loadCursor(OpFuncParams ¶ms) { - int16 id = load16(); + int16 id = _vm->_game->_script->readInt16(); if ((id == -1) || (id == -2)) { char file[10]; if (id == -1) { for (int i = 0; i < 9; i++) - file[i] = *_vm->_global->_inter_execPtr++; + file[i] = _vm->_game->_script->readChar(); } else - strncpy(file, GET_VAR_STR(load16()), 10); + strncpy(file, GET_VAR_STR(_vm->_game->_script->readInt16()), 10); file[9] = '\0'; - uint16 start = load16(); - int8 index = (int8) *_vm->_global->_inter_execPtr++; + uint16 start = _vm->_game->_script->readUint16(); + int8 index = _vm->_game->_script->readInt8(); int vmdSlot = _vm->_vidPlayer->slotOpen(file); @@ -820,101 +237,102 @@ bool Inter_v6::o6_loadCursor(OpFuncParams ¶ms) { return false; } - int8 index = (int8) *_vm->_global->_inter_execPtr++; + int8 index = _vm->_game->_script->readInt8(); if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth()) return false; - int16 width, height; - byte *dataBuf = _vm->_game->loadTotResource(id, 0, &width, &height); + Resource *resource = _vm->_game->_resources->getResource((uint16) id); + if (!resource) + return false; - _vm->_video->fillRect(_vm->_draw->_cursorSprites, + _vm->_video->fillRect(*_vm->_draw->_cursorSprites, index * _vm->_draw->_cursorWidth, 0, index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, _vm->_draw->_cursorHeight - 1, 0); - _vm->_video->drawPackedSprite(dataBuf, width, height, - index * _vm->_draw->_cursorWidth, 0, 0, _vm->_draw->_cursorSprites); + _vm->_video->drawPackedSprite(resource->getData(), + resource->getWidth(), resource->getHeight(), + index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites); _vm->_draw->_cursorAnimLow[index] = 0; + delete resource; return false; } -bool Inter_v6::o6_evaluateStore(OpFuncParams ¶ms) { - byte *savedPos; - int16 varOff; - int16 token; - int16 result; - byte loopCount; - uint16 var_6, var_A; +bool Inter_v6::o6_assign(OpFuncParams ¶ms) { + uint16 size, destType; + int16 dest = _vm->_game->_script->readVarIndex(&size, &destType); - varOff = _vm->_parse->parseVarIndex(&var_6, &var_A); + if (size != 0) { + int16 src; - if (var_6 != 0) { - int16 var_4; + _vm->_game->_script->push(); - savedPos = _vm->_global->_inter_execPtr; + src = _vm->_game->_script->readVarIndex(&size, 0); - var_4 = _vm->_parse->parseVarIndex(&var_6, 0); + memcpy(_vm->_inter->_variables->getAddressOff8(dest), + _vm->_inter->_variables->getAddressOff8(src), size * 4); - memcpy(_vm->_inter->_variables->getAddressOff8(varOff), - _vm->_inter->_variables->getAddressOff8(var_4), var_6 * 4); + _vm->_game->_script->pop(); - _vm->_global->_inter_execPtr = savedPos; - evalExpr(&var_4); + _vm->_game->_script->evalExpr(&src); return false; } - if (*_vm->_global->_inter_execPtr == 98) { - _vm->_global->_inter_execPtr++; - loopCount = *_vm->_global->_inter_execPtr++; + byte loopCount; + if (_vm->_game->_script->peekByte() == 98) { + _vm->_game->_script->skip(1); + loopCount = _vm->_game->_script->readByte(); for (int i = 0; i < loopCount; i++) { - uint8 c = *_vm->_global->_inter_execPtr++; - uint16 n = load16(); + uint8 c = _vm->_game->_script->readByte(); + uint16 n = _vm->_game->_script->readUint16(); - memset(_vm->_inter->_variables->getAddressOff8(varOff), c, n); + memset(_vm->_inter->_variables->getAddressOff8(dest), c, n); - varOff += n; + dest += n; } return false; - } else if (*_vm->_global->_inter_execPtr == 99) { - _vm->_global->_inter_execPtr++; - loopCount = *_vm->_global->_inter_execPtr++; + } else if (_vm->_game->_script->peekByte() == 99) { + _vm->_game->_script->skip(1); + loopCount = _vm->_game->_script->readByte(); } else loopCount = 1; for (int i = 0; i < loopCount; i++) { - token = evalExpr(&result); - switch (var_A) { - case 16: - case 18: - WRITE_VARO_UINT8(varOff + i, _vm->_global->_inter_resVal); + int16 result; + int16 srcType = _vm->_game->_script->evalExpr(&result); + + switch (destType) { + case TYPE_VAR_INT8: + case TYPE_ARRAY_INT8: + WRITE_VARO_UINT8(dest + i, _vm->_game->_script->getResultInt()); break; - case 17: - case 27: - WRITE_VARO_UINT16(varOff + i * 2, _vm->_global->_inter_resVal); + case TYPE_VAR_INT16: + case TYPE_ARRAY_INT16: + WRITE_VARO_UINT16(dest + i * 2, _vm->_game->_script->getResultInt()); break; - case 23: - case 26: - WRITE_VAR_OFFSET(varOff + i * 4, _vm->_global->_inter_resVal); + case TYPE_VAR_INT32: + case TYPE_ARRAY_INT32: + WRITE_VAR_OFFSET(dest + i * 4, _vm->_game->_script->getResultInt()); break; - case 24: - WRITE_VARO_UINT16(varOff + i * 4, _vm->_global->_inter_resVal); + case TYPE_VAR_INT32_AS_INT16: + WRITE_VARO_UINT16(dest + i * 4, _vm->_game->_script->getResultInt()); break; - case 25: - case 28: - if (token == 20) - WRITE_VARO_UINT8(varOff, result); + case TYPE_VAR_STR: + case TYPE_ARRAY_STR: + if (srcType == TYPE_IMM_INT16) + WRITE_VARO_UINT8(dest, result); else - WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr); + WRITE_VARO_STR(dest, _vm->_game->_script->getResultStr()); break; } } @@ -936,7 +354,7 @@ bool Inter_v6::o6_palLoad(OpFuncParams ¶ms) { bool Inter_v6::o6_freeCollision(OpFuncParams ¶ms) { int16 id; - id = _vm->_parse->parseValExpr(); + id = _vm->_game->_script->readValExpr(); switch (id + 5) { case 0: @@ -972,17 +390,17 @@ bool Inter_v6::o6_freeCollision(OpFuncParams ¶ms) { bool Inter_v6::o6_fillRect(OpFuncParams ¶ms) { int16 destSurf; - _vm->_draw->_destSurface = destSurf = load16(); + _vm->_draw->_destSurface = destSurf = _vm->_game->_script->readInt16(); - _vm->_draw->_destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->_destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->_spriteBottom = _vm->_parse->parseValExpr(); + _vm->_draw->_destSpriteX = _vm->_game->_script->readValExpr(); + _vm->_draw->_destSpriteY = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteRight = _vm->_game->_script->readValExpr(); + _vm->_draw->_spriteBottom = _vm->_game->_script->readValExpr(); - evalExpr(0); + _vm->_game->_script->evalExpr(0); - _vm->_draw->_backColor = _vm->_global->_inter_resVal & 0xFFFF; - uint16 extraVar = _vm->_global->_inter_resVal >> 16; + _vm->_draw->_backColor = _vm->_game->_script->getResultInt() & 0xFFFF; + uint16 extraVar = _vm->_game->_script->getResultInt() >> 16; if (extraVar != 0) warning("Urban Stub: o6_fillRect(), extraVar = %d", extraVar); @@ -1019,11 +437,8 @@ void Inter_v6::probe16bitMusic(char *fileName) { fileName[len - 1] = 'V'; - int16 handle; - if ((handle = _vm->_dataIO->openData(fileName)) >= 0) { - _vm->_dataIO->closeData(handle); + if (_vm->_dataIO->existData(fileName)) return; - } fileName[len - 1] = '8'; } diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp index 2c94b3fb24..dacc72d6c7 100644 --- a/engines/gob/map_v1.cpp +++ b/engines/gob/map_v1.cpp @@ -64,7 +64,6 @@ void Map_v1::init(void) { void Map_v1::loadMapObjects(const char *avjFile) { char avoName[128]; byte *dataBuf; - int16 handle; int16 tmp; int32 flag; int16 gobDataCount; @@ -75,15 +74,14 @@ void Map_v1::loadMapObjects(const char *avjFile) { strcpy(avoName, _sourceFile); strcat(avoName, ".avo"); - handle = _vm->_dataIO->openData(avoName); - if (handle >= 0) { + if (_vm->_dataIO->existData(avoName)) { _loadFromAvo = true; - _vm->_dataIO->closeData(handle); dataBuf = _vm->_dataIO->getData(avoName); } else { _loadFromAvo = false; dataBuf = _vm->_dataIO->getData(avjFile); } + Common::MemoryReadStream mapData(dataBuf, 4294967295U); init(); @@ -146,7 +144,6 @@ void Map_v1::loadMapObjects(const char *avjFile) { void Map_v1::loadSounds(Common::SeekableReadStream &data) { int16 count; - int16 handle; char buf[19]; char sndNames[20][14]; @@ -162,11 +159,9 @@ void Map_v1::loadSounds(Common::SeekableReadStream &data) { _vm->_sound->sampleLoad(&_vm->_goblin->_soundData[14], SOUND_SND, "diamant1.snd"); for (int i = 0; i < count; i++) { - handle = _vm->_dataIO->openData(sndNames[i]); - if (handle < 0) + if (!_vm->_dataIO->existData(sndNames[i])) continue; - _vm->_dataIO->closeData(handle); _vm->_sound->sampleLoad(&_vm->_goblin->_soundData[i], SOUND_SND, sndNames[i]); } } diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp index db4f2075e1..6ceda7ab44 100644 --- a/engines/gob/map_v2.cpp +++ b/engines/gob/map_v2.cpp @@ -31,7 +31,8 @@ #include "gob/goblin.h" #include "gob/inter.h" #include "gob/game.h" -#include "gob/parse.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/mult.h" namespace Gob { @@ -51,22 +52,24 @@ void Map_v2::loadMapObjects(const char *avjFile) { int16 mapWidth, mapHeight; int16 tmp; byte *variables; - byte *extData; uint32 tmpPos; uint32 passPos; - var = _vm->_parse->parseVarIndex(); + var = _vm->_game->_script->readVarIndex(); variables = _vm->_inter->_variables->getAddressOff8(var); - id = _vm->_inter->load16(); + id = _vm->_game->_script->readInt16(); if (id == -1) { _passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var); return; } - extData = _vm->_game->loadExtData(id, 0, 0); - Common::MemoryReadStream mapData(extData, 4294967295U); + Resource *resource = _vm->_game->_resources->getResource(id); + if (!resource) + return; + + Common::SeekableReadStream &mapData = *resource->stream(); if (mapData.readByte() == 3) { _screenWidth = 640; @@ -88,7 +91,7 @@ void Map_v2::loadMapObjects(const char *avjFile) { passPos = mapData.pos(); mapData.skip(_mapWidth * _mapHeight); - if (*extData == 1) + if (resource->getData()[0] == 1) wayPointsCount = _wayPointsCount = 40; else wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount; @@ -130,11 +133,11 @@ void Map_v2::loadMapObjects(const char *avjFile) { for (int i = 0; i < _vm->_goblin->_gobsCount; i++) loadGoblinStates(mapData, i); - _vm->_goblin->_soundSlotsCount = _vm->_inter->load16(); + _vm->_goblin->_soundSlotsCount = _vm->_game->_script->readInt16(); for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++) _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1); - delete[] extData; + delete resource; } void Map_v2::loadGoblinStates(Common::SeekableReadStream &data, int index) { diff --git a/engines/gob/map_v4.cpp b/engines/gob/map_v4.cpp index 858e7972bc..1db3d6a3f8 100644 --- a/engines/gob/map_v4.cpp +++ b/engines/gob/map_v4.cpp @@ -31,7 +31,8 @@ #include "gob/goblin.h" #include "gob/inter.h" #include "gob/game.h" -#include "gob/parse.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/mult.h" namespace Gob { @@ -49,14 +50,13 @@ void Map_v4::loadMapObjects(const char *avjFile) { int16 mapWidth, mapHeight; int16 tmp; byte *variables; - byte *extData; uint32 tmpPos; uint32 passPos; - var = _vm->_parse->parseVarIndex(); + var = _vm->_game->_script->readVarIndex(); variables = _vm->_inter->_variables->getAddressOff8(var); - id = _vm->_inter->load16(); + id = _vm->_game->_script->readInt16(); if (((uint16) id) >= 65520) { warning("Woodruff Stub: loadMapObjects ID >= 65520"); @@ -66,8 +66,11 @@ void Map_v4::loadMapObjects(const char *avjFile) { return; } - extData = _vm->_game->loadExtData(id, 0, 0); - Common::MemoryReadStream mapData(extData, 4294967295U); + Resource *resource = _vm->_game->_resources->getResource(id); + if (!resource) + return; + + Common::SeekableReadStream &mapData = *resource->stream(); _widthByte = mapData.readByte(); if (_widthByte == 4) { @@ -99,7 +102,7 @@ void Map_v4::loadMapObjects(const char *avjFile) { passPos = mapData.pos(); mapData.skip(_mapWidth * _mapHeight); - if (*extData == 1) + if (resource->getData()[0] == 1) wayPointsCount = _wayPointsCount = 40; else wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount; @@ -146,11 +149,11 @@ void Map_v4::loadMapObjects(const char *avjFile) { for (int i = 0; i < _vm->_goblin->_gobsCount; i++) loadGoblinStates(mapData, i); - _vm->_goblin->_soundSlotsCount = _vm->_inter->load16(); + _vm->_goblin->_soundSlotsCount = _vm->_game->_script->readInt16(); for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++) _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1); - delete[] extData; + delete resource; } } // End of namespace Gob diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 9111db9121..695976da61 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -9,6 +9,7 @@ MODULE_OBJS := \ draw_bargon.o \ draw_fascin.o \ driver_vga.o \ + expression.o \ game.o \ game_v1.o \ game_v2.o \ @@ -43,12 +44,12 @@ MODULE_OBJS := \ mult_v1.o \ mult_v2.o \ palanim.o \ - parse.o \ - parse_v1.o \ - parse_v2.o \ + resources.o \ scenery.o \ scenery_v1.o \ scenery_v2.o \ + script.o \ + totfile.o \ util.o \ variables.o \ video.o \ diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index 11ef43280f..5aec5ff76e 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -31,6 +31,7 @@ #include "gob/util.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/script.h" #include "gob/palanim.h" #include "gob/scenery.h" #include "gob/video.h" @@ -85,7 +86,6 @@ Mult::Mult(GobEngine *vm) : _vm(vm) { _palFadingGreen = 0; _palFadingBlue = 0; - _animSurf = 0; _animLeft = 0; _animTop = 0; _animWidth = 0; @@ -111,7 +111,7 @@ Mult::~Mult() { void Mult::initAll(void) { _objects = 0; - _animSurf = 0; + _animSurf.reset(); _renderData = 0; _vm->_scenery->init(); @@ -145,7 +145,7 @@ void Mult::freeMult() { _renderObjs = 0; _orderArray = 0; - _animSurf = 0; + _animSurf.reset(); _vm->_draw->freeSprite(22); } @@ -237,7 +237,7 @@ void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape, _animArrayData = 0; _orderArray = 0; - _animSurf = 0; + _animSurf.reset(); _vm->_draw->freeSprite(22); _animDataAllocated = false; @@ -252,8 +252,6 @@ void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape, } void Mult::drawText(bool &stop, bool &stopNoClear) { - byte *savedIP; - int16 cmd; for (_index = 0; _index < _multData->textKeysCount; _index++) { if (_multData->textKeys[_index].frame != _frame) @@ -266,9 +264,10 @@ void Mult::drawText(bool &stop, bool &stopNoClear) { stopNoClear = true; _multData->frameStart = 0; } else if (cmd == 3) { + warning("Mult::drawText, cmd == 3"); stop = false; - savedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = _multData->textKeys[_index].script; +// uint32 startPos = _vm->_game->_script->pos(); +// _vm->_global->_inter_execPtr = _multData->textKeys[_index].script; } } } diff --git a/engines/gob/mult.h b/engines/gob/mult.h index 3bb3af17b3..7766508922 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -232,7 +232,7 @@ public: int8 *_orderArray; - SurfaceDesc::Ptr _animSurf; + SurfaceDescPtr _animSurf; int16 _animLeft; int16 _animTop; int16 _animWidth; diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index a369e7d297..1bb162c789 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -1,4 +1,4 @@ -/* ScummVM - Graphic Adventure Engine +/* 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 @@ -32,6 +32,8 @@ #include "gob/util.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/inter.h" #include "gob/scenery.h" @@ -41,9 +43,6 @@ Mult_v1::Mult_v1(GobEngine *vm) : Mult(vm) { } void Mult_v1::loadMult(int16 resId) { - uint32 dataSize; - byte *extData; - debugC(4, kDebugGameFlow, "Loading mult"); _multData = new Mult_Data; @@ -52,8 +51,11 @@ void Mult_v1::loadMult(int16 resId) { _multData->sndSlotsCount = 0; _multData->frameStart = 0; - extData = (byte *) _vm->_game->loadExtData(resId, 0, 0, &dataSize); - Common::MemoryReadStream data(extData, dataSize); + Resource *resource = _vm->_game->_resources->getResource(resId); + if (!resource) + return; + + Common::SeekableReadStream &data = *resource->stream(); _multData->staticCount = data.readSByte() + 1; _multData->animCount = data.readSByte() + 1; @@ -157,15 +159,14 @@ void Mult_v1::loadMult(int16 resId) { switch (_multData->sndKeys[i].cmd) { case 1: case 4: - _multData->sndKeys[i].resId = - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _multData->sndKeys[i].resId = _vm->_game->_script->peekUint16(); for (j = 0; j < i; j++) { if (_multData->sndKeys[i].resId == _multData->sndKeys[j].resId) { _multData->sndKeys[i].soundIndex = _multData->sndKeys[j].soundIndex; - _vm->_global->_inter_execPtr += 2; + _vm->_game->_script->skip(2); break; } } @@ -178,16 +179,16 @@ void Mult_v1::loadMult(int16 resId) { break; case 3: - _vm->_global->_inter_execPtr += 6; + _vm->_game->_script->skip(6); break; case 5: - _vm->_global->_inter_execPtr += _multData->sndKeys[i].freq * 2; + _vm->_game->_script->skip(_multData->sndKeys[i].freq * 2); break; } } - delete[] extData; + delete resource; } void Mult_v1::freeMultKeys() { @@ -234,7 +235,7 @@ void Mult_v1::freeMultKeys() { _animArrayY = 0; _animArrayData = 0; - _animSurf = 0; + _animSurf.reset(); _vm->_draw->freeSprite(22); _animDataAllocated = false; @@ -319,8 +320,8 @@ void Mult_v1::playMultInit() { 320, 200, 0); _vm->_draw->_spritesArray[22] = _animSurf; - _vm->_video->drawSprite(_vm->_draw->_backSurface, - _animSurf, 0, 0, 319, 199, 0, 0, 0); + _vm->_video->drawSprite(*_vm->_draw->_backSurface, + *_animSurf, 0, 0, 319, 199, 0, 0, 0); _animDataAllocated = true; } else @@ -349,7 +350,7 @@ void Mult_v1::drawStatics(bool &stop) { _vm->_scenery->_curStatic = _multData->staticIndices[_vm->_scenery->_curStatic]; _vm->_scenery->renderStatic(_vm->_scenery->_curStatic, _vm->_scenery->_curStaticLayer); - _vm->_video->drawSprite(_vm->_draw->_backSurface, _animSurf, + _vm->_video->drawSprite(*_vm->_draw->_backSurface, *_animSurf, 0, 0, 319, 199, 0, 0, 0); } } diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 1181862039..135c50c92c 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -32,9 +32,10 @@ #include "gob/util.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/goblin.h" #include "gob/inter.h" -#include "gob/parse.h" #include "gob/scenery.h" #include "gob/video.h" #include "gob/videoplayer.h" @@ -60,11 +61,9 @@ void Mult_v2::loadMult(int16 resId) { int8 index; uint8 staticCount; uint8 animCount; - uint32 dataSize; - byte *extData; bool hasImds; - index = (resId & 0x8000) ? *_vm->_global->_inter_execPtr++ : 0; + index = (resId & 0x8000) ? _vm->_game->_script->readByte() : 0; resId &= 0x7FFF; debugC(4, kDebugGameFlow, "Loading mult %d", index); @@ -80,8 +79,11 @@ void Mult_v2::loadMult(int16 resId) { _multData->sndSlotsCount = 0; _multData->frameStart = 0; - extData = (byte *) _vm->_game->loadExtData(resId, 0, 0, &dataSize); - Common::MemoryReadStream data(extData, dataSize); + Resource *resource = _vm->_game->_resources->getResource(resId); + if (!resource) + return; + + Common::SeekableReadStream &data = *resource->stream(); _multData->staticCount = staticCount = data.readSByte(); _multData->animCount = animCount = data.readSByte(); @@ -206,14 +208,13 @@ void Mult_v2::loadMult(int16 resId) { switch (_multData->sndKeys[i].cmd) { case 1: case 4: - _multData->sndKeys[i].resId = - READ_LE_UINT16(_vm->_global->_inter_execPtr); + _multData->sndKeys[i].resId = _vm->_game->_script->peekUint16(); for (j = 0; j < i; j++) { if (_multData->sndKeys[j].resId == _multData->sndKeys[i].resId) { _multData->sndKeys[i].soundIndex = _multData->sndKeys[j].soundIndex; - _vm->_global->_inter_execPtr += 2; + _vm->_game->_script->skip(2); break; } } @@ -226,7 +227,7 @@ void Mult_v2::loadMult(int16 resId) { } break; case 3: - _vm->_global->_inter_execPtr += 4; + _vm->_game->_script->skip(4); break; case -1: @@ -244,17 +245,17 @@ void Mult_v2::loadMult(int16 resId) { if (hasImds) loadImds(data); - delete[] extData; + delete resource; } void Mult_v2::loadImds(Common::SeekableReadStream &data) { int16 size; - size = _vm->_inter->load16(); - _multData->execPtr = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += size * 2; + size = _vm->_game->_script->readInt16(); + _multData->execPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos(); + _vm->_game->_script->skip(size * 2); - if (_vm->_game->_totFileData[0x29] < 51) + if (_vm->_game->_script->getVersionMinor() < 3) return; size = data.readSint16LE(); @@ -263,13 +264,27 @@ void Mult_v2::loadImds(Common::SeekableReadStream &data) { data.read(_multData->somepointer10, size * 20); } - size = _vm->_inter->load16(); + size = _vm->_game->_script->readInt16(); if (size <= 0) return; _multData->imdFiles = new char[size * 14]; - memcpy(_multData->imdFiles, _vm->_global->_inter_execPtr, size * 14); - _vm->_global->_inter_execPtr += size * 14; + memcpy(_multData->imdFiles, + _vm->_game->_script->getData() + _vm->_game->_script->pos(), size * 14); + + // WORKAROUND: The Windows version of Lost in Time has VMD not IMD files, + // but they are still referenced as IMD. + if ((_vm->getGameType() == kGameTypeLostInTime) && + (_vm->getPlatform() == Common::kPlatformWindows)) { + + for (int i = 0; i < size; i++) { + char *dot = strrchr(_multData->imdFiles + (i * 14), '.'); + if (dot) + *dot = '\0'; + } + } + + _vm->_game->_script->skip(size * 14); data.seek(2, SEEK_CUR); for (int i = 0; i < 4; i++) { _multData->imdKeysCount[i] = data.readSint16LE(); @@ -382,14 +397,16 @@ void Mult_v2::multSub(uint16 multIndex) { if (multIndex > 7) error("Multindex out of range"); + _vm->_util->notifyNewAnim(); + debugC(4, kDebugGameFlow, "Sub mult %d", multIndex); _multData = _multDatas[multIndex]; if (!_multData) { - _vm->_parse->parseValExpr(); - _vm->_parse->parseValExpr(); - _vm->_parse->parseValExpr(); - _vm->_parse->parseValExpr(); + _vm->_game->_script->readValExpr(); + _vm->_game->_script->readValExpr(); + _vm->_game->_script->readValExpr(); + _vm->_game->_script->readValExpr(); return; } @@ -412,9 +429,9 @@ void Mult_v2::multSub(uint16 multIndex) { _multData->animObjs[index][0] = flags; for (int i = 1; i < 4; i++) - _multData->animObjs[index][i] = _vm->_parse->parseValExpr(); + _multData->animObjs[index][i] = _vm->_game->_script->readValExpr(); - expr = _vm->_parse->parseValExpr(); + expr = _vm->_game->_script->readValExpr(); _multData->animKeysFrames[index] = expr; _multData->animKeysStartFrames[index] = expr; @@ -565,8 +582,8 @@ void Mult_v2::playMultInit() { _vm->_draw->initSpriteSurf(22, width, height, 0); _animSurf = _vm->_draw->_spritesArray[22]; - _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], - _vm->_draw->_spritesArray[22], 0, 0, + _vm->_video->drawSprite(*_vm->_draw->_spritesArray[21], + *_vm->_draw->_spritesArray[22], 0, 0, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); for (_counter = 0; _counter < _objCount; _counter++) @@ -622,8 +639,8 @@ void Mult_v2::drawStatics(bool &stop) { _vm->_scenery->_curStatic = -1; } - _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], - _vm->_draw->_spritesArray[22], 0, 0, + _vm->_video->drawSprite(*_vm->_draw->_spritesArray[21], + *_vm->_draw->_spritesArray[22], 0, 0, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); } } @@ -856,7 +873,7 @@ void Mult_v2::animate() { animObj.newBottom = MAX(animObj.lastBottom, _vm->_scenery->_toRedrawBottom); - if ((_vm->_game->_totFileData[0x29] > 50) && + if ((_vm->_game->_script->getVersionMinor() > 2) && (animObj.newLeft == animObj.lastLeft) && (animObj.newTop == animObj.lastTop) && (animObj.newRight == animObj.lastRight) && diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp deleted file mode 100644 index 81a7da6389..0000000000 --- a/engines/gob/parse.cpp +++ /dev/null @@ -1,476 +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 "gob/gob.h" -#include "gob/parse.h" -#include "gob/global.h" -#include "gob/game.h" -#include "gob/inter.h" - -namespace Gob { - -Parse::Parse(GobEngine *vm) : _vm(vm) { -} - -int32 Parse::encodePtr(byte *ptr, int type) { - int32 offset = 0; - - switch (type) { - case kExecPtr: - offset = ptr - _vm->_game->_totFileData; - break; - case kInterVar: - offset = ptr - ((byte *) _vm->_inter->_variables->getAddressOff8(0)); - break; - case kResStr: - offset = ptr - ((byte *) _vm->_global->_inter_resStr); - break; - default: - error("Parse::encodePtr(): Unknown pointer type"); - } - assert((offset & 0xF0000000) == 0); - return (type << 28) | offset; -} - -byte *Parse::decodePtr(int32 n) { - byte *ptr; - - switch (n >> 28) { - case kExecPtr: - ptr = _vm->_game->_totFileData; - break; - case kInterVar: - ptr = (byte *) _vm->_inter->_variables->getAddressOff8(0); - break; - case kResStr: - ptr = (byte *) _vm->_global->_inter_resStr; - break; - default: - error("Parse::decodePtr(): Unknown pointer type"); - } - return ptr + (n & 0x0FFFFFFF); -} - -void Parse::skipExpr(char stopToken) { - int16 dimCount; - byte operation; - int16 num; - int16 dim; - - num = 0; - while (true) { - operation = *_vm->_global->_inter_execPtr++; - - if ((operation >= 14) && (operation <= OP_FUNC)) { - switch (operation) { - case 14: - _vm->_global->_inter_execPtr += 4; - if (*_vm->_global->_inter_execPtr == 97) - _vm->_global->_inter_execPtr++; - break; - - case OP_LOAD_VAR_INT16: - case OP_LOAD_VAR_INT8: - case OP_LOAD_IMM_INT16: - case 23: - case 24: - _vm->_global->_inter_execPtr += 2; - break; - - case OP_LOAD_IMM_INT32: - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT8: - _vm->_global->_inter_execPtr += 1; - break; - - case OP_LOAD_IMM_STR: - _vm->_global->_inter_execPtr += - strlen((char *) _vm->_global->_inter_execPtr) + 1; - break; - - case OP_LOAD_VAR_STR: - _vm->_global->_inter_execPtr += 2; - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - skipExpr(OP_END_MARKER); - } - break; - - case 15: - _vm->_global->_inter_execPtr += 2; - - case OP_ARRAY_UINT8: - case OP_ARRAY_UINT32: - case OP_ARRAY_UINT16: - case OP_ARRAY_STR: - dimCount = _vm->_global->_inter_execPtr[2]; - // skip header and dimensions - _vm->_global->_inter_execPtr += 3 + dimCount; - // skip indices - for (dim = 0; dim < dimCount; dim++) - skipExpr(OP_END_MARKER); - - if ((operation == OP_ARRAY_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - skipExpr(OP_END_MARKER); - } - break; - - case OP_FUNC: - _vm->_global->_inter_execPtr++; - skipExpr(OP_END_EXPR); - } - continue; - } // if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) - - if (operation == OP_BEGIN_EXPR) { - num++; - continue; - } - - if ((operation == OP_NOT) || ((operation >= OP_NEG) && (operation <= 8))) - continue; - - if ((operation >= OP_OR) && (operation <= OP_NEQ)) - continue; - - if (operation == OP_END_EXPR) - num--; - - if (operation != stopToken) - continue; - - if ((stopToken != OP_END_EXPR) || (num < 0)) - return; - } -} - -void Parse::printExpr(char stopToken) { - // Expression printing disabled by default - return; - - byte *savedPos = _vm->_global->_inter_execPtr; - printExpr_internal(stopToken); - - // restore IP to start of expression - _vm->_global->_inter_execPtr = savedPos; -} - -void Parse::printExpr_internal(char stopToken) { - int16 dimCount; - byte operation; - int16 num; - int16 dim; - byte *arrDesc; - byte func; - - num = 0; - while (true) { - operation = *_vm->_global->_inter_execPtr++; - - if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) { - // operands - - switch (operation) { - case OP_LOAD_VAR_INT16: // int16 variable load - debugN(5, "var16_%d", _vm->_inter->load16()); - break; - - case OP_LOAD_VAR_INT8: // int8 variable load: - debugN(5, "var8_%d", _vm->_inter->load16()); - break; - - case OP_LOAD_IMM_INT32: // int32/uint32 immediate - debugN(5, "%d", READ_LE_UINT32(_vm->_global->_inter_execPtr)); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: // int16 immediate - debugN(5, "%d", _vm->_inter->load16()); - break; - - case OP_LOAD_IMM_INT8: // int8 immediate - debugN(5, "%d", (int8) *_vm->_global->_inter_execPtr++); - break; - - case OP_LOAD_IMM_STR: // string immediate - debugN(5, "\42%s\42", _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += - strlen((char *) _vm->_global->_inter_execPtr) + 1; - break; - - case 23: // uint32 variable load - case 24: // uint32 variable load as uint16 - debugN(5, "var_%d", _vm->_inter->load16()); - break; - - case OP_LOAD_VAR_STR: // string variable load - debugN(5, "(&var_%d)", _vm->_inter->load16()); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - debugN(5, "{"); - printExpr_internal(OP_END_MARKER); // this also prints the closing } - } - break; - - case OP_ARRAY_UINT8: // uint8 array access - case OP_ARRAY_UINT32: // uint32 array access - case OP_ARRAY_UINT16: // uint16 array access - case OP_ARRAY_STR: // string array access - debugN(5, "\n"); - if (operation == OP_ARRAY_STR) - debugN(5, "(&"); - - debugN(5, "var_%d[", _vm->_inter->load16()); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - for (dim = 0; dim < dimCount; dim++) { - printExpr_internal(OP_END_MARKER); - debugN(5, " of %d", (int16) arrDesc[dim]); - if (dim != dimCount - 1) - debugN(5, ","); - } - debugN(5, "]"); - if (operation == OP_ARRAY_STR) - debugN(5, ")"); - - if ((operation == OP_ARRAY_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - debugN(5, "{"); - printExpr_internal(OP_END_MARKER); // this also prints the closing } - } - break; - - case OP_FUNC: // function - func = *_vm->_global->_inter_execPtr++; - if (func == FUNC_SQR) - debugN(5, "sqr("); - else if (func == FUNC_RAND) - debugN(5, "rand("); - else if (func == FUNC_ABS) - debugN(5, "abs("); - else if ((func == FUNC_SQRT1) || (func == FUNC_SQRT2) || (func == FUNC_SQRT3)) - debugN(5, "sqrt("); - else - debugN(5, "id("); - printExpr_internal(OP_END_EXPR); - break; - } - continue; - } // if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) - - // operators - switch (operation) { - case OP_BEGIN_EXPR: - debugN(5, "("); - break; - - case OP_NOT: - debugN(5, "!"); - break; - - case OP_END_EXPR: - debugN(5, ")"); - break; - - case OP_NEG: - debugN(5, "-"); - break; - - case OP_ADD: - debugN(5, "+"); - break; - - case OP_SUB: - debugN(5, "-"); - break; - - case OP_BITOR: - debugN(5, "|"); - break; - - case OP_MUL: - debugN(5, "*"); - break; - - case OP_DIV: - debugN(5, "/"); - break; - - case OP_MOD: - debugN(5, "%%"); - break; - - case OP_BITAND: - debugN(5, "&"); - break; - - case OP_OR: - debugN(5, "||"); - break; - - case 31: - debugN(5, "&&"); - break; - - case OP_LESS: - debugN(5, "<"); - break; - - case OP_LEQ: - debugN(5, "<="); - break; - - case OP_GREATER: - debugN(5, ">"); - break; - - case OP_GEQ: - debugN(5, ">="); - break; - - case OP_EQ: - debugN(5, "=="); - break; - - case OP_NEQ: - debugN(5, "!="); - break; - - case 99: - debugN(5, "\n"); - break; - - case OP_END_MARKER: - debugN(5, "}"); - if (stopToken != OP_END_MARKER) { - debugN(5, "Closing paren without opening?"); - } - break; - - default: - debugN(5, "<%d>", (int16) operation); - error("Parse::printExpr(): invalid operator in expression"); - break; - } - - if (operation == OP_BEGIN_EXPR) { - num++; - continue; - } - - if ((operation == OP_NOT) || ((operation >= OP_NEG) && (operation <= 8))) - continue; - - if ((operation >= OP_OR) && (operation <= OP_NEQ)) - continue; - - if (operation == OP_END_EXPR) - num--; - - if (operation == stopToken) { - if ((stopToken != OP_END_EXPR) || (num < 0)) { - return; - } - } - } -} - - -void Parse::printVarIndex() { - byte *arrDesc; - int16 dim; - int16 dimCount; - int16 operation; - int16 temp; - - byte *pos = _vm->_global->_inter_execPtr; - - operation = *_vm->_global->_inter_execPtr++; - switch (operation) { - case 23: - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - debugN(5, "&var_%d", temp); - if ((operation == OP_LOAD_VAR_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - debugN(5, "+"); - printExpr(OP_END_MARKER); - } - break; - - case OP_ARRAY_UINT32: - case OP_ARRAY_STR: - debugN(5, "&var_%d[", _vm->_inter->load16()); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - for (dim = 0; dim < dimCount; dim++) { - printExpr(OP_END_MARKER); - debugN(5, " of %d", (int16) arrDesc[dim]); - if (dim != dimCount - 1) - debugN(5, ","); - } - debugN(5, "]"); - - if ((operation == OP_ARRAY_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - debugN(5, "+"); - printExpr(OP_END_MARKER); - } - break; - - default: - debugN(5, "var_0"); - break; - } - debugN(5, "\n"); - _vm->_global->_inter_execPtr = pos; - return; -} - -int Parse::cmpHelper(byte *operPtr, int32 *valPtr) { - byte var_C = operPtr[-3]; - int cmpTemp = 0; - if (var_C == OP_LOAD_IMM_INT16) { - cmpTemp = (int)valPtr[-3] - (int)valPtr[-1]; - } else if (var_C == OP_LOAD_IMM_STR) { - if ((char *)decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *)decodePtr(valPtr[-3])); - valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - cmpTemp = strcmp(_vm->_global->_inter_resStr, (char *)decodePtr(valPtr[-1])); - } - - return cmpTemp; -} - - -} // End of namespace Gob diff --git a/engines/gob/parse.h b/engines/gob/parse.h deleted file mode 100644 index d72b4d5c2b..0000000000 --- a/engines/gob/parse.h +++ /dev/null @@ -1,148 +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$ - * - */ - -#ifndef GOB_PARSE_H -#define GOB_PARSE_H - -namespace Gob { - -enum { - OP_NEG = 1, - OP_ADD = 2, - OP_SUB = 3, - OP_BITOR = 4, - OP_MUL = 5, - OP_DIV = 6, - OP_MOD = 7, - OP_BITAND = 8, - OP_BEGIN_EXPR = 9, - OP_END_EXPR = 10, - OP_NOT = 11, - - OP_END_MARKER = 12, // Marks end of an array or string - - - OP_ARRAY_UINT8 = 16, - - OP_LOAD_VAR_INT16 = 17, - OP_LOAD_VAR_INT8 = 18, - OP_LOAD_IMM_INT32 = 19, - OP_LOAD_IMM_INT16 = 20, - OP_LOAD_IMM_INT8 = 21, - OP_LOAD_IMM_STR = 22, - - OP_LOAD_VAR_UINT32 = 23, // ??? - OP_LOAD_VAR_UINT32_AS_UINT16 = 24, // ??? - OP_LOAD_VAR_STR = 25, - - OP_ARRAY_UINT32 = 26, - OP_ARRAY_UINT16 = 27, - OP_ARRAY_STR = 28, - - OP_FUNC = 29, - - OP_OR = 30, // Logical OR - OP_AND = 31, // Logical AND - OP_LESS = 32, - OP_LEQ = 33, - OP_GREATER = 34, - OP_GEQ = 35, - OP_EQ = 36, - OP_NEQ = 37 -}; - -enum { - FUNC_SQRT1 = 0, - FUNC_SQRT2 = 1, - FUNC_SQRT3 = 6, - - FUNC_SQR = 5, - FUNC_ABS = 7, - FUNC_RAND = 10 -}; - -enum { - // FIXME: The following two 'truth values' are stored inside the list - // of "operators". So they somehow coincide with OP_LOAD_VAR_UINT32 - // and OP_LOAD_VAR_UINT32_AS_UINT16. I haven't yet quite understood - // how, resp. what that means. You have been warned. - GOB_TRUE = 24, - GOB_FALSE = 23 -}; - -class Parse { -public: - void skipExpr(char stopToken); - void printExpr(char stopToken); - void printVarIndex(void); - virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0) = 0; - virtual int16 parseValExpr(byte stopToken = 99) = 0; - virtual int16 parseExpr(byte stopToken, byte *resultPtr) = 0; - - Parse(GobEngine *vm); - virtual ~Parse() {} - -protected: - enum PointerType { - kExecPtr = 0, - kInterVar = 1, - kResStr = 2 - }; - - GobEngine *_vm; - - int32 encodePtr(byte *ptr, int type); - byte *decodePtr(int32 n); - - void printExpr_internal(char stopToken); - - int cmpHelper(byte *operPtr, int32 *valPtr); -}; - -class Parse_v1 : public Parse { -public: - Parse_v1(GobEngine *vm); - virtual ~Parse_v1() {} - - virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0); - virtual int16 parseValExpr(byte stopToken = 99); - virtual int16 parseExpr(byte stopToken, byte *resultPtr); -}; - -class Parse_v2 : public Parse_v1 { -public: - Parse_v2(GobEngine *vm); - virtual ~Parse_v2() {} - - virtual int16 getOffset(int16 arg_0, byte arg_2, uint32 arg_3, uint16 arg_7, uint16 arg_9); - - virtual int16 parseVarIndex(uint16 *arg_0 = 0, uint16 *arg_4 = 0); - virtual int16 parseValExpr(byte stopToken = 99); - virtual int16 parseExpr(byte stopToken, byte *resultPtr); -}; - -} // End of namespace Gob - -#endif // GOB_PARSE_H diff --git a/engines/gob/parse_v1.cpp b/engines/gob/parse_v1.cpp deleted file mode 100644 index c993d6ca70..0000000000 --- a/engines/gob/parse_v1.cpp +++ /dev/null @@ -1,834 +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 "gob/gob.h" -#include "gob/parse.h" -#include "gob/global.h" -#include "gob/inter.h" - -namespace Gob { - -Parse_v1::Parse_v1(GobEngine *vm) : Parse(vm) { -} - -int16 Parse_v1::parseVarIndex(uint16 *arg_0, uint16 *arg_4) { - int16 temp2; - byte *arrDesc; - int16 dim; - int16 dimCount; - int16 operation; - int16 temp; - int16 offset; - int16 val; - - operation = *_vm->_global->_inter_execPtr++; - debugC(5, kDebugParser, "var parse = %d", operation); - switch (operation) { - case 23: - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - debugC(5, kDebugParser, "oper = %d", - (int16) *_vm->_global->_inter_execPtr); - - if ((operation == OP_LOAD_VAR_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - val = parseValExpr(OP_END_MARKER); - temp += val; - debugC(5, kDebugParser, "parse subscript = %d", val); - } - return temp; - - case OP_ARRAY_UINT32: - case OP_ARRAY_STR: - temp = _vm->_inter->load16() * 4; - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - offset *= 4; - if (operation != OP_ARRAY_STR) - return temp + offset; - - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - } - return offset * _vm->_global->_inter_animDataSize + temp; - - default: - return 0; - } -} - -int16 Parse_v1::parseValExpr(byte stopToken) { - int16 values[20]; - byte operStack[20]; - int16 *valPtr; - byte *operPtr; - byte *arrDesc; - byte operation; - int16 temp2; - int16 dim; - int16 dimCount; - int16 temp; - int16 offset; - int16 stkPos; - int16 brackPos; - static int16 flag = 0; - int16 oldflag; - - oldflag = flag; - if (flag == 0) { - flag = 1; - printExpr(stopToken); - } - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (true) { - stkPos++; - operPtr++; - valPtr++; - - operation = *_vm->_global->_inter_execPtr++; - if ((operation >= OP_LOAD_IMM_INT32) && (operation <= OP_FUNC)) { - *operPtr = OP_LOAD_IMM_INT16; - switch (operation) { - case OP_LOAD_IMM_INT32: - *valPtr = READ_LE_UINT32(_vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *valPtr = _vm->_inter->load16(); - break; - - case 23: - *valPtr = (uint16) VAR(_vm->_inter->load16()); - break; - - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(temp); - break; - - case OP_ARRAY_UINT32: - case OP_ARRAY_STR: - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - if (operation == OP_ARRAY_UINT32) { - *valPtr = (uint16) VAR(temp + offset); - } else { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * - _vm->_global->_inter_animDataSize + temp2); - } - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - if (operation == FUNC_SQR) { - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - } else if (operation == FUNC_ABS) { - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - } else if (operation == FUNC_RAND) { - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - } - *valPtr = _vm->_global->_inter_resVal; - break; - - } // switch - if ((stkPos > 0) && (operPtr[-1] == OP_NEG)) { - stkPos--; - operPtr--; - valPtr--; - operPtr[0] = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } - - if ((stkPos > 0) && (operPtr[-1] >= OP_MUL) && (operPtr[-1] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - switch (operPtr[1]) { - case OP_MUL: - valPtr[0] *= valPtr[2]; - break; - - case OP_DIV: - valPtr[0] /= valPtr[2]; - break; - - case OP_MOD: - valPtr[0] %= valPtr[2]; - break; - - case OP_BITAND: - valPtr[0] &= valPtr[2]; - break; - } - } // if ((stkPos > 0) && (cmdPtr[-1] >= OP_MUL) && (cmdPtr[-1] <= OP_BITAND)) - continue; - } - - if ((operation >= OP_NEG) && (operation <= OP_BEGIN_EXPR)) { - *operPtr = operation; - continue; - } - - while (stkPos >= 2) { - if (operPtr[-2] == OP_BEGIN_EXPR) { - stkPos--; - operPtr--; - valPtr--; - - operPtr[-1] = operPtr[0]; - valPtr[-1] = valPtr[0]; - if ((stkPos > 1) && (operPtr[-2] == OP_NEG)) { - valPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - } - - if ((stkPos > 2) && (operPtr[-2] >= OP_MUL) && (operPtr[-2] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_MUL: - operPtr[-1] *= operPtr[1]; - break; - - case OP_DIV: - operPtr[-1] /= operPtr[1]; - break; - - case OP_MOD: - operPtr[-1] %= operPtr[1]; - break; - - case OP_BITAND: - operPtr[-1] &= operPtr[1]; - break; - } - } - if (operation == OP_END_EXPR) - break; - } // operPtr[-2] == OP_BEGIN_EXPR - - for (brackPos = (stkPos - 2); (brackPos > 0) && - (operStack[brackPos] < OP_OR) && (operStack[brackPos] != OP_BEGIN_EXPR); - brackPos--) - ; - - if ((operStack[brackPos] >= OP_OR) || (operStack[brackPos] == OP_BEGIN_EXPR)) - brackPos++; - - if ((operPtr[-2] < 2) || (operPtr[-2] > 8)) - break; - - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_ADD: - values[brackPos] += valPtr[1]; - continue; - case OP_SUB: - values[brackPos] -= valPtr[1]; - continue; - case OP_BITOR: - values[brackPos] |= valPtr[1]; - continue; - case OP_MUL: - valPtr[-1] *= valPtr[1]; - continue; - case OP_DIV: - valPtr[-1] /= valPtr[1]; - continue; - case OP_MOD: - valPtr[-1] %= valPtr[1]; - continue; - case OP_BITAND: - valPtr[-1] &= valPtr[1]; - continue; - } - } - - if (operation != OP_END_EXPR) { - if (operation != stopToken) - debugC(5, kDebugParser, "stoptoken error: %d != %d", - operation, stopToken); - - flag = oldflag; - return values[0]; - } - - stkPos--; - operPtr--; - valPtr--; - } -} - -int16 Parse_v1::parseExpr(byte stopToken, byte *arg_2) { - int32 values[20]; - byte operStack[20]; - int32 prevPrevVal; - int32 prevVal; - int32 curVal; - int32 *valPtr; - byte *operPtr; - byte *arrDescPtr; - byte operation; - int16 dimCount; - int16 temp; - int16 temp2; - uint16 offset; - int16 dim; - bool var_1A; - int16 stkPos; - int16 brackStart; - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (true) { - stkPos++; - operPtr++; - valPtr++; - operation = *_vm->_global->_inter_execPtr++; - if ((operation >= OP_LOAD_IMM_INT32) && (operation <= OP_FUNC)) { - switch (operation) { - case OP_LOAD_IMM_INT32: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_LE_UINT32(_vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_inter->load16(); - break; - - case OP_LOAD_IMM_STR: - *operPtr = OP_LOAD_IMM_STR; - *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); - _vm->_global->_inter_execPtr += - strlen((char *) _vm->_global->_inter_execPtr) + 1; - break; - - case 23: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = VAR(_vm->_inter->load16()); - break; - - case OP_LOAD_VAR_STR: - *operPtr = OP_LOAD_IMM_STR; - temp = _vm->_inter->load16() * 4; - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(temp), - kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(temp); - } - break; - - case OP_ARRAY_UINT32: - case OP_ARRAY_STR: - *operPtr = operation - 6; - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDescPtr = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - dim = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = offset * arrDescPtr[dim] + temp2; - } - - if (operation == OP_ARRAY_UINT32) { - *valPtr = VAR(temp + offset); - break; - } - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( - temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), - kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(temp * 4 + - offset * 4 * _vm->_global->_inter_animDataSize + temp2); - } - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - switch (operation) { - case FUNC_SQR: - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - break; - - case FUNC_SQRT1: - case FUNC_SQRT2: - case FUNC_SQRT3: - curVal = 1; - prevVal = 1; - - do { - prevPrevVal = prevVal; - prevVal = curVal; - curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; - } while ((curVal != prevVal) && (curVal != prevPrevVal)); - _vm->_global->_inter_resVal = curVal; - break; - - case FUNC_RAND: - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - break; - - case FUNC_ABS: - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - break; - } - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_global->_inter_resVal; - } - - if ((stkPos > 0) && ((operPtr[-1] == OP_NEG) || (operPtr[-1] == OP_NOT))) { - stkPos--; - operPtr--; - valPtr--; - - if (*operPtr == OP_NEG) { - *operPtr = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } else if (*operPtr == OP_NOT) { - if (operPtr[1] == GOB_FALSE) - *operPtr = GOB_TRUE; - else - *operPtr = GOB_FALSE; - } - } - - if (stkPos <= 0) - continue; - - switch (operPtr[-1]) { - case OP_ADD: - if (operPtr[-2] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-2]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-2])); - valPtr[-2] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[0])); - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - break; - - case OP_MUL: - valPtr[-2] *= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-2] /= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-2] %= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-2] &= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } - continue; - } // (op >= OP_LOAD_IMM_INT32) && (op <= OP_FUNC) - - if ((operation == stopToken) || (operation == OP_OR) || - (operation == OP_AND) || (operation == OP_END_EXPR)) { - while (stkPos >= 2) { - var_1A = false; - if ((operPtr[-2] == OP_BEGIN_EXPR) && - ((operation == OP_END_EXPR) || (operation == stopToken))) { - operPtr[-2] = operPtr[-1]; - if ((operPtr[-2] == OP_LOAD_IMM_INT16) || (operPtr[-2] == OP_LOAD_IMM_STR)) - valPtr[-2] = valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - - if (stkPos > 1) { - if (operPtr[-2] == OP_NEG) { - operPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - stkPos--; - operPtr--; - valPtr--; - } else if (operPtr[-2] == OP_NOT) { - if (operPtr[-1] == GOB_FALSE) - operPtr[-2] = GOB_TRUE; - else - operPtr[-2] = GOB_FALSE; - - stkPos--; - operPtr--; - valPtr--; - } - } // stkPos > 1 - - if (stkPos > 2) { - switch (operPtr[-2]) { - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } // switch - } // stkPos > 2 - - if (operation != stopToken) - break; - } // if ((operPtr[-2] == OP_BEGIN_EXPR) && ...) - - for (brackStart = (stkPos - 2); (brackStart > 0) && - (operStack[brackStart] < OP_OR) && (operStack[brackStart] != OP_BEGIN_EXPR); - brackStart--) - ; - - if ((operStack[brackStart] >= OP_OR) || (operStack[brackStart] == OP_BEGIN_EXPR)) - brackStart++; - - switch (operPtr[-2]) { - case OP_ADD: - if (operStack[brackStart] == OP_LOAD_IMM_INT16) { - values[brackStart] += valPtr[-1]; - } else if (operStack[brackStart] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[brackStart])); - values[brackStart] = - encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_SUB: - values[brackStart] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_BITOR: - values[brackStart] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_OR: - // (x OR false) == x - // (x OR true) == true - if (operPtr[-3] == GOB_FALSE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_AND: - // (x AND false) == false - // (x AND true) == x - if (operPtr[-3] == GOB_TRUE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LESS: - operPtr[-3] = (cmpHelper(operPtr, valPtr) < 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) <= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GREATER: - operPtr[-3] = (cmpHelper(operPtr, valPtr) > 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) >= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_EQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) == 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_NEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) != 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - default: - var_1A = true; - break; - } // switch - - if (var_1A) - break; - } // while (stkPos >= 2) - - if ((operation == OP_OR) || (operation == OP_AND)) { - if (operPtr[-1] == OP_LOAD_IMM_INT16) { - if (valPtr[-1] != 0) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - } - - if (((operation == OP_OR) && (operPtr[-1] == GOB_TRUE)) || - ((operation == OP_AND) && (operPtr[-1] == GOB_FALSE))) { - if ((stkPos > 1) && (operPtr[-2] == OP_BEGIN_EXPR)) { - skipExpr(OP_END_EXPR); - operPtr[-2] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else - skipExpr(stopToken); - - operation = _vm->_global->_inter_execPtr[-1]; - if ((stkPos > 0) && (operPtr[-1] == OP_NOT)) { - if (operPtr[0] == GOB_FALSE) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - - stkPos--; - operPtr--; - valPtr--; - } - } else - operPtr[0] = operation; - } else { - stkPos--; - operPtr--; - valPtr--; - } - - if (operation != stopToken) - continue; - - if (arg_2 != 0) - *arg_2 = operStack[0]; - - switch (operStack[0]) { - case OP_LOAD_IMM_INT16: - _vm->_global->_inter_resVal = values[0]; - break; - - case OP_LOAD_IMM_STR: - if ((char *) decodePtr(values[0]) != _vm->_global->_inter_resStr) - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[0])); - break; - - case OP_NOT: - if (arg_2 != 0) - *arg_2 ^= 1; - break; - - case 23: - case 24: - break; - - default: - _vm->_global->_inter_resVal = 0; - if (arg_2 != 0) - *arg_2 = OP_LOAD_IMM_INT16; - break; - } - return 0; - } // (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR) - - if (operation < OP_NEG || operation > OP_NOT) { - if (operation < OP_LESS || operation > OP_NEQ) - continue; - - if (stkPos > 2) { - if (operPtr[-2] == OP_ADD) { - if (operPtr[-3] == OP_LOAD_IMM_INT16) { - valPtr[-3] += valPtr[-1]; - } else if (operPtr[-3] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); - valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - } else if (operPtr[-2] == OP_SUB) { - valPtr[-3] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else if (operPtr[-2] == OP_BITOR) { - valPtr[-3] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - } - } - *operPtr = operation; - } -} - -} // End of namespace Gob diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp deleted file mode 100644 index e7f91650b5..0000000000 --- a/engines/gob/parse_v2.cpp +++ /dev/null @@ -1,1062 +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 "gob/gob.h" -#include "gob/parse.h" -#include "gob/global.h" -#include "gob/inter.h" - -namespace Gob { - -Parse_v2::Parse_v2(GobEngine *vm) : Parse_v1(vm) { -} - -int16 Parse_v2::parseVarIndex(uint16 *arg_0, uint16 *arg_4) { - int16 temp2; - byte *arrDesc; - int16 dim; - int16 dimCount; - int16 operation; - int16 temp; - int16 offset; - int16 val; - uint32 varPos = 0; - - operation = *_vm->_global->_inter_execPtr++; - - while ((operation == 14) || (operation == 15)) { - if (operation == 14) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - if (arg_0) - *arg_0 = READ_LE_UINT16(_vm->_global->_inter_execPtr); - if (arg_4) - *arg_4 = 14; - - _vm->_global->_inter_execPtr += 2; - - debugC(2, kDebugParser, "parseVarIndex: Prefix %d (%d)", varPos, operation); - - if (*_vm->_global->_inter_execPtr != 97) - return varPos; - - _vm->_global->_inter_execPtr++; - - } else if (operation == 15) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - uint16 var_0C = _vm->_inter->load16(); - if (arg_0) - *arg_0 = var_0C; - if (arg_4) - *arg_4 = 15; - - uint8 var_A = *_vm->_global->_inter_execPtr++; - - byte *var_12 = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += var_A; - - uint16 var_6 = 0; - - for (int i = 0; i < var_A; i++) { - temp2 = parseValExpr(OP_END_MARKER); - - int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); - - var_6 = var_6 * var_12[i] + ax; - } - - varPos += var_6 * var_0C * 4; - - debugC(2, kDebugParser, "parseVarIndex: Prefix %d (%d)", varPos, operation); - - if (*_vm->_global->_inter_execPtr != 97) - return varPos; - - _vm->_global->_inter_execPtr++; - } - - operation = *_vm->_global->_inter_execPtr++; - } - - if (arg_0) - *arg_0 = 0; - if (arg_4) - *arg_4 = operation; - - debugC(5, kDebugParser, "var parse = %d", operation); - switch (operation) { - case OP_ARRAY_UINT8: - case OP_ARRAY_UINT32: - case OP_ARRAY_UINT16: - case OP_ARRAY_STR: - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - if (operation == OP_ARRAY_UINT8) - return varPos + temp + offset; - if (operation == OP_ARRAY_UINT32) - return varPos + (temp + offset) * 4; - if (operation == OP_ARRAY_UINT16) - return varPos + (temp + offset) * 2; - temp *= 4; - offset *= 4; - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - } - return varPos + offset * _vm->_global->_inter_animDataSize + temp; - - case OP_LOAD_VAR_INT16: - return varPos + _vm->_inter->load16() * 2; - - case OP_LOAD_VAR_INT8: - return varPos + _vm->_inter->load16(); - - case 23: - case 24: - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - debugC(5, kDebugParser, "oper = %d", - (int16) *_vm->_global->_inter_execPtr); - if ((operation == OP_LOAD_VAR_STR) && (*_vm->_global->_inter_execPtr == 13)) { - _vm->_global->_inter_execPtr++; - val = parseValExpr(OP_END_MARKER); - temp += val; - debugC(5, kDebugParser, "parse subscript = %d", val); - } - return varPos + temp; - - default: - return 0; - } -} - -int16 Parse_v2::parseValExpr(byte stopToken) { - int16 values[20]; - byte operStack[20]; - int16 *valPtr; - byte *operPtr; - byte *arrDesc; - byte operation; - int16 temp2; - int16 dim; - int16 dimCount; - int16 temp; - int16 offset; - int16 stkPos; - int16 brackPos; - static int16 flag = 0; - int16 oldflag; - uint32 varPos = 0; - - memset(values, 0, 20 * sizeof(int16)); - - oldflag = flag; - if (flag == 0) { - flag = 1; - printExpr(stopToken); - } - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (1) { - operation = *_vm->_global->_inter_execPtr++; - - while ((operation == 14) || (operation == 15)) { - if (operation == 14) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - _vm->_global->_inter_execPtr += 3; - } else if (operation == 15) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - uint16 var_0C = _vm->_inter->load16(); - uint8 var_A = *_vm->_global->_inter_execPtr++; - - byte *var_12 = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += var_A; - - uint16 var_6 = 0; - - for (int i = 0; i < var_A; i++) { - temp2 = parseValExpr(OP_END_MARKER); - - int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); - - var_6 = var_6 * var_12[i] + ax; - } - - varPos += var_6 * var_0C * 4; - - _vm->_global->_inter_execPtr++; - } - - debugC(2, kDebugParser, "parseValExpr: Prefix %d (%d)", varPos, operation); - - operation = *_vm->_global->_inter_execPtr++; - } - - stkPos++; - operPtr++; - valPtr++; - - if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) { - *operPtr = OP_LOAD_IMM_INT16; - switch (operation) { - case OP_ARRAY_UINT8: - case OP_ARRAY_UINT32: - case OP_ARRAY_UINT16: - case OP_ARRAY_STR: - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDesc = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = arrDesc[dim] * offset + temp2; - } - if (operation == OP_ARRAY_UINT8) - *valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset); - else if (operation == OP_ARRAY_UINT32) - *valPtr = (uint16) READ_VARO_UINT32(varPos + temp * 4 + offset * 4); - else if (operation == OP_ARRAY_UINT16) - *valPtr = READ_VARO_UINT16(varPos + temp * 2 + offset * 2); - else if (operation == OP_ARRAY_STR) { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(varPos + temp * 4 + - offset * 4 * _vm->_global->_inter_animDataSize + temp2); - } - break; - - case OP_LOAD_VAR_INT16: - *valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2); - break; - - case OP_LOAD_VAR_INT8: - *valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16()); - break; - - case OP_LOAD_IMM_INT32: - *valPtr = (uint16) READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *valPtr = _vm->_inter->load16(); - break; - - case OP_LOAD_IMM_INT8: - *valPtr = (int8) *_vm->_global->_inter_execPtr++; - break; - - case 23: - *valPtr = (uint16) READ_VARO_UINT32(varPos + _vm->_inter->load16() * 4); - break; - - case 24: - *valPtr = READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4); - break; - - case OP_LOAD_VAR_STR: - temp = _vm->_inter->load16() * 4; - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *valPtr = READ_VARO_UINT8(varPos + temp); - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - if (operation == FUNC_SQR) { - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - } else if (operation == FUNC_ABS) { - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - } else if (operation == FUNC_RAND) { - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - } - *valPtr = _vm->_global->_inter_resVal; - break; - - } // switch - if ((stkPos > 0) && (operPtr[-1] == OP_NEG)) { - stkPos--; - operPtr--; - valPtr--; - operPtr[0] = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } - - if ((stkPos > 0) && (operPtr[-1] >= OP_MUL) && (operPtr[-1] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - switch (operPtr[1]) { - case OP_MUL: - valPtr[0] *= valPtr[2]; - break; - - case OP_DIV: - valPtr[0] /= valPtr[2]; - break; - - case OP_MOD: - valPtr[0] %= valPtr[2]; - break; - - case OP_BITAND: - valPtr[0] &= valPtr[2]; - break; - } - } // if ((stkPos > 0) && (cmdPtr[-1] >= OP_MUL) && (cmdPtr[-1] <= OP_BITAND)) - varPos = 0; - continue; - } - - if ((operation >= OP_NEG) && (operation <= OP_BEGIN_EXPR)) { - *operPtr = operation; - continue; - } - - while (stkPos >= 2) { - if (operPtr[-2] == OP_BEGIN_EXPR) { - stkPos--; - operPtr--; - valPtr--; - - operPtr[-1] = operPtr[0]; - valPtr[-1] = valPtr[0]; - if ((stkPos > 1) && (operPtr[-2] == OP_NEG)) { - operPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - } - - if ((stkPos > 2) && (operPtr[-2] >= OP_MUL) && (operPtr[-2] <= OP_BITAND)) { - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_MUL: - valPtr[-1] *= valPtr[1]; - break; - - case OP_DIV: - valPtr[-1] /= valPtr[1]; - break; - - case OP_MOD: - valPtr[-1] %= valPtr[1]; - break; - - case OP_BITAND: - valPtr[-1] &= valPtr[1]; - break; - } - } - if (operation == OP_END_EXPR) - break; - } // operPtr[-2] == OP_BEGIN_EXPR - - for (brackPos = (stkPos - 2); (brackPos > 0) && - (operStack[brackPos] < OP_OR) && (operStack[brackPos] != OP_BEGIN_EXPR); - brackPos--) - ; - - if ((operStack[brackPos] >= OP_OR) || (operStack[brackPos] == OP_BEGIN_EXPR)) - brackPos++; - - if ((operPtr[-2] < 2) || (operPtr[-2] > 8)) - break; - - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - switch (operPtr[0]) { - case OP_ADD: - values[brackPos] += valPtr[1]; - continue; - case OP_SUB: - values[brackPos] -= valPtr[1]; - continue; - case OP_BITOR: - values[brackPos] |= valPtr[1]; - continue; - case OP_MUL: - valPtr[-1] *= valPtr[1]; - continue; - case OP_DIV: - valPtr[-1] /= valPtr[1]; - continue; - case OP_MOD: - valPtr[-1] %= valPtr[1]; - continue; - case OP_BITAND: - valPtr[-1] &= valPtr[1]; - continue; - } - } - - if (operation != OP_END_EXPR) { - if (operation != stopToken) { - debugC(5, kDebugParser, "stoptoken error: %d != %d", - operation, stopToken); - } - flag = oldflag; - return values[0]; - } - - stkPos--; - operPtr--; - valPtr--; - } -} - -int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { - int32 values[20]; - byte operStack[20]; - int32 prevPrevVal; - int32 prevVal; - int32 curVal; - int32 *valPtr; - byte *operPtr; - byte *arrDescPtr; - byte operation; - int16 dimCount; - int16 temp; - int16 temp2; - int16 offset; - int16 dim; - bool var_1A; - int16 stkPos; - int16 brackStart; - uint32 varPos = 0; - - memset(operStack, 0, 20); - - stkPos = -1; - operPtr = operStack - 1; - valPtr = values - 1; - - while (true) { - operation = *_vm->_global->_inter_execPtr++; - - while ((operation == 14) || (operation == 15)) { - if (operation == 14) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - _vm->_global->_inter_execPtr += 2; - if (*_vm->_global->_inter_execPtr == 97) - _vm->_global->_inter_execPtr++; - } else if (operation == 15) { - uint16 n = _vm->_inter->load16(); - varPos += n * 4; - - uint16 var_0C = _vm->_inter->load16(); - uint8 var_A = *_vm->_global->_inter_execPtr++; - - byte *var_12 = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += var_A; - - uint16 var_6 = 0; - - for (int i = 0; i < var_A; i++) { - temp2 = parseValExpr(OP_END_MARKER); - - int16 ax = getOffset(temp2, var_12[i], varPos, 0, 0); - - var_6 = var_6 * var_12[i] + ax; - } - - varPos += var_6 * var_0C * 4; - - if (*_vm->_global->_inter_execPtr == 97) - _vm->_global->_inter_execPtr++; - } - - debugC(2, kDebugParser, "parseExpr: Prefix %d (%d)", varPos, operation); - - operation = *_vm->_global->_inter_execPtr++; - } - - stkPos++; - operPtr++; - valPtr++; - - if ((operation >= OP_ARRAY_UINT8) && (operation <= OP_FUNC)) { - switch (operation) { - case OP_ARRAY_UINT8: - case OP_ARRAY_UINT32: - case OP_ARRAY_UINT16: - case OP_ARRAY_STR: - *operPtr = (operation == OP_ARRAY_STR) ? OP_LOAD_IMM_STR : OP_LOAD_IMM_INT16; - temp = _vm->_inter->load16(); - dimCount = *_vm->_global->_inter_execPtr++; - arrDescPtr = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += dimCount; - offset = 0; - for (dim = 0; dim < dimCount; dim++) { - temp2 = parseValExpr(OP_END_MARKER); - offset = offset * arrDescPtr[dim] + temp2; - } - if (operation == OP_ARRAY_UINT8) - *valPtr = (int8) READ_VARO_UINT8(varPos + temp + offset); - else if (operation == OP_ARRAY_UINT32) - *valPtr = READ_VARO_UINT32(varPos + temp * 4 + offset * 4); - else if (operation == OP_ARRAY_UINT16) - *valPtr = (int16) READ_VARO_UINT16(varPos + temp * 2 + offset * 2); - else if (operation == OP_ARRAY_STR) { - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8( - varPos + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4), - kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp2 = parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(varPos + temp * 4 + - offset * 4 * _vm->_global->_inter_animDataSize + temp2); - } - } - break; - - case OP_LOAD_VAR_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 2); - break; - - case OP_LOAD_VAR_INT8: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int8) READ_VARO_UINT8(varPos + _vm->_inter->load16()); - break; - - case OP_LOAD_IMM_INT32: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_LE_UINT32(varPos + _vm->_global->_inter_execPtr); - _vm->_global->_inter_execPtr += 4; - break; - - case OP_LOAD_IMM_INT16: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_inter->load16(); - break; - - case OP_LOAD_IMM_INT8: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int8) *_vm->_global->_inter_execPtr++; - break; - - case OP_LOAD_IMM_STR: - *operPtr = OP_LOAD_IMM_STR; - *valPtr = encodePtr(_vm->_global->_inter_execPtr, kExecPtr); - _vm->_global->_inter_execPtr += - strlen((char *) _vm->_global->_inter_execPtr) + 1; - break; - - case 23: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT32(varPos + _vm->_inter->load16() * 4); - break; - - case 24: - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = (int16) READ_VARO_UINT16(varPos + _vm->_inter->load16() * 4); - break; - - case OP_LOAD_VAR_STR: - *operPtr = OP_LOAD_IMM_STR; - temp = _vm->_inter->load16() * 4; - *valPtr = encodePtr(_vm->_inter->_variables->getAddressOff8(varPos + temp), kInterVar); - if (*_vm->_global->_inter_execPtr == 13) { - _vm->_global->_inter_execPtr++; - temp += parseValExpr(OP_END_MARKER); - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = READ_VARO_UINT8(varPos + temp); - } - break; - - case OP_FUNC: - operation = *_vm->_global->_inter_execPtr++; - parseExpr(OP_END_EXPR, 0); - - switch (operation) { - case FUNC_SQRT1: - case FUNC_SQRT2: - case FUNC_SQRT3: - curVal = 1; - prevVal = 1; - - do { - prevPrevVal = prevVal; - prevVal = curVal; - curVal = (curVal + _vm->_global->_inter_resVal / curVal) / 2; - } while ((curVal != prevVal) && (curVal != prevPrevVal)); - _vm->_global->_inter_resVal = curVal; - break; - - case FUNC_SQR: - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - break; - - case FUNC_ABS: - if (_vm->_global->_inter_resVal < 0) - _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; - break; - - case FUNC_RAND: - _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); - break; - } - - *operPtr = OP_LOAD_IMM_INT16; - *valPtr = _vm->_global->_inter_resVal; - break; - } - - if ((stkPos > 0) && ((operPtr[-1] == OP_NEG) || (operPtr[-1] == OP_NOT))) { - stkPos--; - operPtr--; - valPtr--; - - if (*operPtr == OP_NEG) { - *operPtr = OP_LOAD_IMM_INT16; - valPtr[0] = -valPtr[1]; - } else - *operPtr = (operPtr[1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; - } - - if (stkPos <= 0) { - varPos = 0; - continue; - } - - switch (operPtr[-1]) { - case OP_ADD: - if (operPtr[-2] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-2]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-2])); - valPtr[-2] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[0])); - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - break; - - case OP_MUL: - valPtr[-2] *= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-2] /= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-2] %= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-2] &= valPtr[0]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } - varPos = 0; - continue; - } // (op >= OP_ARRAY_UINT8) && (op <= OP_FUNC) - - if ((operation == stopToken) || (operation == OP_OR) || - (operation == OP_AND) || (operation == OP_END_EXPR)) { - while (stkPos >= 2) { - var_1A = false; - if ((operPtr[-2] == OP_BEGIN_EXPR) && - ((operation == OP_END_EXPR) || (operation == stopToken))) { - operPtr[-2] = operPtr[-1]; - if ((operPtr[-2] == OP_LOAD_IMM_INT16) || (operPtr[-2] == OP_LOAD_IMM_STR)) - valPtr[-2] = valPtr[-1]; - - stkPos--; - operPtr--; - valPtr--; - - if (stkPos > 1) { - if (operPtr[-2] == OP_NEG) { - operPtr[-2] = OP_LOAD_IMM_INT16; - valPtr[-2] = -valPtr[-1]; - stkPos--; - operPtr--; - valPtr--; - } else if (operPtr[-2] == OP_NOT) { - operPtr[-2] = (operPtr[-1] == GOB_FALSE) ? GOB_TRUE : GOB_FALSE; - stkPos--; - operPtr--; - valPtr--; - } - } // stkPos > 1 - - if (stkPos > 2) { - switch (operPtr[-2]) { - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } // switch - } // stkPos > 2 - - if (operation != stopToken) - break; - } // if ((operPtr[-2] == OP_BEGIN_EXPR) && ...) - - for (brackStart = (stkPos - 2); (brackStart > 0) && - (operStack[brackStart] < OP_OR) && (operStack[brackStart] != OP_BEGIN_EXPR); - brackStart--) - ; - - if ((operStack[brackStart] >= OP_OR) || (operStack[brackStart] == OP_BEGIN_EXPR)) - brackStart++; - - switch (operPtr[-2]) { - case OP_ADD: - if (operStack[brackStart] == OP_LOAD_IMM_INT16) { - values[brackStart] += valPtr[-1]; - } else if (operStack[brackStart] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(values[brackStart]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[brackStart])); - values[brackStart] = - encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_SUB: - values[brackStart] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_BITOR: - values[brackStart] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - continue; - - case OP_MUL: - valPtr[-3] *= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_DIV: - valPtr[-3] /= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_MOD: - valPtr[-3] %= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_BITAND: - valPtr[-3] &= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_OR: - // (x OR false) == x - // (x OR true) == true - if (operPtr[-3] == GOB_FALSE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_AND: - // (x AND false) == false - // (x AND true) == x - if (operPtr[-3] == GOB_TRUE) - operPtr[-3] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LESS: - operPtr[-3] = (cmpHelper(operPtr, valPtr) < 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_LEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) <= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GREATER: - operPtr[-3] = (cmpHelper(operPtr, valPtr) > 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_GEQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) >= 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_EQ: - operPtr[-3] = (cmpHelper(operPtr, valPtr) == 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - - case OP_NEQ: { - int cmpTemp = 0; - - if (operPtr[-3] == OP_LOAD_IMM_INT16) { - cmpTemp = valPtr[-3] - valPtr[-1]; - } else if (operPtr[-3] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); - valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - // FIXME: Why scumm_stricmp here and strcmp everywhere else? - cmpTemp = scumm_stricmp(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - operPtr[-3] = (cmpTemp != 0) ? GOB_TRUE : GOB_FALSE; - //operPtr[-3] = (cmpHelper(operPtr, valPtr) != 0) ? GOB_TRUE : GOB_FALSE; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - break; - } - - default: - var_1A = true; - break; - } // switch - - if (var_1A) - break; - } // while (stkPos >= 2) - - if ((operation == OP_OR) || (operation == OP_AND)) { - if (operPtr[-1] == OP_LOAD_IMM_INT16) { - if (valPtr[-1] != 0) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - } - - if (((operation == OP_OR) && (operPtr[-1] == GOB_TRUE)) || - ((operation == OP_AND) && (operPtr[-1] == GOB_FALSE))) { - if ((stkPos > 1) && (operPtr[-2] == OP_BEGIN_EXPR)) { - skipExpr(OP_END_EXPR); - operPtr[-2] = operPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else { - skipExpr(stopToken); - } - operation = _vm->_global->_inter_execPtr[-1]; - if ((stkPos > 0) && (operPtr[-1] == OP_NOT)) { - if (operPtr[0] == GOB_FALSE) - operPtr[-1] = GOB_TRUE; - else - operPtr[-1] = GOB_FALSE; - - stkPos--; - operPtr--; - valPtr--; - } - } else - operPtr[0] = operation; - } else { - stkPos--; - operPtr--; - valPtr--; - } - - if (operation != stopToken) - continue; - - if (arg_2 != 0) - *arg_2 = operStack[0]; - - switch (operStack[0]) { - case OP_NOT: - if (arg_2 != 0) - *arg_2 ^= 1; - break; - - case OP_LOAD_IMM_INT16: - _vm->_global->_inter_resVal = values[0]; - break; - - case OP_LOAD_IMM_STR: - if ((char *) decodePtr(values[0]) != _vm->_global->_inter_resStr) - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[0])); - break; - - case 23: - case 24: - break; - - default: - _vm->_global->_inter_resVal = 0; - if (arg_2 != 0) - *arg_2 = OP_LOAD_IMM_INT16; - break; - } - return 0; - } // (operation == stopToken) || (operation == OP_OR) || (operation == OP_AND) || (operation == OP_END_EXPR) - - if ((operation < OP_NEG) || (operation > OP_NOT)) { - if ((operation < OP_LESS) || (operation > OP_NEQ)) - continue; - - if (stkPos > 2) { - if (operPtr[-2] == OP_ADD) { - if (operPtr[-3] == OP_LOAD_IMM_INT16) { - valPtr[-3] += valPtr[-1]; - } else if (operPtr[-3] == OP_LOAD_IMM_STR) { - if ((char *) decodePtr(valPtr[-3]) != _vm->_global->_inter_resStr) { - strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-3])); - valPtr[-3] = encodePtr((byte *) _vm->_global->_inter_resStr, kResStr); - } - strcat(_vm->_global->_inter_resStr, (char *) decodePtr(valPtr[-1])); - } - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - - } else if (operPtr[-2] == OP_SUB) { - valPtr[-3] -= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } else if (operPtr[-2] == OP_BITOR) { - valPtr[-3] |= valPtr[-1]; - stkPos -= 2; - operPtr -= 2; - valPtr -= 2; - } - } - } - *operPtr = operation; - } -} - -int16 Parse_v2::getOffset(int16 arg_0, byte arg_2, uint32 arg_3, uint16 arg_7, uint16 arg_9) { - if (arg_0 < 0) - return 0; - - if (arg_2 > arg_0) - return arg_0; - - return arg_2 - 1; -} - -} // End of namespace Gob diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp new file mode 100644 index 0000000000..20427e547b --- /dev/null +++ b/engines/gob/resources.cpp @@ -0,0 +1,706 @@ +/* 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/util.h" +#include "common/endian.h" +#include "common/stream.h" + +#include "gob/gob.h" +#include "gob/resources.h" +#include "gob/totfile.h" +#include "gob/dataio.h" +#include "gob/game.h" +#include "gob/global.h" + +namespace Gob { + +Resource::Resource(byte *data, int32 size, bool needFree, + int16 width, int16 height) { + + _data = data; + _size = size; + _width = width; + _height = height; + _needFree = needFree; + + _stream = new Common::MemoryReadStream(data, size); +} + +Resource::~Resource() { + delete _stream; + + if (_needFree) + delete[] _data; +} + +byte *Resource::getData() const { + return _data; +} + +int32 Resource::getSize() const { + return _size; +} + +int16 Resource::getWidth() const { + return _width; +} + +int16 Resource::getHeight() const { + return _height; +} + +Common::MemoryReadStream *Resource::stream() const { + return _stream; +} + + +TextItem::TextItem(byte *data, int32 size) { + _data = data; + _size = size; + + _stream = new Common::MemoryReadStream(data, size); +} + +TextItem::~TextItem() { + delete _stream; +} + +byte *TextItem::getData() const { + return _data; +} + +int32 TextItem::getSize() const { + return _size; +} + +Common::MemoryReadStream *TextItem::stream() const { + return _stream; +} + + +Resources::TOTResourceTable::TOTResourceTable() { + items = 0; +} + +Resources::TOTResourceTable::~TOTResourceTable() { + delete[] items; +} + + +Resources::EXTResourceTable::EXTResourceTable() { + itemsCount = 0; + unknown = 0; + items = 0; +} + +Resources::EXTResourceTable::~EXTResourceTable() { + delete[] items; +} + + +Resources::TOTTextTable::TOTTextTable() { + items = 0; + data = 0; + needFree = false; +} + +Resources::TOTTextTable::~TOTTextTable() { + delete[] items; + if (needFree) + delete[] data; +} + + +Resources::Resources(GobEngine *vm) : _vm(vm) { + unload(false); +} + +Resources::~Resources() { + unload(); +} + +bool Resources::load(const Common::String &fileName) { + unload(); + + Common::String fileBase; + + _totFile = TOTFile::createFileName(fileName, _hasLOM); + + if (_hasLOM) { + warning("Stub: Resources::load(%s)", fileName.c_str()); + unload(); + return false; + } + + fileBase = TOTFile::getFileBase(fileName); + + _extFile = fileBase + ".ext"; + + if (!loadTOTResourceTable()) { + unload(); + return false; + } + + if (!loadEXTResourceTable()) { + unload(); + return false; + } + + if (!loadTOTTextTable(fileBase)) { + unload(); + return false; + } + + if (!loadIMFile()) { + unload(); + return false; + } + + if (!loadEXFile()) { + unload(); + return false; + } + + return true; +} + +void Resources::unload(bool del) { + if (del) { + delete _totResourceTable; + delete _extResourceTable; + delete _totTextTable; + + delete[] _totData; + delete[] _imData; + + _totFile.clear(); + _extFile.clear(); + _exFile.clear(); + } + + _totResourceTable = 0; + _extResourceTable = 0; + _totTextTable = 0; + _totData = 0; + _totSize = 0; + _imData = 0; + _imSize = 0; +} + +bool Resources::isLoaded() const { + return (_totResourceTable != 0); +} + +bool Resources::loadTOTResourceTable() { + TOTFile totFile(_vm); + + if (!totFile.load(_totFile)) + return false; + + TOTFile::Properties totProps; + if (!totFile.getProperties(totProps)) + return false; + + Common::SeekableReadStream *stream = totFile.getStream(); + if (!stream) + return false; + + if ((totProps.resourcesOffset == 0xFFFFFFFF) || + (totProps.resourcesOffset == 0)) + // No resources here + return false; + + _totResourceTable = new TOTResourceTable; + + stream->seek(totProps.resourcesOffset); + _totResourceTable->itemsCount = stream->readSint16LE(); + + _totResourceTable->dataOffset = totProps.resourcesOffset + kTOTResTableSize + + _totResourceTable->itemsCount * kTOTResItemSize; + + + uint32 resSize = _totResourceTable->itemsCount * kTOTResItemSize + + kTOTResTableSize; + + // Would the table actually fit into the TOT? + if ((totProps.resourcesOffset + resSize) > ((uint32) stream->size())) + return false; + + _totResourceTable->unknown = stream->readByte(); + _totResourceTable->items = new TOTResourceItem[_totResourceTable->itemsCount]; + + for (int i = 0; i < _totResourceTable->itemsCount; ++i) { + TOTResourceItem &item = _totResourceTable->items[i]; + + item.offset = stream->readSint32LE(); + item.size = stream->readSint16LE(); + item.width = stream->readSint16LE(); + item.height = stream->readSint16LE(); + + if (item.offset < 0) { + item.type = kResourceIM; + item.index = -item.offset - 1; + } else + item.type = kResourceTOT; + } + + _totResStart = totProps.scriptEnd; + _totSize = stream->size() - _totResStart; + if (_totSize <= 0) + return false; + + if (!stream->seek(totProps.scriptEnd)) + return false; + + _totData = new byte[_totSize]; + if (stream->read(_totData, _totSize) != _totSize) + return false; + + return !stream->err(); +} + +bool Resources::loadEXTResourceTable() { + _extResourceTable = new EXTResourceTable; + + DataStream *stream = _vm->_dataIO->getDataStream(_extFile.c_str()); + if (!stream) + return true; + + _extResourceTable->itemsCount = stream->readSint16LE(); + _extResourceTable->unknown = stream->readByte(); + + if (_extResourceTable->itemsCount > 0) + _extResourceTable->items = new EXTResourceItem[_extResourceTable->itemsCount]; + + for (int i = 0; i < _extResourceTable->itemsCount; i++) { + EXTResourceItem &item = _extResourceTable->items[i]; + + item.offset = stream->readUint32LE(); + item.size = stream->readUint16LE(); + item.width = stream->readUint16LE(); + item.height = stream->readUint16LE(); + + if (item.offset < 0) { + item.type = kResourceEX; + item.offset = -item.offset - 1; + } else { + item.type = kResourceEXT; + item.offset += kEXTResTableSize + + kEXTResItemSize * _extResourceTable->itemsCount; + } + + item.packed = (item.width & 0x8000) != 0; + + item.width &= 0x7FFF; + } + + delete stream; + return true; +} + +bool Resources::loadTOTTextTable(const Common::String &fileBase) { + TOTFile totFile(_vm); + + if (!totFile.load(_totFile)) + return false; + + TOTFile::Properties totProps; + if (!totFile.getProperties(totProps)) + return false; + + Common::SeekableReadStream *stream = totFile.getStream(); + if (!stream) + return false; + + if (totProps.textsOffset == ((uint32) -1)) + // No texts + return true; + + _totTextTable = new TOTTextTable; + + bool fromTOT; + if (totProps.textsOffset == 0) { + fromTOT = false; + _totTextTable->data = loadTOTLocTexts(fileBase, _totTextTable->size); + _totTextTable->needFree = true; + } else { + fromTOT = true; + _totTextTable->data = _totData + totProps.textsOffset - _totResStart; + _totTextTable->needFree = false; + _totTextTable->size = _totSize - totProps.textsOffset; + } + + if (_totTextTable->data) { + Common::MemoryReadStream totTextTable(_totTextTable->data, _totTextTable->size); + _totTextTable->itemsCount = totTextTable.readSint16LE() & 0x3FFF; + + _totTextTable->items = new TOTTextItem[_totTextTable->itemsCount]; + for (int i = 0; i < _totTextTable->itemsCount; ++i) { + TOTTextItem &item = _totTextTable->items[i]; + + item.offset = totTextTable.readSint16LE(); + item.size = totTextTable.readSint16LE(); + + if (fromTOT) + item.offset -= (totProps.textsOffset - _totResStart); + } + } + + return true; +} + +bool Resources::loadIMFile() { + TOTFile totFile(_vm); + + if (!totFile.load(_totFile)) + return false; + + TOTFile::Properties totProps; + if (!totFile.getProperties(totProps)) + return false; + + if ((totProps.communHandling != 0) && (totProps.imFileNumber == 0)) + // No IM file + return true; + + Common::String imFile = "commun.im"; + + char num = totProps.imFileNumber + '0'; + if (num == '0') + num = '1'; + + imFile += num; + + DataStream *stream = _vm->_dataIO->getDataStream(imFile.c_str()); + if (!stream) + return true; + + _imSize = stream->size(); + if (_imSize <= 0) { + _imSize = 0; + delete stream; + return true; + } + + _imData = new byte[_imSize]; + if (stream->read(_imData, _imSize) != _imSize) { + delete[] _imData; + _imData = 0; + _imSize = 0; + } + + delete stream; + return true; +} + +bool Resources::loadEXFile() { + TOTFile totFile(_vm); + + if (!totFile.load(_totFile)) + return false; + + TOTFile::Properties totProps; + if (!totFile.getProperties(totProps)) + return false; + + _exFile = "commun.ex"; + _exFile += totProps.exFileNumber + '0'; + + if (!_vm->_dataIO->existData(_exFile.c_str())) { + _exFile.clear(); + return true; + } + + return true; +} + +Common::String Resources::getLocTextFile(const Common::String &fileBase, + int language) { + + Common::String locTextFile = fileBase + "."; + switch (language) { + case kLanguageFrench: + locTextFile += "dat"; + break; + case kLanguageGerman: + locTextFile += "all"; + break; + case kLanguageSpanish: + locTextFile += "esp"; + break; + case kLanguageItalian: + locTextFile += "ita"; + break; + case kLanguageAmerican: + locTextFile += "usa"; + break; + case kLanguageDutch: + locTextFile += "ndl"; + break; + case kLanguageKorean: + locTextFile += "kor"; + break; + case kLanguageHebrew: + locTextFile += "isr"; + break; + default: + locTextFile += "ang"; + break; + } + + if (!_vm->_dataIO->existData(locTextFile.c_str())) + locTextFile.clear(); + + return locTextFile; +} + +byte *Resources::loadTOTLocTexts(const Common::String &fileBase, int32 &size) { + Common::String locTextFile; + + locTextFile = getLocTextFile(fileBase, _vm->_global->_languageWanted); + + if (!locTextFile.empty()) { + + _vm->_global->_foundLanguage = true; + _vm->_global->_language = _vm->_global->_languageWanted; + + } else if (!_vm->_global->_foundLanguage) { + + // Trying US for GB and vice versa + if (_vm->_global->_languageWanted == kLanguageBritish) { + + locTextFile = getLocTextFile(fileBase, kLanguageAmerican); + if (!locTextFile.empty()) + _vm->_global->_language = kLanguageAmerican; + + } else if (_vm->_global->_languageWanted == kLanguageAmerican) { + + locTextFile = getLocTextFile(fileBase, kLanguageBritish); + if (!locTextFile.empty()) + _vm->_global->_language = kLanguageBritish; + + } + + if (locTextFile.empty()) { + // Looking for the first existing language + for (int i = 0; i < 10; i++) { + locTextFile = getLocTextFile(fileBase, i); + if (!locTextFile.empty()) { + _vm->_global->_language = i; + break; + } + } + } + + } + + debugC(1, kDebugFileIO, "Using language %d for %s", + _vm->_global->_language, _totFile.c_str()); + + if (locTextFile.empty()) + return 0; + + size = _vm->_dataIO->getDataSize(locTextFile.c_str()); + return _vm->_dataIO->getData(locTextFile.c_str()); +} + +Resource *Resources::getResource(uint16 id, int16 *width, int16 *height) const { + if (_hasLOM) { + warning("Stub: Resources::getResource(): Has LOM"); + return 0; + } + + Resource *resource = 0; + if (id >= 30000) + resource = getEXTResource(id - 30000); + else + resource = getTOTResource(id); + + if (!resource) + return 0; + + if (width) + *width = resource->getWidth(); + if (height) + *height = resource->getHeight(); + + return resource; +} + +TextItem *Resources::getTextItem(uint16 id) const { + if (!_totTextTable || !_totTextTable->data) + return 0; + + if (id >= _totTextTable->itemsCount) + return 0; + + TOTTextItem &totItem = _totTextTable->items[id]; + + if ((totItem.offset == 0xFFFF) || (totItem.size == 0)) + return 0; + if ((totItem.offset + totItem.size) > (_totTextTable->size)) + return 0; + + return new TextItem(_totTextTable->data + totItem.offset, totItem.size); +} + +byte *Resources::getTexts() const { + if (!_totTextTable) + return 0; + + return _totTextTable->data; +} + +Resource *Resources::getTOTResource(uint16 id) const { + if (id >= _totResourceTable->itemsCount) { + warning("Trying to load non-existent TOT resource (%s, %d/%d)", + _totFile.c_str(), id, _totResourceTable->itemsCount - 1); + return 0; + } + + TOTResourceItem &totItem = _totResourceTable->items[id]; + + byte *data = 0; + if (totItem.type == kResourceIM) + data = getIMData(totItem); + if (totItem.type == kResourceTOT) + data = getTOTData(totItem); + + if (!data) + return 0; + + return new Resource(data, totItem.size, false, totItem.width, totItem.height); +} + +Resource *Resources::getEXTResource(uint16 id) const { + if (!_extResourceTable || (id > _extResourceTable->itemsCount)) + return 0; + + EXTResourceItem &extItem = _extResourceTable->items[id]; + + uint32 size = extItem.size; + + if (extItem.width & 0x4000) + size += 1 << 16; + if (extItem.width & 0x2000) + size += 2 << 16; + if (extItem.width & 0x1000) + size += 4 << 16; + if (extItem.height == 0) + size += extItem.width << 16; + + byte *data = 0; + if (extItem.type == kResourceEXT) + data = getEXTData(extItem, size); + if (extItem.type == kResourceEX) + data = getEXData(extItem, size); + + if (!data) + return 0; + + if (extItem.packed) { + byte *packedData = data; + + size = READ_LE_UINT32(packedData); + data = new byte[size]; + + _vm->_dataIO->unpackData(packedData, data); + + delete[] packedData; + } + + return new Resource(data, size, true, extItem.width & 0xFFF, extItem.height); +} + +byte *Resources::getTOTData(TOTResourceItem &totItem) const { + if (totItem.size < 0) + return 0; + + int32 offset = _totResourceTable->dataOffset + totItem.offset - _totResStart; + + if ((offset < 0) || (((uint32) (offset + totItem.size)) > _totSize)) + return 0; + + return _totData + offset; +} + +byte *Resources::getIMData(TOTResourceItem &totItem) const { + if (totItem.size < 0) + return 0; + + int32 indexOffset = totItem.index * 4; + if ((indexOffset < 0) || (((uint32) indexOffset) >= _imSize)) + return 0; + + uint32 offset = READ_LE_UINT32(_imData + indexOffset); + if ((offset + totItem.size) > _imSize) + return 0; + + return _imData + offset; +} + +byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const { + DataStream *stream = _vm->_dataIO->getDataStream(_extFile.c_str()); + if (!stream) + return 0; + + if (!stream->seek(extItem.offset)) { + delete stream; + return 0; + } + + byte *data = new byte[extItem.packed ? (size + 2) : size]; + if (stream->read(data, size) != size) { + delete[] data; + delete stream; + return 0; + } + + delete stream; + return data; +} + +byte *Resources::getEXData(EXTResourceItem &extItem, uint32 size) const { + DataStream *stream = _vm->_dataIO->getDataStream(_exFile.c_str()); + if (!stream) + return 0; + + if (!stream->seek(extItem.offset)) { + delete stream; + return 0; + } + + byte *data = new byte[extItem.packed ? (size + 2) : size]; + if (stream->read(data, size) != size) { + delete[] data; + delete stream; + return 0; + } + + delete stream; + return data; +} + +} // End of namespace Gob diff --git a/engines/gob/resources.h b/engines/gob/resources.h new file mode 100644 index 0000000000..80acef645c --- /dev/null +++ b/engines/gob/resources.h @@ -0,0 +1,207 @@ +/* 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_RESOURCES_H +#define GOB_RESOURCES_H + +#include "common/str.h" + +namespace Common { + class MemoryReadStream; +} + +namespace Gob { + +class GobEngine; + +class Resource { +public: + Resource(byte *data, int32 size, bool needFree = true, + int16 width = 0, int16 height = 0); + ~Resource(); + + byte *getData () const; + int32 getSize () const; + int16 getWidth () const; + int16 getHeight() const; + + Common::MemoryReadStream *stream() const; + +private: + byte *_data; + int32 _size; + int16 _width; + int16 _height; + bool _needFree; + + Common::MemoryReadStream *_stream; +}; + +class TextItem { +public: + TextItem(byte *data, int32 size); + ~TextItem(); + + byte *getData() const; + int32 getSize() const; + + Common::MemoryReadStream *stream() const; + +private: + byte *_data; + int32 _size; + + Common::MemoryReadStream *_stream; +}; + +class Resources { +public: + Resources(GobEngine *vm); + ~Resources(); + + bool load(const Common::String &fileName); + void unload(bool del = true); + + bool isLoaded() const; + + Resource *getResource(uint16 id, int16 *width = 0, int16 *height = 0) const; + TextItem *getTextItem(uint16 id) const; + + byte *getTexts() const; + +private: + // Structure sizes in the files + static const int kTOTResItemSize = 4 + 2 + 2 + 2; + static const int kTOTResTableSize = 2 + 1; + static const int kEXTResItemSize = 4 + 2 + 2 + 2; + static const int kEXTResTableSize = 2 + 1; + static const int kTOTTextTableSize = 2; + static const int kTOTTextItemSize = 2 + 2; + + enum ResourceType { + kResourceTOT, + kResourceIM, + kResourceEXT, + kResourceEX + }; + + struct TOTResourceItem { + ResourceType type; + int16 size; + int16 width; + int16 height; + union { + int32 offset; + int32 index; + }; + }; + + struct TOTResourceTable { + int16 itemsCount; + byte unknown; + TOTResourceItem *items; + uint32 dataOffset; + + TOTResourceTable(); + ~TOTResourceTable(); + }; + + struct EXTResourceItem { + ResourceType type; + int32 offset; + uint16 size; + int16 width; + int16 height; + bool packed; + }; + + struct EXTResourceTable { + int16 itemsCount; + byte unknown; + EXTResourceItem *items; + + EXTResourceTable(); + ~EXTResourceTable(); + }; + + struct TOTTextItem { + uint16 offset; + int16 size; + }; + + struct TOTTextTable { + bool needFree; + int16 itemsCount; + + byte *data; + int32 size; + + TOTTextItem *items; + + TOTTextTable(); + ~TOTTextTable(); + }; + + GobEngine *_vm; + + Common::String _totFile; + Common::String _extFile; + Common::String _exFile; + + byte *_totData; + uint32 _totSize; + + byte *_imData; + uint32 _imSize; + + bool _hasLOM; + int32 _totResStart; + + TOTResourceTable *_totResourceTable; + EXTResourceTable *_extResourceTable; + TOTTextTable *_totTextTable; + + bool loadTOTResourceTable(); + bool loadEXTResourceTable(); + bool loadTOTTextTable(const Common::String &fileBase); + bool loadIMFile(); + bool loadEXFile(); + + byte *loadTOTLocTexts(const Common::String &fileBase, int32 &size); + bool getLocTextFile(char *locTextFile, int language); + Common::String getLocTextFile(const Common::String &fileBase, int language); + + Resource *getTOTResource(uint16 id) const; + Resource *getEXTResource(uint16 id) const; + + byte *getTOTData(TOTResourceItem &totItem) const; + byte *getIMData(TOTResourceItem &totItem) const; + byte *getEXTData(EXTResourceItem &extItem, uint32 size) const; + byte *getEXData(EXTResourceItem &extItem, uint32 size) const; +}; + +} // End of namespace Gob + +#endif // GOB_RESOURCES_H diff --git a/engines/gob/save/savefile.cpp b/engines/gob/save/savefile.cpp index b3b545548f..e1c4c62b12 100644 --- a/engines/gob/save/savefile.cpp +++ b/engines/gob/save/savefile.cpp @@ -331,17 +331,14 @@ bool SavePartSprite::readPalette(const byte *palette) { return true; } -bool SavePartSprite::readSprite(const SurfaceDesc *sprite) { - if (!sprite) - return false; - +bool SavePartSprite::readSprite(const SurfaceDesc &sprite) { // The sprite's dimensions have to fit - if (((uint32) sprite->getWidth()) != _width) + if (((uint32)sprite.getWidth()) != _width) return false; - if (((uint32) sprite->getHeight()) != _height) + if (((uint32)sprite.getHeight()) != _height) return false; - memcpy(_dataSprite, sprite->getVidMem(), _width * _height); + memcpy(_dataSprite, sprite.getVidMem(), _width * _height); return true; } @@ -360,17 +357,14 @@ bool SavePartSprite::writePalette(byte *palette) const { return true; } -bool SavePartSprite::writeSprite(SurfaceDesc *sprite) const { - if (!sprite) - return false; - +bool SavePartSprite::writeSprite(SurfaceDesc &sprite) const { // The sprite's dimensions have to fit - if (((uint32) sprite->getWidth()) != _width) + if (((uint32)sprite.getWidth()) != _width) return false; - if (((uint32) sprite->getHeight()) != _height) + if (((uint32)sprite.getHeight()) != _height) return false; - memcpy(sprite->getVidMem(), _dataSprite, _width * _height); + memcpy(sprite.getVidMem(), _dataSprite, _width * _height); return true; } diff --git a/engines/gob/save/savefile.h b/engines/gob/save/savefile.h index 6c211c1d5c..615be8e0f2 100644 --- a/engines/gob/save/savefile.h +++ b/engines/gob/save/savefile.h @@ -162,15 +162,15 @@ public: /** Read a palette into the part. */ bool readPalette(const byte *palette); /** Read a sprite into the part. */ - bool readSprite(const SurfaceDesc *sprite); - + bool readSprite(const SurfaceDesc &sprite); + /** Read size bytes of raw data into the sprite. */ bool readSpriteRaw(const byte *data, uint32 size); /** Write a palette out of the part. */ bool writePalette(byte *palette) const; /** Write a sprite out of the part. */ - bool writeSprite(SurfaceDesc *sprite) const; + bool writeSprite(SurfaceDesc &sprite) const; private: uint32 _width; diff --git a/engines/gob/save/savehandler.cpp b/engines/gob/save/savehandler.cpp index 74b878f0a1..4e2c09bdca 100644 --- a/engines/gob/save/savehandler.cpp +++ b/engines/gob/save/savehandler.cpp @@ -242,14 +242,14 @@ bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { if ((index < 0) || (index >= SPRITES_COUNT)) return false; - SurfaceDesc *sprite = _vm->_draw->_spritesArray[index]; + SurfaceDescPtr sprite = _vm->_draw->_spritesArray[index]; // Target sprite exists? if (!sprite) return false; // Load the sprite - if (!_sprite->writeSprite(sprite)) + if (!_sprite->writeSprite(*sprite)) return false; // Handle palette @@ -272,13 +272,13 @@ bool TempSpriteHandler::load(int16 dataVar, int32 size, int32 offset) { } bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { - SurfaceDesc *sprite; + SurfaceDescPtr sprite; if (!createSprite(dataVar, size, offset, &sprite)) return false; // Save the sprite - if (!_sprite->readSprite(sprite)) + if (!_sprite->readSprite(*sprite)) return false; // Handle palette @@ -291,7 +291,7 @@ bool TempSpriteHandler::save(int16 dataVar, int32 size, int32 offset) { } bool TempSpriteHandler::createSprite(int16 dataVar, int32 size, - int32 offset, SurfaceDesc **sprite) { + int32 offset, SurfaceDescPtr *sprite) { delete _sprite; _sprite = 0; @@ -305,7 +305,7 @@ bool TempSpriteHandler::createSprite(int16 dataVar, int32 size, if ((index < 0) || (index >= SPRITES_COUNT)) return false; - SurfaceDesc *sprt = _vm->_draw->_spritesArray[index]; + SurfaceDescPtr sprt = _vm->_draw->_spritesArray[index]; // Sprite exists? if (!sprt) diff --git a/engines/gob/save/savehandler.h b/engines/gob/save/savehandler.h index cb984f7abb..55505d1b9a 100644 --- a/engines/gob/save/savehandler.h +++ b/engines/gob/save/savehandler.h @@ -27,11 +27,11 @@ #define GOB_SAVE_SAVEHANDLER_H #include "common/savefile.h" +#include "engines/gob/video.h" // for SurfaceDescPtr namespace Gob { class GobEngine; -class SurfaceDesc; class SavePartInfo; class SavePartVars; class SavePartSprite; @@ -139,7 +139,7 @@ public: /** Create a fitting sprite. */ bool createSprite(int16 dataVar, int32 size, - int32 offset, SurfaceDesc **sprite = 0); + int32 offset, SurfaceDescPtr *sprite = 0); protected: SavePartSprite *_sprite; diff --git a/engines/gob/save/saveload.cpp b/engines/gob/save/saveload.cpp index abda2f8a65..81239f07dc 100644 --- a/engines/gob/save/saveload.cpp +++ b/engines/gob/save/saveload.cpp @@ -61,7 +61,7 @@ int32 SaveLoad::getSize(const char *fileName) { int32 size = handler->getSize(); debugC(4, kDebugSaveLoad, "Size is %d", size); - + return size; } diff --git a/engines/gob/save/saveload_v3.cpp b/engines/gob/save/saveload_v3.cpp index 2f89644ee0..58232e6991 100644 --- a/engines/gob/save/saveload_v3.cpp +++ b/engines/gob/save/saveload_v3.cpp @@ -302,7 +302,7 @@ bool SaveLoad_v3::GameHandler::createReader(int slot) { if (!_reader || (_reader->getSlot() != ((uint32) slot))) { Common::String slotFile = _slotFile->build(slot); - + if (slotFile.empty()) return false; @@ -319,7 +319,7 @@ bool SaveLoad_v3::GameHandler::createReader(int slot) { } else _reader = new SaveReader(_usesScreenshots ? 3 : 2, slot, slotFile); - + if (!_reader->load()) { delete _reader; _reader = 0; @@ -337,7 +337,7 @@ bool SaveLoad_v3::GameHandler::createWriter(int slot) { if (!_writer || (_writer->getSlot() != ((uint32) slot))) { Common::String slotFile = _slotFile->build(slot); - + if (slotFile.empty()) return false; @@ -495,7 +495,7 @@ SaveLoad_v3::SaveLoad_v3(GobEngine *vm, const char *targetName, ScreenshotType s _gameHandler = new GameHandler(vm, targetName, true); _screenshotHandler = new ScreenshotHandler(vm, _gameHandler, sShotType); } - + _tempSpriteHandler = new TempSpriteHandler(vm); _notesHandler = new NotesHandler(2560, vm, targetName); diff --git a/engines/gob/save/saveload_v4.cpp b/engines/gob/save/saveload_v4.cpp index 6e1d5208ff..06280af2a6 100644 --- a/engines/gob/save/saveload_v4.cpp +++ b/engines/gob/save/saveload_v4.cpp @@ -317,7 +317,7 @@ bool SaveLoad_v4::GameHandler::createReader(int slot) { if (!_reader || (_reader->getSlot() != ((uint32) slot))) { Common::String slotFile = _slotFile->build(slot); - + if (slotFile.empty()) return false; @@ -334,7 +334,7 @@ bool SaveLoad_v4::GameHandler::createReader(int slot) { } else _reader = new SaveReader(3, slot, slotFile); - + if (!_reader->load()) { delete _reader; _reader = 0; @@ -352,7 +352,7 @@ bool SaveLoad_v4::GameHandler::createWriter(int slot) { if (!_writer || (_writer->getSlot() != ((uint32) slot))) { Common::String slotFile = _slotFile->build(slot); - + if (slotFile.empty()) return false; diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp index 16c6079f45..7a4b8ad868 100644 --- a/engines/gob/scenery.cpp +++ b/engines/gob/scenery.cpp @@ -31,6 +31,8 @@ #include "gob/global.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/script.h" +#include "gob/resources.h" #include "gob/inter.h" #include "gob/map.h" #include "gob/videoplayer.h" @@ -39,33 +41,33 @@ namespace Gob { Scenery::Scenery(GobEngine *vm) : _vm(vm) { for (int i = 0; i < 20; i++) { - _spriteRefs[i] = 0; + _spriteRefs[i] = 0; _spriteResId[i] = 0; } for (int i = 0; i < 10; i++) { _staticPictCount[i] = 0; - _staticResId[i] = 0; - _animPictCount[i] = 0; - _animResId[i] = 0; + _staticResId[i] = 0; + _animPictCount[i] = 0; + _animResId[i] = 0; } - _curStatic = 0; + _curStatic = 0; _curStaticLayer = 0; - _toRedrawLeft = 0; - _toRedrawRight = 0; - _toRedrawTop = 0; + _toRedrawLeft = 0; + _toRedrawRight = 0; + _toRedrawTop = 0; _toRedrawBottom = 0; - _animTop = 0; + _animTop = 0; _animLeft = 0; _pCaptureCounter = 0; for (int i = 0; i < 70; i++ ) { _staticPictToSprite[i] = 0; - _animPictToSprite[i] = 0; + _animPictToSprite[i] = 0; } } @@ -78,17 +80,17 @@ Scenery::~Scenery() { void Scenery::init() { for (int i = 0; i < 10; i++) { - _animPictCount[i] = 0; + _animPictCount[i] = 0; _staticPictCount[i] = -1; } for (int i = 0; i < 20; i++) { - _spriteRefs[i] = 0; + _spriteRefs[i] = 0; _spriteResId[i] = -1; } _curStaticLayer = -1; - _curStatic = -1; + _curStatic = -1; } int16 Scenery::loadStatic(char search) { @@ -97,28 +99,26 @@ int16 Scenery::loadStatic(char search) { int16 picsCount; int16 resId; int16 sceneryIndex; - byte *extData = 0; - byte *dataPtr; Static *ptr; int16 width; int16 height; int16 sprResId; int16 sprIndex; - _vm->_inter->evalExpr(&sceneryIndex); + _vm->_game->_script->evalExpr(&sceneryIndex); - size = _vm->_inter->load16(); - backsPtr = (int16 *) _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr += size * 2; - picsCount = _vm->_inter->load16(); - resId = _vm->_inter->load16(); + size = _vm->_game->_script->readInt16(); + backsPtr = (int16 *) (_vm->_game->_script->getData() + _vm->_game->_script->pos()); + _vm->_game->_script->skip(size * 2); + picsCount = _vm->_game->_script->readInt16(); + resId = _vm->_game->_script->readInt16(); if (search) { int i; for (i = 0; i < 10; i++) { if ((_staticPictCount[i] != -1) && (_staticResId[i] == resId)) { - _vm->_global->_inter_execPtr += 8 * _staticPictCount[i]; + _vm->_game->_script->skip(8 * _staticPictCount[i]); return i; } @@ -128,52 +128,54 @@ int16 Scenery::loadStatic(char search) { } _staticPictCount[sceneryIndex] = picsCount; - _staticResId[sceneryIndex] = resId; + _staticResId[sceneryIndex] = resId; - if (resId >= 30000) { - extData = _vm->_game->loadExtData(resId, 0, 0); - dataPtr = extData; - } else - dataPtr = _vm->_game->loadTotResource(resId); + Resource *resource = _vm->_game->_resources->getResource((uint16) resId); + if (!resource) + return 0; ptr = &_statics[sceneryIndex]; - ptr->layersCount = (int16) READ_LE_UINT16(dataPtr); - dataPtr += 2; + ptr->layersCount = resource->stream()->readSint16LE(); ptr->layers = new StaticLayer[ptr->layersCount]; for (int i = 0; i < ptr->layersCount; i++) { - int16 offset = READ_LE_UINT16(dataPtr + i * 2); - Common::MemoryReadStream layerData(dataPtr + offset, 4294967295U); + Common::SeekableReadStream &layerData = *resource->stream(); - ptr->layers[i].planeCount = layerData.readSint16LE(); + layerData.seek(2 + i * 2); + layerData.seek(layerData.readUint16LE()); - ptr->layers[i].planes = new StaticPlane[ptr->layers[i].planeCount]; - for (int j = 0; j < ptr->layers[i].planeCount; ++j) { - ptr->layers[i].planes[j].pictIndex = layerData.readByte(); - ptr->layers[i].planes[j].pieceIndex = layerData.readByte(); - ptr->layers[i].planes[j].drawOrder = layerData.readByte(); - ptr->layers[i].planes[j].destX = layerData.readSint16LE(); - ptr->layers[i].planes[j].destY = layerData.readSint16LE(); - ptr->layers[i].planes[j].transp = layerData.readSByte(); - } + ptr->layers[i].backResId = layerData.readSint16LE(); + ptr->layers[i].planeCount = layerData.readSint16LE(); + if (ptr->layers[i].planeCount > 0) { + ptr->layers[i].planes = new StaticPlane[ptr->layers[i].planeCount]; + for (int j = 0; j < ptr->layers[i].planeCount; j++) { + ptr->layers[i].planes[j].pictIndex = layerData.readByte(); + ptr->layers[i].planes[j].pieceIndex = layerData.readByte(); + ptr->layers[i].planes[j].drawOrder = layerData.readByte(); + ptr->layers[i].planes[j].destX = layerData.readSint16LE(); + ptr->layers[i].planes[j].destY = layerData.readSint16LE(); + ptr->layers[i].planes[j].transp = layerData.readSByte(); + } + } else + ptr->layers[i].planes = 0; ptr->layers[i].backResId = (int16) READ_LE_UINT16(backsPtr); backsPtr++; } - ptr->pieces = new PieceDesc*[picsCount]; + ptr->pieces = new PieceDesc*[picsCount]; ptr->piecesCount = new uint32[picsCount]; for (int i = 0; i < picsCount; i++) { - int16 pictDescId = _vm->_inter->load16(); + int16 pictDescId = _vm->_game->_script->readInt16(); loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]); - width = _vm->_inter->load16(); - height = _vm->_inter->load16(); - sprResId = _vm->_inter->load16(); + width = _vm->_game->_script->readInt16(); + height = _vm->_game->_script->readInt16(); + sprResId = _vm->_game->_script->readInt16(); for (sprIndex = 0; sprIndex < 20; sprIndex++) { if (_spriteResId[sprIndex] == sprResId) break; @@ -183,27 +185,24 @@ int16 Scenery::loadStatic(char search) { _staticPictToSprite[7 * sceneryIndex + i] = sprIndex; _spriteRefs[sprIndex]++; } else { - for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; - sprIndex--) - ; + for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; sprIndex--); _staticPictToSprite[7 * sceneryIndex + i] = sprIndex; _spriteRefs[sprIndex] = 1; _spriteResId[sprIndex] = sprResId; _vm->_draw->initSpriteSurf(sprIndex, width, height, 2); - _vm->_video->clearSurf(_vm->_draw->_spritesArray[sprIndex]); - _vm->_draw->_destSurface = sprIndex; - _vm->_draw->_spriteLeft = sprResId; + _vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]); + _vm->_draw->_destSurface = sprIndex; + _vm->_draw->_spriteLeft = sprResId; _vm->_draw->_transparency = 0; - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; + _vm->_draw->_destSpriteX = 0; + _vm->_draw->_destSpriteY = 0; _vm->_draw->spriteOperation(DRAW_LOADSPRITE); } } - delete[] extData; - + delete resource; return sceneryIndex + 100; } @@ -211,7 +210,7 @@ void Scenery::freeStatic(int16 index) { int16 spr; if (index == -1) - _vm->_inter->evalExpr(&index); + _vm->_game->_script->evalExpr(&index); if (_staticPictCount[index] == -1) return; @@ -229,12 +228,13 @@ void Scenery::freeStatic(int16 index) { for (int i = 0; i < _statics[index].layersCount; i++) delete[] _statics[index].layers[i].planes; + delete[] _statics[index].layers; delete[] _statics[index].pieces; delete[] _statics[index].piecesCount; _statics[index].layersCount = 0; - _staticPictCount[index] = -1; + _staticPictCount[index] = -1; } void Scenery::renderStatic(int16 scenery, int16 layer) { @@ -261,22 +261,21 @@ void Scenery::renderStatic(int16 scenery, int16 layer) { _vm->_draw->_spriteLeft = layerPtr->backResId; if (_vm->_draw->_spriteLeft != -1) { - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; - _vm->_draw->_destSurface = 21; - _vm->_draw->_transparency = 0; + _vm->_draw->_destSpriteX = 0; + _vm->_draw->_destSpriteY = 0; + _vm->_draw->_destSurface = 21; + _vm->_draw->_transparency = 0; _vm->_draw->spriteOperation(DRAW_LOADSPRITE); } planeCount = layerPtr->planeCount; for (order = 0; order < 100; order++) { - for (plane = 0, planePtr = layerPtr->planes; - plane < planeCount; plane++, planePtr++) { + for (plane = 0, planePtr = layerPtr->planes; plane < planeCount; plane++, planePtr++) { if (planePtr->drawOrder != order) continue; pieceIndex = planePtr->pieceIndex; - pictIndex = planePtr->pictIndex - 1; + pictIndex = planePtr->pictIndex - 1; if (pictIndex >= _staticPictCount[scenery]) continue; @@ -289,19 +288,19 @@ void Scenery::renderStatic(int16 scenery, int16 layer) { _vm->_draw->_destSpriteX = planePtr->destX; _vm->_draw->_destSpriteY = planePtr->destY; - left = ptr->pieces[pictIndex][pieceIndex].left; - right = ptr->pieces[pictIndex][pieceIndex].right; - top = ptr->pieces[pictIndex][pieceIndex].top; + left = ptr->pieces[pictIndex][pieceIndex].left; + right = ptr->pieces[pictIndex][pieceIndex].right; + top = ptr->pieces[pictIndex][pieceIndex].top; bottom = ptr->pieces[pictIndex][pieceIndex].bottom; _vm->_draw->_sourceSurface = _staticPictToSprite[scenery * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; - _vm->_draw->_spriteLeft = left; - _vm->_draw->_spriteTop = top; - _vm->_draw->_spriteRight = right - left + 1; - _vm->_draw->_spriteBottom = bottom - top + 1; - _vm->_draw->_transparency = planePtr->transp ? 3 : 0; + _vm->_draw->_destSurface = 21; + _vm->_draw->_spriteLeft = left; + _vm->_draw->_spriteTop = top; + _vm->_draw->_spriteRight = right - left + 1; + _vm->_draw->_spriteBottom = bottom - top + 1; + _vm->_draw->_transparency = planePtr->transp ? 3 : 0; _vm->_draw->spriteOperation(DRAW_BLITSURF); } } @@ -337,7 +336,7 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) { continue; pieceIndex = planePtr->pieceIndex; - pictIndex = planePtr->pictIndex - 1; + pictIndex = planePtr->pictIndex - 1; if (pictIndex >= _staticPictCount[index]) continue; @@ -351,9 +350,9 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) { _vm->_draw->_destSpriteX = planePtr->destX; _vm->_draw->_destSpriteY = planePtr->destY; - left = pictPtr[pictIndex][pieceIndex].left; - right = pictPtr[pictIndex][pieceIndex].right; - top = pictPtr[pictIndex][pieceIndex].top; + left = pictPtr[pictIndex][pieceIndex].left; + right = pictPtr[pictIndex][pieceIndex].right; + top = pictPtr[pictIndex][pieceIndex].top; bottom = pictPtr[pictIndex][pieceIndex].bottom; if (_vm->_draw->_destSpriteX > _toRedrawRight) @@ -372,10 +371,10 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) { _vm->_draw->_destSpriteY = _toRedrawTop; } - _vm->_draw->_spriteLeft = left; - _vm->_draw->_spriteTop = top; - _vm->_draw->_spriteRight = right - left + 1; - _vm->_draw->_spriteBottom = bottom - top + 1; + _vm->_draw->_spriteLeft = left; + _vm->_draw->_spriteTop = top; + _vm->_draw->_spriteRight = right - left + 1; + _vm->_draw->_spriteBottom = bottom - top + 1; if ((_vm->_draw->_spriteRight <= 0) || (_vm->_draw->_spriteBottom <= 0)) @@ -393,8 +392,8 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) { _vm->_draw->_sourceSurface = _staticPictToSprite[index * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; - _vm->_draw->_transparency = planePtr->transp ? 3 : 0; + _vm->_draw->_destSurface = 21; + _vm->_draw->_transparency = planePtr->transp ? 3 : 0; _vm->_draw->spriteOperation(DRAW_BLITSURF); } } @@ -422,8 +421,6 @@ int16 Scenery::loadAnim(char search) { int16 j; int16 sceneryIndex; int16 framesCount; - byte *extData; - byte *dataPtr; Animation *ptr; int16 width; int16 height; @@ -431,15 +428,14 @@ int16 Scenery::loadAnim(char search) { int16 sprIndex; uint32 layerPos; - extData = 0; - _vm->_inter->evalExpr(&sceneryIndex); - picsCount = _vm->_inter->load16(); - resId = _vm->_inter->load16(); + _vm->_game->_script->evalExpr(&sceneryIndex); + picsCount = _vm->_game->_script->readInt16(); + resId = _vm->_game->_script->readInt16(); if (search) { for (i = 0; i < 10; i++) { if ((_animPictCount[i] != 0) && (_animResId[i] == resId)) { - _vm->_global->_inter_execPtr += 8 * _animPictCount[i]; + _vm->_game->_script->skip(8 * _animPictCount[i]); return i; } @@ -451,50 +447,50 @@ int16 Scenery::loadAnim(char search) { _animPictCount[sceneryIndex] = picsCount; _animResId[sceneryIndex] = resId; - if (resId >= 30000) { - extData = _vm->_game->loadExtData(resId, 0, 0); - dataPtr = extData; - } else - dataPtr = _vm->_game->loadTotResource(resId); + Resource *resource = _vm->_game->_resources->getResource((uint16) resId); + if (!resource) + return 0; ptr = &_animations[sceneryIndex]; - ptr->layersCount = READ_LE_UINT16(dataPtr); - dataPtr += 2; + ptr->layersCount = resource->stream()->readSint16LE(); ptr->layers = new AnimLayer[ptr->layersCount]; for (i = 0; i < ptr->layersCount; i++) { - int16 offset = READ_LE_UINT16(dataPtr + i * 2); - Common::MemoryReadStream layerData(dataPtr + offset - 2, 4294967295U); - - ptr->layers[i].unknown0 = layerData.readSint16LE(); - ptr->layers[i].posX = layerData.readSint16LE(); - ptr->layers[i].posY = layerData.readSint16LE(); - ptr->layers[i].animDeltaX = layerData.readSint16LE(); - ptr->layers[i].animDeltaY = layerData.readSint16LE(); - ptr->layers[i].transp = layerData.readSByte(); + Common::SeekableReadStream &layerData = *resource->stream(); + + layerData.seek(2 + i * 2); + layerData.seek(layerData.readUint16LE()); + + ptr->layers[i].unknown0 = layerData.readSint16LE(); + ptr->layers[i].posX = layerData.readSint16LE(); + ptr->layers[i].posY = layerData.readSint16LE(); + ptr->layers[i].animDeltaX = layerData.readSint16LE(); + ptr->layers[i].animDeltaY = layerData.readSint16LE(); + ptr->layers[i].transp = layerData.readSByte(); ptr->layers[i].framesCount = layerData.readSint16LE(); + // Going through the AnimFramePiece, finding the end for each layerPos = layerData.pos(); framesCount = 0; - layerData.seek(4, SEEK_CUR); - for (j = 0; j < ptr->layers[i].framesCount; - j++, framesCount++, layerData.seek(4, SEEK_CUR)) { + for (j = 0; j < ptr->layers[i].framesCount; j++) { + layerData.skip(4); // pictIndex, pieceIndex, destX, destY while (layerData.readByte() == 1) { framesCount++; - layerData.seek(4, SEEK_CUR); + layerData.skip(4); // pictIndex, pieceIndex, destX, destY } + framesCount++; } layerData.seek(layerPos); ptr->layers[i].frames = new AnimFramePiece[framesCount]; for (j = 0; j < framesCount; j++) { - ptr->layers[i].frames[j].pictIndex = layerData.readByte(); + ptr->layers[i].frames[j].pictIndex = layerData.readByte(); ptr->layers[i].frames[j].pieceIndex = layerData.readByte(); - ptr->layers[i].frames[j].destX = layerData.readSByte(); - ptr->layers[i].frames[j].destY = layerData.readSByte(); - ptr->layers[i].frames[j].notFinal = layerData.readSByte(); + ptr->layers[i].frames[j].destX = layerData.readSByte(); + ptr->layers[i].frames[j].destY = layerData.readSByte(); + ptr->layers[i].frames[j].notFinal = layerData.readSByte(); } } @@ -502,13 +498,13 @@ int16 Scenery::loadAnim(char search) { ptr->piecesCount = new uint32[picsCount]; for (i = 0; i < picsCount; i++) { - int16 pictDescId = _vm->_inter->load16(); + int16 pictDescId = _vm->_game->_script->readInt16(); loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]); - width = _vm->_inter->load16(); - height = _vm->_inter->load16(); - sprResId = _vm->_inter->load16(); + width = _vm->_game->_script->readInt16(); + height = _vm->_game->_script->readInt16(); + sprResId = _vm->_game->_script->readInt16(); for (sprIndex = 0; sprIndex < 20; sprIndex++) if (_spriteResId[sprIndex] == sprResId) break; @@ -517,27 +513,26 @@ int16 Scenery::loadAnim(char search) { _animPictToSprite[7 * sceneryIndex + i] = sprIndex; _spriteRefs[sprIndex]++; } else { - for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; + for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex]; sprIndex--) ; _animPictToSprite[7 * sceneryIndex + i] = sprIndex; - _spriteRefs[sprIndex] = 1; + _spriteRefs[sprIndex] = 1; _spriteResId[sprIndex] = sprResId; _vm->_draw->initSpriteSurf(sprIndex, width, height, 2); - _vm->_video->clearSurf(_vm->_draw->_spritesArray[sprIndex]); - _vm->_draw->_destSurface = sprIndex; - _vm->_draw->_spriteLeft = sprResId; + _vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]); + _vm->_draw->_destSurface = sprIndex; + _vm->_draw->_spriteLeft = sprResId; _vm->_draw->_transparency = 0; - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; + _vm->_draw->_destSpriteX = 0; + _vm->_draw->_destSpriteY = 0; _vm->_draw->spriteOperation(DRAW_LOADSPRITE); } } - delete[] extData; - + delete resource; return sceneryIndex + 100; } @@ -545,7 +540,7 @@ void Scenery::freeAnim(int16 index) { int16 spr; if (index == -1) - _vm->_inter->evalExpr(&index); + _vm->_game->_script->evalExpr(&index); if (_animPictCount[index] == 0) return; @@ -563,6 +558,7 @@ void Scenery::freeAnim(int16 index) { for (int i = 0; i < _animations[index].layersCount; i++) delete[] _animations[index].layers[i].frames; + delete[] _animations[index].layers; delete[] _animations[index].pieces; delete[] _animations[index].piecesCount; @@ -607,8 +603,8 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, return; _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, - _toRedrawRight - _toRedrawLeft + 1, - _toRedrawBottom - _toRedrawTop + 1); + _toRedrawRight - _toRedrawLeft + 1, + _toRedrawBottom - _toRedrawTop + 1); *_pCaptureCounter = *_pCaptureCounter + 1; } @@ -628,7 +624,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, while (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) <= frame) _vm->_vidPlayer->slotPlay(obj.videoSlot - 1); } else { - int16 curFrame = _vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1); + int16 curFrame = _vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1); uint8 frameWrap = curFrame / 256; frame = (frame + 1) % 256; @@ -636,17 +632,17 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, _vm->_vidPlayer->slotPlay(obj.videoSlot - 1); } - destX = 0; - destY = 0; - left = *(obj.pPosX); - top = *(obj.pPosY); - right = left + _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - 1; - bottom = top + _vm->_vidPlayer->getHeight(obj.videoSlot - 1) - 1; + destX = 0; + destY = 0; + left = *(obj.pPosX); + top = *(obj.pPosY); + right = left + _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - 1; + bottom = top + _vm->_vidPlayer->getHeight(obj.videoSlot - 1) - 1; if (flags & 2) { if (left < _vm->_mult->_animLeft) { destX += _vm->_mult->_animLeft - left; - left = _vm->_mult->_animLeft; + left = _vm->_mult->_animLeft; } if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right) @@ -654,7 +650,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, if (top < _vm->_mult->_animTop) { destY += _vm->_mult->_animTop - top; - top = _vm->_mult->_animTop; + top = _vm->_mult->_animTop; } if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom) @@ -663,7 +659,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, } else if (flags & 4) { if (left < _toRedrawLeft) { destX += _toRedrawLeft - left; - left = _toRedrawLeft; + left = _toRedrawLeft; } if (right > _toRedrawRight) @@ -671,16 +667,16 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, if (top < _toRedrawTop) { destY += _toRedrawTop - top; - top = _toRedrawTop; + top = _toRedrawTop; } if (bottom > _toRedrawBottom) bottom = _toRedrawBottom; } else { - _toRedrawTop = top; - _toRedrawLeft = left; - _toRedrawRight = right; + _toRedrawTop = top; + _toRedrawLeft = left; + _toRedrawRight = right; _toRedrawBottom = bottom; } @@ -690,7 +686,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, if (left < _vm->_mult->_animLeft) { destX += _vm->_mult->_animLeft - left; - left = _vm->_mult->_animLeft; + left = _vm->_mult->_animLeft; } if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right) @@ -698,40 +694,40 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, if (top < _vm->_mult->_animTop) { destY += _vm->_mult->_animTop - top; - top = _vm->_mult->_animTop; + top = _vm->_mult->_animTop; } if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom) bottom = _vm->_mult->_animTop + _vm->_mult->_animHeight - 1; - _vm->_draw->_spriteLeft = destX; - _vm->_draw->_spriteTop = destY; - _vm->_draw->_spriteRight = right - left + 1; - _vm->_draw->_spriteBottom = bottom - top + 1; - _vm->_draw->_destSpriteX = left; - _vm->_draw->_destSpriteY = top; + _vm->_draw->_spriteLeft = destX; + _vm->_draw->_spriteTop = destY; + _vm->_draw->_spriteRight = right - left + 1; + _vm->_draw->_spriteBottom = bottom - top + 1; + _vm->_draw->_destSpriteX = left; + _vm->_draw->_destSpriteY = top; _vm->_draw->_transparency = layer; if (layer & 0x80) _vm->_draw->_spriteLeft = _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - (destX + _vm->_draw->_spriteRight); _vm->_vidPlayer->slotCopyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getVidMem(), - _vm->_draw->_spriteLeft, _vm->_draw->_spriteTop, + _vm->_draw->_spriteLeft, _vm->_draw->_spriteTop, _vm->_draw->_spriteRight, _vm->_draw->_spriteBottom, _vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY, _vm->_draw->_backSurface->getWidth(), (_vm->_draw->_transparency != 0) ? 0 : -1); _vm->_draw->invalidateRect(_vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY, - _vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1, + _vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1, _vm->_draw->_destSpriteY + _vm->_draw->_spriteBottom - 1); } if (!(flags & 4)) { - _animLeft = _toRedrawLeft = left; - _animTop = _toRedrawTop = top; - _animRight = _toRedrawRight = right; + _animLeft = _toRedrawLeft = left; + _animTop = _toRedrawTop = top; + _animRight = _toRedrawRight = right; _animBottom = _toRedrawBottom = bottom; } @@ -757,13 +753,13 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, return; _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, - _toRedrawRight - _toRedrawLeft + 1, - _toRedrawBottom - _toRedrawTop + 1); + _toRedrawRight - _toRedrawLeft + 1, + _toRedrawBottom - _toRedrawTop + 1); *_pCaptureCounter = *_pCaptureCounter + 1; } - pictPtr = _animations[animation].pieces; + pictPtr = _animations[animation].pieces; framePtr = layerPtr->frames; for (i = 0; i < frame; i++, framePtr++) @@ -771,9 +767,9 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, framePtr++; if (flags & 4) { - _toRedrawLeft = MAX(_toRedrawLeft, _vm->_mult->_animLeft); - _toRedrawTop = MAX(_toRedrawTop, _vm->_mult->_animTop); - _toRedrawRight = MIN(_toRedrawRight, + _toRedrawLeft = MAX(_toRedrawLeft, _vm->_mult->_animLeft); + _toRedrawTop = MAX(_toRedrawTop, _vm->_mult->_animTop); + _toRedrawRight = MIN(_toRedrawRight, (int16)(_vm->_mult->_animLeft + _vm->_mult->_animWidth - 1)); _toRedrawBottom = MIN(_toRedrawBottom, (int16)(_vm->_mult->_animTop + _vm->_mult->_animHeight - 1)); @@ -844,7 +840,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, (_vm->_mult->_animLeft + _vm->_mult->_animWidth) + 1; if (destY < _vm->_mult->_animTop) { - top += _vm->_mult->_animTop - destY; + top += _vm->_mult->_animTop - destY; destY = _vm->_mult->_animTop; } @@ -863,7 +859,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, right -= destX + right - left - _toRedrawRight; if (destY < _toRedrawTop) { - top += _toRedrawTop - destY; + top += _toRedrawTop - destY; destY = _toRedrawTop; } @@ -877,33 +873,33 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, if (doDraw) { _vm->_draw->_sourceSurface = _animPictToSprite[animation * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = 21; - _vm->_draw->_spriteLeft = left; - _vm->_draw->_spriteTop = top; - _vm->_draw->_spriteRight = right - left + 1; + _vm->_draw->_spriteLeft = left; + _vm->_draw->_spriteTop = top; + _vm->_draw->_spriteRight = right - left + 1; _vm->_draw->_spriteBottom = bottom - top + 1; - _vm->_draw->_destSpriteX = destX; - _vm->_draw->_destSpriteY = destY; + _vm->_draw->_destSpriteX = destX; + _vm->_draw->_destSpriteY = destY; _vm->_draw->_transparency = transp; _vm->_draw->spriteOperation(DRAW_BLITSURF); } if (!(flags & 4)) { if (_toRedrawLeft == -12345) { - _toRedrawLeft = destX; - _animLeft = destX; - _toRedrawTop = destY; - _animTop = destY; - _toRedrawRight = destX + right - left; - _animRight = destX + right - left; + _toRedrawLeft = destX; + _animLeft = destX; + _toRedrawTop = destY; + _animTop = destY; + _toRedrawRight = destX + right - left; + _animRight = destX + right - left; _toRedrawBottom = destY + bottom - top; - _animBottom = destY + bottom - top; + _animBottom = destY + bottom - top; } else { - _toRedrawLeft = MIN(_toRedrawLeft, destX); - _toRedrawTop = MIN(_toRedrawTop, destY); - _toRedrawRight = - MAX(_toRedrawRight, (int16)(destX + right - left)); + _toRedrawLeft = MIN(_toRedrawLeft, destX); + _toRedrawTop = MIN(_toRedrawTop, destY); + _toRedrawRight = + MAX(_toRedrawRight, (int16)(destX + right - left)); _toRedrawBottom = MAX(_toRedrawBottom, (int16)(destY + bottom - top)); } @@ -952,41 +948,23 @@ Scenery::AnimLayer *Scenery::getAnimLayer(uint16 index, uint16 layer) { } void Scenery::loadPieces(int16 pictDescId, PieceDesc *&pieceDesc, uint32 &piecesCount) { - byte *data; - uint32 size; - bool fromExt = false; - - if (pictDescId >= 30000) { - fromExt = true; - - uint32 eSize; - - data = _vm->_game->loadExtData(pictDescId, 0, 0, &eSize); - size = eSize; - } else { - int16 tSize; - - data = _vm->_game->loadTotResource(pictDescId, &tSize); - size = tSize; + Resource *resource = _vm->_game->_resources->getResource(pictDescId); + if (!resource) { + warning("Scenery::loadPieces(): Can't load %d", pictDescId); + return; } - if (!data) - error("Scenery::loadPieces(): Can't load pictDescId %d", pictDescId); - - piecesCount = size / 8; + piecesCount = resource->getSize() / 8; pieceDesc = new PieceDesc[piecesCount]; - Common::MemoryReadStream pieceData(data, size); - for (uint32 i = 0; i < piecesCount; i++) { - pieceDesc[i].left = (int16) pieceData.readUint16LE(); - pieceDesc[i].right = (int16) pieceData.readUint16LE(); - pieceDesc[i].top = (int16) pieceData.readUint16LE(); - pieceDesc[i].bottom = (int16) pieceData.readUint16LE(); + pieceDesc[i].left = resource->stream()->readSint16LE(); + pieceDesc[i].right = resource->stream()->readSint16LE(); + pieceDesc[i].top = resource->stream()->readSint16LE(); + pieceDesc[i].bottom = resource->stream()->readSint16LE(); } - if (fromExt) - delete[] data; + delete resource; } } // End of namespace Gob diff --git a/engines/gob/script.cpp b/engines/gob/script.cpp new file mode 100644 index 0000000000..6162e943bf --- /dev/null +++ b/engines/gob/script.cpp @@ -0,0 +1,522 @@ +/* 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/util.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/script.h" +#include "gob/dataio.h" +#include "gob/expression.h" +#include "gob/videoplayer.h" + +namespace Gob { + +Script::Script(GobEngine *vm) : _vm(vm) { + _expression = new Expression(vm); + + _finished = true; + + _totData = 0; + _totPtr = 0; + _totSize = 0; + + _lomHandle = -1; + + memset(&_totProperties, 0, sizeof(TOTFile::Properties)); +} + +Script::~Script() { + unload(); + + delete _expression; +} + +uint32 Script::read(byte *data, int32 size) { + int32 toRead = MIN<int32>(size, _totSize - (_totPtr - _totData)); + + if (toRead < 1) + return 0; + + memcpy(data, _totPtr, toRead); + _totPtr += toRead; + + return toRead; +} + +uint32 Script::peek(byte *data, int32 size, int32 offset) const { + int32 totOffset = ((_totPtr + offset) - _totData); + + if (totOffset < 1) + return 0; + if (((uint32) totOffset) >= _totSize) + return 0; + + int32 toPeek = MIN<int32>(size, _totSize - totOffset); + if (toPeek < 1) + return 0; + + memcpy(data, _totPtr + offset, toPeek); + + return toPeek; +} + +int32 Script::pos() const { + if (!_totData) + return -1; + + return _totPtr - _totData; +} + +int32 Script::getSize() const { + if (!_totData) + return -1; + + return _totSize; +} + +bool Script::seek(int32 offset, int whence) { + if (!_totData) + return false; + + if (whence == SEEK_CUR) + offset += pos(); + else if (whence == SEEK_END) + offset += _totSize; + + if ((offset < 0) || (((uint32) offset) >= _totSize)) + return false; + + // Cannot seek into the header + if (offset < 128) { + _finished = true; + return false; + } + + // A successful seek means the script file continues to be executed + _finished = false; + + _totPtr = _totData + offset; + + return true; +} + +bool Script::skip(int32 offset) { + return seek(offset, SEEK_CUR); +} + +int32 Script::getOffset(byte *ptr) const { + if (!_totData) + return -1; + + if ((ptr < _totData) || (ptr >= (_totData + _totSize))) + return -1; + + return ptr - _totData; +} + +byte *Script::getData(int32 offset) const { + if (!_totData) + return 0; + if ((offset < 0) || (((uint32) offset) >= _totSize)) + return 0; + + return _totData + offset; +} + +byte *Script::getData() { + return _totData; +} + +byte Script::readByte() { + byte v; + + read(&v, 1); + + return v; +} + +char Script::readChar() { + return (char) readByte(); +} + +uint8 Script::readUint8() { + return (uint8) readByte(); +} + +uint16 Script::readUint16() { + byte v[2]; + + read(v, 2); + + return READ_LE_UINT16(v); +} + +uint32 Script::readUint32() { + byte v[4]; + + read(v, 4); + + return READ_LE_UINT32(v); +} + +int8 Script::readInt8() { + return (int8) readByte(); +} + +int16 Script::readInt16() { + return (int16) readUint16(); +} + +int32 Script::readInt32() { + return (int32) readUint32(); +} + +char *Script::readString(int32 length) { + if (length < 0) { + length = 0; + while (_totPtr[length++] != '\0'); + } + + char *string = (char *) _totPtr; + + _totPtr += length; + + return string; +} + +byte Script::peekByte(int32 offset) { + byte v; + + peek(&v, 1, offset); + + return v; +} + +char Script::peekChar(int32 offset) { + return (char) peekByte(offset); +} + +uint8 Script::peekUint8(int32 offset) { + return (uint8) peekByte(offset); +} + +uint16 Script::peekUint16(int32 offset) { + byte v[2]; + + peek(v, 2, offset); + + return READ_LE_UINT16(v); +} + +uint32 Script::peekUint32(int32 offset) { + byte v[4]; + + peek(v, 4, offset); + + return READ_LE_UINT32(v); +} + +int8 Script::peekInt8(int32 offset) { + return (int8) peekByte(offset); +} + +int16 Script::peekInt16(int32 offset) { + return (int16) peekUint16(offset); +} + +int32 Script::peekInt32(int32 offset) { + return (int32) peekUint32(offset); +} + +char *Script::peekString(int32 offset) { + return (char *) (_totPtr + offset); +} + +int16 Script::readVarIndex(uint16 *size, uint16 *type) { + return _expression->parseVarIndex(size, type); +} + +int16 Script::readValExpr(byte stopToken) { + return _expression->parseValExpr(stopToken); +} + +int16 Script::readExpr(byte stopToken, byte *type) { + return _expression->parseExpr(stopToken, type); +} + +void Script::skipExpr(char stopToken) { + _expression->skipExpr(stopToken); +} + +char Script::evalExpr(int16 *pRes) { + byte type; + + _expression->printExpr(99); + + _expression->parseExpr(99, &type); + if (!pRes) + return type; + + switch (type) { + case TYPE_IMM_INT16: + *pRes = _expression->getResultInt(); + break; + + case TYPE_IMM_STR: + case GOB_FALSE: + *pRes = 0; + break; + + case GOB_TRUE: + *pRes = 1; + break; + } + + return type; +} + +bool Script::evalBoolResult() { + byte type; + + _expression->printExpr(99); + + _expression->parseExpr(99, &type); + if ( (type == GOB_TRUE) || + ((type == TYPE_IMM_INT16) && _expression->getResultInt())) + return true; + else + return false; +} + +int32 Script::getResultInt() const { + return _expression->getResultInt(); +} + +char *Script::getResultStr() const { + return _expression->getResultStr(); +} + +bool Script::load(const Common::String &fileName) { + unload(); + + _finished = false; + + bool isLOM; + + _totFile = TOTFile::createFileName(fileName, isLOM); + + if (isLOM) { + if (!loadLOM(_totFile)) { + unload(); + return false; + } + } else { + if (!loadTOT(_totFile)) { + unload(); + return false; + } + } + + return true; +} + +bool Script::loadTOT(const Common::String &fileName) { + TOTFile totFile(_vm); + + if (!totFile.load(fileName)) + return false; + + Common::SeekableReadStream *stream = totFile.getStream(); + if (!stream) + return false; + + if (!totFile.getProperties(_totProperties)) + return false; + + _totSize = _totProperties.scriptEnd; + if (_totSize <= 0) + return false; + + _totData = new byte[_totSize]; + if (stream->read(_totData, _totSize) != _totSize) + return false; + + return true; +} + +bool Script::loadLOM(const Common::String &fileName) { + warning("Stub: Script::loadLOM(%s)", _totFile.c_str()); + + _lomHandle = _vm->_dataIO->openData(_totFile.c_str()); + if (_lomHandle < 0) + return false; + + DataStream *stream = _vm->_dataIO->openAsStream(_lomHandle); + + stream->seek(48); + _totSize = stream->readUint32LE(); + stream->seek(0); + + _totData = new byte[_totSize]; + stream->read(_totData, _totSize); + + delete stream; + + return false; +} + +void Script::unload() { + unloadTOT(); +} + +void Script::unloadTOT() { + if (_lomHandle >= 0) + _vm->_dataIO->closeData(_lomHandle); + + // Unwind the call stack + while (!_callStack.empty()) + pop(); + + delete[] _totData; + + _totData = 0; + _totSize = 0; + _totPtr = 0; + _lomHandle = -1; + _totFile.clear(); + + _finished = true; +} + +bool Script::isLoaded() const { + return _totData != 0; +} + +void Script::setFinished(bool finished) { + _finished = finished; +} + +bool Script::isFinished() const { + return _finished; +} + +void Script::push() { + if (!isLoaded()) + // Nothing to do + return; + + CallEntry currentCall; + + currentCall.totPtr = _totPtr; + currentCall.finished = _finished; + + _callStack.push(currentCall); +} + +void Script::pop(bool ret) { + if (!isLoaded()) + // Nothing to do + return; + + // Unmatched pop? + assert(!_callStack.empty()); + + CallEntry lastCall = _callStack.pop(); + + if (ret) { + _totPtr = lastCall.totPtr; + _finished = lastCall.finished; + } +} + +void Script::call(uint32 offset) { + if (!isLoaded()) + // Nothing to do + return; + + push(); + seek(offset); +} + +uint8 Script::getVersionMajor() const { + return _totProperties.versionMajor; +} + +uint8 Script::getVersionMinor() const { + return _totProperties.versionMinor; +} + +uint32 Script::getVariablesCount() const { + return _totProperties.variablesCount; +} + +uint32 Script::getTextsOffset() const { + return _totProperties.textsOffset; +} + +uint32 Script::getResourcesOffset() const { + return _totProperties.resourcesOffset; +} + +uint16 Script::getAnimDataSize() const { + return _totProperties.animDataSize; +} + +uint8 Script::getImFileNumber() const { + return _totProperties.imFileNumber; +} + +uint8 Script::getExFileNumber() const { + return _totProperties.exFileNumber; +} + +uint8 Script::getCommunHandling() const { + return _totProperties.communHandling; +} + +uint16 Script::getFunctionOffset(uint8 function) const { + if (!_totData) + return 0; + + // Offsets 100-128, 2 bytes per function + assert(function <= 13); + + return _totProperties.functions[function]; +} + +uint32 Script::getVariablesCount(const char *fileName, GobEngine *vm) { + DataStream *stream = vm->_dataIO->getDataStream(fileName); + if (!stream) + return 0; + + stream->seek(0x2C); + uint32 variablesCount = stream->readUint32LE(); + delete stream; + + return variablesCount; +} + +} // End of namespace Gob diff --git a/engines/gob/script.h b/engines/gob/script.h new file mode 100644 index 0000000000..64a04503b1 --- /dev/null +++ b/engines/gob/script.h @@ -0,0 +1,169 @@ +/* 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_SCRIPT_H +#define GOB_SCRIPT_H + +#include "common/str.h" +#include "common/stack.h" + +#include "gob/totfile.h" + +namespace Gob { + +class GobEngine; +class Expression; + +class Script { +public: + Script(GobEngine *vm); + ~Script(); + + /** Read data and move the pointer accordingly. */ + uint32 read(byte *data, int32 size); + /** Read data (from an optional offset) without moving the pointer. */ + uint32 peek(byte *data, int32 size, int32 offset = 0) const; + + // Stream properties + int32 pos() const; + int32 getSize() const; + + // Stream seeking + bool seek(int32 offset, int whence = SEEK_SET); + bool skip(int32 offset); + + // Reading data + byte readByte (); + char readChar (); + uint8 readUint8 (); + uint16 readUint16(); + uint32 readUint32(); + int8 readInt8 (); + int16 readInt16 (); + int32 readInt32 (); + char *readString(int32 length = -1); + + // Peeking data + byte peekByte (int32 offset = 0); + char peekChar (int32 offset = 0); + uint8 peekUint8 (int32 offset = 0); + uint16 peekUint16(int32 offset = 0); + uint32 peekUint32(int32 offset = 0); + int8 peekInt8 (int32 offset = 0); + int16 peekInt16 (int32 offset = 0); + int32 peekInt32 (int32 offset = 0); + char *peekString(int32 offset = 0); + + // Expression parsing functions + int16 readVarIndex(uint16 *size = 0, uint16 *type = 0); + int16 readValExpr(byte stopToken = 99); + int16 readExpr(byte stopToken, byte *type); + void skipExpr(char stopToken); + + // Higher-level expression parsing functions + char evalExpr(int16 *pRes); + bool evalBoolResult(); + + // Accessing the result of expressions + int32 getResultInt() const; + char *getResultStr() const; + + /** Returns the offset the specified pointer is within the script data. */ + int32 getOffset(byte *ptr) const; + /** Returns the data pointer to the offset. */ + byte *getData(int32 offset) const; + + /** Returns the raw data pointer. */ + byte *getData(); + + /** Load a script file. */ + bool load(const Common::String &fileName); + /** Unload the script. */ + void unload(); + /** Was a script loaded? */ + bool isLoaded() const; + + /** Setting the 'finished' property. */ + void setFinished(bool finished); + /** Querying the 'finished' property. */ + bool isFinished() const; + + // Call stack operations + /** Push the current script position onto the call stack. */ + void push(); + /** Pop a script position from the call stack (and return there). */ + void pop(bool ret = true); + /** Push the current script position and branch to the specified offset. */ + void call(uint32 offset); + + // Fixed properties + uint8 getVersionMajor () const; + uint8 getVersionMinor () const; + uint32 getVariablesCount () const; + uint32 getTextsOffset () const; + uint32 getResourcesOffset() const; + uint16 getAnimDataSize () const; + uint8 getImFileNumber () const; + uint8 getExFileNumber () const; + uint8 getCommunHandling () const; + + uint16 getFunctionOffset (uint8 function) const; + + static uint32 getVariablesCount(const char *fileName, GobEngine *vm); + +private: + struct CallEntry { + byte *totPtr; + bool finished; + }; + + GobEngine *_vm; + Expression *_expression; + + bool _finished; + + Common::String _totFile; + byte *_totData; + byte *_totPtr; + uint32 _totSize; + + int16 _lomHandle; + + TOTFile::Properties _totProperties; + + Common::Stack<CallEntry> _callStack; + + /** Loading a TOT file. */ + bool loadTOT(const Common::String &fileName); + /** Loading a LOM file. */ + bool loadLOM(const Common::String &fileName); + + /** Unloading a TOT file. */ + void unloadTOT(); +}; + +} // End of namespace Gob + +#endif // GOB_SCRIPT_H diff --git a/engines/gob/sound/adlib.cpp b/engines/gob/sound/adlib.cpp index 07481431b6..7ab8e1f8dd 100644 --- a/engines/gob/sound/adlib.cpp +++ b/engines/gob/sound/adlib.cpp @@ -39,18 +39,33 @@ const unsigned char AdLib::_volRegNums[] = { }; AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer) { + init(); +} + +AdLib::~AdLib() { + Common::StackLock slock(_mutex); + + _mixer->stopHandle(_handle); + OPLDestroy(_opl); + if (_data && _freeData) + delete[] _data; +} + +void AdLib::init() { _index = -1; _data = 0; _playPos = 0; _dataSize = 0; _rate = _mixer->getOutputRate(); + _opl = makeAdlibOPL(_rate); _first = true; _ended = false; _playing = false; - _needFree = false; + + _freeData = false; _repCount = -1; _samplesTillPoll = 0; @@ -63,15 +78,6 @@ AdLib::AdLib(Audio::Mixer &mixer) : _mixer(&mixer) { this, -1, 255, 0, false, true); } -AdLib::~AdLib() { - Common::StackLock slock(_mutex); - - _mixer->stopHandle(_handle); - OPLDestroy(_opl); - if (_data && _needFree) - delete[] _data; -} - int AdLib::readBuffer(int16 *buffer, const int numSamples) { Common::StackLock slock(_mutex); int samples; @@ -107,7 +113,9 @@ int AdLib::readBuffer(int16 *buffer, const int numSamples) { if (_ended) { _first = true; _ended = false; - _playPos = _data + 3 + (_data[1] + 1) * 0x38; + + rewind(); + _samplesTillPoll = 0; if (_repCount == -1) { reset(); @@ -120,7 +128,6 @@ int AdLib::readBuffer(int16 *buffer, const int numSamples) { else _playing = false; } - return numSamples; } @@ -173,48 +180,6 @@ void AdLib::reset() { writeOPL(0x01, 0x20); } -void AdLib::setVoices() { - // Definitions of the 9 instruments - for (int i = 0; i < 9; i++) - setVoice(i, i, true); -} - -void AdLib::setVoice(byte voice, byte instr, bool set) { - int i; - int j; - uint16 strct[27]; - byte channel; - byte *dataPtr; - - // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26 - // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27 - for (i = 0; i < 2; i++) { - dataPtr = _data + 3 + instr * 0x38 + i * 0x1A; - for (j = 0; j < 27; j++) { - strct[j] = READ_LE_UINT16(dataPtr); - dataPtr += 2; - } - channel = _operators[voice] + i * 3; - writeOPL(0xBD, 0x00); - writeOPL(0x08, 0x00); - writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F)); - if (!i) - writeOPL(0xC0 | voice, - ((strct[2] & 7) << 1) | (1 - (strct[12] & 1))); - writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF)); - writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF)); - writeOPL(0x20 | channel, ((strct[9] & 1) << 7) | - ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) | - ((strct[11] & 1) << 4) | (strct[1] & 0xF)); - if (!i) - writeOPL(0xE0 | channel, (strct[26] & 3)); - else - writeOPL(0xE0 | channel, (strct[14] & 3)); - if (i && set) - writeOPL(0x40 | channel, 0); - } -} - void AdLib::setKey(byte voice, byte note, bool on, bool spec) { short freq = 0; short octa = 0; @@ -278,7 +243,7 @@ void AdLib::setKey(byte voice, byte note, bool on, bool spec) { writeOPL(0xB0 + voice, (freq >> 8) | (octa << 2) | 0x20 * on); if (!freq) - warning("Voice %d, note %02X unknown", voice, note); + warning("AdLib: Voice %d, note %02X unknown", voice, note); } void AdLib::setVolume(byte voice, byte volume) { @@ -287,17 +252,102 @@ void AdLib::setVolume(byte voice, byte volume) { } void AdLib::pollMusic() { + if ((_playPos > (_data + _dataSize)) && (_dataSize != 0xFFFFFFFF)) { + _ended = true; + return; + } + + interpret(); +} + +void AdLib::unload() { + _playing = false; + _index = -1; + + if (_data && _freeData) + delete[] _data; + + _freeData = false; +} + +bool AdLib::isPlaying() const { + return _playing; +} + +bool AdLib::getRepeating() const { + return _repCount != 0; +} + +void AdLib::setRepeating(int32 repCount) { + _repCount = repCount; +} + +int AdLib::getIndex() const { + return _index; +} + +void AdLib::startPlay() { + if (_data) _playing = true; +} + +void AdLib::stopPlay() { + Common::StackLock slock(_mutex); + _playing = false; +} + +ADLPlayer::ADLPlayer(Audio::Mixer &mixer) : AdLib(mixer) { +} + +ADLPlayer::~ADLPlayer() { +} + +bool ADLPlayer::load(const char *fileName) { + Common::File song; + + unload(); + song.open(fileName); + if (!song.isOpen()) + return false; + + _freeData = true; + _dataSize = song.size(); + _data = new byte[_dataSize]; + song.read(_data, _dataSize); + song.close(); + + reset(); + setVoices(); + _playPos = _data + 3 + (_data[1] + 1) * 0x38; + + return true; +} + +bool ADLPlayer::load(byte *data, uint32 size, int index) { + unload(); + _repCount = 0; + + _dataSize = size; + _data = data; + _index = index; + + reset(); + setVoices(); + _playPos = _data + 3 + (_data[1] + 1) * 0x38; + + return true; +} + +void ADLPlayer::unload() { + AdLib::unload(); +} + +void ADLPlayer::interpret() { unsigned char instr; byte channel; byte note; byte volume; uint16 tempo; - if ((_playPos > (_data + _dataSize)) && (_dataSize != 0xFFFFFFFF)) { - _ended = true; - return; - } - // First tempo, we'll ignore it... if (_first) { tempo = *(_playPos++); @@ -352,7 +402,7 @@ void AdLib::pollMusic() { _samplesTillPoll = 0; return; default: - warning("Unknown special command in ADL, stopping playback: %X", + warning("ADLPlayer: Unknown special command %X, stopping playback", instr & 0x0F); _repCount = 0; _ended = true; @@ -360,7 +410,7 @@ void AdLib::pollMusic() { } break; default: - warning("Unknown command in ADL, stopping playback: %X", + warning("ADLPlayer: Unknown command %X, stopping playback", instr & 0xF0); _repCount = 0; _ended = true; @@ -383,75 +433,349 @@ void AdLib::pollMusic() { _samplesTillPoll = tempo * (_rate / 1000); } -bool AdLib::load(const char *fileName) { +void ADLPlayer::reset() { + AdLib::reset(); +} + +void ADLPlayer::rewind() { + _playPos = _data + 3 + (_data[1] + 1) * 0x38; +} + +void ADLPlayer::setVoices() { + // Definitions of the 9 instruments + for (int i = 0; i < 9; i++) + setVoice(i, i, true); +} + +void ADLPlayer::setVoice(byte voice, byte instr, bool set) { + uint16 strct[27]; + byte channel; + byte *dataPtr; + + // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26 + // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27 + for (int i = 0; i < 2; i++) { + dataPtr = _data + 3 + instr * 0x38 + i * 0x1A; + for (int j = 0; j < 27; j++) { + strct[j] = READ_LE_UINT16(dataPtr); + dataPtr += 2; + } + channel = _operators[voice] + i * 3; + writeOPL(0xBD, 0x00); + writeOPL(0x08, 0x00); + writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F)); + if (!i) + writeOPL(0xC0 | voice, + ((strct[2] & 7) << 1) | (1 - (strct[12] & 1))); + writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF)); + writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF)); + writeOPL(0x20 | channel, ((strct[9] & 1) << 7) | + ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) | + ((strct[11] & 1) << 4) | (strct[1] & 0xF)); + if (!i) + writeOPL(0xE0 | channel, (strct[26] & 3)); + else + writeOPL(0xE0 | channel, (strct[14] & 3)); + if (i && set) + writeOPL(0x40 | channel, 0); + } +} + + +MDYPlayer::MDYPlayer(Audio::Mixer &mixer) : AdLib(mixer) { + init(); +} + +MDYPlayer::~MDYPlayer() { +} + +void MDYPlayer::init() { + _soundMode = 0; + + _timbres = 0; + _tbrCount = 0; + _tbrStart = 0; + _timbresSize = 0; +} + +bool MDYPlayer::loadMDY(Common::SeekableReadStream &stream) { + unloadMDY(); + + _freeData = true; + + byte mdyHeader[70]; + stream.read(mdyHeader, 70); + + _tickBeat = mdyHeader[36]; + _beatMeasure = mdyHeader[37]; + _totalTick = mdyHeader[38] + (mdyHeader[39] << 8) + (mdyHeader[40] << 16) + (mdyHeader[41] << 24); + _dataSize = mdyHeader[42] + (mdyHeader[43] << 8) + (mdyHeader[44] << 16) + (mdyHeader[45] << 24); + _nrCommand = mdyHeader[46] + (mdyHeader[47] << 8) + (mdyHeader[48] << 16) + (mdyHeader[49] << 24); +// _soundMode is either 0 (melodic) or 1 (percussive) + _soundMode = mdyHeader[58]; + _pitchBendRangeStep = 25*mdyHeader[59]; + _basicTempo = mdyHeader[60] + (mdyHeader[61] << 8); + + if (_pitchBendRangeStep < 25) + _pitchBendRangeStep = 25; + else if (_pitchBendRangeStep > 300) + _pitchBendRangeStep = 300; + + _data = new byte[_dataSize]; + stream.read(_data, _dataSize); + + reset(); + _playPos = _data; + + return true; +} + +bool MDYPlayer::loadMDY(const char *fileName) { Common::File song; - unload(); song.open(fileName); if (!song.isOpen()) return false; - _needFree = true; - _dataSize = song.size(); - _data = new byte[_dataSize]; - song.read(_data, _dataSize); - song.close(); + bool loaded = loadMDY(song); - reset(); - setVoices(); - _playPos = _data + 3 + (_data[1] + 1) * 0x38; + song.close(); - return true; + return loaded; } -bool AdLib::load(byte *data, uint32 size, int index) { - unload(); - _repCount = 0; +bool MDYPlayer::loadTBR(Common::SeekableReadStream &stream) { + unloadTBR(); - _dataSize = size; - _data = data; - _index = index; + _timbresSize = stream.size(); + + _timbres = new byte[_timbresSize]; + stream.read(_timbres, _timbresSize); reset(); setVoices(); - _playPos = _data + 3 + (_data[1] + 1) * 0x38; return true; } -void AdLib::unload() { - _playing = false; - _index = -1; +bool MDYPlayer::loadTBR(const char *fileName) { + Common::File timbres; - if (_data && _needFree) - delete[] _data; + timbres.open(fileName); + if (!timbres.isOpen()) + return false; + + bool loaded = loadTBR(timbres); - _needFree = false; + timbres.close(); + + return loaded; } -bool AdLib::isPlaying() const { - return _playing; +void MDYPlayer::unload() { + unloadTBR(); + unloadMDY(); } -bool AdLib::getRepeating() const { - return _repCount != 0; +void MDYPlayer::unloadMDY() { + AdLib::unload(); } -void AdLib::setRepeating(int32 repCount) { - _repCount = repCount; +void MDYPlayer::unloadTBR() { + delete[] _timbres; + + _timbres = 0; + _timbresSize = 0; } -int AdLib::getIndex() const { - return _index; +void MDYPlayer::interpret() { + unsigned char instr; + byte channel; + byte note; + byte volume; + uint8 tempoMult, tempoFrac; + uint8 ctrlByte1, ctrlByte2; + uint8 timbre; + + if (_first) { + for (int i = 0; i < 11; i ++) + setVolume(i, 0); + +// TODO : Set pitch range + + _tempo = _basicTempo; + _wait = *(_playPos++); + _first = false; + } + do { + instr = *_playPos; +// printf("instr 0x%X\n", instr); + switch(instr) { + case 0xF8: + _wait = *(_playPos++); + break; + case 0xFC: + _ended = true; + _samplesTillPoll = 0; + return; + case 0xF0: + _playPos++; + ctrlByte1 = *(_playPos++); + ctrlByte2 = *(_playPos++); + if (ctrlByte1 != 0x7F || ctrlByte2 != 0) { + _playPos -= 2; + while (*(_playPos++) != 0xF7); + } else { + tempoMult = *(_playPos++); + tempoFrac = *(_playPos++); + _tempo = _basicTempo * tempoMult + (unsigned)(((long)_basicTempo * tempoFrac) >> 7); + _playPos++; + } + _wait = *(_playPos++); + break; + default: + if (instr >= 0x80) { + _playPos++; + } + channel = (int)(instr & 0x0f); + + switch(instr & 0xf0) { + case 0x90: + note = *(_playPos++); + volume = *(_playPos++); + _pollNotes[channel] = note; + setVolume(channel, volume); + setKey(channel, note, true, false); + break; + case 0x80: + _playPos += 2; + note = _pollNotes[channel]; + setKey(channel, note, false, false); + break; + case 0xA0: + setVolume(channel, *(_playPos++)); + break; + case 0xC0: + timbre = *(_playPos++); + setVoice(channel, timbre, false); + break; + case 0xE0: + warning("MDYPlayer: Pitch bend not yet implemented"); + + note = *(_playPos)++; + note += (unsigned)(*(_playPos++)) << 7; + + setKey(channel, note, _notOn[channel], true); + + break; + case 0xB0: + _playPos += 2; + break; + case 0xD0: + _playPos++; + break; + default: + warning("MDYPlayer: Bad MIDI instr byte: 0%X", instr); + while ((*_playPos) < 0x80) + _playPos++; + if (*_playPos != 0xF8) + _playPos--; + break; + } //switch instr & 0xF0 + _wait = *(_playPos++); + break; + } //switch instr + } while (_wait == 0); + + if (_wait == 0xF8) { + _wait = 0xF0; + if (*_playPos != 0xF8) + _wait += *(_playPos++); + } +// _playPos++; + _samplesTillPoll = _wait * (_rate / 1000); } -void AdLib::startPlay() { - if (_data) _playing = true; +void MDYPlayer::reset() { + AdLib::reset(); + +// _soundMode 1 : Percussive mode. + if (_soundMode == 1) { + writeOPL(0xA6, 0); + writeOPL(0xB6, 0); + writeOPL(0xA7, 0); + writeOPL(0xB7, 0); + writeOPL(0xA8, 0); + writeOPL(0xB8, 0); + +// TODO set the correct frequency for the last 4 percussive voices + } } -void AdLib::stopPlay() { - Common::StackLock slock(_mutex); - _playing = false; +void MDYPlayer::rewind() { + _playPos = _data; +} + +void MDYPlayer::setVoices() { + byte *timbrePtr; + + timbrePtr = _timbres; + debugC(6, kDebugSound, "TBR version: %X.%X", timbrePtr[0], timbrePtr[1]); + timbrePtr += 2; + + _tbrCount = READ_LE_UINT16(timbrePtr); + debugC(6, kDebugSound, "Timbres counter: %d", _tbrCount); + timbrePtr += 2; + _tbrStart = READ_LE_UINT16(timbrePtr); + + timbrePtr += 2; + for (int i = 0; i < _tbrCount ; i++) + setVoice(i, i, true); +} + +void MDYPlayer::setVoice(byte voice, byte instr, bool set) { + uint16 strct[27]; + byte channel; + byte *timbrePtr; + char timbreName[10]; + + timbreName[9] = '\0'; + for (int j = 0; j < 9; j++) + timbreName[j] = _timbres[6 + j + (instr * 9)]; + debugC(6, kDebugSound, "Loading timbre %s", timbreName); + + // i = 0 : 0 1 2 3 4 5 6 7 8 9 10 11 12 26 + // i = 1 : 13 14 15 16 17 18 19 20 21 22 23 24 25 27 + for (int i = 0; i < 2; i++) { + timbrePtr = _timbres + _tbrStart + instr * 0x38 + i * 0x1A; + for (int j = 0; j < 27; j++) { + if (timbrePtr >= (_timbres + _timbresSize)) { + warning("MDYPlayer: Instrument %d out of range (%d, %d)", instr, + (uint32) (timbrePtr - _timbres), _timbresSize); + strct[j] = 0; + } else + strct[j] = READ_LE_UINT16(timbrePtr); + timbrePtr += 2; + } + channel = _operators[voice] + i * 3; + writeOPL(0xBD, 0x00); + writeOPL(0x08, 0x00); + writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F)); + if (!i) + writeOPL(0xC0 | voice, + ((strct[2] & 7) << 1) | (1 - (strct[12] & 1))); + writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF)); + writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF)); + writeOPL(0x20 | channel, ((strct[9] & 1) << 7) | + ((strct[10] & 1) << 6) | ((strct[5] & 1) << 5) | + ((strct[11] & 1) << 4) | (strct[1] & 0xF)); + if (!i) + writeOPL(0xE0 | channel, (strct[26] & 3)); + else { + writeOPL(0xE0 | channel, (strct[14] & 3)); + writeOPL(0x40 | channel, 0); + } + } } } // End of namespace Gob diff --git a/engines/gob/sound/adlib.h b/engines/gob/sound/adlib.h index 4cd83d5883..3f7b46643f 100644 --- a/engines/gob/sound/adlib.h +++ b/engines/gob/sound/adlib.h @@ -38,7 +38,7 @@ class GobEngine; class AdLib : public Audio::AudioStream { public: AdLib(Audio::Mixer &mixer); - ~AdLib(); + virtual ~AdLib(); bool isPlaying() const; int getIndex() const; @@ -49,9 +49,7 @@ public: void startPlay(); void stopPlay(); - bool load(const char *fileName); - bool load(byte *data, uint32 size, int index = -1); - void unload(); + virtual void unload(); // AudioStream API int readBuffer(int16 *buffer, const int numSamples); @@ -89,18 +87,88 @@ protected: bool _playing; bool _first; bool _ended; - bool _needFree; + + bool _freeData; int _index; + unsigned char _wait; + uint8 _tickBeat; + uint8 _beatMeasure; + uint32 _totalTick; + uint32 _nrCommand; + uint16 _pitchBendRangeStep; + uint16 _basicTempo, _tempo; + void writeOPL(byte reg, byte val); void setFreqs(); - void reset(); - void setVoices(); - void setVoice(byte voice, byte instr, bool set); void setKey(byte voice, byte note, bool on, bool spec); void setVolume(byte voice, byte volume); void pollMusic(); + + virtual void interpret() = 0; + + virtual void reset(); + virtual void rewind() = 0; + virtual void setVoices() = 0; + +private: + void init(); +}; + +class ADLPlayer : public AdLib { +public: + ADLPlayer(Audio::Mixer &mixer); + ~ADLPlayer(); + + bool load(const char *fileName); + bool load(byte *data, uint32 size, int index = -1); + + void unload(); + +protected: + void interpret(); + + void reset(); + void rewind(); + + void setVoices(); + void setVoice(byte voice, byte instr, bool set); +}; + +class MDYPlayer : public AdLib { +public: + MDYPlayer(Audio::Mixer &mixer); + ~MDYPlayer(); + + bool loadMDY(const char *fileName); + bool loadMDY(Common::SeekableReadStream &stream); + bool loadTBR(const char *fileName); + bool loadTBR(Common::SeekableReadStream &stream); + + void unload(); + +protected: + byte _soundMode; + + byte *_timbres; + uint16 _tbrCount; + uint16 _tbrStart; + uint32 _timbresSize; + + void interpret(); + + void reset(); + void rewind(); + + void setVoices(); + void setVoice(byte voice, byte instr, bool set); + + void unloadTBR(); + void unloadMDY(); + +private: + void init(); }; } // End of namespace Gob diff --git a/engines/gob/sound/bgatmosphere.cpp b/engines/gob/sound/bgatmosphere.cpp index 12ceb031b7..6ce184155e 100644 --- a/engines/gob/sound/bgatmosphere.cpp +++ b/engines/gob/sound/bgatmosphere.cpp @@ -27,6 +27,7 @@ #include "common/events.h" #include "gob/sound/bgatmosphere.h" +#include "gob/sound/sounddesc.h" namespace Gob { diff --git a/engines/gob/sound/bgatmosphere.h b/engines/gob/sound/bgatmosphere.h index 3fa648b94d..aa8cf58e10 100644 --- a/engines/gob/sound/bgatmosphere.h +++ b/engines/gob/sound/bgatmosphere.h @@ -29,11 +29,12 @@ #include "sound/mixer.h" #include "common/mutex.h" -#include "gob/sound/sounddesc.h" #include "gob/sound/soundmixer.h" namespace Gob { +class SoundDesc; + class BackgroundAtmosphere : private SoundMixer { public: enum PlayMode { diff --git a/engines/gob/sound/cdrom.cpp b/engines/gob/sound/cdrom.cpp index ec9b2aaccb..4d6a7ec966 100644 --- a/engines/gob/sound/cdrom.cpp +++ b/engines/gob/sound/cdrom.cpp @@ -30,6 +30,7 @@ #include "gob/gob.h" #include "gob/sound/cdrom.h" #include "gob/helper.h" +#include "gob/dataio.h" namespace Gob { @@ -86,7 +87,7 @@ void CDROM::startTrack(const char *trackName) { byte *matchPtr = getTrackBuffer(trackName); if (!matchPtr) { - warning("Track \"%s\" not found", trackName); + warning("CDROM: Track \"%s\" not found", trackName); return; } diff --git a/engines/gob/sound/cdrom.h b/engines/gob/sound/cdrom.h index 201f7adb75..6f01e6f90a 100644 --- a/engines/gob/sound/cdrom.h +++ b/engines/gob/sound/cdrom.h @@ -26,10 +26,10 @@ #ifndef GOB_SOUND_CDROM_H #define GOB_SOUND_CDROM_H -#include "gob/dataio.h" - namespace Gob { +class DataStream; + class CDROM { public: CDROM(); diff --git a/engines/gob/sound/infogrames.cpp b/engines/gob/sound/infogrames.cpp index 0b46f3485c..c955dba43f 100644 --- a/engines/gob/sound/infogrames.cpp +++ b/engines/gob/sound/infogrames.cpp @@ -55,7 +55,7 @@ bool Infogrames::loadSong(const char *fileName) { _mixer->getOutputRate(), _mixer->getOutputRate() / 75); if (!_song->load(fileName)) { - warning("Couldn't load infogrames music"); + warning("Infogrames: Couldn't load music \"%s\"", fileName); clearSong(); return false; } @@ -92,7 +92,7 @@ void Infogrames::clearSong() { bool Infogrames::loadInst(const char *fileName) { _instruments = new Audio::Infogrames::Instruments; if (!_instruments->load(fileName)) { - warning("Couldn't load instruments file"); + warning("Infogrames: Couldn't load instruments \"%s\"", fileName); clearInstruments(); return false; } diff --git a/engines/gob/sound/protracker.cpp b/engines/gob/sound/protracker.cpp index 891580ef40..3e33cfd494 100644 --- a/engines/gob/sound/protracker.cpp +++ b/engines/gob/sound/protracker.cpp @@ -25,6 +25,8 @@ #include "common/file.h" +#include "sound/mods/protracker.h" + #include "gob/sound/protracker.h" namespace Gob { diff --git a/engines/gob/sound/protracker.h b/engines/gob/sound/protracker.h index 6270530427..73cae0d510 100644 --- a/engines/gob/sound/protracker.h +++ b/engines/gob/sound/protracker.h @@ -28,7 +28,6 @@ #include "sound/mixer.h" #include "sound/audiostream.h" -#include "sound/mods/protracker.h" namespace Gob { diff --git a/engines/gob/sound/sound.cpp b/engines/gob/sound/sound.cpp index f0cf17b989..d3afc9baa3 100644 --- a/engines/gob/sound/sound.cpp +++ b/engines/gob/sound/sound.cpp @@ -31,20 +31,28 @@ #include "gob/game.h" #include "gob/inter.h" +#include "gob/sound/pcspeaker.h" +#include "gob/sound/soundblaster.h" +#include "gob/sound/adlib.h" +#include "gob/sound/infogrames.h" +#include "gob/sound/protracker.h" +#include "gob/sound/cdrom.h" + namespace Gob { Sound::Sound(GobEngine *vm) : _vm(vm) { _pcspeaker = new PCSpeaker(*_vm->_mixer); _blaster = new SoundBlaster(*_vm->_mixer); - _adlib = 0; + _adlPlayer = 0; + _mdyPlayer = 0; _infogrames = 0; _protracker = 0; _cdrom = 0; _bgatmos = 0; - if (!_vm->_noMusic && _vm->hasAdlib()) - _adlib = new AdLib(*_vm->_mixer); + _hasAdLib = (!_vm->_noMusic && _vm->hasAdlib()); + if (!_vm->_noMusic && (_vm->getPlatform() == Common::kPlatformAmiga)) { _infogrames = new Infogrames(*_vm->_mixer); _protracker = new Protracker(*_vm->_mixer); @@ -62,7 +70,8 @@ Sound::Sound(GobEngine *vm) : _vm(vm) { Sound::~Sound() { delete _pcspeaker; delete _blaster; - delete _adlib; + delete _adlPlayer; + delete _mdyPlayer; delete _infogrames; delete _protracker; delete _cdrom; @@ -105,14 +114,11 @@ bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName, debugC(2, kDebugSound, "Loading sample \"%s\"", fileName); - int16 handle = _vm->_dataIO->openData(fileName); - if (handle < 0) { + if (!_vm->_dataIO->existData(fileName)) { warning("Can't open sample file \"%s\"", fileName); return false; } - _vm->_dataIO->closeData(handle); - byte *data; uint32 size; @@ -121,7 +127,7 @@ bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName, return false; size = _vm->_dataIO->getDataSize(fileName); - return sndDesc->load(type, SOUND_FILE, data, size); + return sndDesc->load(type, data, size); } void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdlib, int index) { @@ -130,9 +136,14 @@ void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdlib, int index) { if (sndDesc->getType() == SOUND_ADL) { - if (_adlib && noteAdlib) - if ((index == -1) || (_adlib->getIndex() == index)) - _adlib->stopPlay(); + if (noteAdlib) { + if (_adlPlayer) + if ((index == -1) || (_adlPlayer->getIndex() == index)) + _adlPlayer->stopPlay(); + if (_mdyPlayer) + if ((index == -1) || (_mdyPlayer->getIndex() == index)) + _mdyPlayer->stopPlay(); + } } else { @@ -223,50 +234,112 @@ void Sound::infogramesStop() { _infogrames->stop(); } -bool Sound::adlibLoad(const char *fileName) { - if (!_adlib) +bool Sound::adlibLoadADL(const char *fileName) { + if (!_hasAdLib) return false; - debugC(1, kDebugSound, "Adlib: Loading data (\"%s\")", fileName); + if (!_adlPlayer) + _adlPlayer = new ADLPlayer(*_vm->_mixer); + + debugC(1, kDebugSound, "Adlib: Loading ADL data (\"%s\")", fileName); - return _adlib->load(fileName); + return _adlPlayer->load(fileName); } -bool Sound::adlibLoad(byte *data, uint32 size, int index) { - if (!_adlib) +bool Sound::adlibLoadADL(byte *data, uint32 size, int index) { + if (!_hasAdLib) return false; - debugC(1, kDebugSound, "Adlib: Loading data (%d)", index); + if (!_adlPlayer) + _adlPlayer = new ADLPlayer(*_vm->_mixer); + + debugC(1, kDebugSound, "Adlib: Loading ADL data (%d)", index); - return _adlib->load(data, size, index); + return _adlPlayer->load(data, size, index); } void Sound::adlibUnload() { - if (!_adlib) + if (!_hasAdLib) return; debugC(1, kDebugSound, "Adlib: Unloading data"); - _adlib->unload(); + if (_adlPlayer) + _adlPlayer->unload(); + if (_mdyPlayer) + _mdyPlayer->unload(); +} + +bool Sound::adlibLoadMDY(const char *fileName) { + if (!_hasAdLib) + return false; + + if (!_mdyPlayer) + _mdyPlayer = new MDYPlayer(*_vm->_mixer); + + debugC(1, kDebugSound, "Adlib: Loading MDY data (\"%s\")", fileName); + + if (!_vm->_dataIO->existData(fileName)) { + warning("Can't open MDY file \"%s\"", fileName); + return false; + } + + DataStream *stream = _vm->_dataIO->getDataStream(fileName); + + bool loaded = _mdyPlayer->loadMDY(*stream); + + delete stream; + + return loaded; +} + +bool Sound::adlibLoadTBR(const char *fileName) { + if (!_hasAdLib) + return false; + + if (!_mdyPlayer) + _mdyPlayer = new MDYPlayer(*_vm->_mixer); + + if (!_vm->_dataIO->existData(fileName)) { + warning("Can't open TBR file \"%s\"", fileName); + return false; + } + + debugC(1, kDebugSound, "Adlib: Loading MDY instruments (\"%s\")", fileName); + + DataStream *stream = _vm->_dataIO->getDataStream(fileName); + + bool loaded = _mdyPlayer->loadTBR(*stream); + + delete stream; + + return loaded; } void Sound::adlibPlayTrack(const char *trackname) { - if (!_adlib || _adlib->isPlaying()) + if (!_hasAdLib) return; - debugC(1, kDebugSound, "Adlib: Playing track \"%s\"", trackname); + if (!_adlPlayer) + _adlPlayer = new ADLPlayer(*_vm->_mixer); - _adlib->unload(); - _adlib->load(trackname); - _adlib->startPlay(); + if (_adlPlayer->isPlaying()) + return; + + debugC(1, kDebugSound, "Adlib: Playing ADL track \"%s\"", trackname); + + _adlPlayer->unload(); + _adlPlayer->load(trackname); + _adlPlayer->startPlay(); } void Sound::adlibPlayBgMusic() { - int track; - - if (!_adlib) + if (!_hasAdLib) return; + if (!_adlPlayer) + _adlPlayer = new ADLPlayer(*_vm->_mixer); + static const char *tracksMac[] = { // "musmac1.adl", // TODO: This track isn't played correctly at all yet "musmac2.adl", @@ -285,58 +358,82 @@ void Sound::adlibPlayBgMusic() { }; if (_vm->getPlatform() == Common::kPlatformWindows) { - track = _vm->_util->getRandom(ARRAYSIZE(tracksWin)); + int track = _vm->_util->getRandom(ARRAYSIZE(tracksWin)); adlibPlayTrack(tracksWin[track]); } else { - track = _vm->_util->getRandom(ARRAYSIZE(tracksMac)); + int track = _vm->_util->getRandom(ARRAYSIZE(tracksMac)); adlibPlayTrack(tracksMac[track]); } } void Sound::adlibPlay() { - if (!_adlib) + if (!_hasAdLib) return; debugC(1, kDebugSound, "Adlib: Starting playback"); - _adlib->startPlay(); + if (_adlPlayer) + _adlPlayer->startPlay(); + if (_mdyPlayer) + _mdyPlayer->startPlay(); } void Sound::adlibStop() { - if (!_adlib) + if (!_hasAdLib) return; debugC(1, kDebugSound, "Adlib: Stopping playback"); - _adlib->stopPlay(); + if (_adlPlayer) + _adlPlayer->stopPlay(); + if (_mdyPlayer) + _mdyPlayer->stopPlay(); } bool Sound::adlibIsPlaying() const { - if (!_adlib) + if (!_hasAdLib) return false; - return _adlib->isPlaying(); + if (_adlPlayer && _adlPlayer->isPlaying()) + return true; + if (_mdyPlayer && _mdyPlayer->isPlaying()) + return true; + + return false; } int Sound::adlibGetIndex() const { - if (!_adlib) + if (!_hasAdLib) return -1; - return _adlib->getIndex(); + if (_adlPlayer) + return _adlPlayer->getIndex(); + if (_mdyPlayer) + return _mdyPlayer->getIndex(); + + return -1; } bool Sound::adlibGetRepeating() const { - if (!_adlib) + if (!_hasAdLib) return false; - return _adlib->getRepeating(); + if (_adlPlayer) + return _adlPlayer->getRepeating(); + if (_mdyPlayer) + return _mdyPlayer->getRepeating(); + + return false; } void Sound::adlibSetRepeating(int32 repCount) { - if (!_adlib) + if (!_hasAdLib) return; - _adlib->setRepeating(repCount); + if (_adlPlayer) + _adlPlayer->setRepeating(repCount); + if (_mdyPlayer) + _mdyPlayer->setRepeating(repCount); } void Sound::blasterPlay(SoundDesc *sndDesc, int16 repCount, @@ -425,17 +522,12 @@ void Sound::cdLoadLIC(const char *fname) { debugC(1, kDebugSound, "CDROM: Loading LIC \"%s\"", fname); - int handle = _vm->_dataIO->openData(fname); - - if (handle == -1) + if (!_vm->_dataIO->existData(fname)) return; - _vm->_dataIO->closeData(handle); - _vm->_dataIO->getUnpackedData(fname); - handle = _vm->_dataIO->openData(fname); - DataStream *stream = _vm->_dataIO->openAsStream(handle, true); + DataStream *stream = _vm->_dataIO->getDataStream(fname); _cdrom->readLIC(*stream); diff --git a/engines/gob/sound/sound.h b/engines/gob/sound/sound.h index dbdd580ec7..6f6c1d0469 100644 --- a/engines/gob/sound/sound.h +++ b/engines/gob/sound/sound.h @@ -27,16 +27,19 @@ #define GOB_SOUND_SOUND_H #include "gob/sound/sounddesc.h" -#include "gob/sound/pcspeaker.h" -#include "gob/sound/soundblaster.h" -#include "gob/sound/adlib.h" -#include "gob/sound/infogrames.h" -#include "gob/sound/protracker.h" -#include "gob/sound/cdrom.h" #include "gob/sound/bgatmosphere.h" namespace Gob { +class GobEngine; +class PCSpeaker; +class SoundBlaster; +class ADLPlayer; +class MDYPlayer; +class Infogrames; +class Protracker; +class CDROM; + class Sound { public: static const int kSoundsCount = 60; @@ -77,8 +80,10 @@ public: // AdLib - bool adlibLoad(const char *fileName); - bool adlibLoad(byte *data, uint32 size, int index = -1); + bool adlibLoadADL(const char *fileName); + bool adlibLoadADL(byte *data, uint32 size, int index = -1); + bool adlibLoadMDY(const char *fileName); + bool adlibLoadTBR(const char *fileName); void adlibUnload(); void adlibPlayTrack(const char *trackname); @@ -139,11 +144,14 @@ public: private: GobEngine *_vm; + bool _hasAdLib; + SoundDesc _sounds[kSoundsCount]; PCSpeaker *_pcspeaker; SoundBlaster *_blaster; - AdLib *_adlib; + ADLPlayer *_adlPlayer; + MDYPlayer *_mdyPlayer; Infogrames *_infogrames; Protracker *_protracker; CDROM *_cdrom; diff --git a/engines/gob/sound/soundblaster.cpp b/engines/gob/sound/soundblaster.cpp index 23eea90688..69610dc949 100644 --- a/engines/gob/sound/soundblaster.cpp +++ b/engines/gob/sound/soundblaster.cpp @@ -24,6 +24,7 @@ */ #include "gob/sound/soundblaster.h" +#include "gob/sound/sounddesc.h" namespace Gob { diff --git a/engines/gob/sound/soundblaster.h b/engines/gob/sound/soundblaster.h index c57e4a443e..a2dc87267c 100644 --- a/engines/gob/sound/soundblaster.h +++ b/engines/gob/sound/soundblaster.h @@ -29,11 +29,12 @@ #include "common/mutex.h" #include "sound/mixer.h" -#include "gob/sound/sounddesc.h" #include "gob/sound/soundmixer.h" namespace Gob { +class SoundDesc; + class SoundBlaster : public SoundMixer { public: SoundBlaster(Audio::Mixer &mixer); diff --git a/engines/gob/sound/sounddesc.cpp b/engines/gob/sound/sounddesc.cpp index c4c78eebbd..b9b327d105 100644 --- a/engines/gob/sound/sounddesc.cpp +++ b/engines/gob/sound/sounddesc.cpp @@ -29,15 +29,17 @@ #include "sound/wave.h" #include "gob/sound/sounddesc.h" +#include "gob/resources.h" namespace Gob { SoundDesc::SoundDesc() { + _resource = 0; + _data = _dataPtr = 0; _size = 0; _type = SOUND_SND; - _source = SOUND_FILE; _repCount = 0; _frequency = 0; @@ -50,23 +52,31 @@ SoundDesc::~SoundDesc() { free(); } -void SoundDesc::set(SoundType type, SoundSource src, - byte *data, uint32 dSize) { - +void SoundDesc::set(SoundType type, byte *data, uint32 dSize) { free(); _type = type; - _source = src; _data = _dataPtr = data; _size = dSize; } -bool SoundDesc::load(SoundType type, SoundSource src, - byte *data, uint32 dSize) { +void SoundDesc::set(SoundType type, Resource *resource) { + byte *data = 0; + uint32 dSize = 0; + + if (resource && (resource->getSize() > 0)) { + data = resource->getData(); + dSize = resource->getSize(); + } + + set(type, data, dSize); + _resource = resource; +} + +bool SoundDesc::load(SoundType type, byte *data, uint32 dSize) { free(); - _source = src; switch (type) { case SOUND_ADL: return loadADL(data, dSize); @@ -79,10 +89,28 @@ bool SoundDesc::load(SoundType type, SoundSource src, return false; } +bool SoundDesc::load(SoundType type, Resource *resource) { + if (!resource || (resource->getSize() <= 0)) + return false; + + if (!load(type, resource->getData(), resource->getSize())) + return false; + + _resource = resource; + return true; +} + void SoundDesc::free() { - if (_source != SOUND_TOT) - delete[] _data; - _data = _dataPtr = 0; + if (_resource) { + delete _resource; + _data = 0; + } + + delete[] _data; + + _resource = 0; + _data = 0; + _dataPtr = 0; _id = 0; } diff --git a/engines/gob/sound/sounddesc.h b/engines/gob/sound/sounddesc.h index 83efd61e6d..9e5d20e138 100644 --- a/engines/gob/sound/sounddesc.h +++ b/engines/gob/sound/sounddesc.h @@ -30,18 +30,14 @@ namespace Gob { +class Resource; + enum SoundType { SOUND_SND, SOUND_WAV, SOUND_ADL }; -enum SoundSource { - SOUND_FILE, - SOUND_TOT, - SOUND_EXT -}; - class SoundDesc { public: int16 _repCount; @@ -58,8 +54,11 @@ public: bool isId(int16 id) const { return _dataPtr && (_id == id); } - void set(SoundType type, SoundSource src, byte *data, uint32 dSize); - bool load(SoundType type, SoundSource src, byte *data, uint32 dSize); + void set(SoundType type, byte *data, uint32 dSize); + void set(SoundType type, Resource *resource); + bool load(SoundType type, byte *data, uint32 dSize); + bool load(SoundType type, Resource *resource); + void free(); void convToSigned(); @@ -71,12 +70,12 @@ public: ~SoundDesc(); private: + Resource *_resource; byte *_data; byte *_dataPtr; uint32 _size; SoundType _type; - SoundSource _source; bool loadSND(byte *data, uint32 dSize); bool loadWAV(byte *data, uint32 dSize); diff --git a/engines/gob/sound/soundmixer.cpp b/engines/gob/sound/soundmixer.cpp index ea1dd2ef82..68a96d3b01 100644 --- a/engines/gob/sound/soundmixer.cpp +++ b/engines/gob/sound/soundmixer.cpp @@ -24,6 +24,7 @@ */ #include "gob/sound/soundmixer.h" +#include "gob/sound/sounddesc.h" namespace Gob { diff --git a/engines/gob/sound/soundmixer.h b/engines/gob/sound/soundmixer.h index f32beb149f..20376b5152 100644 --- a/engines/gob/sound/soundmixer.h +++ b/engines/gob/sound/soundmixer.h @@ -31,10 +31,10 @@ #include "sound/audiostream.h" #include "sound/mixer.h" -#include "gob/sound/sounddesc.h" - namespace Gob { +class SoundDesc; + class SoundMixer : public Audio::AudioStream { public: SoundMixer(Audio::Mixer &mixer, Audio::Mixer::SoundType type); diff --git a/engines/gob/totfile.cpp b/engines/gob/totfile.cpp new file mode 100644 index 0000000000..bbf62c143b --- /dev/null +++ b/engines/gob/totfile.cpp @@ -0,0 +1,135 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "common/str.h" +#include "common/stream.h" + +#include "gob/gob.h" +#include "gob/totfile.h" +#include "gob/dataio.h" +#include "gob/videoplayer.h" + +namespace Gob { + +TOTFile::TOTFile(GobEngine *vm) : _vm(vm) { + _stream = 0; + + memset(_header, 0, 128); +} + +TOTFile::~TOTFile() { + unload(); +} + +bool TOTFile::load(const Common::String &fileName) { + // Trying to open normally + _stream = _vm->_dataIO->getDataStream(fileName.c_str()); + + if (!_stream) + // Trying to open from video + _stream = _vm->_vidPlayer->getExtraData(fileName.c_str()); + + if (!_stream) + return false; + + if (_stream->read(_header, 128) != 128) + return false; + + _stream->seek(0); + + return true; +} + +void TOTFile::unload() { + delete _stream; + + _stream = 0; +} + +Common::SeekableReadStream *TOTFile::getStream() const { + return _stream; +} + +bool TOTFile::getProperties(Properties &props) const { + if (!_stream) + return false; + + // Offset 39-41: Version in "Major.Minor" string form + if (_header[40] != '.') + return false; + + props.versionMajor = _header[39] - '0'; + props.versionMinor = _header[41] - '0'; + + props.variablesCount = READ_LE_UINT32(_header + 44); + + props.textsOffset = READ_LE_UINT32(_header + 48); + props.resourcesOffset = READ_LE_UINT32(_header + 52); + + props.animDataSize = READ_LE_UINT16(_header + 56); + + props.imFileNumber = _header[59]; + props.exFileNumber = _header[60]; + props.communHandling = _header[61]; + + for (int i = 0; i < 14; i++) + props.functions[i] = READ_LE_UINT16(_header + 100 + i * 2); + + props.scriptEnd = _stream->size(); + if (props.textsOffset > 0) + props.scriptEnd = MIN(props.scriptEnd, props.textsOffset); + if (props.resourcesOffset > 0) + props.scriptEnd = MIN(props.scriptEnd, props.resourcesOffset); + + return true; +} + +Common::String TOTFile::createFileName(const Common::String &base, bool &isLOM) { + isLOM = false; + + const char *dot; + if ((dot = strrchr(base.c_str(), '.'))) { + // fileName includes an extension + + if (!scumm_stricmp(dot + 1, "LOM")) + isLOM = true; + + return base; + } + + return base + ".tot"; +} + +Common::String TOTFile::getFileBase(const Common::String &fileName) { + const char *dot; + if ((dot = strrchr(fileName.c_str(), '.'))) { + // fileName includes an extension + return Common::String(fileName.c_str(), dot); + } + + return fileName; +} + +} // End of namespace Gob diff --git a/engines/gob/totfile.h b/engines/gob/totfile.h new file mode 100644 index 0000000000..00963d36a2 --- /dev/null +++ b/engines/gob/totfile.h @@ -0,0 +1,80 @@ +/* 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_TOTFILE_H +#define GOB_TOTFILE_H + +#include "common/str.h" + +namespace Common { + class SeekableReadStream; +} + +namespace Gob { + +class TOTFile { +public: + enum Function { + kFunctionStart = 0, + kFunctionCenter = 13 + }; + + struct Properties { + uint8 versionMajor; + uint8 versionMinor; + uint32 variablesCount; + uint32 textsOffset; + uint32 resourcesOffset; + uint16 animDataSize; + uint8 imFileNumber; + uint8 exFileNumber; + uint8 communHandling; + uint16 functions[14]; + uint32 scriptEnd; + }; + + TOTFile(GobEngine *vm); + ~TOTFile(); + + bool load(const Common::String &fileName); + void unload(); + + Common::SeekableReadStream *getStream() const; + bool getProperties(Properties &props) const; + + static Common::String createFileName(const Common::String &base, bool &isLOM); + static Common::String getFileBase(const Common::String &fileName); + +private: + GobEngine *_vm; + + Common::SeekableReadStream *_stream; + + byte _header[128]; +}; + +} // End of namespace Gob + +#endif // GOB_TOTFILE_H diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 2916caa340..b0e7691c07 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -120,6 +120,8 @@ void Util::processInput(bool scroll) { _fastMode ^= 1; else if (event.kbd.keycode == Common::KEYCODE_g) _fastMode ^= 2; + else if (event.kbd.keycode == Common::KEYCODE_p) + _vm->pauseGame(); break; } addKeyToBuffer(event.kbd); @@ -233,6 +235,17 @@ int16 Util::checkKey(void) { return translateKey(key); } +bool Util::checkKey(int16 &key) { + Common::KeyState keyS; + + if (!getKeyFromBuffer(keyS)) + return false; + + key = translateKey(keyS); + + return true; +} + void Util::getMouseState(int16 *pX, int16 *pY, int16 *pButtons) { Common::Point mouse = g_system->getEventManager()->getMousePos(); *pX = mouse.x + _vm->_video->_scrollOffsetX - _vm->_video->_screenDeltaX; @@ -318,6 +331,12 @@ void Util::setFrameRate(int16 rate) { _frameRate = rate; _frameWaitTime = 1000 / rate; _startFrameTime = getTimeKey(); + _frameWaitLag = 0; +} + +void Util::notifyNewAnim() { + _startFrameTime = getTimeKey(); + _frameWaitLag = 0; } void Util::waitEndFrame() { diff --git a/engines/gob/util.h b/engines/gob/util.h index 19b11801bc..0a76ee40ab 100644 --- a/engines/gob/util.h +++ b/engines/gob/util.h @@ -64,6 +64,7 @@ public: void clearKeyBuf(void); int16 getKey(void); int16 checkKey(void); + bool checkKey(int16 &key); void getMouseState(int16 *pX, int16 *pY, int16 *pButtons); void setMousePos(int16 x, int16 y); @@ -75,6 +76,7 @@ public: void clearPalette(void); int16 getFrameRate(); void setFrameRate(int16 rate); + void notifyNewAnim(); void waitEndFrame(); void setScrollOffset(int16 x = -1, int16 y = -1); diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp index 08aabea004..3b4822cc77 100644 --- a/engines/gob/video.cpp +++ b/engines/gob/video.cpp @@ -96,7 +96,6 @@ Video::Video(GobEngine *vm) : _vm(vm) { _scrollOffsetX = 0; _scrollOffsetY = 0; - _splitSurf = 0; _splitHeight1 = 200; _splitHeight2 = 0; _splitStart = 0; @@ -148,9 +147,8 @@ void Video::initPrimary(int16 mode) { } } -SurfaceDesc *Video::initSurfDesc(int16 vidMode, int16 width, int16 height, - int16 flags) { - SurfaceDesc *descPtr = 0; +SurfaceDescPtr Video::initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) { + SurfaceDescPtr descPtr; if (flags & PRIMARY_SURFACE) assert((width == _surfWidth) && (height == _surfHeight)); @@ -170,7 +168,7 @@ SurfaceDesc *Video::initSurfDesc(int16 vidMode, int16 width, int16 height, if (!(flags & SCUMMVM_CURSOR)) width = (width + 7) & 0xFFF8; - descPtr = new SurfaceDesc(vidMode, width, height); + descPtr = SurfaceDescPtr(new SurfaceDesc(vidMode, width, height)); } return descPtr; } @@ -241,15 +239,15 @@ void Video::sparseRetrace(int max) { _lastSparse = timeKey; } -void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest) { - if ((x >= dest->getWidth()) || (x < 0) || - (y >= dest->getHeight()) || (y < 0)) +void Video::putPixel(int16 x, int16 y, int16 color, SurfaceDesc &dest) { + if ((x >= dest.getWidth()) || (x < 0) || + (y >= dest.getHeight()) || (y < 0)) return; _videoDriver->putPixel(x, y, color, dest); } -void Video::fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, +void Video::fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 color) { if (_doRangeClamp) { @@ -258,20 +256,20 @@ void Video::fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, if (top > bottom) SWAP(top, bottom); - if ((left >= dest->getWidth()) || (right < 0) || - (top >= dest->getHeight()) || (bottom < 0)) + if ((left >= dest.getWidth()) || (right < 0) || + (top >= dest.getHeight()) || (bottom < 0)) return; - left = CLIP(left, (int16) 0, (int16) (dest->getWidth() - 1)); - top = CLIP(top, (int16) 0, (int16) (dest->getHeight() - 1)); - right = CLIP(right, (int16) 0, (int16) (dest->getWidth() - 1)); - bottom = CLIP(bottom, (int16) 0, (int16) (dest->getHeight() - 1)); + left = CLIP(left, (int16)0, (int16)(dest.getWidth() - 1)); + top = CLIP(top, (int16)0, (int16)(dest.getHeight() - 1)); + right = CLIP(right, (int16)0, (int16)(dest.getWidth() - 1)); + bottom = CLIP(bottom, (int16)0, (int16)(dest.getHeight() - 1)); } _videoDriver->fillRect(dest, left, top, right, bottom, color); } -void Video::drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, +void Video::drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, int16 color) { if ((x0 == x1) || (y0 == y1)) @@ -286,7 +284,7 @@ void Video::drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, * version found in the Wikipedia article about the * "Bresenham's line algorithm" instead */ -void Video::drawCircle(SurfaceDesc *dest, int16 x0, int16 y0, +void Video::drawCircle(SurfaceDesc &dest, int16 x0, int16 y0, int16 radius, int16 color) { int16 f = 1 - radius; int16 ddFx = 0; @@ -319,11 +317,11 @@ void Video::drawCircle(SurfaceDesc *dest, int16 x0, int16 y0, } } -void Video::clearSurf(SurfaceDesc *dest) { - Video::fillRect(dest, 0, 0, dest->getWidth() - 1, dest->getHeight() - 1, 0); +void Video::clearSurf(SurfaceDesc &dest) { + Video::fillRect(dest, 0, 0, dest.getWidth() - 1, dest.getHeight() - 1, 0); } -void Video::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, +void Video::drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { int16 destRight; int16 destBottom; @@ -334,8 +332,8 @@ void Video::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, if (top > bottom) SWAP(top, bottom); - if ((left >= source->getWidth()) || (right < 0) || - (top >= source->getHeight()) || (bottom < 0)) + if ((left >= source.getWidth()) || (right < 0) || + (top >= source.getHeight()) || (bottom < 0)) return; if (left < 0) { @@ -346,12 +344,12 @@ void Video::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, y -= top; top = 0; } - right = CLIP(right, (int16) 0, (int16) (source->getWidth() - 1)); - bottom = CLIP(bottom, (int16) 0, (int16) (source->getHeight() - 1)); - if (right - left >= source->getWidth()) - right = left + source->getWidth() - 1; - if (bottom - top >= source->getHeight()) - bottom = top + source->getHeight() - 1; + right = CLIP(right, (int16)0, (int16)(source.getWidth() - 1)); + bottom = CLIP(bottom, (int16)0, (int16)(source.getHeight() - 1)); + if (right - left >= source.getWidth()) + right = left + source.getWidth() - 1; + if (bottom - top >= source.getHeight()) + bottom = top + source.getHeight() - 1; if (x < 0) { left -= x; @@ -361,30 +359,30 @@ void Video::drawSprite(SurfaceDesc *source, SurfaceDesc *dest, top -= y; y = 0; } - if ((x >= dest->getWidth()) || (left > right) || - (y >= dest->getHeight()) || (top > bottom)) + if ((x >= dest.getWidth()) || (left > right) || + (y >= dest.getHeight()) || (top > bottom)) return; destRight = x + right - left; destBottom = y + bottom - top; - if (destRight >= dest->getWidth()) - right -= destRight - dest->getWidth() + 1; + if (destRight >= dest.getWidth()) + right -= destRight - dest.getWidth() + 1; - if (destBottom >= dest->getHeight()) - bottom -= destBottom - dest->getHeight() + 1; + if (destBottom >= dest.getHeight()) + bottom -= destBottom - dest.getHeight() + 1; } _videoDriver->drawSprite(source, dest, left, top, right, bottom, x, y, transp); } -void Video::drawSpriteDouble(SurfaceDesc *source, SurfaceDesc *dest, +void Video::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) { _videoDriver->drawSpriteDouble(source, dest, left, top, right, bottom, x, y, transp); } void Video::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, - int16 color1, int16 color2, int16 transp, SurfaceDesc *dest) { + int16 color1, int16 color2, int16 transp, SurfaceDesc &dest) { byte *dataPtr; byte *itemData; int16 itemSize; @@ -417,25 +415,25 @@ void Video::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, item = 0; } - _videoDriver->drawLetter((unsigned char) item, x, y, fontDesc, color1, color2, transp, dest); + _videoDriver->drawLetter((unsigned char)item, x, y, fontDesc, color1, color2, transp, dest); } void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, int16 transp, SurfaceDesc *dest) { + int16 x, int16 y, int16 transp, SurfaceDesc &dest) { if (spriteUncompressor(sprBuf, width, height, x, y, transp, dest)) return; - _vm->validateVideoMode(dest->_vidMode); + _vm->validateVideoMode(dest._vidMode); _videoDriver->drawPackedSprite(sprBuf, width, height, x, y, transp, dest); } -void Video::drawPackedSprite(const char *path, SurfaceDesc *dest, int width) { +void Video::drawPackedSprite(const char *path, SurfaceDesc &dest, int width) { byte *data; data = _vm->_dataIO->getData(path); - drawPackedSprite(data, width, dest->getHeight(), 0, 0, 0, dest); + drawPackedSprite(data, width, dest.getHeight(), 0, 0, 0, dest); delete[] data; } diff --git a/engines/gob/video.h b/engines/gob/video.h index 4341d05c14..c71a18daa6 100644 --- a/engines/gob/video.h +++ b/engines/gob/video.h @@ -28,9 +28,9 @@ #include "common/list.h" #include "common/rect.h" +#include "common/ptr.h" #include "gob/gob.h" -#include "gob/helper.h" namespace Graphics { class PaletteLUT; @@ -39,9 +39,9 @@ namespace Graphics { namespace Gob { // Some Surfaces are simultaneous in Draw::spritesArray and discrete -// variables, so it's a references counting class that cleans -// up its own mess -class SurfaceDesc : public ReferenceCounter<SurfaceDesc> { +// variables, so if in doubt you should use a SurfaceDescPtr shared +// pointer object to refer to any SurfaceDesc. +class SurfaceDesc { public: int16 _vidMode; @@ -54,7 +54,6 @@ public: void setVidMem(byte *vidMem); void resize(int16 width, int16 height); void swap(SurfaceDesc &surf); - void swap(SurfaceDesc *surf) { assert(surf); swap(*surf); } SurfaceDesc(int16 vidMode, int16 width, int16 height, byte *vidMem = 0); ~SurfaceDesc() { if (_ownVidMem) delete[] _vidMem; } @@ -66,6 +65,9 @@ private: bool _ownVidMem; }; +typedef Common::SharedPtr<SurfaceDesc> SurfaceDescPtr; + + class Video { public: struct FontDesc { @@ -117,7 +119,7 @@ public: int16 _scrollOffsetX; int16 _scrollOffsetY; - SurfaceDesc::Ptr _splitSurf; + SurfaceDescPtr _splitSurf; int16 _splitHeight1; int16 _splitHeight2; int16 _splitStart; @@ -129,7 +131,7 @@ public: void freeDriver(); void initPrimary(int16 mode); - SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, + SurfaceDescPtr initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags); void setSize(bool defaultTo1XScaler); @@ -139,24 +141,24 @@ public: void waitRetrace(bool mouse = true); void sparseRetrace(int max); - void putPixel(int16 x, int16 y, int16 color, SurfaceDesc *dest); - virtual void fillRect(SurfaceDesc *dest, int16 left, int16 top, + void putPixel(int16 x, int16 y, int16 color, SurfaceDesc &dest); + virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 color); - void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, + void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, int16 color); - void drawCircle(SurfaceDesc *dest, int16 x0, int16 y0, + void drawCircle(SurfaceDesc &dest, int16 x0, int16 y0, int16 radius, int16 color); - void clearSurf(SurfaceDesc *dest); - void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, + void clearSurf(SurfaceDesc &dest); + void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); - void drawSpriteDouble(SurfaceDesc *source, SurfaceDesc *dest, + void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp); void drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc, - int16 color1, int16 color2, int16 transp, SurfaceDesc *dest); + int16 color1, int16 color2, int16 transp, SurfaceDesc &dest); void drawPackedSprite(byte *sprBuf, int16 width, int16 height, - int16 x, int16 y, int16 transp, SurfaceDesc *dest); - void drawPackedSprite(const char *path, SurfaceDesc *dest, + int16 x, int16 y, int16 transp, SurfaceDesc &dest); + void drawPackedSprite(const char *path, SurfaceDesc &dest, int width = 320); void setPalColor(byte *pal, byte red, byte green, byte blue) { @@ -181,7 +183,7 @@ public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x, int16 y, int16 transp, - SurfaceDesc *destDesc) = 0; + SurfaceDesc &destDesc) = 0; virtual void init() {} @@ -210,7 +212,7 @@ protected: class Video_v1 : public Video { public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); + int16 x, int16 y, int16 transp, SurfaceDesc &destDesc); Video_v1(GobEngine *vm); virtual ~Video_v1() {} @@ -219,7 +221,7 @@ public: class Video_v2 : public Video_v1 { public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); + int16 x, int16 y, int16 transp, SurfaceDesc &destDesc); Video_v2(GobEngine *vm); virtual ~Video_v2() {} @@ -228,9 +230,9 @@ public: class Video_v6 : public Video_v2 { public: virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc *destDesc); + int16 x, int16 y, int16 transp, SurfaceDesc &destDesc); - virtual void fillRect(SurfaceDesc *dest, int16 left, int16 top, + virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 color); virtual void init(); @@ -245,13 +247,13 @@ private: void buildPalLUT(); - void shadeRect(SurfaceDesc *dest, + void shadeRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color, byte strength); - void drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc *surfDesc); - void drawYUVData(const byte *srcData, SurfaceDesc *destDesc, + void drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc &surfDesc); + void drawYUVData(const byte *srcData, SurfaceDesc &destDesc, int16 width, int16 height, int16 x, int16 y); - void drawYUV(SurfaceDesc *destDesc, int16 x, int16 y, + void drawYUV(SurfaceDesc &destDesc, int16 x, int16 y, int16 dataWidth, int16 dataHeight, int16 width, int16 height, const byte *dataY, const byte *dataU, const byte *dataV); }; @@ -260,13 +262,13 @@ class VideoDriver { public: VideoDriver() {} virtual ~VideoDriver() {} - virtual void drawSprite(SurfaceDesc *source, SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; - virtual void drawSpriteDouble(SurfaceDesc *source, SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; - virtual void fillRect(SurfaceDesc *dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0; - virtual void putPixel(int16 x, int16 y, byte color, SurfaceDesc *dest) = 0; - virtual void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc *dest) = 0; - virtual void drawLine(SurfaceDesc *dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0; - virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc *dest) = 0; + virtual void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; + virtual void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0; + virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0; + virtual void putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest) = 0; + virtual void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc &dest) = 0; + virtual void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0; + virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc &dest) = 0; }; } // End of namespace Gob diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp index 3c9627c041..699ac5f934 100644 --- a/engines/gob/video_v1.cpp +++ b/engines/gob/video_v1.cpp @@ -34,7 +34,7 @@ Video_v1::Video_v1(GobEngine *vm) : Video(vm) { } char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) { + int16 x, int16 y, int16 transp, SurfaceDesc &destDesc) { byte *memBuffer; byte *srcPtr, *destPtr, *linePtr; byte temp; @@ -46,10 +46,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 bufPos; int16 strLen; - if (!destDesc) - return 1; - - _vm->validateVideoMode(destDesc->_vidMode); + _vm->validateVideoMode(destDesc._vidMode); if (sprBuf[0] != 1) return 0; @@ -59,7 +56,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, if (sprBuf[2] == 2) { SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); - Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1, + Video::drawSprite(sourceDesc, destDesc, 0, 0, srcWidth - 1, srcHeight - 1, x, y, transp); return 1; } else { @@ -69,7 +66,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, srcPtr = sprBuf + 3; sourceLeft = READ_LE_UINT16(srcPtr); - destPtr = destDesc->getVidMem() + destDesc->getWidth() * y + x; + destPtr = destDesc.getVidMem() + destDesc.getWidth() * y + x; curWidth = 0; curHeight = 0; @@ -96,7 +93,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->getWidth(); + linePtr += destDesc.getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) @@ -125,7 +122,7 @@ char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->getWidth(); + linePtr += destDesc.getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) { diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp index ab0c7e52db..b526b63a37 100644 --- a/engines/gob/video_v2.cpp +++ b/engines/gob/video_v2.cpp @@ -34,7 +34,7 @@ Video_v2::Video_v2(GobEngine *vm) : Video_v1(vm) { } char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) { + int16 x, int16 y, int16 transp, SurfaceDesc &destDesc) { byte *memBuffer; byte *srcPtr, *destPtr, *linePtr; byte temp; @@ -47,10 +47,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 strLen; int16 lenCmd; - if (!destDesc) - return 1; - - _vm->validateVideoMode(destDesc->_vidMode); + _vm->validateVideoMode(destDesc._vidMode); if (sprBuf[0] != 1) return 0; @@ -60,7 +57,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, if (sprBuf[2] == 2) { SurfaceDesc sourceDesc(0x13, srcWidth, srcHeight, sprBuf + 3); - Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1, + Video::drawSprite(sourceDesc, destDesc, 0, 0, srcWidth - 1, srcHeight - 1, x, y, transp); return 1; } else if (sprBuf[2] == 1) { @@ -70,7 +67,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, srcPtr = sprBuf + 3; sourceLeft = READ_LE_UINT32(srcPtr); - destPtr = destDesc->getVidMem() + destDesc->getWidth() * y + x; + destPtr = destDesc.getVidMem() + destDesc.getWidth() * y + x; curWidth = 0; curHeight = 0; @@ -104,7 +101,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->getWidth(); + linePtr += destDesc.getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) @@ -133,7 +130,7 @@ char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, curWidth++; if (curWidth >= srcWidth) { curWidth = 0; - linePtr += destDesc->getWidth(); + linePtr += destDesc.getWidth(); destPtr = linePtr; curHeight++; if (curHeight >= srcHeight) { diff --git a/engines/gob/video_v6.cpp b/engines/gob/video_v6.cpp index f0d554bd01..983eeea8cf 100644 --- a/engines/gob/video_v6.cpp +++ b/engines/gob/video_v6.cpp @@ -77,11 +77,8 @@ void Video_v6::buildPalLUT() { } char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, - int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) { - if (!destDesc) - return 1; - - _vm->validateVideoMode(destDesc->_vidMode); + int16 x, int16 y, int16 transp, SurfaceDesc &destDesc) { + _vm->validateVideoMode(destDesc._vidMode); if ((sprBuf[0] == 1) && (sprBuf[1] == 3)) { drawPacked(sprBuf, x, y, destDesc); @@ -93,7 +90,7 @@ char Video_v6::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, return 1; } -void Video_v6::fillRect(SurfaceDesc *dest, +void Video_v6::fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 color) { if (!(color & 0xFF00)) { @@ -112,27 +109,27 @@ void Video_v6::fillRect(SurfaceDesc *dest, if (top > bottom) SWAP(top, bottom); - if ((left >= dest->getWidth()) || (right < 0) || - (top >= dest->getHeight()) || (bottom < 0)) + if ((left >= dest.getWidth()) || (right < 0) || + (top >= dest.getHeight()) || (bottom < 0)) return; - left = CLIP(left, (int16) 0, (int16) (dest->getWidth() - 1)); - top = CLIP(top, (int16) 0, (int16) (dest->getHeight() - 1)); - right = CLIP(right, (int16) 0, (int16) (dest->getWidth() - 1)); - bottom = CLIP(bottom, (int16) 0, (int16) (dest->getHeight() - 1)); + left = CLIP(left, (int16)0, (int16)(dest.getWidth() - 1)); + top = CLIP(top, (int16)0, (int16)(dest.getHeight() - 1)); + right = CLIP(right, (int16)0, (int16)(dest.getWidth() - 1)); + bottom = CLIP(bottom, (int16)0, (int16)(dest.getHeight() - 1)); } byte strength = 16 - (((uint16) color) >> 12); shadeRect(dest, left, top, right, bottom, color, strength); } -void Video_v6::shadeRect(SurfaceDesc *dest, +void Video_v6::shadeRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color, byte strength) { int width = right - left + 1; int height = bottom - top + 1; - int dWidth = dest->getWidth(); - byte *vidMem = dest->getVidMem() + dWidth * top + left; + int dWidth = dest.getWidth(); + byte *vidMem = dest.getVidMem() + dWidth * top + left; byte sY, sU, sV; _palLUT->getEntry(color, sY, sU, sV); @@ -167,7 +164,7 @@ void Video_v6::shadeRect(SurfaceDesc *dest, delete dither; } -void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc *surfDesc) { +void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc &surfDesc) { const byte *data = sprBuf + 2; int16 width = READ_LE_UINT16(data); @@ -193,7 +190,7 @@ void Video_v6::drawPacked(const byte *sprBuf, int16 x, int16 y, SurfaceDesc *sur delete[] uncBuf; } -void Video_v6::drawYUVData(const byte *srcData, SurfaceDesc *destDesc, +void Video_v6::drawYUVData(const byte *srcData, SurfaceDesc &destDesc, int16 width, int16 height, int16 x, int16 y) { int16 dataWidth = width; @@ -212,16 +209,16 @@ void Video_v6::drawYUVData(const byte *srcData, SurfaceDesc *destDesc, } -void Video_v6::drawYUV(SurfaceDesc *destDesc, int16 x, int16 y, +void Video_v6::drawYUV(SurfaceDesc &destDesc, int16 x, int16 y, int16 dataWidth, int16 dataHeight, int16 width, int16 height, const byte *dataY, const byte *dataU, const byte *dataV) { - byte *vidMem = destDesc->getVidMem() + y * destDesc->getWidth() + x; + byte *vidMem = destDesc.getVidMem() + y * destDesc.getWidth() + x; - if ((x + width - 1) >= destDesc->getWidth()) - width = destDesc->getWidth() - x; - if ((y + height - 1) >= destDesc->getHeight()) - height = destDesc->getHeight() - y; + if ((x + width - 1) >= destDesc.getWidth()) + width = destDesc.getWidth() - x; + if ((y + height - 1) >= destDesc.getHeight()) + height = destDesc.getHeight() - y; Graphics::SierraLight *dither = new Graphics::SierraLight(width, _palLUT); @@ -241,7 +238,7 @@ void Video_v6::drawYUV(SurfaceDesc *destDesc, int16 x, int16 y, } dither->nextLine(); - vidMem += destDesc->getWidth(); + vidMem += destDesc.getWidth(); } delete dither; diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 88a6cb1a8e..6c07d22333 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -150,8 +150,10 @@ Graphics::CoktelVideo::State VideoPlayer::Video::nextFrame() { return _state; } + VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm) { _primaryVideo = new Video(vm); + _ownSurf = false; _backSurf = false; _needBlit = false; _noCursorSwitch = false; @@ -199,15 +201,11 @@ bool VideoPlayer::findFile(char *fileName, Type &which) { int i; for (i = 0; i < ARRAYSIZE(_extensions); i++) { if ((which == kVideoTypeTry) || (which == ((Type) i))) { - int16 handle; - fileName[len] = '.'; fileName[len + 1] = 0; strcat(fileName, _extensions[i]); - handle = _vm->_dataIO->openData(fileName); - if (handle >= 0) { - _vm->_dataIO->closeData(handle); + if (_vm->_dataIO->existData(fileName)) { which = (Type) i; break; } @@ -225,7 +223,7 @@ bool VideoPlayer::findFile(char *fileName, Type &which) { } bool VideoPlayer::primaryOpen(const char *videoFile, int16 x, int16 y, - int16 flags, Type which) { + int32 flags, Type which) { char fileName[256]; @@ -251,10 +249,13 @@ bool VideoPlayer::primaryOpen(const char *videoFile, int16 x, int16 y, _noCursorSwitch = true; } + _ownSurf = false; + if (!(flags & kFlagNoVideo)) { - SurfaceDesc::Ptr surf; + SurfaceDescPtr surf; if (flags & kFlagOtherSurface) { + _ownSurf = true; _backSurf = false; surf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, @@ -263,6 +264,13 @@ bool VideoPlayer::primaryOpen(const char *videoFile, int16 x, int16 y, _vm->_draw->_spritesArray[x] = surf; x = 0; + } else if (flags & kFlagScreenSurface) { + _ownSurf = true; + _backSurf = false; + + surf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, + _vm->_width, _vm->_height, 0); + _vm->_draw->_spritesArray[0] = surf; } else { _backSurf = ((flags & kFlagFrontSurface) == 0); surf = _vm->_draw->_spritesArray[_backSurf ? 21 : 20]; @@ -459,13 +467,14 @@ void VideoPlayer::slotCopyPalette(int slot, int16 palStart, int16 palEnd) { } void VideoPlayer::slotWaitEndFrame(int slot, bool onlySound) { - if ((slot < 0) || (((uint) slot) >= _videoSlots.size()) || !_videoSlots[slot]) - return; + Video *video = getVideoBySlot(slot); - Graphics::CoktelVideo &video = *(_videoSlots[slot]->getVideo()); + if (video) { + Graphics::CoktelVideo &cVideo = *video->getVideo(); - if (!onlySound || (video.getFeatures() & Graphics::CoktelVideo::kFeaturesSound)) - video.waitEndFrame(); + if (!onlySound || (cVideo.getFeatures() & Graphics::CoktelVideo::kFeaturesSound)) + cVideo.waitEndFrame(); + } } bool VideoPlayer::slotIsOpen(int slot) const { @@ -611,10 +620,24 @@ Common::MemoryReadStream *VideoPlayer::getExtraData(const char *fileName, int sl return 0; } -bool VideoPlayer::doPlay(int16 frame, int16 breakKey, +void VideoPlayer::playFrame(int16 frame, int16 breakKey, uint16 palCmd, int16 palStart, int16 palEnd, int16 palFrame, int16 endFrame) { + if (!_primaryVideo) + return; + + Video &video = *_primaryVideo; + Graphics::CoktelVideo &cVideo = *video.getVideo(); + + if (cVideo.getCurrentFrame() != frame) + cVideo.seekFrame(frame); + if (palFrame < 0) + palFrame = 0; + if (endFrame < 0) + endFrame = cVideo.getFramesCount() - 1; + + bool modifiedPal = false; if ((frame == palFrame) || ((frame == endFrame) && (palCmd == 8))) { @@ -622,7 +645,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey, _vm->_draw->_applyPal = true; if (palCmd >= 4) - copyPalette(*(_primaryVideo->getVideo()), palStart, palEnd); + copyPalette(cVideo, palStart, palEnd); } if (modifiedPal && (palCmd == 8) && !_backSurf) @@ -632,7 +655,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey, if (_needBlit) _vm->_draw->forceBlit(); - Graphics::CoktelVideo::State state = _primaryVideo->nextFrame(); + Graphics::CoktelVideo::State state = video.nextFrame(); WRITE_VAR(11, frame); if (_needBlit) @@ -648,7 +671,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey, } if ((state.flags & Graphics::CoktelVideo::kStatePalette) && (palCmd > 1)) { - copyPalette(*(_primaryVideo->getVideo()), palStart, palEnd); + copyPalette(cVideo, palStart, palEnd); if (!_backSurf) _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); @@ -660,17 +683,25 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey, _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - if (_backSurf) { - _vm->_draw->invalidateRect(state.left, state.top, state.right, state.bottom); - _vm->_draw->blitInvalidated(); - } else - _vm->_video->dirtyRectsAdd(state.left, state.top, state.right, state.bottom); - _vm->_video->retrace(); + if (!_ownSurf) { + if (_backSurf) { + _vm->_draw->invalidateRect(state.left, state.top, state.right, state.bottom); + _vm->_draw->blitInvalidated(); + } else + _vm->_video->dirtyRectsAdd(state.left, state.top, state.right, state.bottom); + _vm->_video->retrace(); + } if (modifiedPal && ((palCmd == 2) || (palCmd == 4))) _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); +} + +bool VideoPlayer::doPlay(int16 frame, int16 breakKey, + uint16 palCmd, int16 palStart, int16 palEnd, + int16 palFrame, int16 endFrame) { + playFrame(frame, breakKey, palCmd, palStart, palEnd, palFrame, endFrame); _vm->_util->processInput(); diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h index eaa0418b68..842426f90a 100644 --- a/engines/gob/videoplayer.h +++ b/engines/gob/videoplayer.h @@ -44,7 +44,8 @@ public: kFlagUseBackSurfaceContent = 0x40, kFlagFrontSurface = 0x80, kFlagNoVideo = 0x100, - kFlagOtherSurface = 0x800 + kFlagOtherSurface = 0x800, + kFlagScreenSurface = 0x400000 }; enum Type { @@ -58,13 +59,17 @@ public: ~VideoPlayer(); bool primaryOpen(const char *videoFile, int16 x = -1, int16 y = -1, - int16 flags = kFlagFrontSurface, Type which = kVideoTypeTry); + int32 flags = kFlagFrontSurface, Type which = kVideoTypeTry); bool primaryPlay(int16 startFrame = -1, int16 lastFrame = -1, int16 breakKey = 27, 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, + uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255, + int16 palFrame = -1 , int16 endFrame = -1); + int slotOpen(const char *videoFile, Type which = kVideoTypeTry); void slotPlay(int slot, int16 frame = -1); void slotClose(int slot); @@ -72,7 +77,7 @@ public: uint16 left, uint16 top, uint16 width, uint16 height, uint16 x, uint16 y, uint16 pitch, int16 transp = -1); void slotCopyPalette(int slot, int16 palStart = -1, int16 palEnd = -1); - void slotWaitEndFrame(int slot, bool onlySound = false); + void slotWaitEndFrame(int slot = -1, bool onlySound = false); void slotSetDoubleMode(int slot, bool doubleMode); @@ -140,6 +145,7 @@ private: Common::Array<Video *> _videoSlots; Video *_primaryVideo; + bool _ownSurf; bool _backSurf; bool _needBlit; bool _noCursorSwitch; |