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/sci | |
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/sci')
76 files changed, 5762 insertions, 5176 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index f9e13304c5..bf919c3a25 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -37,7 +37,7 @@ #include "sci/gfx/gfx_gui.h" // for sciw_set_status_bar #include "sci/gfx/gfx_state_internal.h" #include "sci/gfx/gfx_widgets.h" // for getPort -#include "sci/sfx/songlib.h" // for songlib_t +#include "sci/sfx/songlib.h" // for SongLibrary #include "sci/sfx/iterator.h" // for SCI_SONG_ITERATOR_TYPE_SCI0 #include "sci/sfx/sci_midi.h" #include "sci/vocabulary.h" @@ -46,14 +46,11 @@ namespace Sci { -extern EngineState *g_EngineState; - int g_debug_sleeptime_factor = 1; int g_debug_simulated_key = 0; bool g_debug_track_mouse_clicks = false; bool g_debug_weak_validations = true; - Console::Console(SciEngine *vm) : GUI::Debugger() { _vm = vm; @@ -80,6 +77,7 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("parser_words", WRAP_METHOD(Console, cmdParserWords)); DCmd_Register("sentence_fragments", WRAP_METHOD(Console, cmdSentenceFragments)); DCmd_Register("parse", WRAP_METHOD(Console, cmdParse)); + DCmd_Register("set_parse_nodes", WRAP_METHOD(Console, cmdSetParseNodes)); // Resources DCmd_Register("hexdump", WRAP_METHOD(Console, cmdHexDump)); DCmd_Register("resource_id", WRAP_METHOD(Console, cmdResourceId)); @@ -141,11 +139,28 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("dissect_script", WRAP_METHOD(Console, cmdDissectScript)); DCmd_Register("set_acc", WRAP_METHOD(Console, cmdSetAccumulator)); DCmd_Register("backtrace", WRAP_METHOD(Console, cmdBacktrace)); + DCmd_Register("bt", WRAP_METHOD(Console, cmdBacktrace)); // alias + DCmd_Register("step", WRAP_METHOD(Console, cmdStep)); + DCmd_Register("s", WRAP_METHOD(Console, cmdStep)); // alias + DCmd_Register("step_event", WRAP_METHOD(Console, cmdStepEvent)); + DCmd_Register("se", WRAP_METHOD(Console, cmdStepEvent)); // alias + DCmd_Register("step_ret", WRAP_METHOD(Console, cmdStepRet)); + DCmd_Register("sret", WRAP_METHOD(Console, cmdStepRet)); // alias + DCmd_Register("step_global", WRAP_METHOD(Console, cmdStepGlobal)); + DCmd_Register("sg", WRAP_METHOD(Console, cmdStepGlobal)); // alias + DCmd_Register("step_callk", WRAP_METHOD(Console, cmdStepCallk)); + DCmd_Register("snk", WRAP_METHOD(Console, cmdStepCallk)); // alias + DCmd_Register("disasm", WRAP_METHOD(Console, cmdDissassemble)); + DCmd_Register("disasm_addr", WRAP_METHOD(Console, cmdDissassembleAddress)); + DCmd_Register("send", WRAP_METHOD(Console, cmdSend)); + DCmd_Register("go", WRAP_METHOD(Console, cmdGo)); // Breakpoints DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList)); DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete)); DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod)); + DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointExecMethod)); // alias DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction)); + DCmd_Register("bpe", WRAP_METHOD(Console, cmdBreakpointExecFunction)); // alias // VM DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps)); DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist)); @@ -154,7 +169,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("value_type", WRAP_METHOD(Console, cmdValueType)); DCmd_Register("view_listnode", WRAP_METHOD(Console, cmdViewListNode)); DCmd_Register("view_reference", WRAP_METHOD(Console, cmdViewReference)); + DCmd_Register("vr", WRAP_METHOD(Console, cmdViewReference)); // alias DCmd_Register("view_object", WRAP_METHOD(Console, cmdViewObject)); + DCmd_Register("vo", WRAP_METHOD(Console, cmdViewObject)); // alias DCmd_Register("active_object", WRAP_METHOD(Console, cmdViewActiveObject)); DCmd_Register("acc_object", WRAP_METHOD(Console, cmdViewAccumulatorObject)); @@ -171,18 +188,24 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { con_hook_int(&(gfx_options.dirty_frames), "dirty_frames", "Dirty frames management\n"); */ + + debugState.isValid = false; + debugState.seeking = kDebugSeekNothing; + debugState.seekLevel = 0; + debugState.runningStep = 0; + debugState.stopOnEvent = false; } Console::~Console() { } void Console::preEnter() { - g_EngineState->_sound.sfx_suspend(true); + _vm->_gamestate->_sound.sfx_suspend(true); _vm->_mixer->pauseAll(true); } void Console::postEnter() { - g_EngineState->_sound.sfx_suspend(false); + _vm->_gamestate->_sound.sfx_suspend(false); _vm->_mixer->pauseAll(false); } @@ -205,6 +228,12 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf("weak_validations: Turns some validation errors into warnings\n"); DebugPrintf("script_abort_flag: Set to 1 to abort script execution. Set to 2 to force a replay afterwards\n"); DebugPrintf("\n"); + DebugPrintf("Debug flags\n"); + DebugPrintf("-----------\n"); + DebugPrintf("debugflag_list - Lists the available debug flags and their status\n"); + DebugPrintf("debugflag_enable - Enables a debug flag\n"); + DebugPrintf("debugflag_disable - Disables a debug flag\n"); + DebugPrintf("\n"); DebugPrintf("Commands\n"); DebugPrintf("--------\n"); DebugPrintf("Kernel:\n"); @@ -220,6 +249,7 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" parser_words - Shows the words from the parse node tree\n"); DebugPrintf(" sentence_fragments - Shows the sentence fragments (used to build Parse trees)\n"); DebugPrintf(" parse - Parses a sequence of words and prints the resulting parse tree\n"); + DebugPrintf(" set_parse_nodes - Sets the contents of all parse nodes\n"); DebugPrintf("\n"); DebugPrintf("Resources:\n"); DebugPrintf(" hexdump - Dumps the specified resource to standard output\n"); @@ -289,13 +319,22 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" registers - Shows the current register values\n"); DebugPrintf(" dissect_script - Examines a script\n"); DebugPrintf(" set_acc - Sets the accumulator\n"); - DebugPrintf(" backtrace - Dumps the send/self/super/call/calle/callb stack\n"); + DebugPrintf(" backtrace / bt - Dumps the send/self/super/call/calle/callb stack\n"); + DebugPrintf(" step / s - Executes one operation (no parameters) or several operations (specified as a parameter) \n"); + DebugPrintf(" step_event / se - Steps forward until a SCI event is received.\n"); + DebugPrintf(" step_ret / sret - Steps forward until ret is called on the current execution stack level.\n"); + DebugPrintf(" step_global / sg - Steps until the global variable with the specified index is modified.\n"); + DebugPrintf(" step_callk / snk - Steps forward until it hits the next callk operation, or a specific callk (specified as a parameter)\n"); + DebugPrintf(" disasm - Disassembles a method by name\n"); + DebugPrintf(" disasm_addr - Disassembles one or more commands\n"); + DebugPrintf(" send - Sends a message to an object\n"); + DebugPrintf(" go - Executes the script\n"); DebugPrintf("\n"); DebugPrintf("Breakpoints:\n"); DebugPrintf(" bp_list - Lists the current breakpoints\n"); DebugPrintf(" bp_del - Deletes a breakpoint with the specified index\n"); - DebugPrintf(" bp_exec_method - Sets a breakpoint on the execution of the specified method\n"); - DebugPrintf(" bp_exec_function - Sets a breakpoint on the execution of the specified exported function\n"); + DebugPrintf(" bp_exec_method / bpx - Sets a breakpoint on the execution of the specified method\n"); + DebugPrintf(" bp_exec_function / bpe - Sets a breakpoint on the execution of the specified exported function\n"); DebugPrintf("\n"); DebugPrintf("VM:\n"); DebugPrintf(" script_steps - Shows the number of executed SCI operations\n"); @@ -304,8 +343,8 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" stack - Lists the specified number of stack elements\n"); DebugPrintf(" value_type - Determines the type of a value\n"); DebugPrintf(" view_listnode - Examines the list node at the given address\n"); - DebugPrintf(" view_reference - Examines an arbitrary reference\n"); - DebugPrintf(" view_object - Examines the object at the given address\n"); + DebugPrintf(" view_reference / vr - Examines an arbitrary reference\n"); + DebugPrintf(" view_object / vo - Examines the object at the given address\n"); DebugPrintf(" active_object - Shows information on the currently active object or class\n"); DebugPrintf(" acc_object - Shows information on the object or class at the address indexed by the accumulator\n"); DebugPrintf("\n"); @@ -341,8 +380,8 @@ bool Console::cmdGetVersion(int argc, const char **argv) { bool Console::cmdOpcodes(int argc, const char **argv) { DebugPrintf("Opcode names in numeric order [index: type name]:\n"); - for (uint seeker = 0; seeker < g_EngineState->_kernel->getOpcodesSize(); seeker++) { - opcode op = g_EngineState->_kernel->getOpcode(seeker); + for (uint seeker = 0; seeker < _vm->_gamestate->_kernel->getOpcodesSize(); seeker++) { + opcode op = _vm->_gamestate->_kernel->getOpcode(seeker); DebugPrintf("%03x: %03x %20s | ", seeker, op.type, op.name.c_str()); if ((seeker % 3) == 2) DebugPrintf("\n"); @@ -355,8 +394,8 @@ bool Console::cmdOpcodes(int argc, const char **argv) { bool Console::cmdSelectors(int argc, const char **argv) { DebugPrintf("Selector names in numeric order:\n"); - for (uint seeker = 0; seeker < g_EngineState->_kernel->getSelectorNamesSize(); seeker++) { - DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_kernel->getSelectorName(seeker).c_str()); + for (uint seeker = 0; seeker < _vm->_gamestate->_kernel->getSelectorNamesSize(); seeker++) { + DebugPrintf("%03x: %20s | ", seeker, _vm->_gamestate->_kernel->getSelectorName(seeker).c_str()); if ((seeker % 3) == 2) DebugPrintf("\n"); } @@ -368,8 +407,8 @@ bool Console::cmdSelectors(int argc, const char **argv) { bool Console::cmdKernelFunctions(int argc, const char **argv) { DebugPrintf("Kernel function names in numeric order:\n"); - for (uint seeker = 0; seeker < g_EngineState->_kernel->getKernelNamesSize(); seeker++) { - DebugPrintf("%03x: %20s | ", seeker, g_EngineState->_kernel->getKernelName(seeker).c_str()); + for (uint seeker = 0; seeker < _vm->_gamestate->_kernel->getKernelNamesSize(); seeker++) { + DebugPrintf("%03x: %20s | ", seeker, _vm->_gamestate->_kernel->getKernelName(seeker).c_str()); if ((seeker % 3) == 2) DebugPrintf("\n"); } @@ -380,29 +419,118 @@ bool Console::cmdKernelFunctions(int argc, const char **argv) { } bool Console::cmdSuffixes(int argc, const char **argv) { - g_EngineState->_vocabulary->printSuffixes(); + _vm->_gamestate->_vocabulary->printSuffixes(); return true; } bool Console::cmdParserWords(int argc, const char **argv) { - g_EngineState->_vocabulary->printParserWords(); + _vm->_gamestate->_vocabulary->printParserWords(); + + return true; +} + +enum { + kParseEndOfInput = 0, + kParseOpeningParenthesis = 1, + kParseClosingParenthesis = 2, + kParseNil = 3, + kParseNumber = 4 +}; + +int parseNodes(EngineState *s, int *i, int *pos, int type, int nr, int argc, const char **argv) { + int nextToken = 0, nextValue = 0, newPos = 0, oldPos = 0; + + if (type == kParseNil) + return 0; + + if (type == kParseNumber) { + s->parser_nodes[*pos += 1].type = kParseTreeLeafNode; + s->parser_nodes[*pos].content.value = nr; + return *pos; + } + if (type == kParseEndOfInput) { + sciprintf("Unbalanced parentheses\n"); + return -1; + } + if (type == kParseClosingParenthesis) { + sciprintf("Syntax error at token %d\n", *i); + return -1; + } + + s->parser_nodes[oldPos = ++(*pos)].type = kParseTreeBranchNode; + + for (int j = 0; j <= 1; j++) { + if (*i == argc) { + nextToken = kParseEndOfInput; + } else { + const char *token = argv[(*i)++]; + + if (!strcmp(token, "(")) { + nextToken = kParseOpeningParenthesis; + } else if (!strcmp(token, ")")) { + nextToken = kParseClosingParenthesis; + } else if (!strcmp(token, "nil")) { + nextToken = kParseNil; + } else { + nextValue = strtol(token, NULL, 0); + nextToken = kParseNumber; + } + } + + if ((newPos = s->parser_nodes[oldPos].content.branches[j] = parseNodes(s, i, pos, nextToken, nextValue, argc, argv)) == -1) + return -1; + } + + const char *token = argv[(*i)++]; + if (strcmp(token, ")")) + sciprintf("Expected ')' at token %d\n", *i); + + return oldPos; +} + +bool Console::cmdSetParseNodes(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Sets the contents of all parse nodes.\n"); + DebugPrintf("Usage: %s <parse node1> <parse node2> ... <parse noden>\n", argv[0]); + DebugPrintf("Tokens should be separated by blanks and enclosed in parentheses\n"); + return true; + } + + int i = 0; + int pos = -1; + int nextToken = 0, nextValue = 0; + + const char *token = argv[i++]; + + if (!strcmp(token, "(")) { + nextToken = kParseOpeningParenthesis; + } else if (!strcmp(token, ")")) { + nextToken = kParseClosingParenthesis; + } else if (!strcmp(token, "nil")) { + nextToken = kParseNil; + } else { + nextValue = strtol(token, NULL, 0); + nextToken = kParseNumber; + } + + if (parseNodes(_vm->_gamestate, &i, &pos, nextToken, nextValue, argc, argv) == -1) + return 1; + + vocab_dump_parse_tree("debug-parse-tree", _vm->_gamestate->parser_nodes); return true; } bool Console::cmdRegisters(int argc, const char **argv) { DebugPrintf("Current register values:\n"); -#if 0 - // TODO: p_restadjust - DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(g_EngineState->r_acc), PRINT_REG(g_EngineState->r_prev), *p_restadjust); -#endif + DebugPrintf("acc=%04x:%04x prev=%04x:%04x &rest=%x\n", PRINT_REG(_vm->_gamestate->r_acc), PRINT_REG(_vm->_gamestate->r_prev), *debugState.p_restadjust); - if (!g_EngineState->_executionStack.empty()) { -#if 0 - // TODO: p_pc, p_objp, p_pp, p_sp - DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n", PRINT_REG(*p_pc), PRINT_REG(*p_objp), PRINT_STK(*p_pp), PRINT_STK(*p_sp)); -#endif + if (!_vm->_gamestate->_executionStack.empty()) { + EngineState *s = _vm->_gamestate; // for PRINT_STK + DebugPrintf("pc=%04x:%04x obj=%04x:%04x fp=ST:%04x sp=ST:%04x\n", + PRINT_REG(*debugState.p_pc), PRINT_REG(*debugState.p_objp), + PRINT_STK(*debugState.p_pp), PRINT_STK(*debugState.p_sp)); } else DebugPrintf("<no execution stack: pc,obj,fp omitted>\n"); @@ -428,7 +556,7 @@ bool Console::cmdHexDump(int argc, const char **argv) { if (res == kResourceTypeInvalid) DebugPrintf("Resource type '%s' is not valid\n", argv[1]); else { - Resource *resource = _vm->getResMgr()->findResource(res, resNum, 0); + Resource *resource = _vm->getResMgr()->findResource(ResourceId(res, resNum), 0); if (resource) { Common::hexdump(resource->data, resource->size, 16, 0); DebugPrintf("Resource %s.%03d has been dumped to standard output\n", argv[1], resNum); @@ -460,13 +588,13 @@ bool Console::cmdDissectScript(int argc, const char **argv) { return true; } - g_EngineState->_kernel->dissectScript(atoi(argv[1]), g_EngineState->_vocabulary); + _vm->_gamestate->_kernel->dissectScript(atoi(argv[1]), _vm->_gamestate->_vocabulary); return true; } bool Console::cmdRoomNumber(int argc, const char **argv) { - DebugPrintf("Current room number is %d\n", g_EngineState->currentRoomNumber()); + DebugPrintf("Current room number is %d\n", _vm->_gamestate->currentRoomNumber()); return true; } @@ -489,7 +617,7 @@ bool Console::cmdResourceSize(int argc, const char **argv) { if (res == kResourceTypeInvalid) DebugPrintf("Resource type '%s' is not valid\n", argv[1]); else { - Resource *resource = _vm->getResMgr()->findResource(res, resNum, 0); + Resource *resource = _vm->getResMgr()->findResource(ResourceId(res, resNum), 0); if (resource) { DebugPrintf("Resource size: %d\n", resource->size); } else { @@ -559,7 +687,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) { } for (; resNumber <= resMax; resNumber++) { - if ((script = _vm->getResMgr()->findResource(restype, resNumber, 0))) { + if ((script = _vm->getResMgr()->findResource(ResourceId(restype, resNumber), 0))) { unsigned int seeker = 0, seekerold = 0; uint32 comppos = 0; int output_script_name = 0; @@ -593,7 +721,7 @@ bool Console::cmdHexgrep(int argc, const char **argv) { } bool Console::cmdList(int argc, const char **argv) { - if (argc != 2) { + if (argc < 2) { DebugPrintf("Lists all the resources of a given type\n"); cmdResourceTypes(argc, argv); return true; @@ -604,32 +732,54 @@ bool Console::cmdList(int argc, const char **argv) { if (res == kResourceTypeInvalid) DebugPrintf("Unknown resource type: '%s'\n", argv[1]); else { - int j = 0; - for (int i = 0; i < sci_max_resource_nr[_vm->getResMgr()->_sciVersion]; i++) { - if (_vm->getResMgr()->testResource(res, i)) { - DebugPrintf("%s.%03d | ", getResourceTypeName((ResourceType)res), i); - if (j % 5 == 0) + int number = -1; + + if ((res == kResourceTypeAudio36) || (res == kResourceTypeSync36)) { + if (argc != 3) { + DebugPrintf("Please specify map number\n"); + return true; + } + number = atoi(argv[2]); + } + + Common::List<ResourceId> *resources = _vm->getResMgr()->listResources(res, number); + sort(resources->begin(), resources->end(), ResourceIdLess()); + Common::List<ResourceId>::iterator itr = resources->begin(); + + int cnt = 0; + while (itr != resources->end()) { + if (number == -1) { + DebugPrintf("%8i", itr->number); + if (++cnt % 10 == 0) + DebugPrintf("\n"); + } + else if (number == (int)itr->number) { + DebugPrintf("(%3i, %3i, %3i, %3i) ", (itr->tuple >> 24) & 0xff, (itr->tuple >> 16) & 0xff, + (itr->tuple >> 8) & 0xff, itr->tuple & 0xff); + if (++cnt % 4 == 0) DebugPrintf("\n"); - j++; } + itr++; } DebugPrintf("\n"); + + delete resources; } return true; } bool Console::cmdClearScreen(int argc, const char **argv) { - gfxop_clear_box(g_EngineState->gfx_state, gfx_rect(0, 0, 320, 200)); - gfxop_update_box(g_EngineState->gfx_state, gfx_rect(0, 0, 320, 200)); + gfxop_clear_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); + gfxop_update_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); return false; } bool Console::cmdRedrawScreen(int argc, const char **argv) { - g_EngineState->visual->draw(Common::Point(0, 0)); - gfxop_update_box(g_EngineState->gfx_state, gfx_rect(0, 0, 320, 200)); - gfxop_update(g_EngineState->gfx_state); - gfxop_sleep(g_EngineState->gfx_state, 0); + _vm->_gamestate->visual->draw(Common::Point(0, 0)); + gfxop_update_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); + gfxop_update(_vm->_gamestate->gfx_state); + gfxop_sleep(_vm->_gamestate->gfx_state, 0); return false; } @@ -641,8 +791,8 @@ bool Console::cmdSaveGame(int argc, const char **argv) { } int result = 0; - for (uint i = 0; i < g_EngineState->_fileHandles.size(); i++) - if (g_EngineState->_fileHandles[i].isOpen()) + for (uint i = 0; i < _vm->_gamestate->_fileHandles.size(); i++) + if (_vm->_gamestate->_fileHandles[i].isOpen()) result++; if (result) @@ -656,7 +806,7 @@ bool Console::cmdSaveGame(int argc, const char **argv) { } // TODO: enable custom descriptions? force filename into a specific format? - if (gamestate_save(g_EngineState, out, "debugging")) { + if (gamestate_save(_vm->_gamestate, out, "debugging")) { DebugPrintf("Saving the game state to '%s' failed\n", argv[1]); } @@ -676,17 +826,17 @@ bool Console::cmdRestoreGame(int argc, const char **argv) { Common::SeekableReadStream *in; if (!(in = saveFileMan->openForLoading(argv[1]))) { // found a savegame file - newstate = gamestate_restore(g_EngineState, in); + newstate = gamestate_restore(_vm->_gamestate, in); delete in; } if (newstate) { - g_EngineState->successor = newstate; // Set successor + _vm->_gamestate->successor = newstate; // Set successor script_abort_flag = 2; // Abort current game with replay - g_debugstate_valid = 0; + debugState.isValid = false; - shrink_execution_stack(g_EngineState, g_EngineState->execution_stack_base + 1); + shrink_execution_stack(_vm->_gamestate, _vm->_gamestate->execution_stack_base + 1); return 0; } else { DebugPrintf("Restoring gamestate '%s' failed.\n", argv[1]); @@ -705,27 +855,27 @@ bool Console::cmdRestartGame(int argc, const char **argv) { } if (!scumm_stricmp(argv[1], "play")) { - g_EngineState->restarting_flags |= SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE; + _vm->_gamestate->restarting_flags |= SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE; } else if (!scumm_stricmp(argv[1], "replay")) { - g_EngineState->restarting_flags &= ~SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE; + _vm->_gamestate->restarting_flags &= ~SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE; } else { DebugPrintf("Invalid usage of %s\n", argv[0]); return true; } - g_EngineState->restarting_flags |= SCI_GAME_IS_RESTARTING_NOW; + _vm->_gamestate->restarting_flags |= SCI_GAME_IS_RESTARTING_NOW; script_abort_flag = 1; - g_debugstate_valid = 0; + debugState.isValid = false; return false; } bool Console::cmdClassTable(int argc, const char **argv) { DebugPrintf("Available classes:\n"); - for (uint i = 0; i < g_EngineState->_classtable.size(); i++) { - if (g_EngineState->_classtable[i].reg.segment) { + for (uint i = 0; i < _vm->_gamestate->_classtable.size(); i++) { + if (_vm->_gamestate->_classtable[i].reg.segment) { DebugPrintf(" Class 0x%x at %04x:%04x (script 0x%x)\n", i, - PRINT_REG(g_EngineState->_classtable[i].reg), g_EngineState->_classtable[i].script); + PRINT_REG(_vm->_gamestate->_classtable[i].reg), _vm->_gamestate->_classtable[i].script); } } @@ -735,10 +885,10 @@ bool Console::cmdClassTable(int argc, const char **argv) { bool Console::cmdSentenceFragments(int argc, const char **argv) { DebugPrintf("Sentence fragments (used to build Parse trees)\n"); - for (uint i = 0; i < g_EngineState->_vocabulary->getParserBranchesSize(); i++) { + for (uint i = 0; i < _vm->_gamestate->_vocabulary->getParserBranchesSize(); i++) { int j = 0; - const parse_tree_branch_t &branch = g_EngineState->_vocabulary->getParseTreeBranch(i); + const parse_tree_branch_t &branch = _vm->_gamestate->_vocabulary->getParseTreeBranch(i); DebugPrintf("R%02d: [%x] ->", i, branch.id); while ((j < 10) && branch.data[j]) { int dat = branch.data[j++]; @@ -770,7 +920,7 @@ bool Console::cmdSentenceFragments(int argc, const char **argv) { DebugPrintf("\n"); } - DebugPrintf("%d rules.\n", g_EngineState->_vocabulary->getParserBranchesSize()); + DebugPrintf("%d rules.\n", _vm->_gamestate->_vocabulary->getParserBranchesSize()); return true; } @@ -793,24 +943,24 @@ bool Console::cmdParse(int argc, const char **argv) { } DebugPrintf("Parsing '%s'\n", string); - bool res = g_EngineState->_vocabulary->tokenizeString(words, string, &error); + bool res = _vm->_gamestate->_vocabulary->tokenizeString(words, string, &error); if (res && !words.empty()) { int syntax_fail = 0; - vocab_synonymize_tokens(words, g_EngineState->_synonyms); + vocab_synonymize_tokens(words, _vm->_gamestate->_synonyms); DebugPrintf("Parsed to the following blocks:\n"); for (ResultWordList::const_iterator i = words.begin(); i != words.end(); ++i) DebugPrintf(" Type[%04x] Group[%04x]\n", i->_class, i->_group); - if (g_EngineState->_vocabulary->parseGNF(g_EngineState->parser_nodes, words, true)) + if (_vm->_gamestate->_vocabulary->parseGNF(_vm->_gamestate->parser_nodes, words, true)) syntax_fail = 1; // Building a tree failed if (syntax_fail) DebugPrintf("Building a tree failed.\n"); else - vocab_dump_parse_tree("debug-parse-tree", g_EngineState->parser_nodes); + vocab_dump_parse_tree("debug-parse-tree", _vm->_gamestate->parser_nodes); } else { DebugPrintf("Unknown word: '%s'\n", error); @@ -832,11 +982,11 @@ bool Console::cmdParserNodes(int argc, const char **argv) { for (int i = 0; i < end; i++) { DebugPrintf(" Node %03x: ", i); - if (g_EngineState->parser_nodes[i].type == PARSE_TREE_NODE_LEAF) - DebugPrintf("Leaf: %04x\n", g_EngineState->parser_nodes[i].content.value); + if (_vm->_gamestate->parser_nodes[i].type == kParseTreeLeafNode) + DebugPrintf("Leaf: %04x\n", _vm->_gamestate->parser_nodes[i].content.value); else - DebugPrintf("Branch: ->%04x, ->%04x\n", g_EngineState->parser_nodes[i].content.branches[0], - g_EngineState->parser_nodes[i].content.branches[1]); + DebugPrintf("Branch: ->%04x, ->%04x\n", _vm->_gamestate->parser_nodes[i].content.branches[0], + _vm->_gamestate->parser_nodes[i].content.branches[1]); } return true; @@ -860,10 +1010,10 @@ bool Console::cmdDrawPic(int argc, const char **argv) { if (argc == 4) flags = atoi(argv[3]); - gfxop_new_pic(g_EngineState->gfx_state, atoi(argv[1]), flags, default_palette); - gfxop_clear_box(g_EngineState->gfx_state, gfx_rect(0, 0, 320, 200)); - gfxop_update(g_EngineState->gfx_state); - gfxop_sleep(g_EngineState->gfx_state, 0); + gfxop_new_pic(_vm->_gamestate->gfx_state, atoi(argv[1]), flags, default_palette); + gfxop_clear_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); + gfxop_update(_vm->_gamestate->gfx_state); + gfxop_sleep(_vm->_gamestate->gfx_state, 0); return false; } @@ -878,10 +1028,10 @@ bool Console::cmdDrawRect(int argc, const char **argv) { int col = CLIP<int>(atoi(argv[5]), 0, 15); - gfxop_set_clip_zone(g_EngineState->gfx_state, gfx_rect_fullscreen); - gfxop_fill_box(g_EngineState->gfx_state, gfx_rect(atoi(argv[1]), atoi(argv[2]), - atoi(argv[3]), atoi(argv[4])), g_EngineState->ega_colors[col]); - gfxop_update(g_EngineState->gfx_state); + gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); + gfxop_fill_box(_vm->_gamestate->gfx_state, gfx_rect(atoi(argv[1]), atoi(argv[2]), + atoi(argv[3]), atoi(argv[4])), _vm->_gamestate->ega_colors[col]); + gfxop_update(_vm->_gamestate->gfx_state); return false; } @@ -898,9 +1048,9 @@ bool Console::cmdDrawCel(int argc, const char **argv) { int cel = atoi(argv[3]); int palette = atoi(argv[4]); - gfxop_set_clip_zone(g_EngineState->gfx_state, gfx_rect_fullscreen); - gfxop_draw_cel(g_EngineState->gfx_state, view, loop, cel, Common::Point(160, 100), g_EngineState->ega_colors[0], palette); - gfxop_update(g_EngineState->gfx_state); + gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); + gfxop_draw_cel(_vm->_gamestate->gfx_state, view, loop, cel, Common::Point(160, 100), _vm->_gamestate->ega_colors[0], palette); + gfxop_update(_vm->_gamestate->gfx_state); return false; } @@ -921,7 +1071,7 @@ bool Console::cmdViewInfo(int argc, const char **argv) { DebugPrintf("Resource view.%d ", view); - loops = gfxop_lookup_view_get_loops(g_EngineState->gfx_state, view); + loops = gfxop_lookup_view_get_loops(_vm->_gamestate->gfx_state, view); if (loops < 0) DebugPrintf("does not exist.\n"); @@ -931,17 +1081,17 @@ bool Console::cmdViewInfo(int argc, const char **argv) { for (i = 0; i < loops; i++) { int j, cels; - DebugPrintf("Loop %d: %d cels.\n", i, cels = gfxop_lookup_view_get_cels(g_EngineState->gfx_state, view, i)); + DebugPrintf("Loop %d: %d cels.\n", i, cels = gfxop_lookup_view_get_cels(_vm->_gamestate->gfx_state, view, i)); for (j = 0; j < cels; j++) { int width; int height; Common::Point mod; // Show pixmap on screen - view_pixmaps = g_EngineState->gfx_state->gfxResMan->getView(view, &i, &j, palette); - gfxop_draw_cel(g_EngineState->gfx_state, view, i, j, Common::Point(0,0), transparent, palette); + view_pixmaps = _vm->_gamestate->gfx_state->gfxResMan->getView(view, &i, &j, palette); + gfxop_draw_cel(_vm->_gamestate->gfx_state, view, i, j, Common::Point(0,0), transparent, palette); - gfxop_get_cel_parameters(g_EngineState->gfx_state, view, i, j, &width, &height, &mod); + gfxop_get_cel_parameters(_vm->_gamestate->gfx_state, view, i, j, &width, &height, &mod); DebugPrintf(" cel %d: size %dx%d, adj+(%d,%d)\n", j, width, height, mod.x, mod.y); } @@ -963,7 +1113,7 @@ bool Console::cmdUpdateZone(int argc, const char **argv) { int width = atoi(argv[3]); int height = atoi(argv[4]); - g_EngineState->gfx_state->driver->update(gfx_rect(x, y, width, height), Common::Point(x, y), GFX_BUFFER_FRONT); + _vm->_gamestate->gfx_state->driver->update(gfx_rect(x, y, width, height), Common::Point(x, y), GFX_BUFFER_FRONT); return false; } @@ -983,14 +1133,14 @@ bool Console::cmdPropagateZone(int argc, const char **argv) { int map = CLIP<int>(atoi(argv[5]), 0, 1); rect_t rect = gfx_rect(x, y, width, height); - gfxop_set_clip_zone(g_EngineState->gfx_state, gfx_rect_fullscreen); + gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); if (map == 1) - gfxop_clear_box(g_EngineState->gfx_state, rect); + gfxop_clear_box(_vm->_gamestate->gfx_state, rect); else - gfxop_update_box(g_EngineState->gfx_state, rect); - gfxop_update(g_EngineState->gfx_state); - gfxop_sleep(g_EngineState->gfx_state, 0); + gfxop_update_box(_vm->_gamestate->gfx_state, rect); + gfxop_update(_vm->_gamestate->gfx_state); + gfxop_sleep(_vm->_gamestate->gfx_state, 0); return false; } @@ -1005,18 +1155,18 @@ bool Console::cmdFillScreen(int argc, const char **argv) { int col = CLIP<int>(atoi(argv[1]), 0, 15); - gfxop_set_clip_zone(g_EngineState->gfx_state, gfx_rect_fullscreen); - gfxop_fill_box(g_EngineState->gfx_state, gfx_rect_fullscreen, g_EngineState->ega_colors[col]); - gfxop_update(g_EngineState->gfx_state); + gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); + gfxop_fill_box(_vm->_gamestate->gfx_state, gfx_rect_fullscreen, _vm->_gamestate->ega_colors[col]); + gfxop_update(_vm->_gamestate->gfx_state); return false; } bool Console::cmdCurrentPort(int argc, const char **argv) { - if (!g_EngineState->port) + if (!_vm->_gamestate->port) DebugPrintf("There is no port active currently.\n"); else - DebugPrintf("Current port ID: %d\n", g_EngineState->port->_ID); + DebugPrintf("Current port ID: %d\n", _vm->_gamestate->port->_ID); return true; } @@ -1032,16 +1182,16 @@ bool Console::cmdPrintPort(int argc, const char **argv) { GfxPort *port; if (!scumm_stricmp(argv[1], "current")) { - port = g_EngineState->port; + port = _vm->_gamestate->port; if (!port) DebugPrintf("There is no active port currently\n"); else port->print(0); } else { - if (!g_EngineState->visual) { + if (!_vm->_gamestate->visual) { DebugPrintf("Visual is uninitialized\n"); } else { - port = g_EngineState->visual->getPort(atoi(argv[1])); + port = _vm->_gamestate->visual->getPort(atoi(argv[1])); if (!port) DebugPrintf("No such port\n"); else @@ -1055,7 +1205,7 @@ bool Console::cmdPrintPort(int argc, const char **argv) { bool Console::cmdParseGrammar(int argc, const char **argv) { DebugPrintf("Parse grammar, in strict GNF:\n"); - g_EngineState->_vocabulary->buildGNF(true); + _vm->_gamestate->_vocabulary->buildGNF(true); return true; } @@ -1063,8 +1213,8 @@ bool Console::cmdParseGrammar(int argc, const char **argv) { bool Console::cmdVisualState(int argc, const char **argv) { DebugPrintf("State of the current visual widget:\n"); - if (g_EngineState->visual) - g_EngineState->visual->print(0); + if (_vm->_gamestate->visual) + _vm->_gamestate->visual->print(0); else DebugPrintf("The visual widget is uninitialized.\n"); @@ -1072,11 +1222,11 @@ bool Console::cmdVisualState(int argc, const char **argv) { } bool Console::cmdFlushPorts(int argc, const char **argv) { - gfxop_set_pointer_cursor(g_EngineState->gfx_state, GFXOP_NO_POINTER); + gfxop_set_pointer_cursor(_vm->_gamestate->gfx_state, GFXOP_NO_POINTER); DebugPrintf("Flushing dynamically allocated ports (for memory profiling)...\n"); - delete g_EngineState->visual; - g_EngineState->gfx_state->gfxResMan->freeAllResources(); - g_EngineState->visual = NULL; + delete _vm->_gamestate->visual; + _vm->_gamestate->gfx_state->gfxResMan->freeAllResources(); + _vm->_gamestate->visual = NULL; return true; } @@ -1084,8 +1234,8 @@ bool Console::cmdFlushPorts(int argc, const char **argv) { bool Console::cmdDynamicViews(int argc, const char **argv) { DebugPrintf("List of active dynamic views:\n"); - if (g_EngineState->dyn_views) - g_EngineState->dyn_views->print(0); + if (_vm->_gamestate->dyn_views) + _vm->_gamestate->dyn_views->print(0); else DebugPrintf("The list is empty.\n"); @@ -1095,8 +1245,8 @@ bool Console::cmdDynamicViews(int argc, const char **argv) { bool Console::cmdDroppedViews(int argc, const char **argv) { DebugPrintf("List of dropped dynamic views:\n"); - if (g_EngineState->drop_views) - g_EngineState->drop_views->print(0); + if (_vm->_gamestate->drop_views) + _vm->_gamestate->drop_views->print(0); else DebugPrintf("The list is empty.\n"); @@ -1105,13 +1255,13 @@ bool Console::cmdDroppedViews(int argc, const char **argv) { bool Console::cmdPriorityBands(int argc, const char **argv) { if (argc != 2) { - DebugPrintf("Priority bands start at y=%d. They end at y=%d\n", g_EngineState->priority_first, g_EngineState->priority_last); - DebugPrintf("Use %d <priority band> to print the start of priority for the specified priority band (0 - 15)\n", argv[0]); + DebugPrintf("Priority bands start at y=%d. They end at y=%d\n", _vm->_gamestate->priority_first, _vm->_gamestate->priority_last); + DebugPrintf("Use %s <priority band> to print the start of priority for the specified priority band (0 - 15)\n", argv[0]); return true; } int zone = CLIP<int>(atoi(argv[1]), 0, 15); - DebugPrintf("Zone %x starts at y=%d\n", zone, _find_priority_band(g_EngineState, zone)); + DebugPrintf("Zone %x starts at y=%d\n", zone, _find_priority_band(_vm->_gamestate, zone)); return true; } @@ -1123,15 +1273,15 @@ bool Console::cmdStatusBarColors(int argc, const char **argv) { return true; } - g_EngineState->titlebar_port->_color = g_EngineState->ega_colors[atoi(argv[1])]; - g_EngineState->titlebar_port->_bgcolor = g_EngineState->ega_colors[atoi(argv[2])]; + _vm->_gamestate->titlebar_port->_color = _vm->_gamestate->ega_colors[atoi(argv[1])]; + _vm->_gamestate->titlebar_port->_bgcolor = _vm->_gamestate->ega_colors[atoi(argv[2])]; - g_EngineState->status_bar_foreground = atoi(argv[1]); - g_EngineState->status_bar_background = atoi(argv[2]); + _vm->_gamestate->status_bar_foreground = atoi(argv[1]); + _vm->_gamestate->status_bar_background = atoi(argv[2]); - sciw_set_status_bar(g_EngineState, g_EngineState->titlebar_port, g_EngineState->_statusBarText, - g_EngineState->status_bar_foreground, g_EngineState->status_bar_background); - gfxop_update(g_EngineState->gfx_state); + sciw_set_status_bar(_vm->_gamestate, _vm->_gamestate->titlebar_port, _vm->_gamestate->_statusBarText, + _vm->_gamestate->status_bar_foreground, _vm->_gamestate->status_bar_background); + gfxop_update(_vm->_gamestate->gfx_state); return false; } @@ -1139,8 +1289,8 @@ bool Console::cmdStatusBarColors(int argc, const char **argv) { bool Console::cmdPrintSegmentTable(int argc, const char **argv) { DebugPrintf("Segment table:\n"); - for (uint i = 0; i < g_EngineState->seg_manager->_heap.size(); i++) { - MemObject *mobj = g_EngineState->seg_manager->_heap[i]; + for (uint i = 0; i < _vm->_gamestate->seg_manager->_heap.size(); i++) { + MemObject *mobj = _vm->_gamestate->seg_manager->_heap[i]; if (mobj && mobj->getType()) { DebugPrintf(" [%04x] ", i); @@ -1201,10 +1351,10 @@ bool Console::cmdPrintSegmentTable(int argc, const char **argv) { bool Console::segmentInfo(int nr) { DebugPrintf("[%04x] ", nr); - if ((nr < 0) || ((uint)nr >= g_EngineState->seg_manager->_heap.size()) || !g_EngineState->seg_manager->_heap[nr]) + if ((nr < 0) || ((uint)nr >= _vm->_gamestate->seg_manager->_heap.size()) || !_vm->_gamestate->seg_manager->_heap[nr]) return false; - MemObject *mobj = g_EngineState->seg_manager->_heap[nr]; + MemObject *mobj = _vm->_gamestate->seg_manager->_heap[nr]; switch (mobj->getType()) { @@ -1227,10 +1377,10 @@ bool Console::segmentInfo(int nr) { for (uint i = 0; i < scr->_objects.size(); i++) { DebugPrintf(" "); // Object header - Object *obj = obj_get(g_EngineState, scr->_objects[i].pos); + Object *obj = obj_get(_vm->_gamestate, scr->_objects[i].pos); if (obj) DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(scr->_objects[i].pos), - obj_get_name(g_EngineState, scr->_objects[i].pos), obj->_variables.size(), obj->methods_nr); + obj_get_name(_vm->_gamestate, scr->_objects[i].pos), obj->_variables.size(), obj->methods_nr); } } break; @@ -1271,12 +1421,12 @@ bool Console::segmentInfo(int nr) { reg_t objpos; objpos.offset = i; objpos.segment = nr; - DebugPrintf(" [%04x] %s; copy of ", i, obj_get_name(g_EngineState, objpos)); + DebugPrintf(" [%04x] %s; copy of ", i, obj_get_name(_vm->_gamestate, objpos)); // Object header - Object *obj = obj_get(g_EngineState, ct->_table[i].pos); + Object *obj = obj_get(_vm->_gamestate, ct->_table[i].pos); if (obj) DebugPrintf("[%04x:%04x] %s : %3d vars, %3d methods\n", PRINT_REG(ct->_table[i].pos), - obj_get_name(g_EngineState, ct->_table[i].pos), obj->_variables.size(), obj->methods_nr); + obj_get_name(_vm->_gamestate, ct->_table[i].pos), obj->_variables.size(), obj->methods_nr); } } break; @@ -1342,7 +1492,7 @@ bool Console::cmdSegmentInfo(int argc, const char **argv) { } if (!scumm_stricmp(argv[1], "all")) { - for (uint i = 0; i < g_EngineState->seg_manager->_heap.size(); i++) + for (uint i = 0; i < _vm->_gamestate->seg_manager->_heap.size(); i++) segmentInfo(i); } else { int nr = atoi(argv[1]); @@ -1361,7 +1511,7 @@ bool Console::cmdKillSegment(int argc, const char **argv) { return true; } - g_EngineState->seg_manager->getScript(atoi(argv[1]))->setLockers(0); + _vm->_gamestate->seg_manager->getScript(atoi(argv[1]))->setLockers(0); return true; } @@ -1377,24 +1527,24 @@ bool Console::cmdShowMap(int argc, const char **argv) { return true; } - gfxop_set_clip_zone(g_EngineState->gfx_state, gfx_rect_fullscreen); + gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); int map = atoi(argv[1]); switch (map) { case 0: - g_EngineState->visual->add_dirty_abs((GfxContainer *)g_EngineState->visual, gfx_rect(0, 0, 320, 200), 0); - g_EngineState->visual->draw(Common::Point(0, 0)); + _vm->_gamestate->visual->add_dirty_abs((GfxContainer *)_vm->_gamestate->visual, gfx_rect(0, 0, 320, 200), 0); + _vm->_gamestate->visual->draw(Common::Point(0, 0)); break; case 1: - gfx_xlate_pixmap(g_EngineState->gfx_state->pic->priority_map, g_EngineState->gfx_state->driver->getMode(), GFX_XLATE_FILTER_NONE); - gfxop_draw_pixmap(g_EngineState->gfx_state, g_EngineState->gfx_state->pic->priority_map, gfx_rect(0, 0, 320, 200), Common::Point(0, 0)); + gfx_xlate_pixmap(_vm->_gamestate->gfx_state->pic->priority_map, _vm->_gamestate->gfx_state->driver->getMode(), GFX_XLATE_FILTER_NONE); + gfxop_draw_pixmap(_vm->_gamestate->gfx_state, _vm->_gamestate->gfx_state->pic->priority_map, gfx_rect(0, 0, 320, 200), Common::Point(0, 0)); break; case 2: - gfx_xlate_pixmap(g_EngineState->gfx_state->control_map, g_EngineState->gfx_state->driver->getMode(), GFX_XLATE_FILTER_NONE); - gfxop_draw_pixmap(g_EngineState->gfx_state, g_EngineState->gfx_state->control_map, gfx_rect(0, 0, 320, 200), Common::Point(0, 0)); + gfx_xlate_pixmap(_vm->_gamestate->gfx_state->control_map, _vm->_gamestate->gfx_state->driver->getMode(), GFX_XLATE_FILTER_NONE); + gfxop_draw_pixmap(_vm->_gamestate->gfx_state, _vm->_gamestate->gfx_state->control_map, gfx_rect(0, 0, 320, 200), Common::Point(0, 0)); break; default: @@ -1402,7 +1552,7 @@ bool Console::cmdShowMap(int argc, const char **argv) { return true; } - gfxop_update(g_EngineState->gfx_state); + gfxop_update(_vm->_gamestate->gfx_state); return false; } @@ -1410,14 +1560,14 @@ bool Console::cmdShowMap(int argc, const char **argv) { bool Console::cmdSongLib(int argc, const char **argv) { DebugPrintf("Song library:\n"); - song_t *seeker = *(g_EngineState->_sound._songlib.lib); + Song *seeker = _vm->_gamestate->_sound._songlib._lib; do { DebugPrintf(" %p", (void *)seeker); if (seeker) { - DebugPrintf("[%04lx,p=%d,s=%d]->", seeker->handle, seeker->priority, seeker->status); - seeker = seeker->next; + DebugPrintf("[%04lx,p=%d,s=%d]->", seeker->_handle, seeker->_priority, seeker->_status); + seeker = seeker->_next; } DebugPrintf("\n"); } while (seeker); @@ -1428,12 +1578,12 @@ bool Console::cmdSongLib(int argc, const char **argv) { bool Console::cmdGCInvoke(int argc, const char **argv) { DebugPrintf("Performing garbage collection...\n"); - run_gc(g_EngineState); + run_gc(_vm->_gamestate); return true; } bool Console::cmdGCObjects(int argc, const char **argv) { - reg_t_hash_map *use_map = find_all_used_references(g_EngineState); + reg_t_hash_map *use_map = find_all_used_references(_vm->_gamestate); DebugPrintf("Reachable object references (normalised):\n"); for (reg_t_hash_map::iterator i = use_map->begin(); i != use_map->end(); ++i) { @@ -1447,7 +1597,7 @@ bool Console::cmdGCObjects(int argc, const char **argv) { void _print_address(void * _, reg_t addr) { if (addr.segment) - ((SciEngine *)g_engine)->getDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(addr)); + ((SciEngine *)g_engine)->getSciDebugger()->DebugPrintf(" %04x:%04x\n", PRINT_REG(addr)); } bool Console::cmdGCShowReachable(int argc, const char **argv) { @@ -1460,20 +1610,20 @@ bool Console::cmdGCShowReachable(int argc, const char **argv) { reg_t addr; - if (parse_reg_t(g_EngineState, argv[1], &addr)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &addr)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } - MemObject *mobj = GET_SEGMENT_ANY(*g_EngineState->seg_manager, addr.segment); + MemObject *mobj = GET_SEGMENT_ANY(*_vm->_gamestate->seg_manager, addr.segment); if (!mobj) { DebugPrintf("Unknown segment : %x\n", addr.segment); return 1; } DebugPrintf("Reachable from %04x:%04x:\n", PRINT_REG(addr)); - mobj->listAllOutgoingReferences(g_EngineState, addr, NULL, _print_address); + mobj->listAllOutgoingReferences(_vm->_gamestate, addr, NULL, _print_address); return true; } @@ -1489,13 +1639,13 @@ bool Console::cmdGCShowFreeable(int argc, const char **argv) { reg_t addr; - if (parse_reg_t(g_EngineState, argv[1], &addr)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &addr)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } - MemObject *mobj = GET_SEGMENT_ANY(*g_EngineState->seg_manager, addr.segment); + MemObject *mobj = GET_SEGMENT_ANY(*_vm->_gamestate->seg_manager, addr.segment); if (!mobj) { DebugPrintf("Unknown segment : %x\n", addr.segment); return true; @@ -1519,39 +1669,35 @@ bool Console::cmdGCNormalize(int argc, const char **argv) { reg_t addr; - if (parse_reg_t(g_EngineState, argv[1], &addr)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &addr)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } - MemObject *mobj = GET_SEGMENT_ANY(*g_EngineState->seg_manager, addr.segment); + MemObject *mobj = GET_SEGMENT_ANY(*_vm->_gamestate->seg_manager, addr.segment); if (!mobj) { DebugPrintf("Unknown segment : %x\n", addr.segment); return true; } - addr = mobj->findCanonicAddress(g_EngineState->seg_manager, addr); + addr = mobj->findCanonicAddress(_vm->_gamestate->seg_manager, addr); DebugPrintf(" %04x:%04x\n", PRINT_REG(addr)); return true; } bool Console::cmdVMVarlist(int argc, const char **argv) { - //const char *varnames[] = {"global", "local", "temp", "param"}; + const char *varnames[] = {"global", "local", "temp", "param"}; DebugPrintf("Addresses of variables in the VM:\n"); -#if 0 - // TODO: p_var_segs, p_vars, p_var_base, p_var_max - for (int i = 0; i < 4; i++) { - DebugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(p_var_segs[i], p_vars[i] - p_var_base[i]))); - if (p_var_max) - DebugPrintf(" total %d", p_var_max[i]); + DebugPrintf("%s vars at %04x:%04x ", varnames[i], PRINT_REG(make_reg(debugState.p_var_segs[i], debugState.p_vars[i] - debugState.p_var_base[i]))); + if (debugState.p_var_max) + DebugPrintf(" total %d", debugState.p_var_max[i]); DebugPrintf("\n"); } -#endif return true; } @@ -1567,7 +1713,7 @@ bool Console::cmdVMVars(int argc, const char **argv) { return true; } - //const char *varnames[] = {"global", "local", "temp", "param"}; + const char *varnames[] = {"global", "local", "temp", "param"}; const char *varabbrev = "gltp"; const char *vartype_pre = strchr(varabbrev, *argv[1]); int vartype; @@ -1585,31 +1731,21 @@ bool Console::cmdVMVars(int argc, const char **argv) { return true; } -#if 0 - // TODO: p_var_max - if ((p_var_max) && (p_var_max[vartype] <= idx)) { - DebugPrintf("Max. index is %d (0x%x)\n", p_var_max[vartype], p_var_max[vartype]); + if ((debugState.p_var_max) && (debugState.p_var_max[vartype] <= idx)) { + DebugPrintf("Max. index is %d (0x%x)\n", debugState.p_var_max[vartype], debugState.p_var_max[vartype]); return true; } -#endif switch (argc) { case 2: -#if 0 - // TODO: p_vars - DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(p_vars[vartype][idx])); -#endif + DebugPrintf("%s var %d == %04x:%04x\n", varnames[vartype], idx, PRINT_REG(debugState.p_vars[vartype][idx])); break; case 3: -#if 0 - // TODO: p_vars - - if (parse_reg_t(g_EngineState, argv[3], &p_vars[vartype][idx])) { + if (parse_reg_t(_vm->_gamestate, argv[3], &debugState.p_vars[vartype][idx])) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } -#endif break; default: DebugPrintf("Too many arguments\n"); @@ -1625,19 +1761,19 @@ bool Console::cmdStack(int argc, const char **argv) { return true; } - if (g_EngineState->_executionStack.empty()) { + if (_vm->_gamestate->_executionStack.empty()) { DebugPrintf("No exec stack!"); return true; } - ExecStack &xs = g_EngineState->_executionStack.back(); + ExecStack &xs = _vm->_gamestate->_executionStack.back(); int nr = atoi(argv[1]); for (int i = nr; i > 0; i--) { if ((xs.sp - xs.fp - i) == 0) DebugPrintf("-- temp variables --\n"); - if (xs.sp - i >= g_EngineState->stack_base) - DebugPrintf("ST:%04x = %04x:%04x\n", (unsigned)(xs.sp - i - g_EngineState->stack_base), PRINT_REG(xs.sp[-i])); + if (xs.sp - i >= _vm->_gamestate->stack_base) + DebugPrintf("ST:%04x = %04x:%04x\n", (unsigned)(xs.sp - i - _vm->_gamestate->stack_base), PRINT_REG(xs.sp[-i])); } return true; @@ -1655,13 +1791,13 @@ bool Console::cmdValueType(int argc, const char **argv) { reg_t val; - if (parse_reg_t(g_EngineState, argv[1], &val)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &val)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } - int t = determine_reg_type(g_EngineState, val, true); + int t = determine_reg_type(_vm->_gamestate, val, true); int invalid = t & KSIG_INVALID; switch (t & ~KSIG_INVALID) { @@ -1699,7 +1835,7 @@ bool Console::cmdViewListNode(int argc, const char **argv) { reg_t addr; - if (parse_reg_t(g_EngineState, argv[1], &addr)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &addr)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; @@ -1722,21 +1858,21 @@ bool Console::cmdViewReference(int argc, const char **argv) { reg_t reg = NULL_REG; reg_t reg_end = NULL_REG; - if (parse_reg_t(g_EngineState, argv[1], ®)) { + if (parse_reg_t(_vm->_gamestate, argv[1], ®)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } if (argc > 2) { - if (parse_reg_t(g_EngineState, argv[2], ®_end)) { + if (parse_reg_t(_vm->_gamestate, argv[2], ®_end)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } } - int type_mask = determine_reg_type(g_EngineState, reg, 1); + int type_mask = determine_reg_type(_vm->_gamestate, reg, 1); int filter; int found = 0; @@ -1766,7 +1902,7 @@ bool Console::cmdViewReference(int argc, const char **argv) { case 0: break; case KSIG_LIST: { - List *l = lookup_list(g_EngineState, reg); + List *l = lookup_list(_vm->_gamestate, reg); DebugPrintf("list\n"); @@ -1782,11 +1918,11 @@ bool Console::cmdViewReference(int argc, const char **argv) { break; case KSIG_OBJECT: DebugPrintf("object\n"); - printObject(g_EngineState, reg); + printObject(_vm->_gamestate, reg); break; case KSIG_REF: { int size; - unsigned char *block = g_EngineState->seg_manager->dereference(reg, &size); + unsigned char *block = _vm->_gamestate->seg_manager->dereference(reg, &size); DebugPrintf("raw data\n"); @@ -1830,32 +1966,28 @@ bool Console::cmdViewObject(int argc, const char **argv) { reg_t addr; - if (parse_reg_t(g_EngineState, argv[1], &addr)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &addr)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } DebugPrintf("Information on the object at the given address:\n"); - printObject(g_EngineState, addr); + printObject(_vm->_gamestate, addr); return true; } bool Console::cmdViewActiveObject(int argc, const char **argv) { DebugPrintf("Information on the currently active object or class:\n"); - -#if 0 - // TODO: p_objp - printObject(g_EngineState, *p_objp); -#endif + printObject(_vm->_gamestate, *debugState.p_objp); return true; } bool Console::cmdViewAccumulatorObject(int argc, const char **argv) { DebugPrintf("Information on the currently active object or class at the address indexed by the accumulator:\n"); - printObject(g_EngineState, g_EngineState->r_acc); + printObject(_vm->_gamestate, _vm->_gamestate->r_acc); return true; } @@ -1875,13 +2007,13 @@ bool Console::cmdSetAccumulator(int argc, const char **argv) { reg_t val; - if (parse_reg_t(g_EngineState, argv[1], &val)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &val)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } - g_EngineState->r_acc = val; + _vm->_gamestate->r_acc = val; return true; } @@ -1889,31 +2021,31 @@ bool Console::cmdSetAccumulator(int argc, const char **argv) { bool Console::cmdBacktrace(int argc, const char **argv) { DebugPrintf("Dumping the send/self/super/call/calle/callb stack:\n"); - DebugPrintf("Call stack (current base: 0x%x):\n", g_EngineState->execution_stack_base); + DebugPrintf("Call stack (current base: 0x%x):\n", _vm->_gamestate->execution_stack_base); Common::List<ExecStack>::iterator iter; uint i = 0; - for (iter = g_EngineState->_executionStack.begin(); - iter != g_EngineState->_executionStack.end(); ++iter, ++i) { + for (iter = _vm->_gamestate->_executionStack.begin(); + iter != _vm->_gamestate->_executionStack.end(); ++iter, ++i) { ExecStack &call = *iter; - const char *objname = obj_get_name(g_EngineState, call.sendp); + const char *objname = obj_get_name(_vm->_gamestate, call.sendp); int paramc, totalparamc; switch (call.type) { case EXEC_STACK_TYPE_CALL: {// Normal function sciprintf(" %x:[%x] %s::%s(", i, call.origin, objname, (call.selector == -1) ? "<call[be]?>" : - selector_name(g_EngineState, call.selector)); + selector_name(_vm->_gamestate, call.selector)); } break; case EXEC_STACK_TYPE_KERNEL: // Kernel function - sciprintf(" %x:[%x] k%s(", i, call.origin, g_EngineState->_kernel->getKernelName(-(call.selector) - 42).c_str()); + sciprintf(" %x:[%x] k%s(", i, call.origin, _vm->_gamestate->_kernel->getKernelName(-(call.selector) - 42).c_str()); break; case EXEC_STACK_TYPE_VARSELECTOR: sciprintf(" %x:[%x] vs%s %s::%s (", i, call.origin, (call.argc) ? "write" : "read", - objname, g_EngineState->_kernel->getSelectorName(call.selector).c_str()); + objname, _vm->_gamestate->_kernel->getSelectorName(call.selector).c_str()); break; } @@ -1938,15 +2070,15 @@ bool Console::cmdBacktrace(int argc, const char **argv) { if (call.sp == CALL_SP_CARRY) sciprintf(" sp,fp:carry"); else { - sciprintf(" sp=ST:%04x", (unsigned)(call.sp - g_EngineState->stack_base)); - sciprintf(" fp=ST:%04x", (unsigned)(call.fp - g_EngineState->stack_base)); + sciprintf(" sp=ST:%04x", (unsigned)(call.sp - _vm->_gamestate->stack_base)); + sciprintf(" fp=ST:%04x", (unsigned)(call.fp - _vm->_gamestate->stack_base)); } } else sciprintf(" pc:none"); - sciprintf(" argp:ST:%04x", (unsigned)(call.variables_argp - g_EngineState->stack_base)); + sciprintf(" argp:ST:%04x", (unsigned)(call.variables_argp - _vm->_gamestate->stack_base)); if (call.type == EXEC_STACK_TYPE_CALL) - sciprintf(" script: %d", (*(Script *)g_EngineState->seg_manager->_heap[call.addr.pc.segment]).nr); + sciprintf(" script: %d", (*(Script *)_vm->_gamestate->seg_manager->_heap[call.addr.pc.segment]).nr); sciprintf("\n"); } @@ -1954,8 +2086,255 @@ bool Console::cmdBacktrace(int argc, const char **argv) { return true; } +bool Console::cmdStep(int argc, const char **argv) { + debugState.isValid = false; + if (argc == 2 && atoi(argv[1]) > 0) + debugState.runningStep = atoi(argv[1]) - 1; + + return true; +} + +bool Console::cmdStepEvent(int argc, const char **argv) { + debugState.stopOnEvent = true; + debugState.isValid = false; + + return true; +} + +bool Console::cmdStepRet(int argc, const char **argv) { + debugState.seeking = kDebugSeekLevelRet; + debugState.seekLevel = _vm->_gamestate->_executionStack.size() - 1; + debugState.isValid = false; + + return true; +} + +bool Console::cmdStepGlobal(int argc, const char **argv) { + if (argc != 2) { + DebugPrintf("Steps until the global variable with the specified index is modified.\n"); + DebugPrintf("Usage: %s <global variable index>\n", argv[0]); + return true; + } + + debugState.seeking = kDebugSeekGlobal; + debugState.seekSpecial = atoi(argv[1]); + debugState.isValid = false; + + return true; +} + +bool Console::cmdStepCallk(int argc, const char **argv) { + int callk_index; + char *endptr; + + if (argc == 2) { + /* Try to convert the parameter to a number. If the conversion stops + before end of string, assume that the parameter is a function name + and scan the function table to find out the index. */ + callk_index = strtoul(argv[1], &endptr, 0); + if (*endptr != '\0') { + callk_index = -1; + for (uint i = 0; i < _vm->_gamestate->_kernel->getKernelNamesSize(); i++) + if (argv[1] == _vm->_gamestate->_kernel->getKernelName(i)) { + callk_index = i; + break; + } + + if (callk_index == -1) { + DebugPrintf("Unknown kernel function '%s'\n", argv[1]); + return true; + } + } + + debugState.seeking = kDebugSeekSpecialCallk; + debugState.seekSpecial = callk_index; + debugState.isValid = false; + } else { + debugState.seeking = kDebugSeekCallk; + debugState.isValid = false; + } + + return true; +} + +bool Console::cmdDissassemble(int argc, const char **argv) { + if (argc != 3) { + DebugPrintf("Disassembles a method by name.\n"); + DebugPrintf("Usage: %s <object> <method>\n", argv[0]); + return true; + } + + reg_t objAddr = NULL_REG; + + if (parse_reg_t(_vm->_gamestate, argv[1], &objAddr)) { + DebugPrintf("Invalid address passed.\n"); + DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); + return true; + } + + Object *obj = obj_get(_vm->_gamestate, objAddr); + int selector_id = _vm->_gamestate->_kernel->findSelector(argv[2]); + reg_t addr; + + if (!obj) { + DebugPrintf("Not an object."); + return true; + } + + if (selector_id < 0) { + DebugPrintf("Not a valid selector name."); + return true; + } + + if (lookup_selector(_vm->_gamestate, objAddr, selector_id, NULL, &addr) != kSelectorMethod) { + DebugPrintf("Not a method."); + return true; + } + + do { + // TODO + //addr = disassemble(_vm->_gamestate, addr, 0, 0); + } while (addr.offset > 0); + + return true; +} + +bool Console::cmdDissassembleAddress(int argc, const char **argv) { + if (argc < 2) { + DebugPrintf("Disassembles one or more commands.\n"); + DebugPrintf("Usage: %s [startaddr] <options>\n", argv[0]); + DebugPrintf("Valid options are:\n"); + DebugPrintf(" bwt : Print byte/word tag\n"); + DebugPrintf(" c<x> : Disassemble <x> bytes\n"); + DebugPrintf(" bc : Print bytecode\n"); + return true; + } + + reg_t vpc = NULL_REG; + int op_count = 1; + int do_bwc = 0; + int do_bytes = 0; + int size; + + if (parse_reg_t(_vm->_gamestate, argv[1], &vpc)) { + DebugPrintf("Invalid address passed.\n"); + DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); + return true; + } + + _vm->_gamestate->seg_manager->dereference(vpc, &size); + size += vpc.offset; // total segment size + + for (int i = 1; i < argc; i++) { + if (!scumm_stricmp(argv[i], "bwt")) + do_bwc = 1; + else if (!scumm_stricmp(argv[i], "bc")) + do_bytes = 1; + else if (toupper(argv[i][0]) == 'C') + op_count = atoi(argv[i] + 1); + else { + DebugPrintf("Invalid option '%s'\n", argv[i]); + return true; + } + } + + if (op_count < 0) { + DebugPrintf("Invalid op_count\n"); + return true; + } + + do { + // TODO + //vpc = disassemble(_vm->_gamestate, vpc, do_bwc, do_bytes); + + } while ((vpc.offset > 0) && (vpc.offset + 6 < size) && (--op_count)); + + return true; +} + +bool Console::cmdSend(int argc, const char **argv) { + if (argc < 3) { + DebugPrintf("Sends a message to an object.\n"); + DebugPrintf("Usage: %s <object> <selector name> <param1> <param2> ... <paramn>\n", argv[0]); + DebugPrintf("Example: send ?fooScript cue\n"); + return true; + } + + reg_t object; + + if (parse_reg_t(_vm->_gamestate, argv[1], &object)) { + DebugPrintf("Invalid address passed for parameter 1.\n"); + DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); + return true; + } + + const char *selector_name = argv[2]; + StackPtr stackframe = _vm->_gamestate->_executionStack.front().sp; + int selector_id; + int i; + ExecStack *xstack; + Object *o; + reg_t fptr; + + selector_id = _vm->_gamestate->_kernel->findSelector(selector_name); + + if (selector_id < 0) { + sciprintf("Unknown selector: \"%s\"\n", selector_name); + return 1; + } + + o = obj_get(_vm->_gamestate, object); + if (o == NULL) { + sciprintf("Address \"%04x:%04x\" is not an object\n", PRINT_REG(object)); + return 1; + } + + SelectorType selector_type = lookup_selector(_vm->_gamestate, object, selector_id, 0, &fptr); + + if (selector_type == kSelectorNone) { + sciprintf("Object does not support selector: \"%s\"\n", selector_name); + return 1; + } + + stackframe[0] = make_reg(0, selector_id); + stackframe[1] = make_reg(0, argc - 3); // -object -selector name -command name + + for (i = 3; i < argc; i++) { + if (parse_reg_t(_vm->_gamestate, argv[i], &stackframe[i])) { + DebugPrintf("Invalid address passed for parameter %d.\n", i); + DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); + return true; + } + } + + xstack = add_exec_stack_entry(_vm->_gamestate, fptr, + _vm->_gamestate->_executionStack.front().sp + argc, + object, argc - 3, + _vm->_gamestate->_executionStack.front().sp - 1, 0, object, + _vm->_gamestate->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS); + xstack->selector = selector_id; + xstack->type = selector_type == kSelectorVariable ? EXEC_STACK_TYPE_VARSELECTOR : EXEC_STACK_TYPE_CALL; + + // Now commit the actual function: + xstack = send_selector(_vm->_gamestate, object, object, stackframe, argc - 3, stackframe); + + xstack->sp += argc; + xstack->fp += argc; + + _vm->_gamestate->_executionStackPosChanged = true; + + return true; +} + +bool Console::cmdGo(int argc, const char **argv) { + debugState.seeking = kDebugSeekNothing; + debugState.isValid = false; + + return true; +} + bool Console::cmdBreakpointList(int argc, const char **argv) { - Breakpoint *bp = g_EngineState->bp_list; + Breakpoint *bp = _vm->_gamestate->bp_list; int i = 0; int bpdata; @@ -1994,7 +2373,7 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) { // Find breakpoint with given index bp_prev = NULL; - bp = g_EngineState->bp_list; + bp = _vm->_gamestate->bp_list; while (bp && i < idx) { bp_prev = bp; bp = bp->next; @@ -2013,11 +2392,11 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) { if (bp_prev) bp_prev->next = bp_next; else - g_EngineState->bp_list = bp_next; + _vm->_gamestate->bp_list = bp_next; // Check if there are more breakpoints of the same type. If not, clear // the respective bit in s->have_bp. - for (bp = g_EngineState->bp_list; bp; bp = bp->next) { + for (bp = _vm->_gamestate->bp_list; bp; bp = bp->next) { if (bp->type == type) { found = 1; break; @@ -2025,7 +2404,7 @@ bool Console::cmdBreakpointDelete(int argc, const char **argv) { } if (!found) - g_EngineState->have_bp &= ~type; + _vm->_gamestate->have_bp &= ~type; return true; } @@ -2044,23 +2423,23 @@ bool Console::cmdBreakpointExecMethod(int argc, const char **argv) { Thus, we can't check whether the command argument is a valid method name. A breakpoint set on an invalid method name will just never trigger. */ Breakpoint *bp; - if (g_EngineState->bp_list) { + if (_vm->_gamestate->bp_list) { // List exists, append the breakpoint to the end - bp = g_EngineState->bp_list; + bp = _vm->_gamestate->bp_list; while (bp->next) bp = bp->next; bp->next = (Breakpoint *)malloc(sizeof(Breakpoint)); bp = bp->next; } else { // No list, so create the list head - g_EngineState->bp_list = (Breakpoint *)malloc(sizeof(Breakpoint)); - bp = g_EngineState->bp_list; + _vm->_gamestate->bp_list = (Breakpoint *)malloc(sizeof(Breakpoint)); + bp = _vm->_gamestate->bp_list; } bp->next = NULL; bp->type = BREAK_SELECTOR; bp->data.name = (char *)malloc(strlen(argv[1]) + 1); strcpy(bp->data.name, argv[1]); - g_EngineState->have_bp |= BREAK_SELECTOR; + _vm->_gamestate->have_bp |= BREAK_SELECTOR; return true; } @@ -2077,22 +2456,22 @@ bool Console::cmdBreakpointExecFunction(int argc, const char **argv) { Thus, we can't check whether the command argument is a valid method name. A breakpoint set on an invalid method name will just never trigger. */ Breakpoint *bp; - if (g_EngineState->bp_list) { + if (_vm->_gamestate->bp_list) { // List exists, append the breakpoint to the end - bp = g_EngineState->bp_list; + bp = _vm->_gamestate->bp_list; while (bp->next) bp = bp->next; bp->next = (Breakpoint *)malloc(sizeof(Breakpoint)); bp = bp->next; } else { // No list, so create the list head - g_EngineState->bp_list = (Breakpoint *)malloc(sizeof(Breakpoint)); - bp = g_EngineState->bp_list; + _vm->_gamestate->bp_list = (Breakpoint *)malloc(sizeof(Breakpoint)); + bp = _vm->_gamestate->bp_list; } bp->next = NULL; bp->type = BREAK_EXPORT; bp->data.address = (atoi(argv[1]) << 16 | atoi(argv[2])); - g_EngineState->have_bp |= BREAK_EXPORT; + _vm->_gamestate->have_bp |= BREAK_EXPORT; return true; } @@ -2105,7 +2484,7 @@ bool Console::cmdIsSample(int argc, const char **argv) { return true; } - Resource *song = _vm->getResMgr()->findResource(kResourceTypeSound, atoi(argv[1]), 0); + Resource *song = _vm->getResMgr()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0); SongIterator *songit; Audio::AudioStream *data; @@ -2143,7 +2522,7 @@ bool Console::cmdSfx01Header(int argc, const char **argv) { return true; } - Resource *song = _vm->getResMgr()->findResource(kResourceTypeSound, atoi(argv[1]), 0); + Resource *song = _vm->getResMgr()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0); if (!song) { DebugPrintf("Doesn't exist\n"); @@ -2308,7 +2687,7 @@ bool Console::cmdSfx01Track(int argc, const char **argv) { return true; } - Resource *song = _vm->getResMgr()->findResource(kResourceTypeSound, atoi(argv[1]), 0); + Resource *song = _vm->getResMgr()->findResource(ResourceId(kResourceTypeSound, atoi(argv[1])), 0); int offset = atoi(argv[2]); @@ -2333,18 +2712,18 @@ bool Console::cmdStopSfx(int argc, const char **argv) { reg_t id; - if (parse_reg_t(g_EngineState, argv[1], &id)) { + if (parse_reg_t(_vm->_gamestate, argv[1], &id)) { DebugPrintf("Invalid address passed.\n"); DebugPrintf("Check the \"addresses\" command on how to use addresses\n"); return true; } int handle = id.segment << 16 | id.offset; // frobnicate handle - EngineState* s = g_EngineState; // for PUT_SEL32V + EngineState* s = _vm->_gamestate; // for PUT_SEL32V if (id.segment) { - g_EngineState->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); - g_EngineState->_sound.sfx_remove_song(handle); + _vm->_gamestate->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); + _vm->_gamestate->_sound.sfx_remove_song(handle); PUT_SEL32V(id, signal, -1); PUT_SEL32V(id, nodePtr, 0); PUT_SEL32V(id, handle, 0); @@ -2363,9 +2742,9 @@ bool Console::cmdExit(int argc, const char **argv) { if (!scumm_stricmp(argv[1], "game")) { // Quit gracefully script_abort_flag = 1; // Terminate VM - g_debugstate_valid = 0; - g_debug_seeking = 0; - g_debug_step_running = 0; + debugState.isValid = false; + debugState.seeking = kDebugSeekNothing; + debugState.runningStep = 0; } else if (!scumm_stricmp(argv[1], "now")) { // Quit ungracefully @@ -2583,7 +2962,7 @@ void Console::printList(List *l) { while (!pos.isNull()) { Node *node; - NodeTable *nt = (NodeTable *)GET_SEGMENT(*g_EngineState->seg_manager, pos.segment, MEM_OBJ_NODES); + NodeTable *nt = (NodeTable *)GET_SEGMENT(*_vm->_gamestate->seg_manager, pos.segment, MEM_OBJ_NODES); if (!nt || !nt->isValidEntry(pos.offset)) { DebugPrintf(" WARNING: %04x:%04x: Doesn't contain list node!\n", @@ -2610,7 +2989,7 @@ void Console::printList(List *l) { } int Console::printNode(reg_t addr) { - MemObject *mobj = GET_SEGMENT(*g_EngineState->seg_manager, addr.segment, MEM_OBJ_LISTS); + MemObject *mobj = GET_SEGMENT(*_vm->_gamestate->seg_manager, addr.segment, MEM_OBJ_LISTS); if (mobj) { ListTable *lt = (ListTable *)mobj; @@ -2627,7 +3006,7 @@ int Console::printNode(reg_t addr) { } else { NodeTable *nt; Node *node; - mobj = GET_SEGMENT(*g_EngineState->seg_manager, addr.segment, MEM_OBJ_NODES); + mobj = GET_SEGMENT(*_vm->_gamestate->seg_manager, addr.segment, MEM_OBJ_NODES); if (!mobj) { DebugPrintf("Segment #%04x is not a list or node segment\n", addr.segment); @@ -2853,34 +3232,34 @@ int c_stepover(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { return 1; } - g_debugstate_valid = 0; + debugState.isValid = false; opcode = s->_heap[*p_pc]; opnumber = opcode >> 1; if (opnumber == 0x22 /* callb */ || opnumber == 0x23 /* calle */ || opnumber == 0x25 /* send */ || opnumber == 0x2a /* self */ || opnumber == 0x2b /* super */) { - g_debug_seeking = _DEBUG_SEEK_SO; - s_debug_seek_level = s->_executionStack.size()-1; - // Store in s_debug_seek_special the offset of the next command after send + debugState.seeking = kDebugSeekSO; + debugState.seekLevel = s->_executionStack.size()-1; + // Store in debugState.seekSpecial the offset of the next command after send switch (opcode) { case 0x46: // calle W - s_debug_seek_special = *p_pc + 5; + debugState.seekSpecial = *p_pc + 5; break; case 0x44: // callb W case 0x47: // calle B case 0x56: // super W - s_debug_seek_special = *p_pc + 4; + debugState.seekSpecial = *p_pc + 4; break; case 0x45: // callb B case 0x57: // super B case 0x4A: // send W case 0x54: // self W - s_debug_seek_special = *p_pc + 3; + debugState.seekSpecial = *p_pc + 3; break; default: - s_debug_seek_special = *p_pc + 2; + debugState.seekSpecial = *p_pc + 2; } } diff --git a/engines/sci/console.h b/engines/sci/console.h index b2e66daa0f..84a8d2f942 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -59,9 +59,10 @@ private: bool cmdSuffixes(int argc, const char **argv); bool cmdParseGrammar(int argc, const char **argv); bool cmdParserNodes(int argc, const char **argv); - bool cmdParserWords(int argc, const char **argv); + bool cmdParserWords(int argc, const char **argv); bool cmdSentenceFragments(int argc, const char **argv); bool cmdParse(int argc, const char **argv); + bool cmdSetParseNodes(int argc, const char **argv); // Resources bool cmdHexDump(int argc, const char **argv); bool cmdResourceId(int argc, const char **argv); @@ -121,6 +122,15 @@ private: bool cmdDissectScript(int argc, const char **argv); bool cmdSetAccumulator(int argc, const char **argv); bool cmdBacktrace(int argc, const char **argv); + bool cmdStep(int argc, const char **argv); + bool cmdStepEvent(int argc, const char **argv); + bool cmdStepRet(int argc, const char **argv); + bool cmdStepGlobal(int argc, const char **argv); + bool cmdStepCallk(int argc, const char **argv); + bool cmdDissassemble(int argc, const char **argv); + bool cmdDissassembleAddress(int argc, const char **argv); + bool cmdSend(int argc, const char **argv); + bool cmdGo(int argc, const char **argv); // Breakpoints bool cmdBreakpointList(int argc, const char **argv); bool cmdBreakpointDelete(int argc, const char **argv); @@ -144,6 +154,7 @@ private: private: SciEngine *_vm; + bool _mouseVisible; }; } // End of namespace Sci diff --git a/engines/sci/debug.h b/engines/sci/debug.h index ec44838826..fbd98e0d6f 100644 --- a/engines/sci/debug.h +++ b/engines/sci/debug.h @@ -28,19 +28,41 @@ namespace Sci { -// Various global variables used for debugging are declared here - -extern int g_stop_on_event; +enum DebugSeeking { + kDebugSeekNothing = 0, + kDebugSeekCallk = 1, // Step forward until callk is found + kDebugSeekLevelRet = 2, // Step forward until returned from this level + kDebugSeekSpecialCallk = 3, // Step forward until a /special/ callk is found + kDebugSeekSO = 4, // Step forward until specified PC (after the send command) and stack depth + kDebugSeekGlobal = 5 // Step forward until one specified global variable is modified +}; -extern int g_debugstate_valid; -extern int g_debug_seeking; -extern int g_debug_step_running; +struct DebugState { + bool isValid; + bool stopOnEvent; + DebugSeeking seeking; // Stepping forward until some special condition is met + int runningStep; // Set to > 0 to allow multiple stepping + int seekLevel; // Used for seekers that want to check their exec stack depth + int seekSpecial; // Used for special seeks + int old_pc_offset; + StackPtr old_sp; + reg_t *p_pc; + StackPtr *p_sp; + StackPtr *p_pp; + reg_t *p_objp; + int *p_restadjust; + SegmentId *p_var_segs; + reg_t **p_vars; + reg_t **p_var_base; + int *p_var_max; // May be NULL even in valid state! +}; +// Various global variables used for debugging are declared here extern int g_debug_sleeptime_factor; extern int g_debug_simulated_key; extern bool g_debug_track_mouse_clicks; extern bool g_debug_weak_validations; - +extern DebugState debugState; } // End of namespace Sci diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index 38095e446e..f04c390944 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -31,9 +31,7 @@ namespace Sci { -// The 4 SCI0 engine generations (pre-395, pre-502, pre-629 and post-629) -#define GF_FOR_SCI0_BEFORE_395 (GF_SCI0_OLD | GF_SCI0_OLDGFXFUNCS | GF_SCI0_OLDGETTIME) -#define GF_FOR_SCI0_BEFORE_502 (GF_SCI0_OLDGFXFUNCS | GF_SCI0_OLDGETTIME) +#define GF_FOR_SCI0_BEFORE_395 (GF_SCI0_OLD | GF_SCI0_OLDGETTIME) #define GF_FOR_SCI0_BEFORE_629 GF_SCI0_OLDGETTIME // SCI1 @@ -113,7 +111,7 @@ static const PlainGameDescriptor SciGameTitles[] = { {{"sci-fanmade", name, { \ {"resource.map", 0, resMapMd5, resMapSize}, \ {"resource.001", 0, resMd5, resSize}, \ - {NULL, 0, NULL, 0}}, lang, Common::kPlatformPC, 0}, \ + {NULL, 0, NULL, 0}}, lang, Common::kPlatformPC, 0, GUIO_NOSPEECH}, \ 0, \ SCI_VERSION_AUTODETECT, \ ver \ @@ -123,6 +121,9 @@ static const PlainGameDescriptor SciGameTitles[] = { #define FANMADE_V(name, resMapMd5, resMapSize, resMd5, resSize, ver) FANMADE_LV(name, resMapMd5, resMapSize, resMd5, resSize, Common::EN_ANY, ver) #define FANMADE(name, resMapMd5, resMapSize, resMd5, resSize) FANMADE_LV(name, resMapMd5, resMapSize, resMd5, resSize, Common::EN_ANY, SCI_VERSION_0) +using Common::GUIO_NONE; +using Common::GUIO_NOSPEECH; + // Game descriptions static const struct SciGameDescription SciGameDescriptions[] = { // Astro Chicken - English DOS @@ -130,8 +131,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"astrochicken", "", { {"resource.map", 0, "f3d1be7752d30ba60614533d531e2e98", 474}, {"resource.001", 0, "6fd05926c2199af0af6f72f90d0d7260", 126895}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -145,7 +146,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "3fb02ce493f6eacdcc3713851024f80e", 559540}, {"resource.002", 0, "d226d7d3b4f77c4a566913fc310487fc", 792380}, {"resource.003", 0, "d226d7d3b4f77c4a566913fc310487fc", 464348}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -160,7 +161,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "4e0836fadc324316c1a418125709ba45", 569057}, {"resource.002", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 826309}, {"resource.003", 0, "85e51acb5f9c539d66e3c8fe40e17da5", 493638}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -172,7 +173,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "467bb5e3224bb54640c3280032aebff5", 633}, {"resource.000", 0, "9780f040d58182994e22d2e34fab85b0", 67367}, {"resource.001", 0, "2af49dbd8f2e1db4ab09f9310dc91259", 570553}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -186,7 +187,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 346731}, {"resource.001", 0, "d2f5a1be74ed963fa849a76892be5290", 794832}, {"resource.002", 0, "c0c29c51af66d65cb53f49e785a2d978", 1280907}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -198,7 +199,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "5738c163e014bbe046474de009020b82", 2727}, {"resource.000", 0, "27ec5fa09cd12a7fd16e86d96a2ed245", 1197694}, {"resource.001", 0, "735be4e58957180cfc807d5e18fdffcd", 1433302}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -209,7 +210,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"christmas1988", "", { {"resource.map", 0, "39485580d34a72997f3d5b3aba4d24f1", 426}, {"resource.001", 0, "11391434f41c834090d7a1e9488ce936", 129739}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_395, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -220,7 +221,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"christmas1990", "16 Colors", { {"resource.map", 0, "8f656714a05b94423ac6eb10ee8797d0", 600}, {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 272629}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -231,7 +232,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"christmas1990", "256 Colors", { {"resource.map", 0, "44b8f45b841b9b5e17e939a35e443988", 600}, {"resource.001", 0, "acde93e58fca4f7a2a5a220558a94aa8", 335362}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -242,7 +243,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"christmas1992", "", { {"resource.map", 0, "f1f8c8a8443f523422af70b4ec85b71c", 318}, {"resource.000", 0, "62fb9256f8e7e6e65a6875efdb7939ac", 203396}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -259,7 +260,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 619219}, {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 713382}, {"resource.005", 0, "605b67a9ef199a9bb015745e7c004cf4", 478384}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -270,7 +271,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"iceman", "Demo", { {"resource.map", 0, "782974f29d8a824782d2d4aea39964e3", 1056}, {"resource.001", 0, "d4b75e280d1c3a97cfef1b0bebff387c", 573647}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -286,7 +287,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "36670a917550757d57df84c96cf9e6d9", 566549}, {"resource.003", 0, "d97a96f1ab91b41cf46a02cc89b0a04e", 624303}, {"resource.004", 0, "8613c45fc771d658e5a505b9a4a54f31", 670883}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -301,7 +302,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "250b859381ebf2bf8922bd99683b0cc1", 566464}, {"resource.003", 0, "dc7c5280e7acfaffe6ef2a6c963c5f94", 622118}, {"resource.004", 0, "64f342463f6f35ba71b3509ef696ae3f", 669188}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -319,7 +320,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "6821dc97cf643ba521a4e840dda3c58b", 647410}, {"resource.005", 0, "c6e551bdc24f0acc193159038d4ca767", 605882}, {"resource.006", 0, "8f880a536908ab496bbc552f7f5c3738", 585255}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -330,7 +331,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"camelot", "Demo", { {"resource.map", 0, "f4cd75c15be75e04cdca3acda2c0b0ea", 468}, {"resource.001", 0, "4930708722f34bfbaa4945fb08f55f61", 232523}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -345,7 +346,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "8e1a3a8c588007404b532b8dfacc1460", 722250}, {"resource.003", 0, "8e1a3a8c588007404b532b8dfacc1460", 723712}, {"resource.004", 0, "8e1a3a8c588007404b532b8dfacc1460", 729143}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -362,7 +363,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "8e1a3a8c588007404b532b8dfacc1460", 345734}, {"resource.006", 0, "8e1a3a8c588007404b532b8dfacc1460", 332446}, {"resource.007", 0, "8e1a3a8c588007404b532b8dfacc1460", 358182}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -380,7 +381,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "d1038c75d85a6650d48e07d174a6a913", 838175}, {"resource.005", 0, "1c3804e56b114028c5873a35c2f06d13", 653002}, {"resource.006", 0, "f9487732289a4f4966b4e34eea413325", 842817}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -397,7 +398,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1064637}, {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1154950}, {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1042966}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -414,7 +415,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "1867136d01ece57b531032d466910522", 823686}, {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1261462}, {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284720}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -430,7 +431,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "1867136d01ece57b531032d466910522", 823610}, {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1260237}, {"resource.005", 0, "21ebe6b39b57a73fc449f67f013765aa", 1284609}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -447,7 +448,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "b7bb35c027bb424ecefcd122768e5e60", 705631}, {"resource.005", 0, "58942b1aa6d6ffeb66e9f8897fd4435f", 469243}, {"resource.006", 0, "8c767b3939add63d11274065e46aad04", 713158}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -458,7 +459,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"longbow", "Demo", { {"resource.map", 0, "cbc5cb73341de1bff1b1e20a640af220", 588}, {"resource.001", 0, "f05a20cc07eee85da8e999d0ac0f596b", 869916}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -475,7 +476,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "9cfce07e204a329e94fda8b5657621da", 1101869}, {"resource.005", 0, "d036df0872f2db19bca34601276be2d7", 1176914}, {"resource.006", 0, "b367a6a59f29ee30dde1d88a5a41152d", 1123585}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -487,7 +488,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"ecoquest", "Demo", { {"resource.map", 0, "c819e171359b7c95f4c13b846d5c034e", 873}, {"resource.001", 0, "baf9393a9bfa73098adb501e5bc5487b", 657518}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -498,7 +499,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"ecoquest", "CD", { {"resource.map", 0, "a4b73d5d2b55bdb6e44345e99c8fbdd0", 4804}, {"resource.000", 0, "d908dbef56816ac6c60dd145fdeafb2b", 3536046}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -512,7 +513,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "96d4435d24c01f1c1675e46457604c5f", 1413719}, {"resource.002", 0, "28fe9b4f0567e71feb198bc9f3a2c605", 1241816}, {"resource.003", 0, "f3146df0ad4297f5ce35aa8c4753bf6c", 586832}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -526,7 +527,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212161}, {"resource.002", 0, "323b3b12f43d53f27d259beb225f0aa7", 1129316}, {"resource.003", 0, "83ac03e4bddb2c1ac2d36d2a587d0536", 1145616}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -540,7 +541,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, {"resource.002", 0, "02d7d0411f7903aacb3bc8b0f8ca8a9a", 1202581}, {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1175835}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -555,7 +556,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "2fed7451bca81b0c891eed1a956f2263", 1212060}, {"resource.002", 0, "2d21a1d2dcbffa551552e3e0725d2284", 1186033}, {"resource.003", 0, "84dd11b6825255671c703aee5ceff620", 1174993}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -566,7 +567,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"ecoquest2", "Demo", { {"resource.map", 0, "607cfa0d8a03b7d348c06ee727e3d939", 1321}, {"resource.000", 0, "dd6f614c43c029f063e93cd243af90a4", 525992}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -577,7 +578,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"ecoquest2", "Floppy", { {"resource.map", 0, "28fb7b6abb9fc1cb8882d7c2e701b63f", 5658}, {"resource.000", 0, "cc1d17e5637528dbe4a812699e1cbfc6", 4208192}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -588,7 +589,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"freddypharkas", "Demo", { {"resource.map", 0, "97aa9fcfe84c9993a64debd28c32393a", 1909}, {"resource.000", 0, "5ea8e7a3ea10cce6efd5c106dc62fd8c", 867724}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -599,7 +600,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"freddypharkas", "CD", { {"resource.map", 0, "d46b282f228a67ba13bd4b4009e95f8f", 6058}, {"resource.000", 0, "ee3c64ffff0ba9fb08bea2624631c598", 5490246}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -612,7 +613,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "554f65315d851184f6e38211489fdd8f", -1}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -625,7 +626,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "304b5a5781800affd2235152a5794fa8", -1}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -641,7 +642,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "419dbd5366f702b4123dedbbb0cffaae", 1456640}, {"resource.003", 0, "05acdc256c742e79c50b9fe7ec2cc898", 863310}, {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -654,7 +655,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a32674e7fbf7b213b4a066c8037f16b6", 5816}, {"resource.000", 0, "96b07e9b914dba1c8dc6c78a176326df", 5233230}, {"resource.msg", 0, "45b5bf74933ac3727e4cc844446dc052", 796156}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -665,7 +666,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"freddypharkas", "CD Demo", { {"resource.map", 0, "a62a7eae85dd1e6b07f39662b278437e", 1918}, {"resource.000", 0, "4962a3c4dd44e36e78ea4a7a374c2220", 957382}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -676,7 +677,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"funseeker", "", { {"resource.map", 0, "7ee6859ef74314f6d91938c3595348a9", 282}, {"resource.001", 0, "f1e680095424e31f7fae1255d36bacba", 40692}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -687,7 +688,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk1", "CD Demo", { {"resource.map", 0, "39645952ae0ed8072c7e838f31b75464", 2490}, {"resource.000", 0, "eb3ed7477ca4110813fe1fcf35928561", 1718450}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -699,7 +700,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk1", "", { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10783}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -710,7 +711,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk1", "", { {"resource.map", 0, "65e8c14092e4c9b3b3538b7602c8c5ec", 10783}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 13022630}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -721,7 +722,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk1", "", { {"resource.map", 0, "ad6508b0296b25c07b1f58828dc33696", 10789}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13077029}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -732,7 +733,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk1", "CD", { {"resource.map", 0, "372d059f75856afa6d73dd84cbb8913d", 10996}, {"resource.000", 0, "69b7516962510f780d38519cc15fcc7c", 12581736}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -743,7 +744,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk1", "CD", { {"resource.map", 0, "a7d3e55114c65647310373cb390815ba", 11392}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13400497}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -754,7 +755,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk1", "CD", { {"resource.map", 0, "7cb6e9bba15b544ec7a635c45bde9953", 11404}, {"resource.000", 0, "091cf08910780feabc56f8551b09cb36", 13381599}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -765,7 +766,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"gk2", "Demo", { {"resource.map", 0, "e0effce11c4908f4b91838741716c83d", 1351}, {"resource.000", 0, "d04cfc7f04b6f74d13025378be49ec2b", 4640330}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -785,7 +786,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"ressci.005", 0, "14b62d4a3bddee57a03cb1495a798a0f", 38075705}, {"resmap.006", 0, "ce9359037277b7d7976da185c2fa0aad", 2977}, {"ressci.006", 0, "8e44e03890205a7be12f45aaba9644b4", 60659424}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -796,7 +797,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"hoyle1", "Demo", { {"resource.map", 0, "60f764020a6b788bbbe415dbc2ccb9f3", 931}, {"resource.000", 0, "5fe3670e3ddcd4f85c10013b5453141a", 615522}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -809,7 +810,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 162783}, {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 342309}, {"resource.003", 0, "e0dd44069a62a463fd124974b915f10d", 328912}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -820,7 +821,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"hoyle1", "", { {"resource.map", 0, "1034a218943d12f1f36e753fa10c95b8", 4386}, {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 518308}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -833,7 +834,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "2a72b1aba65fa6e339370eb86d8601d1", 5166}, {"resource.001", 0, "e0dd44069a62a463fd124974b915f10d", 218755}, {"resource.002", 0, "e0dd44069a62a463fd124974b915f10d", 439502}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -846,7 +847,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "4f894d203f64aa23d9ff64d30ae36926", 2100}, {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 98138}, {"resource.002", 0, "8f2dd70abe01112eca464cda818b5eb6", 196631}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -858,7 +859,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"hoyle2", "", { {"resource.map", 0, "62ed48d20c580e5a98f102f7cd93706a", 1356}, {"resource.001", 0, "8f2dd70abe01112eca464cda818b5eb6", 222704}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -872,7 +873,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f1f158e428398cb87fc41fb4aa8c2119", 2088}, {"resource.000", 0, "595b6039ea1356e7f96a52c58eedcf22", 355791}, {"resource.001", 0, "143df8aef214a2db34c2d48190742012", 632273}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -885,7 +886,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"hoyle3", "Demo", { {"resource.map", 0, "0d06cacc87dc21a08cd017e73036f905", 735}, {"resource.001", 0, "24db2bccda0a3c43ac4a7b5edb116c7e", 797678}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -898,7 +899,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "7216a2972f9c595c45ab314941628e43", 2247}, {"resource.000", 0, "6ef28cac094dcd97fdb461662ead6f92", 541845}, {"resource.001", 0, "0a98a268ee99b92c233a0d7187c1f0fa", 845795}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -909,7 +910,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"hoyle4", "Demo", { {"resource.map", 0, "662087cb383e52e3cc4ae7ecb10e20aa", 938}, {"resource.000", 0, "24c10844792c54d476d272213cbac300", 675252}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -922,7 +923,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "65cbe19b36fffc71c8e7b2686bd49ad7", 1800}, {"resource.001", 0, "bac3ec6cb3e3920984ab0f32becf5163", 313476}, {"resource.002", 0, "b86daa3ba2784d1502da881eedb80d9b", 719747}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_01_VGA_ODD, SCI_VERSION_1 @@ -938,7 +939,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "9ae2a13708d691cd42f9129173c4b39d", 795123}, {"resource.003", 0, "9ae2a13708d691cd42f9129173c4b39d", 763224}, {"resource.004", 0, "9ae2a13708d691cd42f9129173c4b39d", 820443}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_01, SCI_VERSION_01 @@ -949,10 +950,10 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq1sci", "SCI Remake Demo", { {"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954}, {"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, - SCI_VERSION_01 + SCI_VERSION_0 }, // King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection) @@ -963,10 +964,10 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "fed9e0072ffd511d248674e60dee2099", 555439}, {"resource.002", 0, "fed9e0072ffd511d248674e60dee2099", 714062}, {"resource.003", 0, "fed9e0072ffd511d248674e60dee2099", 717478}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, - SCI_VERSION_01 + SCI_VERSION_0 }, // King's Quest 4 - English Amiga (from www.back2roots.org) @@ -979,7 +980,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "fb351106ec865fad9af5d78bd6b8e3cb", 663629}, {"resource.003", 0, "fd16c9c223f7dc5b65f06447615224ff", 683016}, {"resource.004", 0, "3fac034c7d130e055d05bc43a1f8d5f8", 549993}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -990,7 +991,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq4sci", "Demo", { {"resource.map", 0, "992ac7cc31d3717fe53818a9bb6d1dae", 594}, {"resource.001", 0, "143e1c14f15ad0fbfc714f648a65f661", 205330}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1005,7 +1006,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "77615c595388acf3d1df8e107bfb6b52", 536573}, {"resource.003", 0, "77615c595388acf3d1df8e107bfb6b52", 707591}, {"resource.004", 0, "77615c595388acf3d1df8e107bfb6b52", 479562}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1022,7 +1023,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "851a62d00972dc4002f472cc0d84e71d", 321593}, {"resource.006", 0, "851a62d00972dc4002f472cc0d84e71d", 333777}, {"resource.007", 0, "851a62d00972dc4002f472cc0d84e71d", 341038}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_395, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1039,7 +1040,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0c8566848a76eea19a6d6220914030a7", 325102}, {"resource.006", 0, "0c8566848a76eea19a6d6220914030a7", 337288}, {"resource.007", 0, "0c8566848a76eea19a6d6220914030a7", 343882}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_395, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1058,7 +1059,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "31a5487f4d942e6354d5be49d59707c9", 834146}, {"resource.006", 0, "26c0c25399b6715fec03fc3e12544fe3", 823048}, {"resource.007", 0, "b914b5901e786327213e779725d30dd1", 778772}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1077,7 +1078,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "5aa3d59968b569cd509dde00d4eb8751", 754201}, {"resource.006", 0, "56546b20db11a4836f900efa6d3a3e74", 672099}, {"resource.007", 0, "56546b20db11a4836f900efa6d3a3e74", 794194}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1096,7 +1097,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "de3c5c09e350fded36ca354998c2194d", 754784}, {"resource.006", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 672527}, {"resource.007", 0, "11cb750f5f816445ad0f4b9f50a4f59a", 794259}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1109,7 +1110,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f68ba690e5920725dcf9328001b90e33", 13122}, {"resource.000", 0, "449471bfd77be52f18a3773c7f7d843d", 571368}, {"resource.001", 0, "b45a581ff8751e052c7e364f58d3617f", 16800210}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1127,7 +1128,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "b6c43441cb78a9b484efc8e614aac092", 1287999}, {"resource.006", 0, "672ede1136e9e401658538e51bd5dc22", 1172619}, {"resource.007", 0, "2f48faf27666b58c276dda20f91f4a93", 1240456}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, 0, SCI_VERSION_1 @@ -1145,7 +1146,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "9c429782d102739f6bbb81e8b953b0cb", 1267525}, {"resource.006", 0, "d1a75fdc01840664d00366cff6919366", 1208972}, {"resource.007", 0, "c07494f0cce7c05210893938786a955b", 1337361}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1163,7 +1164,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "f4e441f284560eaa8022102315656a7d", 1267757}, {"resource.006", 0, "8eeabd92af71e766e323db2100879102", 1209325}, {"resource.007", 0, "dc10c107e0923b902326a040b9c166b9", 1337859}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1181,7 +1182,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "6556ff8e7c4d1acf6a78aea154daa76c", 1287869}, {"resource.006", 0, "da82e4beb744731d0a151f1d4922fafa", 1170456}, {"resource.007", 0, "431def14ca29cdb5e6a5e84d3f38f679", 1240176}, - {NULL, 0, NULL, 0}}, Common::PL_POL, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::PL_POL, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1194,7 +1195,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "f75727c00a6d884234fa2a43c951943a", 706}, {"resource.000", 0, "535b1b920441ec73f42eaa4ccfd47b89", 264116}, {"resource.msg", 0, "54d1fdc936f98c81f9e4c19e04fb1510", 8260}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1206,7 +1207,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, {"resource.msg", 0, "3cf5de44de36191f109d425b8450efc8", 258590}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1218,7 +1219,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a362063318eebe7d6423b1d9dc6213e1", 8703}, {"resource.000", 0, "f2b7f753992c56a0c7a08d6a5077c895", 7863324}, {"resource.msg", 0, "756297b2155db9e43f621c6f6fb763c3", 282822}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1230,7 +1231,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq6", "CD", { {"resource.map", 0, "7a550ebfeae2575ca00d47703a6a774c", 9215}, {"resource.000", 0, "233394a5f33b475ae5975e7e9a420865", 8376352}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, 7, SCI_VERSION_1_1 @@ -1243,7 +1244,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "a73a5ab04b8f60c4b75b946a4dccea5a", 8953}, {"resource.000", 0, "4da3ad5868a775549a7cc4f72770a58e", 8537260}, {"resource.msg", 0, "41eed2d3893e1ca6c3695deba4e9d2e8", 267102}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1255,7 +1256,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq7", "", { {"resource.map", 0, "2be9ab94429c721af8e05c507e048a15", 18697}, {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 203882535}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1266,7 +1267,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq7", "", { {"resource.map", 0, "8676b0fbbd7362989a029fe72fea14c6", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1277,7 +1278,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq7", "", { {"resource.map", 0, "838b9ff132bd6962026fee832e8a7ddb", 18697}, {"resource.000", 0, "eb63ea3a2c2469dc2d777d351c626404", 206626576}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1288,7 +1289,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq7", "", { {"resource.map", 0, "0b62693cbe87e3aaca3e8655a437f27f", 18709}, {"resource.000", 0, "51c1ead1163e19a2de8f121c39df7a76", 200764100}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1299,7 +1300,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"kq7", "Demo", { {"resource.map", 0, "b44f774108d63faa1d021101221c5a54", 1690}, {"resource.000", 0, "d9659d2cf0c269c6a9dc776707f5bea0", 2433827}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1317,7 +1318,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "2ab23f64306b18c28302c8ec2964c5d6", 605134}, {"resource.004", 0, "aa553977f7e5804081de293800d3bcce", 695067}, {"resource.005", 0, "bfd870d51dc97729f0914095f58e6957", 676881}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1332,7 +1333,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721149}, {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667365}, {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683737}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAtariST, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAtariST, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1343,7 +1344,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"laurabow", "Demo", { {"resource.map", 0, "e625726268ff4e123ada11f31f0249f3", 768}, {"resource.001", 0, "0c8912290af0890f8d95faeb4ddb2d68", 333031}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1357,7 +1358,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 721381}, {"resource.003", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 667468}, {"resource.004", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 683807}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1374,7 +1375,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, {"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, {"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1391,7 +1392,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 327465}, {"resource.006", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 328390}, {"resource.007", 0, "e45c888d9c7c04aec0a20e9f820b79ff", 317687}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1403,7 +1404,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"laurabow2", "Demo", { {"resource.map", 0, "24dffc5db1d88c7999f13e8767ed7346", 855}, {"resource.000", 0, "2b2b1b4f7584f9b38fd13f6ab95634d1", 781912}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1415,7 +1416,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"laurabow2", "", { {"resource.map", 0, "610bfd9a852004222f0faaf5fc9e630a", 6489}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5035964}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1427,25 +1428,23 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"laurabow2", "CD", { {"resource.map", 0, "a70945e61ba7ac7bfea6b7bd72c6aec5", 7274}, {"resource.000", 0, "82578b8d5a7e09c4c58891ca49fae35b", 5598672}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 }, -#if 0 - // FIXME: add resource.msg, since the other files are the same as in the spanish version - // Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from markcoolio in bug report #2723787)) - // SCI interpreter version 1.001.069 (just a guess) + // Laura Bow 2 v1.1 - German DOS Floppy (from Tobis87, updated info from markcoolio in bug report #2723787, updated info from #2797962)) + // Executable scanning reports "2.000.274" {{"laurabow2", "", { {"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {"resource.msg", 0, "795c928cd00dfec9fbc62ebcd12e1f65", 303185}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 }, -#endif // Laura Bow 2 - Spanish DOS CD (from jvprat) // Executable scanning reports "2.000.274", VERSION file reports "1.000.000, May 10, 1994" @@ -1453,7 +1452,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "3b6dfbcda210bbc3f23fd1927113bf98", 6483}, {"resource.000", 0, "57084910bc923bff5d6d9bc1b56e9604", 5028766}, {"resource.msg", 0, "71f1f0cd9f082da2e750c793a8ed9d84", 286141}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1467,7 +1466,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "38936d3c68b6f79d3ffb13955713fed7", 591352}, {"resource.002", 0, "24c958bc922b07f91e25e8c93aa01fcf", 491230}, {"resource.003", 0, "685cd6c1e05a695ab1e0db826337ee2a", 553279}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1482,7 +1481,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "24ed6dc01b1e7fbc66c3d63a5994549a", 750465}, {"resource.002", 0, "5790ac0505f7ca98d4567132b875eb1e", 681041}, {"resource.003", 0, "4a34c3367c2fe7eb380d741374da1989", 572251}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1495,7 +1494,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 922406}, {"resource.001", 0, "ec20246209d7b19f38989261e5c8f5b8", 1111226}, {"resource.002", 0, "85d6935ef77e6b0e16bc307640a0d913", 1088312}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1508,7 +1507,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.000", 0, "d3bceaebef3f7be941c2038b3565161e", 918242}, {"resource.001", 0, "d34cadb11e1aefbb497cf91bc1d3baa7", 1114688}, {"resource.002", 0, "85b030bb66d5342b0a068f1208c431a8", 1078443}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1519,7 +1518,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl1sci", "VGA Remake Demo", { {"resource.map", 0, "434e1f6c39d71647b34f0ee57b2bbd68", 444}, {"resource.001", 0, "0c0768215c562d9dace4a5ca53696cf3", 359913}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1535,7 +1534,21 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "112648995dbc194037f1e4ed2e195910", 1063341}, {"resource.002", 0, "3fe2a3aec0ed53c7d6db1845a67e3aa2", 1095908}, {"resource.003", 0, "ac175df0ea9a2cba57f0248651856d27", 376556}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI1_510_OR_LATER, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1 + }, + + // Larry 1 VGA Remake - Russian DOS + // Executable scanning reports "1.000.510", VERSION file reports "2.0" + // SCI interpreter version 1.000.510 + {{"lsl1sci", "VGA Remake", { + {"resource.map", 0, "b54413d35e206d21ae2b2bdb092bd13a", 3198}, + {"resource.000", 0, "0d7b2afa666bd36d9535a15d3a837a66", 928566}, + {"resource.001", 0, "bc8ca10c807515d959cbd91f9ba47735", 1123759}, + {"resource.002", 0, "b7409ab32bc3bee2d6cce887cd33f2b6", 1092160}, + {NULL, 0, NULL, 0}}, Common::RU_RUS, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1550,7 +1563,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "a0d4a625311d307257da7fc43d00459d", 630106}, {"resource.003", 0, "a0d4a625311d307257da7fc43d00459d", 570356}, {"resource.004", 0, "a0d4a625311d307257da7fc43d00459d", 717844}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1562,8 +1575,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl2", "Demo", { {"resource.map", 0, "03dba704bb77da55a91ad27b5a3cac09", 528}, {"resource.001", 0, "9f5520f0297206928df0b0b36493cd33", 127532}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -1578,8 +1591,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "4a24443a25e2b1492462a52809605dc2", 204861}, {"resource.005", 0, "4a24443a25e2b1492462a52809605dc2", 277732}, {"resource.006", 0, "4a24443a25e2b1492462a52809605dc2", 345683}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -1594,7 +1607,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "96033f57accfca903750413fd09193c8", 204867}, {"resource.005", 0, "96033f57accfca903750413fd09193c8", 274953}, {"resource.006", 0, "96033f57accfca903750413fd09193c8", 345818}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_395, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1611,7 +1624,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "5c10e462c8cf589610773e4fe8bfd996", 527238}, {"resource.004", 0, "f408e59cbee1457f042e5773b8c53951", 651634}, {"resource.005", 0, "433911eb764089d493aed1f958a5615a", 524259}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1625,7 +1638,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "f18441027154292836b973c655fa3175", 578024}, {"resource.003", 0, "f18441027154292836b973c655fa3175", 506807}, {"resource.004", 0, "f18441027154292836b973c655fa3175", 513651}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1642,7 +1655,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "f18441027154292836b973c655fa3175", 302946}, {"resource.006", 0, "f18441027154292836b973c655fa3175", 282465}, {"resource.007", 0, "f18441027154292836b973c655fa3175", 257174}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1654,7 +1667,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "33a2384f395470af3d2180e37ad0322a", 1140}, {"resource.001", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 76525}, {"resource.002", 0, "f773d79b93dfd4052ec8c1cc64c1e6ab", 268299}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1669,7 +1682,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "3827a9b17b926e12dcc336860f50612a", 672403}, {"resource.003", 0, "3827a9b17b926e12dcc336860f50612a", 587036}, {"resource.004", 0, "3827a9b17b926e12dcc336860f50612a", 691932}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1684,7 +1697,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "65f1bdaa20f6d0470e9d969f22473873", 671614}, {"resource.003", 0, "65f1bdaa20f6d0470e9d969f22473873", 586921}, {"resource.004", 0, "65f1bdaa20f6d0470e9d969f22473873", 690826}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -1702,7 +1715,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "3ce5901f1bc171ac0274d99a4eeb9e57", 623022}, {"resource.005", 0, "f8b2d1137bb767e5d232056b99dd69eb", 623621}, {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 715598}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1721,7 +1734,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "59eba83ad465b08d763b44f86afa86f6", 664717}, {"resource.006", 0, "bafc64e3144f115dc58c6aee02de98fb", 754966}, {"resource.007", 0, "59eba83ad465b08d763b44f86afa86f6", 683135}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1732,7 +1745,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl5", "Demo", { {"resource.map", 0, "efe8d3f45ce4f6bd9a6643e0ac8d2a97", 504}, {"resource.001", 0, "8bd8d9c0b5f455ee1269d63ce86c50dd", 531380}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1750,7 +1763,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 1011944}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1024810}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 1030656}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1768,7 +1781,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 959342}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1021774}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 993408}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1787,7 +1800,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 920524}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 946540}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 958842}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1806,7 +1819,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "0cc8d35a744031c772ca7cd21ae95273", 958079}, {"resource.006", 0, "dda27ce00682aa76198dac124bbbe334", 1015136}, {"resource.007", 0, "ac443fae1285fb359bf2b2bc6a7301ae", 987222}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1817,7 +1830,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl5", "", { {"resource.map", 0, "a99776df795127f387cb35dae872d4e4", 5919}, {"resource.000", 0, "a8989a5a89e7d4f702b26b378c7a357a", 7001981}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -1828,7 +1841,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "bb8a39d9e2a77ba449a1e591109ad9a8", 6973}, {"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_1_1, SCI_VERSION_1_1 @@ -1839,7 +1852,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "0b91234b7112782962cb480b7791b6e2", 7263}, {"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_1_1, SCI_VERSION_1_1 @@ -1850,7 +1863,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "bafe85f32738854135991d4324ad147e", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5773160}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1861,7 +1874,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "97797ea775baaf18a1907d357d3c0ea6", 7268}, {"resource.000", 0, "f6cbc6da7b90ea135883e0759848ca2c", 5776092}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1872,7 +1885,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "633bf8f42170b6271019917c8009989b", 6943}, {"resource.000", 0, "7884a8db9253e29e6b37a2651fd90ba3", 5733116}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1883,7 +1896,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lslcasino", "", { {"resource.map", 0, "194f1578f2624db813c9072359ad1639", 783}, {"resource.001", 0, "3733433b517ec3d14a3331d9ab3842ae", 344830}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -1895,7 +1908,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "0c0804434ea62278dd15032b1947426c", 8872}, {"resource.000", 0, "9a9f4870504444cda863dd14d077a680", 18520872}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1906,7 +1919,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "badfdf446ffed569a310d2c63a249421", 8896}, {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18534274}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1917,7 +1930,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl6", "", { {"resource.map", 0, "d184e9aa4f2d4b5670ddb3669db82cda", 8896}, {"resource.000", 0, "bd944d2b06614a5b39f1586906f0ee88", 18538987}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1928,7 +1941,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl7", "", { {"resmap.000", 0, "eae93e1b1d1ccc58b4691c371281c95d", 8188}, {"ressci.000", 0, "89353723488219e25589165d73ed663e", 66965678}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1939,7 +1952,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl7", "", { {"resmap.000", 0, "c11e6bfcfc2f2d05da47e5a7df3e9b1a", 8188}, {"ressci.000", 0, "a8c6817bb94f332ff498a71c8b47f893", 66971724}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1950,7 +1963,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl7", "", { {"resmap.000", 0, "4407849fd52fe3efb0c30fba60cd5cd4", 8206}, {"ressci.000", 0, "dc37c3055fffbefb494ff22b145d377b", 66964472}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1961,7 +1974,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl7", "", { {"resmap.000", 0, "9852a97141f789413f29bf956052acdb", 8212}, {"ressci.000", 0, "440b9fed89590abb4e4386ed6f948ee2", 67140181}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1972,7 +1985,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl7", "", { {"resmap.000", 0, "8f3d603e1acc834a5d598b30cdfc93f3", 8188}, {"ressci.000", 0, "32792f9bc1bf3633a88b382bb3f6e40d", 67071418}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1983,7 +1996,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lsl7", "Demo", { {"ressci.000", 0, "5cc6159688b2dc03790a67c90ccc67f9", 10195878}, {"resmap.000", 0, "6a2b2811eef82e87cde91cf1de845af8", 2695}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -1994,7 +2007,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lighthouse", "Demo", { {"resource.map", 0, "543124606352bfa5e07696ddf2a669be", 64}, {"resource.000", 0, "5d7714416b612463d750fb9c5690c859", 28952}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2005,7 +2018,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"lighthouse", "Demo", { {"resmap.000", 0, "3bdee7a16926975a4729f75cf6b80a92", 1525}, {"ressci.000", 0, "3c585827fa4a82f4c04a56a0bc52ccee", 11494351}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2018,7 +2031,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"ressci.001", 0, "14e922c47b92156377cb49e241691792", 99591924}, {"resmap.002", 0, "c68db5333f152fea6ca2dfc75cad8b34", 7573}, {"ressci.002", 0, "175468431a979b9f317c294ce3bc1430", 94628315}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2031,7 +2044,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"ressci.001", 0, "18553177dbf83fb2cb6c8edcbb174183", 99543093}, {"resmap.002", 0, "e7dc85884a2417e2eff9de0c63dd65fa", 7630}, {"ressci.002", 0, "3c8d627c555b0e3e4f1d9955bc0f0df4", 94631127}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2043,7 +2056,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "c2cf672c3f4251e7472d4542af3bf764", 933}, {"resource.000", 0, "8be56a3a88c065ee00c02c0e29199f3a", 14643}, {"resource.001", 0, "9e33566515b18bee7915db448063bba2", 871853}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_01, SCI_VERSION_01 @@ -2058,7 +2071,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "6767f8c8585f617aaa91d442f41ae714", 1032989}, {"resource.003", 0, "b1288e0821ee358d1ffe877e5900c8ec", 1047565}, {"resource.004", 0, "f79daa70390d73746742ffcfc3dc4471", 937580}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_01, SCI_VERSION_01 @@ -2072,7 +2085,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "49c8f7dcd9989e4491a93554bec325b0", 238019}, {"resource.002", 0, "564f516d991032e781492592a4eaa275", 1414142}, {"resource.003", 0, "dd6cef0c592eadb7e6be9a25307c57a2", 1344719}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_01, SCI_VERSION_01 @@ -2085,7 +2098,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "4aa28ac93fae03cf854594da13d9229c", 2700}, {"resource.001", 0, "fb552ae550ca1dac19ed8f6a3767612d", 262885}, {"resource.002", 0, "fb552ae550ca1dac19ed8f6a3767612d", 817191}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_01, SCI_VERSION_01 @@ -2096,7 +2109,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"mothergoose", "", { {"resource.map", 0, "52aae15e493cafd1da7e1c9b657a5bb9", 7026}, {"resource.000", 0, "b7ecd8ae9e254e80310b5a668b276e6e", 2948975}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_01, SCI_VERSION_01 @@ -2108,7 +2121,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"mothergoose", "CD", { {"resource.map", 0, "1c7f311b0a2c927b2fbe81ae341fb2f6", 5790}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 4369438}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2119,7 +2132,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"mothergoose", "Demo", { {"resource.map", 0, "87f9dc1cafc4d4fa835fb2f00cf3a6ef", 4560}, {"resource.001", 0, "5a0ed1d745855148364de1b3be099bac", 2070072}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2131,7 +2144,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"mothergoose", "", { {"resource.map", 0, "5159a1578c4306bfe070a3e4d8c2e1d3", 4741}, {"resource.000", 0, "1926925c95d82f0999590e93b02887c5", 15150768}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2143,7 +2156,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"msastrochicken", "", { {"resource.map", 0, "5b457cbe5042f557e5b610148171f6c0", 1158}, {"resource.001", 0, "453ea81ef66a50cbe33ce06302afe47f", 229737}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2167,7 +2180,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"ressci.006", 0, "3aae6559aa1df273bc542d5ac6330d75", 77901360}, {"resmap.007", 0, "afbd16ea77869a720afa1c5371de107d", 7972}, //{"ressci.007", 0, "3aae6559aa1df273bc542d5ac6330d75", 25859038}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2186,7 +2199,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"ressci.004", 0, "53f457cddb0dffc056593905c4cbb989", 42447131}, {"resmap.005", 0, "8bd5ceeedcbe16dfe55d1b90dcd4be84", 1942}, {"ressci.005", 0, "05f9fe2bee749659acb3cd2c90252fc5", 67905112}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2198,7 +2211,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pepper", "Demo", { {"resource.map", 0, "379bb4fb896630b14f2d91ed21e36ba1", 984}, {"resource.000", 0, "118f6c31a93ec7fd9a231c61125229e3", 645494}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2209,7 +2222,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pepper", "Demo", { {"resource.map", 0, "975e8df76106a5c13d12ab674f906a02", 2514}, {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1698164}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2220,7 +2233,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pepper", "Demo", { {"resource.map", 0, "9c9b7b900651a370dd3fb38d478b1798", 2524}, {"resource.000", 0, "e6a918a2dd7a4bcecd8fb389f43287c2", 1713544}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2231,7 +2244,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pq1sci", "VGA Remake", { {"resource.map", 0, "35efa814fb994b1cbdac9611e401da67", 5013}, {"resource.000", 0, "e0d5ddf34eda903a38f0837e2aa7145b", 6401433}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2245,7 +2258,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "523db0c07f1da2a822c2c39ee0482544", 179334}, {"resource.002", 0, "499737c21a28ac026e11ab817100d610", 511099}, {"resource.003", 0, "e008f5d6e2a7c4d4a0da0173e4fa8f8b", 553970}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2256,8 +2269,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pq2", "Demo", { {"resource.map", 0, "8b77d0d4650c2052b356cece28294b58", 576}, {"resource.001", 0, "376ef6d6eaaeed66e1424bd219c4b9ab", 215398}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -2272,8 +2285,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "77f02def3094af804fd2371db25b7100", 342149}, {"resource.005", 0, "77f02def3094af804fd2371db25b7100", 349899}, {"resource.006", 0, "77f02def3094af804fd2371db25b7100", 354991}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -2285,8 +2298,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509525}, {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 546000}, {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 591851}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -2298,8 +2311,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "77f02def3094af804fd2371db25b7100", 509760}, {"resource.002", 0, "77f02def3094af804fd2371db25b7100", 542897}, {"resource.003", 0, "77f02def3094af804fd2371db25b7100", 586857}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -2314,7 +2327,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "f7044bb08a1fcbe5077791ed8d4996f0", 691207}, {"resource.003", 0, "630bfa65beb05f743552704ac2899dae", 759891}, {"resource.004", 0, "7b229fbdf30d670d0728cede3e984a7e", 838663}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2331,7 +2344,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "87361c17fd863b58f98828de68770279", 682288}, {"resource.004", 0, "6258d5dd85898d8e218eb8113ebc9059", 722738}, {"resource.005", 0, "6258d5dd85898d8e218eb8113ebc9059", 704485}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2347,7 +2360,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "c18e0d408e4f4f40365d42aa15931f67", 1153561}, {"resource.003", 0, "8791b9eef53edf77c2dac950142221d3", 1159791}, {"resource.004", 0, "1b91e891a3c60a941dac0eecdf83375b", 1143606}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2360,7 +2373,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "ec8e58e7663ae5173853abf6c76b52bb", 867}, {"resource.000", 0, "277f97771f7a6d89677141f02da313d6", 65150}, {"resource.001", 0, "5c5a551b6c86cce2ee75becb90e0b586", 624411}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2376,7 +2389,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "cce99b96a578b62ff6cebdae8d122feb", 1179358}, {"resource.003", 0, "4836f460f4cfc8de61e2df4c45775504", 1180956}, {"resource.004", 0, "0c3eb84b9755852d9e795e0d5c9373c7", 1171760}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2387,7 +2400,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pq4", "Demo", { {"resource.map", 0, "be56f87a1c4a13062a30a362df860c2f", 1472}, {"resource.000", 0, "527d5684016e6816157cd15d9071b11b", 1121310}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2399,7 +2412,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pq4", "", { {"resource.map", 0, "379dfe80ed6bd16c47e4b950c4722eac", 11374}, {"resource.000", 0, "fd316a09b628b7032248139003369022", 18841068}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2410,7 +2423,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pq4", "", { {"resource.map", 0, "aed9643158ccf01b71f359db33137f82", 9895}, {"resource.000", 0, "da383857b3be1e4514daeba2524359e0", 15141432}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2421,7 +2434,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pq4", "", { {"resource.map", 0, "2393ee728ab930b2762cb5889f9b5aff", 9256}, {"resource.000", 0, "6ba98bd2e436739d87ecd2a9b99cabb4", 14730155}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2432,7 +2445,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"pqswat", "Demo", { {"resource.map", 0, "8c96733ef94c21526792f7ca4e3f2120", 1648}, {"resource.000", 0, "d8892f1b8c56c8f7704325460f49b300", 3676175}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2449,7 +2462,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"ressci.003", 0, "00a755e917c442ca8cf1a1bea689e6fb", 45073980}, {"resmap.004", 0, "4228038906f041623e65789500b22285", 6835}, {"ressci.004", 0, "b7e619e6ecf62fe65d5116a3a422e5f0", 46223872}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2465,7 +2478,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "439ba9b6dde216e6eb97ef3a9830fbe4", 646869}, {"resource.003", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 642203}, {"resource.004", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 641688}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2483,12 +2496,38 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "7288ed6d5da89b7a80b4af3897a7963a", 271185}, {"resource.006", 0, "69366c2a2f99917199fe1b60a4fee19d", 267852}, {"resource.007", 0, "7ab2bf8e224b57f75e0cd6e4ba790761", 272747}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, + // Quest for Glory 1 - Japanese PC-98 5.25" Floppy + // Executable scanning reports "S.old.201" + {{"qfg1", "8 Colors", { + {"resource.map", 0, "5cbeb95dd2a4b7cb242b415cc6ec1c47", 6444}, + {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 859959}, + {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968}, + {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897}, + {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + 0, + SCI_VERSION_AUTODETECT, + SCI_VERSION_01 + }, + + // Quest for Glory 1 - Japanese PC-98 5.25" Floppy + // Executable scanning reports "S.old.201" + {{"qfg1", "16 Colors", { + {"resource.map", 0, "3ecaba33bf77cb434067a0b8aee15097", 6444}, + {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 864754}, + {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121}, + {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575}, + {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + 0, + SCI_VERSION_AUTODETECT, + SCI_VERSION_01 + }, + // Quest for Glory 1 - English Amiga // Executable scanning reports "1.002.020" // SCI interpreter version 0.000.685 @@ -2500,7 +2539,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 654096}, {"resource.004", 0, "16cd4414c37ae3bb6d6da33dce8e25e8", 689124}, {"resource.005", 0, "5f3386ef2f2b1254e4a066f5d9027324", 609529}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2515,7 +2554,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "05ddce5f437a516b89ede2438fac09d8", 635734}, {"resource.003", 0, "951299a82a8134ed12c5c18118d45c2f", 640483}, {"resource.004", 0, "951299a82a8134ed12c5c18118d45c2f", 644443}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2526,7 +2565,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg1", "VGA Remake", { {"resource.map", 0, "a731fb6c9c0b282443f7027bc8694d4c", 8469}, {"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2537,7 +2576,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg1", "VGA Remake Demo", { {"resource.map", 0, "ac0257051c95a59c0cdc0be24d9b11fa", 729}, {"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2556,7 +2595,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "a77d2576c842b2b06da57d4ac8fc51c0", 579975}, {"resource.006", 0, "ccf5dba33e5cab6d5872838c0f8db44c", 500039}, {"resource.007", 0, "4c9fc1587545879295cb9627f56a2cb8", 575056}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_01 @@ -2571,7 +2610,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "df137dc7869cab07e1149ba2333c815c", 790750}, {"resource.003", 0, "b192607c42f6960ecdf2ad2e4f90e9bc", 972804}, {"resource.004", 0, "cd2de58e27665d5853530de93fae7cd6", 983617}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_01 @@ -2589,7 +2628,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "df137dc7869cab07e1149ba2333c815c", 478688}, {"resource.006", 0, "b1944bd664ddbd2859cdaa0c4a0d6281", 507489}, {"resource.007", 0, "cd2de58e27665d5853530de93fae7cd6", 490794}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_01 @@ -2600,7 +2639,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg3", "Demo", { {"resource.map", 0, "fd71de9b588a45f085317caacf050e91", 687}, {"resource.000", 0, "b6c69bf6c18bf177492249fe81fc6a6d", 648702}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2611,7 +2650,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg3", "", { {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868000}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2622,7 +2661,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg3", "", { {"resource.map", 0, "19e2bf9b693932b5e2bb59b9f9ab86c9", 5958}, {"resource.000", 0, "6178ad2e83e58e4671ca03315f7a6498", 5868042}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2634,7 +2673,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "10809197c33a5e62819311d8a2f73f85", 5978}, {"resource.000", 0, "ba7ac86155e4c531e46cd73c86daa80a", 5884098}, {"resource.msg", 0, "a63974730d294dec0bea10057c36e506", 256014}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2645,7 +2684,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg4", "Demo", { {"resource.map", 0, "1ba7c7ae1efb315326d45cb931569b1b", 922}, {"resource.000", 0, "41ba03f0b188b029132daa3ece0d3e14", 623154}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2657,7 +2696,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg4", "", { {"resource.map", 0, "685bdb1ed47bbbb0e5e25db392da83ce", 9301}, {"resource.000", 0, "f64fd6aa3977939a86ff30783dd677e1", 11004993}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2668,7 +2707,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg4", "", { {"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, {"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2679,7 +2718,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg4", "", { {"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, {"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2693,7 +2732,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg4", "", { {"resource.map", 0, "aba367f2102e81782d961b14fbe3d630", 10246}, {"resource.000", 0, "263dce4aa34c49d3ad29bec889007b1c", 11571394}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2705,7 +2744,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"qfg4", "", { {"resource.map", 0, "9e0abba8746f40565bc7eb5720522ecd", 9301}, {"resource.000", 0, "57f22cdc54eeb35fce1f26b31b5c3ee1", 11076197}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2716,7 +2755,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"rama", "Demo", { {"resmap.001", 0, "775304e9b2a545156be4d94209550094", 1393}, {"ressci.001", 0, "259437fd75fdf51e8207fda8c01fa4fd", 2334384}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2731,7 +2770,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"ressci.002", 0, "2a68edd064e5e4937b5e9c74b38f2082", 128562138}, {"resmap.003", 0, "31ef4c0621711585d031f0ae81707251", 1636}, {"ressci.003", 0, "2a68edd064e5e4937b5e9c74b38f2082", 6860492}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2742,7 +2781,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"rama", "", { {"ressci.001", 0, "2a68edd064e5e4937b5e9c74b38f2082", 70611091}, {"resmap.001", 0, "70ba2ff04a2b7fb2c52420ba7fbd47c2", 8338}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2753,7 +2792,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"shivers", "", { {"resmap.000", 0, "f2ead37749ed8f6535a2445a7d05a0cc", 46525}, {"ressci.000", 0, "4294c6d7510935f2e0a52e302073c951", 262654836}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2763,7 +2802,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"shivers", "", { {"resmap.000", 0, "f483d0a1f78334c18052e92785c3086e", 46537}, {"ressci.000", 0, "6751b144671e2deed919eb9d284b07eb", 262390692}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2774,7 +2813,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"shivers", "Demo", { {"resmap.000", 0, "d9e0bc5eddefcbe47f528760085d8927", 1186}, {"ressci.000", 0, "3a93c6340b54e07e65d0e5583354d186", 10505469}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2785,7 +2824,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"shivers2", "Demo", { {"resmap.000", 0, "d8659188b84beaef076bd869837cd530", 634}, {"ressci.000", 0, "7fbac0807a044c9543e8ac376d200e59", 4925003}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -2798,7 +2837,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "61b4f74039399e5aa1e737b16d0fc023", 1409}, {"resource.msg", 0, "1aeafe2b495de288d002109650b66614", 1364}, {"resource.000", 0, "8e10d4f05c1fd9f883384fa38a898489", 377394}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -2814,7 +2853,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "2588c1c2ca8b9bed0e3411948c0856a9", 839302}, {"resource.004", 0, "b25a1539c71701f7715f738c5037e9a6", 775515}, {"resource.005", 0, "640ffe1a9acde392cc33cc1b1a528328", 806324}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2830,7 +2869,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "a9e847c687529481f3a22b9bf01f45f7", 1169831}, {"resource.003", 0, "c47600e50c6fc591957ae0c5020ee7b8", 1213262}, {"resource.004", 0, "e19ea4ad131472f9238590f2e1d40289", 1203051}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2841,7 +2880,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq1sci", "VGA Remake Demo", { {"resource.map", 0, "5af709ac5e0e923e0b8174f49978c30e", 636}, {"resource.001", 0, "fd99ea43f57576ded7c86036996346cf", 507642}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2858,7 +2897,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "8c22700a02991b763f512f837636b3ca", 1211307}, {"resource.004", 0, "9b78228ad4f9f335fedf74f1812dcfca", 513325}, {"resource.005", 0, "7d4ebcb745c0bf8fc42e4013f52ecd49", 1101812}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2872,8 +2911,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 754432}, {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 746496}, {"resource.004", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 761984}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_0, SCI_VERSION_0 }, @@ -2888,7 +2927,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 712374}, {"resource.004", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 545053}, {"resource.005", 0, "6d8f34090503ce937e7dbef6cb6cdb6a", 687507}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_510_OR_LATER, SCI_VERSION_0, SCI_VERSION_0 @@ -2899,8 +2938,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq3", "Demo", { {"resource.map", 0, "ec66ac2b1ce58b2575ba00b65058de1a", 612}, {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 180245}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -2912,8 +2951,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 485158}, {"resource.002", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 720244}, {"resource.003", 0, "ceeda7202b96e5c85ecaa88a40a540fc", 688367}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -2925,7 +2964,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 490247}, {"resource.002", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 715777}, {"resource.003", 0, "8b55c4875298f45ea5696a5ee8f6a7fe", 703370}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2942,8 +2981,8 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.005", 0, "9107c2aa5398e28b5c5406df13491f85", 322107}, {"resource.006", 0, "9107c2aa5398e28b5c5406df13491f85", 320643}, {"resource.007", 0, "9107c2aa5398e28b5c5406df13491f85", 344287}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, - GF_FOR_SCI0_BEFORE_502, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, + GF_FOR_SCI0_BEFORE_629, SCI_VERSION_AUTODETECT, SCI_VERSION_0 }, @@ -2955,7 +2994,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "9107c2aa5398e28b5c5406df13491f85", 567245}, {"resource.002", 0, "9107c2aa5398e28b5c5406df13491f85", 596768}, {"resource.003", 0, "9107c2aa5398e28b5c5406df13491f85", 693573}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_0 @@ -2973,7 +3012,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "1887ed88bb34ae7238650e8f77f26315", 798226}, {"resource.005", 0, "3540d1cc84d674cf4b2c898b88a3b563", 790296}, {"resource.006", 0, "ade814bc4d56244c156d9e9bcfebbc11", 664085}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -2990,7 +3029,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "99c6a017da5e769a3b427ca52c8a564f", 824601}, {"resource.005", 0, "10ee1709e6559c724676d058199b75b5", 818745}, {"resource.006", 0, "67fb188b191d88efe8414af6ea297b93", 672675}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformAmiga, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3002,7 +3041,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq4", "", { {"resource.map", 0, "a18088c8aceb06025dbc945f29e02935", 5124}, {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 5502009}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3014,7 +3053,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq4", "", { {"resource.map", 0, "71ccf4f82ac4efb588731acfb7bf2603", 5646}, {"resource.000", 0, "e1f46832cd2458796028e054a0466031", 933928}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3031,7 +3070,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "96fa33d89d838bc3f671c5b953e7a896", 1240130}, {"resource.004", 0, "ff9c87da3bc53473fdee8b9d3edbc93c", 1200631}, {"resource.005", 0, "e33019ac19f755ae33fbf49b4fc9066c", 1053294}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3048,7 +3087,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.004", 0, "b8d6efbd3235329bfe844c794097b2c9", 1064761}, {"resource.005", 0, "47ee647b5b12232d27e63cc627c25899", 1156765}, {"resource.006", 0, "dfb023e4e2a1e7a00fa18f9ede72a91b", 924059}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3064,18 +3103,44 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "5289000399d503b59da9e23129256f1a", 1325546}, {"resource.004", 0, "4277c61bed40a50dadc4b5a344520af2", 1251000}, {"resource.005", 0, "5f885abd335978e2fd4e5f886d7676c8", 1102880}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 }, + // Space Quest 4 - Japanese PC-98 5.25" Floppy + // SCI interpreter version 1.000.1068 + {{"sq4", "", { + {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, + {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, + {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, + {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, + {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1 + }, + + // Space Quest 4 - Japanese PC-98 5.25" Floppy + // SCI interpreter version 1.000.1068 + {{"sq4", "", { + {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, + {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, + {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, + {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1 + }, + // Space Quest 4 - English DOS CD (from the Space Quest Collection) // Executable scanning reports "1.001.064", VERSION file reports "1.0" {{"sq4", "CD", { {"resource.map", 0, "ed90a8e3ccc53af6633ff6ab58392bae", 7054}, {"resource.000", 0, "63247e3901ab8963d4eece73747832e0", 5157378}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3092,7 +3157,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1319306}, {"resource.004", 0, "776fba81c110d1908776232cbe190e20", 1253752}, {"resource.005", 0, "55fae26c2a92f16ef72c1e216e827c0f", 1098328}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NONE}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3107,7 +3172,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.001", 0, "567608beb69d9dffdb42a8f39cb11a5e", 994323}, {"resource.002", 0, "74c62fa2146ff3b3b2ea2b3fb95b9af9", 1140801}, {"resource.003", 0, "42a307941edeb1a3be31daeb2e4be90b", 1088408}, - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3124,7 +3189,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.003", 0, "47ee647b5b12232d27e63cc627c25899", 1321146}, {"resource.004", 0, "c06350184a490c10eb4585fff0aa3192", 1254368}, {"resource.005", 0, "b8d6efbd3235329bfe844c794097b2c9", 1098717}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, GF_FOR_SCI1_200_OR_LATER, SCI_VERSION_AUTODETECT, SCI_VERSION_1 @@ -3136,7 +3201,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "bb8ad78793c26bdb3f77498b1d6515a9", 125988}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3147,7 +3212,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq5", "", { {"resource.map", 0, "8bde0a9adb9a3e9aaa861826874c9834", 6473}, {"resource.000", 0, "f4a48705764544d7cc64a7bb22a610df", 6025184}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3159,7 +3224,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "66317c12ac6e818d1f7c17e83c1d9819", 6143}, {"resource.000", 0, "4147edc5045e6d62998018b5614c58ec", 5496486}, {"resource.msg", 0, "7c71cfc36153cfe07b450423a51f7e68", 146282}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3170,7 +3235,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq5", "", { {"resource.000", 0, "5040026519f37199f3616fb1d4704dff", 6047170}, {"resource.map", 0, "5b09168baa2f6e2e22787429b2d72f54", 6492}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3182,7 +3247,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq6", "", { {"resource.map", 0, "6dddfa3a8f3a3a513ec9dfdfae955005", 10528}, {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3193,7 +3258,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq6", "", { {"resource.map", 0, "e0615d6e4e10e37ae42e6a2a95aaf145", 10528}, {"resource.000", 0, "c4259ab7355aead07773397b1052827d", 41150806}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3204,7 +3269,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq6", "Demo", { {"resource.map", 0, "368f07b07433db3f819fa3fa0e5efee5", 2572}, {"resource.000", 0, "ab12724e078dea34b624e0d2a38dcd7c", 2272050}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3215,7 +3280,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"sq6", "", { {"resource.map", 0, "664d797415484f85c90b1b45aedc7686", 10534}, {"resource.000", 0, "ba87ba91e5bdabb4169dd0df75777722", 40933685}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3227,7 +3292,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"islandbrain", "", { {"resource.map", 0, "2388efef8430b041b0f3b00b9050e4a2", 3281}, {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 2103560}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3238,7 +3303,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"islandbrain", "", { {"resource.map", 0, "3c07da06bdd1689f9d07af78fb94d0ec", 3101}, {"resource.000", 0, "ecc686e0034fb4d41de077ac7167b3cf", 1947866}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3249,7 +3314,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"islandbrain", "Demo", { {"resource.map", 0, "a8e5ca8ed1996974afa59f4c45e06195", 986}, {"resource.000", 0, "b3acd9b9dd7fe53c4ee133ac9a1acfab", 586560}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_1_1 @@ -3261,7 +3326,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"torin", "Demo", { {"resmap.000", 0, "9a3e172cde9963d0a969f26469318cec", 3403}, {"ressci.000", 0, "db3e290481c35c3224e9602e71e4a1f1", 5073868}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, ADGF_DEMO, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3272,7 +3337,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3284,7 +3349,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, // TODO: depend on one of the patches? - {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::ES_ESP, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3295,7 +3360,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::FR_FRA, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3306,7 +3371,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::DE_DEU, Common::kPlatformWindows, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3317,7 +3382,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {{"torin", "", { {"resmap.000", 0, "bb3b0b22ff08df54fbe2d06263409be6", 9799}, {"ressci.000", 0, "693a259d346c9360f4a0c11fdaae430a", 55973887}, - {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0}, + {NULL, 0, NULL, 0}}, Common::IT_ITA, Common::kPlatformWindows, 0, GUIO_NONE}, 0, SCI_VERSION_AUTODETECT, SCI_VERSION_32 @@ -3364,7 +3429,8 @@ static SciGameDescription s_fallbackDesc = { AD_ENTRY1(0, 0), // This should always be AD_ENTRY1(0, 0) in the fallback descriptor Common::UNK_LANG, Common::kPlatformPC, - ADGF_NO_FLAGS + ADGF_NO_FLAGS, + GUIO_NONE }, 0, SCI_VERSION_AUTODETECT, @@ -3388,7 +3454,9 @@ static const ADParams detectionParams = { // List of files for file-based fallback detection (optional) 0, // Flags - 0 + 0, + // Additional GUI options (for every game} + Common::GUIO_NONE }; class SciMetaEngine : public AdvancedMetaEngine { diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index bfd38f2c1b..a1e2c24955 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -64,13 +64,13 @@ int _reset_graphics_input(EngineState *s) { s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal1_amiga(file)); file.close(); } else { - resource = s->resmgr->findResource(kResourceTypePalette, 999, 1); + resource = s->resmgr->findResource(ResourceId(kResourceTypePalette, 999), 1); if (resource) { if (s->_version < SCI_VERSION_1_1) s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal1(999, resource->data, resource->size)); else s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal11(999, resource->data, resource->size)); - s->resmgr->unlockResource(resource, 999, kResourceTypePalette); + s->resmgr->unlockResource(resource); } else { debug(2, "Couldn't find the default palette!"); } @@ -89,14 +89,14 @@ int _reset_graphics_input(EngineState *s) { s->priority_first = 42; // Priority zone 0 ends here - if (s->_flags & GF_SCI0_OLDGFXFUNCS) + if (s->_kernel->usesOldGfxFunctions()) s->priority_last = 200; else s->priority_last = 190; font_nr = -1; do { - resource = s->resmgr->testResource(kResourceTypeFont, ++font_nr); + resource = s->resmgr->testResource(ResourceId(kResourceTypeFont, ++font_nr)); } while ((!resource) && (font_nr < sci_max_resource_nr[s->resmgr->_sciVersion])); if (!resource) { @@ -196,7 +196,7 @@ int create_class_table_sci11(EngineState *s) { char *seeker_ptr; int classnr; - Resource *vocab996 = s->resmgr->findResource(kResourceTypeVocab, 996, 1); + Resource *vocab996 = s->resmgr->findResource(ResourceId(kResourceTypeVocab, 996), 1); if (!vocab996) s->_classtable.resize(20); @@ -204,7 +204,7 @@ int create_class_table_sci11(EngineState *s) { s->_classtable.resize(vocab996->size >> 2); for (scriptnr = 0; scriptnr < 1000; scriptnr++) { - Resource *heap = s->resmgr->findResource(kResourceTypeHeap, scriptnr, 0); + Resource *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, scriptnr), 0); if (heap) { int global_vars = READ_LE_UINT16(heap->data + 2); @@ -236,7 +236,7 @@ int create_class_table_sci11(EngineState *s) { } } - s->resmgr->unlockResource(vocab996, 996, kResourceTypeVocab); + s->resmgr->unlockResource(vocab996); vocab996 = NULL; return 0; } @@ -247,7 +247,7 @@ static int create_class_table_sci0(EngineState *s) { int classnr; int magic_offset; // For strange scripts in older SCI versions - Resource *vocab996 = s->resmgr->findResource(kResourceTypeVocab, 996, 1); + Resource *vocab996 = s->resmgr->findResource(ResourceId(kResourceTypeVocab, 996), 1); if (!vocab996) s->_classtable.resize(20); @@ -256,7 +256,7 @@ static int create_class_table_sci0(EngineState *s) { for (scriptnr = 0; scriptnr < 1000; scriptnr++) { int objtype = 0; - Resource *script = s->resmgr->findResource(kResourceTypeScript, scriptnr, 0); + Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, scriptnr), 0); if (script) { if (s->_flags & GF_SCI0_OLD) @@ -318,7 +318,7 @@ static int create_class_table_sci0(EngineState *s) { } } - s->resmgr->unlockResource(vocab996, 996, kResourceTypeVocab); + s->resmgr->unlockResource(vocab996); vocab996 = NULL; return 0; } @@ -499,7 +499,7 @@ int game_init(EngineState *s) { s->game_obj = game_obj; // Mark parse tree as unused - s->parser_nodes[0].type = PARSE_TREE_NODE_LEAF; + s->parser_nodes[0].type = kParseTreeLeafNode; s->parser_nodes[0].content.value = 0; s->_menubar = new Menubar(); // Create menu bar diff --git a/engines/sci/engine/gc.cpp b/engines/sci/engine/gc.cpp index 24a7fbd1a9..1bfb66987e 100644 --- a/engines/sci/engine/gc.cpp +++ b/engines/sci/engine/gc.cpp @@ -106,7 +106,7 @@ reg_t_hash_map *find_all_used_references(EngineState *s) { wm.push(es.objp); wm.push(es.sendp); if (es.type == EXEC_STACK_TYPE_VARSELECTOR) - wm.push(*(es.addr.varp)); + wm.push(*(es.getVarPointer(s))); } } #ifdef DEBUG_GC_VERBOSE diff --git a/engines/sci/engine/gc.h b/engines/sci/engine/gc.h index e6fa737aaf..9f9347ca18 100644 --- a/engines/sci/engine/gc.h +++ b/engines/sci/engine/gc.h @@ -45,19 +45,23 @@ struct reg_t_Hash { } }; -// The reg_t_hash_map is actually really a hashset +/* + * The reg_t_hash_map is actually really a hashset + */ typedef Common::HashMap<reg_t, bool, reg_t_Hash, reg_t_EqualTo> reg_t_hash_map; +/** + * Finds all used references and normalises them to their memory addresses + * @param s The state to gather all information from + * @return A hash map containing entries for all used references + */ reg_t_hash_map *find_all_used_references(EngineState *s); -/* Finds all used references and normalises them to their memory addresses -** Parameters: (EngineState *) s: The state to gather all information from -** Returns : (reg_t_hash_map *) A hash map containing entries for all used references -*/ +/** + * Runs garbage collection on the current system state + * @param s The state in which we should gc + */ void run_gc(EngineState *s); -/* Runs garbage collection on the current system state -** Parameters: (EngineState *) s: The state in which we should gc -*/ } // End of namespace Sci diff --git a/engines/sci/engine/grammar.cpp b/engines/sci/engine/grammar.cpp index 2c035fcb53..e75441432d 100644 --- a/engines/sci/engine/grammar.cpp +++ b/engines/sci/engine/grammar.cpp @@ -351,7 +351,7 @@ parse_rule_list_t *Vocabulary::buildGNF(bool verbose) { int ntrules_nr; parse_rule_list_t *ntlist = NULL; parse_rule_list_t *tlist, *new_tlist; - GUI::Debugger *con = ((SciEngine *)g_engine)->getDebugger(); + Console *con = ((SciEngine *)g_engine)->getSciDebugger(); for (uint i = 1; i < _parserBranches.size(); i++) { // branch rule 0 is treated specially parse_rule_t *rule = _vbuild_rule(&_parserBranches[i]); @@ -414,7 +414,7 @@ parse_rule_list_t *Vocabulary::buildGNF(bool verbose) { static int _vbpt_pareno(parse_tree_node_t *nodes, int *pos, int base) { // Opens parentheses nodes[base].content.branches[0] = (*pos) + 1; - nodes[++(*pos)].type = PARSE_TREE_NODE_BRANCH; + nodes[++(*pos)].type = kParseTreeBranchNode; nodes[*pos].content.branches[0] = 0; nodes[*pos].content.branches[1] = 0; return *pos; @@ -423,7 +423,7 @@ static int _vbpt_pareno(parse_tree_node_t *nodes, int *pos, int base) { static int _vbpt_parenc(parse_tree_node_t *nodes, int *pos, int paren) { // Closes parentheses for appending nodes[paren].content.branches[1] = ++(*pos); - nodes[*pos].type = PARSE_TREE_NODE_BRANCH; + nodes[*pos].type = kParseTreeBranchNode; nodes[*pos].content.branches[0] = 0; nodes[*pos].content.branches[1] = 0; return *pos; @@ -432,10 +432,10 @@ static int _vbpt_parenc(parse_tree_node_t *nodes, int *pos, int paren) { static int _vbpt_append(parse_tree_node_t *nodes, int *pos, int base, int value) { // writes one value to an existing base node and creates a successor node for writing nodes[base].content.branches[0] = ++(*pos); - nodes[*pos].type = PARSE_TREE_NODE_LEAF; + nodes[*pos].type = kParseTreeLeafNode; nodes[*pos].content.value = value; nodes[base].content.branches[1] = ++(*pos); - nodes[*pos].type = PARSE_TREE_NODE_BRANCH; + nodes[*pos].type = kParseTreeBranchNode; nodes[*pos].content.branches[0] = 0; nodes[*pos].content.branches[1] = 0; return *pos; @@ -443,7 +443,7 @@ static int _vbpt_append(parse_tree_node_t *nodes, int *pos, int base, int value) static int _vbpt_terminate(parse_tree_node_t *nodes, int *pos, int base, int value) { // Terminates, overwriting a nextwrite forknode - nodes[base].type = PARSE_TREE_NODE_LEAF; + nodes[base].type = kParseTreeLeafNode; nodes[base].content.value = value; return *pos; } @@ -477,7 +477,7 @@ static int _vbpt_write_subexpression(parse_tree_node_t *nodes, int *pos, parse_r } int Vocabulary::parseGNF(parse_tree_node_t *nodes, const ResultWordList &words, bool verbose) { - GUI::Debugger *con = ((SciEngine *)g_engine)->getDebugger(); + Console *con = ((SciEngine *)g_engine)->getSciDebugger(); // Get the start rules: parse_rule_list_t *work = _vocab_clone_rule_list_by_id(_parserRules, _parserBranches[0].data[1]); parse_rule_list_t *results = NULL; @@ -554,14 +554,14 @@ int Vocabulary::parseGNF(parse_tree_node_t *nodes, const ResultWordList &words, { int temp, pos; - nodes[0].type = PARSE_TREE_NODE_BRANCH; + nodes[0].type = kParseTreeBranchNode; nodes[0].content.branches[0] = 1; nodes[0].content.branches[1] = 2; - nodes[1].type = PARSE_TREE_NODE_LEAF; + nodes[1].type = kParseTreeLeafNode; nodes[1].content.value = 0x141; - nodes[2].type = PARSE_TREE_NODE_BRANCH; + nodes[2].type = kParseTreeBranchNode; nodes[2].content.branches[0] = 0; nodes[2].content.branches[1] = 0; diff --git a/engines/sci/engine/intmap.h b/engines/sci/engine/intmap.h index 2cb4f69f1f..1c028975a9 100644 --- a/engines/sci/engine/intmap.h +++ b/engines/sci/engine/intmap.h @@ -83,7 +83,7 @@ public: /** * Checks whether a key is in the map, adds it if neccessary. - * @param value The key to check for/add + * @param key The key to check for/add * @param add Whether to add the key if it's not in there * @param was_added Set to non-zero if and only if the key is new, ignored if NULL. * @return The new (or old) index, or -1 if add was zero and @@ -91,6 +91,11 @@ public: */ int checkKey(int key, bool add, bool *wasAdded = 0); + /** + * Looks up a key in the map + * @parmam key The key to look for + * @return The value or -1 if not found + */ int lookupKey(int key) const; diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 3b998c7092..b03a073d8f 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -38,127 +38,9 @@ namespace Sci { // Default kernel name table #define SCI0_KNAMES_WELL_DEFINED 0x6e -#define SCI0_KNAMES_DEFAULT_ENTRIES_NR 0x72 -#define SCI1_KNAMES_DEFAULT_ENTRIES_NR 0x89 +#define SCI_KNAMES_DEFAULT_ENTRIES_NR 0x89 -static const char *sci0_default_knames[SCI0_KNAMES_DEFAULT_ENTRIES_NR] = { - /*0x00*/ "Load", - /*0x01*/ "UnLoad", - /*0x02*/ "ScriptID", - /*0x03*/ "DisposeScript", - /*0x04*/ "Clone", - /*0x05*/ "DisposeClone", - /*0x06*/ "IsObject", - /*0x07*/ "RespondsTo", - /*0x08*/ "DrawPic", - /*0x09*/ "Show", - /*0x0a*/ "PicNotValid", - /*0x0b*/ "Animate", - /*0x0c*/ "SetNowSeen", - /*0x0d*/ "NumLoops", - /*0x0e*/ "NumCels", - /*0x0f*/ "CelWide", - /*0x10*/ "CelHigh", - /*0x11*/ "DrawCel", - /*0x12*/ "AddToPic", - /*0x13*/ "NewWindow", - /*0x14*/ "GetPort", - /*0x15*/ "SetPort", - /*0x16*/ "DisposeWindow", - /*0x17*/ "DrawControl", - /*0x18*/ "HiliteControl", - /*0x19*/ "EditControl", - /*0x1a*/ "TextSize", - /*0x1b*/ "Display", - /*0x1c*/ "GetEvent", - /*0x1d*/ "GlobalToLocal", - /*0x1e*/ "LocalToGlobal", - /*0x1f*/ "MapKeyToDir", - /*0x20*/ "DrawMenuBar", - /*0x21*/ "MenuSelect", - /*0x22*/ "AddMenu", - /*0x23*/ "DrawStatus", - /*0x24*/ "Parse", - /*0x25*/ "Said", - /*0x26*/ "SetSynonyms", - /*0x27*/ "HaveMouse", - /*0x28*/ "SetCursor", - /*0x29*/ "FOpen", - /*0x2a*/ "FPuts", - /*0x2b*/ "FGets", - /*0x2c*/ "FClose", - /*0x2d*/ "SaveGame", - /*0x2e*/ "RestoreGame", - /*0x2f*/ "RestartGame", - /*0x30*/ "GameIsRestarting", - /*0x31*/ "DoSound", - /*0x32*/ "NewList", - /*0x33*/ "DisposeList", - /*0x34*/ "NewNode", - /*0x35*/ "FirstNode", - /*0x36*/ "LastNode", - /*0x37*/ "EmptyList", - /*0x38*/ "NextNode", - /*0x39*/ "PrevNode", - /*0x3a*/ "NodeValue", - /*0x3b*/ "AddAfter", - /*0x3c*/ "AddToFront", - /*0x3d*/ "AddToEnd", - /*0x3e*/ "FindKey", - /*0x3f*/ "DeleteKey", - /*0x40*/ "Random", - /*0x41*/ "Abs", - /*0x42*/ "Sqrt", - /*0x43*/ "GetAngle", - /*0x44*/ "GetDistance", - /*0x45*/ "Wait", - /*0x46*/ "GetTime", - /*0x47*/ "StrEnd", - /*0x48*/ "StrCat", - /*0x49*/ "StrCmp", - /*0x4a*/ "StrLen", - /*0x4b*/ "StrCpy", - /*0x4c*/ "Format", - /*0x4d*/ "GetFarText", - /*0x4e*/ "ReadNumber", - /*0x4f*/ "BaseSetter", - /*0x50*/ "DirLoop", - /*0x51*/ "CanBeHere", - /*0x52*/ "OnControl", - /*0x53*/ "InitBresen", - /*0x54*/ "DoBresen", - /*0x55*/ "DoAvoider", - /*0x56*/ "SetJump", - /*0x57*/ "SetDebug", - /*0x58*/ "InspectObj", - /*0x59*/ "ShowSends", - /*0x5a*/ "ShowObjs", - /*0x5b*/ "ShowFree", - /*0x5c*/ "MemoryInfo", - /*0x5d*/ "StackUsage", - /*0x5e*/ "Profiler", - /*0x5f*/ "GetMenu", - /*0x60*/ "SetMenu", - /*0x61*/ "GetSaveFiles", - /*0x62*/ "GetCWD", - /*0x63*/ "CheckFreeSpace", - /*0x64*/ "ValidPath", - /*0x65*/ "CoordPri", - /*0x66*/ "StrAt", - /*0x67*/ "DeviceInfo", - /*0x68*/ "GetSaveDir", - /*0x69*/ "CheckSaveGame", - /*0x6a*/ "ShakeScreen", - /*0x6b*/ "FlushResources", - /*0x6c*/ "SinMult", - /*0x6d*/ "CosMult", - /*0x6e*/ "SinDiv", - /*0x6f*/ "CosDiv", - /*0x70*/ "Graph", - /*0x71*/ SCRIPT_UNKNOWN_FUNCTION_STRING -}; - -static const char *sci1_default_knames[SCI1_KNAMES_DEFAULT_ENTRIES_NR] = { +static const char *sci_default_knames[SCI_KNAMES_DEFAULT_ENTRIES_NR] = { /*0x00*/ "Load", /*0x01*/ "UnLoad", /*0x02*/ "ScriptID", @@ -487,6 +369,10 @@ Kernel::Kernel(ResourceManager *resmgr, bool isOldSci0) : _resmgr(resmgr) { // Map a few special selectors for later use mapSelectors(); + + // SCI0 games using old graphics functions (before version 0.000.502) have the TimesSin + // kernel function, whereas newer games have the SinMult kernel function in its place + _oldGfxFunctions = !hasKernelFunction("SinMult"); } Kernel::~Kernel() { @@ -495,7 +381,7 @@ Kernel::~Kernel() { bool Kernel::loadSelectorNames(bool isOldSci0) { int count; - Resource *r = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES, 0); + Resource *r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SNAMES), 0); if (!r) // No such resource? return false; @@ -520,7 +406,7 @@ bool Kernel::loadSelectorNames(bool isOldSci0) { bool Kernel::loadOpcodes() { int count, i = 0; - Resource* r = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_OPCODES, 0); + Resource* r = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_OPCODES), 0); _opcodes.clear(); @@ -846,35 +732,26 @@ reg_t *kernel_dereference_reg_pointer(EngineState *s, reg_t pointer, int entries return (reg_t*)_kernel_dereference_pointer(s, pointer, entries, sizeof(reg_t)); } -// Alternative kernel func names retriever. Required for KQ1/SCI (at least). -static void _vocab_get_knames0alt(const Resource *r, Common::StringList &names) { - uint idx = 0; - - while (idx < r->size) { - Common::String tmp((const char *)r->data + idx); - names.push_back(tmp); - idx += tmp.size() + 1; - } - - // The mystery kernel function- one in each SCI0 package - names.push_back(SCRIPT_UNKNOWN_FUNCTION_STRING); +void setDefaultKernelNames(Common::StringList &names) { + names.resize(SCI_KNAMES_DEFAULT_ENTRIES_NR); + for (int i = 0; i < SCI_KNAMES_DEFAULT_ENTRIES_NR; i++) + names[i] = sci_default_knames[i]; } static void vocab_get_knames0(ResourceManager *resmgr, Common::StringList &names) { int count, i, index = 2, empty_to_add = 1; - Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0); + Resource *r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES), 0); if (!r) { // No kernel name table found? Fall back to default table - names.resize(SCI0_KNAMES_DEFAULT_ENTRIES_NR); - for (i = 0; i < SCI0_KNAMES_DEFAULT_ENTRIES_NR; i++) - names[i] = sci0_default_knames[i]; + setDefaultKernelNames(names); return; } count = READ_LE_UINT16(r->data); if (count > 1023) { - _vocab_get_knames0alt(r, names); + // Newer kernel name table, found in KQ1. We can use the default table here + setDefaultKernelNames(names); return; } @@ -898,20 +775,6 @@ static void vocab_get_knames0(ResourceManager *resmgr, Common::StringList &names } } -static void vocab_get_knames1(ResourceManager *resmgr, Common::StringList &names) { - // vocab.999/999.voc is notoriously unreliable in SCI1 games, and should not be used - // We hardcode the default SCI1 kernel names here (i.e. the ones inside the "special" - // 999.voc file from FreeSCI). All SCI1 games seem to be working with this change, but - // if any SCI1 game has different kernel vocabulary names, it might not work. It seems - // that all SCI1 games use the same kernel vocabulary names though, so this seems to be - // a safe change. If there's any SCI1 game with different kernel vocabulary names, we can - // add special flags to it to our detector - - names.resize(SCI1_KNAMES_DEFAULT_ENTRIES_NR); - for (int i = 0; i < SCI1_KNAMES_DEFAULT_ENTRIES_NR; i++) - names[i] = sci1_default_knames[i]; -} - #ifdef ENABLE_SCI32 static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &names) { /* @@ -925,7 +788,7 @@ static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &name */ //unsigned int size = 64, pos = 3; int len; - Resource *r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES, 0); + Resource *r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES), 0); if(r == NULL) // failed to open vocab.999 (happens with SCI1 demos) return; // FIXME: should return a default table for this engine const byte nCnt = *r->data; @@ -945,23 +808,18 @@ bool Kernel::loadKernelNames() { switch (_resmgr->_sciVersion) { case SCI_VERSION_0: case SCI_VERSION_01: - vocab_get_knames0(_resmgr, _kernelNames); - break; case SCI_VERSION_01_VGA: case SCI_VERSION_01_VGA_ODD: - // HACK: KQ5 needs the SCI1 default vocabulary names to work correctly. - // Having more vocabulary names (like in SCI1) doesn't seem to have any - // ill effects, other than resulting in unmapped functions towards the - // end, which are never used by the game interpreter anyway - // return vocab_get_knames0(resmgr, count); + vocab_get_knames0(_resmgr, _kernelNames); + break; case SCI_VERSION_1_EARLY: case SCI_VERSION_1_LATE: - vocab_get_knames1(_resmgr, _kernelNames); - break; case SCI_VERSION_1_1: - vocab_get_knames1(_resmgr, _kernelNames); - // KQ6CD calls unimplemented function 0x26 - _kernelNames[0x26] = "Dummy"; + setDefaultKernelNames(_kernelNames); + if (_resmgr->_sciVersion == SCI_VERSION_1_1) { + // KQ6CD calls unimplemented function 0x26 + _kernelNames[0x26] = "Dummy"; + } break; #ifdef ENABLE_SCI32 case SCI_VERSION_32: diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index ddc3f93cb7..e3ecddca26 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -69,19 +69,28 @@ public: uint getKernelNamesSize() const { return _kernelNames.size(); } const Common::String &getKernelName(uint number) const { return _kernelNames[number]; } - /* Determines the selector ID of a selector by its name - ** (const char *) selectorName: Name of the selector to look up - ** Returns : (int) The appropriate selector ID, or -1 on error - */ + /** + * Determines the selector ID of a selector by its name + * @param selectorName Name of the selector to look up + * @return The appropriate selector ID, or -1 on error + */ int findSelector(const char *selectorName) const; - /* Detects whether a particular kernel function is required in the game - ** (const char *) functionName: The name of the desired kernel function - ** Returns : (bool) true if the kernel function is listed in the kernel table, - ** false otherwise + /** + * Detects whether a particular kernel function is required in the game + * @param functionName The name of the desired kernel function + * @return True if the kernel function is listed in the kernel table, false otherwise */ bool hasKernelFunction(const char *functionName) const; + /* Applies to all versions before 0.000.502 + ** Old SCI versions used to interpret the third DrawPic() parameter inversely, + ** with the opposite default value (obviously). + ** Also, they used 15 priority zones from 42 to 200 instead of 14 priority + ** zones from 42 to 190. + */ + bool usesOldGfxFunctions() const { return _oldGfxFunctions; } + // Script dissection/dumping functions void dissectScript(int scriptNumber, Vocabulary *vocab); void dumpScriptObject(char *data, int seeker, int objsize); @@ -104,18 +113,18 @@ private: /** * Loads the kernel selector names. - * Returns true upon success, false otherwise. + * @return True upon success, false otherwise. */ bool loadSelectorNames(bool isOldSci0); - /* Maps special selectors - ** Returns : (void) - */ + /** + * Maps special selectors + */ void mapSelectors(); - /* Maps kernel functions - ** Returns : (void) - */ + /** + * Maps kernel functions + */ void mapFunctions(); /** @@ -125,10 +134,13 @@ private: bool loadOpcodes(); ResourceManager *_resmgr; + bool _oldGfxFunctions; // Kernel-related lists - // List of opcodes, loaded from vocab.998. This list is only used for debugging - // purposes, as we hardcode the list of opcodes in the sci_opcodes enum (script.h) + /** + * List of opcodes, loaded from vocab.998. This list is only used for debugging + * purposes, as we hardcode the list of opcodes in the sci_opcodes enum (script.h) + */ Common::Array<opcode> _opcodes; Common::StringList _selectorNames; Common::StringList _kernelNames; @@ -178,72 +190,62 @@ int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvoc /******************** Text functionality ********************/ +/** + * Looks up text referenced by scripts + * SCI uses two values to reference to text: An address, and an index. The address + * determines whether the text should be read from a resource file, or from the heap, + * while the index either refers to the number of the string in the specified source, + * or to a relative position inside the text. + * + * @param s The current state + * @param address The address to look up + * @param index The relative index + * @return The referenced text, or NULL on error. + */ char *kernel_lookup_text(EngineState *s, reg_t address, int index); -/* Looks up text referenced by scripts -** Parameters: (EngineState *s): The current state -** (reg_t) address: The address to look up -** (int) index: The relative index -** Returns : (char *): The referenced text, or NULL on error. -** SCI uses two values to reference to text: An address, and an index. The address -** determines whether the text should be read from a resource file, or from the heap, -** while the index either refers to the number of the string in the specified source, -** or to a relative position inside the text. -*/ /******************** Debug functionality ********************/ - +/** + * Checks whether a heap address contains an object + * @param s The current state + * @parm obj The address to check + * @return True if it is an object, false otherwise + */ bool is_object(EngineState *s, reg_t obj); -/* Checks whether a heap address contains an object -** Parameters: (EngineState *) s: The current state -** (reg_t) obj: The address to check -** Returns : (bool) true if it is an object, false otherwise -*/ /******************** Kernel function parameter macros ********************/ /* Returns the parameter value or (alt) if not enough parameters were supplied */ - - -#define KP_ALT(x, alt) ((x < argc)? argv[x] : (alt)) -#define KP_UINT(x) ((uint16) x.offset) -#define KP_SINT(x) ((int16) x.offset) - - -#define SKPV(x) KP_SINT(argv[x]) -#define UKPV(x) KP_UINT(argv[x]) -#define SKPV_OR_ALT(x,a) KP_SINT(KP_ALT(x, make_reg(0, a))) -#define UKPV_OR_ALT(x,a) KP_UINT(KP_ALT(x, make_reg(0, a))) - +/** + * Dereferences a heap pointer + * @param s The state to operate on + * @param pointer The pointer to dereference + * @parm entries The number of values expected (for checking; use 0 for strings) + * @return A physical reference to the address pointed to, or NULL on error or + * if not enugh entries were available. + * reg_t dereferenciation also assures alignedness of data. + */ reg_t *kernel_dereference_reg_pointer(EngineState *s, reg_t pointer, int entries); byte *kernel_dereference_bulk_pointer(EngineState *s, reg_t pointer, int entries); #define kernel_dereference_char_pointer(state, pointer, entries) (char*)kernel_dereference_bulk_pointer(state, pointer, entries) -/* Dereferences a heap pointer -** Parameters: (EngineState *) s: The state to operate on -** (reg_t ) pointer: The pointer to dereference -** (int) entries: The number of values expected (for checking) -** (use 0 for strings) -** Returns : (reg_t/char *): A physical reference to the address pointed -** to, or NULL on error or if not enugh entries -** were available -** reg_t dereferenciation also assures alignedness of data. -*/ /******************** Priority macros/functions ********************/ - +/** + * Finds the position of the priority band specified + * Parameters: (EngineState *) s: State to search in + * (int) band: Band to look for + * Returns : (int) Offset at which the band starts + */ int _find_priority_band(EngineState *s, int band); -/* Finds the position of the priority band specified -** Parameters: (EngineState *) s: State to search in -** (int) band: Band to look for -** Returns : (int) Offset at which the band starts -*/ +/** + * Does the opposite of _find_priority_band + * @param s Engine state + * @param y Coordinate to check + * @return The priority band y belongs to + */ int _find_view_priority(EngineState *s, int y); -/* Does the opposite of _find_priority_band -** Parameters: (EngineState *) s: State -** (int) y: Coordinate to check -** Returns : (int) The priority band y belongs to -*/ #define SCI0_VIEW_PRIORITY_14_ZONES(y) (((y) < s->priority_first)? 0 : (((y) >= s->priority_last)? 14 : 1\ + ((((y) - s->priority_first) * 14) / (s->priority_last - s->priority_first)))) @@ -257,58 +259,62 @@ int _find_view_priority(EngineState *s, int y); #define SCI0_PRIORITY_BAND_FIRST(nr) ((((nr) == 0)? 0 : \ ((s->priority_first) + (((nr)-1) * (s->priority_last - s->priority_first)) / 15))) -#define VIEW_PRIORITY(y) _find_view_priority(s, y) -#define PRIORITY_BAND_FIRST(nr) _find_priority_band(s, nr) - - - /******************** Dynamic view list functions ********************/ - +/** + * Determines the base rectangle of the specified view object + * @param s The state to use + * @param object The object to set + * @return The absolute base rectangle + */ Common::Rect set_base(EngineState *s, reg_t object); -/* Determines the base rectangle of the specified view object -** Parameters: (EngineState *) s: The state to use -** (reg_t) object: The object to set -** Returns : (abs_rect) The absolute base rectangle -*/ +/** + * Determines the now-seen rectangle of a view object + * @param s The state to use + * @param object The object to check + * @param clip Flag to determine wheter priority band clipping + * should be performed + * @return The absolute rectangle describing the now-seen area. + */ extern Common::Rect get_nsrect(EngineState *s, reg_t object, byte clip); -/* Determines the now-seen rectangle of a view object -** Parameters: (EngineState *) s: The state to use -** (reg_t) object: The object to check -** (byte) clip: Flag to determine wheter priority band -** clipping should be performed -** Returns : (abs_rect) The absolute rectangle describing the -** now-seen area. -*/ +/** + * Removes all views in anticipation of a new window or text + */ void _k_dyn_view_list_prepare_change(EngineState *s); -/* Removes all views in anticipation of a new window or text */ + +/** + * Redraws all views after a new window or text was added + */ void _k_dyn_view_list_accept_change(EngineState *s); -/* Redraws all views after a new window or text was added */ /******************** Misc functions ********************/ -void process_sound_events(EngineState *s); /* Get all sound events, apply their changes to the heap */ +/** + * Get all sound events, apply their changes to the heap + */ +void process_sound_events(EngineState *s); +/** + * Resolves an address into a list node + * @param s The state to operate on + * @param addr The address to resolve + * @return The list node referenced, or NULL on error + */ Node *lookup_node(EngineState *s, reg_t addr); -/* Resolves an address into a list node -** Parameters: (EngineState *) s: The state to operate on -** (reg_t) addr: The address to resolve -** Returns : (Node *) The list node referenced, or NULL on error -*/ - +/** + * Resolves a list pointer to a list + * @param s The state to operate on + * @param addr The address to resolve + * @return The list referenced, or NULL on error + */ List *lookup_list(EngineState *s, reg_t addr); -/* Resolves a list pointer to a list -** Parameters: (EngineState *) s: The state to operate on -** (reg_t) addr: The address to resolve -** Returns : (List *) The list referenced, or NULL on error -*/ /******************** Constants ********************/ diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 66395035c8..e40368a5c0 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -33,12 +33,10 @@ namespace Sci { -int g_stop_on_event = 0; - #define SCI_VARIABLE_GAME_SPEED 3 reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int mask = UKPV(0); + int mask = argv[0].toUint16(); reg_t obj = argv[1]; sci_event_t e; int oldx, oldy; @@ -90,10 +88,12 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { case SCI_EVT_KEYBOARD: if ((e.buckybits & SCI_EVM_LSHIFT) && (e.buckybits & SCI_EVM_RSHIFT) && (e.data == '-')) { sciprintf("Debug mode activated\n"); - g_debug_seeking = g_debug_step_running = 0; + debugState.seeking = kDebugSeekNothing; + debugState.runningStep = 0; } else if ((e.buckybits & SCI_EVM_CTRL) && (e.data == '`')) { sciprintf("Debug mode activated\n"); - g_debug_seeking = g_debug_step_running = 0; + debugState.seeking = kDebugSeekNothing; + debugState.runningStep = 0; } else { PUT_SEL32V(obj, type, SCI_EVT_KEYBOARD); // Keyboard event s->r_acc = make_reg(0, 1); @@ -110,7 +110,7 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { // track left buttton clicks, if requested if (e.type == SCI_EVT_MOUSE_PRESS && e.data == 1 && g_debug_track_mouse_clicks) { - ((SciEngine *)g_engine)->getDebugger()->DebugPrintf("Mouse clicked at %d, %d\n", + ((SciEngine *)g_engine)->getSciDebugger()->DebugPrintf("Mouse clicked at %d, %d\n", s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y); } @@ -137,8 +137,29 @@ reg_t kGetEvent(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->r_acc = NULL_REG; // Unknown or no event } - if ((s->r_acc.offset) && (g_stop_on_event)) { - g_stop_on_event = 0; + if ((s->r_acc.offset) && (debugState.stopOnEvent)) { + debugState.stopOnEvent = false; + + // A SCI event occured, and we have been asked to stop, so open the debug console + Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger(); + con->DebugPrintf("SCI event occured: "); + switch (e.type) { + case SCI_EVT_QUIT: + con->DebugPrintf("quit event\n"); + break; + case SCI_EVT_KEYBOARD: + con->DebugPrintf("keyboard event\n"); + break; + case SCI_EVT_MOUSE_RELEASE: + case SCI_EVT_MOUSE_PRESS: + con->DebugPrintf("mouse click event\n"); + break; + default: + con->DebugPrintf("unknown or no event (event type %d)\n", e.type); + } + + con->attach(); + con->onFrame(); } return s->r_acc; diff --git a/engines/sci/engine/kfile.cpp b/engines/sci/engine/kfile.cpp index 87ddb46e50..ed18c7fcd6 100644 --- a/engines/sci/engine/kfile.cpp +++ b/engines/sci/engine/kfile.cpp @@ -197,7 +197,7 @@ void file_open(EngineState *s, const char *filename, int mode) { reg_t kFOpen(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *name = kernel_dereference_char_pointer(s, argv[0], 0); - int mode = UKPV(1); + int mode = argv[1].toUint16(); debug(3, "kFOpen(%s,0x%x)", name, mode); file_open(s, name, mode); @@ -227,8 +227,8 @@ void file_close(EngineState *s, int handle) { } reg_t kFClose(EngineState *s, int funct_nr, int argc, reg_t *argv) { - debug(3, "kFClose(%d)", UKPV(0)); - file_close(s, UKPV(0)); + debug(3, "kFClose(%d)", argv[0].toUint16()); + file_close(s, argv[0].toUint16()); return s->r_acc; } @@ -248,7 +248,7 @@ void fwrite_wrapper(EngineState *s, int handle, char *data, int length) { } reg_t kFPuts(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int handle = UKPV(0); + int handle = argv[0].toUint16(); char *data = kernel_dereference_char_pointer(s, argv[1], 0); fwrite_wrapper(s, handle, data, strlen(data)); @@ -267,6 +267,12 @@ static void fgets_wrapper(EngineState *s, char *dest, int maxsize, int handle) { return; } f->_in->readLine_NEW(dest, maxsize); + // The returned string must not have an ending LF + int strSize = strlen(dest); + if (strSize > 0) { + if (dest[strSize - 1] == 0x0A) + dest[strSize - 1] = 0; + } debugC(2, kDebugLevelFile, "FGets'ed \"%s\"\n", dest); } @@ -301,8 +307,8 @@ static void fseek_wrapper(EngineState *s, int handle, int offset, int whence) { reg_t kFGets(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *dest = kernel_dereference_char_pointer(s, argv[0], 0); - int maxsize = UKPV(1); - int handle = UKPV(2); + int maxsize = argv[1].toUint16(); + int handle = argv[2].toUint16(); debug(3, "kFGets(%d,%d)", handle, maxsize); fgets_wrapper(s, dest, maxsize, handle); @@ -344,7 +350,7 @@ enum { }; reg_t kDeviceInfo(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int mode = UKPV(0); + int mode = argv[0].toUint16(); char *game_prefix, *input_s, *output_s; switch (mode) { @@ -394,7 +400,7 @@ reg_t kDeviceInfo(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_DEVICE_INFO_GET_SAVEFILE_NAME: { output_s = kernel_dereference_char_pointer(s, argv[1], 0); game_prefix = kernel_dereference_char_pointer(s, argv[2], 0); - int savegame_id = UKPV(3); + int savegame_id = argv[3].toUint16(); sprintf(output_s, "__throwaway"); debug(3, "K_DEVICE_INFO_GET_SAVEFILE_NAME(%s,%d) -> %s", game_prefix, savegame_id, output_s); delete_savegame(s, savegame_id); @@ -474,7 +480,7 @@ void listSavegames(Common::Array<SavegameDesc> &saves) { reg_t kCheckSaveGame(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *game_id = kernel_dereference_char_pointer(s, argv[0], 0); - int savedir_nr = UKPV(1); + int savedir_nr = argv[1].toUint16(); debug(3, "kCheckSaveGame(%s, %d)", game_id, savedir_nr); @@ -560,7 +566,7 @@ reg_t kGetSaveFiles(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kSaveGame(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *game_id = kernel_dereference_char_pointer(s, argv[0], 0); - int savedir_nr = UKPV(1); + int savedir_nr = argv[1].toUint16(); int savedir_id; // Savegame ID, derived from savedir_nr and the savegame ID list char *game_description = kernel_dereference_char_pointer(s, argv[2], 0); char *version = argc > 3 ? strdup(kernel_dereference_char_pointer(s, argv[3], 0)) : NULL; @@ -633,7 +639,7 @@ reg_t kSaveGame(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kRestoreGame(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *game_id = kernel_dereference_char_pointer(s, argv[0], 0); - int savedir_nr = UKPV(1); + int savedir_nr = argv[1].toUint16(); debug(3, "kRestoreGame(%s,%d)", game_id, savedir_nr); @@ -739,37 +745,37 @@ void DirSeeker::nextFile() { reg_t kFileIO(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int func_nr = UKPV(0); + int func_nr = argv[0].toUint16(); switch (func_nr) { case K_FILEIO_OPEN : { char *name = kernel_dereference_char_pointer(s, argv[1], 0); - int mode = UKPV(2); + int mode = argv[2].toUint16(); file_open(s, name, mode); debug(3, "K_FILEIO_OPEN(%s,0x%x)", name, mode); break; } case K_FILEIO_CLOSE : { - int handle = UKPV(1); + int handle = argv[1].toUint16(); debug(3, "K_FILEIO_CLOSE(%d)", handle); file_close(s, handle); break; } case K_FILEIO_READ_RAW : { - int handle = UKPV(1); + int handle = argv[1].toUint16(); char *dest = kernel_dereference_char_pointer(s, argv[2], 0); - int size = UKPV(3); + int size = argv[3].toUint16(); debug(3, "K_FILEIO_READ_RAW(%d,%d)", handle, size); fread_wrapper(s, dest, size, handle); break; } case K_FILEIO_WRITE_RAW : { - int handle = UKPV(1); + int handle = argv[1].toUint16(); char *buf = kernel_dereference_char_pointer(s, argv[2], 0); - int size = UKPV(3); + int size = argv[3].toUint16(); debug(3, "K_FILEIO_WRITE_RAW(%d,%d)", handle, size); fwrite_wrapper(s, handle, buf, size); @@ -788,16 +794,16 @@ reg_t kFileIO(EngineState *s, int funct_nr, int argc, reg_t *argv) { } case K_FILEIO_READ_STRING : { char *dest = kernel_dereference_char_pointer(s, argv[1], 0); - int size = UKPV(2); - int handle = UKPV(3); + int size = argv[2].toUint16(); + int handle = argv[3].toUint16(); debug(3, "K_FILEIO_READ_STRING(%d,%d)", handle, size); fgets_wrapper(s, dest, size, handle); return argv[1]; } case K_FILEIO_WRITE_STRING : { - int handle = UKPV(1); - int size = UKPV(3); + int handle = argv[1].toUint16(); + int size = argv[3].toUint16(); char *buf = kernel_dereference_char_pointer(s, argv[2], size); debug(3, "K_FILEIO_WRITE_STRING(%d,%d)", handle, size); @@ -810,9 +816,9 @@ reg_t kFileIO(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case K_FILEIO_SEEK : { - int handle = UKPV(1); - int offset = UKPV(2); - int whence = UKPV(3); + int handle = argv[1].toUint16(); + int offset = argv[2].toUint16(); + int whence = argv[3].toUint16(); debug(3, "K_FILEIO_SEEK(%d,%d,%d)", handle, offset, whence); fseek_wrapper(s, handle, offset, whence); @@ -821,7 +827,7 @@ reg_t kFileIO(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_FILEIO_FIND_FIRST : { char *mask = kernel_dereference_char_pointer(s, argv[1], 0); reg_t buf = argv[2]; - int attr = UKPV(3); // We won't use this, Win32 might, though... + int attr = argv[3].toUint16(); // We won't use this, Win32 might, though... debug(3, "K_FILEIO_FIND_FIRST(%s,0x%x)", mask, attr); #ifndef WIN32 diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index e58fc79244..6e737597d6 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -25,6 +25,7 @@ #include "common/system.h" #include "common/events.h" +#include "graphics/cursorman.h" #include "sci/sci.h" #include "sci/debug.h" // for g_debug_sleeptime_factor @@ -163,7 +164,7 @@ int _find_view_priority(EngineState *s, int y) { return j; return 14; // Maximum } else { - if (!(s->_flags & GF_SCI0_OLDGFXFUNCS)) + if (!s->_kernel->usesOldGfxFunctions()) return SCI0_VIEW_PRIORITY_14_ZONES(y); else return SCI0_VIEW_PRIORITY(y) == 15 ? 14 : SCI0_VIEW_PRIORITY(y); @@ -171,7 +172,7 @@ int _find_view_priority(EngineState *s, int y) { } int _find_priority_band(EngineState *s, int nr) { - if (!(s->_flags & GF_SCI0_OLDGFXFUNCS) && (nr < 0 || nr > 14)) { + if (!s->_kernel->usesOldGfxFunctions() && (nr < 0 || nr > 14)) { if (nr == 15) return 0xffff; else { @@ -180,7 +181,7 @@ int _find_priority_band(EngineState *s, int nr) { return 0; } - if ((s->_flags & GF_SCI0_OLDGFXFUNCS) && (nr < 0 || nr > 15)) { + if (s->_kernel->usesOldGfxFunctions() && (nr < 0 || nr > 15)) { warning("Attempt to get priority band %d", nr); return 0; } @@ -190,7 +191,7 @@ int _find_priority_band(EngineState *s, int nr) { else { int retval; - if (!(s->_flags & GF_SCI0_OLDGFXFUNCS)) + if (!s->_kernel->usesOldGfxFunctions()) retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr); else retval = SCI0_PRIORITY_BAND_FIRST(nr); @@ -304,16 +305,16 @@ reg_t kSetCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) { switch (argc) { case 1 : if (s->_version < SCI_VERSION_1_1) { - if (SKPV(0) <= 1) { + if (argv[0].toSint16() <= 1) { // Newer (SCI1.1) semantics: show/hide cursor - g_system->showMouse(SKPV(0) != 0); + CursorMan.showMouse(argv[0].toSint16() != 0); } else { // Pre-SCI1.1: set cursor according to the first parameter - GFX_ASSERT(gfxop_set_pointer_cursor(s->gfx_state, SKPV(0))); + GFX_ASSERT(gfxop_set_pointer_cursor(s->gfx_state, argv[0].toSint16())); } } else { // SCI1.1: Show/hide cursor - g_system->showMouse(SKPV(0) != 0); + CursorMan.showMouse(argv[0].toSint16() != 0); } break; case 2 : @@ -329,37 +330,37 @@ reg_t kSetCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) { // this would open the menu on top. LSL5 is an exception, as the game can open // the menu when the player presses a button during the intro, but the cursor is // not placed on (x, 0) or (x, 1) - if (SKPV(1) <= 1) { + if (argv[1].toSint16() <= 1) { GFX_ASSERT(gfxop_set_pointer_cursor(s->gfx_state, - SKPV(1) == 0 ? GFXOP_NO_POINTER : SKPV(0))); + argv[1].toSint16() == 0 ? GFXOP_NO_POINTER : argv[0].toSint16())); } else { // newer (SCI1.1) semantics: set pointer position GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state, - Common::Point(UKPV(0), UKPV(1)))); + Common::Point(argv[0].toUint16(), argv[1].toUint16()))); } } else { // SCI1.1 and newer: set pointer position GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state, - Common::Point(UKPV(0), UKPV(1)))); + Common::Point(argv[0].toUint16(), argv[1].toUint16()))); } break; case 4 : GFX_ASSERT(gfxop_set_pointer_cursor(s->gfx_state, - UKPV(0) == 0 ? GFXOP_NO_POINTER : SKPV(0))); + argv[0].toUint16() == 0 ? GFXOP_NO_POINTER : argv[0].toSint16())); // Set pointer position, if requested if (argc > 2) { - Common::Point newpos = Common::Point(SKPV(2) + s->port->_bounds.x, SKPV(3) + s->port->_bounds.y); - GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state, newpos)); + Common::Point newPos = Common::Point(argv[2].toSint16() + s->port->_bounds.x, argv[3].toSint16() + s->port->_bounds.y); + GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state, newPos)); } break; case 3 : case 5 : case 9 : if (argc > 3) { - Common::Point hotspot = Common::Point(SKPV(3), SKPV(4)); - GFX_ASSERT(gfxop_set_pointer_view(s->gfx_state, UKPV(0), UKPV(1), UKPV(2), &hotspot)); + Common::Point hotspot = Common::Point(argv[3].toSint16(), argv[4].toSint16()); + GFX_ASSERT(gfxop_set_pointer_view(s->gfx_state, argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), &hotspot)); } else { - GFX_ASSERT(gfxop_set_pointer_view(s->gfx_state, UKPV(0), UKPV(1), UKPV(2), NULL)); + GFX_ASSERT(gfxop_set_pointer_view(s->gfx_state, argv[0].toUint16(), argv[1].toUint16(), argv[2].toUint16(), NULL)); } break; default : @@ -370,26 +371,26 @@ reg_t kSetCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kMoveCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) { - Common::Point newpos; + Common::Point newPos; - newpos = s->gfx_state->pointer_pos; + newPos = s->gfx_state->pointer_pos; if (argc == 1) { // Case ignored on IBM PC } else { - newpos.x = SKPV(0) + s->port->zone.x; - newpos.y = SKPV(1) + s->port->zone.y; + newPos.x = argv[0].toSint16() + s->port->zone.x; + newPos.y = argv[1].toSint16() + s->port->zone.y; - if (newpos.x > s->port->zone.x + s->port->zone.width) - newpos.x = s->port->zone.x + s->port->zone.width; - if (newpos.y > s->port->zone.y + s->port->zone.height) - newpos.y = s->port->zone.y + s->port->zone.height; + if (newPos.x > s->port->zone.x + s->port->zone.width) + newPos.x = s->port->zone.x + s->port->zone.width; + if (newPos.y > s->port->zone.y + s->port->zone.height) + newPos.y = s->port->zone.y + s->port->zone.height; - if (newpos.x < 0) newpos.x = 0; - if (newpos.y < 0) newpos.y = 0; + if (newPos.x < 0) newPos.x = 0; + if (newPos.y < 0) newPos.y = 0; } - GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state, newpos)); + GFX_ASSERT(gfxop_set_pointer_position(s->gfx_state, newPos)); return s->r_acc; } @@ -397,7 +398,7 @@ reg_t kMoveCursor(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kShow(EngineState *s, int funct_nr, int argc, reg_t *argv) { int old_map = s->pic_visible_map; - s->pic_visible_map = (gfx_map_mask_t) UKPV_OR_ALT(0, 1); + s->pic_visible_map = (argc > 0) ? (gfx_map_mask_t) argv[0].toUint16() : GFX_MASK_VISUAL; switch (s->pic_visible_map) { @@ -427,7 +428,7 @@ reg_t kShow(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kPicNotValid(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->r_acc = make_reg(0, s->pic_not_valid); if (argc) - s->pic_not_valid = (byte)UKPV(0); + s->pic_not_valid = (byte)argv[0].toUint16(); return s->r_acc; } @@ -488,12 +489,12 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { GfxPort *port = s->port; int redraw_port = 0; - area = gfx_rect(SKPV(2), SKPV(1) , SKPV(4), SKPV(3)); + area = gfx_rect(argv[2].toSint16(), argv[1].toSint16() , argv[4].toSint16(), argv[3].toSint16()); area.width = area.width - area.x; // Since the actual coordinates are absolute area.height = area.height - area.y; - switch (SKPV(0)) { + switch (argv[0].toSint16()) { case K_GRAPH_GET_COLORS_NR: @@ -501,11 +502,12 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; case K_GRAPH_DRAW_LINE: { - - gfx_color_t gfxcolor = graph_map_color(s, SKPV(5), SKPV_OR_ALT(6, -1), SKPV_OR_ALT(7, -1)); + int16 priority = (argc > 6) ? argv[6].toSint16() : -1; + int16 control = (argc > 7) ? argv[7].toSint16() : -1; + gfx_color_t gfxcolor = graph_map_color(s, argv[5].toSint16(), priority, control); debugC(2, kDebugLevelGraphics, "draw_line((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n", - SKPV(2), SKPV(1), SKPV(4), SKPV(3), SKPV(5), SKPV_OR_ALT(6, -1), SKPV_OR_ALT(7, -1), gfxcolor.mask); + argv[2].toSint16(), argv[1].toSint16(), argv[4].toSint16(), argv[3].toSint16(), argv[5].toSint16(), priority, control, gfxcolor.mask); redraw_port = 1; @@ -513,7 +515,7 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { // have negative width/height). The actual dirty rectangle is constructed in gfxdr_add_dirty(). // FIXME/TODO: We need to change the semantics of this call, so that no fake rectangles are used. As it is, it's // not possible change rect_t to Common::Rect, as we assume that Common::Rect forms a *valid* rectangle. - ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_line(Common::Point(SKPV(2), SKPV(1)), Common::Point(SKPV(4), SKPV(3)), + ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_line(Common::Point(argv[2].toSint16(), argv[1].toSint16()), Common::Point(argv[4].toSint16(), argv[3].toSint16()), gfxcolor, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); } @@ -551,13 +553,14 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; case K_GRAPH_FILL_BOX_ANY: { + int16 priority = (argc > 7) ? argv[7].toSint16() : -1; + int16 control = (argc > 8) ? argv[8].toSint16() : -1; + gfx_color_t color = graph_map_color(s, argv[6].toSint16(), priority, control); - gfx_color_t color = graph_map_color(s, SKPV(6), SKPV_OR_ALT(7, -1), SKPV_OR_ALT(8, -1)); - - color.mask = (byte)UKPV(5); + color.mask = (byte)argv[5].toUint16(); debugC(2, kDebugLevelGraphics, "fill_box_any((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n", - SKPV(2), SKPV(1), SKPV(4), SKPV(3), SKPV(6), SKPV_OR_ALT(7, -1), SKPV_OR_ALT(8, -1), UKPV(5)); + argv[2].toSint16(), argv[1].toSint16(), argv[4].toSint16(), argv[3].toSint16(), argv[6].toSint16(), priority, control, argv[5].toUint16()); // FIXME/TODO: this is not right, as some of the dialogs are drawn *behind* some widgets. But at least it works for now //ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT)); // old code @@ -568,7 +571,7 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_GRAPH_UPDATE_BOX: { - debugC(2, kDebugLevelGraphics, "update_box(%d, %d, %d, %d)\n", SKPV(1), SKPV(2), SKPV(3), SKPV(4)); + debugC(2, kDebugLevelGraphics, "update_box(%d, %d, %d, %d)\n", argv[1].toSint16(), argv[2].toSint16(), argv[3].toSint16(), argv[4].toSint16()); area.x += s->port->zone.x; area.y += s->port->zone.y; @@ -581,7 +584,7 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_GRAPH_REDRAW_BOX: { - debugC(2, kDebugLevelGraphics, "redraw_box(%d, %d, %d, %d)\n", SKPV(1), SKPV(2), SKPV(3), SKPV(4)); + debugC(2, kDebugLevelGraphics, "redraw_box(%d, %d, %d, %d)\n", argv[1].toSint16(), argv[2].toSint16(), argv[3].toSint16(), argv[4].toSint16()); area.x += s->port->zone.x; area.y += s->port->zone.y; @@ -597,14 +600,14 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_GRAPH_ADJUST_PRIORITY: - debugC(2, kDebugLevelGraphics, "adjust_priority(%d, %d)\n", SKPV(1), SKPV(2)); - s->priority_first = SKPV(1) - 10; - s->priority_last = SKPV(2) - 10; + debugC(2, kDebugLevelGraphics, "adjust_priority(%d, %d)\n", argv[1].toSint16(), argv[2].toSint16()); + s->priority_first = argv[1].toSint16() - 10; + s->priority_last = argv[2].toSint16() - 10; break; default: - warning("Unhandled Graph() operation %04x", SKPV(0)); + warning("Unhandled Graph() operation %04x", argv[0].toSint16()); } @@ -619,9 +622,13 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kTextSize(EngineState *s, int funct_nr, int argc, reg_t *argv) { int width, height; char *text = argv[1].segment ? (char *) kernel_dereference_bulk_pointer(s, argv[1], 0) : NULL; + const char *sep = NULL; reg_t *dest = kernel_dereference_reg_pointer(s, argv[0], 4); - int maxwidth = KP_UINT(KP_ALT(3, NULL_REG)); - int font_nr = KP_UINT(argv[2]); + int maxwidth = (argc > 3) ? argv[3].toUint16() : 0; + int font_nr = argv[2].toUint16(); + + if ((argc > 4) && (argv[4].segment)) + sep = (const char *)kernel_dereference_bulk_pointer(s, argv[4], 0); if (maxwidth < 0) maxwidth = 0; @@ -634,7 +641,7 @@ reg_t kTextSize(EngineState *s, int funct_nr, int argc, reg_t *argv) { return s->r_acc; } - GFX_ASSERT(gfxop_get_text_params(s->gfx_state, font_nr, text, maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE, + GFX_ASSERT(gfxop_get_text_params(s->gfx_state, font_nr, s->strSplit(text, sep).c_str(), maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE, &width, &height, 0, NULL, NULL, NULL)); debugC(2, kDebugLevelStrings, "GetTextSize '%s' -> %dx%d\n", text, width, height); @@ -647,7 +654,7 @@ reg_t kTextSize(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kWait(EngineState *s, int funct_nr, int argc, reg_t *argv) { uint32 time; - int sleep_time = UKPV(0); + int sleep_time = argv[0].toUint16(); time = g_system->getMillis(); s->r_acc = make_reg(0, ((long)time - (long)s->last_wait_time) * 60 / 1000); @@ -663,15 +670,15 @@ reg_t kWait(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kCoordPri(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int y = SKPV(0); + int y = argv[0].toSint16(); - return make_reg(0, VIEW_PRIORITY(y)); + return make_reg(0, _find_view_priority(s, y)); } reg_t kPriCoord(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int priority = SKPV(0); + int priority = argv[0].toSint16(); - return make_reg(0, PRIORITY_BAND_FIRST(priority)); + return make_reg(0, _find_priority_band(s, priority)); } void _k_dirloop(reg_t obj, uint16 angle, EngineState *s, int funct_nr, int argc, reg_t *argv) { @@ -720,7 +727,7 @@ void _k_dirloop(reg_t obj, uint16 angle, EngineState *s, int funct_nr, int argc, } reg_t kDirLoop(EngineState *s, int funct_nr, int argc, reg_t *argv) { - _k_dirloop(argv[0], UKPV(1), s, funct_nr, argc, argv); + _k_dirloop(argv[0], argv[1].toUint16(), s, funct_nr, argc, argv); return s->r_acc; } @@ -771,7 +778,7 @@ static int collides_with(EngineState *s, Common::Rect area, reg_t other_obj, int reg_t kCanBeHere(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t obj = argv[0]; - reg_t cliplist_ref = KP_ALT(1, NULL_REG); + reg_t cliplist_ref = (argc > 1) ? argv[1] : NULL_REG; List *cliplist = NULL; GfxPort *port = s->picture_port; uint16 signal; @@ -863,18 +870,18 @@ reg_t kCanBeHere(EngineState *s, int funct_nr, int argc, reg_t *argv) { } // CanBeHere reg_t kIsItSkip(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int view = SKPV(0); - int loop = SKPV(1); - int cel = SKPV(2); - int y = UKPV(3); - int x = UKPV(4); + int view = argv[0].toSint16(); + int loop = argv[1].toSint16(); + int cel = argv[2].toSint16(); + int y = argv[3].toUint16(); + int x = argv[4].toUint16(); gfxr_view_t *res = NULL; gfx_pixmap_t *pxm = NULL; res = s->gfx_state->gfxResMan->getView(view, &loop, &cel, 0); if (!res) { - GFXWARN("Attempt to get cel parameters for invalid view %d\n", view); + warning("[GFX] Attempt to get cel parameters for invalid view %d", view); return make_reg(0, -1); } @@ -888,9 +895,9 @@ reg_t kIsItSkip(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kCelHigh(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int view = SKPV(0); - int loop = SKPV(1); - int cel = SKPV(2); + int view = argv[0].toSint16(); + int loop = argv[1].toSint16(); + int cel = argv[2].toSint16(); int height, width; Common::Point offset; @@ -906,9 +913,9 @@ reg_t kCelHigh(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kCelWide(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int view = SKPV(0); - int loop = SKPV(1); - int cel = SKPV(2); + int view = argv[0].toSint16(); + int loop = argv[1].toSint16(); + int cel = argv[2].toSint16(); int height, width; Common::Point offset; @@ -967,15 +974,15 @@ reg_t kOnControl(EngineState *s, int funct_nr, int argc, reg_t *argv) { map = GFX_MASK_CONTROL; else { arg = 1; - map = (gfx_map_mask_t) SKPV(0); + map = (gfx_map_mask_t) argv[0].toSint16(); } - ystart = SKPV(arg + 1); - xstart = SKPV(arg); + ystart = argv[arg + 1].toSint16(); + xstart = argv[arg].toSint16(); if (argc > 3) { - ylen = SKPV(arg + 3) - ystart; - xlen = SKPV(arg + 2) - xstart; + ylen = argv[arg + 3].toSint16() - ystart; + xlen = argv[arg + 2].toSint16() - xstart; } return make_reg(0, gfxop_scan_bitmask(s->gfx_state, gfx_rect(xstart, ystart + 10, xlen, ylen), map)); @@ -987,23 +994,18 @@ void _k_view_list_free_backgrounds(EngineState *s, ViewObject *list, int list_nr reg_t kDrawPic(EngineState *s, int funct_nr, int argc, reg_t *argv) { drawn_pic_t dp; - int add_to_pic = 1; + bool add_to_pic = (argc > 2) ? !argv[2].toSint16() : false; gfx_color_t transparent = s->wm_port->_bgcolor; int picFlags = DRAWPIC01_FLAG_FILL_NORMALLY; - dp.nr = SKPV(0); - dp.palette = SKPV_OR_ALT(3, 0); + if (s->_kernel->usesOldGfxFunctions()) + add_to_pic = (argc > 2) ? argv[2].toSint16() : false; - if ((argc > 1) && (UKPV(1) & K_DRAWPIC_FLAG_MIRRORED)) - picFlags |= DRAWPIC1_FLAG_MIRRORED; + dp.nr = argv[0].toSint16(); + dp.palette = (argc > 3) ? argv[3].toSint16() : 0; - if (s->_flags & GF_SCI0_OLDGFXFUNCS) { - if (!SKPV_OR_ALT(2, 0)) - add_to_pic = 0; - } else { - if (SKPV_OR_ALT(2, 1)) - add_to_pic = 0; - } + if ((argc > 1) && (argv[1].toUint16() & K_DRAWPIC_FLAG_MIRRORED)) + picFlags |= DRAWPIC1_FLAG_MIRRORED; gfxop_disable_dirty_frames(s->gfx_state); @@ -1013,7 +1015,7 @@ reg_t kDrawPic(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->old_screen = gfxop_grab_pixmap(s->gfx_state, gfx_rect(0, 10, 320, 190)); - debugC(2, kDebugLevelGraphics, "Drawing pic.%03d\n", SKPV(0)); + debugC(2, kDebugLevelGraphics, "Drawing pic.%03d\n", argv[0].toSint16()); if (add_to_pic) { s->_pics.push_back(dp); @@ -1043,14 +1045,14 @@ reg_t kDrawPic(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->pic_priority_table = gfxop_get_pic_metainfo(s->gfx_state); if (argc > 1) - s->pic_animate = SKPV(1) & 0xff; // The animation used during kAnimate() later on + s->pic_animate = argv[1].toSint16() & 0xff; // The animation used during kAnimate() later on s->dyn_views = NULL; s->drop_views = NULL; s->priority_first = 42; - if (s->_flags & GF_SCI0_OLDGFXFUNCS) + if (s->_kernel->usesOldGfxFunctions()) s->priority_last = 200; else s->priority_last = 190; @@ -1157,9 +1159,9 @@ static Common::Rect nsrect_clip(EngineState *s, int y, Common::Rect retval, int int pri_top; if (priority == -1) - priority = VIEW_PRIORITY(y); + priority = _find_view_priority(s, y); - pri_top = PRIORITY_BAND_FIRST(priority) + 1; + pri_top = _find_priority_band(s, priority) + 1; // +1: Don't know why, but this seems to be happening if (retval.top < pri_top) @@ -1251,7 +1253,7 @@ reg_t kSetNowSeen(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kPalette(EngineState *s, int funct_nr, int argc, reg_t *argv) { - switch (UKPV(0)) { + switch (argv[0].toUint16()) { case 1: debug(5, "STUB: kPalette() effect 1, direct palette set"); break; @@ -1264,11 +1266,11 @@ reg_t kPalette(EngineState *s, int funct_nr, int argc, reg_t *argv) { case 4: { // Set palette intensity #if 0 // Colors 0 (black) and 255 (white) cannot be changed - int16 from = CLIP<int16>(1, 255, UKPV(2)); - int16 to = CLIP<int16>(1, 255, UKPV(3)); - int16 intensity = UKPV(4); + int16 from = CLIP<int16>(1, 255, argv[2].toUint16()); + int16 to = CLIP<int16>(1, 255, argv[3].toUint16()); + int16 intensity = argv[4].toUint16(); - if (argc < 5 || UKPV(5) == 0) { + if (argc < 5 || argv[5].toUint16() == 0) { s->gfx_state->gfxResMan->setPaletteIntensity(from, to, intensity); } else { warning("kPalette: argv[5] != 0"); @@ -1280,9 +1282,9 @@ reg_t kPalette(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case 5: { // Find closest color - int r = UKPV(1); - int g = UKPV(2); - int b = UKPV(3); + int r = argv[1].toUint16(); + int g = argv[2].toUint16(); + int b = argv[3].toUint16(); int i, delta, bestindex = -1, bestdelta = 200000; @@ -1312,7 +1314,7 @@ reg_t kPalette(EngineState *s, int funct_nr, int argc, reg_t *argv) { debug(5, "STUB: kPalette() effect 8, set stored palette"); break; default: - warning("kPalette(): Unimplemented subfunction: %d", UKPV(0)); + warning("kPalette(): Unimplemented subfunction: %d", argv[0].toUint16()); } return s->r_acc; @@ -1573,7 +1575,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { int font_nr = GET_SEL32V(obj, font); reg_t text_pos = GET_SEL32(obj, text); - char *text = text_pos.isNull() ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL); + const char *text = text_pos.isNull() ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL); int view = GET_SEL32V(obj, view); int cel = sign_extend_byte(GET_SEL32V(obj, cel)); int loop = sign_extend_byte(GET_SEL32V(obj, loop)); @@ -1587,7 +1589,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { switch (type) { case K_CONTROL_BUTTON: debugC(2, kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d\n", PRINT_REG(obj), x, y); - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, text, font_nr, + ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, s->strSplit(text, NULL).c_str(), font_nr, (int8)(state & kControlStateFramed), (int8)inverse, (int8)(state & kControlStateDisabled))); break; @@ -1596,7 +1598,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { debugC(2, kDebugLevelGraphics, "drawing text %04x:%04x to %d,%d, mode=%d\n", PRINT_REG(obj), x, y, mode); - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, text, font_nr, mode, + ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, s->strSplit(text).c_str(), font_nr, mode, (int8)(!!(state & kControlStateDitherFramed)), (int8)inverse)); break; @@ -1623,8 +1625,8 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { case K_CONTROL_CONTROL: case K_CONTROL_CONTROL_ALIAS: { - char **entries_list = NULL; - char *seeker; + const char **entries_list = NULL; + const char *seeker; int entries_nr; int lsTop = GET_SEL32V(obj, lsTop) - text_pos.offset; int list_top = 0; @@ -1644,7 +1646,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { if (entries_nr) { // determine list_top, selection, and the entries_list seeker = text; - entries_list = (char**)malloc(sizeof(char *) * entries_nr); + entries_list = (const char**)malloc(sizeof(char *) * entries_nr); for (i = 0; i < entries_nr; i++) { entries_list[i] = seeker; seeker += entry_size ; @@ -1698,7 +1700,8 @@ static void draw_obj_to_control_map(EngineState *s, GfxDynView *view) { if (!is_object(s, obj)) warning("View %d does not contain valid object reference %04x:%04x", view->_ID, PRINT_REG(obj)); - if (!(view->signalp && (((reg_t *)view->signalp)->offset & _K_VIEW_SIG_FLAG_IGNORE_ACTOR))) { + reg_t* sp = view->signalp.getPointer(s); + if (!(sp && (sp->offset & _K_VIEW_SIG_FLAG_IGNORE_ACTOR))) { Common::Rect abs_zone = get_nsrect(s, make_reg(view->_ID, view->_subID), 1); draw_rect_to_control_map(s, abs_zone); } @@ -1749,8 +1752,9 @@ static void _k_view_list_do_postdraw(EngineState *s, GfxList *list) { fprintf(stderr, "obj %04x:%04x has pflags %x\n", PRINT_REG(obj), (widget->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE))); #endif - if (widget->signalp) { - *((reg_t *)(widget->signalp)) = make_reg(0, widget->signal & 0xffff); /* Write back signal */ + reg_t* sp = widget->signalp.getPointer(s); + if (sp) { + *sp = make_reg(0, widget->signal & 0xffff); /* Write back signal */ } widget = (GfxDynView *)widget->_next; @@ -1765,7 +1769,7 @@ void _k_view_list_mark_free(EngineState *s, reg_t off) { while (w) { if (w->_ID == off.segment && w->_subID == off.offset) { - w->under_bitsp = NULL; + w->under_bitsp.obj = NULL_REG; } w = (GfxDynView *)w->_next; @@ -1792,7 +1796,7 @@ int _k_view_list_dispose_loop(EngineState *s, List *list, GfxDynView *widget, in return -1; if (GFXW_IS_DYN_VIEW(widget) && (widget->_ID != GFXW_NO_ID)) { - signal = ((reg_t *)widget->signalp)->offset; + signal = widget->signalp.getPointer(s)->offset; if (signal & _K_VIEW_SIG_FLAG_DISPOSE_ME) { reg_t obj = make_reg(widget->_ID, widget->_subID); reg_t under_bits = NULL_REG; @@ -1800,20 +1804,21 @@ int _k_view_list_dispose_loop(EngineState *s, List *list, GfxDynView *widget, in if (!is_object(s, obj)) { error("Non-object %04x:%04x present in view list during delete time", PRINT_REG(obj)); obj = NULL_REG; - } else - if (widget->under_bitsp) { // Is there a bg picture left to clean? - reg_t mem_handle = *((reg_t*)(widget->under_bitsp)); + } else { + reg_t *ubp = widget->under_bitsp.getPointer(s); + if (ubp) { // Is there a bg picture left to clean? + reg_t mem_handle = *ubp; if (mem_handle.segment) { if (!kfree(s, mem_handle)) { - *((reg_t*)(widget->under_bitsp)) = make_reg(0, widget->under_bits = 0); + *ubp = make_reg(0, widget->under_bits = 0); } else { warning("Treating viewobj %04x:%04x as no longer present", PRINT_REG(obj)); obj = NULL_REG; } } } - + } if (is_object(s, obj)) { if (invoke_selector(INV_SEL(obj, delete_, kContinueOnInvalidSelector), 0)) warning("Object at %04x:%04x requested deletion, but does not have a delete funcselector", PRINT_REG(obj)); @@ -1822,11 +1827,12 @@ int _k_view_list_dispose_loop(EngineState *s, List *list, GfxDynView *widget, in return dropped; } - if (widget->under_bitsp) - under_bits = *((reg_t*)(widget->under_bitsp)); + reg_t *ubp = widget->under_bitsp.getPointer(s); + if (ubp) + under_bits = *ubp; if (under_bits.segment) { - *((reg_t*)(widget->under_bitsp)) = make_reg(0, 0); + *ubp = make_reg(0, 0); graph_restore_box(s, under_bits); } @@ -1871,7 +1877,6 @@ static GfxDynView *_k_make_dynview_obj(EngineState *s, reg_t obj, int options, i int palette; int signal; reg_t under_bits; - reg_t *under_bitsp, *signalp; Common::Point pos; int z; GfxDynView *widget; @@ -1913,19 +1918,21 @@ static GfxDynView *_k_make_dynview_obj(EngineState *s, reg_t obj, int options, i PUT_SEL32V(obj, cel, cel); } + ObjVarRef under_bitsp; if (lookup_selector(s, obj, s->_kernel->_selectorMap.underBits, &(under_bitsp), NULL) != kSelectorVariable) { - under_bitsp = NULL; + under_bitsp.obj = NULL_REG; under_bits = NULL_REG; debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no underBits\n", PRINT_REG(obj)); } else - under_bits = *((reg_t *)under_bitsp); + under_bits = *under_bitsp.getPointer(s); + ObjVarRef signalp; if (lookup_selector(s, obj, s->_kernel->_selectorMap.signal, &(signalp), NULL) != kSelectorVariable) { - signalp = NULL; + signalp.obj = NULL_REG; signal = 0; debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no signal selector\n", PRINT_REG(obj)); } else { - signal = signalp->offset; + signal = signalp.getPointer(s)->offset; debugC(2, kDebugLevelGraphics, " with signal = %04x\n", signal); } @@ -2000,8 +2007,9 @@ static void _k_make_view_list(EngineState *s, GfxList **widget_list, List *list, widget = (GfxDynView *)(*widget_list)->_contents; while (widget) { // Read back widget values - if (widget->signalp) - widget->signal = ((reg_t *)(widget->signalp))->offset; + reg_t *sp = widget->signalp.getPointer(s); + if (sp) + widget->signal = sp->offset; widget = (GfxDynView *)widget->_next; } @@ -2227,7 +2235,7 @@ void _k_draw_view_list(EngineState *s, GfxList *list, int flags) { widget = gfxw_picviewize_dynview(widget); if (GFXW_IS_DYN_VIEW(widget) && widget->_ID) { - uint16 signal = (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) ? ((reg_t *)(widget->signalp))->offset : 0; + uint16 signal = (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) ? widget->signalp.getPointer(s)->offset : 0; if (signal & _K_VIEW_SIG_FLAG_HIDDEN) gfxw_hide_widget(widget); @@ -2247,7 +2255,7 @@ void _k_draw_view_list(EngineState *s, GfxList *list, int flags) { else gfxw_show_widget(widget); - *((reg_t *)(widget->signalp)) = make_reg(0, signal); // Write the changes back + *widget->signalp.getPointer(s) = make_reg(0, signal); // Write the changes back }; } // ...if we're drawing disposeables and this one is disposeable, or if we're drawing non- @@ -2269,13 +2277,13 @@ reg_t kAddToPic(EngineState *s, int funct_nr, int argc, reg_t *argv) { int view, cel, loop, x, y, priority, control; GfxWidget *widget; - view = KP_UINT(argv[0]); - loop = KP_UINT(argv[1]); - cel = KP_UINT(argv[2]); - x = KP_SINT(argv[3]); - y = KP_SINT(argv[4]) + 1 /* magic + 1 */; - priority = KP_SINT(argv[5]); - control = KP_SINT(argv[6]); + view = argv[0].toUint16(); + loop = argv[1].toUint16(); + cel = argv[2].toUint16(); + x = argv[3].toSint16(); + y = argv[4].toSint16() + 1 /* magic + 1 */; + priority = argv[5].toSint16(); + control = argv[6].toSint16(); widget = gfxw_new_dyn_view(s->gfx_state, Common::Point(x, y), 0, view, loop, cel, 0, priority, -1 /* No priority */ , ALIGN_CENTER, ALIGN_BOTTOM, 0); @@ -2331,7 +2339,7 @@ reg_t kSetPort(EngineState *s, int funct_nr, int argc, reg_t *argv) { switch (argc) { case 1 : { - unsigned int port_nr = SKPV(0); + unsigned int port_nr = argv[0].toSint16(); GfxPort *new_port; /* We depart from official semantics here, sorry! @@ -2354,10 +2362,10 @@ reg_t kSetPort(EngineState *s, int funct_nr, int argc, reg_t *argv) { return s->r_acc; } case 6 : { - port_origin_y = SKPV(0); - port_origin_x = SKPV(1); + port_origin_y = argv[0].toSint16(); + port_origin_x = argv[1].toSint16(); - if (SKPV(0) == -10) { + if (argv[0].toSint16() == -10) { s->port->draw(gfxw_point_zero); // Update the port we're leaving s->port = s->iconbar_port; activated_icon_bar = true; @@ -2365,20 +2373,20 @@ reg_t kSetPort(EngineState *s, int funct_nr, int argc, reg_t *argv) { } // Notify the graphics resource manager that the pic port bounds changed - s->gfx_state->gfxResMan->changePortBounds(UKPV(5), UKPV(4), UKPV(3) + UKPV(5), UKPV(2) + UKPV(4)); + s->gfx_state->gfxResMan->changePortBounds(argv[5].toUint16(), argv[4].toUint16(), argv[3].toUint16() + argv[5].toUint16(), argv[2].toUint16() + argv[4].toUint16()); // LSL6 calls kSetPort to extend the screen to draw the GUI. If we free all resources // here, the background picture is freed too, and this makes everything a big mess. // FIXME/TODO: This code really needs to be rewritten to conform to the original behavior if (s->_gameName != "LSL6") { - s->gfx_state->pic_port_bounds = gfx_rect(UKPV(5), UKPV(4), UKPV(3), UKPV(2)); + s->gfx_state->pic_port_bounds = gfx_rect(argv[5].toUint16(), argv[4].toUint16(), argv[3].toUint16(), argv[2].toUint16()); // FIXME: Should really only invalidate all loaded pic resources here; // this is overkill s->gfx_state->gfxResMan->freeAllResources(); } else { // WORKAROUND for LSL6 - printf("SetPort case 6 called in LSL6. Origin: %d, %d - Clip rect: %d, %d, %d, %d\n", SKPV(1), SKPV(0), UKPV(5), UKPV(4), UKPV(3), UKPV(2)); + printf("SetPort case 6 called in LSL6. Origin: %d, %d - Clip rect: %d, %d, %d, %d\n", argv[1].toSint16(), argv[0].toSint16(), argv[5].toUint16(), argv[4].toUint16(), argv[3].toUint16(), argv[2].toUint16()); } break; @@ -2392,12 +2400,12 @@ reg_t kSetPort(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kDrawCel(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int view = SKPV(0); - int loop = SKPV(1); - int cel = SKPV(2); - int x = SKPV(3); - int y = SKPV(4); - int priority = SKPV_OR_ALT(5, -1); + int view = argv[0].toSint16(); + int loop = argv[1].toSint16(); + int cel = argv[2].toSint16(); + int x = argv[3].toSint16(); + int y = argv[4].toSint16(); + int priority = (argc > 5) ? argv[5].toSint16() : -1; GfxView *new_view; /* @@ -2424,7 +2432,7 @@ reg_t kDrawCel(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kDisposeWindow(EngineState *s, int funct_nr, int argc, reg_t *argv) { - unsigned int goner_nr = SKPV(0); + unsigned int goner_nr = argv[0].toSint16(); GfxPort *goner; GfxPort *pred; @@ -2472,26 +2480,28 @@ reg_t kNewWindow(EngineState *s, int funct_nr, int argc, reg_t *argv) { int priority; int argextra = argc == 13 ? 4 : 0; // Triggers in PQ3 and SCI1.1 games - y = SKPV(0); - x = SKPV(1); - yl = SKPV(2) - y; - xl = SKPV(3) - x; + y = argv[0].toSint16(); + x = argv[1].toSint16(); + yl = argv[2].toSint16() - y; + xl = argv[3].toSint16() - x; y += s->wm_port->_bounds.y; if (x + xl > 319) x -= ((x + xl) - 319); - flags = SKPV(5 + argextra); + flags = argv[5 + argextra].toSint16(); - priority = SKPV_OR_ALT(6 + argextra, -1); + priority = (argc > 6 + argextra) ? argv[6 + argextra].toSint16() : -1; bgcolor.mask = 0; - if (SKPV_OR_ALT(8 + argextra, 255) >= 0) { + int16 bgColor = (argc > 8 + argextra) ? argv[8 + argextra].toSint16() : 255; + + if (bgColor >= 0) { if (s->resmgr->_sciVersion < SCI_VERSION_01_VGA) - bgcolor.visual = get_pic_color(s, SKPV_OR_ALT(8 + argextra, 15)); + bgcolor.visual = get_pic_color(s, MIN<int>(bgColor, 15)); else - bgcolor.visual = get_pic_color(s, SKPV_OR_ALT(8 + argextra, 255)); + bgcolor.visual = get_pic_color(s, bgColor); bgcolor.mask = GFX_MASK_VISUAL; } else { bgcolor.visual = PaletteEntry(0,0,0); @@ -2501,9 +2511,10 @@ reg_t kNewWindow(EngineState *s, int funct_nr, int argc, reg_t *argv) { bgcolor.mask |= priority >= 0 ? GFX_MASK_PRIORITY : 0; bgcolor.alpha = 0; bgcolor.control = -1; - debugC(2, kDebugLevelGraphics, "New window with params %d, %d, %d, %d\n", SKPV(0), SKPV(1), SKPV(2), SKPV(3)); + debugC(2, kDebugLevelGraphics, "New window with params %d, %d, %d, %d\n", argv[0].toSint16(), argv[1].toSint16(), argv[2].toSint16(), argv[3].toSint16()); - fgcolor.visual = get_pic_color(s, SKPV_OR_ALT(7 + argextra, 0)); + int16 visualColor = (argc > 7 + argextra) ? argv[7 + argextra].toSint16() : 0; + fgcolor.visual = get_pic_color(s, visualColor); fgcolor.mask = GFX_MASK_VISUAL; fgcolor.control = -1; fgcolor.priority = -1; @@ -2518,14 +2529,14 @@ reg_t kNewWindow(EngineState *s, int funct_nr, int argc, reg_t *argv) { lWhite.alpha = 0; lWhite.priority = -1; lWhite.control = -1; + const char *title = argv[4 + argextra].segment ? kernel_dereference_char_pointer(s, argv[4 + argextra], 0) : NULL; window = sciw_new_window(s, gfx_rect(x, y, xl, yl), s->titlebar_port->_font, fgcolor, bgcolor, - s->titlebar_port->_font, lWhite, black, argv[4 + argextra].segment ? - kernel_dereference_char_pointer(s, argv[4 + argextra], 0) : NULL, flags); + s->titlebar_port->_font, lWhite, black, title ? s->strSplit(title, NULL).c_str() : NULL, flags); // PQ3 and SCI1.1 games have the interpreter store underBits implicitly if (argextra) - gfxw_port_auto_restore_background(s->visual, window, gfx_rect(SKPV(5), SKPV(4), SKPV(7) - SKPV(5), SKPV(6) - SKPV(4))); + gfxw_port_auto_restore_background(s->visual, window, gfx_rect(argv[5].toSint16(), argv[4].toSint16(), argv[7].toSint16() - argv[5].toSint16(), argv[6].toSint16() - argv[4].toSint16())); ADD_TO_WINDOW_PORT(window); FULL_REDRAW(); @@ -2956,8 +2967,8 @@ static void animate_do_animation(EngineState *s, int funct_nr, int argc, reg_t * reg_t kAnimate(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Animations are supposed to take a maximum of animation_delay milliseconds. - reg_t cast_list_ref = KP_ALT(0, NULL_REG); - int cycle = (KP_ALT(1, NULL_REG)).offset; + reg_t cast_list_ref = (argc > 0) ? argv[0] : NULL_REG; + int cycle = (argc > 1) ? argv[1].toUint16() : 0; List *cast_list = NULL; int open_animation = 0; @@ -3065,8 +3076,8 @@ reg_t kAnimate(EngineState *s, int funct_nr, int argc, reg_t *argv) { #define SHAKE_RIGHT 2 reg_t kShakeScreen(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int shakes = SKPV_OR_ALT(0, 1); - int directions = SKPV_OR_ALT(1, 1); + int shakes = (argc > 0) ? argv[0].toSint16() : 1; + int directions = (argc > 1) ? argv[1].toSint16() : 1; gfx_pixmap_t *screen = gfxop_grab_pixmap(s->gfx_state, gfx_rect(0, 0, 320, 200)); int i; @@ -3115,7 +3126,7 @@ reg_t kShakeScreen(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { int argpt; reg_t textp = argv[0]; - int index = UKPV_OR_ALT(1, 0); + int index = (argc > 1) ? argv[1].toUint16() : 0; int temp; bool save_under = false; gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 }; @@ -3157,24 +3168,24 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { } while (argpt < argc) { - switch (UKPV(argpt++)) { + switch (argv[argpt++].toUint16()) { case K_DISPLAY_SET_COORDS: - area.x = UKPV(argpt++); - area.y = UKPV(argpt++); + area.x = argv[argpt++].toUint16(); + area.y = argv[argpt++].toUint16(); debugC(2, kDebugLevelGraphics, "Display: set_coords(%d, %d)\n", area.x, area.y); break; case K_DISPLAY_SET_ALIGNMENT: - halign = (gfx_alignment_t)KP_SINT(argv[argpt++]); + halign = (gfx_alignment_t)argv[argpt++].toSint16(); debugC(2, kDebugLevelGraphics, "Display: set_align(%d)\n", halign); break; case K_DISPLAY_SET_COLOR: - temp = KP_SINT(argv[argpt++]); + temp = argv[argpt++].toSint16(); debugC(2, kDebugLevelGraphics, "Display: set_color(%d)\n", temp); if ((s->resmgr->_sciVersion < SCI_VERSION_01_VGA) && temp >= 0 && temp <= 15) color0 = (s->ega_colors[temp]); @@ -3191,7 +3202,7 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_DISPLAY_SET_BGCOLOR: - temp = KP_SINT(argv[argpt++]); + temp = argv[argpt++].toSint16(); debugC(2, kDebugLevelGraphics, "Display: set_bg_color(%d)\n", temp); if (s->resmgr->_sciVersion < SCI_VERSION_01_VGA && temp >= 0 && temp <= 15) bg_color = s->ega_colors[temp]; @@ -3208,20 +3219,20 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_DISPLAY_SET_GRAYTEXT: - gray = KP_SINT(argv[argpt++]); + gray = argv[argpt++].toSint16(); debugC(2, kDebugLevelGraphics, "Display: set_graytext(%d)\n", gray); break; case K_DISPLAY_SET_FONT: - font_nr = KP_UINT(argv[argpt++]); + font_nr = argv[argpt++].toUint16(); debugC(2, kDebugLevelGraphics, "Display: set_font(\"font.%03d\")\n", font_nr); break; case K_DISPLAY_WIDTH: - area.width = UKPV(argpt++); + area.width = argv[argpt++].toUint16(); if (area.width == 0) area.width = MAX_TEXT_WIDTH_MAGIC_VALUE; @@ -3236,7 +3247,7 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_DISPLAY_RESTORE_UNDER: - debugC(2, kDebugLevelGraphics, "Display: restore_under(%04x)\n", UKPV(argpt)); + debugC(2, kDebugLevelGraphics, "Display: restore_under(%04x)\n", argv[argpt].toUint16()); graph_restore_box(s, argv[argpt++]); update_immediately = true; argpt++; @@ -3250,7 +3261,7 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; default: - debugC(2, kDebugLevelGraphics, "Unknown Display() command %x\n", UKPV(argpt - 1)); + debugC(2, kDebugLevelGraphics, "Unknown Display() command %x\n", argv[argpt - 1].toUint16()); return NULL_REG; } } @@ -3281,7 +3292,7 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { assert_primary_widget_lists(s); - text_handle = gfxw_new_text(s->gfx_state, area, font_nr, text, halign, ALIGN_TOP, color0, *color1, bg_color, 0); + text_handle = gfxw_new_text(s->gfx_state, area, font_nr, s->strSplit(text).c_str(), halign, ALIGN_TOP, color0, *color1, bg_color, 0); if (!text_handle) { error("Display: Failed to create text widget"); @@ -3314,7 +3325,7 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kShowMovie(EngineState *s, int funct_nr, int argc, reg_t *argv) { const char *filename = kernel_dereference_char_pointer(s, argv[0], 0); - int framerate = UKPV(1); // FIXME: verify + int framerate = argv[1].toUint16(); // FIXME: verify int frameNr = 0; SeqDecoder seq; @@ -3367,7 +3378,7 @@ reg_t kSetVideoMode(EngineState *s, int funct_nr, int argc, reg_t *argv) { // (320x240 resolution, although the intro in KQ6 is 320x200). // Refer to http://en.wikipedia.org/wiki/Mode_X - warning("STUB: SetVideoMode %d", UKPV(0)); + warning("STUB: SetVideoMode %d", argv[0].toUint16()); return s->r_acc; } diff --git a/engines/sci/engine/kmath.cpp b/engines/sci/engine/kmath.cpp index 21fde8aeb2..e4c314c605 100644 --- a/engines/sci/engine/kmath.cpp +++ b/engines/sci/engine/kmath.cpp @@ -29,18 +29,18 @@ namespace Sci { reg_t kRandom(EngineState *s, int funct_nr, int argc, reg_t *argv) { - return make_reg(0, SKPV(0) + (int)((SKPV(1) + 1.0 - SKPV(0)) * (rand() / (RAND_MAX + 1.0)))); + return make_reg(0, argv[0].toSint16() + (int)((argv[1].toSint16() + 1.0 - argv[0].toSint16()) * (rand() / (RAND_MAX + 1.0)))); } reg_t kAbs(EngineState *s, int funct_nr, int argc, reg_t *argv) { // This is a hack, but so is the code in Hoyle1 that needs it. if (argv[0].segment) return make_reg(0, 0x3e8); // Yes people, this is an object - return make_reg(0, abs(SKPV(0))); + return make_reg(0, abs(argv[0].toSint16())); } reg_t kSqrt(EngineState *s, int funct_nr, int argc, reg_t *argv) { - return make_reg(0, (int16) sqrt((float) abs(SKPV(0)))); + return make_reg(0, (int16) sqrt((float) abs(argv[0].toSint16()))); } int get_angle(int xrel, int yrel) { @@ -66,10 +66,10 @@ int get_angle(int xrel, int yrel) { reg_t kGetAngle(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Based on behavior observed with a test program created with // SCI Studio. - int x1 = SKPV(0); - int y1 = SKPV(1); - int x2 = SKPV(2); - int y2 = SKPV(3); + int x1 = argv[0].toSint16(); + int y1 = argv[1].toSint16(); + int x2 = argv[2].toSint16(); + int y2 = argv[3].toSint16(); int xrel = x2 - x1; int yrel = y1 - y2; // y-axis is mirrored. int angle; @@ -101,29 +101,31 @@ reg_t kGetAngle(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kGetDistance(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int xrel = (int)(((float) SKPV(1) - SKPV_OR_ALT(3, 0)) / cos(SKPV_OR_ALT(5, 0) * PI / 180.0)); // This works because cos(0)==1 - int yrel = SKPV(0) - SKPV_OR_ALT(2, 0); - + int xdiff = (argc > 3) ? argv[3].toSint16() : 0; + int ydiff = (argc > 2) ? argv[2].toSint16() : 0; + int angle = (argc > 5) ? argv[5].toSint16() : 0; + int xrel = (int)(((float) argv[1].toSint16() - xdiff) / cos(angle * PI / 180.0)); // This works because cos(0)==1 + int yrel = argv[0].toSint16() - ydiff; return make_reg(0, (int16)sqrt((float) xrel*xrel + yrel*yrel)); } reg_t kTimesSin(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int angle = SKPV(0); - int factor = SKPV(1); + int angle = argv[0].toSint16(); + int factor = argv[1].toSint16(); return make_reg(0, (int)(factor * 1.0 * sin(angle * PI / 180.0))); } reg_t kTimesCos(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int angle = SKPV(0); - int factor = SKPV(1); + int angle = argv[0].toSint16(); + int factor = argv[1].toSint16(); return make_reg(0, (int)(factor * 1.0 * cos(angle * PI / 180.0))); } reg_t kCosDiv(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int angle = SKPV(0); - int value = SKPV(1); + int angle = argv[0].toSint16(); + int value = argv[1].toSint16(); double cosval = cos(angle * PI / 180.0); if ((cosval < 0.0001) && (cosval > 0.0001)) { @@ -134,8 +136,8 @@ reg_t kCosDiv(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kSinDiv(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int angle = SKPV(0); - int value = SKPV(1); + int angle = argv[0].toSint16(); + int value = argv[1].toSint16(); double sinval = sin(angle * PI / 180.0); if ((sinval < 0.0001) && (sinval > 0.0001)) { @@ -146,8 +148,8 @@ reg_t kSinDiv(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kTimesTan(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int param = SKPV(0); - int scale = SKPV_OR_ALT(1, 1); + int param = argv[0].toSint16(); + int scale = (argc > 1) ? argv[1].toSint16() : 1; param -= 90; if ((param % 90) == 0) { @@ -158,8 +160,8 @@ reg_t kTimesTan(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kTimesCot(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int param = SKPV(0); - int scale = SKPV_OR_ALT(1, 1); + int param = argv[0].toSint16(); + int scale = (argc > 1) ? argv[1].toSint16() : 1; if ((param % 90) == 0) { warning("Attempted tan(pi/2)"); diff --git a/engines/sci/engine/kmenu.cpp b/engines/sci/engine/kmenu.cpp index 121333a6e3..c65d201b90 100644 --- a/engines/sci/engine/kmenu.cpp +++ b/engines/sci/engine/kmenu.cpp @@ -46,11 +46,11 @@ reg_t kAddMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kSetMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int index = UKPV(0); + int index = argv[0].toUint16(); int i = 2; while (i < argc) { - s->_menubar->setAttribute(s, (index >> 8) - 1, (index & 0xff) - 1, UKPV(i - 1), argv[i]); + s->_menubar->setAttribute(s, (index >> 8) - 1, (index & 0xff) - 1, argv[i - 1].toUint16(), argv[i]); i += 2; } @@ -58,16 +58,16 @@ reg_t kSetMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kGetMenu(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int index = UKPV(0); + int index = argv[0].toUint16(); - return s->_menubar->getAttribute((index >> 8) - 1, (index & 0xff) - 1, UKPV(1)); + return s->_menubar->getAttribute((index >> 8) - 1, (index & 0xff) - 1, argv[1].toUint16()); } reg_t kDrawStatus(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t text = argv[0]; - int fgcolor = SKPV_OR_ALT(1, s->status_bar_foreground); - int bgcolor = SKPV_OR_ALT(2, s->status_bar_background); + int fgcolor = (argc > 1) ? argv[1].toSint16() : s->status_bar_foreground; + int bgcolor = (argc > 2) ? argv[2].toSint16() : s->status_bar_background; s->titlebar_port->_color.visual = get_pic_color(s, fgcolor); s->titlebar_port->_color.mask = GFX_MASK_VISUAL; @@ -92,7 +92,7 @@ reg_t kDrawStatus(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kDrawMenuBar(EngineState *s, int funct_nr, int argc, reg_t *argv) { - if (SKPV(0)) + if (argv[0].toSint16()) sciw_set_menubar(s, s->titlebar_port, s->_menubar, -1); else sciw_set_status_bar(s, s->titlebar_port, "", 0, 0); @@ -125,7 +125,7 @@ static int _menu_go_down(Menubar *menubar, int menu_nr, int item_nr) { reg_t kMenuSelect(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t event = argv[0]; - /*int pause_sound = UKPV_OR_ALT(1, 1);*/ /* FIXME: Do this eventually */ + /*int pause_sound = (argc > 1) ? argv[1].toUint16() : 1;*/ /* FIXME: Do this eventually */ bool claimed = false; int type = GET_SEL32V(event, type); int message = GET_SEL32V(event, message); diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 2e86362404..98fba97f0e 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -52,7 +52,7 @@ reg_t kGameIsRestarting(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->r_acc = make_reg(0, (s->restarting_flags & SCI_GAME_WAS_RESTARTED)); if (argc) { // Only happens during replay - if (!UKPV(0)) // Set restarting flag + if (!argv[0].toUint16()) // Set restarting flag s->restarting_flags &= ~SCI_GAME_WAS_RESTARTED; } @@ -89,14 +89,15 @@ reg_t k_Unknown(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kFlushResources(EngineState *s, int funct_nr, int argc, reg_t *argv) { run_gc(s); - debugC(2, kDebugLevelRoom, "Entering room number %d", UKPV(0)); + debugC(2, kDebugLevelRoom, "Entering room number %d", argv[0].toUint16()); return s->r_acc; } reg_t kSetDebug(EngineState *s, int funct_nr, int argc, reg_t *argv) { sciprintf("Debug mode activated\n"); - g_debug_seeking = g_debug_step_running = 0; + debugState.seeking = kDebugSeekNothing; + debugState.runningStep = 0; return s->r_acc; } @@ -127,7 +128,7 @@ reg_t kGetTime(EngineState *s, int funct_nr, int argc, reg_t *argv) { return make_reg(0, retval); } - int mode = argc > 0 ? UKPV_OR_ALT(0, 0) : 0; + int mode = (argc > 0) ? argv[0].toUint16() : 0; switch (mode) { case _K_NEW_GETTIME_TICKS : @@ -164,15 +165,15 @@ enum { }; reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) { - switch (UKPV(0)) { + switch (argv[0].toUint16()) { case K_MEMORY_ALLOCATE_CRITICAL : - if (!s->seg_manager->allocDynmem(UKPV(1), "kMemory() critical", &s->r_acc)) { + if (!s->seg_manager->allocDynmem(argv[1].toUint16(), "kMemory() critical", &s->r_acc)) { error("Critical heap allocation failed"); } return s->r_acc; break; case K_MEMORY_ALLOCATE_NONCRITICAL : - s->seg_manager->allocDynmem(UKPV(1), "kMemory() non-critical", &s->r_acc); + s->seg_manager->allocDynmem(argv[1].toUint16(), "kMemory() non-critical", &s->r_acc); break; case K_MEMORY_FREE : if (s->seg_manager->freeDynmem(argv[1])) { @@ -180,7 +181,7 @@ reg_t kMemory(EngineState *s, int funct_nr, int argc, reg_t *argv) { } break; case K_MEMORY_MEMCPY : { - int size = UKPV(3); + int size = argv[3].toUint16(); byte *dest = kernel_dereference_bulk_pointer(s, argv[1], size); byte *src = kernel_dereference_bulk_pointer(s, argv[2], size); diff --git a/engines/sci/engine/kmovement.cpp b/engines/sci/engine/kmovement.cpp index b116fa4093..20a7be3aea 100644 --- a/engines/sci/engine/kmovement.cpp +++ b/engines/sci/engine/kmovement.cpp @@ -70,9 +70,9 @@ used in an iterative stepping algorithm reg_t kSetJump(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Input data reg_t object = argv[0]; - int dx = SKPV(1); - int dy = SKPV(2); - int gy = SKPV(3); + int dx = argv[1].toSint16(); + int dy = argv[2].toSint16(); + int gy = argv[3].toSint16(); // Derived data int c; @@ -223,8 +223,9 @@ reg_t kInitBresen(EngineState *s, int funct_nr, int argc, reg_t *argv) { int deltax = GET_SEL32SV(mover, x) - GET_SEL32SV(client, x); int deltay = GET_SEL32SV(mover, y) - GET_SEL32SV(client, y); + int step_factor = (argc < 1) ? argv[1].toUint16() : 1; - initialize_bresen(s, argc, argv, mover, KP_UINT(KP_ALT(1, make_reg(0, 1))), deltax, deltay); + initialize_bresen(s, argc, argv, mover, step_factor, deltax, deltay); return s->r_acc; } diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp index 3f0af0b538..c254875230 100644 --- a/engines/sci/engine/kpathing.cpp +++ b/engines/sci/engine/kpathing.cpp @@ -48,8 +48,8 @@ static void POLY_SET_POINT(byte *p, int i, const Common::Point &pt) { } static void POLY_GET_POINT_REG_T(const reg_t *p, int i, Common::Point &pt) { - pt.x = KP_SINT((p)[(i) * 2]); - pt.y = KP_SINT((p)[(i) * 2 + 1]); + pt.x = (p)[(i) * 2].toUint16(); + pt.y = (p)[(i) * 2 + 1].toUint16(); } // SCI-defined polygon types @@ -286,13 +286,13 @@ static Common::Point read_point(const byte *list, int is_reg_t, int offset) { */ static bool polygons_equal(EngineState *s, reg_t p1, reg_t p2) { // Check for same type - if (KP_UINT(GET_SEL32(p1, type)) != KP_UINT(GET_SEL32(p2, type))) + if (GET_SEL32(p1, type).toUint16() != GET_SEL32(p2, type).toUint16()) return false; - int size = KP_UINT(GET_SEL32(p1, size)); + int size = GET_SEL32(p1, size).toUint16(); // Check for same number of points - if (size != KP_UINT(GET_SEL32(p2, size))) + if (size != GET_SEL32(p2, size).toUint16()) return false; const byte *p1_points = kernel_dereference_bulk_pointer(s, GET_SEL32(p1, points), size * POLY_POINT_SIZE); @@ -356,8 +356,8 @@ static void draw_point(EngineState *s, Common::Point p, int start) { static void draw_polygon(EngineState *s, reg_t polygon) { reg_t points = GET_SEL32(polygon, points); - int size = KP_UINT(GET_SEL32(polygon, size)); - int type = KP_UINT(GET_SEL32(polygon, type)); + int size = GET_SEL32(polygon, size).toUint16(); + int type = GET_SEL32(polygon, type).toUint16(); Common::Point first, prev; const byte *list = kernel_dereference_bulk_pointer(s, points, size * POLY_POINT_SIZE); int is_reg_t = polygon_is_reg_t(list, size); @@ -403,8 +403,8 @@ static void draw_input(EngineState *s, reg_t poly_list, Common::Point start, Com static void print_polygon(EngineState *s, reg_t polygon) { reg_t points = GET_SEL32(polygon, points); - int size = KP_UINT(GET_SEL32(polygon, size)); - int type = KP_UINT(GET_SEL32(polygon, type)); + int size = GET_SEL32(polygon, size).toUint16(); + int type = GET_SEL32(polygon, type).toUint16(); int i; const byte *point_array = kernel_dereference_bulk_pointer(s, points, size * POLY_POINT_SIZE); int is_reg_t = polygon_is_reg_t(point_array, size); @@ -1228,9 +1228,9 @@ static Polygon *convert_polygon(EngineState *s, reg_t polygon) { // Returns : (Polygon *) The converted polygon int i; reg_t points = GET_SEL32(polygon, points); - int size = KP_UINT(GET_SEL32(polygon, size)); + int size = GET_SEL32(polygon, size).toUint16(); const byte *list = kernel_dereference_bulk_pointer(s, points, size * POLY_POINT_SIZE); - Polygon *poly = new Polygon(KP_UINT(GET_SEL32(polygon, type))); + Polygon *poly = new Polygon(GET_SEL32(polygon, type).toUint16()); int is_reg_t = polygon_is_reg_t(list, size); // WORKAROUND: broken polygon in LSL1VGA, room 350, after opening elevator @@ -1388,7 +1388,7 @@ static PathfindingState *convert_polygon_set(EngineState *s, reg_t poly_list, Co // Polygon is not a duplicate, so convert it polygon = convert_polygon(s, node->value); pf_s->polygons.push_back(polygon); - count += KP_UINT(GET_SEL32(node->value, size)); + count += GET_SEL32(node->value, size).toUint16(); } node = lookup_node(s, node->succ); @@ -1642,7 +1642,7 @@ static reg_t output_path(PathfindingState *p, EngineState *s) { } reg_t kAvoidPath(EngineState *s, int funct_nr, int argc, reg_t *argv) { - Common::Point start = Common::Point(SKPV(0), SKPV(1)); + Common::Point start = Common::Point(argv[0].toSint16(), argv[1].toSint16()); #ifdef DEBUG_AVOIDPATH GfxPort *port = s->picture_port; @@ -1669,10 +1669,10 @@ reg_t kAvoidPath(EngineState *s, int funct_nr, int argc, reg_t *argv) { } case 6 : case 7 : { - Common::Point end = Common::Point(SKPV(2), SKPV(3)); + Common::Point end = Common::Point(argv[2].toSint16(), argv[3].toSint16()); reg_t poly_list = argv[4]; - //int poly_list_size = UKPV(5); - int opt = UKPV_OR_ALT(6, 1); + //int poly_list_size = argv[5].toUint16(); + int opt = (argc > 6) ? argv[6].toUint16() : 1; reg_t output; PathfindingState *p; diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index e400cb0827..d82f8ff132 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -32,16 +32,16 @@ namespace Sci { reg_t read_selector(EngineState *s, reg_t object, Selector selector_id, const char *file, int line) { - reg_t *address; + ObjVarRef address; if (lookup_selector(s, object, selector_id, &address, NULL) != kSelectorVariable) return NULL_REG; else - return *address; + return *address.getPointer(s); } void write_selector(EngineState *s, reg_t object, Selector selector_id, reg_t value, const char *fname, int line) { - reg_t *address; + ObjVarRef address; if ((selector_id < 0) || (selector_id > (int)s->_kernel->getSelectorNamesSize())) { warning("Attempt to write to invalid selector %d of" @@ -53,7 +53,7 @@ void write_selector(EngineState *s, reg_t object, Selector selector_id, reg_t va warning("Selector '%s' of object at %04x:%04x could not be" " written to (%s L%d)", s->_kernel->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line); else - *address = value; + *address.getPointer(s) = value; } int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvocation noinvalid, int kfunct, @@ -114,8 +114,8 @@ bool is_object(EngineState *s, reg_t object) { // Loads arbitrary resources of type 'restype' with resource numbers 'resnrs' // This implementation ignores all resource numbers except the first one. reg_t kLoad(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int restype = KP_UINT(argv[0]); - int resnr = KP_UINT(argv[1]); + int restype = argv[0].toUint16(); + int resnr = argv[1].toUint16(); // Request to dynamically allocate hunk memory for later use if (restype == kResourceTypeMemory) @@ -125,19 +125,27 @@ reg_t kLoad(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kLock(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int restype = UKPV(0) & 0x7f; - int resnr = UKPV(1); - int state = argc > 2 ? UKPV(2) : 1; + int state = argc > 2 ? argv[2].toUint16() : 1; + ResourceType type = (ResourceType)(argv[0].toUint16() & 0x7f); + ResourceId id = ResourceId(type, argv[1].toUint16()); Resource *which; switch (state) { case 1 : - s->resmgr->findResource((ResourceType)restype, resnr, 1); + s->resmgr->findResource(id, 1); break; case 0 : - which = s->resmgr->findResource((ResourceType)restype, resnr, 0); - s->resmgr->unlockResource(which, resnr, (ResourceType)restype); + which = s->resmgr->findResource(id, 0); + + if (which) + s->resmgr->unlockResource(which); + else { + if (id.type == kResourceTypeInvalid) + warning("[Resmgr] Attempt to unlock resource %i of invalid type %i", id.number, type); + else + warning("[Resmgr] Attempt to unlock non-existant resource %s", id.toString().c_str()); + } break; } return s->r_acc; @@ -145,7 +153,7 @@ reg_t kLock(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Unloads an arbitrary resource of type 'restype' with resource numbber 'resnr' reg_t kUnLoad(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int restype = KP_UINT(argv[0]); + int restype = argv[0].toUint16(); reg_t resnr = argv[1]; if (restype == kResourceTypeMemory) @@ -155,26 +163,23 @@ reg_t kUnLoad(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kResCheck(EngineState *s, int funct_nr, int argc, reg_t *argv) { - ResourceType restype = (ResourceType)(UKPV(0) & 0x7f); - - switch (restype) { - case kResourceTypeAudio36: - case kResourceTypeSync36: { - assert(argc >= 6); - - uint module = UKPV(1); - uint noun = UKPV(2); - uint verb = UKPV(3); - uint cond = UKPV(4); - uint seq = UKPV(5); - warning("ResCheck: checking for currently unsupported %s resource: module %i; tuple (%i, %i, %i, %i)", - getResourceTypeName(restype), module, noun, verb, cond, seq); - return make_reg(0, 1); - } - default: - Resource *res = s->resmgr->testResource(restype, UKPV(1)); - return make_reg(0, res != NULL); + Resource *res = NULL; + ResourceType restype = (ResourceType)(argv[0].toUint16() & 0x7f); + + if ((restype == kResourceTypeAudio36) || (restype == kResourceTypeSync36)) { + if (argc >= 6) { + uint noun = argv[2].toUint16() & 0xff; + uint verb = argv[3].toUint16() & 0xff; + uint cond = argv[4].toUint16() & 0xff; + uint seq = argv[5].toUint16() & 0xff; + + res = s->resmgr->testResource(ResourceId(restype, argv[1].toUint16(), noun, verb, cond, seq)); + } + } else { + res = s->resmgr->testResource(ResourceId(restype, argv[1].toUint16())); } + + return make_reg(0, res != NULL); } reg_t kClone(EngineState *s, int funct_nr, int argc, reg_t *argv) { @@ -252,8 +257,8 @@ reg_t kDisposeClone(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Returns script dispatch address index in the supplied script reg_t kScriptID(EngineState *s, int funct_nr, int argc, reg_t *argv) { - int script = KP_UINT(argv[0]); - int index = KP_UINT(KP_ALT(1, NULL_REG)); + int script = argv[0].toUint16(); + int index = (argc > 1) ? argv[1].toUint16() : 0; SegmentId scriptid = script_get_segment(s, script, SCRIPT_GET_LOAD); Script *scr; @@ -313,7 +318,7 @@ reg_t kIsObject(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kRespondsTo(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t obj = argv[0]; - int selector = KP_UINT(argv[1]); + int selector = argv[1].toUint16(); return make_reg(0, is_heap_object(s, obj) && lookup_selector(s, obj, selector, NULL, NULL) != kSelectorNone); } diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index b0fbda36f9..bb27589d84 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -123,7 +123,7 @@ enum AudioSyncCommands { static void script_set_priority(EngineState *s, reg_t obj, int priority) { int song_nr = GET_SEL32V(obj, number); - Resource *song = s->resmgr->findResource(kResourceTypeSound, song_nr, 0); + Resource *song = s->resmgr->findResource(ResourceId(kResourceTypeSound, song_nr), 0); int flags = GET_SEL32V(obj, flags); if (priority == -1) { @@ -140,7 +140,7 @@ static void script_set_priority(EngineState *s, reg_t obj, int priority) { } SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, songit_id_t id) { - Resource *song = s->resmgr->findResource(kResourceTypeSound, song_nr, 0); + Resource *song = s->resmgr->findResource(ResourceId(kResourceTypeSound, song_nr), 0); if (!song) return NULL; @@ -151,7 +151,7 @@ SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, void process_sound_events(EngineState *s) { /* Get all sound events, apply their changes to the heap */ int result; - song_handle_t handle; + SongHandle handle; int cue; if (s->_version >= SCI_VERSION_01) @@ -202,9 +202,9 @@ void process_sound_events(EngineState *s) { /* Get all sound events, apply their reg_t kDoSound_SCI0(EngineState *s, int funct_nr, int argc, reg_t *argv) { - reg_t obj = KP_ALT(1, NULL_REG); - uint16 command = UKPV(0); - song_handle_t handle = FROBNICATE_HANDLE(obj); + reg_t obj = (argc > 1) ? argv[1] : NULL_REG; + uint16 command = argv[0].toUint16(); + SongHandle handle = FROBNICATE_HANDLE(obj); int number = obj.segment ? GET_SEL32V(obj, number) : -1; /* We were not going to use it anyway */ @@ -335,7 +335,7 @@ reg_t kDoSound_SCI0(EngineState *s, int funct_nr, int argc, reg_t *argv) { case _K_SCI0_SOUND_VOLUME: { /* range from 0x0 to 0xf */ /* parameter optional. If present, set.*/ - int vol = SKPV_OR_ALT(1, -1); + int vol = (argc > 1) ? argv[1].toSint16() : -1; if (vol != -1) s->_sound.sfx_set_volume(vol << 0xf); @@ -381,9 +381,9 @@ reg_t kDoSound_SCI0(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { - uint16 command = UKPV(0); - reg_t obj = KP_ALT(1, NULL_REG); - song_handle_t handle = FROBNICATE_HANDLE(obj); + uint16 command = argv[0].toUint16(); + reg_t obj = (argc > 1) ? argv[1] : NULL_REG; + SongHandle handle = FROBNICATE_HANDLE(obj); int number = obj.segment ? GET_SEL32V(obj, number) : -1; /* We were not going to use it anyway */ @@ -456,7 +456,7 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { switch (command) { case _K_SCI01_SOUND_MASTER_VOLME : { - int vol = SKPV_OR_ALT(1, -1); + int vol = (argc > 1) ? argv[1].toSint16() : -1; if (vol != -1) s->_sound.sfx_set_volume(vol << 0xf); @@ -487,13 +487,13 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { int looping = GET_SEL32V(obj, loop); //int vol = GET_SEL32V(obj, vol); int pri = GET_SEL32V(obj, pri); - RESTORE_BEHAVIOR rb = (RESTORE_BEHAVIOR) UKPV(2); /* Too lazy to look up a default value for this */ + RESTORE_BEHAVIOR rb = (RESTORE_BEHAVIOR) argv[2].toUint16(); /* Too lazy to look up a default value for this */ if (obj.segment) { s->_sound.sfx_song_set_status(handle, SOUND_STATUS_PLAYING); s->_sound.sfx_song_set_loops(handle, looping); s->_sound.sfx_song_renice(handle, pri); - song_lib_set_restore_behavior(s->_sound._songlib, handle, rb); + s->_sound._songlib.setSongRestoreBehavior(handle, rb); } break; @@ -503,7 +503,7 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { //int vol = GET_SEL32V(obj, vol); //int pri = GET_SEL32V(obj, pri); - if (obj.segment && (s->resmgr->testResource(kResourceTypeSound, number))) { + if (obj.segment && (s->resmgr->testResource(ResourceId(kResourceTypeSound, number)))) { sciprintf("Initializing song number %d\n", number); s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1, handle), 0, handle, number); @@ -551,7 +551,7 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case _K_SCI01_SOUND_SUSPEND_HANDLE : { - int state = UKPV(2); + int state = argv[2].toUint16(); int setstate = (state) ? SOUND_STATUS_SUSPENDED : SOUND_STATUS_PLAYING; @@ -647,12 +647,12 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case _K_SCI01_SOUND_MIDI_SEND : { - int channel = SKPV(2); - int midiCmd = UKPV(3) == 0xff ? + int channel = argv[2].toSint16(); + int midiCmd = argv[3].toUint16() == 0xff ? 0xe0 : /* Pitch wheel */ - 0xb0; /* UKPV(3) is actually a controller number */ - int controller = UKPV(3); - int param = UKPV(4); + 0xb0; /* argv[3].toUint16() is actually a controller number */ + int controller = argv[3].toUint16(); + int param = argv[4].toUint16(); s->_sound.sfx_send_midi(handle, channel, midiCmd, controller, param); @@ -662,7 +662,7 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case _K_SCI01_SOUND_HOLD : { - //int flag = SKPV(2); + //int flag = argv[2].toSint16(); break; } } @@ -671,9 +671,9 @@ reg_t kDoSound_SCI01(EngineState *s, int funct_nr, int argc, reg_t *argv) { } reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { - uint16 command = UKPV(0); - reg_t obj = KP_ALT(1, NULL_REG); - song_handle_t handle = FROBNICATE_HANDLE(obj); + uint16 command = argv[0].toUint16(); + reg_t obj = (argc > 1) ? argv[1] : NULL_REG; + SongHandle handle = FROBNICATE_HANDLE(obj); int number = obj.segment ? GET_SEL32V(obj, number) : -1; /* We were not going to use it anyway */ @@ -798,16 +798,16 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { int looping = GET_SEL32V(obj, loop); //int vol = GET_SEL32V(obj, vol); int pri = GET_SEL32V(obj, pri); - song_t *song = song_lib_find(s->_sound._songlib, handle); + Song *song = s->_sound._songlib.findSong(handle); - if (GET_SEL32V(obj, nodePtr) && (song && number != song->resource_num)) { + if (GET_SEL32V(obj, nodePtr) && (song && number != song->_resourceNum)) { s->_sound.sfx_song_set_status(handle, SOUND_STATUS_STOPPED); s->_sound.sfx_remove_song(handle); PUT_SEL32(obj, nodePtr, NULL_REG); } if (!GET_SEL32V(obj, nodePtr) && obj.segment) { - if (!s->resmgr->testResource(kResourceTypeSound, number)) { + if (!s->resmgr->testResource(ResourceId(kResourceTypeSound, number))) { sciprintf("Could not open song number %d\n", number); return NULL_REG; } @@ -837,7 +837,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { s->_sound.sfx_remove_song(handle); } - if (obj.segment && (s->resmgr->testResource(kResourceTypeSound, number))) { + if (obj.segment && (s->resmgr->testResource(ResourceId(kResourceTypeSound, number)))) { sciprintf("Initializing song number %d\n", number); s->_sound.sfx_add_song(build_iterator(s, number, SCI_SONG_ITERATOR_TYPE_SCI1, handle), 0, handle, number); @@ -866,10 +866,10 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { case _K_SCI1_SOUND_FADE_HANDLE : { fade_params_t fade; if (obj.segment) { - fade.final_volume = UKPV(2); - fade.ticks_per_step = UKPV(3); - fade.step_size = UKPV(4); - fade.action = UKPV(5) ? + fade.final_volume = argv[2].toUint16(); + fade.ticks_per_step = argv[3].toUint16(); + fade.step_size = argv[4].toUint16(); + fade.action = argv[5].toUint16() ? FADE_ACTION_FADE_AND_STOP : FADE_ACTION_FADE_AND_CONT; @@ -877,7 +877,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { /* FIXME: The next couple of lines actually STOP the handle, rather ** than fading it! */ - if (UKPV(5)) { + if (argv[5].toUint16()) { PUT_SEL32V(obj, signal, -1); PUT_SEL32V(obj, nodePtr, 0); PUT_SEL32V(obj, handle, 0); @@ -890,7 +890,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case _K_SCI1_SOUND_HOLD_HANDLE : { - int value = SKPV(2); + int value = argv[2].toSint16(); s->_sound.sfx_song_set_hold(handle, value); break; @@ -902,7 +902,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { break; } case _K_SCI1_SOUND_SET_HANDLE_PRIORITY : { - int value = SKPV(2); + int value = argv[2].toSint16(); script_set_priority(s, obj, value); break; @@ -950,7 +950,7 @@ reg_t kDoSound_SCI1(EngineState *s, int funct_nr, int argc, reg_t *argv) { } case _K_SCI1_SOUND_MIDI_SEND : { s->_sound.sfx_send_midi(handle, - UKPV(2), UKPV(3), UKPV(4), UKPV(5)); + argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), argv[5].toUint16()); break; } case _K_SCI1_SOUND_REVERB : { @@ -975,109 +975,120 @@ reg_t kDoSound(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Used for speech playback in CD games reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) { Audio::Mixer *mixer = g_system->getMixer(); - int sampleLen = 0; - if (!s->_sound._audioResource) - s->_sound._audioResource = new AudioResource(s->resmgr, s->_version); - - switch (UKPV(0)) { + switch (argv[0].toUint16()) { case kSciAudioWPlay: - case kSciAudioPlay: - s->_sound._audioResource->stop(); - - if (argc == 2) { // KQ5CD, KQ6 floppy - Audio::AudioStream *audioStream = s->_sound._audioResource->getAudioStream(UKPV(1), 65535, &sampleLen); - - if (audioStream) - mixer->playInputStream(Audio::Mixer::kSpeechSoundType, s->_sound._audioResource->getAudioHandle(), audioStream); - } else if (argc == 6) { // SQ4CD or newer - //uint32 volume = UKPV(1); - // Make a BE number - uint32 audioNumber = (((UKPV(2) & 0xFF) << 24) & 0xFF000000) | - (((UKPV(3) & 0xFF) << 16) & 0x00FF0000) | - (((UKPV(4) & 0xFF) << 8) & 0x0000FF00) | - ( (UKPV(5) & 0xFF) & 0x000000FF); - - printf("%d %d %d %d -> %d\n", UKPV(2), UKPV(3), UKPV(4), UKPV(5), audioNumber); // debugging - - Audio::AudioStream *audioStream = s->_sound._audioResource->getAudioStream(audioNumber, UKPV(1), &sampleLen); - - if (audioStream) - mixer->playInputStream(Audio::Mixer::kSpeechSoundType, s->_sound._audioResource->getAudioHandle(), audioStream); - } else { // Hopefully, this should never happen + case kSciAudioPlay: { + uint16 module; + uint32 number; + + s->_sound.stopAudio(); + + if (argc == 2) { + module = 65535; + number = argv[1].toUint16(); + } else if (argc == 6) { + module = argv[1].toUint16(); + number = ((argv[2].toUint16() & 0xff) << 24) | ((argv[3].toUint16() & 0xff) << 16) | + ((argv[4].toUint16() & 0xff) << 8) | (argv[5].toUint16() & 0xff); + } else { warning("kDoAudio: Play called with an unknown number of parameters (%d)", argc); + return NULL_REG; } - return make_reg(0, sampleLen); // return sample length in ticks + + return make_reg(0, s->_sound.startAudio(module, number)); // return sample length in ticks + } case kSciAudioStop: - s->_sound._audioResource->stop(); + s->_sound.stopAudio(); break; case kSciAudioPause: - s->_sound._audioResource->pause(); + s->_sound.pauseAudio(); break; case kSciAudioResume: - s->_sound._audioResource->resume(); + s->_sound.resumeAudio(); break; case kSciAudioPosition: - return make_reg(0, s->_sound._audioResource->getAudioPosition()); + return make_reg(0, s->_sound.getAudioPosition()); case kSciAudioRate: - s->_sound._audioResource->setAudioRate(UKPV(1)); + s->_sound.setAudioRate(argv[1].toUint16()); break; case kSciAudioVolume: - mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, UKPV(1)); + mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, argv[1].toUint16()); break; case kSciAudioLanguage: if (argc == 1) { // In SCI1.1: tests for digital audio support return make_reg(0, 1); } else { - s->_sound._audioResource->setAudioLang(SKPV(1)); + s->resmgr->setAudioLanguage(argv[1].toSint16()); } break; default: - warning("kDoAudio: Unhandled case %d", UKPV(0)); + warning("kDoAudio: Unhandled case %d", argv[0].toUint16()); } return s->r_acc; } reg_t kDoSync(EngineState *s, int funct_nr, int argc, reg_t *argv) { - switch (UKPV(0)) { - case kSciAudioSyncStart: - if (argc == 3) { // KQ5CD, KQ6 floppy - if (s->_sound._soundSync) { - s->resmgr->unlockResource(s->_sound._soundSync, s->_sound._soundSync->number, kResourceTypeSync); - } + switch (argv[0].toUint16()) { + case kSciAudioSyncStart: { + ResourceId id; - // Load sound sync resource and lock it - s->_sound._soundSync = (ResourceSync *)s->resmgr->findResource(kResourceTypeSync, UKPV(2), 1); + if (s->_sound._syncResource) { + s->resmgr->unlockResource(s->_sound._syncResource); + s->_sound._syncResource = NULL; + } - if (s->_sound._soundSync) { - s->_sound._soundSync->startSync(s, argv[1]); - } else { - // Notify the scripts to stop sound sync - PUT_SEL32V(argv[1], syncCue, -1); - } - } else if (argc == 7) { // SQ4CD or newer - // TODO - warning("kDoSync: Start called with new semantics - 6 parameters: %d %d %d %d %d %d", UKPV(1), UKPV(2), UKPV(3), UKPV(4), UKPV(5), UKPV(6)); - } else { // Hopefully, this should never happen + // Load sound sync resource and lock it + if (argc == 3) { + id = ResourceId(kResourceTypeSync, argv[2].toUint16()); + } else if (argc == 7) { + id = ResourceId(kResourceTypeSync36, argv[2].toUint16(), argv[3].toUint16(), argv[4].toUint16(), + argv[5].toUint16(), argv[6].toUint16()); + } else { warning("kDoSync: Start called with an unknown number of parameters (%d)", argc); + return s->r_acc; + } + + s->_sound._syncResource = s->resmgr->findResource(id, 1); + + if (s->_sound._syncResource) { + PUT_SEL32V(argv[1], syncCue, 0); + s->_sound._syncOffset = 0; + } else { + warning("DoSync: failed to find resource %s", id.toString().c_str()); + // Notify the scripts to stop sound sync + PUT_SEL32V(argv[1], syncCue, -1); } break; - case kSciAudioSyncNext: - if (s->_sound._soundSync) { - s->_sound._soundSync->nextSync(s, argv[1]); + } + case kSciAudioSyncNext: { + Resource *res = s->_sound._syncResource; + if (res && (s->_sound._syncOffset < res->size - 1)) { + int16 syncCue = -1; + int16 syncTime = (int16)READ_LE_UINT16(res->data + s->_sound._syncOffset); + + s->_sound._syncOffset += 2; + + if ((syncTime != -1) && (s->_sound._syncOffset < res->size - 1)) { + syncCue = (int16)READ_LE_UINT16(res->data + s->_sound._syncOffset); + s->_sound._syncOffset += 2; + } + + PUT_SEL32V(argv[1], syncTime, syncTime); + PUT_SEL32V(argv[1], syncCue, syncCue); } break; + } case kSciAudioSyncStop: - if (s->_sound._soundSync) { - s->_sound._soundSync->stopSync(); - s->resmgr->unlockResource(s->_sound._soundSync, s->_sound._soundSync->number, kResourceTypeSync); - s->_sound._soundSync = NULL; + if (s->_sound._syncResource) { + s->resmgr->unlockResource(s->_sound._syncResource); + s->_sound._syncResource = NULL; } break; default: - warning("kDoSync: Unhandled case %d", UKPV(0)); + warning("DoSync: Unhandled subfunction %d", argv[0].toUint16()); } return s->r_acc; diff --git a/engines/sci/engine/kstring.cpp b/engines/sci/engine/kstring.cpp index 3898664921..2a30a103b6 100644 --- a/engines/sci/engine/kstring.cpp +++ b/engines/sci/engine/kstring.cpp @@ -48,7 +48,7 @@ char *kernel_lookup_text(EngineState *s, reg_t address, int index) { else { int textlen; int _index = index; - textres = s->resmgr->findResource(kResourceTypeText, address.offset, 0); + textres = s->resmgr->findResource(ResourceId(kResourceTypeText, address.offset), 0); if (!textres) { error("text.%03d not found", address.offset); @@ -281,7 +281,7 @@ reg_t kStrCmp(EngineState *s, int funct_nr, int argc, reg_t *argv) { char *s2 = kernel_dereference_char_pointer(s, argv[1], 0); if (argc > 2) - return make_reg(0, strncmp(s1, s2, UKPV(2))); + return make_reg(0, strncmp(s1, s2, argv[2].toUint16())); else return make_reg(0, strcmp(s1, s2)); } @@ -304,7 +304,7 @@ reg_t kStrCpy(EngineState *s, int funct_nr, int argc, reg_t *argv) { } if (argc > 2) { - int length = SKPV(2); + int length = argv[2].toSint16(); if (length >= 0) strncpy(dest, src, length); @@ -376,19 +376,19 @@ reg_t kStrAt(EngineState *s, int funct_nr, int argc, reg_t *argv) { ((strlen(dst) < 2) || (!lsl5PasswordWorkaround && !is_print_str(dst)))) { // SQ4 array handling detected #ifndef SCUMM_BIG_ENDIAN - int odd = KP_UINT(argv[1]) & 1; + int odd = argv[1].toUint16() & 1; #else - int odd = !(KP_UINT(argv[1]) & 1); + int odd = !(argv[1].toUint16() & 1); #endif - dest2 = ((reg_t *) dest) + (KP_UINT(argv[1]) / 2); + dest2 = ((reg_t *) dest) + (argv[1].toUint16() / 2); dest = ((byte *)(&dest2->offset)) + odd; } else - dest += KP_UINT(argv[1]); + dest += argv[1].toUint16(); s->r_acc = make_reg(0, *dest); if (argc > 2) - *dest = KP_SINT(argv[2]); /* Request to modify this char */ + *dest = argv[2].toSint16(); /* Request to modify this char */ return s->r_acc; } @@ -423,7 +423,7 @@ reg_t kFormat(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t dest = argv[0]; char *target = (char *) kernel_dereference_bulk_pointer(s, dest, 0); reg_t position = argv[1]; /* source */ - int index = UKPV(2); + int index = argv[2].toUint16(); char *source; char *str_base = target; int mode = 0; @@ -452,7 +452,7 @@ reg_t kFormat(EngineState *s, int funct_nr, int argc, reg_t *argv) { #endif for (i = startarg; i < argc; i++) - arguments[i-startarg] = UKPV(i); /* Parameters are copied to prevent overwriting */ + arguments[i-startarg] = argv[i].toUint16(); /* Parameters are copied to prevent overwriting */ while ((xfer = *source++)) { if (xfer == '%') { @@ -646,13 +646,13 @@ reg_t kStrLen(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kGetFarText(EngineState *s, int funct_nr, int argc, reg_t *argv) { - Resource *textres = s->resmgr->findResource(kResourceTypeText, UKPV(0), 0); + Resource *textres = s->resmgr->findResource(ResourceId(kResourceTypeText, argv[0].toUint16()), 0); char *seeker; - int counter = UKPV(1); + int counter = argv[1].toUint16(); if (!textres) { - error("text.%d does not exist", UKPV(0)); + error("text.%d does not exist", argv[0].toUint16()); return NULL_REG; } @@ -693,18 +693,18 @@ reg_t kMessage(EngineState *s, int funct_nr, int argc, reg_t *argv) { if (isGetMessage) { func = K_MESSAGE_GET; - tuple.noun = UKPV(0); - tuple.verb = UKPV(2); + tuple.noun = argv[0].toUint16(); + tuple.verb = argv[2].toUint16(); tuple.cond = 0; tuple.seq = 1; } else { - func = UKPV(0); + func = argv[0].toUint16(); if (argc >= 6) { - tuple.noun = UKPV(2); - tuple.verb = UKPV(3); - tuple.cond = UKPV(4); - tuple.seq = UKPV(5); + tuple.noun = argv[2].toUint16(); + tuple.verb = argv[3].toUint16(); + tuple.cond = argv[4].toUint16(); + tuple.seq = argv[5].toUint16(); } } @@ -717,7 +717,7 @@ reg_t kMessage(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t retval; if (func == K_MESSAGE_GET) { - s->_msgState.loadRes(s->resmgr, UKPV(1), true); + s->_msgState.loadRes(s->resmgr, argv[1].toUint16(), true); s->_msgState.findTuple(tuple); if (isGetMessage) @@ -762,7 +762,7 @@ reg_t kMessage(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_MESSAGE_SIZE: { MessageState tempState; - if (tempState.loadRes(s->resmgr, UKPV(1), false) && tempState.findTuple(tuple) && tempState.getMessage()) + if (tempState.loadRes(s->resmgr, argv[1].toUint16(), false) && tempState.findTuple(tuple) && tempState.getMessage()) return make_reg(0, tempState.getText().size() + 1); else return NULL_REG; @@ -772,7 +772,7 @@ reg_t kMessage(EngineState *s, int funct_nr, int argc, reg_t *argv) { case K_MESSAGE_REFNOUN: { MessageState tempState; - if (tempState.loadRes(s->resmgr, UKPV(1), false) && tempState.findTuple(tuple)) { + if (tempState.loadRes(s->resmgr, argv[1].toUint16(), false) && tempState.findTuple(tuple)) { MessageTuple t = tempState.getRefTuple(); switch (func) { case K_MESSAGE_REFCOND: diff --git a/engines/sci/engine/memobj.cpp b/engines/sci/engine/memobj.cpp index c0775ae51e..4d37d2aece 100644 --- a/engines/sci/engine/memobj.cpp +++ b/engines/sci/engine/memobj.cpp @@ -269,13 +269,6 @@ void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, //-------------------- clones -------------------- -template<typename T> -void Table<T>::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) { - for (uint i = 0; i < _table.size(); i++) - if (isValidEntry(i)) - (*note)(param, make_reg(segId, i)); -} - void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) { CloneTable *clone_table = this; Clone *clone; diff --git a/engines/sci/engine/memobj.h b/engines/sci/engine/memobj.h index c006caaddc..50c43a0e88 100644 --- a/engines/sci/engine/memobj.h +++ b/engines/sci/engine/memobj.h @@ -166,9 +166,11 @@ public: /** This struct is used to buffer the list of send calls in send_selector() */ struct CallsStruct { + reg_t addr_func; + reg_t varp_objp; union { reg_t func; - reg_t *var; + ObjVarRef var; } address; StackPtr argp; int argc; @@ -500,7 +502,11 @@ public: entries_used--; } - virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note); + virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) { + for (uint i = 0; i < _table.size(); i++) + if (isValidEntry(i)) + (*note)(param, make_reg(segId, i)); + } }; diff --git a/engines/sci/engine/message.cpp b/engines/sci/engine/message.cpp index 4f5efa106c..c019f7a3bc 100644 --- a/engines/sci/engine/message.cpp +++ b/engines/sci/engine/message.cpp @@ -229,11 +229,11 @@ int MessageState::loadRes(ResourceManager *resmgr, int module, bool lock) { } // Otherwise, free the old resource - resmgr->unlockResource(_currentResource, _module, kResourceTypeMessage); + resmgr->unlockResource(_currentResource); _locked = false; } - _currentResource = resmgr->findResource(kResourceTypeMessage, module, lock); + _currentResource = resmgr->findResource(ResourceId(kResourceTypeMessage, module), lock); if (_currentResource == NULL || _currentResource->data == NULL) { warning("Message: failed to load %d.msg", module); diff --git a/engines/sci/engine/said.cpp b/engines/sci/engine/said.cpp index 7d0467efa6..327231857e 100644 --- a/engines/sci/engine/said.cpp +++ b/engines/sci/engine/said.cpp @@ -1918,7 +1918,7 @@ static int said_next_node() { #define SAID_NEXT_NODE said_next_node() static int said_leaf_node(tree_t pos, int value) { - said_tree[pos].type = PARSE_TREE_NODE_LEAF; + said_tree[pos].type = kParseTreeLeafNode; if (value != VALUE_IGNORE) said_tree[pos].content.value = value; @@ -1927,7 +1927,7 @@ static int said_leaf_node(tree_t pos, int value) { } static int said_branch_node(tree_t pos, int left, int right) { - said_tree[pos].type = PARSE_TREE_NODE_BRANCH; + said_tree[pos].type = kParseTreeBranchNode; if (left != VALUE_IGNORE) said_tree[pos].content.branches[0] = left; @@ -2057,12 +2057,12 @@ static int said_parse_spec(EngineState *s, byte *spec) { // primitive functions #define AUG_READ_BRANCH(a, br, p) \ - if (tree[p].type != PARSE_TREE_NODE_BRANCH) \ + if (tree[p].type != kParseTreeBranchNode) \ return 0; \ a = tree[p].content.branches[br]; #define AUG_READ_VALUE(a, p) \ - if (tree[p].type != PARSE_TREE_NODE_LEAF) \ + if (tree[p].type != kParseTreeLeafNode) \ return 0; \ a = tree[p].content.value; diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index a69e96eb3d..146d65b56d 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -52,7 +52,7 @@ SongIterator *build_iterator(EngineState *s, int song_nr, SongIteratorType type, // of the classes they are syncing. static void sync_MemObjPtr(Common::Serializer &s, MemObject *&obj); -static void sync_songlib_t(Common::Serializer &s, songlib_t &obj); +static void sync_songlib_t(Common::Serializer &s, SongLibrary &obj); static void sync_reg_t(Common::Serializer &s, reg_t &obj) { s.syncAsUint16LE(obj.segment); @@ -73,22 +73,22 @@ static void syncCStr(Common::Serializer &s, char **str) { } -static void sync_song_t(Common::Serializer &s, song_t &obj) { - s.syncAsSint32LE(obj.handle); - s.syncAsSint32LE(obj.resource_num); - s.syncAsSint32LE(obj.priority); - s.syncAsSint32LE(obj.status); - s.syncAsSint32LE(obj.restore_behavior); - s.syncAsSint32LE(obj.restore_time); - s.syncAsSint32LE(obj.loops); - s.syncAsSint32LE(obj.hold); +static void sync_song_t(Common::Serializer &s, Song &obj) { + s.syncAsSint32LE(obj._handle); + s.syncAsSint32LE(obj._resourceNum); + s.syncAsSint32LE(obj._priority); + s.syncAsSint32LE(obj._status); + s.syncAsSint32LE(obj._restoreBehavior); + s.syncAsSint32LE(obj._restoreTime); + s.syncAsSint32LE(obj._loops); + s.syncAsSint32LE(obj._hold); if (s.isLoading()) { + obj._it = 0; obj._delay = 0; - obj.it = 0; - obj.next_playing = 0; - obj.next_stopping = 0; - obj.next = 0; + obj._next = 0; + obj._nextPlaying = 0; + obj._nextStopping = 0; } } @@ -401,25 +401,25 @@ void StringFrag::saveLoadWithSerializer(Common::Serializer &s) { #pragma mark - -static void sync_songlib_t(Common::Serializer &s, songlib_t &obj) { +static void sync_songlib_t(Common::Serializer &s, SongLibrary &obj) { int songcount = 0; if (s.isSaving()) - songcount = song_lib_count(obj); + songcount = obj.countSongs(); s.syncAsUint32LE(songcount); if (s.isLoading()) { - song_lib_init(&obj); + obj._lib = 0; while (songcount--) { - song_t *newsong = (song_t *)calloc(1, sizeof(song_t)); + Song *newsong = (Song *)calloc(1, sizeof(Song)); sync_song_t(s, *newsong); - song_lib_add(obj, newsong); + obj.addSong(newsong); } } else { - song_t *seeker = *(obj.lib); + Song *seeker = obj._lib; while (seeker) { - seeker->restore_time = seeker->it->getTimepos(); + seeker->_restoreTime = seeker->_it->getTimepos(); sync_song_t(s, *seeker); - seeker = seeker->next; + seeker = seeker->_next; } } } @@ -544,9 +544,9 @@ static void load_script(EngineState *s, SegmentId seg) { scr->buf = (byte *)malloc(scr->buf_size); assert(scr->buf); - script = s->resmgr->findResource(kResourceTypeScript, scr->nr, 0); + script = s->resmgr->findResource(ResourceId(kResourceTypeScript, scr->nr), 0); if (s->_version >= SCI_VERSION_1_1) - heap = s->resmgr->findResource(kResourceTypeHeap, scr->nr, 0); + heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, scr->nr), 0); memcpy(scr->buf, script->data, script->size); if (s->seg_manager->isSci1_1) @@ -692,36 +692,31 @@ static void reconstruct_clones(EngineState *s, SegManager *self) { int _reset_graphics_input(EngineState *s); static void reconstruct_sounds(EngineState *s) { - song_t *seeker; + Song *seeker; SongIteratorType it_type = s->resmgr->_sciVersion >= SCI_VERSION_01 ? SCI_SONG_ITERATOR_TYPE_SCI1 : SCI_SONG_ITERATOR_TYPE_SCI0; - if (s->_sound._songlib.lib) - seeker = *(s->_sound._songlib.lib); - else { - song_lib_init(&s->_sound._songlib); - seeker = NULL; - } + seeker = s->_sound._songlib._lib; while (seeker) { SongIterator *base, *ff; int oldstatus; SongIterator::Message msg; - base = ff = build_iterator(s, seeker->resource_num, it_type, seeker->handle); - if (seeker->restore_behavior == RESTORE_BEHAVIOR_CONTINUE) - ff = new_fast_forward_iterator(base, seeker->restore_time); + base = ff = build_iterator(s, seeker->_resourceNum, it_type, seeker->_handle); + if (seeker->_restoreBehavior == RESTORE_BEHAVIOR_CONTINUE) + ff = new_fast_forward_iterator(base, seeker->_restoreTime); ff->init(); - msg = SongIterator::Message(seeker->handle, SIMSG_SET_LOOPS(seeker->loops)); + msg = SongIterator::Message(seeker->_handle, SIMSG_SET_LOOPS(seeker->_loops)); songit_handle_message(&ff, msg); - msg = SongIterator::Message(seeker->handle, SIMSG_SET_HOLD(seeker->hold)); + msg = SongIterator::Message(seeker->_handle, SIMSG_SET_HOLD(seeker->_hold)); songit_handle_message(&ff, msg); - oldstatus = seeker->status; - seeker->status = SOUND_STATUS_STOPPED; - seeker->it = ff; - s->_sound.sfx_song_set_status(seeker->handle, oldstatus); - seeker = seeker->next; + oldstatus = seeker->_status; + seeker->_status = SOUND_STATUS_STOPPED; + seeker->_it = ff; + s->_sound.sfx_song_set_status(seeker->_handle, oldstatus); + seeker = seeker->_next; } } @@ -729,7 +724,7 @@ void internal_stringfrag_strncpy(EngineState *s, reg_t *dest, reg_t *src, int le EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { EngineState *retval; - songlib_t temp; + SongLibrary temp; /* if (s->sound_server) { @@ -782,7 +777,7 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { temp = retval->_sound._songlib; retval->_sound.sfx_init(retval->resmgr, s->sfx_init_flags); retval->sfx_init_flags = s->sfx_init_flags; - song_lib_free(retval->_sound._songlib); + retval->_sound._songlib.freeSounds(); retval->_sound._songlib = temp; _reset_graphics_input(retval); @@ -803,8 +798,8 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { str = &retval->sys_strings->strings[i]; char *data = (char *)str->value; if (data) { - str->value = (reg_t *)calloc(str->max_size+1, sizeof(char)); // FIXME -- sizeof(char) or sizeof(reg_t) ?? - strncpy((char *)str->value, data, str->max_size+1); // FIXME -- strncpy or internal_stringfrag_strncpy ? + str->value = (reg_t *)calloc(str->max_size + 1, sizeof(reg_t)); + strncpy((char *)str->value, data, str->max_size + 1); // FIXME -- strncpy or internal_stringfrag_strncpy ? free(data); } } diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index 74bbaa8854..fb094e00f6 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -200,6 +200,9 @@ void Kernel::mapSelectors() { FIND_SELECTOR(points); FIND_SELECTOR(syncCue); FIND_SELECTOR(syncTime); + FIND_SELECTOR(printLang); + FIND_SELECTOR(subtitleLang); + FIND_SELECTOR(parseLang); } void Kernel::dumpScriptObject(char *data, int seeker, int objsize) { @@ -295,7 +298,7 @@ void Kernel::dumpScriptClass(char *data, int seeker, int objsize) { void Kernel::dissectScript(int scriptNumber, Vocabulary *vocab) { int objectctr[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned int _seeker = 0; - Resource *script = _resmgr->findResource(kResourceTypeScript, scriptNumber, 0); + Resource *script = _resmgr->findResource(ResourceId(kResourceTypeScript, scriptNumber), 0); if (!script) { sciprintf("Script not found!\n"); diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 26ba01b440..a79fec2489 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -26,177 +26,23 @@ // Script debugger functionality. Absolutely not threadsafe. #include "sci/sci.h" +#include "sci/console.h" #include "sci/debug.h" #include "sci/engine/state.h" -#include "sci/engine/gc.h" -#include "sci/engine/kernel_types.h" -#include "sci/engine/kernel.h" -#include "sci/engine/savegame.h" -#include "sci/gfx/gfx_widgets.h" -#include "sci/gfx/gfx_gui.h" -#include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual -#include "sci/resource.h" -#include "sci/vocabulary.h" -#include "sci/sfx/iterator.h" -#include "sci/sfx/sci_midi.h" - -#include "common/util.h" -#include "common/savefile.h" - -#include "sound/audiostream.h" namespace Sci { -int g_debugstate_valid = 0; // Set to 1 while script_debug is running -int g_debug_step_running = 0; // Set to >0 to allow multiple stepping -static bool s_debug_commands_hooked = false; // Commands hooked to the console yet? -int g_debug_seeking = 0; // Stepping forward until some special condition is met -static int s_debug_seek_level = 0; // Used for seekers that want to check their exec stack depth -static int s_debug_seek_special = 0; // Used for special seeks(1) - -#define _DEBUG_SEEK_NOTHING 0 -#define _DEBUG_SEEK_CALLK 1 // Step forward until callk is found -#define _DEBUG_SEEK_LEVEL_RET 2 // Step forward until returned from this level -#define _DEBUG_SEEK_SPECIAL_CALLK 3 // Step forward until a /special/ callk is found -#define _DEBUG_SEEK_SO 5 // Step forward until specified PC (after the send command) and stack depth -#define _DEBUG_SEEK_GLOBAL 6 // Step forward until one specified global variable is modified - -static reg_t *p_pc; -static StackPtr *p_sp; -static StackPtr *p_pp; -static reg_t *p_objp; -static int *p_restadjust; -static SegmentId *p_var_segs; -static reg_t **p_vars; -static reg_t **p_var_base; -static int *p_var_max; // May be NULL even in valid state! - -char inputbuf[256] = ""; - -union cmd_param_t { - int32 val; - const char *str; - reg_t reg; -}; - -typedef int (*ConCommand)(EngineState *s, const Common::Array<cmd_param_t> &cmdParams); - -struct cmd_mm_entry_t { - const char *name; - const char *description; -}; // All later structures must "extend" this - -struct cmd_command_t : public cmd_mm_entry_t { - ConCommand command; - const char *param; -}; - -// Dummy function, so that it compiles -int con_hook_command(ConCommand command, const char *name, const char *param, const char *description) { - - return 0; -} - -int c_step(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - g_debugstate_valid = 0; - if (cmdParams.size() && (cmdParams[0].val > 0)) - g_debug_step_running = cmdParams[0].val - 1; - - return 0; -} - -enum { - _parse_eoi, - _parse_token_pareno, - _parse_token_parenc, - _parse_token_nil, - _parse_token_number -}; - -int _parse_getinp(int *i, int *nr, const Common::Array<cmd_param_t> &cmdParams) { - const char *token; - - if ((unsigned)*i == cmdParams.size()) - return _parse_eoi; - - token = cmdParams[(*i)++].str; - - if (!strcmp(token, "(")) - return _parse_token_pareno; - - if (!strcmp(token, ")")) - return _parse_token_parenc; - - if (!strcmp(token, "nil")) - return _parse_token_nil; - - *nr = strtol(token, NULL, 0); - - return _parse_token_number; -} - -int _parse_nodes(EngineState *s, int *i, int *pos, int type, int nr, const Common::Array<cmd_param_t> &cmdParams) { - int nexttk, nextval, newpos, oldpos; - - if (type == _parse_token_nil) - return 0; - - if (type == _parse_token_number) { - s->parser_nodes[*pos += 1].type = PARSE_TREE_NODE_LEAF; - s->parser_nodes[*pos].content.value = nr; - return *pos; - } - if (type == _parse_eoi) { - sciprintf("Unbalanced parentheses\n"); - return -1; - } - if (type == _parse_token_parenc) { - sciprintf("Syntax error at token %d\n", *i); - return -1; - } - s->parser_nodes[oldpos = ++(*pos)].type = PARSE_TREE_NODE_BRANCH; - - nexttk = _parse_getinp(i, &nextval, cmdParams); - if ((newpos = s->parser_nodes[oldpos].content.branches[0] = _parse_nodes(s, i, pos, nexttk, nextval, cmdParams)) == -1) - return -1; - - nexttk = _parse_getinp(i, &nextval, cmdParams); - if ((newpos = s->parser_nodes[oldpos].content.branches[1] = _parse_nodes(s, i, pos, nexttk, nextval, cmdParams)) == -1) - return -1; - - if (_parse_getinp(i, &nextval, cmdParams) != _parse_token_parenc) - sciprintf("Expected ')' at token %d\n", *i); - - return oldpos; -} - -int c_set_parse_nodes(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - int i = 0; - int foo, bar; - int pos = -1; - - if (!s) { - sciprintf("Not in debug state\n"); - return 1; - } - - bar = _parse_getinp(&i, &foo, cmdParams); - if (_parse_nodes(s, &i, &pos, bar, foo, cmdParams) == -1) - return 1; - - vocab_dump_parse_tree("debug-parse-tree", s->parser_nodes); - return 0; -} - extern const char *selector_name(EngineState *s, int selector); -int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) { +DebugState debugState; + +int propertyOffsetToId(EngineState *s, int prop_ofs, reg_t objp) { Object *obj = obj_get(s, objp); byte *selectoroffset; int selectors; if (!obj) { - sciprintf("Applied prop_ofs_to_id on non-object at %04x:%04x\n", PRINT_REG(objp)); + sciprintf("Applied propertyOffsetToId on non-object at %04x:%04x\n", PRINT_REG(objp)); return -1; } @@ -213,7 +59,7 @@ int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) { } if (prop_ofs < 0 || (prop_ofs >> 1) >= selectors) { - sciprintf("Applied prop_ofs_to_id to invalid property offset %x (property #%d not in [0..%d]) on object at %04x:%04x\n", + sciprintf("Applied propertyOffsetToId to invalid property offset %x (property #%d not in [0..%d]) on object at %04x:%04x\n", prop_ofs, prop_ofs >> 1, selectors - 1, PRINT_REG(objp)); return -1; } @@ -251,7 +97,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod opsize = scr[pos.offset]; opcode = opsize >> 1; - if (!g_debugstate_valid) { + if (!debugState.isValid) { sciprintf("Not in debug state\n"); return retval; } @@ -380,11 +226,11 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod } } - if (pos == *p_pc) { // Extra information if debugging the current opcode + if (pos == *debugState.p_pc) { // Extra information if debugging the current opcode if ((opcode == op_pTos) || (opcode == op_sTop) || (opcode == op_pToa) || (opcode == op_aTop) || (opcode == op_dpToa) || (opcode == op_ipToa) || (opcode == op_dpTos) || (opcode == op_ipTos)) { int prop_ofs = scr[pos.offset + 1]; - int prop_id = prop_ofs_to_id(s, prop_ofs, *p_objp); + int prop_id = propertyOffsetToId(s, prop_ofs, *debugState.p_objp); sciprintf(" (%s)", selector_name(s, prop_id)); } @@ -392,39 +238,38 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod sciprintf("\n"); - if (pos == *p_pc) { // Extra information if debugging the current opcode + if (pos == *debugState.p_pc) { // Extra information if debugging the current opcode if (opcode == op_callk) { - int stackframe = (scr[pos.offset + 2] >> 1) + (*p_restadjust); - int argc = ((*p_sp)[- stackframe - 1]).offset; + int stackframe = (scr[pos.offset + 2] >> 1) + (*debugState.p_restadjust); + int argc = ((*debugState.p_sp)[- stackframe - 1]).offset; if (!(s->_flags & GF_SCI0_OLD)) - argc += (*p_restadjust); + argc += (*debugState.p_restadjust); sciprintf(" Kernel params: ("); for (int j = 0; j < argc; j++) { - sciprintf("%04x:%04x", PRINT_REG((*p_sp)[j - stackframe])); + sciprintf("%04x:%04x", PRINT_REG((*debugState.p_sp)[j - stackframe])); if (j + 1 < argc) sciprintf(", "); } sciprintf(")\n"); } else if ((opcode == op_send) || (opcode == op_self)) { - int restmod = *p_restadjust; + int restmod = *debugState.p_restadjust; int stackframe = (scr[pos.offset + 1] >> 1) + restmod; - reg_t *sb = *p_sp; + reg_t *sb = *debugState.p_sp; uint16 selector; - reg_t *val_ref; reg_t fun_ref; while (stackframe > 0) { int argc = sb[- stackframe + 1].offset; const char *name = NULL; - reg_t called_obj_addr = *p_objp; + reg_t called_obj_addr = *debugState.p_objp; if (opcode == op_send) called_obj_addr = s->r_acc; else if (opcode == op_self) - called_obj_addr = *p_objp; + called_obj_addr = *debugState.p_objp; selector = sb[- stackframe].offset; @@ -435,7 +280,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod sciprintf(" %s::%s[", name, (selector > s->_kernel->getSelectorNamesSize()) ? "<invalid>" : selector_name(s, selector)); - switch (lookup_selector(s, called_obj_addr, selector, &val_ref, &fun_ref)) { + switch (lookup_selector(s, called_obj_addr, selector, 0, &fun_ref)) { case kSelectorMethod: sciprintf("FUNCT"); argc += restmod; @@ -467,218 +312,32 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod return retval; } -static int c_disasm_addr(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - reg_t vpc = cmdParams[0].reg; - int op_count = 1; - int do_bwc = 0; - int do_bytes = 0; - unsigned int i; - int invalid = 0; - int size; - - s->seg_manager->dereference(vpc, &size); - size += vpc.offset; // total segment size - - for (i = 1; i < cmdParams.size(); i++) { - if (!scumm_stricmp(cmdParams[i].str, "bwt")) - do_bwc = 1; - else if (!scumm_stricmp(cmdParams[i].str, "bc")) - do_bytes = 1; - else if (toupper(cmdParams[i].str[0]) == 'C') - op_count = atoi(cmdParams[i].str + 1); - else { - invalid = 1; - sciprintf("Invalid option '%s'\n", cmdParams[i].str); - } - } - - if (invalid || op_count < 0) - return invalid; - - do { - vpc = disassemble(s, vpc, do_bwc, do_bytes); - - } while ((vpc.offset > 0) && (vpc.offset + 6 < size) && (--op_count)); - return 0; -} - -static int c_disasm(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - Object *obj = obj_get(s, cmdParams[0].reg); - int selector_id = s->_kernel->findSelector(cmdParams[1].str); - reg_t addr; - - if (!obj) { - sciprintf("Not an object."); - return 1; - } - - if (selector_id < 0) { - sciprintf("Not a valid selector name."); - return 1; - } - - if (lookup_selector(s, cmdParams[0].reg, selector_id, NULL, &addr) != kSelectorMethod) { - sciprintf("Not a method."); - return 1; - } - - do { - addr = disassemble(s, addr, 0, 0); - } while (addr.offset > 0); - - return 0; -} - -static int c_sg(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - g_debug_seeking = _DEBUG_SEEK_GLOBAL; - s_debug_seek_special = cmdParams[0].val; - g_debugstate_valid = 0; - - return 0; -} - -static int c_snk(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - int callk_index; - char *endptr; - - if (!g_debugstate_valid) { - sciprintf("Not in debug state\n"); - return 1; - } - - if (cmdParams.size() > 0) { - /* Try to convert the parameter to a number. If the conversion stops - before end of string, assume that the parameter is a function name - and scan the function table to find out the index. */ - callk_index = strtoul(cmdParams [0].str, &endptr, 0); - if (*endptr != '\0') { - callk_index = -1; - for (uint i = 0; i < s->_kernel->getKernelNamesSize(); i++) - if (cmdParams [0].str == s->_kernel->getKernelName(i)) { - callk_index = i; - break; - } - - if (callk_index == -1) { - sciprintf("Unknown kernel function '%s'\n", cmdParams[0].str); - return 1; - } - } - - g_debug_seeking = _DEBUG_SEEK_SPECIAL_CALLK; - s_debug_seek_special = callk_index; - g_debugstate_valid = 0; - } else { - g_debug_seeking = _DEBUG_SEEK_CALLK; - g_debugstate_valid = 0; - } - - return 0; -} - -static int c_sret(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - g_debug_seeking = _DEBUG_SEEK_LEVEL_RET; - s_debug_seek_level = s->_executionStack.size()-1; - g_debugstate_valid = 0; - return 0; -} - -static int c_go(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - g_debug_seeking = 0; - g_debugstate_valid = 0; - return 0; -} - -static int c_send(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - reg_t object = cmdParams[0].reg; - const char *selector_name = cmdParams[1].str; - StackPtr stackframe = s->_executionStack.front().sp; - int selector_id; - unsigned int i; - ExecStack *xstack; - Object *o; - reg_t *vptr; - reg_t fptr; - - selector_id = s->_kernel->findSelector(selector_name); - - if (selector_id < 0) { - sciprintf("Unknown selector: \"%s\"\n", selector_name); - return 1; - } - - o = obj_get(s, object); - if (o == NULL) { - sciprintf("Address \"%04x:%04x\" is not an object\n", PRINT_REG(object)); - return 1; - } - - SelectorType selector_type = lookup_selector(s, object, selector_id, &vptr, &fptr); - - if (selector_type == kSelectorNone) { - sciprintf("Object does not support selector: \"%s\"\n", selector_name); - return 1; - } - - stackframe[0] = make_reg(0, selector_id); - stackframe[1] = make_reg(0, cmdParams.size() - 2); - - for (i = 2; i < cmdParams.size(); i++) - stackframe[i] = cmdParams[i].reg; - - xstack = add_exec_stack_entry(s, fptr, - s->_executionStack.front().sp + cmdParams.size(), - object, cmdParams.size() - 2, - s->_executionStack.front().sp - 1, 0, object, - s->_executionStack.size()-1, SCI_XS_CALLEE_LOCALS); - xstack->selector = selector_id; - xstack->type = selector_type == kSelectorVariable ? EXEC_STACK_TYPE_VARSELECTOR : EXEC_STACK_TYPE_CALL; - - // Now commit the actual function: - xstack = send_selector(s, object, object, stackframe, cmdParams.size() - 2, stackframe); - - xstack->sp += cmdParams.size(); - xstack->fp += cmdParams.size(); - - s->_executionStackPosChanged = true; - - return 0; -} - -// Breakpoint commands - -int c_se(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - g_stop_on_event = 1; - g_debugstate_valid = 0; - - return 0; -} void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *objp, int *restadjust, SegmentId *segids, reg_t **variables, reg_t **variables_base, int *variables_nr, int bp) { // Do we support a separate console? - int old_debugstate = g_debugstate_valid; - - p_var_segs = segids; - p_vars = variables; - p_var_max = variables_nr; - p_var_base = variables_base; - p_pc = pc; - p_sp = sp; - p_pp = pp; - p_objp = objp; - p_restadjust = restadjust; + bool old_debugstate = debugState.isValid; + + debugState.p_var_segs = segids; + debugState.p_vars = variables; + debugState.p_var_max = variables_nr; + debugState.p_var_base = variables_base; + debugState.p_pc = pc; + debugState.p_sp = sp; + debugState.p_pp = pp; + debugState.p_objp = objp; + debugState.p_restadjust = restadjust; sciprintf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc)); - g_debugstate_valid = 1; + debugState.isValid = true; disassemble(s, *pc, 0, 1); - if (g_debug_seeking == _DEBUG_SEEK_GLOBAL) - sciprintf("Global %d (0x%x) = %04x:%04x\n", s_debug_seek_special, - s_debug_seek_special, PRINT_REG(s->script_000->locals_block->_locals[s_debug_seek_special])); + if (debugState.seeking == kDebugSeekGlobal) + sciprintf("Global %d (0x%x) = %04x:%04x\n", debugState.seekSpecial, + debugState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[debugState.seekSpecial])); - g_debugstate_valid = old_debugstate; + debugState.isValid = old_debugstate; - if (g_debug_seeking && !bp) { // Are we looking for something special? + if (debugState.seeking && !bp) { // Are we looking for something special? MemObject *mobj = GET_SEGMENT(*s->seg_manager, pc->segment, MEM_OBJ_SCRIPT); if (mobj) { @@ -690,86 +349,65 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t * int paramb1 = pc->offset + 1 >= code_buf_size ? 0 : code_buf[pc->offset + 1]; int paramf1 = (opcode & 1) ? paramb1 : (pc->offset + 2 >= code_buf_size ? 0 : (int16)READ_LE_UINT16(code_buf + pc->offset + 1)); - switch (g_debug_seeking) { - case _DEBUG_SEEK_SPECIAL_CALLK: - if (paramb1 != s_debug_seek_special) + switch (debugState.seeking) { + case kDebugSeekSpecialCallk: + if (paramb1 != debugState.seekSpecial) return; - case _DEBUG_SEEK_CALLK: { + case kDebugSeekCallk: { if (op != op_callk) return; break; } - case _DEBUG_SEEK_LEVEL_RET: { - if ((op != op_ret) || (s_debug_seek_level < (int)s->_executionStack.size()-1)) + case kDebugSeekLevelRet: { + if ((op != op_ret) || (debugState.seekLevel < (int)s->_executionStack.size()-1)) return; break; } - case _DEBUG_SEEK_GLOBAL: + case kDebugSeekGlobal: if (op < op_sag) return; if ((op & 0x3) > 1) return; // param or temp if ((op & 0x3) && s->_executionStack.back().local_segment > 0) return; // locals and not running in script.000 - if (paramf1 != s_debug_seek_special) + if (paramf1 != debugState.seekSpecial) return; // CORRECT global? break; + case kDebugSeekSO: + // FIXME: Unhandled? + break; + + case kDebugSeekNothing: + // FIXME: Unhandled? + break; } - g_debug_seeking = _DEBUG_SEEK_NOTHING; + debugState.seeking = kDebugSeekNothing; // OK, found whatever we were looking for } } - g_debugstate_valid = (g_debug_step_running == 0); - - if (g_debugstate_valid) { - p_pc = pc; - p_sp = sp; - p_pp = pp; - p_objp = objp; - p_restadjust = restadjust; - p_var_segs = segids; - p_vars = variables; - p_var_max = variables_nr; - p_var_base = variables_base; + debugState.isValid = (debugState.runningStep == 0); + + if (debugState.isValid) { + debugState.p_pc = pc; + debugState.p_sp = sp; + debugState.p_pp = pp; + debugState.p_objp = objp; + debugState.p_restadjust = restadjust; + debugState.p_var_segs = segids; + debugState.p_vars = variables; + debugState.p_var_max = variables_nr; + debugState.p_var_base = variables_base; sciprintf("Step #%d\n", script_step_counter); disassemble(s, *pc, 0, 1); - - if (!s_debug_commands_hooked) { - s_debug_commands_hooked = true; - - con_hook_command(c_step, "s", "i*", "Executes one or several operations\n\nEXAMPLES\n\n" - " s 4\n\n Execute 4 commands\n\n s\n\n Execute next command"); - con_hook_command(c_disasm_addr, "disasm-addr", "!as*", "Disassembles one or more commands\n\n" - "USAGE\n\n disasm-addr [startaddr] <options>\n\n" - " Valid options are:\n" - " bwt : Print byte/word tag\n" - " c<x> : Disassemble <x> bytes\n" - " bc : Print bytecode\n\n"); - con_hook_command(c_disasm, "disasm", "!as", "Disassembles a method by name\n\nUSAGE\n\n disasm <obj> <method>\n\n"); - con_hook_command(c_snk, "snk", "s*", "Steps forward until it hits the next\n callk operation.\n" - " If invoked with a parameter, it will\n look for that specific callk.\n"); - con_hook_command(c_se, "se", "", "Steps forward until an SCI event is received.\n"); - con_hook_command(c_send, "send", "!asa*", "Sends a message to an object\nExample: send ?fooScript cue"); - con_hook_command(c_sret, "sret", "", "Steps forward until ret is called\n on the current execution stack\n level."); - con_hook_command(c_go, "go", "", "Executes the script.\n"); - con_hook_command(c_set_parse_nodes, "set_parse_nodes", "s*", "Sets the contents of all parse nodes.\n" - " Input token must be separated by\n blanks."); - con_hook_command(c_sg, "sg", "!i", - "Steps until the global variable with the\n" - "specified index is modified.\n\nSEE ALSO\n\n" - " s.1, snk.1, so.1, bpx.1"); - } // If commands were not hooked up } - if (g_debug_step_running) - g_debug_step_running--; } } // End of namespace Sci diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index dcf7180501..2227167673 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -129,8 +129,8 @@ Script *SegManager::allocateScript(EngineState *s, int script_nr, SegmentId *seg } void SegManager::setScriptSize(Script &scr, EngineState *s, int script_nr) { - Resource *script = s->resmgr->findResource(kResourceTypeScript, script_nr, 0); - Resource *heap = s->resmgr->findResource(kResourceTypeHeap, script_nr, 0); + Resource *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, script_nr), 0); + Resource *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, script_nr), 0); scr.script_size = script->size; scr.heap_size = 0; // Set later @@ -430,7 +430,7 @@ void SegManager::heapRelocate(reg_t block) { #define INST_LOOKUP_CLASS(id) ((id == 0xffff) ? NULL_REG : get_class_address(s, id, SCRIPT_GET_LOCK, NULL_REG)) -reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller); +reg_t get_class_address(EngineState *s, int classnr, SCRIPT_GET lock, reg_t caller); Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) { Object *obj; diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index dc91d60e69..a41d820014 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -45,29 +45,38 @@ namespace Sci { class SegManager : public Common::Serializable { public: - // Initialize the segment manager + /** + * Initialize the segment manager + */ SegManager(bool sci1_1); - // Deallocate all memory associated with the segment manager + /** + * Deallocate all memory associated with the segment manager + */ ~SegManager(); virtual void saveLoadWithSerializer(Common::Serializer &ser); // 1. Scripts - // Allocate a script into the segment manager - // Parameters: (int) script_nr: number of the script to load - // (state_t *) s: The state containing resource manager handlers to load the - // script data - // Returns : (int) 0 on failure, 1 on success - // (int) *seg_id: The segment ID of the newly allocated segment, on success + /** + * Allocate a script into the segment manager + * @param s The state containing resource manager + * handlers to load the script data + * @param script_nr The number of the script to load + * @param seg_id The segment ID of the newly allocated segment, + * on success + * @return 0 on failure, 1 on success + */ Script *allocateScript(EngineState *s, int script_nr, SegmentId *seg_id); // The script must then be initialised; see section (1b.), below. - // Forcefully deallocate a previously allocated script - // Parameters: (int) script_nr: number of the script to deallocate - // Returns : (int) 1 on success, 0 on failure + /** + * Forcefully deallocate a previously allocated script + * @param script_nr number of the script to deallocate + * @return 1 on success, 0 on failure + */ int deallocateScript(int script_nr); /** @@ -76,30 +85,40 @@ public: */ bool scriptIsLoaded(SegmentId seg); - // Validate whether the specified public function is exported by the script in the specified segment - // Parameters: (int) pubfunct: Index of the function to validate - // (int) seg: Segment ID of the script the check is to be performed for - // Returns : (uint16) 0 if the public function is invalid, its offset into the script's segment - // otherwise + /** + * Validate whether the specified public function is exported by + * the script in the specified segment + * @param pubfunct Index of the function to validate + * @param seg Segment ID of the script the check is to + * be performed for + * @return NULL if the public function is invalid, its + * offset into the script's segment otherwise + */ uint16 validateExportFunc(int pubfunct, SegmentId seg); - // Get the segment ID associated with a script number - // Parameters: (int) script_nr: Number of the script to look up - // Returns : (int) The associated segment ID, or -1 if no matching segment exists + /** + * Get the segment ID associated with a script number + * @param script_nr Number of the script to look up + * @return The associated segment ID, or -1 if no + * matching segment exists + */ SegmentId segGet(int script_nr) const; /** - * Return a pointer to the specified script. If the id is invalid, does not refer - * to a script or the script is not loaded, this will invoke error(). + * Return a pointer to the specified script. + * If the id is invalid, does not refer to a script or the script is + * not loaded, this will invoke error(). * @param seg ID of the script segment to check for - * @return pointer to the Script object + * @return A pointer to the Script object */ Script *getScript(SegmentId seg); /** - * Return a pointer to the specified script. If the id is invalid, does not refer + * Return a pointer to the specified script. + * If the id is invalid, does not refer to a script, or + * the script is not loaded, this will return NULL * @param seg ID of the script segment to check for - * @return pointer to the Script object, or NULL + * @return A pointer to the Script object, or NULL */ Script *getScriptIfLoaded(SegmentId seg); @@ -112,51 +131,70 @@ public: // to be used during script instantiation, // i.e. loading and linking. - // Initializes a script's local variable block - // Parameters: (SegmentId) seg: Segment containing the script to initialize - // (int) nr: Number of local variables to allocate - // All variables are initialized to zero. + /** + * Initializes a script's local variable block + * All variables are initialized to zero. + * @param seg Segment containing the script to initialize + * @param nr Number of local variables to allocate + */ void scriptInitialiseLocalsZero(SegmentId seg, int nr); - // Initializes a script's local variable block according to a prototype - // Parameters: (reg_t) location: Location to initialize from + /** + * Initializes a script's local variable block according to a prototype + * @param location Location to initialize from + */ void scriptInitialiseLocals(reg_t location); - // Initializes an object within the segment manager - // Parameters: (reg_t) obj_pos: Location (segment, offset) of the object - // Returns : (Object *) A newly created Object describing the object - // obj_pos must point to the beginning of the script/class block (as opposed - // to what the VM considers to be the object location) - // The corresponding Object is stored within the relevant script. + /** + * Initializes an object within the segment manager + * @param obj_pos Location (segment, offset) of the object. It must + * point to the beginning of the script/class block + * (as opposed to what the VM considers to be the + * object location) + * @returns A newly created Object describing the object, + * stored within the relevant script + */ Object *scriptObjInit(EngineState *s, reg_t obj_pos); - // Informs the segment manager that a code block must be relocated - // Parameters: (reg_t) location: Start of block to relocate + /** + * Informs the segment manager that a code block must be relocated + * @param location Start of block to relocate + */ void scriptAddCodeBlock(reg_t location); - // Tells the segment manager whether exports are wide (32-bit) or not. - // Parameters: (int) flag: 1 if exports are wide, 0 otherwise + /** + * Tells the segment manager whether exports are wide (32-bit) or not. + * @param flag 1 if exports are wide, 0 otherwise + */ void setExportWidth(int flag); - // Processes a relocation block witin a script - // Parameters: (reg_t) obj_pos: Location (segment, offset) of the block - // Returns : (Object *) Location of the relocation block - // This function is idempotent, but it must only be called after all - // objects have been instantiated, or a run-time error will occur. + /** + * Processes a relocation block witin a script + * This function is idempotent, but it must only be called after all + * objects have been instantiated, or a run-time error will occur. + * @param obj_pos Location (segment, offset) of the block + * @return Location of the relocation block + */ void scriptRelocate(reg_t block); - // Determines whether the script referenced by the indicated segment is marked as being deleted. - // Parameters: (SegmentId) Segment ID of the script to investigate - // Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise - // Will return 0 when applied to an invalid or non-script seg. + /** + * Determines whether the script referenced by the indicated segment + * is marked as being deleted. + * Will return 0 when applied to an invalid or non-script seg. + * @param seg Segment ID of the script to investigate + * @return 1 iff seg points to a script and the segment is + * deleted, 0 otherwise + */ bool scriptIsMarkedAsDeleted(SegmentId seg); // 2. Clones - // Allocate a fresh clone - // Returns : (Clone*): Reference to the memory allocated for the clone - // (reg_t) *addr: The offset of the freshly allocated clone + /** + * Allocate a fresh clone + * @param addr The offset of the freshly allocated clone + * @return Reference to the memory allocated for the clone + */ Clone *alloc_Clone(reg_t *addr); @@ -166,76 +204,96 @@ public: // 4. Stack - // Allocates a data stack - // Parameters: (int) size: Number of stack entries to reserve - // Returns : (DataStack *): The physical stack - // (SegmentId) segid: Segment ID of the stack + /** + * Allocates a data stack + * @param size Number of stack entries to reserve + * @param segid Segment ID of the stack + * @return The physical stack + */ DataStack *allocateStack(int size, SegmentId *segid); // 5. System Strings - // Allocates a system string table - // Returns : (DataStack *): The physical stack - // (SegmentId) segid: Segment ID of the stack - // See also sys_string_acquire(); + /** + * Allocates a system string table + * See also sys_string_acquire(); + * @param[in] segid Segment ID of the stack + * @returns The physical stack + */ SystemStrings *allocateSysStrings(SegmentId *segid); // 5. System Strings - // Allocates a string fragments segment - // Returns : (SegmentId): Segment ID to use for string fragments - // See also stringfrag.h + /** + * Allocates a string fragments segment + * See also stringfrag.h + * @return Segment ID to use for string fragments + */ SegmentId allocateStringFrags(); // 6, 7. Lists and Nodes - // Allocate a fresh list - // Returns : (listY_t*): Reference to the memory allocated for the list - // (reg_t) *addr: The offset of the freshly allocated list + /** + * Allocate a fresh list + * @param[in] addr The offset of the freshly allocated list + * @return Reference to the memory allocated for the list + */ List *alloc_List(reg_t *addr); - // Allocate a fresh node - // Returns : (node_t*): Reference to the memory allocated for the node - // (reg_t) *addr: The offset of the freshly allocated node + /** + * Allocate a fresh node + * @param[in] addr The offset of the freshly allocated node + * @return Reference to the memory allocated for the node + */ Node *alloc_Node(reg_t *addr); // 8. Hunk Memory - // Allocate a fresh chunk of the hunk - // Parameters: (int) size: Number of bytes to allocate for the hunk entry - // (const char *) hunk_type: A descriptive string for the hunk entry, - // for debugging purposes - // Returns : (Hunk *): Reference to the memory allocated for the hunk piece - // (reg_t) *addr: The offset of the freshly allocated hunk entry + /** + * Allocate a fresh chunk of the hunk + * @param[in] size Number of bytes to allocate for the hunk entry + * @param[in] hunk_type A descriptive string for the hunk entry, for + * debugging purposes + * @param[out] addr The offset of the freshly allocated hunk entry + * @return Reference to the memory allocated for the hunk + * piece + */ Hunk *alloc_hunk_entry(const char *hunk_type, int size, reg_t *addr); - // Deallocates a hunk entry - // Parameters: (reg_t) addr: Offset of the hunk entry to delete + /** + * Deallocates a hunk entry + * @param[in] addr Offset of the hunk entry to delete + */ void free_hunk_entry(reg_t addr); // 9. Dynamic Memory - // Allocate some dynamic memory - // Parameters: (int) size: Number of bytes to allocate - // (const char_ *) description: A descriptive string, - // for debugging purposes - // Returns : (unsigned char*): Raw pointer into the allocated dynamic memory - // (reg_t) *addr: The offset of the freshly allocated X + /** + * Allocate some dynamic memory + * @param[in] size Number of bytes to allocate + * @param[in] description A descriptive string for debugging purposes + * @param[out] addr The offset of the freshly allocated X + * @return Raw pointer into the allocated dynamic + * memory + */ unsigned char *allocDynmem(int size, const char *description, reg_t *addr); - // Deallocates a piece of dynamic memory - // Parameters: (reg_t) addr: Offset of the dynmem chunk to free + /** + * Deallocates a piece of dynamic memory + * @param[in] addr Offset of the dynmem chunk to free + */ int freeDynmem(reg_t addr); - // Gets the description of a dynmem segment - // Parameters: (reg_t) addr: Segment to describe - // Returns : (const char *): Pointer to the descriptive string set in - // allocDynmem + /** + * Gets the description of a dynmem segment + * @param[in] addr Segment to describe + * @return Pointer to the descriptive string set in allocDynmem + */ const char *getDescription(reg_t addr); @@ -251,10 +309,12 @@ public: // Generic Operations on Segments and Addresses - // Dereferences a raw memory pointer - // Parameters: (reg_t) reg: The reference to dereference - // Returns : (byte *) The data block referenced - // (int) size: (optionally) the theoretical maximum size of it + /** + * Dereferences a raw memory pointer + * @param[in] reg The reference to dereference + * @param[out] size (optional) The theoretical maximum size + * @return The data block referenced + */ byte *dereference(reg_t reg, int *size); @@ -266,17 +326,17 @@ public: int initialiseScript(Script &scr, EngineState *s, int script_nr); private: - IntMapper *id_seg_map; // id - script id; seg - index of heap + IntMapper *id_seg_map; ///< id - script id; seg - index of heap public: // TODO: make private Common::Array<MemObject *> _heap; int reserved_id; int exports_wide; bool isSci1_1; - SegmentId Clones_seg_id; // ID of the (a) clones segment - SegmentId Lists_seg_id; // ID of the (a) list segment - SegmentId Nodes_seg_id; // ID of the (a) node segment - SegmentId Hunks_seg_id; // ID of the (a) hunk segment + SegmentId Clones_seg_id; ///< ID of the (a) clones segment + SegmentId Lists_seg_id; ///< ID of the (a) list segment + SegmentId Nodes_seg_id; ///< ID of the (a) node segment + SegmentId Hunks_seg_id; ///< ID of the (a) hunk segment private: MemObject *allocNonscriptSegment(MemObjectType type, SegmentId *segid); @@ -295,11 +355,12 @@ private: Object *scriptObjInit0(EngineState *s, reg_t obj_pos); Object *scriptObjInit11(EngineState *s, reg_t obj_pos); - /* Check segment validity - ** Parameters: (int) seg: The segment to validate - ** Returns : (bool) false if 'seg' is an invalid segment - ** true if 'seg' is a valid segment - */ + /** + * Check segment validity + * @param[in] seg The segment to validate + * @return false if 'seg' is an invalid segment, true if + * 'seg' is a valid segment + */ bool check(SegmentId seg); void dbgPrint(const char* msg, void *i); // for debug only diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 0e4b63acee..e618077d54 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -123,7 +123,76 @@ EngineState::~EngineState() { } uint16 EngineState::currentRoomNumber() const { - return KP_UINT(script_000->locals_block->_locals[13]); + return script_000->locals_block->_locals[13].toUint16(); +} + +kLanguage EngineState::charToLanguage(const char c) const { + switch (c) { + case 'F': + return K_LANG_FRENCH; + case 'S': + return K_LANG_SPANISH; + case 'I': + return K_LANG_ITALIAN; + case 'G': + return K_LANG_GERMAN; + case 'J': + case 'j': + return K_LANG_JAPANESE; + case 'P': + return K_LANG_PORTUGUESE; + default: + return K_LANG_NONE; + } +} + +Common::String EngineState::getLanguageString(const char *str, kLanguage lang) const { + kLanguage secondLang = K_LANG_NONE; + + const char *seeker = str; + while (*seeker) { + if ((*seeker == '%') || (*seeker == '#')) { + secondLang = charToLanguage(*(seeker + 1)); + + if (secondLang != K_LANG_NONE) + break; + } + + seeker++; + } + + if ((secondLang == K_LANG_JAPANESE) && (*(seeker + 1) == 'J')) { + // FIXME: Add Kanji support + lang = K_LANG_ENGLISH; + } + + if (secondLang == lang) + return Common::String(seeker + 2); + + if (seeker) + return Common::String(str, seeker - str); + else + return Common::String(str); +} + +Common::String EngineState::strSplit(const char *str, const char *sep) { + EngineState *s = this; + + kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang); + kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang); + + // Use English when no language settings are present in the game + if (lang == K_LANG_NONE) + lang = K_LANG_ENGLISH; + + Common::String retval = getLanguageString(str, lang); + + if ((subLang != K_LANG_NONE) && (sep != NULL)) { + retval += sep; + retval += getLanguageString(str, subLang); + } + + return retval; } } // End of namespace Sci diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 15c1c2e63e..ecfb9fe6f7 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -88,6 +88,18 @@ enum { SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE = 4 }; +/** Supported languages */ +enum kLanguage { + K_LANG_NONE = 0, + K_LANG_ENGLISH = 1, + K_LANG_FRENCH = 33, + K_LANG_SPANISH = 34, + K_LANG_ITALIAN = 39, + K_LANG_GERMAN = 49, + K_LANG_JAPANESE = 81, + K_LANG_PORTUGUESE = 351 +}; + struct drawn_pic_t { int nr; int palette; @@ -209,6 +221,16 @@ public: uint16 currentRoomNumber() const; + /** + * Processes a multilanguage string based on the current language settings and + * returns a string that is ready to be displayed. + * @param str the multilanguage string + * @param sep optional seperator between main language and subtitle language, + * if NULL is passed no subtitle will be added to the returned string + * @return processed string + */ + Common::String strSplit(const char *str, const char *sep = "\r----------\r"); + /* Debugger data: */ Breakpoint *bp_list; /**< List of breakpoints */ int have_bp; /**< Bit mask specifying which types of breakpoints are used in bp_list */ @@ -239,6 +261,10 @@ public: Kernel *_kernel; EngineState *successor; /**< Successor of this state: Used for restoring */ + +private: + kLanguage charToLanguage(const char c) const; + Common::String getLanguageString(const char *str, kLanguage lang) const; }; /** diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index fd8ce33f51..92f890512a 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -50,7 +50,6 @@ int script_abort_flag = 0; // Set to 1 to abort execution. Set to 2 to force a r int script_step_counter = 0; // Counts the number of steps executed // FIXME: Avoid non-const global vars int script_gc_interval = GC_INTERVAL; // Number of steps in between gcs // FIXME: Avoid non-const global vars - static bool breakpointFlag = false; // FIXME: Avoid non-const global vars static reg_t _dummy_register; // FIXME: Avoid non-const global vars @@ -187,13 +186,7 @@ static void validate_write_var(reg_t *r, reg_t *stack_base, int type, int max, i #define OBJ_PROPERTY(o, p) (validate_property(o, p)) -int script_error(EngineState *s, const char *file, int line, const char *reason) { - error("Script error in file %s, line %d: %s\n", file, line, reason); - return 0; -} -#define CORE_ERROR(area, msg) script_error(s, "[" area "] " __FILE__, __LINE__, msg) - -reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller) { +reg_t get_class_address(EngineState *s, int classnr, SCRIPT_GET lock, reg_t caller) { if (NULL == s) { warning("vm.c: get_class_address(): NULL passed for \"s\""); @@ -280,10 +273,10 @@ static void _exec_varselectors(EngineState *s) { ExecStack &xs = s->_executionStack.back(); // varselector access? if (xs.argc) { // write? - *(xs.addr.varp) = xs.variables_argp[1]; + *(xs.getVarPointer(s)) = xs.variables_argp[1]; } else // No, read - s->r_acc = *(xs.addr.varp); + s->r_acc = *(xs.getVarPointer(s)); s->_executionStack.pop_back(); } @@ -294,7 +287,6 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt // Returns a pointer to the TOS exec_stack element assert(s); - reg_t *varp; reg_t funcp; int selector; int argc; @@ -310,8 +302,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt argc = validate_arithmetic(*argp); if (argc > 0x800) { // More arguments than the stack could possibly accomodate for - CORE_ERROR("SEND", "More than 0x800 arguments to function call\n"); - return NULL; + error("send_selector(): More than 0x800 arguments to function call"); } // Check if a breakpoint is set on this method @@ -341,6 +332,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt sciprintf("Send to %04x:%04x, selector %04x (%s):", PRINT_REG(send_obj), selector, s->_selectorNames[selector].c_str()); #endif // VM_DEBUG_SEND + ObjVarRef varp; switch (lookup_selector(s, send_obj, selector, &varp, &funcp)) { case kSelectorNone: // WORKAROUND: LSL6 tries to access the invalid 'keep' selector of the game object. @@ -377,7 +369,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt #endif { // Argument is supplied -> Selector should be set if (print_send_action) { - reg_t oldReg = *varp; + reg_t oldReg = *varp.getPointer(s); reg_t newReg = argp[1]; sciprintf("[write to selector: change %04x:%04x to %04x:%04x]\n", PRINT_REG(oldReg), PRINT_REG(newReg)); @@ -396,7 +388,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt default: sciprintf("Send error: Variable selector %04x in %04x:%04x called with %04x params\n", selector, PRINT_REG(send_obj), argc); script_debug_flag = 1; // Enter debug mode - g_debug_seeking = g_debug_step_running = 0; + debugState.seeking = debugState.runningStep = 0; #endif } break; @@ -454,8 +446,8 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt return &(s->_executionStack.back()); } -ExecStack *add_exec_stack_varselector(EngineState *s, reg_t objp, int argc, StackPtr argp, Selector selector, reg_t *address, int origin) { - ExecStack *xstack = add_exec_stack_entry(s, NULL_REG, address, objp, argc, argp, selector, objp, origin, SCI_XS_CALLEE_LOCALS); +ExecStack *add_exec_stack_varselector(EngineState *s, reg_t objp, int argc, StackPtr argp, Selector selector, const ObjVarRef& address, int origin) { + ExecStack *xstack = add_exec_stack_entry(s, NULL_REG, 0, objp, argc, argp, selector, objp, origin, SCI_XS_CALLEE_LOCALS); // Store selector address in sp xstack->addr.varp = address; @@ -575,8 +567,7 @@ void run_vm(EngineState *s, int restoring) { const byte *code_buf = NULL; // (Avoid spurious warning) if (!local_script) { - script_error(s, __FILE__, __LINE__, "Program Counter gone astray"); - return; + error("run_vm(): program counter gone astray (local_script pointer is null)"); } if (!restoring) @@ -606,14 +597,12 @@ void run_vm(EngineState *s, int restoring) { while (1) { byte opcode; - int old_pc_offset; - StackPtr old_sp; byte opnumber; int var_type; // See description below int var_number; - old_pc_offset = xs->addr.pc.offset; - old_sp = xs->sp; + debugState.old_pc_offset = xs->addr.pc.offset; + debugState.old_sp = xs->sp; if (s->_executionStackPosChanged) { Script *scr; @@ -688,12 +677,12 @@ void run_vm(EngineState *s, int restoring) { #ifndef DISABLE_VALIDATIONS if (xs->sp < xs->fp) - script_error(s, "[VM] "__FILE__, __LINE__, "Stack underflow"); + error("run_vm(): stack underflow"); variables_max[VAR_TEMP] = xs->sp - xs->fp; if (xs->addr.pc.offset >= code_buf_size) - script_error(s, "[VM] "__FILE__, __LINE__, "Program Counter gone astray"); + error("run_vm(): program counter gone astray"); #endif opcode = GET_OP_BYTE(); // Get opcode @@ -1048,9 +1037,9 @@ void run_vm(EngineState *s, int restoring) { if (old_xs->type == EXEC_STACK_TYPE_VARSELECTOR) { // varselector access? if (old_xs->argc) // write? - *(old_xs->addr.varp) = old_xs->variables_argp[1]; + *(old_xs->getVarPointer(s)) = old_xs->variables_argp[1]; else // No, read - s->r_acc = *(old_xs->addr.varp); + s->r_acc = *(old_xs->getVarPointer(s)); } // Not reached the base, so let's do a soft return @@ -1106,7 +1095,7 @@ void run_vm(EngineState *s, int restoring) { r_temp = get_class_address(s, opparams[0], SCRIPT_GET_LOAD, xs->addr.pc); if (!r_temp.segment) - CORE_ERROR("VM", "Invalid superclass in object"); + error("[VM]: Invalid superclass in object"); else { s_temp = xs->sp; xs->sp -= ((opparams[1] >> 1) + restadjust); // Adjust stack @@ -1410,7 +1399,7 @@ void run_vm(EngineState *s, int restoring) { break; default: - script_error(s, __FILE__, __LINE__, "Illegal opcode"); + error("run_vm(): illegal opcode %x", opnumber); } // switch(opcode >> 1) @@ -1424,16 +1413,7 @@ void run_vm(EngineState *s, int restoring) { opnumber); } //#endif - -#if 0 - if (script_error_flag) { - g_debug_step_running = 0; // Stop multiple execution - g_debug_seeking = 0; // Stop special seeks - xs->addr.pc.offset = old_pc_offset; - xs->sp = old_sp; - } else -#endif - ++script_step_counter; + ++script_step_counter; } } @@ -1507,7 +1487,7 @@ static SelectorType _lookup_selector_function(EngineState *s, int seg_id, Object return kSelectorNone; } -SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector selector_id, reg_t **vptr, reg_t *fptr) { +SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector selector_id, ObjVarRef *varp, reg_t *fptr) { Object *obj = obj_get(s, obj_location); Object *species; int index; @@ -1518,9 +1498,8 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select selector_id &= ~1; if (!obj) { - CORE_ERROR("SLC-LU", "Attempt to send to non-object or invalid script"); - sciprintf("Address was %04x:%04x\n", PRINT_REG(obj_location)); - return kSelectorNone; + error("lookup_selector(): Attempt to send to non-object or invalid script. Address was %04x:%04x", + PRINT_REG(obj_location)); } if (IS_CLASS(obj)) @@ -1530,9 +1509,8 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select if (!obj) { - CORE_ERROR("SLC-LU", "Error while looking up Species class"); - sciprintf("Original address was %04x:%04x\n", PRINT_REG(obj_location)); - sciprintf("Species address was %04x:%04x\n", PRINT_REG(obj->_variables[SCRIPT_SPECIES_SELECTOR])); + error("lookup_selector(): Error while looking up Species class.\nOriginal address was %04x:%04x. Species address was %04x:%04x\n", + PRINT_REG(obj_location), PRINT_REG(obj->_variables[SCRIPT_SPECIES_SELECTOR])); return kSelectorNone; } @@ -1540,15 +1518,17 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select if (index >= 0) { // Found it as a variable - if (vptr) - *vptr = &obj->_variables[index]; + if (varp) { + varp->obj = obj_location; + varp->varindex = index; + } return kSelectorVariable; } return _lookup_selector_function(s, obj_location.segment, obj, selector_id, fptr); } -SegmentId script_get_segment(EngineState *s, int script_nr, int load) { +SegmentId script_get_segment(EngineState *s, int script_nr, SCRIPT_GET load) { SegmentId segment; if ((load & SCRIPT_GET_LOAD) == SCRIPT_GET_LOAD) @@ -1570,31 +1550,24 @@ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index) { Script *script = NULL; #ifndef DISABLE_VALIDATIONS - if (!seg) { - CORE_ERROR("EXPORTS", "Script invalid or not loaded"); - sciprintf("Script was script.%03d (0x%x)\n", - script_nr, script_nr); - return NULL_REG; - } + if (!seg) + error("script_lookup_export(): script.%03d (0x%x) is invalid or not loaded", + script_nr, script_nr); #endif script = script_locate_by_segment(s, seg); #ifndef DISABLE_VALIDATIONS - if (script - && export_index < script->exports_nr - && export_index >= 0) + if (script && export_index < script->exports_nr && export_index >= 0) #endif return make_reg(seg, READ_LE_UINT16((byte *)(script->export_table + export_index))); #ifndef DISABLE_VALIDATIONS else { - CORE_ERROR("EXPORTS", "Export invalid or script missing "); if (!script) - sciprintf("(script.%03d missing)\n", script_nr); + error("script_lookup_export(): script.%03d missing", script_nr); else - sciprintf("(script.%03d: Sought export %d/%d)\n", - script_nr, export_index, script->exports_nr); - return NULL_REG; + error("script_lookup_export(): script.%03d: Sought invalid export %d/%d", + script_nr, export_index, script->exports_nr); } #endif } @@ -1607,9 +1580,9 @@ int script_instantiate_common(EngineState *s, int script_nr, Resource **script, *was_new = 1; - *script = s->resmgr->findResource(kResourceTypeScript, script_nr, 0); + *script = s->resmgr->findResource(ResourceId(kResourceTypeScript, script_nr), 0); if (s->_version >= SCI_VERSION_1_1) - *heap = s->resmgr->findResource(kResourceTypeHeap, script_nr, 0); + *heap = s->resmgr->findResource(ResourceId(kResourceTypeHeap, script_nr), 0); if (!*script || (s->_version >= SCI_VERSION_1_1 && !heap)) { sciprintf("Script 0x%x requested but not found\n", script_nr); @@ -1943,12 +1916,9 @@ static void _init_stack_base_with_selector(EngineState *s, Selector selector) { s->stack_base[1] = NULL_REG; } -EngineState *g_EngineState = 0; - -static EngineState *_game_run(EngineState *s, int restoring) { +static EngineState *_game_run(EngineState *&s, int restoring) { EngineState *successor = NULL; int game_is_finished = 0; - g_EngineState = s; do { s->_executionStackPosChanged = false; run_vm(s, (successor || restoring) ? 1 : 0); @@ -1976,7 +1946,6 @@ static EngineState *_game_run(EngineState *s, int restoring) { script_free_vm_memory(s); delete s; s = successor; - g_EngineState = s; if (script_abort_flag == 2) { sciprintf("Restarting with replay()\n"); @@ -2012,7 +1981,7 @@ int game_run(EngineState **_s) { return 1; } // and ENGAGE! - *_s = s = _game_run(s, 0); + _game_run(*_s, 0); sciprintf(" Game::play() finished.\n"); @@ -2059,11 +2028,12 @@ const char *obj_get_name(EngineState *s, reg_t pos) { return name; } + void quit_vm() { script_abort_flag = 1; // Terminate VM - g_debugstate_valid = 0; - g_debug_seeking = 0; - g_debug_step_running = 0; + debugState.isValid = false; + debugState.seeking = kDebugSeekNothing; + debugState.runningStep = 0; } void shrink_execution_stack(EngineState *s, uint size) { @@ -2075,5 +2045,15 @@ void shrink_execution_stack(EngineState *s, uint size) { s->_executionStack.erase(iter, s->_executionStack.end()); } +reg_t* ObjVarRef::getPointer(EngineState *s) const { + Object *o = obj_get(s, obj); + if (!o) return 0; + return &(o->_variables[varindex]); +} + +reg_t* ExecStack::getVarPointer(EngineState *s) const { + assert(type == EXEC_STACK_TYPE_VARSELECTOR); + return addr.varp.getPointer(s); +} } // End of namespace Sci diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index 5bfbe71ce9..a3fabbe44b 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -198,13 +198,27 @@ struct selector_map_t { Selector points; /**< Used by AvoidPath() */ Selector syncCue; /**< Used by DoSync() */ - Selector syncTime; /**< Used by DoSync() */ + Selector syncTime; + + Selector printLang; /**< Used for i18n */ + Selector subtitleLang; + Selector parseLang; +}; + +// A reference to an object's variable. +// The object is stored as a reg_t, the variable as an index into _variables +struct ObjVarRef { + reg_t obj; + int varindex; + + reg_t* getPointer(EngineState *s) const; }; + struct ViewObject { reg_t obj; - reg_t *signalp; /* Used only indirectly */ - reg_t *underBitsp; /* The same goes for the handle storage */ + ObjVarRef signalp; /* Used only indirectly */ + ObjVarRef underBitsp; /* The same goes for the handle storage */ int underBits; /* Copy of the underbits: Needed for cleanup */ int x, y; @@ -231,10 +245,12 @@ enum ExecStackType { struct ExecStack { reg_t objp; reg_t sendp; /**< Pointer to the object containing the invoked method */ + union { - reg_t *varp; /**< Variable pointer for read/write access */ + ObjVarRef varp; /**< Variable pointer for r/w access */ reg_t pc; /**< Not accurate for the TOS element */ } addr; + StackPtr fp; /**< Frame pointer */ StackPtr sp; /**< Stack pointer */ int argc; @@ -246,6 +262,8 @@ struct ExecStack { Selector selector; /**< The selector which was used to call or -1 if not applicable */ int origin; /**< The stack frame position the call was made from, or -1 if it was the initial call. */ ExecStackType type; + + reg_t* getVarPointer(EngineState *s) const; }; @@ -273,8 +291,8 @@ struct Breakpoint { }; /** - * Set this to 1 to abort script execution immediately. Aborting will leave the - * debug exec stack intact. + * Set this to 1 to abort script execution immediately. Aborting will + * leave the debug exec stack intact. * Set it to 2 to force a replay afterwards. */ extern int script_abort_flag; @@ -293,31 +311,36 @@ extern int script_step_counter; /** * Executes function pubfunct of the specified script. - * Parameters: (EngineState *) s: The state which is to be executed with - * (uint16) script: The script which is called - * (uint16) pubfunct: The exported script function which is to be called - * (StackPtr) sp: Stack pointer position - * (reg_t) calling_obj: The heap address of the object which executed the call - * (uint16) argc: Number of arguments supplied - * (StackPtr) argp: Pointer to the first supplied argument - * Returns : (ExecStack *): A pointer to the new exec stack TOS entry + * @param[in] s The state which is to be executed with + * @param[in] script The script which is called + * @param[in] pubfunct The exported script function which is to + * be called + * @param[in] sp Stack pointer position + * @param[in] calling_obj The heap address of the object that + * executed the call + * @param[in] argc Number of arguments supplied + * @param[in] argp Pointer to the first supplied argument + * @return A pointer to the new exec stack TOS entry */ -ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackPtr sp, reg_t calling_obj, - uint16 argc, StackPtr argp); +ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, + StackPtr sp, reg_t calling_obj, uint16 argc, StackPtr argp); /** * Executes a "send" or related operation to a selector. - * Parameters: (EngineState *) s: The EngineState to operate on - * (reg_t) send_obj: Heap address of the object to send to - * (reg_t) work_obj: Heap address of the object initiating the send - * (StackPtr) sp: Stack pointer position - * (int) framesize: Size of the send as determined by the "send" operation - * (StackPtr) argp: Pointer to the beginning of the heap block containing the - * data to be sent. This area is a succession of one or more - * sequences of [selector_number][argument_counter] and then - * "argument_counter" word entries with the parameter values. - * Returns : (ExecStack *): A pointer to the new execution stack TOS entry + * @param[in] s The EngineState to operate on + * @param[in] send_obj Heap address of the object to send to + * @param[in] work_obj Heap address of the object initiating the send + * @param[in] sp Stack pointer position + * @param[in] framesize Size of the send as determined by the "send" + * operation + * @param[in] argp Pointer to the beginning of the heap block + * containing the data to be sent. This area is a + * succession of one or more sequences of + * [selector_number][argument_counter] and then + * "argument_counter" word entries with the + * parameter values. + * @return A pointer to the new execution stack TOS entry */ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPtr sp, int framesize, StackPtr argp); @@ -328,267 +351,300 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, /** * Adds an entry to the top of the execution stack. * - * @param s The state with which to execute - * @param pc The initial program counter - * @param sp The initial stack pointer - * @param objp Pointer to the beginning of the current object - * @param argc Number of parameters to call with - * @param argp Heap pointer to the first parameter - * @param selector The selector by which it was called or - * NULL_SELECTOR if n.a. For debugging. - * @param sendp Pointer to the object which the message was sent to. - * Equal to objp for anything but super. - * @param origin Number of the execution stack element this entry was created by - * (usually the current TOS number, except for multiple sends). - * @param local_segment The segment to use for local variables, - * or SCI_XS_CALLEE_LOCALS to use obj's segment. - * @return a pointer to the new exec stack TOS entry - */ -ExecStack *add_exec_stack_entry(EngineState *s, reg_t pc, StackPtr sp, reg_t objp, int argc, - StackPtr argp, Selector selector, reg_t sendp, int origin, SegmentId local_segment); + * @param[in] s The state with which to execute + * @param[in] pc The initial program counter + * @param[in] sp The initial stack pointer + * @param[in] objp Pointer to the beginning of the current object + * @param[in] argc Number of parameters to call with + * @param[in] argp Heap pointer to the first parameter + * @param[in] selector The selector by which it was called or + * NULL_SELECTOR if n.a. For debugging. + * @param[in] sendp Pointer to the object which the message was + * sent to. Equal to objp for anything but super. + * @param[in] origin Number of the execution stack element this + * entry was created by (usually the current TOS + * number, except for multiple sends). + * @param[in] local_segment The segment to use for local variables, + * or SCI_XS_CALLEE_LOCALS to use obj's segment. + * @return A pointer to the new exec stack TOS entry + */ +ExecStack *add_exec_stack_entry(EngineState *s, reg_t pc, StackPtr sp, + reg_t objp, int argc, StackPtr argp, Selector selector, + reg_t sendp, int origin, SegmentId local_segment); /** * Adds one varselector access to the execution stack. - * Parameters: (EngineState *) s: The EngineState to use - * (reg_t) objp: Pointer to the object owning the selector - * (int) argc: 1 for writing, 0 for reading - * (StackPtr) argp: Pointer to the address of the data to write -2 - * (int) selector: Selector name - * (reg_t *) address: Heap address of the selector - * (int) origin: Stack frame which the access originated from - * Returns : (ExecStack *): Pointer to the new exec-TOS element * This function is called from send_selector only. + * @param[in] s The EngineState to use + * @param[in] objp Pointer to the object owning the selector + * @param[in] argc 1 for writing, 0 for reading + * @param[in] argp Pointer to the address of the data to write -2 + * @param[in] selector Selector name + * @param[in] address Heap address of the selector + * @param[in] origin Stack frame which the access originated from + * @return Pointer to the new exec-TOS element */ -ExecStack *add_exec_stack_varselector(EngineState *s, reg_t objp, int argc, StackPtr argp, - Selector selector, reg_t *address, int origin); - +ExecStack *add_exec_stack_varselector(EngineState *s, reg_t objp, int argc, + StackPtr argp, Selector selector, const ObjVarRef& address, + int origin); +/** + * This function executes SCI bytecode + * It executes the code on s->heap[pc] until it hits a 'ret' operation + * while (stack_base == stack_pos). Requires s to be set up correctly. + * @param[in] s The state to use + * @param[in] restoring 1 if s has just been restored, 0 otherwise + */ void run_vm(EngineState *s, int restoring); -/* Executes the code on s->heap[pc] until it hits a 'ret' operation while (stack_base == stack_pos) -** Parameters: (EngineState *) s: The state to use -** (int) restoring: 1 if s has just been restored, 0 otherwise -** Returns : (void) -** This function will execute SCI bytecode. It requires s to be set up -** correctly. -*/ +/** + * Handles a fatal error condition + * @param[in] s The state to recover from + * @param[in] line Source code line number the error occured in + * @param[in] file File the error occured in + */ void vm_handle_fatal_error(EngineState *s, int line, const char *file); -/* Handles a fatal error condition -** Parameters: (EngineState *) s: The state to recover from -** (int) line: Source code line number the error occured in -** (const char *) file: File the error occured in -*/ - - -void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *objp, - int *restadjust, SegmentId *segids, reg_t **variables, reg_t **variables_base, - int *variables_nr, int bp); -/* Debugger functionality -** Parameters: (EngineState *) s: The state at which debugging should take place -** (reg_t *) pc: Pointer to the program counter -** (StackPtr *) sp: Pointer to the stack pointer -** (StackPtr *) pp: Pointer to the frame pointer -** (reg_t *) objp: Pointer to the object base pointer -** (int *) restadjust: Pointer to the &rest adjustment value -** (SegmentId *) segids: four-element array containing segment IDs for locals etc. -** (reg_t **) variables: four-element array referencing registers for globals etc. -** (reg_t **) variables_base: four-element array referencing -** register bases for temps etc. -** (int *) variables_nr: four-element array giving sizes for params etc. (may be NULL) -** (int) bp: Flag, set to 1 when a breakpoint is triggered -** Returns : (void) -*/ + +/** + * Debugger functionality + * @param[in] s The state at which debugging should take + * place + * @param[in] pc Pointer to the program counter + * @param[in] sp Pointer to the stack pointer + * @param[in] pp Pointer to the frame pointer + * @param[in] objp Pointer to the object base pointer + * @param[in] restadjust Pointer to the &rest adjustment value + * @param[in] segids four-element array containing segment IDs + * for locals etc. + * @param[in] variables four-element array referencing registers + * for globals etc. + * @param[in] variables_base four-element array referencing register + * bases for temps etc. + * @param[in] variables_nr four-element array giving sizes for params + * etc. (may be NULL) + * @param[in] bp Flag, set to 1 when a breakpoint is + * triggered + */ +void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, + reg_t *objp, int *restadjust, SegmentId *segids, reg_t **variables, + reg_t **variables_base, int *variables_nr, int bp); + +/** + * Initializes a EngineState block + * @param[in] s The state to initialize + * @return 0 on success, 1 if vocab.996 (the class table) is missing + * or corrupted + */ int script_init_engine(EngineState *s); -/* Initializes a EngineState block -** Parameters: (EngineState *) s: The state to initialize -** Returns : 0 on success, 1 if vocab.996 (the class table) is missing or corrupted -*/ +/** + * Sets the gamestate's save_dir to the parameter path + * @param[in] s The state to set + * @param[in] path Path where save_dir will point to + */ void script_set_gamestate_save_dir(EngineState *s, const char *path); -/* Sets the gamestate's save_dir to the parameter path -** Parameters: (EngineState *) s: The state to set -** (const char *) path: Path where save_dir will point to -** Returns : (void) -*/ +/** + * Frees all additional memory associated with a EngineState block + * @param[in] s The EngineState whose elements should be cleared + */ void script_free_engine(EngineState *s); -/* Frees all additional memory associated with a EngineState block -** Parameters: (EngineState *) s: The EngineState whose elements should be cleared -** Returns : (void) -*/ +/** + * Frees all script memory (heap, hunk, and class tables). + * This operation is implicit in script_free_engine(), but is required for + * restoring the game state. + * @param[in] s The EngineState to free + */ void script_free_vm_memory(EngineState *s); -/* Frees all script memory (heap, hunk, and class tables). -** Parameters: (EngineState *) s: The EngineState to free -** Returns : (void) -** This operation is implicit in script_free_engine(), but is required for restoring -** the game state. -*/ - - -SelectorType lookup_selector(EngineState *s, reg_t obj, Selector selectorid, reg_t **vptr, reg_t *fptr); -/* Looks up a selector and returns its type and value -** Parameters: (EngineState *) s: The EngineState to use -** (reg_t) obj: Address of the object to look the selector up in -** (Selector) selectorid: The selector to look up -** Returns : (SelectorType) kSelectorNone if the selector was not found in the object or its superclasses. -** kSelectorVariable if the selector represents an object-relative variable -** kSelectorMethod if the selector represents a method -** (reg_t *) *vptr: A pointer to the storage space associated with the selector, if -** it is a variable -** (reg_t) *fptr: A reference to the function described by that selector, if it is -** a valid function selector. -** *vptr is written to iff it is non-NULL and the selector indicates a property of the object. -** *fptr is written to iff it is non-NULL and the selector indicates a member function of that object. -*/ -enum { +/** + * Looks up a selector and returns its type and value + * varindex is written to iff it is non-NULL and the selector indicates a property of the object. + * @param[in] s The EngineState to use + * @param[in] obj Address of the object to look the selector up in + * @param[in] selectorid The selector to look up + * @param[out] varp A reference to the selector, if it is a + * variable. + * @param[out] fptr A reference to the function described by that + * selector, if it is a valid function selector. + * fptr is written to iff it is non-NULL and the + * selector indicates a member function of that + * object. + * @return kSelectorNone if the selector was not found in + * the object or its superclasses. + * kSelectorVariable if the selector represents an + * object-relative variable. + * kSelectorMethod if the selector represents a + * method + */ +SelectorType lookup_selector(EngineState *s, reg_t obj, Selector selectorid, + ObjVarRef *varp, reg_t *fptr); + +/** + * Parameters for script_get_segment() + */ +typedef enum { SCRIPT_GET_DONT_LOAD = 0, /**< Fail if not loaded */ SCRIPT_GET_LOAD = 1, /**< Load, if neccessary */ SCRIPT_GET_LOCK = 3 /**< Load, if neccessary, and lock */ -}; +} SCRIPT_GET; -SegmentId script_get_segment(EngineState *s, int script_id, int load); -/* Determines the segment occupied by a certain script -** Parameters: (EngineState *) s: The state to operate on -** (int) script_id: The script in question -** (int) load: One of SCRIPT_GET_* -** Returns : The script's segment, or 0 on failure -*/ +/** + * Determines the segment occupied by a certain script + * @param[in] s The state to operate on + * @param[in] script_id The script in question + * @param[in] load One of SCRIPT_GET_* + * @return The script's segment, or 0 on failure + */ +SegmentId script_get_segment(EngineState *s, int script_id, SCRIPT_GET load); +/** + * Looks up an entry of the exports table of a script + * @param[in] s The state to operate on + * @param[in] script_nr The script to look up in + * @param[out] export_index The index of the export entry to look up + * @return The handle + */ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index); -/* Looks up an entry of the exports table of a script -** Parameters: (EngineState *) s: The state to operate on -** (int) script_nr: The script to look up in -** Returns : (int) export_index: index of the export entry to look up -*/ +/** + * Makes sure that a script and its superclasses get loaded to the heap. + * If the script already has been loaded, only the number of lockers is + * increased. All scripts containing superclasses of this script are loaded + * recursively as well, unless 'recursive' is set to zero. The + * complementary function is "script_uninstantiate()" below. + * @param[in] s The state to operate on + * @param[in] script_nr The script number to load + * @return The script's segment ID or 0 if out of heap + */ int script_instantiate(EngineState *s, int script_nr); -/* Makes sure that a script and its superclasses get loaded to the heap -** Parameters: (EngineState *) s: The state to operate on -** (int) script_nr: The script number to load -** Returns : (int) The script's segment ID or 0 if out of heap -** If the script already has been loaded, only the number of lockers is increased. -** All scripts containing superclasses of this script aret loaded recursively as well, -** unless 'recursive' is set to zero. -** The complementary function is "script_uninstantiate()" below. -*/ - +/** + * Decreases the numer of lockers of a script and unloads it if that number + * reaches zero. + * This function will recursively unload scripts containing its + * superclasses, if those aren't locked by other scripts as well. + * @param[in] s The state to operate on + * @param[in] script_nr The script number that is requestet to be unloaded + */ void script_uninstantiate(EngineState *s, int script_nr); -/* Decreases the numer of lockers of a script and unloads it if that number reaches zero -** Parameters: (EngineState *) s: The state to operate on -** (int) script_nr: The script number that is requestet to be unloaded -** Returns : (void) -** This function will recursively unload scripts containing its superclasses, if those -** aren't locked by other scripts as well. -*/ - +/** + * Initializes an SCI game + * This function must be run before script_run() is executed. Graphics data + * is initialized iff s->gfx_state != NULL. + * @param[in] s The state to operate on + * @return 0 on success, 1 if an error occured. + */ int game_init(EngineState *s); -/* Initializes an SCI game -** Parameters: (EngineState *) s: The state to operate on -** Returns : (int): 0 on success, 1 if an error occured. -** This function must be run before script_run() is executed. -** Graphics data is initialized iff s->gfx_state != NULL. -*/ +/** + * Initializes the graphics part of an SCI game + * This function may only be called if game_init() did not initialize + * the graphics data. + * @param[in] s The state to initialize the graphics in + * @return 0 on success, 1 if an error occured + */ int game_init_graphics(EngineState *s); -/* Initializes the graphics part of an SCI game -** Parameters: (EngineState *) s: The state to initialize the graphics in -** Returns : (int) 0 on success, 1 if an error occured -** This function may only be called if game_init() did not initialize -** the graphics data. -*/ +/** + * Initializes the sound part of an SCI game + * This function may only be called if game_init() did not initialize + * the sound data. + * @param[in] s The state to initialize the sound in + * @param[in] sound_flags Flags to pass to the sound subsystem + * @return 0 on success, 1 if an error occured + */ int game_init_sound(EngineState *s, int sound_flags); -/* Initializes the sound part of an SCI game -** Parameters: (EngineState *) s: The state to initialize the sound in -** (int) sound_flags: Flags to pass to the sound subsystem -** Returns : (int) 0 on success, 1 if an error occured -** This function may only be called if game_init() did not initialize -** the graphics data. -*/ - +/** + * Runs an SCI game + * This is the main function for SCI games. It takes a valid state, loads + * script 0 to it, finds the game object, allocates a stack, and runs the + * init method of the game object. In layman's terms, this runs an SCI game. + * Note that, EngineState *s may be changed during the game, e.g. if a game + * state is restored. + * @param[in] s Pointer to the pointer of the state to operate on + * @return 0 on success, 1 if an error occured. + */ int game_run(EngineState **s); -/* Runs an SCI game -** Parameters: (EngineState **) s: Pointer to the pointer of the state to operate on -** Returns : (int): 0 on success, 1 if an error occured. -** This is the main function for SCI games. It takes a valid state, loads script 0 to it, -** finds the game object, allocates a stack, and runs the init method of the game object. -** In layman's terms, this runs an SCI game. -** By the way, *s may be changed during the game, e.g. if a game state is restored. -*/ +/** + * Restores an SCI game state and runs the game + * This restores a savegame; otherwise, it behaves just like game_run(). + * @param[in] s Pointer to the pointer of the state to + * operate on + * @param[in] savegame_name Name of the savegame to restore + * @return 0 on success, 1 if an error occured. + */ int game_restore(EngineState **s, char *savegame_name); -/* Restores an SCI game state and runs the game -** Parameters: (EngineState **) s: Pointer to the pointer of the state to operate on -** (char *) savegame_name: Name of the savegame to restore -** Returns : (int): 0 on success, 1 if an error occured. -** This restores a savegame; otherwise, it behaves just like game_run(). -*/ +/** + * Uninitializes an initialized SCI game + * This function should be run after each script_run() call. + * @param[in] s The state to operate on + * @return 0 on success, 1 if an error occured. + */ int game_exit(EngineState *s); -/* Uninitializes an initialized SCI game -** Parameters: (EngineState *) s: The state to operate on -** Returns : (int): 0 on success, 1 if an error occured. -** This function should be run after each script_run() call. -*/ +/** + * Instructs the virtual machine to abort + */ void quit_vm(); -/* Instructs the virtual machine to abort -** Paramteres: (void) -** Returns : (void) -*/ +/** + * Allocates "kernel" memory and returns a handle suitable to be passed on + * to SCI scripts + * @param[in] s Pointer to the EngineState to operate on + * @param[in] type A free-form type description string (static) + * @param[in] space The space to allocate + * @return The handle + */ reg_t kalloc(EngineState *s, const char *type, int space); -/* Allocates "kernel" memory and returns a handle suitable to be passed on to SCI scripts -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (const char *) type: A free-form type description string (static) -** (int) space: The space to allocate -** Returns : (reg_t) The handle -*/ +/** + * Returns a pointer to "kernel" memory based on the handle + * @param[in] s Pointer to the EngineState to operate on + * @param[in] handle The handle to use + * @return A pointer to the allocated memory + */ byte *kmem(EngineState *s, reg_t handle); -/* Returns a pointer to "kernel" memory based on the handle -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) handle: The handle to use -** Returns : (byte *) A pointer to the allocated memory -*/ - +/** + * Frees all "kernel" memory associated with a handle + * @param[in] s Pointer to the EngineState to operate on + * @param[in] handle The handle to free + * @return 0 on success, 1 otherwise + */ int kfree(EngineState *s, reg_t handle); -/* Frees all "kernel" memory associated with a handle -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) handle: The handle to free -** Returns : (int) 0 on success, 1 otherwise -*/ +/** + * Determines the name of an object + * @param[in] s Pointer to the EngineState to operate on + * @param[in] pos Location of the object whose name we want to inspect + * @return A name for that object, or a string describing an error + * that occured while looking it up. The string is stored + * in a static buffer and need not be freed (neither may + * it be modified). + */ const char *obj_get_name(EngineState *s, reg_t pos); -/* Determines the name of an object -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) pos: Location of the object whose name we want to -** inspect -** Returns : (const char *) A name for that object, or a string describing -** an error that occured while looking it up -** The string is stored in a static buffer and need not be freed (neither -** may it be modified). -*/ +/** + * Retrieves an object from the specified location + * @param[in] s Pointer to the EngineState to operate on + * @param[in] offset The object's offset + * @return The object in question, or NULL if there is none + */ Object *obj_get(EngineState *s, reg_t offset); -/* Retrieves an object from the specified location -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) offset: The object's offset -** Returns : (Object *) The object in question, or NULL if there is none -*/ +/** + * Shrink execution stack to size. + * Contains an assert it is not already smaller. + */ void shrink_execution_stack(EngineState *s, uint size); -/* Shrink execution stack to size. -** Contains an assert it is not already smaller. -*/ } // End of namespace Sci diff --git a/engines/sci/engine/vm_types.h b/engines/sci/engine/vm_types.h index 40a5d464ac..cf7ba2573c 100644 --- a/engines/sci/engine/vm_types.h +++ b/engines/sci/engine/vm_types.h @@ -48,6 +48,14 @@ struct reg_t { bool operator!=(const reg_t &x) const { return (offset != x.offset) || (segment != x.segment); } + + uint16 toUint16() const { + return offset; + } + + int16 toSint16() const { + return (int16) offset; + } }; #define PRINT_REG(r) (0xffff) & (unsigned) (r).segment, (unsigned) (r).offset diff --git a/engines/sci/gfx/font.cpp b/engines/sci/gfx/font.cpp index 3aa1747cab..0f1a19f1c0 100644 --- a/engines/sci/gfx/font.cpp +++ b/engines/sci/gfx/font.cpp @@ -104,7 +104,7 @@ bool gfxr_font_calculate_size(Common::Array<TextFragment> &fragments, gfx_bitmap } if (last_breakpoint == 0) { - GFXWARN("Warning: maxsize %d too small for '%s'\n", max_width, text); + warning("[GFX] maxsize %d too small for '%s'", max_width, text); } if (last_breakpoint > maxwidth) @@ -197,7 +197,7 @@ gfx_pixmap_t *gfxr_draw_font(gfx_bitmap_font_t *font, const char *stext, int cha int colors_nr = !!fg0 + !!fg1 + !!bg; if (colors_nr == 0) { - GFXWARN("Pixmap would have zero colors, resetting!\n"); + warning("[GFX] Pixmap would have zero colors, resetting"); colors_nr = 3; hack = 1; fg0 = fg1 = bg = &dummy; diff --git a/engines/sci/gfx/font.h b/engines/sci/gfx/font.h index 935414f550..fe0d81d135 100644 --- a/engines/sci/gfx/font.h +++ b/engines/sci/gfx/font.h @@ -30,6 +30,8 @@ namespace Sci { +/** @name Font operations and stuctures */ +/** @{ */ struct TextFragment { const char *offset; @@ -39,90 +41,109 @@ struct TextFragment { TextFragment(const char *o) : offset(o), length(0) {} }; - -struct gfx_bitmap_font_t { /* gfx_bitmap_font_t: Bitmap font information */ - int ID; /* Unique resource ID */ - - int chars_nr; /* Numer of available characters */ - - int *widths; /* chars_nr character widths, in pixels */ - - int row_size; /* Byte size of each pixel row. For unscaled fonts, this is - ** always 1, 2, or 4. Otherwise, it's a multiple of 4. - */ - - int line_height; /* Height of each text line (usually identical to height) */ - int height; /* Height for all characters, in pixel rows */ - int char_size; /* Amount of memory occupied by one character in data */ - - byte *data; /* Font data, consisting of 'chars_nr' entries of 'height' rows - ** of 'row_size' bytes. For each character ch, its first byte - ** (the topmost row) is located at (data + (charsize * ch)), and - ** its pixel width is widths[ch], provided that (ch < chars_nr). - */ - +/** + * Bitmap font information. + */ +struct gfx_bitmap_font_t { + int ID; /**< Unique resource ID */ + int chars_nr; /**< Numer of available characters */ + int *widths; /**< chars_nr character widths, in pixels */ + int row_size; /** + * Byte size of each pixel row. For unscaled fonts, + * this is always 1, 2, or 4. Otherwise, it's a + * multiple of 4. + */ + int line_height; /** + * Height of each text line (usually identical to + * height) + */ + int height; /**< Height for all characters, in pixel rows */ + int char_size; /** + * Amount of memory occupied by one character + * in data + */ + byte *data; /** + * Font data, consisting of 'chars_nr' entries + * of 'height' rows of 'row_size' bytes. For each + * character ch, its first byte (the topmost row) + * is located at (data + (charsize * ch)), and its + * pixel width is widths[ch], provided that + * (ch < chars_nr). + */ }; -/*******************/ -/* Font operations */ -/*******************/ - -/* SCI0, SCI01 and SCI1 all use the same font format. */ +/** + * Font handling flags. + * + * SCI0, SCI01 and SCI1 all use the same font format. + */ enum fontFlags { - kFontCountWhitespace = 1 << 0, // In SQ3, whitespace is included in text size - kFontNoNewlines = 1 << 1, // Don't treat newline characters - kFontIgnoreLF = 1 << 2 // Interpret CR LF sequences as a single newline, rather than two + kFontCountWhitespace = 1 << 0, //!< In SQ3, whitespace is included in text size + kFontNoNewlines = 1 << 1, //!< Don't treat newline characters + kFontIgnoreLF = 1 << 2 //!< Interpret CR LF sequences as a single newline, rather than two }; +/** + * Generates a bitmap font data structure from a resource. + * + * @param[in] id Resource ID of the resulting font + * @param[in] resource Pointer to the resource data + * @param[in] size Size of the resource block + * @return The resulting font structure, or NULL on error + */ gfx_bitmap_font_t *gfxr_read_font(int id, byte *resource, int size); -/* Generates a bitmap font data structure from a resource -** Parameters: (int) id: Resource ID of the resulting font -** (byte *) resource: Pointer to the resource data -** (int) size: Size of the resource block -** Returns : (gfx_bitmap_font_t *) The resulting font structure, or -** NULL on error -*/ +/** + * Frees a previously allocated font structure. + * + * @param font The font to free + */ void gfxr_free_font(gfx_bitmap_font_t *font); -/* Frees a previously allocated font structure -** Parameters: (gfx_bitmap_font_t *) font: The font to free -** Returns : (void) -*/ +/** + * Calculates the size that would be occupied by drawing a specified + * text. + * + * This function assumes 320x200 mode. + * + * @param[in] font The font to calculate with + * @param[in] max_width Maximum pixel width allowed for the output + * @param[in] text The text to calculate for + * @param[in] flags Any text formatting flags + * @param[out] fragments A newly allocated array of text_fragments, + * containing the start and size of each string + * segment. + * @param[out] width The resulting width + * @param[out] height The resulting height + * @param[out] line_height Pixel height of a single line of text + * @param[out] last_offset Pixel offset after the last drawn line + * @return true if successful, false otherwise + */ bool gfxr_font_calculate_size(Common::Array<TextFragment> &fragments, gfx_bitmap_font_t *font, int max_width, const char *text, int *width, int *height, int *line_height, int *last_offset, int flags); -/* Calculates the size that would be occupied by drawing a specified text -** Parameters: (gfx_bitmap_font_t *) font: The font to calculate with -** (int) max_width: Maximum pixel width allowed for the output -** (const char *) text: The text to calculate for -** (int) flags: Any text formatting flags -** Returns : (text_fragment *) a newly allocated array of text_fragments, -** containing the start and size of each string -** segment -** (int) *width: The resulting width -** (int) *height: The resulting height -** (int) *line_height: Pixel height of a single line of text -** (int) *last_offset: Pixel offset after the last drawn line -** This function assumes 320x200 mode. -*/ - -gfx_pixmap_t *gfxr_draw_font(gfx_bitmap_font_t *font, const char *text, int characters, - PaletteEntry *fg0, PaletteEntry *fg1, PaletteEntry *bg); -/* Draws text in a specific font to a pixmap -** Parameters: (gfx_bitmap_font_t *) font: The font to use for drawing -** (char *) text: The start of the text to draw -** (int) characters: The number of characters to draw -** (gfx_pixmap_color_t *) fg0: The first foreground color -** (gfx_pixmap_color_t *) fg1: The second foreground color -** (gfx_pixmap_color_t *) bg: The background color -** Returns : (gfx_pixmap_t *) The result pixmap, or NULL on error -** The results are written to the pixmap's index buffer. Contents of the -** foreground and background fields are copied into a newly allocated font -** structure, so that the pixmap may be translated directly. -** If any of the colors is null, it will be assumed to be transparent. -** In color index mode, the specified colors have to be preallocated. -*/ + +/** + * Draws text in a specific font to a pixmap. + * + * The results are written to the pixmap's index buffer. Contents of the + * foreground and background fields are copied into a newly allocated font + * structure, so that the pixmap may be translated directly. If any of the + * colors is null, it will be assumed to be transparent. + * In color index mode, the specified colors have to be preallocated. + * + * @param[in] font The font to use for drawing + * @param[in] text The start of the text to draw + * @param[in] characters The number of characters to draw + * @param[in] fg0 The first foreground color + * @param[in] fg1 The second foreground color + * @param[in] bg The background color + * @return The result pixmap, or NULL on error + */ +gfx_pixmap_t *gfxr_draw_font(gfx_bitmap_font_t *font, const char *text, + int characters, PaletteEntry *fg0, PaletteEntry *fg1, + PaletteEntry *bg); +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp index f905244011..04ee5a9a4b 100644 --- a/engines/sci/gfx/gfx_driver.cpp +++ b/engines/sci/gfx/gfx_driver.cpp @@ -25,6 +25,7 @@ #include "common/scummsys.h" #include "common/system.h" +#include "graphics/cursorman.h" #include "graphics/primitives.h" #include "graphics/surface.h" @@ -284,7 +285,7 @@ byte *GfxDriver::createCursor(gfx_pixmap_t *pointer) { int GfxDriver::setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot) { if ((pointer == NULL) || (hotspot == NULL)) { - g_system->showMouse(false); + CursorMan.showMouse(false); } else { byte *cursorData = createCursor(pointer); @@ -298,8 +299,8 @@ int GfxDriver::setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot) { if (!pointer->palette) color_key = 63; - g_system->setMouseCursor(cursorData, pointer->width, pointer->height, hotspot->x, hotspot->y, color_key); - g_system->showMouse(true); + CursorMan.replaceCursor(cursorData, pointer->width, pointer->height, hotspot->x, hotspot->y, color_key); + CursorMan.showMouse(true); delete[] cursorData; cursorData = 0; diff --git a/engines/sci/gfx/gfx_driver.h b/engines/sci/gfx/gfx_driver.h index 4017dc3918..cc8a5208d4 100644 --- a/engines/sci/gfx/gfx_driver.h +++ b/engines/sci/gfx/gfx_driver.h @@ -40,170 +40,202 @@ enum gfx_buffer_t { }; -/* Principial graphics driver architecture -** --------------------------------------- -** -** All graphics drivers must provide -** - One visual front buffer (the actually visible thing) -** - Two dynamic back buffers: -** + visual -** + priority -** - Two static buffers (containing the background image and picviews): -** + visual -** + priority -** -** The control buffer is handled outside the graphics driver architecture. -** Graphics are drawn by first setting the static buffers, then updating -** the back buffers (from the static buffers), adding all picviews and other -** widgets, and finally updating the front buffer. -** -** All coordinates refer to the scaled coordinate system. -** Invalid parameters should produce an error message. -** Support for some valid parameter values is optional (like different line -** modes). If an unsupported but valid parameter is specified, the function -** must use a reasonable default value. -*/ - +/** + * Graphics driver. + * + * Principial graphics driver architecture: + * + * All graphics drivers must provide + * - One visual front buffer (the actually visible thing) + * - Two dynamic back buffers: + * - visual + * - priority + * - Two static buffers (containing the background image and picviews): + * - visual + * - priority + * + * The control buffer is handled outside the graphics driver architecture. + * Graphics are drawn by first setting the static buffers, then updating + * the back buffers (from the static buffers), adding all picviews and other + * widgets, and finally updating the front buffer. + * + * All coordinates refer to the scaled coordinate system. + * Invalid parameters should produce an error message. + * Support for some valid parameter values is optional (like different line + * modes). If an unsupported but valid parameter is specified, the function + * must use a reasonable default value. + */ class GfxDriver { public: - /*** Initialization ***/ - + /** @name Initialization */ + /** @{ */ + /** + * Attempts to initialize a specific graphics mode. + * + * The scaling factors apply to the standard SCI resolution of 320x200 + * pixels and is used for internal representation of graphical data. + * The physical resolution set by the graphics driver may be different + * for practical reasons. + * Must also set _mode, preferably with the gfx_new_mode() function + * specified in gfx_tools.h. + * + * @param[in] xfact Horizontal scaling factor + * @param[in] yfact Vertical scaling factor + * @param[in] bytespp Any of GFX_COLOR_MODE_*. GFX_COLOR_MODE_INDEX + * implies color index mode. + * @return GFX_OK on success, GFX_ERROR if the mode could + * not be set, or GFX_FATAL if the graphics target + * is unuseable. + */ GfxDriver(int xfact, int yfact, Graphics::PixelFormat mode); - /* Attempts to initialize a specific graphics mode - ** Parameters: (int x int) xres, yres: Horizontal and vertical scaling - ** factors - ** (PixelFormat) mode: The mode to use - ** Returns : (int) GFX_OK on success, GFX_ERROR if the mode could not be - ** set, or GFX_FATAL if the graphics target is unuseable. - ** The scaling factors apply to the standard SCI resolution of 320x200 pixels - ** and is used for internal representation of graphical data. The physical - ** resolution set by the graphics driver may be different for practical - ** reasons. - ** Must also set _mode, preferably with the gfx_new_mode() function - ** specified in gfx_tools.h. - */ + /** + * Uninitializes the current graphics mode. + * + * This function frees all memory allocated by the graphics driver, + * including mode and palette information, uninstalls all console + * commands introduced by preceeding init() or init_specific() + * commands, and does any clean-up work (like closing visuals or + * returning to text mode) required by the graphics infrastructure used. + */ ~GfxDriver(); - /* Uninitializes the current graphics mode - ** This function frees all memory allocated by the graphics driver, - ** including mode and palette information, uninstalls all console commands - ** introduced by preceeding init() or init_specific() commands, and does any - ** clean-up work (like closing visuals or returning to text mode) required by - ** the graphics infrastructure used. - */ - - - /*** Drawing operations ***/ - + /** @} */ + + /** @name Drawing operations */ + /** @{ */ + + /** + * Draws a single line to the back buffer. + * + * Note that color.priority is relevant and must be drawn if + * (color.mask & GFX_MASK_PRIORITY). Support for line modes other than + * GFX_LINE_MODE_FAST is optional. For non-fine lines, the coordinates + * provided describe the upper left corner of the pixels of the line + * to draw.line_style support is optional, if + * GFX_CAPABILITY_STIPPLED_LINES is not set. + * + * @param[in] start Starting point of the line to draw + * @param[in] end End point of the line to draw + * @param[in] color The color to draw with + * @param[in] line_mode Any of the line modes + * @param[in] line_style Any of the line styles + * @return GFX_OK or GFX_FATAL + */ int drawLine(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); - /* Draws a single line to the back buffer. - ** Parameters: (Common::Point) start: Starting point of the line to draw - ** (Common::Point) end: End point of the line to draw - ** (gfx_color_t *) color: The color to draw with - ** (int) line_mode: Any of the line modes - ** (int) line_style: Any of the line styles - ** Returns : (int) GFX_OK or GFX_FATAL - ** Note that color.priority is relevant and must be drawn if - ** (color.mask & GFX_MASK_PRIORITY). - ** Support for line modes other than GFX_LINE_MODE_FAST is optional. - ** For non-fine lines, the coordinates provided describe the upper left - ** corner of the pixels of the line to draw. - ** line_style support is optional, if GFX_CAPABILITY_STIPPLED_LINES is not - ** set. - */ + /** + * Draws a single filled and possibly shaded rectangle to the back + * buffer. + * + * Note that color.priority is relevant and must be drawn if + * (color.mask & GFX_MASK_PRIORITY). color2 is relevant only if + * shade_mode is not GFX_SHADE_FLAT. Support for shade modes other + * than GFX_SHADE_FLAT is optional. + * + * @param[in] rect The rectangle to draw + * @param[in] color1 The first color to draw with + * @param[in] color2 The second color to draw with + * @param[in] shade_mode Any of GFX_SHADE_*. + * @return GFX_OK or GFX_FATAL + */ int drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color2, gfx_rectangle_fill_t shade_mode); - /* Draws a single filled and possibly shaded rectangle to the back buffer. - ** Parameters: (rect_t *) rect: The rectangle to draw - ** (gfx_color_t *) color1, color2: The colors to draw with - ** (int) shade_mode: Any of GFX_SHADE_*. - ** Returns : (int) GFX_OK or GFX_FATAL - ** Note that color.priority is relevant and must be drawn if - ** (color.mask & GFX_MASK_PRIORITY). - ** color2 is relevant only if shade_mode is not GFX_SHADE_FLAT. - ** Support for shade modes other than GFX_SHADE_FLAT is optional. - */ - - /*** Pixmap operations ***/ - + /** @} */ + + /** @name Pixmap operations */ + /** @{ */ + + /** + * Draws part of a pixmap to the static or back buffer. + * + * @param[in] pxm The pixmap to draw + * @param[in] priority The priority to draw with, or GFX_NO_PRIORITY + * to draw on top of everything without setting the + * priority back buffer. + * @param[in] src The pixmap-relative source rectangle + * @param[in] dest The destination rectangle + * @param[in] buffer One of GFX_BUFFER_STATIC and GFX_BUFFER_BACK + * @return GFX_OK or GFX_FATAL, or GFX_ERROR if pxm was + * not (but should have been) registered. + */ int drawPixmap(gfx_pixmap_t *pxm, int priority, rect_t src, rect_t dest, gfx_buffer_t buffer); - /* Draws part of a pixmap to the static or back buffer - ** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw - ** (int) priority: The priority to draw with, or GFX_NO_PRIORITY - ** to draw on top of everything without setting the - ** priority back buffer - ** (rect_t) src: The pixmap-relative source rectangle - ** (rect_t) dest: The destination rectangle - ** (int) buffer: One of GFX_BUFFER_STATIC and GFX_BUFFER_BACK - ** Returns : (int) GFX_OK or GFX_FATAL, or GFX_ERROR if pxm was not - ** (but should have been) registered. - */ + /** + * Grabs an image from the visual or priority back buffer. + * + * This function is now mandatory. + * + * @param[in] src The rectangle to grab + * @param[in] pxm The pixmap structure the data is to be written to + * @param[in] map GFX_MASK_VISUAL or GFX_MASK_PRIORITY + * @return GFX_OK, GFX_FATAL, or GFX_ERROR for invalid map + * values pxm may be assumed to be empty and + * pre-allocated with an appropriate memory size. + */ int grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map); - /* Grabs an image from the visual or priority back buffer - ** Parameters: (rect_t) src: The rectangle to grab - ** (gfx_pixmap_t *) pxm: The pixmap structure the data is to - ** be written to - ** (int) map: GFX_MASK_VISUAL or GFX_MASK_PRIORITY - ** Returns : (int) GFX_OK, GFX_FATAL, or GFX_ERROR for invalid map values - ** pxm may be assumed to be empty and pre-allocated with an appropriate - ** memory size. - ** This function is now mandatory. - */ - - - /*** Buffer operations ***/ - + /** @} */ + + /** @name Buffer operations */ + /** @{ */ + + /** + * Updates the front buffer or the back buffers. + * + * This function updates either the visual front buffer, or the two + * back buffers, by copying the specified source region to the + * destination region. + * For heuristical reasons, it may be assumed that the x and y fields + * of src and dest will be identical in /most/ cases.If they aren't, + * the priority map will not be required to be copied. + * + * @param[in] src: Source rectangle + * @param[in] dest: Destination point + * @param[in] buffer: One of GFX_BUFFER_FRONT or GFX_BUFFER_BACK + * @return GFX_OK, GFX_ERROR or GFX_FATAL + */ int update(rect_t src, Common::Point dest, gfx_buffer_t buffer); - /* Updates the front buffer or the back buffers - ** Parameters: (rect_t) src: Source rectangle - ** (Common::Point) dest: Destination point - ** (int) buffer: One of GFX_BUFFER_FRONT or GFX_BUFFER_BACK - ** Returns : (int) GFX_OK, GFX_ERROR or GFX_FATAL - ** This function updates either the visual front buffer, or the two back - ** buffers, by copying the specified source region to the destination - ** region. - ** For heuristical reasons, it may be assumed that the x and y fields of - ** src and dest will be identical in /most/ cases. - ** If they aren't, the priority map will not be required to be copied. - */ + /** + * Sets the contents of the static visual and priority buffers. + * + * pic and priority may be modified or written to freely. They may also + * be used as the actual static buffers, since they are not freed and + * reallocated between calls to set_static_buffer() and update(), + * unless exit() was called in between. + * Note that later version of the driver interface may disallow + * modifying pic and priority. pic and priority are always scaled to + * the appropriate resolution + * + * @param[in] pic The image defining the new content of the + * visual back buffer + * @param[in] priority The priority map containing the new content of + * the priority back buffer in the index buffer + * @return GFX_OK or GFX_FATAL + */ int setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority); - /* Sets the contents of the static visual and priority buffers - ** Parameters: (gfx_pixmap_t *) pic: The image defining the new content - ** of the visual back buffer - ** (gfx_pixmap_t *) priority: The priority map containing - ** the new content of the priority back buffer - ** in the index buffer - ** Returns : (int) GFX_OK or GFX_FATAL - ** pic and priority may be modified or written to freely. They may also be - ** used as the actual static buffers, since they are not freed and re- - ** allocated between calls to set_static_buffer() and update(), unless - ** exit() was called in between. - ** Note that later version of the driver interface may disallow modifying - ** pic and priority. - ** pic and priority are always scaled to the appropriate resolution - */ - - - /*** Mouse pointer operations ***/ - + /** @} */ + + /** @name Mouse pointer operations */ + /** @{ */ + + /** + * Sets a new mouse pointer. + * + * If pointer is not NULL, it will have been scaled to the appropriate + * size and registered as a pixmap (if neccessary) beforehand. If this + * function is called for a target that supports only two-color + * pointers, the image is a color index image, where only color index + * values 0, 1, and GFX_COLOR_INDEX_TRANSPARENT are used. + * + * @param[in] pointer The pointer to set, or NULL to set no pointer. + * @param[in] hotspot The coordinates of the hotspot, or NULL to set + * no pointer. + * @return GFX_OK or GFX_FATAL + */ int setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot); - /* Sets a new mouse pointer. - ** Parameters: (gfx_pixmap_t *) pointer: The pointer to set, or NULL to set - ** no pointer - ** (Common::Point *) hotspot: The coordinates of the hotspot, - ** or NULL to set no pointer - ** Returns : (int) GFX_OK or GFX_FATAL - ** If pointer is not NULL, it will have been scaled to the appropriate - ** size and registered as a pixmap (if neccessary) beforehand. - ** If this function is called for a target that supports only two-color - ** pointers, the image is a color index image, where only color index values - ** 0, 1, and GFX_COLOR_INDEX_TRANSPARENT are used. - */ + /** @} */ gfx_mode_t *getMode() { return _mode; } byte *getVisual0() { return _visual[0]; } @@ -213,7 +245,7 @@ private: gfx_pixmap_t *_priority[2]; byte *_visual[2]; - gfx_mode_t *_mode; /* Currently active mode, NULL if no mode is active */ + gfx_mode_t *_mode; /**< Currently active mode, NULL if no mode is active */ }; } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_gui.cpp b/engines/sci/gfx/gfx_gui.cpp index f73a13d6dd..fb05c0fe29 100644 --- a/engines/sci/gfx/gfx_gui.cpp +++ b/engines/sci/gfx/gfx_gui.cpp @@ -266,7 +266,7 @@ static rect_t _move_and_extend_rect(rect_t rect, Common::Point point, int yplus) return gfx_rect(rect.x + point.x, rect.y + point.y, rect.width + 1, rect.height + yplus); } -GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, char *text, +GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, const char *text, int font, gfx_alignment_t align, char framed, char inverse, int flags, char gray_text) { gfx_color_t *color1, *color2, *bgcolor; @@ -294,7 +294,7 @@ GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, char return list; } -GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, char selected, char inverse, char grayed_out) { +GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, char selected, char inverse, char grayed_out) { gfx_color_t *frame_col = (inverse) ? &(port->_bgcolor) : &(port->_color); GfxList *list; @@ -332,7 +332,7 @@ GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, char *tex return list; } -GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, +GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, gfx_alignment_t align, char framed, char inverse) { GfxList *list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 2), 0); @@ -344,7 +344,7 @@ GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, char *text, return _sciw_add_text_to_list(list, port, zone, text, font, align, framed, inverse, 0, port->gray_text); } -GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, unsigned int cursor, +GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, unsigned int cursor, char inverse) { GfxText *text_handle; @@ -440,7 +440,7 @@ GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, int view, i return list; } -GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, char **entries_list, +GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, const char **entries_list, int entries_nr, int list_top, int selection, char inverse) { GfxList *list; diff --git a/engines/sci/gfx/gfx_gui.h b/engines/sci/gfx/gfx_gui.h index e712d30660..68342aa0c0 100644 --- a/engines/sci/gfx/gfx_gui.h +++ b/engines/sci/gfx/gfx_gui.h @@ -23,8 +23,6 @@ * */ -/* SCI-specific widget handling */ - #ifndef SCI_INCLUDE_SCI_WIDGETS_H #define SCI_INCLUDE_SCI_WIDGETS_H @@ -34,152 +32,196 @@ namespace Sci { class Menu; -// The following flags are applicable to windows in SCI0 +/* SCI-specific widget handling */ + +/** + * Flags for windows in SCI0. + */ enum windowFlags { - kWindowTransparent = 0x01, // 0000 0001 - kWindowNoFrame = 0x02, // 0000 0010 - a window without a frame - // Add title bar to window (10 pixels high, framed, text is centered and written in white on dark gray) - kWindowTitle = 0x04, // 0000 0100 - // bits 3-6 are unused - kWindowDontDraw = 0x80, // 1000 0000 - don't draw anything - kWindowNoDropShadow = 0x1000000, // 0001 0000 0000 0000 0000 0000 0000 (not in SCI) + kWindowTransparent = 0x01, //!< 0000 0001 + kWindowNoFrame = 0x02, //!< 0000 0010 - a window without a frame + kWindowTitle = 0x04, /** + * 0000 0100 - Add title bar to + * window (10 pixels high, framed, + * text is centered and written in + * white on dark gray), bits 3-6 + * are unused + */ + kWindowDontDraw = 0x80, //!< 1000 0000 - don't draw anything + kWindowNoDropShadow = 0x1000000, //!< 0001 0000 0000 0000 0000 0000 0000 (not in SCI) kWindowAutoRestore = 0x2000000 }; +/** Button and frame control flags. */ enum controlStateFlags { - kControlStateEnabled = 0x0001, // 0001 - enabled buttons (used by the interpreter) - kControlStateDisabled = 0x0004, // 0010 - grayed out buttons (used by the interpreter) - kControlStateFramed = 0x0008, // 1000 - widgets surrounded by a frame (used by the interpreter) - kControlStateDitherFramed = 0x1000 // 0001 0000 0000 0000 - widgets surrounded by a dithered frame (used in kgraphics) + kControlStateEnabled = 0x0001, //!< 0001 - enabled buttons (used by the interpreter) + kControlStateDisabled = 0x0004, //!< 0010 - grayed out buttons (used by the interpreter) + kControlStateFramed = 0x0008, //!< 1000 - widgets surrounded by a frame (used by the interpreter) + kControlStateDitherFramed = 0x1000 //!< 0001 0000 0000 0000 - widgets surrounded by a dithered frame (used in kgraphics) }; -void sciw_set_status_bar(EngineState *s, GfxPort *status_bar, const Common::String &text, int fgcolor, int bgcolor); -/* Sets the contents of a port used as status bar -** Parmeters: (EngineState *) s: The affected game state -** (GfxPort *) status_bar: The status bar port -** (const char *) text: The text to draw -** Returns : (void) -*/ - -GfxPort *sciw_new_window(EngineState *s, rect_t area, int font, gfx_color_t color, gfx_color_t bgcolor, - int title_font, gfx_color_t title_color, gfx_color_t title_bg_color, - const char *title, int flags); -/* Creates a new SCI style window -** Parameters: (EngineState *) s: The affected game state -** (rect_t) area: The screen area to frame (not including a potential window title) -** (int) font: Default font number to use -** (gfx_color_t) color: The foreground color to use for drawing -** (gfx_color_t) bgcolor: The background color to use -** (int) title_font: The font to use for the title bar (if any) -** (gfx_color_t) title_color: Color to use for the title bar text -** (gfx_color_t) title_bg_color: Color to use for the title bar background -** (const char *) title: The text to write into the title bar -** (int) flags: Any ORred combination of window flags -** Returns : (GfxPort *) A newly allocated port with the requested characteristics -*/ - -/*---------------------*/ -/*** Control widgets ***/ -/*---------------------*/ - -GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, char selected, char inverse, char gray); -/* Creates a new button control list -** Parameters: (GfxPort *) port: The port containing the color values to use for the -** button (the button is /not/ appended to the port there) -** (reg_t) ID: Button's ID -** (rect_t) zone: The area occupied by the button -** (char *) text: The text to write into the button -** (int) font: The font to use for the button -** (char) selected: Whether the button should be marked as being selected by the keyboard focus -** (char) inverse: Whether to inverse the color scheme -** (char) gray: Whether the button should be grayed out -** Returns : (GfxList *) The button -*/ - -GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, - gfx_alignment_t align, char frame, char inverse); -/* Creates a new text control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (reg_t) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (char *) text: The text -** (int) font: The font the text is to be drawn in -** (gfx_alignment_t) align: Horizontal text alignment to use -** (char) frame: Whether a dithered frame should surround the text -** (char) inverse: Whether the text colors should be inversed -** Returns : (GfxList *) The text control widget list -*/ - -GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, unsigned int cursor, - char inverse); -/* Creates a new edit control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (reg_t) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (char *) text: The text -** (int) font: The font the text is to be drawn in -** (int) cursor: Cursor position -** (char) inverse: Whether the edit widget should be reversed -** Returns : (GfxList *) An appropriate widget list -*/ - -GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, int view, int loop, int cel, - char frame, char inverse); -/* Creates a new icon control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (reg_t) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (int x int x int) view, loop, cel: The cel to display -** (char) frame: Whether the widget should be surrounded by a frame -** (char) lina inverse: Whether colors should be inversed -** Returns : (GfxList *) An appropriate widget list -*/ - -GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, char **entries_list, - int entries_nr, int list_top, int selection, char inverse); -/* Creates a new list control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (int) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (int) font_nr: number of the font to use -** (char **) entries_list: List of strings to contain within the list -** (int) entries_nr: Number of entries in entries_list -** (int) list_top: First list item that is visible -** (int) selection: The list item that is selected -** (char) invserse: The usual meaning -** Returns : (GfxList *) An appropriate widget list -*/ - -/*---------------------*/ -/*** Menubar widgets ***/ -/*---------------------*/ - -void sciw_set_menubar(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection); -/* Draws the menu bar -** Parameters: (EngineState *) s: The state to operate on -** (GfxPort *) status_bar: The status bar port to modify -** (Menubar *) menubar: The menu bar to use -** (int) selection: Number of the menu to hightlight, or -1 for 'none' -** Returns : (void) -*/ - -GfxPort *sciw_new_menu(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection); -/* Creates a menu port -** Parameters: (EngineState *) s: The state to operate on -** (GfxPort *) status_bar: The status bar -** (Menubar *) menubar: The menu bar to use -** (int) selection: Number of the menu to interpret -** Returns : (GfxPort *) The result port -*/ - -GfxPort *sciw_toggle_item(GfxPort *menu_port, Menu *menu, int selection, bool selected); -/* Toggle the selection of a menu item from a menu port -** Parameters: (GfxPort *) menu_port: The port to modify -** (Menu *) menu: The menu the menu port corresponds to -** (int) selection: Number of the menu entry to unselect, or -1 to do a NOP -** (bool) selected: Whether to set the item's state to selected or not -** Returns : (GfxPort *) The modified menu -*/ +/** + * Sets the contents of a port used as status bar. + * + * @param[in] s The affected EngineState + * @param[in] status_bar The status bar port + * @param[in] text The text to draw + * @param[in] fgcolor The foreground color + * @param[in] bgcolor The background color + */ +void sciw_set_status_bar(EngineState *s, GfxPort *status_bar, + const Common::String &text, int fgcolor, int bgcolor); + +/** + * Creates a new SCI style window. + * + * @param[in] s The affected EngineState + * @param[in] area The screen area to frame (not including a + * potential window title) + * @param[in] font Default font number to use + * @param[in] color The foreground color to use for drawing + * @param[in] bgcolor The background color to use + * @param[in] title_font The font to use for the title bar (if any) + * @param[in] title_color Color to use for the title bar text + * @param[in] title_bg_color Color to use for the title bar background + * @param[in] title The text to write into the title bar + * @param[in] flags Any ORred combination of window flags + * @return A newly allocated port with the requested characteristics + */ +GfxPort *sciw_new_window(EngineState *s, rect_t area, int font, + gfx_color_t color, gfx_color_t bgcolor, int title_font, + gfx_color_t title_color, gfx_color_t title_bg_color, + const char *title, int flags); + + +/** @name Control widgets */ +/** @{ */ +/** + * Creates a new button control list. + * + * @param[in] port The port containing the color values to use for the + * button (the button is /not/ appended to the port + * there) + * @param[in] ID Button's ID + * @param[in] zone The area occupied by the button + * @param[in] text The text to write into the button + * @param[in] font The font to use for the button + * @param[in] selected Whether the button should be marked as being + * selected by the keyboard focus + * @param[in] inverse Whether to inverse the color scheme + * @param[in] gray Whether the button should be grayed out + * @return The button + */ +GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, + const char *text, int font, char selected, char inverse, char gray); + +/** + * Creates a new text control list. + * + * @param[in] port The port containing the color values to use + * @param[in] ID Text widget ID + * @param[in] zone Area occupied by the text + * @param[in] text The text + * @param[in] font The font the text is to be drawn in + * @param[in] align Horizontal text alignment to use + * @param[in] frame Whether a dithered frame should surround the text + * @param[in] inverse Whether the text colors should be inversed + * @return The text control widget list + */ +GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, + const char *text, int font, gfx_alignment_t align, char frame, + char inverse); + +/** + * Creates a new edit control list. + * + * @param[in] port The port containing the color values to use + * @param[in] ID Text widget ID + * @param[in] zone Area occupied by the text + * @param[in] text The text + * @param[in] font The font the text is to be drawn in + * @param[in] cursor Cursor position + * @param[in] inverse Whether the edit widget should be reversed + * @return An appropriate widget list + */ +GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, + const char *text, int font, unsigned int cursor, char inverse); + +/** + * Creates a new icon control list. + * + * @param[in] port The port containing the color values to use + * @param[in] ID Text widget ID + * @param[in] zone Area occupied by the text + * @param[in] view The view index + * @param[in] loop The loop index + * @param[in] cel The cel to display + * @param[in] frame Whether the widget should be surrounded by a frame + * @param[in] inverse Whether colors should be inversed + * @return An appropriate widget list + */ +GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, + int view, int loop, int cel, char frame, char inverse); + +/** + * Creates a new list control list. + * + * @param[in] port: The port containing the color values to use + * @param[in] ID: Text widget ID + * @param[in] zone: Area occupied by the text + * @param[in] font_nr: Number of the font to use + * @param[in] entries_list: List of strings to contain within the list + * @param[in] entries_nr: Number of entries in entries_list + * @param[in] list_top: First list item that is visible + * @param[in] selection: The list item that is selected + * @param[in] inverse: The usual meaning + * @return An appropriate widget list + */ +GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, + int font_nr, const char **entries_list, int entries_nr, + int list_top, int selection, char inverse); +/** @} */ + +/** @name Menubar widgets */ +/** @{ */ + +/** + * Draws the menu bar. + * + * @param[in] s: The EngineState to operate on + * @param[in] status_bar: The status bar port to modify + * @param[in] menubar: The menu bar to use + * @param[in] selection: Number of the menu to hightlight, or -1 for + * 'none' + */ +void sciw_set_menubar(EngineState *s, GfxPort *status_bar, Menubar *menubar, + int selection); + +/** + * Creates a menu port. + * + * @param[in] s The state to operate on + * @param[in] status_bar The status bar + * @param[in] menubar The menu bar to use + * @param[in] selection Number of the menu to interpret + * @return The result port + */ +GfxPort *sciw_new_menu(EngineState *s, GfxPort *status_bar, + Menubar *menubar, int selection); + +/** + * Toggle the selection of a menu item from a menu port. + * + * @param[in] menu_port The port to modify + * @param[in] menu The menu the menu port corresponds to + * @param[in] selection Number of the menu entry to unselect, or -1 to do + * a NOP + * @param[in] selected Whether to set the item's state to selected or not + * @return The modified menu + */ +GfxPort *sciw_toggle_item(GfxPort *menu_port, Menu *menu, int selection, + bool selected); +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_options.h b/engines/sci/gfx/gfx_options.h index 393627a1a2..2e2b853562 100644 --- a/engines/sci/gfx/gfx_options.h +++ b/engines/sci/gfx/gfx_options.h @@ -42,20 +42,20 @@ namespace Sci { -/* Dirty rectangle heuristics: */ - -/* One: Redraw one rectangle surrounding the dirty area (insert is O(1)) */ -#define GFXOP_DIRTY_FRAMES_ONE 1 - -/* Clusters: Accumulate dirty rects, merging those that overlap (insert is O(n)) */ -#define GFXOP_DIRTY_FRAMES_CLUSTERS 2 +/** Dirty rectangle heuristics. */ +enum { + GFXOP_DIRTY_FRAMES_ONE = 1, /**< One: Redraw one rectangle surrounding the dirty area (insert is O(1)) */ + GFXOP_DIRTY_FRAMES_CLUSTERS = 2 /**< Clusters: Accumulate dirty rects, merging those that overlap (insert is O(n)) */ +}; +/** + * All user options to the rendering pipeline + * + * See note in sci_conf.h for config_entry_t before changing types of + * variables + */ struct gfx_options_t { #ifdef CUSTOM_GRAPHICS_OPTIONS - /* gfx_options_t: Contains all user options to the rendering pipeline */ - /* See note in sci_conf.h for config_entry_t before changing types of - ** variables */ - int buffer_pics_nr; /* Number of unused pics to buffer */ /* SCI0 pic resource options */ diff --git a/engines/sci/gfx/gfx_res_options.h b/engines/sci/gfx/gfx_res_options.h index f01f93d21b..a595c56606 100644 --- a/engines/sci/gfx/gfx_res_options.h +++ b/engines/sci/gfx/gfx_res_options.h @@ -23,8 +23,6 @@ * */ -/* Configuration options for per-resource customisations */ - #ifndef SCI_GFX_GFX_RES_OPTIONS_H #define SCI_GFX_GFX_RES_OPTIONS_H @@ -35,13 +33,16 @@ #include "sci/gfx/gfx_resmgr.h" namespace Sci { +/** @name Configuration options for per-resource customisations */ +/** @{ */ struct gfx_res_pattern_t { int min, max; }; -/* GFX resource assignments */ - +/** + * GFX resource assignments. + */ struct gfx_res_assign_t { union { struct { @@ -52,23 +53,24 @@ struct gfx_res_assign_t { }; -/* GFX resource modifications */ - +/** + * GFX resource modifications/ + */ struct gfx_res_conf_t { - int type; /* Resource type-- only one allowed */ + int type; /**< Resource type-- only one allowed */ /* If any of the following is 0, it means that there is no restriction. ** Otherwise, one of the patterns associated with them must match. */ - int patterns_nr; /* Number of patterns (only 'view' patterns for views) */ - int loops_nr, cels_nr; /* Number of loop/cel patterns, for views only. + int patterns_nr; /**< Number of patterns (only 'view' patterns for views) */ + int loops_nr, cels_nr; /**< Number of loop/cel patterns, for views only. ** For pics, loops_nr identifies the palette. */ gfx_res_pattern_t *patterns; union { gfx_res_assign_t assign; - byte factor[3]; /* divide by 16 to retrieve factor */ - } conf; /* The actual configuration */ + byte factor[3]; /**< divide by 16 to retrieve factor */ + } conf; /**< The actual configuration */ gfx_res_conf_t *next; }; @@ -84,16 +86,20 @@ struct gfx_res_fullconf_t { struct gfx_options_t; +/** + * Configures a graphical pixmap according to config options. + * + * Modifies pxm as considered appropriate by configuration options. Does + * not do anything in colour index mode. + * + * @param[in] options The options according to which configuration + * should be performed + * @param[in] pxm The pixmap to configure + * @return 0 on success, non-zero otherwise + */ int gfx_get_res_config(gfx_options_t *options, gfx_pixmap_t *pxm); -/* Configures a graphical pixmap according to config options -** Parameters: (gfx_options_t *) options: The options according to which -** configuration should be performed -** (gfx_resource_type_t) pxm: The pixmap to configure -** Returns : (int) 0 on success, non-zero otherwise -** Modifies pxm as considered appropriate by configuration options. Does -** not do anything in colour index mode. -*/ +/** @} */ } // End of namespace Sci #endif diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp index 229470a658..1b76c65ff4 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -59,15 +59,15 @@ GfxResManager::GfxResManager(int version, bool isVGA, gfx_options_t *options, Gf if (_version < SCI_VERSION_01_VGA || !_isVGA) { _staticPalette = gfx_sci0_pic_colors->getref(); } else if (_version == SCI_VERSION_1_1) { - GFXDEBUG("Palettes are not yet supported in this SCI version\n"); + debugC(2, kDebugLevelGraphics, "Palettes are not yet supported in this SCI version\n"); #ifdef ENABLE_SCI32 } else if (_version == SCI_VERSION_32) { - GFXDEBUG("Palettes are not yet supported in this SCI version\n"); + debugC(2, kDebugLevelGraphics, "Palettes are not yet supported in this SCI version\n"); #endif } else { - Resource *res = resManager->findResource(kResourceTypePalette, 999, 0); + Resource *res = resManager->findResource(ResourceId(kResourceTypePalette, 999), 0); if (res && res->data) - _staticPalette = gfxr_read_pal1(res->id, res->data, res->size); + _staticPalette = gfxr_read_pal1(res->id.number, res->data, res->size); } } @@ -77,7 +77,7 @@ GfxResManager::~GfxResManager() { } int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, int flags, int default_palette, int nr) { - Resource *res = _resManager->findResource(kResourceTypePic, nr, 0); + Resource *res = _resManager->findResource(ResourceId(kResourceTypePic, nr), 0); int need_unscaled = unscaled_pic != NULL; gfxr_pic0_params_t style, basic_style; @@ -97,18 +97,18 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic if (need_unscaled) { if (_version == SCI_VERSION_1_1) - gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id, _staticPalette, _portBounds); + gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _staticPalette, _portBounds); else - gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id, _isVGA, _staticPalette, _portBounds); + gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _isVGA, _staticPalette, _portBounds); } if (scaled_pic && scaled_pic->undithered_buffer) memcpy(scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer, scaled_pic->undithered_buffer_size); if (_version == SCI_VERSION_1_1) - gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id, _staticPalette, _portBounds); + gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _staticPalette, _portBounds); else - gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id, _isVGA, _staticPalette, _portBounds); + gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _isVGA, _staticPalette, _portBounds); if (!_isVGA) { if (need_unscaled) @@ -201,7 +201,7 @@ void gfxr_free_resource(gfx_resource_t *resource, int type) { break; default: - GFXWARN("Attempt to free invalid resource type %d\n", type); + warning("[GFX] Attempt to free invalid resource type %d", type); } free(resource); @@ -474,7 +474,7 @@ gfxr_pic_t *GfxResManager::addToPic(int old_nr, int new_nr, int flags, int old_d res = resMap.contains(old_nr) ? resMap[old_nr] : NULL; if (!res) { - GFXWARN("Attempt to add pic %d to non-existing pic %d\n", new_nr, old_nr); + warning("[GFX] Attempt to add pic %d to non-existing pic %d", new_nr, old_nr); return NULL; } } @@ -525,7 +525,7 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { res = resMap.contains(nr) ? resMap[nr] : NULL; if (!res || res->mode != hash) { - Resource *viewRes = _resManager->findResource(kResourceTypeView, nr, 0); + Resource *viewRes = _resManager->findResource(ResourceId(kResourceTypeView, nr), 0); if (!viewRes || !viewRes->data) return NULL; @@ -579,26 +579,26 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { *loop = CLIP<int>(*loop, 0, view->loops_nr - 1); if (*loop < 0) { - GFXWARN("View %d has no loops\n", nr); + warning("[GFX] View %d has no loops", nr); return NULL; } loop_data = view->loops + (*loop); if (loop_data == NULL) { - GFXWARN("Trying to load invalid loop %d of view %d\n", *loop, nr); + warning("[GFX] Trying to load invalid loop %d of view %d", *loop, nr); return NULL; } *cel = CLIP<int>(*cel, 0, loop_data->cels_nr - 1); if (*cel < 0) { - GFXWARN("View %d loop %d has no cels\n", nr, *loop); + warning("[GFX] View %d loop %d has no cels", nr, *loop); return NULL; } cel_data = loop_data->cels[*cel]; if (loop_data == NULL) { - GFXWARN("Trying to load invalid view/loop/cel %d/%d/%d\n", nr, *loop, *cel); + warning("[GFX] Trying to load invalid view/loop/cel %d/%d/%d", nr, *loop, *cel); return NULL; } @@ -622,11 +622,11 @@ gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) { res = resMap.contains(num) ? resMap[num] : NULL; if (!res || res->mode != hash) { - Resource *fontRes = _resManager->findResource(kResourceTypeFont, num, 0); + Resource *fontRes = _resManager->findResource(ResourceId(kResourceTypeFont, num), 0); if (!fontRes || !fontRes->data) return NULL; - gfx_bitmap_font_t *font = gfxr_read_font(fontRes->id, fontRes->data, fontRes->size); + gfx_bitmap_font_t *font = gfxr_read_font(fontRes->id.number, fontRes->data, fontRes->size); if (!res) { res = (gfx_resource_t *)malloc(sizeof(gfx_resource_t)); @@ -659,12 +659,12 @@ gfx_pixmap_t *GfxResManager::getCursor(int num) { res = resMap.contains(num) ? resMap[num] : NULL; if (!res || res->mode != hash) { - Resource *cursorRes = _resManager->findResource(kResourceTypeCursor, num, 0); + Resource *cursorRes = _resManager->findResource(ResourceId(kResourceTypeCursor, num), 0); if (!cursorRes || !cursorRes->data) return NULL; if (_version >= SCI_VERSION_1_1) { - GFXWARN("Attempt to retrieve cursor in SCI1.1 or later\n"); + warning("[GFX] Attempt to retrieve cursor in SCI1.1 or later"); return NULL; } diff --git a/engines/sci/gfx/gfx_resmgr.h b/engines/sci/gfx/gfx_resmgr.h index c5878bf529..1f0f58dce9 100644 --- a/engines/sci/gfx/gfx_resmgr.h +++ b/engines/sci/gfx/gfx_resmgr.h @@ -49,7 +49,7 @@ enum gfx_resource_type_t { GFX_RESOURCE_TYPE_PALETTE, /* FIXME: Add PAL resource */ - GFX_RESOURCE_TYPES_NR /* Number of resource types that are to be supported */ + GFX_RESOURCE_TYPES_NR /**< Number of resource types that are to be supported */ }; #define GFX_RESOURCE_TYPE_0 GFX_RESOURCE_TYPE_VIEW @@ -58,12 +58,13 @@ enum gfx_resource_type_t { #define GFXR_RES_TYPE(id) (id >> 16) #define GFXR_RES_NR(id) (id & 0xffff) - +/** Graphics resource */ struct gfx_resource_t { - int ID; /* Resource ID */ - int lock_sequence_nr; /* See description of lock_counter in GfxResManager */ - int mode; /* A mode type hash */ + int ID; /**< Resource ID */ + int lock_sequence_nr; /**< See description of lock_counter in GfxResManager */ + int mode; /**< A mode type hash */ + /** Scaled pic */ union { gfx_pixmap_t *pointer; gfxr_view_t *view; @@ -71,6 +72,7 @@ struct gfx_resource_t { gfxr_pic_t *pic; } scaled_data; + /** Original pic */ union { gfx_pixmap_t *pointer; gfxr_view_t *view; @@ -85,152 +87,204 @@ struct gfx_options_t; typedef Common::HashMap<int, gfx_resource_t *> IntResMap; - +/** Graphics resource manager */ class GfxResManager { public: - GfxResManager(int version, bool isVGA, gfx_options_t *options, GfxDriver *driver, ResourceManager *resManager); + GfxResManager(int version, bool isVGA, gfx_options_t *options, + GfxDriver *driver, ResourceManager *resManager); ~GfxResManager(); - /* Calculates a unique hash value for the specified options/type setup - ** Parameters: (gfx_resource_type_t) type: The type the hash is to be generated for - ** Returns : (int) A hash over the values of the options entries, covering entries iff - ** they are relevant for the specified type - ** Covering more entries than relevant may slow down the system when options are changed, - ** while covering less may result in invalid cached data being used. - ** Only positive values may be returned, as negative values are used internally by the generic - ** resource manager code. - ** Also, only the lower 20 bits are available to the interpreter. - ** (Yes, this isn't really a "hash" in the traditional sense...) - */ + /** + * Calculates a unique hash value for the specified options/type + * setup. + * + * Covering more entries than relevant may slow down the system when + * options are changed, while covering less may result in invalid + * cached data being used. + * Only positive values may be returned, as negative values are used + * internally by the generic resource manager code. + * Also, only the lower 20 bits are available to the interpreter. + * (Yes, this isn't really a "hash" in the traditional sense...) + * + * @param[in] type The type the hash is to be generated for + * @return A hash over the values of the options entries, + * covering entries iff they are relevant for the + * specified type. + */ int getOptionsHash(gfx_resource_type_t type); - /* 'Tags' all resources for deletion - ** Paramters: (void) - ** Returns : (void) - ** Tagged resources are untagged if they are referenced. - */ + /** + * 'Tags' all resources for deletion. + * + * Tagged resources are untagged if they are referenced. + */ void tagResources() { _tagLockCounter++; } - /* Retrieves an SCI0/SCI01 mouse cursor - ** Parameters: (int) num: The cursor number - ** Returns : (gfx_font_t *) The approprate cursor as a pixmap, or NULL on error - */ + /** + * Retrieves an SCI0/SCI01 mouse cursor. + * + * @param[in] num The cursor number + * @return The approprate cursor as a pixmap, or NULL on error + */ gfx_pixmap_t *getCursor(int num); - /* Retrieves the static palette from the interpreter-specific code - ** Parameters: (int *) colors_nr: Number of colors to use - ** (int) nr: The palette to read - ** Returns : (Palette *) static palette - ** if a static palette must be used, NULL otherwise - */ + /** + * Retrieves the static palette from the interpreter-specific code. + * + * @param[in] colors_nr Number of colors to use + * @param[in] num The palette to read + * @return Static palette if a static palette must be + * used, NULL otherwise + */ Palette *getPalette(int *colors_nr, int num = 999); - /* Retrieves a font - ** Parameters: (int) nr: The font number - ** (int) scaled: Whether the font should be font-scaled - ** Returns : (gfx_font_t *) The appropriate font, or NULL on error - */ + /** + * Retrieves a font. + * + * @param[in] num The font number + * @param[in] scaled Whether the font should be font-scaled + * @return The appropriate font, or NULL on error + */ gfx_bitmap_font_t *getFont(int num, bool scaled = false); - /* Retrieves a translated view cel - ** Parameters: - ** (int) nr: The view number - ** (int *) loop: Pointer to a variable containing the loop number - ** (int *) cel: Pointer to a variable containing the cel number - ** (int) palette: The palette to use - ** Returns : (gfx_view_t *) The relevant view, or NULL if nr was invalid - ** loop and cel are given as pointers in order to allow the underlying variables to be - ** modified if they are invalid (this is relevant for SCI version 0, where invalid - ** loop and cel numbers have to be interpreted as 'maximum' or 'minimum' by the interpreter) - */ + /** + * Retrieves a translated view cel. + * + * @param[in] nr The view number + * @param[in] loop Pointer to a variable containing the loop number + * @param[in] cel Pointer to a variable containing the cel number + * @param[in] palette The palette to use + * @return The relevant view, or NULL if nr was invalid + * loop and cel are given as pointers in order to + * allow the underlying variables to be modified + * if they are invalid (this is relevant for SCI + * version 0, where invalid loop and cel numbers + * have to be interpreted as 'maximum' or 'minimum' + * by the interpreter) + */ gfxr_view_t *getView(int nr, int *loop, int *cel, int palette); - /* Retrieves a displayable (translated) pic resource - ** Parameters: (int) nr: Number of the pic resource - ** (int) maps: The maps to translate (ORred GFX_MASK_*) - ** (int) flags: Interpreter-dependant pic flags - ** (int) default_palette: The default palette to use for drawing (if applicable) - ** (bool) scaled: Whether to return the scaled maps, or the unscaled - ** ones (which may be identical) for some special operations. - ** Returns : (gfxr_pic_t *) The appropriate pic resource with all maps as index (but not - ** neccessarily translated) data. - */ - gfxr_pic_t *getPic(int num, int maps, int flags, int default_palette, bool scaled = false); - - - /* Retrieves a displayable (translated) pic resource written ontop of an existing pic - ** Parameters: (int) old_nr: Number of the pic resource to write on - ** (int) new_nr: Number of the pic resource that is to be added - ** (int) flags: Interpreter-dependant pic flags - ** (int) default_palette: The default palette to use for drawing (if applicable) - ** (int) scaled: Whether to return the scaled maps, or the unscaled - ** ones (which may be identical) for some special operations. - ** Returns : (gfxr_pic_t *) The appropriate pic resource with all maps as index (but not - ** neccessarily translated) data. - ** This function invalidates the cached pic pointed to by old_nr in the cache. While subsequent - ** addToPic() writes will still modify the 'invalidated' pic, gfxr_get_pic() operations will - ** cause it to be removed from the cache and to be replaced by a clean version. - */ - gfxr_pic_t *addToPic(int old_nr, int new_nr, int flags, int old_default_palette, int default_palette); - - /* Calculate a picture - ** Parameters: (gfxr_pic_t *) scaled_pic: The pic structure that is to be written to - ** (gfxr_pic_t *) unscaled_pic: The pic structure the unscaled pic is to be written to, - ** or NULL if it isn't needed. - ** (int) flags: Pic drawing flags (interpreter dependant) - ** (int) default_palette: The default palette to use for pic drawing (interpreter dependant) - ** (int) nr: pic resource number - ** Returns : (int) GFX_ERROR if the resource could not be found, GFX_OK otherwise - */ - int calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, int flags, int default_palette, int nr); - - /* Determines whether support for pointers with more than two colors is required - ** Returns : (bool) false if no support for multi-colored pointers is required, true - ** otherwise - */ + /** + * Retrieves a displayable (translated) pic resource. + * + * @param[in] num Number of the pic resource + * @param[in] maps The maps to translate (ORred GFX_MASK_*) + * @param[in] flags Interpreter-dependant pic flags + * @param[in] default_palette The default palette to use for drawing + * (if applicable) + * @param[in] scaled Whether to return the scaled maps, or + * the unscaled ones (which may be + * identical) for some special operations. + * @return The appropriate pic resource with all + * maps as index (but not neccessarily + * translated) data. + */ + gfxr_pic_t *getPic(int num, int maps, int flags, int default_palette, + bool scaled = false); + + + /** + * Retrieves a displayable (translated) pic resource written ontop of + * an existing pic. + * + * This function invalidates the cached pic pointed to by old_nr in the + * cache. While subsequent addToPic() writes will still modify the + * 'invalidated' pic, gfxr_get_pic() operations will cause it to be + * removed from the cache and to be replaced by a clean version. + * + * @param[in] old_nr Number of the pic resource to write on + * @param[in] new_nr Number of the pic resource that is to + * be added + * @param[in] flags Interpreter-dependant pic flags + * @param[in] old_default_palette The default palette of the pic before + * translation + * @param[in] default_palette The default palette to use for drawing + * (if applicable) + * @return The appropriate pic resource with all + * maps as index (but not neccessarily + * translated) data. + */ + gfxr_pic_t *addToPic(int old_nr, int new_nr, int flags, + int old_default_palette, int default_palette); + + /** + * Calculate a picture + * + * @param[in] scaled_pic The pic structure that is to be + * written to + * @param[in] unscaled_pic The pic structure the unscaled pic is + * to be written to, or NULL if it isn't + * needed. + * @param[in] flags Pic drawing flags (interpreter + * dependant) + * @param[in] default_palette The default palette to use for pic + * drawing (interpreter dependant) + * @param[in] nr pic resource number + * @return GFX_ERROR if the resource could not be + * found, GFX_OK otherwise + */ + int calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, + int flags, int default_palette, int nr); + + /** + * Determines whether support for pointers with more than two colors + * is required. + * + * @return false if no support for multi-colored pointers is required, + * true otherwise + */ bool multicoloredPointers() { return _version > SCI_VERSION_1; } - /* Frees all resources currently allocated - ** Parameter: (void) - ** Returns : (void) - ** This function is intended to be used primarily for debugging. - */ + /** + * Frees all resources currently allocated. + * + * This function is intended to be used primarily for debugging. + */ void freeAllResources(); - /* Frees all tagged resources. - ** Parameters: (void) - ** Returns : (void) - ** Resources are tagged by calling gfx_tag_resources(), and untagged by calling the - ** approprate dereferenciation function. - ** Note that this function currently only affects view resources, as pic resources are - ** treated differently, while font and cursor resources are relatively rare. - */ + /** + * Frees all tagged resources. + * + * Resources are tagged by calling gfx_tag_resources(), and untagged by + * calling the approprate dereferenciation function. + * Note that this function currently only affects view resources, as + * pic resources are treated differently, while font and cursor + * resources are relatively rare. + */ void freeTaggedResources(); - /* Frees a previously allocated resource manager, and all allocated resources. - ** Parameters: (void) - ** Return : (void) - */ + /** + * Frees a previously allocated resource manager, and all allocated + * resources. + */ void freeResManager(); - const PaletteEntry &getColor(int color) { return _staticPalette->getColor(color); } + /** + * Retrieves a color from the static palette + */ + const PaletteEntry &getColor(int color) + { + return _staticPalette->getColor(color); + } - // Set static palette and merge it into the global palette + /** + * Set static palette and merge it into the global palette + */ void setStaticPalette(Palette *newPalette); - /* - ** Sets the picture port bounds - */ + /** + * Sets the picture port bounds + */ void changePortBounds(int x1, int y1, int x2, int y2) { _portBounds = Common::Rect(x1, y1, x2, y2); } @@ -252,7 +306,15 @@ public: } #endif - int getColorCount() { return _staticPalette ? _staticPalette->size() : 0; } + /** + * Gets the number of colors in the static palette. + * + * @return Number of pallete entries + */ + int getColorCount() + { + return _staticPalette ? _staticPalette->size() : 0; + } private: int _version; @@ -260,11 +322,11 @@ private: gfx_options_t *_options; GfxDriver *_driver; Palette *_staticPalette; - int _lockCounter; /* Global lock counter; increased for each new resource allocated. - ** The newly allocated resource will then be assigned the new value - ** of the lock_counter, as will any resources referenced afterwards. - */ - int _tagLockCounter; /* lock counter value at tag time */ + int _lockCounter; /**< Global lock counter; increased for each new + * resource allocated. The newly allocated resource will + * then be assigned the new value of the lock_counter, + * as will any resources referenced afterwards. */ + int _tagLockCounter; /**< lock counter value at tag time */ Common::Rect _portBounds; IntResMap _resourceMaps[GFX_RESOURCE_TYPES_NR]; diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h index 8ce4a8ea83..780060bc4f 100644 --- a/engines/sci/gfx/gfx_resource.h +++ b/engines/sci/gfx/gfx_resource.h @@ -23,7 +23,9 @@ * */ -/* SCI Resource library */ +/** @file gfx_resource.h + * SCI Resource library. + */ #ifndef SCI_GFX_GFX_RESOURCE_H #define SCI_GFX_GFX_RESOURCE_H @@ -44,6 +46,7 @@ namespace Sci { #define GFXR_DITHER_MODE_D16 0 /* Sierra SCI style */ #define GFXR_DITHER_MODE_F256 1 /* Flat color interpolation */ #define GFXR_DITHER_MODE_D256 2 /* 256 color dithering */ + /* Dithering patterns */ #define GFXR_DITHER_PATTERN_SCALED 0 /* Dither per pixel on the 320x200 grid */ #define GFXR_DITHER_PATTERN_1 1 /* Dither per pixel on the target */ @@ -64,52 +67,53 @@ namespace Sci { extern int sci0_palette; -/* (gfx_pic_0.c) The 16 EGA base colors */ +/** The 16 EGA base colors */ extern Palette* gfx_sci0_image_pal[]; extern gfx_pixmap_color_t gfx_sci0_image_colors[][16]; -/* (gfx_pic_0.c) The 256 interpolated colors (initialized when -** gfxr_init_pic() is called for the first time, or when gfxr_init_static_palette() is called) -*/ +/** + * The 256 interpolated colors (initialized when gfxr_init_pic() is called + * for the first time, or when gfxr_init_static_palette() is called) + */ extern Palette* gfx_sci0_pic_colors; - struct gfxr_pic0_params_t { gfx_line_mode_t line_mode; /* one of GFX_LINE_MODE_* */ gfx_brush_mode_t brush_mode; }; +/** A SCI resource pic */ struct gfxr_pic_t { - int ID; /* pic number (NOT resource ID, just number) */ + int ID; /**< pic number (NOT resource ID, just number) */ gfx_mode_t *mode; - gfx_pixmap_t *visual_map; - gfx_pixmap_t *priority_map; - gfx_pixmap_t *control_map; - + gfx_pixmap_t *visual_map; /**< Visual part of pic */ + gfx_pixmap_t *priority_map; /**< Priority map for pic */ + gfx_pixmap_t *control_map; /**< Control map for pic */ + + /** + * Auxiliary map. + * Bit 0: Vis + * Bit 1: Pri + * Bit 2: Ctrl + * Bit 3-5: 'filled' (all three bits are set to 1) + */ byte aux_map[GFXR_AUX_MAP_SIZE]; - /* Auxiliary map details: - ** Bit 0: Vis - ** Bit 1: Pri - ** Bit 2: Ctrl - ** Bit 3-5: 'filled' (all three bits are set to 1) - */ - // rect_t bounds; // unused - void *undithered_buffer; /* copies visual_map->index_data before dithering */ + void *undithered_buffer; /**< copies visual_map->index_data before dithering */ int undithered_buffer_size; int *priorityTable; }; - +/** A animation loop */ struct gfxr_loop_t { - int cels_nr; - gfx_pixmap_t **cels; + int cels_nr; /**< Number of 'cels' or frames in the animation */ + gfx_pixmap_t **cels; /**< Pointer to the pixmaps for the cels */ }; - +/** A graphics view */ struct gfxr_view_t { int ID; @@ -122,172 +126,197 @@ struct gfxr_view_t { int translation[GFX_SCI0_IMAGE_COLORS_NR]; }; +/** + * Initializes the static 256 color palette. + */ void gfxr_init_static_palette(); -/* Initializes the static 256 color palette -** Parameters: (void) -** Returns : (void) -*/ - -gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, int sci1); -/* Initializes a gfxr_pic_t for a specific mode -** Parameters: (gfx_mode_t *) mode: The specific graphics mode -** (int) ID: The ID to assign to the resulting pixmaps -** Returns : (gfxr_pic_t *) The allocated pic resource, or NULL on error. -** This function allocates memory for use by resource drawer functions. -*/ -void gfxr_free_pic(gfxr_pic_t *pic); -/* Uninitializes a pic resource -** Parameters: (gfxr_pic_t *) pic: The pic to free -** Returns : (void) -*/ - -void gfxr_free_view(gfxr_view_t *view); -/* Frees all memory associated with a view -** Paremeters: (gfxr_view_t *) view: The view to free -** Returns : (void) -*/ +/** @name Resource picture management functions */ +/** @{ */ +/** + * Initializes a gfxr_pic_t for a specific mode. + * + * This function allocates memory for use by resource drawer functions. + * + * @param[in] mode The specific graphics mode + * @param[in] ID The ID to assign to the resulting pixmaps + * @param[in] sci1 true if a SCI1 pic, false otherwise + * @return The allocated pic resource, or NULL on error. + */ +gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, bool sci1); +/** + * Uninitializes a pic resource. + * + * @param[in] pic The pic to free + */ +void gfxr_free_pic(gfxr_pic_t *pic); +/** + * Frees all memory associated with a view. + * + * @param[in] view The view to free + */ +void gfxr_free_view(gfxr_view_t *view); +/** @} */ +/** @name SCI0 resource picture operations */ +/** @{ */ -/*********************/ -/* SCI0 operations */ -/*********************/ +/** + * Clears all pic buffers of one pic/ + * + * This function should be called before gfxr_draw_pic0, unless cumulative + * drawing is intended + * + * @param[in] pic The picture to clear + * @param[in] titlebar_size How much space to reserve for the title bar + */ +void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size); +/** + * Draws a pic resource (all formats prior to SCI1.1). + * + * The result is stored in gfxr_visual_map, gfxr_priority_map, and + * gfxr_control_map. The palette entry of gfxr_visual_map is never used. + * Note that the picture will not be drawn dithered; use gfxr_dither_pic0 + * for that. + * + * @param[in] pic The pic to draw to + * @param[in] fill_normally If 1, the pic is drawn normally; if 0, all + * fill operations will fill with black + * @param[in] default_palette The default palette to use for drawing + * @param[in] size Resource size + * @param[in] resource Pointer to the resource data + * @param[in] style The drawing style + * @param[in] resid The resource ID + * @param[in] sci1 true if SCI1, false otherwise + * @param[in] static_pal The static palette + * @param[in] portBounds The bounds of the port being drawn to + */ +void gfxr_draw_pic01(gfxr_pic_t *pic, int fill_normally, + int default_palette, int size, byte *resource, + gfxr_pic0_params_t *style, int resid, int sci1, + Palette *static_pal, Common::Rect portBounds); -void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size); -/* Clears all pic buffers of one pic -** Parameters: (gfxr_pic_t) pic: The picture to clear -** (int) titlebar_size: How much space to reserve for the title bar -** Returns : (void) -** This function should be called before gfxr_draw_pic0, unless cumulative -** drawing is intended -*/ - - -void gfxr_draw_pic01(gfxr_pic_t *pic, int fill_normally, int default_palette, - int size, byte *resource, gfxr_pic0_params_t *style, int resid, int sci1, - Palette *static_pal, Common::Rect portBounds); -/* Draws a pic resource (all formats prior to SCI1.1) -** Parameters: (gfxr_pic_t *) pic: The pic to draw to -** (int) fill_normally: If 1, the pic is drawn normally; if 0, all -** fill operations will fill with black -** (int) default_palette: The default palette to use for drawing -** (int) size: Resource size -** (byte *) resource: Pointer to the resource data -** (gfxr_pic0_params_t *) style: The drawing style -** (int) resid: The resource ID -** (int) sci1: Nonzero if SCI1 -** (Palette *) static_pal: The static palette -** (int) static_pal_nr: Number of entries in static palette -** Returns : (void) -** The result is stored in gfxr_visual_map, gfxr_priority_map, and gfxr_control_map. -** The palette entry of gfxr_visual_map is never used. -** Note that the picture will not be drawn dithered; use gfxr_dither_pic0 for that. -*/ - -void gfxr_draw_pic11(gfxr_pic_t *pic, int fill_normally, int default_palette, - int size, byte *resource, gfxr_pic0_params_t *style, int resid, - Palette *static_pal, Common::Rect portBounds); -/* Draws a pic resource (SCI1.1) -** Parameters: (gfxr_pic_t *) pic: The pic to draw to -** (int) fill_normally: If 1, the pic is drawn normally; if 0, all -** fill operations will fill with black -** (int) default_palette: The default palette to use for drawing -** (int) size: Resource size -** (byte *) resource: Pointer to the resource data -** (gfxr_pic0_params_t *) style: The drawing style -** (int) resid: The resource ID -** (Palette *) static_pal: The static palette -** (int) static_pal_nr: Number of entries in static palette -** Returns : (void) -** The result is stored in gfxr_visual_map, gfxr_priority_map, and gfxr_control_map. -** The palette entry of gfxr_visual_map is never used. -** Note that the picture will not be drawn dithered; use gfxr_dither_pic0 for that. -*/ +/** + * Draws a pic resource (SCI1.1). + * + * The result is stored in gfxr_visual_map, gfxr_priority_map, and + * gfxr_control_map. The palette entry of gfxr_visual_map is never used. + * Note that the picture will not be drawn dithered; use gfxr_dither_pic11 + * for that. + * + * @param[in] pic The pic to draw to + * @param[in] fill_normally If 1, the pic is drawn normally; if 0, all + * fill operations will fill with black + * @param[in] default_palette The default palette to use for drawing + * @param[in] size Resource size + * @param[in] resource Pointer to the resource data + * @param[in] style The drawing style + * @param[in] resid The resource ID + * @param[in] static_pal The static palette + * @param[in] portBounds Bounds of the port being drawn to + */ +void gfxr_draw_pic11(gfxr_pic_t *pic, int fill_normally, + int default_palette, int size, byte *resource, + gfxr_pic0_params_t *style, int resid, Palette *static_pal, + Common::Rect portBounds); +/** + * Removes artifacts from a scaled pic. + * + * Using information from the (correctly rendered) src pic, this function + * implements some heuristics to remove artifacts from dest. Must be used + * before dither_pic0 is called, because it operates on the index buffer. + * + * @param[in] dest The scaled pic + * @param[in] src An unscaled pic + */ void gfxr_remove_artifacts_pic0(gfxr_pic_t *dest, gfxr_pic_t *src); -/* Removes artifacts from a scaled pic -** Parameters: (gfxr_pic_t *) dest: The scaled pic -** (gfxr_pic_t *) src: An unscaled pic -** Returns : (void) -** Using information from the (correctly rendered) src pic, this function implements -** some heuristics to remove artifacts from dest. Must be used before dither_pic0 is -** called, because it operates on the index buffer. -*/ +/** + * Dithers a gfxr_visual_map. + * + * @param[in] pic The pic to dither + * @param[in] mode One of GFXR_DITHER_MODE + * @param[in] pattern One of GFXR_DITHER_PATTERN + */ void gfxr_dither_pic0(gfxr_pic_t *pic, int mode, int pattern); -/* Dithers a gfxr_visual_map -** Parameters: (gfxr_pic_t *) pic: The pic to dither -** (int) mode: One of GFXR_DITHER_MODE -** (int) pattern: One of GFXR_DITHER_PATTERN -** Returns : (void) -*/ +/** + * Calculates a SCI0 view. + * + * @param[in] id Resource ID of the view + * @param[in] resource Pointer to the resource to read + * @param[in] size Size of the resource + * @param[in] palette The palette to use + * @return The resulting view + */ gfxr_view_t *gfxr_draw_view0(int id, byte *resource, int size, int palette); -/* Calculates an SCI0 view -** Parameters: (int) id: Resource ID of the view -** (byte *) resource: Pointer to the resource to read -** (int) size: Size of the resource -** (int) palette: The palette to use -** Returns : (gfxr_view_t *) The resulting view -*/ - -gfx_pixmap_t *gfxr_draw_cursor(int id, byte *resource, int size, bool isSci01); -/* Calculates n SCI cursor -** Parameters: (int) id: The cursor's resource ID -** (byte *) resource: Pointer to the resource data -** (int) size: Resource size -** (bool) isSci01: Set to true to load a SCI1 cursor -** Returns : (gfx_pixmap_t *) A newly allocated pixmap containing an index -** color representation of the cursor -*/ - -/*********************/ -/* SCI1 operations */ -/*********************/ +/** + * Calculates a SCI cursor. + * + * @param[in] id The cursor's resource ID + * @param[in] resource Pointer to the resource data + * @param[in] size Resource size + * @param[in] isSci01 Set to true to load a SCI1 cursor + * @return A newly allocated pixmap containing an index color + * representation of the cursor + */ +gfx_pixmap_t *gfxr_draw_cursor(int id, byte *resource, int size, + bool isSci01); +/** @} */ + + +/** @name SCI1/1.1 resource picture operations */ +/** @{ */ + +/** + * Reads an SCI1 palette. + * + * @param[in] id Resource ID for the palette (or the view it was + * found in) + * @param[in] resource Source data + * @param[in] size Size of the memory block pointed to by resource + * @return Palette with the colors + */ Palette *gfxr_read_pal1(int id, byte *resource, int size); -/* Reads an SCI1 palette -** Parameters: (int) id: Resource ID for the palette (or the view it was found in) -** (int *) colors_nr: Pointer to the variable the number of colors -** will be stored in -** (byte *) resource: Source data -** (int) size: Size of the memory block pointed to by resource -** Returns : (Palette *) *colors_nr Palette with the colors -*/ +/** + * Reads an SCI1 palette. + * + * @param[in] file Palette file + * @return Palette with the colors + */ Palette *gfxr_read_pal1_amiga(Common::File &file); -/* Reads an SCI1 palette -** Parameters: (int *) colors_nr: Pointer to the variable the number of colors -** will be stored in -** (FILE *) f: Palette file -** Returns : (Palette *) Palette with the colors -*/ +/** + * Reads an SCI1.1 palette. + * + * @param[in] id Resource ID for the palette (or the view it was + * found in) + * @param[in] resource Source data + * @param[in] size Size of the memory block pointed to by resource + * @return Palette with the colors + */ Palette *gfxr_read_pal11(int id, byte *resource, int size); -/* Reads an SCI1.1 palette -** Parameters: (int) id: Resource ID for the palette (or the view it was found in) -** (int *) colors_nr: Pointer to the variable the number of colors -** will be stored in -** (byte *) resource: Source data -** (int) size: Size of the memory block pointed to by resource -** Returns : (Palette *) Palette with the colors -*/ +/** + * Calculates an SCI1 view. + * + * @param[in] id Resource ID of the view + * @param[in] resource Pointer to the resource to read + * @param[in] size Size of the resource + * @param[in] static_pal The static palette + * @param[in] isSci11 true if SCI1.1, false otherwise + * @return The resulting view + */ gfxr_view_t *gfxr_draw_view1(int id, byte *resource, int size, Palette *static_pal, bool isSci11); -/* Calculates an SCI1 view -** Parameters: (int) id: Resource ID of the view -** (byte *) resource: Pointer to the resource to read -** (int) size: Size of the resource -** (Palette *) static_pal: The static palette -** (int) static_pal_nr: Number of entries in static palette -** Returns : (gfxr_view_t *) The resulting view -*/ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, bool isAmiga, bool isSci11); - +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_state_internal.h b/engines/sci/gfx/gfx_state_internal.h index c184492054..3f00b5213c 100644 --- a/engines/sci/gfx/gfx_state_internal.h +++ b/engines/sci/gfx/gfx_state_internal.h @@ -34,14 +34,16 @@ namespace Sci { -#define GFXW_FLAG_VISIBLE (1<<0) -#define GFXW_FLAG_OPAQUE (1<<1) -#define GFXW_FLAG_CONTAINER (1<<2) -#define GFXW_FLAG_DIRTY (1<<3) -#define GFXW_FLAG_TAGGED (1<<4) -#define GFXW_FLAG_MULTI_ID (1<<5) /**< Means that the ID used herein may be used more than once, i.e. is not unique */ -#define GFXW_FLAG_IMMUNE_TO_SNAPSHOTS (1<<6) /**< Snapshot restoring doesn't kill this widget, and +5 bonus to saving throws vs. Death Magic */ -#define GFXW_FLAG_NO_IMPLICIT_SWITCH (1<<7) /**< Ports: Don't implicitly switch to this port when disposing windows */ +enum gfxw_flag_t { + GFXW_FLAG_VISIBLE = (1<<0), + GFXW_FLAG_OPAQUE = (1<<1), + GFXW_FLAG_CONTAINER = (1<<2), + GFXW_FLAG_DIRTY = (1<<3), + GFXW_FLAG_TAGGED = (1<<4), + GFXW_FLAG_MULTI_ID = (1<<5), /**< Means that the ID used herein may be used more than once, i.e. is not unique */ + GFXW_FLAG_IMMUNE_TO_SNAPSHOTS = (1<<6), /**< Snapshot restoring doesn't kill this widget, and +5 bonus to saving throws vs. Death Magic */ + GFXW_FLAG_NO_IMPLICIT_SWITCH = (1<<7) /**< Ports: Don't implicitly switch to this port when disposing windows */ +}; struct gfxw_snapshot_t { int serial; /**< The first serial number to kill */ @@ -82,6 +84,7 @@ struct GfxPort; typedef int gfxw_bin_op(GfxWidget *, GfxWidget *); +/** SCI graphics widget */ struct GfxWidget { public: int _magic; /**< Extra check after typecasting */ @@ -101,27 +104,28 @@ public: /** * The widget automatically removes itself from its owner, if it has one. - * Deleting a container will recursively free all of its - * contents. + * Deleting a container will recursively free all of its contents. */ virtual ~GfxWidget(); /** * Draws the widget. * - * The widget is drawn iff it is flagged as dirty. Invoking this operation on - * a container widget will recursively draw all of its contents. + * The widget is drawn iff it is flagged as dirty. Invoking this operation + * on a container widget will recursively draw all of its contents. * - * @param pos The position to draw to (added to the widget's internal position) + * @param[in] pos The position to draw to (added to the widget's + * internal position) */ virtual int draw(const Common::Point &pos) = 0; /** * Tags the specified widget. * - * If invoked on a container widget, this will also tag all of the container's - * contents (but not the contents' contents!) - * FIXME: Actually, the code in GfxContainer::tag contradicts the last claim! + * If invoked on a container widget, this will also tag all of the + * container's contents (but not the contents' contents!) + * FIXME: Actually, the code in GfxContainer::tag contradicts the last + * claim! */ virtual void tag() { _flags |= GFXW_FLAG_TAGGED; @@ -130,10 +134,10 @@ public: /** * Prints a string representation of the widget with sciprintf. * - * Will recursively print all of the widget's contents if the widget contains - * further sub-widgets + * Will recursively print all of the widget's contents if the widget + * contains further sub-widgets * - * @param indentation Number of double spaces to indent + * @param[in] indentation Number of double spaces to indent */ virtual void print(int indentation) const; @@ -143,55 +147,63 @@ public: * This comparison only applies to some widgets; compare_to(a,a)=0 is not * guaranteed. It may be used for sorting for all widgets. * - * @param other other widget - * @return <0, 0, or >0 if other is, respectively, less than, equal - * to, or greater than self + * @param other The other widget + * @return <0, 0, or >0 if other is, respectively, less than, equal + * to, or greater than self */ gfxw_bin_op *compare_to; /** * Compares two compareable widgets for equality. * - * This operation checks whether two widgets describe the same graphical data. - * It is used to determine whether a new widget should be discarded because it - * describes the same graphical data as an old widget that has already been - * drawn. For lists, it also checks whether all contents are in an identical - * order. + * This operation checks whether two widgets describe the same graphical + * data. It is used to determine whether a new widget should be discarded + * because it describes the same graphical data as an old widget that has + * already been drawn. For lists, it also checks whether all contents are + * in an identical order. * - * @param other other widget - * @return false if the widgets are not equal, true if they match + * @param[in] other The other widget + * @return false if the widgets are not equal, true if they match */ gfxw_bin_op *equals; /** - * Determine whether other should replace this even though they are equivalent. + * Determine whether other should replace this even though they are + * equivalent. * * When 'equals' returns true, this means that no new widget will be added. * However, in some cases newer widgets may contain information that should - * cause the older widget to be removed nonetheless; this is indicated by this - * function. + * cause the older widget to be removed nonetheless; this is indicated by + * this function. * - * @param other other widget - * @return false if this should be kept, true if this should be replaced by the 'other' + * @param[in] other The other widget + * @return false if this should be kept, true if this should be + * replaced by the 'other' */ gfxw_bin_op *should_replace; /** - * Tests whether drawing this after other would reduce all traces of other. + * Tests whether drawing this after other would reduce all traces of + * other. * - * /a superarea_of b <=> for each pixel of b there exists an opaque pixel in a at the same location + * /a superarea_of b <=> for each pixel of b there exists an opaque pixel + * in a at the same location * - * @param other the widget to compare for containment - * @return true if this is superarea_of other, false otherwise + * @param[in] other The widget to compare for containment + * @return true if this is superarea_of other, false otherwise */ gfxw_bin_op *superarea_of; /** * Sets the visual for the widget - * This function is called by container->add() and need not be invoked explicitly. - * It also makes sure that dirty rectangles are passed to parent containers. + * + * This function is called by container->add() and need not be invoked + * explicitly. It also makes sure that dirty rectangles are passed to + * parent containers. + * + * @param[in] visual GfxVisual to set for the widget */ - virtual int setVisual(GfxVisual *); + virtual int setVisual(GfxVisual *visual); //protected: void printIntern(int indentation) const; @@ -200,6 +212,7 @@ public: #define GFXW_IS_BOX(widget) ((widget)->_type == GFXW_BOX) +/** SCI box widget */ struct GfxBox : public GfxWidget { gfx_color_t _color1, _color2; gfx_box_shade_t _shadeType; @@ -213,6 +226,7 @@ public: #define GFXW_IS_PRIMITIVE(widget) ((widget)->_type == GFXW_RECT || (widget)->_type == GFXW_LINE) +/** SCI graphics primitive */ struct GfxPrimitive : public GfxWidget { gfx_color_t _color; gfx_line_mode_t _lineMode; @@ -227,6 +241,7 @@ public: #define GFXW_IS_VIEW(widget) ((widget)->_type == GFXW_VIEW || (widget)->_type == GFXW_STATIC_VIEW \ || (widget)->_type == GFXW_DYN_VIEW || (widget)->_type == GFXW_PIC_VIEW) +/** SCI graphics view */ struct GfxView : public GfxWidget { Common::Point _pos; /**< Implies the value of 'bounds' in GfxWidget */ gfx_color_t _color; @@ -242,10 +257,12 @@ public: }; #define GFXW_IS_DYN_VIEW(widget) ((widget)->_type == GFXW_DYN_VIEW || (widget)->_type == GFXW_PIC_VIEW) +/** SCI dynamic view */ struct GfxDynView : public GfxView { /* FIXME: This code is specific to SCI */ rect_t draw_bounds; /* The correct position to draw to */ - void *under_bitsp, *signalp; + ObjVarRef under_bitsp; + ObjVarRef signalp; int under_bits, signal; int _z; /**< The z coordinate: Added to y, but used for sorting */ int sequence; /**< Sequence number: For sorting */ @@ -264,6 +281,7 @@ public: #define GFXW_IS_TEXT(widget) ((widget)->_type == GFXW_TEXT) +/** SCI text widget */ struct GfxText : public GfxWidget { int _font; int lines_nr, lineheight, lastline_width; @@ -292,7 +310,7 @@ typedef int gfxw_unary_container_op(GfxContainer *); typedef int gfxw_container_op(GfxContainer *, GfxWidget *); typedef int gfxw_rect_op(GfxContainer *, rect_t, int); - +/** SCI container widget */ struct GfxContainer : public GfxWidget { rect_t zone; /**< The writeable zone (absolute) for contained objects */ DirtyRectList _dirtyRects; /**< List of dirty rectangles */ @@ -323,7 +341,7 @@ public: #define GFXW_IS_LIST(widget) ((widget)->_type == GFXW_LIST || (widget)->_type == GFXW_SORTED_LIST) #define GFXW_IS_SORTED_LIST(widget) ((widget)->_type == GFXW_SORTED_LIST) - +/** SCI graphics list */ struct GfxList : public GfxContainer { public: GfxList(rect_t area, bool sorted); @@ -333,6 +351,7 @@ public: }; #define GFXW_IS_VISUAL(widget) ((widget)->_type == GFXW_VISUAL) +/** SCI graphic visual */ struct GfxVisual : public GfxContainer { Common::Array<GfxPort *> _portRefs; /**< References to ports */ int _font; /**< Default font */ @@ -352,6 +371,7 @@ public: }; #define GFXW_IS_PORT(widget) ((widget)->_type == GFXW_PORT) +/** SCI graphics port */ struct GfxPort : public GfxContainer { GfxList *_decorations; /**< optional window decorations - drawn before the contents */ GfxWidget *port_bg; /**< Port background widget or NULL */ @@ -365,16 +385,20 @@ struct GfxPort : public GfxContainer { byte gray_text; /**< Whether text is 'grayed out' (dithered) */ public: - /* Creates a new port widget with the default settings - ** Paramaters: (GfxVisual *) visual: The visual the port is added to - ** (GfxPort *) predecessor: The port's predecessor - ** (rect_t) area: The screen area covered by the port (absolute position) - ** (gfx_color_t) fgcolor: Foreground drawing color - ** (gfx_color_t) bgcolor: Background color - ** A port differentiates itself from a list in that it contains additional information, - ** and an optional title (stored in a display list). - ** Ports are assigned implicit IDs identifying their position within the port stack. - */ + /** + * Creates a new port widget with the default settings + * + * A port differentiates itself from a list in that it contains additional + * information, and an optional title (stored in a display list). + * Ports are assigned implicit IDs identifying their position within the + * port stack. + * + * @param[in] visual The visual the port is added to + * @param[in] area The screen area covered by the port (absolute + * position) + * @param[in] fgcolor Foreground drawing color + * @param[in] bgcolor Background color + */ GfxPort(GfxVisual *visual, rect_t area, gfx_color_t fgcolor, gfx_color_t bgcolor); ~GfxPort(); diff --git a/engines/sci/gfx/gfx_system.h b/engines/sci/gfx/gfx_system.h index e1d56ee26d..4d9a39934d 100644 --- a/engines/sci/gfx/gfx_system.h +++ b/engines/sci/gfx/gfx_system.h @@ -37,13 +37,7 @@ namespace Sci { #define GFX_DEBUG /* General output macros */ -# define GFXERROR sciprintf("GFX Error: %s, L%d:", __FILE__, __LINE__); error -# define GFXWARN sciprintf("GFX Warning: %s, L%d:", __FILE__, __LINE__); warning -# ifdef GFX_DEBUG -# define GFXDEBUG sciprintf("GFX-debug: %s, L%d:", __FILE__, __LINE__); sciprintf -# else /* !GFX_DEBUG */ -# define GFXDEBUG if (0) printf -# endif /* !GFX_DEBUG */ +#define GFXERROR sciprintf("GFX Error: %s, L%d:", __FILE__, __LINE__); error /***********************/ /*** Data structures ***/ @@ -57,34 +51,37 @@ namespace Sci { ** enabled */ #define GFX_MODE_FLAG_REVERSE_ALPHA (1<<1) -/** Graphics mode description */ -struct gfx_mode_t { +/** Graphics mode description + * + * Color masks: + * Each of the mask/shift pairs describe where the corresponding color + * values are stored for the described mode. Internally, color + * calculations are done by using 32 bit values for r, g, b, a. After + * the internal values have been calculated, they are shifted RIGHT + * by the xxx_shift amount described above, then ANDed with the + * corresponding color mask; finally, all three results are ORred to- + * gether. The alpha values are used as appropriate; if alpha_mask is + * zero, then images use a special alpha map. + */ - int xfact, yfact; /* Horizontal and vertical scaling factors */ - int xsize, ysize; /* Horizontal and vertical size */ - int bytespp; /* Bytes per pixel */ +struct gfx_mode_t { - uint32 flags; /* GFX_MODE_FLAG_* Flags- see above */ + int xfact, yfact; /**< Horizontal and vertical scaling factors */ + int xsize, ysize; /**< Horizontal and vertical size */ + int bytespp; /**< Bytes per pixel */ + uint32 flags; /**< GFX_MODE_FLAG_* Flags- see above */ - Palette *palette; // Palette or NULL to indicate non-palette mode. - // Palette mode is only supported for bytespp = 1 + /** + * Palette or NULL to indicate non-palette mode. + * Palette mode is only supported for bytespp = 1 + */ + Palette *palette; - /* Color masks */ // TODO: remove those uint32 red_mask, green_mask, blue_mask, alpha_mask; short red_shift, green_shift, blue_shift, alpha_shift; Graphics::PixelFormat format; - - /* Each of the mask/shift pairs describe where the corresponding color - ** values are stored for the described mode. Internally, color - ** calculations are done by using 32 bit values for r, g, b, a. After - ** the internal values have been calculated, they are shifted RIGHT - ** by the xxx_shift amount described above, then ANDed with the - ** corresponding color mask; finally, all three results are ORred to- - ** gether. The alpha values are used as appropriate; if alpha_mask is - ** zero, then images use a special alpha map. */ - }; @@ -93,16 +90,16 @@ struct gfx_mode_t { /** Pixmap-specific color entries */ struct gfx_pixmap_color_t{ - int global_index; /* Global index color or GFX_COLOR_INDEX_UNMAPPED. */ - uint8 r, g, b; /* Real color */ + int global_index; /**< Global index color or GFX_COLOR_INDEX_UNMAPPED. */ + uint8 r, g, b; /**< Real color */ }; /** Full color */ struct gfx_color_t { PaletteEntry visual; - uint8 alpha; /* transparency = (1-opacity) */ + uint8 alpha; /**< transparency = (1-opacity) */ int8 priority, control; - byte mask; /* see mask values below */ + byte mask; /**< see mask values below */ }; @@ -113,11 +110,15 @@ struct rect_t { int width, height; /* width, height: (x,y,width,height)=(5,5,1,1) occupies 1 pixel */ }; -/* Generates a rect_t from index data -** Parameters: (int x int) x,y: Upper left point of the rectangle -** (int x int) width, height: Horizontal and vertical extension of the rectangle -** Returns : (rect_t) A rectangle matching the supplied parameters -*/ +/** + * Generates a rect_t from index data + * + * @param[in] x Left side of the rectangle + * @param[in] y Top side of the rectangle + * @param[in] width Horizontal extent of the rectangle + * @param[in] height Verical extent of the rectangle + * @return A rectangle matching the supplied parameters + */ static inline rect_t gfx_rect(int x, int y, int width, int height) { rect_t rect; @@ -129,11 +130,16 @@ static inline rect_t gfx_rect(int x, int y, int width, int height) { return rect; } -// Temporary helper functions to ease the transition from rect_t to Common::Rect +/** + * Temporary helper function to ease the transition from rect_t to Common::Rect + */ static inline rect_t toSCIRect(Common::Rect in) { return gfx_rect(in.left, in.top, in.width(), in.height()); } +/** + * Temporary helper function to ease the transition from rect_t to Common::Rect + */ static inline Common::Rect toCommonRect(rect_t in) { return Common::Rect(in.x, in.y, in.x + in.width, in.y + in.height); } @@ -142,10 +148,13 @@ static inline Common::Rect toCommonRect(rect_t in) { #define OVERLAP(a, b, z, zl) (a.z >= b.z && a.z < (b.z + b.zl)) -/* Determines whether two rects overlap -** Parameters: (rect_t x rect_t) a,b: The two rect_ts to check for overlap -** Returns : (int) 1 if they overlap, 0 otherwise -*/ +/** + * Determines whether two rects overlap + * + * @param[in] a First rect to check for overlap + * @param[in] b Second rect to check for overlap + * @return 1 if they overlap, 0 otherwise + */ static inline int gfx_rects_overlap(rect_t a, rect_t b) { return (OVERLAP(a, b, x, width) || OVERLAP(b, a, x, width)) && (OVERLAP(a, b, y, height) || OVERLAP(b, a, y, height)); } @@ -159,86 +168,95 @@ extern rect_t gfx_rect_fullscreen; #define GFX_PIC_COLORS 256 -#define GFX_PIXMAP_FLAG_SCALED_INDEX (1<<0) /* Index data is scaled already */ -#define GFX_PIXMAP_FLAG_INSTALLED (1<<2) /* Pixmap has been registered */ -#define GFX_PIXMAP_FLAG_PALETTIZED (1<<6) /* Indicates a palettized view */ +#define GFX_PIXMAP_FLAG_SCALED_INDEX (1<<0) /* Index data is scaled already */ +#define GFX_PIXMAP_FLAG_INSTALLED (1<<2) /* Pixmap has been registered */ +#define GFX_PIXMAP_FLAG_PALETTIZED (1<<6) /* Indicates a palettized view */ #define GFX_PIXMAP_COLOR_KEY_NONE -1 /* No transpacency colour key */ #define GFX_CURSOR_TRANSPARENT 255 // Cursor colour key -struct gfx_pixmap_t { /* gfx_pixmap_t: Pixel map */ +/** Pixel map */ +struct gfx_pixmap_t { - /*** Meta information ***/ - int ID; /* Resource ID, or GFX_RESID_NONE for anonymous graphical data */ - short loop, cel; /* loop and cel number for views */ + /** @name Meta information + * @{*/ + int ID; /**< Resource ID, or GFX_RESID_NONE for anonymous graphical data */ + short loop; /**< loop number for view */ + short cel; /**< cel number for view */ + /** @}*/ - - /*** Color map ***/ + /** @name Color map + * @{*/ Palette *palette; - int colors_nr() const { return palette ? palette->size() : 0; } - /* color entries, or NULL if the - ** default palette is to be used. - ** A maximum of 255 colors is allowed; color - ** index 0xff is reserved for transparency. - ** As a special exception, 256 colors are - ** allowed for background pictures (which do - ** not use transparency) - */ - uint32 flags; - - /*** Hot spot ***/ - int xoffset, yoffset; /* x and y coordinates of the 'hot spot' (unscaled) */ - /*** Index data ***/ - int index_width, index_height; /* width and height of the indexed original image */ - byte *index_data; /* Color-index data, or NULL if read from an - ** external source - */ - - /*** Drawable data ***/ - int width, height; /* width and height of the actual image */ - int data_size; /* Amount of allocated memory */ - byte *data; /* Drawable data, or NULL if not converted. */ - - byte *alpha_map; /* Byte map with alpha values. It is used only if the - ** graphics mode's alpha_mask is zero. - */ + /** + * color entries, or NULL if the default palette is to be used. A maximum + * of 255 colors is allowed; color index 0xff is reserved for transparency. + * As a special exception, 256 colors are allowed for background pictures + * (which do not use transparency) + */ + int colors_nr() const { return palette ? palette->size() : 0; } - int color_key; - int palette_revision; // Revision of palette at the time data was generated + uint32 flags; + /* @} */ + + /** @name Hot spot + * x and y coordinates of the 'hot spot' (unscaled) + * @{*/ + int xoffset, yoffset; + /** @} */ + + /** @name Index data + * @{ + */ + int index_width; /**< width of the indexed original image */ + int index_height; /**< height of the indexed original image */ + byte *index_data; /**< Color-index data, or NULL if read from an external source */ + /** @} */ + + /** @name Drawable data + * @{ + */ + int width; /**< width of the actual image */ + int height; /**< height of the actual image */ + int data_size; /**< Amount of allocated memory */ + byte *data; /**< Drawable data, or NULL if not converted. */ + + byte *alpha_map; /**< Byte map with alpha values. It is used only if the graphics mode's alpha_mask is zero. */ + + int color_key; /**< The color to make transparent */ + int palette_revision; /**< Revision of palette at the time data was generated */ + /** @} */ }; -/***********************/ -/*** Constant values ***/ -/***********************/ -/* Return values */ +/** @name Constant values + * @{ */ + +/** Return values */ enum gfx_return_value_t { - GFX_OK = 0, /* Indicates "operation successful" */ - GFX_ERROR = -1, /* Indicates "operation failed" */ - GFX_FATAL = -2 - /* Fatal error: Used by graphics drivers to indicate that they were unable to - ** do anything useful - */ + GFX_OK = 0, /**< Indicates "operation successful" */ + GFX_ERROR = -1, /**< Indicates "operation failed" */ + GFX_FATAL = -2 /**< Fatal error: Used by graphics drivers to indicate + that they were unable to do anything useful */ }; - -enum gfx_map_mask_t {/* Map masks */ +/** Map masks */ +enum gfx_map_mask_t { GFX_MASK_NONE = 0, GFX_MASK_VISUAL = 1, GFX_MASK_PRIORITY = 2, GFX_MASK_CONTROL = 4 }; -/* 'no priority' mode */ +/** 'no priority' mode */ enum { GFX_NO_PRIORITY = -1 }; -/* Text alignment values */ - +/** Text alignment values */ enum gfx_alignment_t { ALIGN_RIGHT = -1, ALIGN_TOP = -1, @@ -249,16 +267,16 @@ enum gfx_alignment_t { enum gfx_line_mode_t { - GFX_LINE_MODE_CORRECT, /* Scaled separately */ - GFX_LINE_MODE_FAST, /* Scaled by (xfact+yfact)/2 */ - GFX_LINE_MODE_FINE /* Always drawn at width 1 */ + GFX_LINE_MODE_CORRECT, /**< Scaled separately */ + GFX_LINE_MODE_FAST, /**< Scaled by (xfact+yfact)/2 */ + GFX_LINE_MODE_FINE /**< Always drawn at width 1 */ }; enum gfx_brush_mode_t { - GFX_BRUSH_MODE_SCALED, /* Just scale the brush pixels */ - GFX_BRUSH_MODE_ELLIPSES, /* Replace pixels with ellipses */ - GFX_BRUSH_MODE_RANDOM_ELLIPSES, /* Replace pixels with ellipses moved and re-scaled randomly */ - GFX_BRUSH_MODE_MORERANDOM /* Distribute randomly */ + GFX_BRUSH_MODE_SCALED, /**< Just scale the brush pixels */ + GFX_BRUSH_MODE_ELLIPSES, /**< Replace pixels with ellipses */ + GFX_BRUSH_MODE_RANDOM_ELLIPSES, /**< Replace pixels with ellipses moved and re-scaled randomly */ + GFX_BRUSH_MODE_MORERANDOM /**< Distribute randomly */ }; @@ -269,18 +287,19 @@ enum gfx_line_style_t { enum gfx_rectangle_fill_t { - GFX_SHADE_FLAT, /* Don't shade */ - GFX_SHADE_VERTICALLY, /* Shade vertically */ - GFX_SHADE_HORIZONTALLY /* Shade horizontally */ + GFX_SHADE_FLAT, /**< Don't shade */ + GFX_SHADE_VERTICALLY, /**< Shade vertically */ + GFX_SHADE_HORIZONTALLY /**< Shade horizontally */ }; enum gfx_color_mode_t { - GFX_COLOR_MODE_AUTO = 0, /* Auto-detect- handled by the gfxop library */ - GFX_COLOR_MODE_INDEX = 1, /* Index mode */ - GFX_COLOR_MODE_HIGH = 2, /* High color mode (15bpp or 16 bpp) */ - GFX_COLOR_MODE_TRUE = 4 /* True color mode (24 bpp padded to 32 bpp) */ + GFX_COLOR_MODE_AUTO = 0, /**< Auto-detect- handled by the gfxop library */ + GFX_COLOR_MODE_INDEX = 1, /**< Index mode */ + GFX_COLOR_MODE_HIGH = 2, /**< High color mode (15bpp or 16 bpp) */ + GFX_COLOR_MODE_TRUE = 4 /**< True color mode (24 bpp padded to 32 bpp) */ }; +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_tools.cpp b/engines/sci/gfx/gfx_tools.cpp index 4e570f5931..b835084b0c 100644 --- a/engines/sci/gfx/gfx_tools.cpp +++ b/engines/sci/gfx/gfx_tools.cpp @@ -163,7 +163,7 @@ gfx_pixmap_t *gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap) { int size; if (pixmap->index_data) { - GFXWARN("Attempt to allocate pixmap index data twice!\n"); + warning("[GFX] Attempt to allocate pixmap index data twice"); return pixmap; } @@ -180,7 +180,7 @@ gfx_pixmap_t *gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap) { gfx_pixmap_t *gfx_pixmap_free_index_data(gfx_pixmap_t *pixmap) { if (!pixmap->index_data) { - GFXWARN("Attempt to free pixmap index data twice!\n"); + warning("[GFX] Attempt to free pixmap index data twice"); return pixmap; } @@ -193,7 +193,7 @@ gfx_pixmap_t *gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode) { int size; if (pixmap->data) { - GFXWARN("Attempt to allocate pixmap data twice!\n"); + warning("[GFX] Attempt to allocate pixmap data twice"); return pixmap; } @@ -215,7 +215,7 @@ gfx_pixmap_t *gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode) { gfx_pixmap_t *gfx_pixmap_free_data(gfx_pixmap_t *pixmap) { if (!pixmap->data) { - GFXWARN("Attempt to free pixmap data twice!\n"); + warning("[GFX] Attempt to free pixmap data twice"); return pixmap; } diff --git a/engines/sci/gfx/gfx_tools.h b/engines/sci/gfx/gfx_tools.h index 8582dfa565..9b4ce32e89 100644 --- a/engines/sci/gfx/gfx_tools.h +++ b/engines/sci/gfx/gfx_tools.h @@ -23,9 +23,6 @@ * */ -/* SCI graphics subsystem helper functions */ - - #ifndef SCI_GFX_GFX_TOOLS_H #define SCI_GFX_GFX_TOOLS_H @@ -36,162 +33,198 @@ namespace Sci { +/** @name SCI graphics subsystem helper functions */ +/** @{ */ + enum gfx_xlate_filter_t { GFX_XLATE_FILTER_NONE, GFX_XLATE_FILTER_LINEAR, GFX_XLATE_FILTER_TRILINEAR }; +/** + * Allocates a new gfx_mode_t structure with the specified parameters + * + * @param[in] xfact Horizontal scaling factors + * @param[in] yfact Vertical scaling factors + * @param[in] format Pixel format description + * @param[in] palette Number of palette colors, 0 if we're not in palette mode + * @param[in] flags GFX_MODE_FLAG_* values ORred together, or just 0 + * @return A newly allocated gfx_mode_t structure + */ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &format, Palette *palette, int flags); -/* Allocates a new gfx_mode_t structure with the specified parameters -** Parameters: (int x int) xfact x yfact: Horizontal and vertical scaling factors -** (Graphics::PixelFormat) format: pixel format description -** (int) palette: Number of palette colors, 0 if we're not in palette mode -** (int) flags: GFX_MODE_FLAG_* values ORred together, or just 0 -** Returns : (gfx_mode_t *) A newly allocated gfx_mode_t structure -*/ - +/** + * Clips a rect_t + * + * @param[in] box Pointer to the box to clip + * @param[in] maxx Maximum allowed width + * @param[in] maxy Maximum allowed height + */ void gfx_clip_box_basic(rect_t *box, int maxx, int maxy); -/* Clips a rect_t -** Parameters: (rect_t *) box: Pointer to the box to clip -** (int x int) maxx, maxy: Maximum allowed width and height -** Returns : (void) -*/ - +/** + * Frees all memory allocated by a mode structure + * @param[in] mode The mode to free + */ void gfx_free_mode(gfx_mode_t *mode); -/* Frees all memory allocated by a mode structure -** Parameters: (gfx_mode_t *) mode: The mode to free -** Returns : (void) -*/ - +/** + * Creates a new pixmap structure + * + * The following fiels are initialized: + * ID, loop, cel, index_width, index_height, xl, yl, data <- NULL, + * alpha_map <- NULL, internal.handle <- 0, internal.info <- NULL, + * colors <- NULL, index_scaled <- 0 + * + * @param[in] xl Width (in SCI coordinates) of the pixmap + * @param[in] yl Height (in SCI coordinates) of the pixmap + * @param[in] resid The pixmap's resource ID, or GFX_RESID_NONE + * @param[in] loop For views: The pixmap's loop number + * @param[in] cel For cels: The pixmap's cel number + * @return The newly allocated pixmap + */ gfx_pixmap_t *gfx_new_pixmap(int xl, int yl, int resid, int loop, int cel); -/* Creates a new pixmap structure -** Parameters: (int x int) xl x yl: The dimensions (in SCI coordinates) of the pixmap -** (int) resid: The pixmap's resource ID, or GFX_RESID_NONE -** (int) loop: For views: The pixmap's loop number -** (int) cel: For cels: The pixmap's cel number -** Returns : (gfx_pixmap_t *) The newly allocated pixmap -** The following fiels are initialized: -** ID, loop, cel, index_width, index_height, xl, yl, data <- NULL, -** alpha_map <- NULL, internal.handle <- 0, internal.info <- NULL, colors <- NULL, -** index_scaled <- 0 -*/ +/** + * Clones a pixmap, minus its index data, palette and driver-specific + * handles + * + * @param[in] pixmap The pixmap to clone + * @param[in] mode The mode to be applied to the pixmap + * @return The clone + */ gfx_pixmap_t *gfx_clone_pixmap(gfx_pixmap_t *pixmap, gfx_mode_t *mode); -/* Clones a pixmap, minus its index data, palette and driver-specific handles -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to clone -** (gfx_mode_t *) mode: The mode to be applied to the pixmap -** Returns : (gfx_pixmap_t *) The clone -*/ - +/** + * Allocates the index_data field of a pixmap + * + * @param[in] pixmap The pixmap to allocate for + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap); -/* Allocates the index_data field of a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to allocate for -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Frees the index_data field of a pixmap + * + * @param[in] pixmap The pixmap to modify + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_free_index_data(gfx_pixmap_t *pixmap); -/* Frees the index_data field of a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to modify -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Allocates the data field of a pixmap + * + * @param[in] pixmap The pixmap to allocate for + * @param[in] mode The mode the memory is to be allocated for + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode); -/* Allocates the data field of a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to allocate for -** (gfx_mode_t *) mode: The mode the memory is to be allocated for -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Frees the memory allocated for a pixmap's data field + * + * @param[in] pixmap The pixmap to modify + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_free_data(gfx_pixmap_t *pixmap); -/* Frees the memory allocated for a pixmap's data field -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to modify -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Frees all memory associated with a pixmap + * + * @param[in] pxm The pixmap to free + */ void gfx_free_pixmap(gfx_pixmap_t *pxm); -/* Frees all memory associated with a pixmap -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to free -** Returns : (void) -*/ - -void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, Common::Point end, int color); -/* Draws a line to a pixmap's index data buffer -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw to -** (Common::Point) start: Starting point of the line to draw -** (Common::Point) end: End point of the line to draw -** (int) color: The byte value to write -** Returns : (void) -** Remember, this only draws to the /index/ buffer, not to the drawable buffer. -** The line is not clipped. Invalid x, y, x1, y1 values will result in memory corruption. -*/ +/** + * Draws a line to a pixmap's index data buffer + * + * Remember, this only draws to the /index/ buffer, not to the drawable buffer. + * The line is not clipped. Invalid x, y, x1, y1 values will result in memory + * corruption. + * + * @param[in] pxm The pixmap to draw to + * @param[in] start Starting point of the line to draw + * @param[in] end End point of the line to draw + * @param[in] color The byte value to write + */ +void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, + Common::Point end, int color); + +/** + * Draws a filled rectangular area to a pixmap's index buffer + * + * This function only draws to the index buffer. + * + * @param[in] pxm The pixmap to draw to + * @param[in] box The box to fill + * @param[in] color The color to use for drawing + */ void gfx_draw_box_pixmap_i(gfx_pixmap_t *pxm, rect_t box, int color); -/* Draws a filled rectangular area to a pixmap's index buffer -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw to -** (rect_t) box: The box to fill -** (int) color: The color to use for drawing -** Returns : (void) -** This function only draws to the index buffer. -*/ +/** + * Copies part of a pixmap to another pixmap, with clipping + * + * @param[in] dest The destination pixmap + * @param[in] src The source pixmap + * @param[in] box The area to copy + */ void gfx_copy_pixmap_box_i(gfx_pixmap_t *dest, gfx_pixmap_t *src, rect_t box); -/* Copies part of a pixmap to another pixmap, with clipping -** Parameters: (gfx_pixmap_t *) dest: The destination pixmap -** (gfx_pixmap_t *) src: The source pixmap -** (rect_t) box: The area to copy -** Returns : (void) -*/ +/** + * Translates a pixmap's index data to drawable graphics data + * + * @param[in] pxm The pixmap to translate + * @param[in] mode The mode according which to scale + * @param[in] filter How to filter the data + */ void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode, gfx_xlate_filter_t filter); -/* Translates a pixmap's index data to drawable graphics data -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to translate -** (gfx_mode_t *) mode: The mode according which to scale -** (gfx_xlate_filter_t) filter: How to filter the data -** Returns : (void) -*/ -#define GFX_CROSSBLIT_FLAG_DATA_IS_HOMED (1<<0) -/* Means that the first byte in the visual data refers to the -** point corresponding to (dest.x, dest.y) */ +#define GFX_CROSSBLIT_FLAG_DATA_IS_HOMED (1<<0) /**< Means that the first byte in the visual data refers to the point corresponding to (dest.x, dest.y) */ +/** + * Transfers the non-transparent part of a pixmap to a linear pixel + * buffer. + * + * A 'linear buffer' in this context means a data buffer containing an entire + * screen (visual or priority), with fixed offsets between each data row, and + * linear access. + * + * @param[in] mode The graphics mode of the target buffer + * @param[in] pxm The pixmap to transfer + * @param[in] priority The pixmap's priority + * @param[in] src_coords The source coordinates within the pixmap + * @param[in] dest_coords The destination coordinates (no scaling) + * @param[in] dest Memory position of the upper left pixel of + * the linear pixel buffer + * @param[in] dest_line_width Byte offset of the very first pixel in the + * second line of the linear pixel buffer, + * relative to dest. + * @param[in] priority_dest Destination buffer for the pixmap's priority + * values + * @param[in] priority_line_width Byte offset of the first pixel in the second + * line of the priority buffer + * @param[in] priority_skip Amount of bytes allocated by each priority + * value + * @param[in] flags Any crossblit flags + * @return GFX_OK, or GFX_ERROR if the specified mode + * was invalid or unsupported + */ int gfx_crossblit_pixmap(gfx_mode_t *mode, gfx_pixmap_t *pxm, int priority, rect_t src_coords, rect_t dest_coords, byte *dest, int dest_line_width, byte *priority_dest, int priority_line_width, int priority_skip, int flags); -/* Transfers the non-transparent part of a pixmap to a linear pixel buffer -** Parameters: (gfx_mode_t *) mode: The graphics mode of the target buffer -** (gfx_pixmap_t *) pxm: The pixmap to transfer -** (int priority): The pixmap's priority -** (rect_t) src_coords: The source coordinates within the pixmap -** (rect_t) dest_coords: The destination coordinates (no scaling) -** (byte *) dest: Memory position of the upper left pixel of the -** linear pixel buffer -** (int) dest_line_width: Byte offset of the very first pixel in the -** second line of the linear pixel buffer, -** relative to dest. -** (byte *) priority_dest: Destination buffer for the pixmap's priority -** values -** (int) priority_line_width: Byte offset of the first pixel in the -** second line of the priority buffer -** (int) priority_skip: Amount of bytes allocated by each priority value -** (int) flags: Any crossblit flags -** Returns : (int) GFX_OK, or GFX_ERROR if the specified mode was invalid or unsupported -** A 'linear buffer' in this context means a data buffer containing an entire -** screen (visual or priority), with fixed offsets between each data row, and -** linear access. -*/ + +/** + * Scales the index data associated with a pixmap + * + * @param[in] pixmap The pixmap whose index data should be scaled + * @param[in] mode The mode to scale it to + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_scale_index_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode); -/* Scales the index data associated with a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap whose index data should be scaled -** (gfx_mode_t *) mode: The mode to scale it to -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** @} */ } // End of namespace Sci #endif // SCI_GFX_GFX_TOOLS_H diff --git a/engines/sci/gfx/gfx_widgets.cpp b/engines/sci/gfx/gfx_widgets.cpp index 08600c94b2..2207309f48 100644 --- a/engines/sci/gfx/gfx_widgets.cpp +++ b/engines/sci/gfx/gfx_widgets.cpp @@ -681,10 +681,10 @@ int GfxDynView::draw(const Common::Point &pos) { else error("GfxDynView::print: Invalid type %d", _type); - sciprintf(" SORT=%d z=%d seq=%d (%d/%d/%d)@(%d,%d)[p:%d,c:%d]; sig[%04x@%p]", force_precedence, _z, + sciprintf(" SORT=%d z=%d seq=%d (%d/%d/%d)@(%d,%d)[p:%d,c:%d]; sig[%04x@%04X:%04X[%d]]", force_precedence, _z, sequence, _view, _loop, _cel, _pos.x, _pos.y, (_color.mask & GFX_MASK_PRIORITY) ? _color.priority : -1, - (_color.mask & GFX_MASK_CONTROL) ? _color.control : -1, signal, signalp); + (_color.mask & GFX_MASK_CONTROL) ? _color.control : -1, signal, signalp.obj.segment, signalp.obj.offset, signalp.varindex); } static int _gfxwop_dyn_view_equals(GfxWidget *widget, GfxWidget *other) { @@ -794,9 +794,9 @@ GfxDynView::GfxDynView(GfxState *state, Common::Point pos_, int z_, int view_, i draw_bounds = gfx_rect(_pos.x - xalignmod, _pos.y - yalignmod - z_, width, height); _bounds = gfx_rect(_pos.x - offset.x - xalignmod, _pos.y - offset.y - yalignmod - z_, width, height); - under_bitsp = NULL; + under_bitsp.obj = NULL_REG; under_bits = 0; - signalp = NULL; + signalp.obj = NULL_REG; signal = 0; _z = z_; sequence = sequence_; @@ -1270,7 +1270,7 @@ static int _gfxwop_list_equals(GfxWidget *widget, GfxWidget *other) { return 0; if (!GFXW_IS_LIST(widget)) { - GFXWARN("_gfxwop_list_equals(): Method called on non-list!\n"); + warning("[GFX] _gfxwop_list_equals(): Method called on non-list"); widget->print(0); sciprintf("\n"); return 0; @@ -1508,7 +1508,7 @@ GfxPort::~GfxPort() { } if (_visual->_portRefs[_ID] != this) { - GFXWARN("While freeing port %d: Port is at %p, but port list indicates %p", _ID, (void *)this, (void *)_visual->_portRefs[_ID]); + warning("[GFX] While freeing port %d: Port is at %p, but port list indicates %p", _ID, (void *)this, (void *)_visual->_portRefs[_ID]); } else _visual->_portRefs[_ID] = NULL; @@ -1542,7 +1542,7 @@ int GfxPort::setVisual(GfxVisual *visual) { if (_decorations) if (_decorations->setVisual(visual)) { - GFXWARN("Setting the visual for decorations failed for port "); + warning("[GFX] Setting the visual for decorations failed for port "); this->print(1); return 1; } @@ -1631,7 +1631,7 @@ GfxPort *gfxw_remove_port(GfxVisual *visual, GfxPort *port) { VERIFY_WIDGET(port); if (!visual->_contents) { - GFXWARN("Attempt to remove port from empty visual\n"); + warning("[GFX] Attempt to remove port from empty visual"); return NULL; } @@ -1671,7 +1671,7 @@ GfxWidget *gfxw_set_id(GfxWidget *widget, int ID, int subID) { return widget; } -GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, void *under_bitsp, int signal, void *signalp) { +GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp) { if (!widget) return NULL; diff --git a/engines/sci/gfx/gfx_widgets.h b/engines/sci/gfx/gfx_widgets.h index 6c8e848664..80129152cb 100644 --- a/engines/sci/gfx/gfx_widgets.h +++ b/engines/sci/gfx/gfx_widgets.h @@ -23,7 +23,6 @@ * */ -/* Graphical state management */ #ifndef SCI_GFX_GFX_WIDGETS_H #define SCI_GFX_GFX_WIDGETS_H @@ -34,6 +33,8 @@ #include "sci/gfx/operations.h" namespace Sci { +/** @name Widget Graphical State Management */ +/** @{ */ struct GfxState; struct GfxBox; @@ -155,241 +156,324 @@ extern Common::Point gfxw_point_zero; /*-- Primitive types --*/ +/** + * Creates a new box + * + * The graphics state, if non-NULL, is used here for some optimizations. + * + * @param[in] state The (optional) state + * @param[in] area The box's dimensions, relative to its container + * widget + * @param[in] color1 The primary color + * @param[in] color2 The secondary color (ignored if shading is disabled) + * @param[in] shade_type The shade type for the box + * @return The resulting box widget + */ GfxBox *gfxw_new_box(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type); -/* Creates a new box -** Parameters: (GfxState *) state: The (optional) state -** (rect_t) area: The box's dimensions, relative to its container widget -** (gfx_color_t) color1: The primary color -** (gfx_color_t) color1: The secondary color (ignored if shading is disabled) -** (gfx_box_shade_t) shade_type: The shade type for the box -** Returns : (GfxBox *) The resulting box widget -** The graphics state- if non-NULL- is used here for some optimizations. -*/ -GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); -/* Creates a new rectangle -** Parameters: (rect_t) rect: The rectangle area -** (gfx_color_t) color: The rectangle's color -** (gfx_line_mode_t) line_mode: The line mode for the lines that make up the rectangle -** (gfx_line_style_t) line_style: The rectangle's lines' style -** Returns : (GfxPrimitive *) The newly allocated rectangle widget (a Primitive) -*/ +/** + * Creates a new rectangle + * + * @param[in] rect The rectangle area + * @param[in] color The rectangle's color + * @param[in] line_mode The line mode for the lines that make up the + * rectangle + * @param[in] line_style The rectangle's lines' style + * @return The newly allocated rectangle widget (a Primitive) + */ +GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color, + gfx_line_mode_t line_mode, gfx_line_style_t line_style); -GfxPrimitive *gfxw_new_line(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); -/* Creates a new line -** Parameters: (Common::Point * Common::Point) (start, line): The line origin and end point -** (gfx_color_t) color: The line's color -** (gfx_line_mode_t) line_mode: The line mode to use for drawing -** (gfx_line_style_t) line_style: The line style -** Returns : (GfxPrimitive *) The newly allocated line widget (a Primitive) -*/ +/** + * Creates a new line + * + * @param[in] start The line's origin + * @param[in] end The line's end point + * @param[in] color The line's color + * @param[in] line_mode The line mode to use for drawing + * @param[in] line_style The line style + * @return The newly allocated line widget (a Primitive) + */ +GfxPrimitive *gfxw_new_line(Common::Point start, Common::Point end, + gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); +/** View flags */ +enum { + GFXW_VIEW_FLAG_STATIC = (1 << 0), /**< Whether the view should be static */ + GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET = (1 << 1) /**< Whether the view should _not_ apply its x/y offset modifyers */ +}; -/* Whether the view should be static */ -#define GFXW_VIEW_FLAG_STATIC (1 << 0) - -/* Whether the view should _not_ apply its x/y offset modifyers */ -#define GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET (1 << 1) - -GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int flags); -/* Creates a new view (a cel, actually) -** Parameters: (GfxState *) state: The graphics state -** (Common::Point) pos: The position to place the view at -** (int x int x int) view, loop, cel: The global cel ID -** (int) priority: The priority to use for drawing, or -1 for none -** (int) control: The value to write to the control map, or -1 for none -** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and vertical -** cel alignment -** (int) flags: Any combination of GFXW_VIEW_FLAGs -** Returns : (gfxw_cel_t *) A newly allocated cel according to the specs -*/ +/** + * Creates a new view (a cel, actually) + * + * @param[in] state The graphics state + * @param[in] pos The position to place the view at + * @param[in] view The global cel ID + * @param[in] loop The global cel ID + * @param[in] cel The global cel ID + * @param[in] palette The palette to use + * @param[in] priority The priority to use for drawing, or -1 for none + * @param[in] control The value to write to the control map, or -1 for none + * @param[in] halign Horizontal cel alignment + * @param[in] valign Vertical cel alignment + * @param[in] flags Any combination of GFXW_VIEW_FLAGs + * @return A newly allocated cel according to the specs + */ +GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view, int loop, + int cel, int palette, int priority, int control, gfx_alignment_t halign, + gfx_alignment_t valign, int flags); -GfxDynView *gfxw_new_dyn_view(GfxState *state, Common::Point pos, int z, int view, int loop, int cel, int palette, - int priority, int control, gfx_alignment_t halign, gfx_alignment_t valign, int sequence); -/* Creates a new dyn view -** Parameters: (GfxState *) state: The graphics state -** (Common::Point) pos: The position to place the dynamic view at -** (int) z: The z coordinate -** (int x int x int) view, loop, cel: The global cel ID -** (int) priority: The priority to use for drawing, or -1 for none -** (int) control: The value to write to the control map, or -1 for none -** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and vertical -** cel alignment -** (int) sequence: Sequence number: When sorting dynviews, this number is -** considered last for sorting (ascending order) -** Returns : (gfxw_cel_t *) A newly allocated cel according to the specs -** Dynamic views are non-pic views with a unique global identifyer. This allows for drawing -** optimizations when they move or change shape. -*/ -GfxText *gfxw_new_text(GfxState *state, rect_t area, int font, const char *text, gfx_alignment_t halign, - gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, - gfx_color_t bgcolor, int flags); -/* Creates a new text widget -** Parameters: (GfxState *) state: The state the text is to be calculated from -** (rect_t) area: The area the text is to be confined to (the yl value is only -** relevant for text aligment, though) -** (int) font: The number of the font to use -** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and -** vertical text alignment -** (gfx_color_t x gfx_color_t) color1, color2: Text foreground colors (if not equal, -** The foreground is dithered between them) -** (gfx_color_t) bgcolor: Text background color -** (int) flags: GFXR_FONT_FLAGs, orred together (see gfx_resource.h) -** Returns : (GfxText *) The resulting text widget -*/ +/** + * Creates a new dyn view + * + * Dynamic views are non-pic views with a unique global identifyer. This allows for drawing optimizations when they move or change shape. + * + * @param[in] state The graphics state + * @param[in] pos The position to place the dynamic view at + * @param[in] z The z coordinate + * @param[in] view The global cel ID + * @param[in] loop The global cel ID + * @param[in] cel The global cel ID + * @param[in] palette The palette to use + * @param[in] priority The priority to use for drawing, or -1 for none + * @param[in] control The value to write to the control map, or -1 for none + * @param[in] halign Horizontal cel alignment + * @param[in] valign Vertical cel alignment + * @param[in] sequence Sequence number: When sorting dynviews, this number is + * considered last for sorting (ascending order) + * @return A newly allocated cel according to the specs + */ +GfxDynView *gfxw_new_dyn_view(GfxState *state, Common::Point pos, int z, + int view, int loop, int cel, int palette, int priority, int control, + gfx_alignment_t halign, gfx_alignment_t valign, int sequence); +/** + * Creates a new text widget + * + * @param[in] state The state the text is to be calculated from + * @param[in] area The area the text is to be confined to (the yl value is + * only relevant for text aligment, though) + * @param[in] font The number of the font to use + * @param[in] text String to put in text widget + * @param[in] halign Horizontal text alignment + * @param[in] valign Vertical text alignment + * @param[in] color1 Text foreground colors (if not equal, the foreground is + * dithered between them) + * @param[in] color2 Text foreground colors (if not equal, the foreground is + * dithered between them) + * @param[in] bgcolor Text background color + * @param[in] flags GFXR_FONT_FLAGs, orred together (see gfx_resource.h) + * @return The resulting text widget + */ +GfxText *gfxw_new_text(GfxState *state, rect_t area, int font, const char *text, + gfx_alignment_t halign, gfx_alignment_t valign, gfx_color_t color1, + gfx_color_t color2, gfx_color_t bgcolor, int flags); + +/** + * Determines text widget meta-information + * + * @param[in] state The state to operate on + * @param[in] text The widget to query + * @param[out] lines_nr Number of lines used in the text + * @param[out] lineheight Pixel height (SCI scale) of each text line + * @param[out] offset Pixel offset (SCI scale) of the space after the last + * character in the last line + */ void gfxw_text_info(GfxState *state, GfxText *text, int *lines_nr, int *lineheight, int *offset); -/* Determines text widget meta-information -** Parameters: (GfxState *) state: The state to operate on -** (gfx_text_t *) text: The widget to query -** Returns : (int) lines_nr: Number of lines used in the text -** (int) lineheight: Pixel height (SCI scale) of each text line -** (int) offset: Pixel offset (SCI scale) of the space after the -** last character in the last line -*/ +/** + * Sets a widget's ID + * + * A widget ID is unique within the container it is stored in, if and only if it + * was added to that container with gfxw_add(). This function handles widget == + * NULL gracefully (by doing nothing and returning NULL). + * + * @param[in] widget The widget whose ID should be set + * @param[in] ID The ID to set + * @param[in] subID The ID to set + * @return The widget + */ GfxWidget *gfxw_set_id(GfxWidget *widget, int ID, int subID); -/* Sets a widget's ID -** Parmaeters: (GfxWidget *) widget: The widget whose ID should be set -** (int x int) ID, subID: The ID to set -** Returns : (GfxWidget *) widget -** A widget ID is unique within the container it is stored in, if and only if it was -** added to that container with gfxw_add(). -** This function handles widget = NULL gracefully (by doing nothing and returning NULL). -*/ +/** + * Finds a widget with a specific ID in a container and removes it from there + * + * Search is non-recursive; widgets with IDs hidden in subcontainers will not + * be found. + * + * @param[in] container The container to search in + * @param[in] ID The ID to look for + * @param[in] subID The subID to look for, or GFXW_NO_ID for any + * @return The resulting widget or NULL if no match was found + */ GfxWidget *gfxw_remove_id(GfxContainer *container, int ID, int subID); -/* Finds a widget with a specific ID in a container and removes it from there -** Parameters: (GfxContainer *) container: The container to search in -** (int) ID: The ID to look for -** (int) subID: The subID to look for, or GFXW_NO_ID for any -** Returns : (GfxWidget *) The resulting widget or NULL if no match was found -** Search is non-recursive; widgets with IDs hidden in subcontainers will not be found. -*/ +/** + * Initializes a dyn view's interpreter attributes + * + * @param[in] widget The widget affected + * @param[in] under_bits Interpreter-dependant data + * @param[in] under_bitsp Interpreter-dependant data + * @param[in] signal Interpreter-dependant data + * @param[in] signalp Interpreter-dependant data + * @return The widget + */ +GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, + const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp); -GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, void *under_bitsp, int signal, void *signalp); -/* Initializes a dyn view's interpreter attributes -** Parameters: (GfxDynView *) widget: The widget affected -** (int x void * x int x void *) under_bits, inder_bitsp, signal, signalp: Interpreter-dependant data -** Returns : (GfxDynView *) widget -*/ - +/** + * Makes a widget invisible without removing it from the list of widgets + * + * Has no effect on invisible widgets + * + * @param[in] widget The widget to invisibilize + * @return The widget + */ GfxWidget *gfxw_hide_widget(GfxWidget *widget); -/* Makes a widget invisible without removing it from the list of widgets -** Parameters: (GfxWidget *) widget: The widget to invisibilize -** Returns : (GfxWidget *) widget -** Has no effect on invisible widgets -*/ +/** + * Makes an invisible widget reappear + * + * Does not affect visible widgets + * + * @param[in] widget The widget to show again + * @return The widget + */ GfxWidget *gfxw_show_widget(GfxWidget *widget); -/* Makes an invisible widget reappear -** Parameters: (GfxWidget *) widget: The widget to show again -** Returns : (GfxWidget *) widget -** Does not affect visible widgets -*/ +/** + * Marks a widget as "abandoned" + * + * @param[in] widget The widget to abandon + * @return The widget + */ GfxWidget *gfxw_abandon_widget(GfxWidget *widget); -/* Marks a widget as "abandoned" -** Parameters: (GfxWidget *) widget: The widget to abandon -** Returns : (GfxWidget *) widget -*/ - -/*-- Container types --*/ -#define GFXW_LIST_UNSORTED 0 -#define GFXW_LIST_SORTED 1 +/** Container types */ +enum { + GFXW_LIST_UNSORTED = 0, + GFXW_LIST_SORTED = 1 +}; +/** + * Creates a new list widget + * + * List widgets are also referred to as Display Lists. + * + * @param[in] area The area covered by the list (absolute position) + * @param[in] sorted Whether the list should be a sorted list + * @return A newly allocated list widget + */ GfxList *gfxw_new_list(rect_t area, int sorted); -/* Creates a new list widget -** Parameters: (rect_t) area: The area covered by the list (absolute position) -** (int) sorted: Whether the list should be a sorted list -** Returns : (GfxList *) A newly allocated list widget -** List widgets are also referred to as Display Lists. -*/ +/** + * Retrieves the default port from a visual + * + * The 'default port' is the last port to be instantiated; usually the topmost + * or highest-ranking port. + * + * @param[in] visual The visual the port should be retrieved from + * @return The default port, or NULL if no port is present + */ GfxPort *gfxw_find_default_port(GfxVisual *visual); -/* Retrieves the default port from a visual -** Parameters: (GfxVisual *) visual: The visual the port should be retrieved from -** Returns : (GfxPort *) The default port, or NULL if no port is present -** The 'default port' is the last port to be instantiated; usually the topmost -** or highest-ranking port. -*/ +/** + * Sets rectangle to be restored upon port removal + * + * @param[in] visual The visual to operate on + * @param[in] window The affected window + * @param[in] auto_rect The area to restore + */ void gfxw_port_set_auto_restore(GfxVisual *visual, GfxPort *window, rect_t auto_rect); -/* Sets rectangle to be restored upon port removal -** Parameters: (state_t *) s: The state to operate on -** (GfxPort *) window: The affected window -** (rect_t) auto_rect: The area to restore -** Returns : (void) -*/ +/** + * Removes a port from a visual + * + * @param[in] visual The visual the port should be removed from + * @param[in] port The port to remove + * @return port's parent port, or NULL if it had none + */ GfxPort *gfxw_remove_port(GfxVisual *visual, GfxPort *port); -/* Removes a port from a visual -** Parameters: (GfxVisual *) visual: The visual the port should be removed from -** (GfxPort *) port: The port to remove -** Returns : (GfxPort *) port's parent port, or NULL if it had none -*/ +/** + * Removes the widget from the specified port + * + * @param[in] container The container it should be removed from + * @param[in] widget The widget to remove + */ void gfxw_remove_widget_from_container(GfxContainer *container, GfxWidget *widget); -/* Removes the widget from the specified port -** Parameters: (GfxContainer *) container: The container it should be removed from -** (GfxWidget *) widget: The widget to remove -** Returns : (void) -*/ +/** + * Makes a "snapshot" of a visual + * + * It's not really a full qualified snaphot, though. See gfxw_restore_snapshot + * for a full discussion. This operation also increases the global serial number + * counter by one. + * + * @param[in] visual The visual a snapshot is to be taken of + * @param[in] area The area a snapshot should be taken of + * @return The resulting, newly allocated snapshot + */ gfxw_snapshot_t *gfxw_make_snapshot(GfxVisual *visual, rect_t area); -/* Makes a "snapshot" of a visual -** Parameters: (GfxVisual *) visual: The visual a snapshot is to be taken of -** (rect_t) area: The area a snapshot should be taken of -** Returns : (gfxw_snapshot_t *) The resulting, newly allocated snapshot -** It's not really a full qualified snaphot, though. See gfxw_restore_snapshot -** for a full discussion. -** This operation also increases the global serial number counter by one. -*/ +/** + * Predicate to test whether a widget would be destroyed by applying a snapshot + * + * @param[in] snapshot The snapshot to test against + * @param[in] widget The widget to test + * @return An appropriate boolean value + */ int gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, GfxWidget *widget); -/* Predicate to test whether a widget would be destroyed by applying a snapshot -** Parameters: (gfxw_snapshot_t *) snapshot: The snapshot to test against -** (GfxWidget *) widget: The widget to test -** Retunrrs : (int) An appropriate boolean value -*/ +/** + * Restores a snapshot to a visual + * + * The snapshot is not really restored; only more recent widgets touching + * the snapshotted area are destroyed. + * + * @param[in] visual The visual to operate on + * @param[in] snapshot The snapshot to restore + * @return The snapshot (still needs to be freed) + */ gfxw_snapshot_t *gfxw_restore_snapshot(GfxVisual *visual, gfxw_snapshot_t *snapshot); -/* Restores a snapshot to a visual -** Parameters: (GfxVisual *) visual: The visual to operate on -** (gfxw_snapshot_t *) snapshot: The snapshot to restore -** Returns : (gfxw_snapshot_t *) snapshot (still needs to be freed) -** The snapshot is not really restored; only more recent widgets touching -** the snapshotted area are destroyed. -*/ +/** + * As widget->widfree(widget), but destroys all overlapping widgets + * + * This operation calls widget->widfree(widget), but it also destroys all + * widgets with a higher or equal priority drawn after this widget. + * + * @param[in] widget The widget to use + */ void gfxw_annihilate(GfxWidget *widget); -/* As widget->widfree(widget), but destroys all overlapping widgets -** Parameters: (GfxWidget *) widget: The widget to use -** Returns : (void) -** This operation calls widget->widfree(widget), but it also destroys -** all widgets with a higher or equal priority drawn after this widget. -*/ +/** + * Turns a dynview into a picview + * + * The only changes are in function and type variables, actually. + * + * @param[in] dynview The victim + * @return The victim, after his transformation + */ GfxDynView *gfxw_picviewize_dynview(GfxDynView *dynview); -/* Turns a dynview into a picview -** Parameters: (GfxDynView *) dynview: The victim -** Returns : (GfxDynView *) The victim, after his transformation -** The only changes are in function and type variables, actually. -*/ -void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window, rect_t auto_rect); -/* Tags a window widget as automatically restoring the visual background upon removal -** Parameters: (gfx_visual_t *) visual: The base visual -** (GfxPort *) window: The window to tag -** (rect_t) auto_rect: The background to remember -** Also records the specified background rectangle, for later recovery -*/ +/** + * Tags a window widget as automatically restoring the visual background + * upon removal. + * + * Also records the specified background rectangle, for later recovery. + * + * @param[in] visual The base visual + * @param[in] window The window to tag + * @param[in] auto_rect The background to remember + + */ +void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window, + rect_t auto_rect); +/** @} */ } // End of namespace Sci #endif // SCI_GFX_GFX_WIDGETS_H diff --git a/engines/sci/gfx/menubar.h b/engines/sci/gfx/menubar.h index 02d99332d9..44ecd8f1bb 100644 --- a/engines/sci/gfx/menubar.h +++ b/engines/sci/gfx/menubar.h @@ -50,9 +50,7 @@ struct EngineState; /* The number of pixels added to the left of the first menu */ #define MENU_BOX_CENTER_PADDING 10 -/* Number of pixels to leave in between the left and the right centered text content in boxes -** that use right centered content -*/ +/* Number of pixels to leave in between the left and the right centered text content in boxes that use right centered content */ #define MENU_BOX_LEFT_PADDING 0 /* Number of pixels to pad to the left */ @@ -88,16 +86,16 @@ enum MenuType { class MenuItem : public Common::Serializable { public: - MenuType _type; /* Normal or hbar */ - Common::String _keytext; /* right-centered part of the text (the key) */ + MenuType _type; /**< Normal or hbar */ + Common::String _keytext; /**< right-centered part of the text (the key) */ int _flags; - byte _said[MENU_SAID_SPEC_SIZE]; /* Said spec for this item */ + byte _said[MENU_SAID_SPEC_SIZE]; /**< Said spec for this item */ reg_t _saidPos; Common::String _text; reg_t _textPos; - int _modifiers; /* Hotkey for this item */ - int _key; /* Hotkey for this item */ + int _modifiers; /**< Hotkey for this item */ + int _key; /**< Hotkey for this item */ int _enabled; int _tag; @@ -108,9 +106,10 @@ public: /** * Determines whether a message/modifiers key pair matches a menu item's key parameters. - * @param message The message to match - * @param modifiers The modifier flags to match - * @return true on match, false otherwise + * + * @param[in] message The message to match + * @param[in] modifiers The modifier flags to match + * @return true on match, false otherwise */ bool matchKey(int message, int modifiers); }; @@ -156,59 +155,68 @@ public: /** * Adds a menu to the menubar. - * Parameters: (GfxState *) state: The state the fonts are stored in - * (char *) title: The menu title - * (char *) entries: A string of menu entries - * (int) font: The font which is to be used for drawing - * (reg_t) entries_base: Segmented VM address of the entries string - * Returns : (void) + * * The menu entries use the following special characters: * '`' : Right justify the following part * ':' : End of this entry * '#' : Function key (replaced by 'F') * '^' : Control key (replaced by \002, which looks like "CTRL") * '=' : Initial tag value - * and the special string "--!", which represents a horizontal bar in the menu. + * and the special string "--!", which represents a horizontal bar in the + * menu. + * + * @param[in] state The state the fonts are stored in + * @param[in] title The menu title + * @param[in] entries A string of menu entries + * @param[in] font The font which is to be used for drawing + * @param[in] entries_base Segmented VM address of the entries string */ void addMenu(GfxState *state, const char *title, const char *entries, int font, reg_t entries_base); /** - * Sets the (currently unidentified) foo and bar values. - * Parameters: (state_t *) s: The current state - * (int) menu: The menu number to edit - * (int) item: The menu item to change - * (int) attribute: The attribute to modify - * (int) value: The value the attribute should be set to - * Returns : (int) 0 on success, 1 if either menu or item were invalid + * Sets the attributes for a menu item. + * + * @param[in] s The current state + * @param[in] menu The menu number to edit + * @param[in] item The menu item to change + * @param[in] attribute The attribute to modify + * @param[in] value The value the attribute should be set to + * @return 0 on success, 1 if either menu or item were invalid */ int setAttribute(EngineState *s, int menu, int item, int attribute, reg_t value); /** - * Sets the (currently unidentified) foo and bar values. - * Parameters: (int) menu: The menu number - * (int) item: The menu item to read - * (int) attribute: The attribute to read from - * Returns : (int) The attribute value, or -1 on error + * Gets an attribute for a menuitem. + * + * @param[in] menu The menu number + * @param[in] item The menu item to read + * @param[in] attribute The attribute to read from + * @return The attribute value, or -1 on error */ reg_t getAttribute(int menu, int item, int attribute) const; /** * Determines whether the specified menu entry may be activated. - * @return true if the menu item may be selected, false otherwise + * + * @return true if the menu item may be selected, false otherwise */ bool itemValid(int menu, int item) const; /** * Maps the pointer position to a (menu,item) tuple. - * @param pointerPos the current pointer position - * @param menu_nr the current menu (updated by this function if necessary) - * @param item_nr the current menu item (updated by this function if necessary) - * @param port the port of the currently active menu (if any) - * @return true if the pointer is outside a valid port, false otherwise. + * + * @param[in] pointerPos the current pointer position + * @param[in] menu_nr the current menu (updated by this function if + * necessary) + * @param[in] item_nr the current menu item (updated by this function + * if necessary) + * @param[in] port the port of the currently active menu (if any) + * @return true if the pointer is outside a valid port, + * false otherwise. */ bool mapPointer(const Common::Point &pointerPos, int &menu_nr, int &item_nr, GfxPort *port) const; diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp index a730717ef8..1f7c4ed479 100644 --- a/engines/sci/gfx/operations.cpp +++ b/engines/sci/gfx/operations.cpp @@ -281,13 +281,13 @@ gfx_pixmap_t *_gfxr_get_cel(GfxState *state, int nr, int *loop, int *cel, int pa return NULL; if (*loop >= view->loops_nr || *loop < 0) { - GFXWARN("Attempt to get cel from loop %d/%d inside view %d\n", *loop, view->loops_nr, nr); + warning("[GFX] Attempt to get cel from loop %d/%d inside view %d", *loop, view->loops_nr, nr); return NULL; } indexed_loop = view->loops + *loop; if (*cel >= indexed_loop->cels_nr || *cel < 0) { - GFXWARN("Attempt to get cel %d/%d from view %d/%d\n", *cel, indexed_loop->cels_nr, nr, *loop); + warning("[GFX] Attempt to get cel %d/%d from view %d/%d", *cel, indexed_loop->cels_nr, nr, *loop); return NULL; } @@ -414,7 +414,8 @@ static void init_aux_pixmap(gfx_pixmap_t **pixmap) { int gfxop_init(int version, bool isVGA, GfxState *state, gfx_options_t *options, ResourceManager *resManager, Graphics::PixelFormat mode, int xfact, int yfact) { - int initialized = 0; + //int color_depth = bpp ? bpp : 1; + //int initialized = 0; BASIC_CHECKS(GFX_FATAL); @@ -662,7 +663,7 @@ static int line_clip(rect_t *line, rect_t clip, int xfact, int yfact) { return line_check_bar(&(line->x), &(line->width), clip.x, clip.width); } else { // "normal" line - float start = 0.0, end = 1.0; + float start = 0.0f, end = 1.0f; float xv = (float)line->width; float yv = (float)line->height; @@ -682,7 +683,7 @@ static int line_clip(rect_t *line, rect_t clip, int xfact, int yfact) { line->width = (int)(xv * (end - start)); line->height = (int)(yv * (end - start)); - return (start > 1.0 || end < 0.0); + return (start > 1.0f || end < 0.0f); } } @@ -806,7 +807,7 @@ static int _gfxop_draw_line_clipped(GfxState *state, Common::Point start, Common if (line_style == GFX_LINE_STYLE_STIPPLED) { if (start.x != end.x && start.y != end.y) { - GFXWARN("Attempt to draw stippled line which is neither an hbar nor a vbar: (%d,%d) -- (%d,%d)\n", start.x, start.y, end.x, end.y); + warning("[GFX] Attempt to draw stippled line which is neither an hbar nor a vbar: (%d,%d) -- (%d,%d)", start.x, start.y, end.x, end.y); return GFX_ERROR; } return simulate_stippled_line_draw(state->driver, skipone, start, end, color, line_mode); @@ -902,7 +903,7 @@ int gfxop_draw_rectangle(GfxState *state, rect_t rect, gfx_color_t color, gfx_li int gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) { GfxDriver *drv = state->driver; int reverse = 0; // switch color1 and color2 - float mod_offset = 0.0, mod_breadth = 1.0; // 0.0 to 1.0: Color adjustment + float mod_offset = 0.0f, mod_breadth = 1.0f; // 0.0 to 1.0: Color adjustment gfx_rectangle_fill_t driver_shade_type; rect_t new_box; @@ -928,7 +929,7 @@ int gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, gfx_color_t return GFX_OK; if (box.width <= 1 || box.height <= 1) { - GFXDEBUG("Attempt to draw box with size %dx%d\n", box.width, box.height); + debugC(2, kDebugLevelGraphics, "Attempt to draw box with size %dx%d", box.width, box.height); return GFX_OK; } @@ -976,7 +977,7 @@ int gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, gfx_color_t return drv->drawFilledRect(new_box, color1, color1, GFX_SHADE_FLAT); } else { if (PALETTE_MODE) { - GFXWARN("Attempting to draw shaded box in palette mode!\n"); + warning("[GFX] Attempting to draw shaded box in palette mode"); return GFX_ERROR; } @@ -1183,7 +1184,7 @@ int gfxop_set_pointer_cursor(GfxState *state, int nr) { gfx_pixmap_t *new_pointer = state->gfxResMan->getCursor(nr); if (!new_pointer) { - GFXWARN("Attempt to set invalid pointer #%d\n", nr); + warning("[GFX] Attempt to set invalid pointer #%d\n", nr); return GFX_ERROR; } @@ -1200,12 +1201,12 @@ int gfxop_set_pointer_view(GfxState *state, int nr, int loop, int cel, Common::P gfx_pixmap_t *new_pointer = _gfxr_get_cel(state, nr, &real_loop, &real_cel, 0); if (!new_pointer) { - GFXWARN("Attempt to set invalid pointer #%d\n", nr); + warning("[GFX] Attempt to set invalid pointer #%d", nr); return GFX_ERROR; } if (real_loop != loop || real_cel != cel) { - GFXDEBUG("Changed loop/cel from %d/%d to %d/%d in view %d\n", loop, cel, real_loop, real_cel, nr); + debugC(2, kDebugLevelGraphics, "Changed loop/cel from %d/%d to %d/%d in view %d\n", loop, cel, real_loop, real_cel, nr); } // Eco Quest 1 uses a 1x1 transparent cursor to hide the cursor from the user. Some scalers don't seem to support this. @@ -1227,7 +1228,7 @@ int gfxop_set_pointer_position(GfxState *state, Common::Point pos) { state->pointer_pos = pos; if (pos.x > 320 || pos.y > 200) { - GFXWARN("Attempt to place pointer at invalid coordinates (%d, %d)\n", pos.x, pos.y); + warning("[GFX] Attempt to place pointer at invalid coordinates (%d, %d)", pos.x, pos.y); return 0; // Not fatal } @@ -1420,8 +1421,9 @@ static sci_event_t scummvm_get_event(GfxDriver *drv) { // Debug console if (ev.kbd.flags == Common::KBD_CTRL && ev.kbd.keycode == Common::KEYCODE_d) { // Open debug console - ((Sci::SciEngine*)g_engine)->getDebugger()->attach(); - ((Sci::SciEngine*)g_engine)->getDebugger()->onFrame(); + Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger(); + con->attach(); + con->onFrame(); // Clear keyboard event input.type = SCI_EVT_NONE; @@ -1620,7 +1622,7 @@ int gfxop_lookup_view_get_loops(GfxState *state, int nr) { view = state->gfxResMan->getView(nr, &loop, &cel, 0); if (!view) { - GFXWARN("Attempt to retrieve number of loops from invalid view %d\n", nr); + warning("[GFX] Attempt to retrieve number of loops from invalid view %d", nr); return 0; } @@ -1636,10 +1638,10 @@ int gfxop_lookup_view_get_cels(GfxState *state, int nr, int loop) { view = state->gfxResMan->getView(nr, &real_loop, &cel, 0); if (!view) { - GFXWARN("Attempt to retrieve number of cels from invalid/broken view %d\n", nr); + warning("[GFX] Attempt to retrieve number of cels from invalid/broken view %d", nr); return 0; } else if (real_loop != loop) { - GFXWARN("Loop number was corrected from %d to %d in view %d\n", loop, real_loop, nr); + warning("[GFX] Loop number was corrected from %d to %d in view %d", loop, real_loop, nr); } return view->loops[real_loop].cels_nr; @@ -1651,7 +1653,7 @@ int gfxop_check_cel(GfxState *state, int nr, int *loop, int *cel) { gfxr_view_t *testView = state->gfxResMan->getView(nr, loop, cel, 0); if (!testView) { - GFXWARN("Attempt to verify loop/cel values for invalid view %d\n", nr); + warning("[GFX] Attempt to verify loop/cel values for invalid view %d", nr); return GFX_ERROR; } @@ -1666,7 +1668,7 @@ int gfxop_overflow_cel(GfxState *state, int nr, int *loop, int *cel) { gfxr_view_t *testView = state->gfxResMan->getView(nr, &loop_v, &cel_v, 0); if (!testView) { - GFXWARN("Attempt to verify loop/cel values for invalid view %d\n", nr); + warning("[GFX] Attempt to verify loop/cel values for invalid view %d", nr); return GFX_ERROR; } @@ -1688,7 +1690,7 @@ int gfxop_get_cel_parameters(GfxState *state, int nr, int loop, int cel, int *wi view = state->gfxResMan->getView(nr, &loop, &cel, 0); if (!view) { - GFXWARN("Attempt to get cel parameters for invalid view %d\n", nr); + warning("[GFX] Attempt to get cel parameters for invalid view %d", nr); return GFX_ERROR; } @@ -1712,7 +1714,7 @@ static int _gfxop_draw_cel_buffer(GfxState *state, int nr, int loop, int cel, Co view = state->gfxResMan->getView(nr, &loop, &cel, palette); if (!view) { - GFXWARN("Attempt to draw loop/cel %d/%d in invalid view %d\n", loop, cel, nr); + warning("[GFX] Attempt to draw loop/cel %d/%d in invalid view %d\n", loop, cel, nr); return GFX_ERROR; } pxm = view->loops[loop].cels[cel]; @@ -1994,7 +1996,7 @@ int gfxop_draw_text(GfxState *state, TextHandle *handle, rect_t zone) { } if (handle->lines.empty()) { - GFXDEBUG("Skipping draw_text operation because number of lines is zero\n"); + debugC(2, kDebugLevelGraphics, "Skipping draw_text operation because number of lines is zero\n"); return GFX_OK; } diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h index ed71c32b65..d567934ceb 100644 --- a/engines/sci/gfx/operations.h +++ b/engines/sci/gfx/operations.h @@ -93,10 +93,10 @@ typedef Common::List<rect_t> DirtyRectList; struct GfxState { gfx_options_t *options; - Common::Point pointer_pos; /* Mouse pointer coordinates */ + Common::Point pointer_pos; /**< Mouse pointer coordinates */ - rect_t clip_zone_unscaled; /* The current UNSCALED clipping zone */ - rect_t clip_zone; /* The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */ + rect_t clip_zone_unscaled; /**< The current UNSCALED clipping zone */ + rect_t clip_zone; /**< The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */ GfxDriver *driver; @@ -104,543 +104,639 @@ struct GfxState { GfxResManager *gfxResMan; - gfx_pixmap_t *priority_map; /* back buffer priority map (unscaled) */ - gfx_pixmap_t *static_priority_map; /* static buffer priority map (unscaled) */ - gfx_pixmap_t *control_map; /* back buffer control map (only exists unscaled in the first place) */ + gfx_pixmap_t *priority_map; /**< back buffer priority map (unscaled) */ + gfx_pixmap_t *static_priority_map; /**< static buffer priority map (unscaled) */ + gfx_pixmap_t *control_map; /**< back buffer control map (only exists unscaled in the first place) */ - int tag_mode; /* Set to 1 after a new pic is drawn and the resource manager - ** has tagged all resources. Reset after the next front buffer - ** update is done, when all resources that are still tagged are - ** flushed. */ + int tag_mode; /**< Set to 1 after a new pic is drawn and the resource manager has tagged all resources. Reset after the next front buffer update is done, when all resources that are still tagged are flushed. */ - int disable_dirty; /* Set to 1 to disable dirty rect accounting */ + int disable_dirty; /**< Set to 1 to disable dirty rect accounting */ - int pic_nr; /* Number of the current pic */ - int palette_nr; /* Palette number of the current pic */ + int pic_nr; /**< Number of the current pic */ + int palette_nr; /**< Palette number of the current pic */ Common::List<sci_event_t> _events; - gfx_pixmap_t *fullscreen_override; /* An optional override picture which must have unscaled - ** full-screen size, which overrides all other visibility, and - ** which is generally slow */ + gfx_pixmap_t *fullscreen_override; /**< An optional override picture which must have unscaled full-screen size, which overrides all other visibility, and which is generally slow */ - gfxr_pic_t *pic, *pic_unscaled; /* The background picture and its unscaled equivalent */ - rect_t pic_port_bounds; /* Picture port bounds */ + gfxr_pic_t *pic, *pic_unscaled; /**< The background picture and its unscaled equivalent */ + rect_t pic_port_bounds; /**< Picture port bounds */ - DirtyRectList _dirtyRects; /* Dirty rectangles */ + DirtyRectList _dirtyRects; /**< Dirty rectangles */ }; -/**************************/ -/* Fundamental operations */ -/**************************/ - -int gfxop_init(int version, bool isVGA, GfxState *state, - gfx_options_t *options, ResourceManager *resManager, - Graphics::PixelFormat mode, int xfact = 1, int yfact = 1); -/* Initializes a graphics mode -** Parameters: (int) version: The interpreter version -** (GfxState *) state: The state to initialize -** (int x int) xfact, yfact: Horizontal and vertical scale factors -** (PixelFormat) mode: Graphics mode to use -** (gfx_options_t *) options: Rendering options -** (void *) misc_info: Additional information for the interpreter -** part of the resource loader -** Returns : (int) GFX_OK on success, GFX_ERROR if that particular mode is -** unavailable, or GFX_FATAL if the graphics driver is unable -** to provide any useful graphics support -*/ +/** @name Fundamental operations */ +/** @{ */ + +/** + * Initializes a graphics mode. + * + * @param[in] version The interpreter version + * @param[in] isVGA true if using VGA resolution + * @param[in] state The state to initialize + * @param[in] xfact Horizontal scale factor + * @param[in] yfact Vertical scale factors + * @param[in] mode Graphics mode to use + * @param[in] options Rendering options + * @param[in] resManager Resource manager to use + * @return GFX_OK on success, GFX_ERROR if that particular mode + * is unavailable, or GFX_FATAL if the graphics driver + * is unable to provide any useful graphics support + */ +int gfxop_init(int version, bool isVGA, GfxState *state, + gfx_options_t *options, ResourceManager *resManager, + Graphics::PixelFormat mode, int xfact = 1, int yfact = 1); + +/** + * Deinitializes a currently active driver. + * + * @param[in] state The state encapsulating the driver in question + * @return GFX_OK + */ int gfxop_exit(GfxState *state); -/* Deinitializes a currently active driver -** Parameters: (GfxState *) state: The state encapsulating the driver in question -** Returns : (int) GFX_OK -*/ +/** + * Calculates a bit mask calculated from some pixels on the specified + * map. + * + * @param[in] state The state containing the pixels to scan + * @param[in] area The area to check + * @param[in] map The GFX_MASKed map(s) to test + * @return An integer value where, for each 0 <= i <= 15, bit i is set + * iff there exists a map for which the corresponding bit was + * set in the 'map' parameter and for which there exists a + * pixel within the specified area so that the pixel's lower 4 + * bits, interpreted as an integer value, equal i. (Short + * version: This is an implementation of "on_control()"). + */ int gfxop_scan_bitmask(GfxState *state, rect_t area, gfx_map_mask_t map); -/* Calculates a bit mask calculated from some pixels on the specified map -** Parameters: (GfxState *) state: The state containing the pixels to scan -** (rect_t) area: The area to check -** (gfx_map_mask_t) map: The GFX_MASKed map(s) to test -** Returns : (int) An integer value where, for each 0<=i<=15, bit #i is set -** iff there exists a map for which the corresponding bit was set -** in the 'map' parameter and for which there exists a pixel within -** the specified area so that the pixel's lower 4 bits, interpreted -** as an integer value, equal i. -** (Short version: This is an implementation of "on_control()"). -*/ +/** + * Sets the currently visible map. + * + * 'visible_map' can be any of GFX_MASK_VISUAL, GFX_MASK_PRIORITY and + * GFX_MASK_CONTROL; the appropriate map (as far as its contents are known to + * the graphics subsystem) is then subsequently drawn to the screen at each + * update. If this is set to anything other than GFX_MASK_VISUAL, slow + * full-screen updates are performed. Mostly useful for debugging. The screen + * needs to be updated for the changes to take effect. + * + * @param[in] state The state to modify + * @param[in] map The GFX_MASK to set + * @return GFX_OK, or GFX_ERROR if map was invalid + */ int gfxop_set_visible_map(GfxState *state, gfx_map_mask_t map); -/* Sets the currently visible map -** Parameters: (GfxState *) state: The state to modify -** (gfx_map_mask_t) map: The GFX_MASK to set -** Returns : (int) GFX_OK, or GFX_ERROR if map was invalid -** 'visible_map' can be any of GFX_MASK_VISUAL, GFX_MASK_PRIORITY and GFX_MASK_CONTROL; the appropriate -** map (as far as its contents are known to the graphics subsystem) is then subsequently drawn to the -** screen at each update. If this is set to anything other than GFX_MASK_VISUAL, slow full-screen updates -** are performed. Mostly useful for debugging. -** The screen needs to be updated for the changes to take effect. -*/ +/** + * Sets a new clipping zone. + * + * @param[in] state The affected state + * @param[in] zone The new clipping zone + * @return GFX_OK + */ int gfxop_set_clip_zone(GfxState *state, rect_t zone); -/* Sets a new clipping zone -** Parameters: (GfxState *) state: The affected state -** (rect_t) zone: The new clipping zone -** Returns : (int) GFX_OK -*/ +/** @} */ + -/******************************/ -/* Generic drawing operations */ -/******************************/ +/** @name Generic drawing operations */ +/** @{ */ +/** + * Renders a clipped line to the back buffer. + * + * @param[in] state The state affected + * @param[in] start Starting point of the line + * @param[in] end End point of the line + * @param[in] color The color to use for drawing + * @param[in] line_mode Any valid line mode to use + * @param[in] line_style The line style to use + * @return GFX_OK or GFX_FATAL + */ int gfxop_draw_line(GfxState *state, Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); -/* Renders a clipped line to the back buffer -** Parameters: (GfxState *) state: The state affected -** (Common::Point) start: Starting point of the line -** (Common::Point) end: End point of the line -** (gfx_color_t) color: The color to use for drawing -** (gfx_line_mode_t) line_mode: Any valid line mode to use -** (gfx_line_style_t) line_style: The line style to use -** Returns : (int) GFX_OK or GFX_FATAL -*/ -int gfxop_draw_rectangle(GfxState *state, rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, - gfx_line_style_t line_style); -/* Draws a non-filled rectangular box to the back buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) rect: The rectangular area the box is drawn to -** (gfx_color_t) color: The color the box is to be drawn in -** (gfx_line_mode_t) line_mode: The line mode to use -** (gfx_line_style_t) line_style: The line style to use for the box -** Returns : (int) GFX_OK or GFX_FATAL -** Boxes drawn in thin lines will surround the minimal area described by rect. -*/ +/** + * Draws a non-filled rectangular box to the back buffer. + * + * Boxes drawn in thin lines will surround the minimal area described by rect. + * + * @param[in] state The affected state + * @param[in] rect The rectangular area the box is drawn to + * @param[in] color The color the box is to be drawn in + * @param[in] line_mode The line mode to use + * @param[in] line_style The line style to use for the box + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_rectangle(GfxState *state, rect_t rect, gfx_color_t color, + gfx_line_mode_t line_mode, gfx_line_style_t line_style); -int gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, gfx_color_t color2, - gfx_box_shade_t shade_type); -/* Draws a filled box to the back buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) box: The area to draw to -** (gfx_color_t) color1: The primary color to use for drawing -** (gfx_color_t) color2: The secondary color to draw in -** (gfx_box_shade_t) shade_type: The shading system to use -** (e.g. GFX_BOX_SHADE_FLAT) -** Returns : (int) GFX_OK or GFX_FATAL -** The draw mask, control, and priority values are derived from color1. -*/ +/** + * Draws a filled box to the back buffer. + * + * The draw mask, control, and priority values are derived from color1. + * + * @param[in] state The affected state + * @param[in] box The area to draw to + * @param[in] color1 The primary color to use for drawing + * @param[in] color2 The secondary color to draw in + * @param[in] shade_type The shading system to use (e.g. GFX_BOX_SHADE_FLAT) + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, + gfx_color_t color2, gfx_box_shade_t shade_type); +/** + * Fills a box in the back buffer with a specific color. + * + * This is a simple wrapper function for gfxop_draw_box + * + * @param[in] state The state to draw to + * @param[in] box The box to fill + * @param[in] color The color to use for filling + * @return GFX_OK or GFX_FATAL + */ int gfxop_fill_box(GfxState *state, rect_t box, gfx_color_t color); -/* Fills a box in the back buffer with a specific color -** Parameters: (GfxState *) state: The state to draw to -** (rect_t) box: The box to fill -** (gfx_color_t) color: The color to use for filling -** Returns : (int) GFX_OK or GFX_FATAL -** This is a simple wrapper function for gfxop_draw_box -*/ +/** + * Copies a box from the static buffer to the back buffer. + * + * @param[in] state The affected state + * @param[in] box The box to propagate from the static buffer + * @return GFX_OK or GFX_FATAL + */ int gfxop_clear_box(GfxState *state, rect_t box); -/* Copies a box from the static buffer to the back buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) box: The box to propagate from the static buffer -** Returns : (int) GFX_OK or GFX_FATAL -*/ +/** + * Updates all dirty rectangles. + * + * In order to track dirty rectangles, they must be enabled in the options. This + * function instructs the resource manager to free all tagged data on certain + * occasions (see gfxop_new_pic). + * + * @param[in] state The relevant state + * @return GFX_OK or GFX_FATAL if reported by the driver + */ int gfxop_update(GfxState *state); -/* Updates all dirty rectangles -** Parameters: (GfxState) *state: The relevant state -** Returns : (int) GFX_OK or GFX_FATAL if reported by the driver -** In order to track dirty rectangles, they must be enabled in the options. -** This function instructs the resource manager to free all tagged data -** on certain occasions (see gfxop_new_pic). -*/ +/** + * Propagates a box from the back buffer to the front (visible) buffer. + * + * This function instructs the resource manager to free all tagged data on + * certain occasions (see gfxop_new_pic). When called with dirty rectangle + * management enabled, it will automatically propagate all dirty rectangles as + * well, UNLESS dirty frame accounting has been disabled explicitly. + * + * @param[in] state The affected state + * @param[in] box The box to propagate to the front buffer + * @return GFX_OK or GFX_FATAL + */ int gfxop_update_box(GfxState *state, rect_t box); -/* Propagates a box from the back buffer to the front (visible) buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) box: The box to propagate to the front buffer -** Returns : (int) GFX_OK or GFX_FATAL -** This function instructs the resource manager to free all tagged data -** on certain occasions (see gfxop_new_pic). -** When called with dirty rectangle management enabled, it will automatically -** propagate all dirty rectangles as well, UNLESS dirty frame accounting has -** been disabled explicitly. -*/ +/** + * Enables dirty frame accounting. + * + * Dirty frame accounting is enabled by default. + * + * @param[in] state The state dirty frame accounting is to be enabled in + * @return GFX_OK or GFX_ERROR if state was invalid + */ int gfxop_enable_dirty_frames(GfxState *state); -/* Enables dirty frame accounting -** Parameters: (GfxState *) state: The state dirty frame accounting is to be enabled in -** Returns : (int) GFX_OK or GFX_ERROR if state was invalid -** Dirty frame accounting is enabled by default. -*/ +/** + * Disables dirty frame accounting. + * + * @param[in] state The state dirty frame accounting is to be disabled in + * @return GFX_OK or GFX_ERROR if state was invalid + */ int gfxop_disable_dirty_frames(GfxState *state); -/* Disables dirty frame accounting -** Parameters: (GfxState *) state: The state dirty frame accounting is to be disabled in -** Returns : (int) GFX_OK or GFX_ERROR if state was invalid -*/ +/** @} */ -/********************/ -/* Color operations */ -/********************/ - -int gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, int a, - int priority, int control); -/* Maps an r/g/b value to a color and sets a gfx_color_t structure -** Parameters: (GfxState *) state: The current state -** (gfx_color_t *) color: Pointer to the structure to write to -** (int x int x int) r,g,b: The red/green/blue color intensity values -** of the result color (0x00 (minimum) to 0xff (max)) -** If any of these values is less than zero, the -** resulting color will not affect the visual map when -** used for drawing -** (int) a: The alpha (transparency) value, with 0x00 meaning absolutely -** opaque and 0xff meaning fully transparent. Alpha blending support -** is optional for drivers, so these are the only two values that -** are guaranteed to work as intended. Any value in between them -** must guarantee the following opaqueness: -** opaqueness(x-1) >= opaqueness(x) >= opaqueness (x+1) -** (i.e. ([0,255], less-transparent-than) must define a partial order) -** (int) priority: The priority to use for drawing, or -1 for none -** (int) control: The control to use for drawing, or -1 to disable drawing to the -** control map -** Returns : (int) GFX_OK or GFX_ERROR if state is invalid -** In palette mode, this may allocate a new color. Use gfxop_free_color() described below to -** free that color. -*/ +/** @name Color operations */ +/** @{ */ + +/** + * Maps an r/g/b value to a color and sets a gfx_color_t structure. + * + * In palette mode, this may allocate a new color. Use gfxop_free_color() to + * free that color. If any of the r/g/b values are less than zero, the resulting + * color will not affect the visual map when used for drawing + * + * @param[in] state The current state + * @param[in] color Pointer to the structure to write to + * @param[in] r The red color intensity values of the result color + * @param[in] g The green color intensity values of the result color + * @param[in] b The blue color intensity values of the result color + * @param[in] a The alpha (transparency) value, with 0x00 meaning + * absolutely opaque and 0xff meaning fully transparent. + * Alpha blending support is optional for drivers, so these + * are the only two values that are guaranteed to work as + * intended. Any value in between them must guarantee the + * following opaqueness: opaqueness(x-1) >= opaqueness(x) + * >= opaqueness (x+1) (i.e. ([0,255], + * less-transparent-than) must define a partial order) + * @param[in] priority The priority to use for drawing, or -1 for none + * @param[in] control The control to use for drawing, or -1 to disable drawing + * to the control map + * @return GFX_OK or GFX_ERROR if state is invalid + */ +int gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, + int a, int priority, int control); +/** + * Designates a color as a 'system color'. + * + * system colors are permanent colors that cannot be deallocated. as such, they must be used with caution. + * + * @param[in] state The affected state + * @param[in] index The index for the new system color + * @param[in] color The color to designate as a system color + * @return GFX_OK or GFX_ERROR if state is invalid + */ int gfxop_set_system_color(GfxState *state, unsigned int index, gfx_color_t *color); -/* Designates a color as a 'system color' -** Parameters: (GfxState *) state: The affected state -** (unsigned int) index: The index for the new system color -** (gfx_color_t *) color: The color to designate as a system color -** Returns : (int) GFX_OK or GFX_ERROR if state is invalid -** System colors are permanent colors that cannot be deallocated. As such, they must be used -** with caution. -*/ +/** + * Frees a color allocated by gfxop_set_color(). + * + * This function is a no-op in non-index mode, or if color is a system color. + * + * @param[in] state The state affected + * @param[in] color The color to de-allocate + * @return GFX_OK or GFX_ERROR if state is invalid + */ int gfxop_free_color(GfxState *state, gfx_color_t *color); -/* Frees a color allocated by gfxop_set_color() -** Parmaeters: (GfxState *) state: The state affected -** (gfx_color_t *) color: The color to de-allocate -** Returns : (int) GFX_OK or GFX_ERROR if state is invalid -** This function is a no-op in non-index mode, or if color is a system color. -*/ - +/** @} */ -/**********************/ -/* Pointer and IO ops */ -/**********************/ +/** @name Pointer and IO ops */ +/** @{ */ +/** + * Suspends program execution for the specified amount of milliseconds. + * + * The mouse pointer will be redrawn continually, if applicable + * + * @param[in] state The state affected + * @param[in] msecs The amount of milliseconds to wait + * @return GFX_OK or GFX_ERROR + */ int gfxop_sleep(GfxState *state, uint32 msecs); -/* Suspends program execution for the specified amount of milliseconds -** Parameters: (GfxState *) state: The state affected -** (uint32) usecs: The amount of milliseconds to wait -** Returns : (int) GFX_OK or GFX_ERROR -** The mouse pointer will be redrawn continually, if applicable -*/ +/** + * Sets the mouse pointer to a cursor resource. + * + * @param[in] state The affected state + * @param[in] nr Number of the cursor resource to use + * @return GFX_OK, GFX_ERROR if the resource did not exist and was not + * GFXOP_NO_POINTER, or GFX_FATAL on fatal error conditions. + * Use nr = GFX_NO_POINTER to disable the mouse pointer + * (default). + */ int gfxop_set_pointer_cursor(GfxState *state, int nr); -/* Sets the mouse pointer to a cursor resource -** Parameters: (GfxState *) state: The affected state -** (int) nr: Number of the cursor resource to use -** Returns : (int) GFX_OK, GFX_ERROR if the resource did not -** exist and was not GFXOP_NO_POINTER, or GFX_FATAL on -** fatal error conditions. -** Use nr = GFX_NO_POINTER to disable the mouse pointer (default). -*/ +/** + * Sets the mouse pointer to a view resource. + * + * Use gfxop_set_pointer_cursor(state, GFXOP_NO_POINTER) to disable the pointer. + * + * @param[in] state The affected state + * @param[in] nr Number of the view resource to use + * @param[in] loop View loop to use + * @param[in] cel View cel to use + * @param[in] hotspot Manually set hotspot to use, or NULL for default. + * @return GFX_OK or GFX_FATAL + */ int gfxop_set_pointer_view(GfxState *state, int nr, int loop, int cel, Common::Point *hotspot); -/* Sets the mouse pointer to a view resource -** Parameters: (GfxState *) state: The affected state -** (int) nr: Number of the view resource to use -** (int) loop: View loop to use -** (int) cel: View cel to use -** (Common::Point *) hotspot: Manually set hotspot to use, or NULL for default. -** Returns : (int) GFX_OK or GFX_FATAL -** Use gfxop_set_pointer_cursor(state, GFXOP_NO_POINTER) to disable the -** pointer. -*/ +/** + * Teleports the mouse pointer to a specific position. + * + * Depending on the graphics driver, this operation may be without any effect + * + * @param[in] state The state the pointer is in + * @param[in] pos The position to teleport it to + * @return Any error code or GFX_OK + */ int gfxop_set_pointer_position(GfxState *state, Common::Point pos); -/* Teleports the mouse pointer to a specific position -** Parameters: (GfxState *) state: The state the pointer is in -** (Common::Point) pos: The position to teleport it to -** Returns : (int) Any error code or GFX_OK -** Depending on the graphics driver, this operation may be without -** any effect -*/ +/** + * Retrieves the next input event from the driver. + * + * @param[in] state The affected state + * @param[in] mask The event mask to poll from (see uinput.h) + * @return The next event in the driver's event queue, or a NONE event + * if no event matching the mask was found. + */ sci_event_t gfxop_get_event(GfxState *state, unsigned int mask); -/* Retrieves the next input event from the driver -** Parameters: (GfxState *) state: The affected state -** (int) mask: The event mask to poll from (see uinput.h) -** Returns : (sci_event_t) The next event in the driver's event queue, or -** a NONE event if no event matching the mask was found. -*/ +/** @} */ +/** @name View operations */ +/** @{ */ -/*******************/ -/* View operations */ -/*******************/ - +/** + * Determines the number of loops associated with a view. + * + * @param[in] state The state to use + * @param[in] nr Number of the view to investigate + * @return The number of loops, or GFX_ERROR if the view didn't exist + */ int gfxop_lookup_view_get_loops(GfxState *state, int nr); -/* Determines the number of loops associated with a view -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view to investigate -** Returns : (int) The number of loops, or GFX_ERROR if the view didn't exist -*/ +/** + * Determines the number of cels associated stored in a loop. + * + * @param[in] state The state to look up in + * @param[in] nr Number of the view to look up in + * @param[in] loop Number of the loop the number of cels of are to be + * investigated + * @return The number of cels in that loop, or GFX_ERROR if either the + * view or the loop didn't exist + */ int gfxop_lookup_view_get_cels(GfxState *state, int nr, int loop); -/* Determines the number of cels associated stored in a loop -** Parameters: (GfxState *) state: The state to look up in -** (int) nr: Number of the view to look up in -** (int) loop: Number of the loop the number of cels of -** are to be investigated -** Returns : (int) The number of cels in that loop, or GFX_ERROR if either -** the view or the loop didn't exist -*/ +/** + * Clips the view/loop/cel position of a cel. + * + * *loop is clipped first, then *cel. The resulting setup will be a valid view + * configuration. + * + * @param[in] state The state to use + * @param[in] nr Number of the view to use + * @param[in] loop Pointer to the variable storing the loop number to verify + * @param[in] cel Pointer to the variable storing the cel number to check + * @return GFX_OK or GFX_ERROR if the view didn't exist + */ int gfxop_check_cel(GfxState *state, int nr, int *loop, int *cel); -/* Clips the view/loop/cel position of a cel -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view to use -** (int *) loop: Pointer to the variable storing the loop -** number to verify -** (int *) cel: Pointer to the variable storing the cel -** number to check -** Returns : (int) GFX_OK or GFX_ERROR if the view didn't exist -** *loop is clipped first, then *cel. The resulting setup will be a valid -** view configuration. -*/ +/** + * Resets loop/cel values to zero if they have become invalid. + * + * @param[in] state The state to use + * @param[in] nr Number of the view to use + * @param[in] loop Pointer to the variable storing the loop number to verify + * @param[in] cel Pointer to the variable storing the cel number to check + * @return GFX_OK or GFX_ERROR if the view didn't exist *loop is + * clipped first, then *cel. The resulting setup will be a + * valid view configuration. + */ int gfxop_overflow_cel(GfxState *state, int nr, int *loop, int *cel); -/* Resets loop/cel values to zero if they have become invalid -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view to use -** (int *) loop: Pointer to the variable storing the loop -** number to verify -** (int *) cel: Pointer to the variable storing the cel -** number to check -** Returns : (int) GFX_OK or GFX_ERROR if the view didn't exist -** *loop is clipped first, then *cel. The resulting setup will be a valid -** view configuration. -*/ +/** + * Retrieves the width and height of a cel. + * + * @param[in] state The state to use + * @param[in] nr Number of the view + * @param[in] loop Loop number to examine + * @param[in] cel The cel (inside the loop) to look up + * @param[in] width The variable the width will be stored in + * @param[in] height The variable the height will be stored in + * @param[in] offset The variable the cel's x/y offset will be stored in + * @return GFX_OK if the lookup succeeded, GFX_ERROR if the + * nr/loop/cel combination was invalid + */ int gfxop_get_cel_parameters(GfxState *state, int nr, int loop, int cel, int *width, int *height, Common::Point *offset); -/* Retrieves the width and height of a cel -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view -** (int) loop: Loop number to examine -** (int) cel: The cel (inside the loop) to look up -** (int *) width: The variable the width will be stored in -** (int *) height: The variable the height will be stored in -** (Common::Point *) offset: The variable the cel's x/y offset will be stored in -** Returns : (int) GFX_OK if the lookup succeeded, GFX_ERROR if the nr/loop/cel -** combination was invalid -*/ -int gfxop_draw_cel(GfxState *state, int nr, int loop, int cel, Common::Point pos, - gfx_color_t color, int palette); -/* Draws (part of) a cel to the back buffer -** Parameters: (GfxState *) state: The state encapsulating the driver to draw with -** (int) nr: Number of the view to draw -** (int) loop: Loop of the cel to draw -** (int) cel: The cel number of the cel to draw -** (Common::Point) pos: The positino the cel is to be drawn to -** (gfx_color_t color): The priority and control values to use for drawing -** (int) palette: The palette to use -** Returns : (int) GFX_OK or GFX_FATAL -*/ +/** + * Draws (part of) a cel to the back buffer. + * + * @param[in] state The state encapsulating the driver to draw with + * @param[in] nr Number of the view to draw + * @param[in] loop Loop of the cel to draw + * @param[in] cel The cel number of the cel to draw + * @param[in] pos The positino the cel is to be drawn to + * @param[in] color The priority and control values to use for drawing + * @param[in] palette The palette to use + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_cel(GfxState *state, int nr, int loop, int cel, + Common::Point pos, gfx_color_t color, int palette); -int gfxop_draw_cel_static(GfxState *state, int nr, int loop, int cel, Common::Point pos, - gfx_color_t color, int palette); -/* Draws a cel to the static buffer; no clipping is performed -** Parameters: (GfxState *) state: The state encapsulating the driver to draw with -** (int) nr: Number of the view to draw -** (int) loop: Loop of the cel to draw -** (int) cel: The cel number of the cel to draw -** (Common::Point) pos: The positino the cel is to be drawn to -** (gfx_color_t color): The priority and control values to use for drawing -** (int) palette: The palette to use -** Returns : (int) GFX_OK or GFX_FATAL -** Let me repeat, no clipping (except for the display borders) is performed. -*/ +/** + * Draws a cel to the static buffer; no clipping is performed. + * + * No clipping (except for the display borders) is performed. + * + * @param[in] state The state encapsulating the driver to draw with + * @param[in] nr Number of the view to draw + * @param[in] loop Loop of the cel to draw + * @param[in] cel The cel number of the cel to draw + * @param[in] pos The positino the cel is to be drawn to + * @param[in] color The priority and control values to use for drawing + * @param[in] palette The palette to use + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_cel_static(GfxState *state, int nr, int loop, int cel, + Common::Point pos, gfx_color_t color, int palette); -int gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, Common::Point pos, - gfx_color_t color, int palette); -/* Draws (part of) a clipped cel to the static buffer -** Parameters: (GfxState *) state: The state encapsulating the driver to draw with -** (int) nr: Number of the view to draw -** (int) loop: Loop of the cel to draw -** (int) cel: The cel number of the cel to draw -** (Common::Point) pos: The positino the cel is to be drawn to -** (gfx_color_t color): The priority and control values to use for drawing -** (int) palette: The palette to use -** Returns : (int) GFX_OK or GFX_FATAL -** This function does clip. -*/ +/** + * Draws (part of) a clipped cel to the static buffer. + * + * This function does clip. + * + * @param[in] state The state encapsulating the driver to draw with + * @param[in] nr Number of the view to draw + * @param[in] loop Loop of the cel to draw + * @param[in] cel The cel number of the cel to draw + * @param[in] pos The positino the cel is to be drawn to + * @param[in] color The priority and control values to use for drawing + * @param[in] palette The palette to use + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, + Common::Point pos, gfx_color_t color, int palette); +/** @} */ -/******************/ -/* Pic operations */ -/******************/ -/* These operations are exempt from clipping */ +/** @name Pic operations + * These operations are exempt from clipping */ +/** @{ */ +/** + * Draws a pic and writes it over the static buffer. + * + * This function instructs the resource manager to tag all data as "unused". + * See the resource manager tag functions for a full description. + * + * @param[in] state The state affected + * @param[in] nr Number of the pic to draw + * @param[in] flags Interpreter-dependant flags to use for drawing + * @param[in] default_palette The default palette for drawing + * @return GFX_OK or GFX_FATAL + */ int gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette); -/* Draws a pic and writes it over the static buffer -** Parameters: (GfxState *) state: The state affected -** (int) nr: Number of the pic to draw -** (int) flags: Interpreter-dependant flags to use for drawing -** (int) default_palette: The default palette for drawing -** Returns : (int) GFX_OK or GFX_FATAL -** This function instructs the resource manager to tag all data as "unused". -** See the resource manager tag functions for a full description. -*/ +/** + * Retrieves all meta-information assigned to the current pic. + * + * @param[in] state The state affected + * @return NULL if the pic doesn't exist or has no meta-information, + * the meta-info otherwise. This meta-information is referred + * to as 'internal data' in the pic code + */ int *gfxop_get_pic_metainfo(GfxState *state); -/* Retrieves all meta-information assigned to the current pic -** Parameters: (GfxState *) state: The state affected -** Returns : (int *) NULL if the pic doesn't exist or has no meta-information, -** the meta-info otherwise -** This meta-information is referred to as 'internal data' in the pic code -*/ +/** + * Adds a pic to the static buffer. + * + * @param[in] state The state affected + * @param[in] nr Number of the pic to add + * @param[in] flags Interpreter-dependant flags to use for drawing + * @param[in] default_palette The default palette for drawing + * @return GFX_OK or GFX_FATAL + */ int gfxop_add_to_pic(GfxState *state, int nr, int flags, int default_palette); -/* Adds a pic to the static buffer -** Parameters: (GfxState *) state: The state affected -** (int) nr: Number of the pic to add -** (int) flags: Interpreter-dependant flags to use for drawing -** (int) default_palette: The default palette for drawing -** Returns : (int) GFX_OK or GFX_FATAL -*/ - +/** @} */ +/** @name Text operations */ +/** @{ */ -/*******************/ -/* Text operations */ -/*******************/ - - +/** + * Returns the fixed line height for one specified font. + * + * @param[in] state The state to work on + * @param[in] font_nr Number of the font to inspect + * @return GFX_ERROR, GFX_FATAL, or the font line height + */ int gfxop_get_font_height(GfxState *state, int font_nr); -/* Returns the fixed line height for one specified font -** Parameters: (GfxState *) state: The state to work on -** (int) font_nr: Number of the font to inspect -** Returns : (int) GFX_ERROR, GFX_FATAL, or the font line height -*/ +/** + * Calculates the width and height of a specified text in a specified + * font. + * + * @param[in] state The state to use + * @param[in] font_nr Font number to use for the calculation + * @param[in] text The text to examine + * @param[in] flags ORred GFXR_FONT_FLAGs + * @param[in] maxwidth The maximum pixel width to allow for the text + * @param[out] width The resulting width + * @param[out] height The resulting height + * @param[out] lines_nr Number of lines used in the text + * @param[out] lineheight Pixel height (SCI scale) of each text line + * @param[out] lastline_width Pixel offset (SCI scale) of the space after + * the last character in the last line + * @return GFX_OK or GFX_ERROR if the font didn't exist + */ int gfxop_get_text_params(GfxState *state, int font_nr, const char *text, int maxwidth, int *width, int *height, int flags, int *lines_nr, int *lineheight, int *lastline_width); -/* Calculates the width and height of a specified text in a specified font -** Parameters: (GfxState *) state: The state to use -** (int) font_nr: Font number to use for the calculation -** (const char *) text: The text to examine -** (int) flags: ORred GFXR_FONT_FLAGs -** (int) maxwidth: The maximum pixel width to allow for the text -** Returns : (int) GFX_OK or GFX_ERROR if the font didn't exist -** (int) *width: The resulting width -** (int) *height: The resulting height -** (int) *lines_nr: Number of lines used in the text -** (int) *lineheight: Pixel height (SCI scale) of each text line -** (int) *lastline_wdith: Pixel offset (SCI scale) of the space -** after the last character in the last line -*/ -TextHandle *gfxop_new_text(GfxState *state, int font_nr, const Common::String &text, int maxwidth, - gfx_alignment_t halign, gfx_alignment_t valign, gfx_color_t color1, - gfx_color_t color2, gfx_color_t bg_color, int flags); -/* Generates a new text handle that can be used to draw any text -** Parameters: (GfxState *) state: The state to use -** (int) font_nr: Font number to use for the calculation -** (const char *) text: The text to examine -** (int) maxwidth: The maximum pixel width to allow for the text -** (gfx_alignment_t) halign: The horizontal text alignment -** (gfx_alignment_t) valign: The vertical text alignment -** (gfx_color_t x gfx_color_t) color1, color2: The text's foreground colors -** (the function will dither between those two) -** (gfx_color_t) bg_color: The background color -** (int) flags: ORred GFXR_FONT_FLAGs -** Returns : (TextHandle *) A newly allocated TextHandle, or -** NULL if font_nr was invalid -** The control and priority values for the text will be extracted from color1. -** Note that the colors must have been allocated properly, or the text may display in -** incorrect colors. -*/ +/** + * Generates a new text handle that can be used to draw any text. + * + * The control and priority values for the text will be extracted from color1. + * Note that the colors must have been allocated properly, or the text may + * display in incorrect colors. + * + * @param[in] state The state to use + * @param[in] font_nr Font number to use for the calculation + * @param[in] text The text to examine + * @param[in] maxwidth: The maximum pixel width to allow for the text + * @param[in] halign The horizontal text alignment + * @param[in] valign The vertical text alignment + * @param[in] color1 The text's foreground colors (the function will dither + * between color1 and 2) + * @param[in] color2 The text's foreground colors (the function will dither + * between color1 and 2) + * @param[in] bg_color The background color + * @param[in] flags ORred GFXR_FONT_FLAGs + * @return A newly allocated TextHandle, or NULL if font_nr was + * invalid + */ +TextHandle *gfxop_new_text(GfxState *state, int font_nr, + const Common::String &text, int maxwidth, gfx_alignment_t halign, + gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, + gfx_color_t bg_color, int flags); +/** + * Frees a previously allocated text handle and all related resources. + * + * @param[in] state The state to use + * @param[in] handle The handle to free + * @return GFX_OK + */ int gfxop_free_text(GfxState *state, TextHandle *handle); -/* Frees a previously allocated text handle and all related resources -** Parameters: (GfxState *) state: The state to use -** (TextHandle *) handle: The handle to free -** Returns : (int) GFX_OK -*/ +/** + * Draws text stored in a text handle. + * + * @param[in] state The target state + * @param[in] handle The text handle to use for drawing + * @param[in] zone The rectangular box to draw to. In combination with + * halign and valign, this defines where the text is drawn + * to. + * @return GFX_OK or GFX_FATAL + */ int gfxop_draw_text(GfxState *state, TextHandle *handle, rect_t zone); -/* Draws text stored in a text handle -** Parameters: (GfxState *) state: The target state -** (TextHandle *) handle: The text handle to use for drawing -** (rect_t) zone: The rectangular box to draw to. In combination with -** halign and valign, this defines where the text is -** drawn to. -** Returns : (int) GFX_OK or GFX_FATAL -*/ +/** @} */ -/****************************/ -/* Manual pixmap operations */ -/****************************/ +/** @name Manual pixmap operations */ +/** @{ */ +/** + * Grabs a screen section from the back buffer and stores it in a pixmap. + * + * Obviously, this only affects the visual map + * + * @param[in] state The affected state + * @param[in] area The area to grab + * Returns A result pixmap, or NULL on error + */ gfx_pixmap_t *gfxop_grab_pixmap(GfxState *state, rect_t area); -/* Grabs a screen section from the back buffer and stores it in a pixmap -** Parameters: (GfxState *) state: The affected state -** (rect_t) area: The area to grab -** Returns : (gfx_pixmap_t *) A result pixmap, or NULL on error -** Obviously, this only affects the visual map -*/ -int gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, Common::Point pos); -/* Draws part of a pixmap to the screen -** Parameters: (GfxState *) state: The affected state -** (gfx_pixmap_t *) pxm: The pixmap to draw -** (rect_t) zone: The segment of the pixmap to draw -** (Common::Point) pos: The position the pixmap should be drawn to -** Returns : (int) GFX_OK or any error code -*/ +/** + * Draws part of a pixmap to the screen. + * + * @param[in] state The affected state + * @param[in] pxm The pixmap to draw + * @param[in] zone The segment of the pixmap to draw + * @param[in] pos The position the pixmap should be drawn to + * @return GFX_OK or any error code + */ +int gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, + Common::Point pos); +/** + * Frees a pixmap returned by gfxop_grab_pixmap(). + * + * @param[in] state The affected state + * @param[in] pxm The pixmap to free + * @return GFX_OK, or GFX_ERROR if the state was invalid + */ int gfxop_free_pixmap(GfxState *state, gfx_pixmap_t *pxm); -/* Frees a pixmap returned by gfxop_grab_pixmap() -** Parameters: (GfxState *) state: The affected state -** (gfx_pixmap_t *) pxm: The pixmap to free -** Returns : (int) GFX_OK, or GFX_ERROR if the state was invalid -*/ +/** @} */ -/******************************/ -/* Dirty rectangle operations */ -/******************************/ + +/** @name Dirty rectangle operations */ +/** @{ */ /** * Adds a dirty rectangle to 'base' according to a strategy. - * @param list the list to add to - * @param box the dirty frame to addable - * @param strategy the dirty frame heuristic to use (see gfx_options.h) + * + * @param[in] list the list to add to + * @param[in] box the dirty frame to addable + * @param[in] strategy the dirty frame heuristic to use (see gfx_options.h) */ void gfxdr_add_dirty(DirtyRectList &list, rect_t box, int strategy); +/** + * Clips a rectangle against another one. + * + * @param[in] rect The rectangle to clip + * @param[in] clipzone The outer bounds rect must be in + * @return 1 if rect is empty now, 0 otherwise + */ int _gfxop_clip(rect_t *rect, rect_t clipzone); -/* Clips a rectangle against another one -** Parameters: (rect_t *) rect: The rectangle to clip -** (rect_t) clipzone: The outer bounds rect must be in -** Reuturns : (int) 1 if rect is empty now, 0 otherwise -*/ +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/palette.h b/engines/sci/gfx/palette.h index 127871bce4..65d1cac18e 100644 --- a/engines/sci/gfx/palette.h +++ b/engines/sci/gfx/palette.h @@ -42,15 +42,18 @@ struct PaletteEntry { : r(R), g(G), b(B), parent_index(-1), refcount(PALENTRY_FREE) { } - // Color data + /** @name Color data */ + /** @{ */ byte r, g, b; + /** @} */ - // Index in parent palette, or -1 + /** Index in parent palette, or -1 */ int parent_index; - // Number of references from child palettes. (This includes palettes - // of pixmaps.) - // Special values: PALENTRY_LOCKED, PALENTRY_FREE + /** + * Number of references from child palettes. (This includes palettes + * of pixmaps.) + * Special values: PALENTRY_LOCKED, PALENTRY_FREE */ int refcount; }; @@ -98,10 +101,9 @@ private: Palette *_parent; - bool _dirty; // Palette has changed - int _refcount; // Number of pixmaps (or other objects) using this palette - int _revision; // When this is incremented, all child references are - // invalidated + bool _dirty; /**< Palette has changed */ + int _refcount; /**< Number of pixmaps (or other objects) using this palette */ + int _revision; /**< When this is incremented, all child references are invalidated */ }; diff --git a/engines/sci/gfx/res_pic.cpp b/engines/sci/gfx/res_pic.cpp index bb9e8a75a7..2c91cb579f 100644 --- a/engines/sci/gfx/res_pic.cpp +++ b/engines/sci/gfx/res_pic.cpp @@ -152,7 +152,7 @@ void gfxr_init_static_palette() { } -gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, int sci1) { +gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, bool sci1) { gfxr_pic_t *pic = (gfxr_pic_t*)malloc(sizeof(gfxr_pic_t)); pic->mode = mode; @@ -798,7 +798,7 @@ static void _gfxr_draw_line(gfxr_pic_t *pic, int x, int y, int ex, int ey, int c line.height = ey - y; if (x > 319 || y > 199 || x < 0 || y < 0 || ex > 319 || ey > 199 || ex < 0 || ey < 0) { - GFXWARN("While building pic: Attempt to draw line (%d,%d) to (%d,%d): cmd was %d\n", x, y, ex, ey, cmd); + warning("[GFX] While building pic: Attempt to draw line (%d,%d) to (%d,%d): cmd was %d", x, y, ex, ey, cmd); return; } @@ -1088,7 +1088,7 @@ void gfxr_remove_artifacts_pic0(gfxr_pic_t *dest, gfxr_pic_t *src) { assert(src->mode->yfact == 1); if (bound_x == 1 && bound_y == 1) { - GFXWARN("attempt to remove artifacts from unscaled pic!\n"); + warning("[GFX] attempt to remove artifacts from unscaled pic"); return; } @@ -1431,7 +1431,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, switch (opx) { case PIC_SCI1_OPX_SET_PALETTE_ENTRIES: - GFXWARN("SCI1 Set palette entried not implemented\n"); + warning("[GFX] SCI1 Set palette entried not implemented"); goto end_op_loop; case PIC_SCI0_OPX_SET_PALETTE_ENTRIES: @@ -1580,7 +1580,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, pic->priorityTable = (int*)malloc(16 * sizeof(int)); } else { // This occurs in the title screen of Longbow, perhaps with the animated Robin sprite - GFXWARN("pic->priorityTable is not NULL (%p); this only occurs with overlaid pics, otherwise it's a bug", (void *)pic->priorityTable); + warning("[GFX] pic->priorityTable is not NULL (%p); this only occurs with overlaid pics, otherwise it's a bug", (void *)pic->priorityTable); } pri_table = pic->priorityTable; @@ -1626,13 +1626,13 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, return; default: - GFXWARN("Unknown op %02x\n", op); + warning("[GFX] Unknown op %02x", op); return; } end_op_loop: {} } - GFXWARN("Reached end of pic resource %04x\n", resid); + warning("[GFX] Reached end of pic resource %04x", resid); } void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, byte *resource, @@ -1674,7 +1674,7 @@ void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, view->index_height, 1); } else { - GFXWARN("No view was contained in SCI1.1 pic resource"); + warning("[GFX] No view was contained in SCI1.1 pic resource"); } gfxr_draw_pic01(pic, flags, default_palette, size - vector_data_ptr, resource + vector_data_ptr, style, resid, 1, static_pal, portBounds); diff --git a/engines/sci/gfx/res_view.cpp b/engines/sci/gfx/res_view.cpp index f5f151cd3c..b30c57f38d 100644 --- a/engines/sci/gfx/res_view.cpp +++ b/engines/sci/gfx/res_view.cpp @@ -232,7 +232,7 @@ static int decompress_sci_view(int id, int loop, int cel, byte *resource, byte * /* if (writepos - bytes < 0) { - GFXWARN("View %02x:(%d/%d) describes more bytes than needed: %d/%d bytes at rel. offset 0x%04x\n", + warning("[GFX] View %02x:(%d/%d) describes more bytes than needed: %d/%d bytes at rel. offset 0x%04x", id, loop, cel, writepos - bytes, pixmap_size, pos - 1); bytes = pixmap_size - writepos; } @@ -246,7 +246,7 @@ static int decompress_sci_view(int id, int loop, int cel, byte *resource, byte * assert(op || literal_pos + bytes <= size); if (!mirrored && (writepos + bytes > pixmap_size)) { - GFXWARN("Writing out of bounds: %d bytes at %d > size %d\n", bytes, writepos, pixmap_size); + warning("[GFX] Writing out of bounds: %d bytes at %d > size %d", bytes, writepos, pixmap_size); } if (mirrored) { @@ -302,14 +302,14 @@ static int decompress_sci_view_amiga(int id, int loop, int cel, byte *resource, writepos += 2 * xl; if (writepos >= pixmap_size && bytes) { - GFXWARN("View %02x:(%d/%d) writing out of bounds\n", id, loop, cel); + warning("[GFX] View %02x:(%d/%d) writing out of bounds", id, loop, cel); break; } } } } else { if (writepos + bytes > pixmap_size) { - GFXWARN("View %02x:(%d/%d) describes more bytes than needed: %d/%d bytes at rel. offset 0x%04x\n", + warning("[GFX] View %02x:(%d/%d) describes more bytes than needed: %d/%d bytes at rel. offset 0x%04x", id, loop, cel, writepos - bytes, pixmap_size, pos - 1); bytes = pixmap_size - writepos; } @@ -319,7 +319,7 @@ static int decompress_sci_view_amiga(int id, int loop, int cel, byte *resource, } if (writepos < pixmap_size) { - GFXWARN("View %02x:(%d/%d) not enough pixel data in view\n", id, loop, cel); + warning("[GFX] View %02x:(%d/%d) not enough pixel data in view", id, loop, cel); return 1; } @@ -331,7 +331,7 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso int yl = READ_LE_UINT16(cel_base + 2); int pixmap_size = xl * yl; int xdisplace = isSci11 ? READ_LE_UINT16(cel_base + 4) : (int8) cel_base[4]; - int ydisplace = isSci11 ? READ_LE_UINT16(cel_base + 6) : (int8) cel_base[5]; + int ydisplace = isSci11 ? READ_LE_UINT16(cel_base + 6) : cel_base[5]; int runlength_offset = isSci11 ? READ_LE_UINT16(cel_base + 24) : 8; int literal_offset = isSci11 ? READ_LE_UINT16(cel_base + 28) : 8; gfx_pixmap_t *retval = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xl, yl, id, loop, cel)); diff --git a/engines/sci/gfx/seq_decoder.h b/engines/sci/gfx/seq_decoder.h index 16574007fe..b9feadb5f3 100644 --- a/engines/sci/gfx/seq_decoder.h +++ b/engines/sci/gfx/seq_decoder.h @@ -28,6 +28,9 @@ namespace Sci { +/** + * Decoder for image sequences + */ class SeqDecoder { public: SeqDecoder() : _fileStream(0), _palette(0) { } @@ -37,7 +40,9 @@ public: gfx_pixmap_t *getFrame(bool &hasNext); private: - bool decodeFrame(byte *runlength_data, int runlength_size, byte *literal_data, int literal_size, byte *dest, int xl, int yl, int color_key); + bool decodeFrame(byte *runlength_data, int runlength_size, + byte *literal_data, int literal_size, byte *dest, int xl, int yl, + int color_key); Common::SeekableReadStream *_fileStream; Palette *_palette; diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 01be4c5ba6..52c079e829 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -56,13 +56,6 @@ const char *sci_version_types[] = { const int sci_max_resource_nr[] = {65536, 1000, 2048, 2048, 2048, 65536, 65536, 65536}; -enum SolFlags { - kSolFlagCompressed = 1 << 0, - kSolFlagUnknown = 1 << 1, - kSolFlag16Bit = 1 << 2, - kSolFlagIsSigned = 1 << 3 -}; - static const char *sci_error_types[] = { "No error", "I/O error", @@ -94,15 +87,15 @@ static const char *resourceTypeSuffixes[] = { }; const char *getResourceTypeName(ResourceType restype) { - return resourceTypeNames[restype]; + if (restype != kResourceTypeInvalid) + return resourceTypeNames[restype]; + else + return "invalid"; } //-- Resource main functions -- Resource::Resource() { data = NULL; - number = 0; - type = kResourceTypeInvalid; - id = 0; size = 0; file_offset = 0; status = kResStatusNoMalloc; @@ -131,56 +124,45 @@ void Resource::unalloc() { ResourceSource *ResourceManager::addExternalMap(const char *file_name) { ResourceSource *newsrc = new ResourceSource(); - // Add the new source to the SLL of sources - newsrc->next = _sources; - _sources = newsrc; - newsrc->source_type = kSourceExtMap; newsrc->location_name = file_name; newsrc->scanned = false; newsrc->associated_map = NULL; + _sources.push_back(newsrc); return newsrc; } ResourceSource *ResourceManager::addSource(ResourceSource *map, ResSourceType type, const char *filename, int number) { ResourceSource *newsrc = new ResourceSource(); - // Add the new source to the SLL of sources - newsrc->next = _sources; - _sources = newsrc; - newsrc->source_type = type; newsrc->scanned = false; newsrc->location_name = filename; newsrc->volume_number = number; newsrc->associated_map = map; + _sources.push_back(newsrc); return newsrc; } ResourceSource *ResourceManager::addPatchDir(const char *dirname) { ResourceSource *newsrc = new ResourceSource(); - // Add the new source to the SLL of sources - newsrc->next = _sources; - _sources = newsrc; - newsrc->source_type = kSourceDirectory; newsrc->scanned = false; newsrc->location_name = dirname; + _sources.push_back(newsrc); return 0; } ResourceSource *ResourceManager::getVolume(ResourceSource *map, int volume_nr) { - ResourceSource *seeker = _sources; - - while (seeker) { - if ((seeker->source_type == kSourceVolume || seeker->source_type == kSourceAudioVolume) - && seeker->associated_map == map && seeker->volume_number == volume_nr) - return seeker; - seeker = seeker->next; + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) { + ResourceSource *src = *it; + if ((src->source_type == kSourceVolume || src->source_type == kSourceAudioVolume) + && src->associated_map == map && src->volume_number == volume_nr) + return src; } return NULL; @@ -198,19 +180,19 @@ bool ResourceManager::loadPatch(Resource *res, Common::File &file) { res->header = new byte[res->headerSize]; if ((res->data == NULL) || ((res->headerSize > 0) && (res->header == NULL))) { - error("Can't allocate %d bytes needed for loading %s.%i", res->size + res->headerSize, resourceTypeNames[res->type], res->number); + error("Can't allocate %d bytes needed for loading %s", res->size + res->headerSize, res->id.toString().c_str()); } unsigned int really_read; if (res->headerSize > 0) { really_read = file.read(res->header, res->headerSize); if (really_read != res->headerSize) - error("Read %d bytes from %s.%i but expected %d", really_read, resourceTypeNames[res->type], res->number, res->headerSize); + error("Read %d bytes from %s but expected %d", really_read, res->id.toString().c_str(), res->headerSize); } really_read = file.read(res->data, res->size); if (really_read != res->size) - error("Read %d bytes from %s.%i but expected %d", really_read, resourceTypeNames[res->type], res->number, res->size); + error("Read %d bytes from %s but expected %d", really_read, res->id.toString().c_str(), res->size); res->status = kResStatusAllocated; return true; @@ -228,20 +210,11 @@ bool ResourceManager::loadFromPatchFile(Resource *res) { return loadPatch(res, file); } -bool ResourceManager::loadFromAudioVolume(Resource *res) { - Common::File file; - const char *filename = res->source->location_name.c_str(); - if (file.open(filename) == false) { - warning("Failed to open audio volume %s", filename); - res->unalloc(); - return false; - } - - file.seek(res->file_offset, SEEK_SET); - - int type = file.readByte() & 0x7f; - if (type != res->type) { - warning("Resource type mismatch loading %s.%i from %s", resourceTypeNames[res->type], res->number, filename); +bool ResourceManager::loadFromAudioVolumeSCI11(Resource *res, Common::File &file) { + ResourceType type = (ResourceType)(file.readByte() & 0x7f); + if (((res->id.type == kResourceTypeAudio || res->id.type == kResourceTypeAudio36) && (type != kResourceTypeAudio)) + || ((res->id.type == kResourceTypeSync || res->id.type == kResourceTypeSync36) && (type != kResourceTypeSync))) { + warning("Resource type mismatch loading %s from %s", res->id.toString().c_str(), file.getName()); res->unalloc(); return false; } @@ -263,6 +236,21 @@ bool ResourceManager::loadFromAudioVolume(Resource *res) { return loadPatch(res, file); } +bool ResourceManager::loadFromAudioVolumeSCI1(Resource *res, Common::File &file) { + res->data = new byte[res->size]; + + if (res->data == NULL) { + error("Can't allocate %d bytes needed for loading %s", res->size, res->id.toString().c_str()); + } + + unsigned int really_read = file.read(res->data, res->size); + if (really_read != res->size) + warning("Read %d bytes from %s but expected %d", really_read, res->id.toString().c_str(), res->size); + + res->status = kResStatusAllocated; + return true; +} + Common::File *ResourceManager::getVolumeFile(const char *filename) { Common::List<Common::File *>::iterator it = _volumeFiles.begin(); Common::File *file; @@ -301,8 +289,7 @@ void ResourceManager::loadResource(Resource *res) { if (res->source->source_type == kSourcePatch && loadFromPatchFile(res)) return; - if (res->source->source_type == kSourceAudioVolume && loadFromAudioVolume(res)) - return; + // Either loading from volume or patch loading failed file = getVolumeFile(res->source->location_name.c_str()); if (!file) { @@ -311,18 +298,25 @@ void ResourceManager::loadResource(Resource *res) { return; } file->seek(res->file_offset, SEEK_SET); - int error = decompress(res, file); - if (error) { - warning("Error %d occured while reading %s.%03d from resource file: %s", - error, getResourceTypeName(res->type), res->number, sci_error_types[error]); - res->unalloc(); - } + if (res->source->source_type == kSourceAudioVolume) { + if (_sciVersion < SCI_VERSION_1_1) + loadFromAudioVolumeSCI1(res, *file); + else + loadFromAudioVolumeSCI11(res, *file); + } else { + int error = decompress(res, file); + if (error) { + warning("Error %d occured while reading %s from resource file: %s", + error, res->id.toString().c_str(), sci_error_types[error]); + res->unalloc(); + } + } } -Resource *ResourceManager::testResource(ResourceType type, int number) { - if (_resMap.contains(RESOURCE_HASH(type, number))) - return _resMap.getVal(RESOURCE_HASH(type, number)); +Resource *ResourceManager::testResource(ResourceId id) { + if (_resMap.contains(id)) + return _resMap.getVal(id); return NULL; } @@ -347,7 +341,7 @@ int ResourceManager::guessSciVersion() { int i; for (i = 0; i < 1000; i++) { - res = testResource(kResourceTypeView, i); + res = testResource(ResourceId(kResourceTypeView, i)); if (!res) continue; @@ -371,7 +365,7 @@ int ResourceManager::guessSciVersion() { // Try the same thing with pics for (i = 0; i < 1000; i++) { - res = testResource(kResourceTypePic, i); + res = testResource(ResourceId(kResourceTypePic, i)); if (!res) continue; @@ -414,72 +408,63 @@ int ResourceManager::addAppropriateSources() { addSource(map, kSourceVolume, name.c_str(), number); } addPatchDir("."); - // TODO: add RESOURCE.AUD and RESOURCE.SFX for SCI1.1 games if (Common::File::exists("MESSAGE.MAP")) addSource(addExternalMap("MESSAGE.MAP"), kSourceVolume, "RESOURCE.MSG", 0); return 1; } int ResourceManager::addInternalSources() { - if (testResource(kResourceTypeMap, 65535)) { - ResourceSource *src = addSource(NULL, kSourceIntMap, "65535.MAP", 65535); + Common::List<ResourceId> *resources = listResources(kResourceTypeMap); + Common::List<ResourceId>::iterator itr = resources->begin(); + + while (itr != resources->end()) { + ResourceSource *src = addSource(NULL, kSourceIntMap, "MAP", itr->number); - if (Common::File::exists("RESOURCE.SFX")) + if ((itr->number == 65535) && Common::File::exists("RESOURCE.SFX")) addSource(src, kSourceAudioVolume, "RESOURCE.SFX", 0); else if (Common::File::exists("RESOURCE.AUD")) addSource(src, kSourceAudioVolume, "RESOURCE.AUD", 0); + + itr++; } return 1; } -int ResourceManager::scanNewSources(ResourceSource *source) { - if (!source) - return SCI_ERROR_NO_RESOURCE_FILES_FOUND; - - int resource_error = 0; - if (source->next) - scanNewSources(source->next); - - if (!source->scanned) { - source->scanned = true; - switch (source->source_type) { - case kSourceDirectory: - readResourcePatches(source); - break; - case kSourceExtMap: - if (_mapVersion < SCI_VERSION_1) - resource_error = readResourceMapSCI0(source); - else - resource_error = readResourceMapSCI1(source); +void ResourceManager::scanNewSources() { + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) { + ResourceSource *source = *it; - if (resource_error == SCI_ERROR_RESMAP_NOT_FOUND) { - // FIXME: Try reading w/o resource.map - resource_error = SCI_ERROR_NO_RESOURCE_FILES_FOUND; - } - - if (resource_error == SCI_ERROR_NO_RESOURCE_FILES_FOUND) { - // Initialize empty resource manager - _resMap.clear(); - resource_error = 0; + if (!source->scanned) { + source->scanned = true; + switch (source->source_type) { + case kSourceDirectory: + readResourcePatches(source); + break; + case kSourceExtMap: + if (_mapVersion < SCI_VERSION_1) + readResourceMapSCI0(source); + else + readResourceMapSCI1(source); + break; + case kSourceExtAudioMap: + readAudioMapSCI1(source); + break; + case kSourceIntMap: + readAudioMapSCI11(source); + break; + default: + break; } - break; - case kSourceIntMap: - if (source->volume_number == 65535) - resource_error = readMap65535(source); - break; - default: - break; } } - return resource_error; } -void ResourceManager::freeResourceSources(ResourceSource *rss) { - if (rss) { - freeResourceSources(rss->next); - delete rss; - } +void ResourceManager::freeResourceSources() { + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) + delete *it; + + _sources.clear(); } ResourceManager::ResourceManager(int version, int maxMemory) { @@ -488,8 +473,8 @@ ResourceManager::ResourceManager(int version, int maxMemory) { _memoryLRU = 0; _LRU.clear(); _resMap.clear(); - _sources = NULL; _sciVersion = version; + _audioMapSCI1 = NULL; addAppropriateSources(); @@ -503,19 +488,19 @@ ResourceManager::ResourceManager(int version, int maxMemory) { debug("Using resource map version %d %s", _mapVersion, sci_version_types[_mapVersion]); debug("Using volume version %d %s", _volVersion, sci_version_types[_volVersion]); - scanNewSources(_sources); + scanNewSources(); addInternalSources(); - scanNewSources(_sources); + scanNewSources(); if (version == SCI_VERSION_AUTODETECT) switch (_mapVersion) { case SCI_VERSION_0: - if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB)) { + if (testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB))) { version = guessSciVersion() ? SCI_VERSION_01_VGA : SCI_VERSION_0; - } else if (testResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB)) { + } else if (testResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB))) { version = guessSciVersion(); if (version != SCI_VERSION_01_VGA) { - version = testResource(kResourceTypeVocab, 912) ? SCI_VERSION_0 : SCI_VERSION_01; + version = testResource(ResourceId(kResourceTypeVocab, 912)) ? SCI_VERSION_0 : SCI_VERSION_01; } } else { version = guessSciVersion() ? SCI_VERSION_01_VGA : SCI_VERSION_0; @@ -525,7 +510,7 @@ ResourceManager::ResourceManager(int version, int maxMemory) { version = _mapVersion; break; case SCI_VERSION_1: { - Resource *res = testResource(kResourceTypeScript, 0); + Resource *res = testResource(ResourceId(kResourceTypeScript, 0)); _sciVersion = version = SCI_VERSION_1_EARLY; loadResource(res); @@ -579,12 +564,12 @@ ResourceManager::ResourceManager(int version, int maxMemory) { ResourceManager::~ResourceManager() { // freeing resources - Common::HashMap<uint32, Resource *>::iterator itr = _resMap.begin(); + ResourceMap::iterator itr = _resMap.begin(); while (itr != _resMap.end()) { delete itr->_value; itr ++; } - freeResourceSources(_sources); + freeResourceSources(); _resMap.empty(); Common::List<Common::File *>::iterator it = _volumeFiles.begin(); @@ -628,8 +613,7 @@ void ResourceManager::printLRU() { while (it != _LRU.end()) { res = *it; - debug("\t%s.%03d: %d bytes", getResourceTypeName(res->type), - res->number, res->size); + debug("\t%s: %d bytes", res->id.toString().c_str(), res->size); mem += res->size; entries ++; it ++; @@ -638,15 +622,10 @@ void ResourceManager::printLRU() { debug("Total: %d entries, %d bytes (mgr says %d)", entries, mem, _memoryLRU); } -void ResourceManager::freeOldResources(int last_invulnerable) { - while (_maxMemory < _memoryLRU && (!last_invulnerable || !_LRU.empty())) { +void ResourceManager::freeOldResources() { + while (_maxMemory < _memoryLRU) { + assert(!_LRU.empty()); Resource *goner = *_LRU.reverse_begin(); - if (!goner) { - debug("Internal error: mgr->lru_last is NULL!"); - debug("LRU-mem= %d", _memoryLRU); - debug("lru_first = %p", (void *)*_LRU.begin()); - printLRU(); - } removeFromLRU(goner); goner->unalloc(); #ifdef SCI_VERBOSE_RESMGR @@ -655,17 +634,30 @@ void ResourceManager::freeOldResources(int last_invulnerable) { } } -Resource *ResourceManager::findResource(ResourceType type, int number, bool lock) { +Common::List<ResourceId> *ResourceManager::listResources(ResourceType type, int mapNumber) { + Common::List<ResourceId> *resources = new Common::List<ResourceId>; + + ResourceMap::iterator itr = _resMap.begin(); + while (itr != _resMap.end()) { + if ((itr->_value->id.type == type) && ((mapNumber == -1) || (itr->_value->id.number == mapNumber))) + resources->push_back(itr->_value->id); + itr++; + } + + return resources; +} + +Resource *ResourceManager::findResource(ResourceId id, bool lock) { Resource *retval; - if (number >= sci_max_resource_nr[_sciVersion]) { - int modded_number = number % sci_max_resource_nr[_sciVersion]; - sciprintf("[resmgr] Requested invalid resource %s.%d, mapped to %s.%d\n", - getResourceTypeName(type), number, getResourceTypeName(type), modded_number); - number = modded_number; + if (id.number >= sci_max_resource_nr[_sciVersion]) { + ResourceId moddedId = ResourceId(id.type, id.number % sci_max_resource_nr[_sciVersion], id.tuple); + sciprintf("[resmgr] Requested invalid resource %s, mapped to %s\n", + id.toString().c_str(), moddedId.toString().c_str()); + id = moddedId; } - retval = testResource(type, number); + retval = testResource(id); if (!retval) return NULL; @@ -677,6 +669,8 @@ Resource *ResourceManager::findResource(ResourceType type, int number, bool lock // Unless an error occured, the resource is now either // locked or allocated, but never queued or freed. + freeOldResources(); + if (lock) { if (retval->status == kResStatusAllocated) { retval->status = kResStatusLocked; @@ -689,28 +683,19 @@ Resource *ResourceManager::findResource(ResourceType type, int number, bool lock addToLRU(retval); } - freeOldResources(retval->status == kResStatusAllocated); - if (retval->data) return retval; else { - sciprintf("Resmgr: Failed to read %s.%03d\n", getResourceTypeName(retval->type), retval->number); + sciprintf("Resmgr: Failed to read %s\n", retval->id.toString().c_str()); return NULL; } } -void ResourceManager::unlockResource(Resource *res, int resnum, ResourceType restype) { - if (!res) { - if (restype == kResourceTypeInvalid) - sciprintf("Resmgr: Warning: Attempt to unlock non-existant resource %03d.%03d!\n", restype, resnum); - else - sciprintf("Resmgr: Warning: Attempt to unlock non-existant resource %s.%03d!\n", getResourceTypeName(restype), resnum); - return; - } +void ResourceManager::unlockResource(Resource *res) { + assert(res); if (res->status != kResStatusLocked) { - sciprintf("Resmgr: Warning: Attempt to unlock unlocked resource %s.%03d\n", - getResourceTypeName(res->type), res->number); + warning("[Resmgr] Attempt to unlock unlocked resource %s", res->id.toString().c_str()); return; } @@ -720,20 +705,21 @@ void ResourceManager::unlockResource(Resource *res, int resnum, ResourceType res addToLRU(res); } - freeOldResources(0); + freeOldResources(); } int ResourceManager::detectMapVersion() { Common::File file; byte buff[6]; - ResourceSource *rsrc = _sources; - // looking for extarnal map among sources - while (rsrc) { + ResourceSource *rsrc= 0; + + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) { + rsrc = *it; + if (rsrc->source_type == kSourceExtMap) { file.open(rsrc->location_name); break; } - rsrc = rsrc->next; } if (file.isOpen() == false) { warning("Failed to open resource map file"); @@ -787,14 +773,14 @@ int ResourceManager::detectMapVersion() { int ResourceManager::detectVolVersion() { Common::File file; - ResourceSource *rsrc = _sources; - // looking for a volume among sources - while (rsrc) { + ResourceSource *rsrc; + for (Common::List<ResourceSource *>::iterator it = _sources.begin(); it != _sources.end(); ++it) { + rsrc = *it; + if (rsrc->source_type == kSourceVolume) { file.open(rsrc->location_name); break; } - rsrc = rsrc->next; } if (file.isOpen() == false) { warning("Failed to open volume file"); @@ -865,7 +851,7 @@ int ResourceManager::detectVolVersion() { void ResourceManager::processPatch(ResourceSource *source, ResourceType restype, int resnumber) { Common::File file; Resource *newrsc; - uint32 resId = RESOURCE_HASH(restype, resnumber); + ResourceId resId = ResourceId(restype, resnumber); byte patchtype, patch_data_offset; int fsize; @@ -895,23 +881,13 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType restype, } // Prepare destination, if neccessary if (_resMap.contains(resId) == false) { - // FIXME: code duplication - switch (restype) { - case kResourceTypeSync: - newrsc = new ResourceSync; - break; - default: - newrsc = new Resource; - break; - } + newrsc = new Resource; _resMap.setVal(resId, newrsc); } else newrsc = _resMap.getVal(resId); // Overwrite everything, because we're patching newrsc->id = resId; - newrsc->number = resnumber; newrsc->status = kResStatusNoMalloc; - newrsc->type = restype; newrsc->source = source; newrsc->size = fsize - patch_data_offset - 2; newrsc->headerSize = patch_data_offset; @@ -1001,14 +977,12 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) { type = (ResourceType)(id >> 11); number = id & 0x7FF; - uint32 resId = RESOURCE_HASH(type, number); + ResourceId resId = ResourceId(type, number); // adding a new resource if (_resMap.contains(resId) == false) { res = new Resource; - res->id = resId;//id; res->file_offset = offset & (((~bMask) << 24) | 0xFFFFFF); - res->number = number; - res->type = type; + res->id = resId; res->source = getVolume(map, offset >> bShift); _resMap.setVal(resId, res); } @@ -1026,7 +1000,7 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { memset(resMap, 0, sizeof(resource_index_t) * 32); byte type = 0, prevtype = 0; byte nEntrySize = _mapVersion == SCI_VERSION_1_1 ? SCI11_RESMAP_ENTRIES_SIZE : SCI1_RESMAP_ENTRIES_SIZE; - uint32 resId; + ResourceId resId; // Read resource type and offsets to resource offsets block from .MAP file // The last entry has type=0xFF (0x1F) and offset equals to map file length @@ -1067,22 +1041,12 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { perror(""); return SCI_ERROR_RESMAP_NOT_FOUND; } - resId = RESOURCE_HASH(type, number); + resId = ResourceId((ResourceType)type, number); // adding new resource only if it does not exist if (_resMap.contains(resId) == false) { - switch (type) { - case kResourceTypeSync: - res = new ResourceSync; - break; - default: - res = new Resource; - break; - } - + res = new Resource; _resMap.setVal(resId, res); - res->type = (ResourceType)type; - res->number = number; - res->id = resId;//res->number | (res->type << 16); + res->id = resId; res->source = getVolume(map, volume_nr); res->file_offset = off; } @@ -1091,71 +1055,249 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { return 0; } -int ResourceManager::readMap65535(ResourceSource *map) { - // Early SCI1.1 65535.MAP structure (uses RESOURCE.AUD): - // ========= - // 6-byte entries: - // w nEntry - // dw offset +void ResourceManager::addResource(ResourceId resId, ResourceSource *src, uint32 offset, uint32 size) { + // Adding new resource only if it does not exist + if (_resMap.contains(resId) == false) { + Resource *res = new Resource; + _resMap.setVal(resId, res); + res->id = resId; + res->source = src; + res->file_offset = offset; + res->size = size; + } +} + +void ResourceManager::removeAudioResource(ResourceId resId) { + // Remove resource, unless it was loaded from a patch + if (_resMap.contains(resId)) { + Resource *res = _resMap.getVal(resId); - // Late SCI1.1 65535.MAP structure (uses RESOURCE.SFX): - // ========= - // 5-byte entries: - // w nEntry - // tb offset (cumulative) + if (res->source->source_type == kSourceAudioVolume) { + if (res->lockers == 0) { + _resMap.erase(resId); + delete res; + } else { + warning("Failed to remove resource %s (still in use)", resId.toString().c_str()); + } + } + } +} - Resource *mapRes = findResource(kResourceTypeMap, map->volume_number, false); +// Early SCI1.1 65535.MAP structure (uses RESOURCE.AUD): +// ========= +// 6-byte entries: +// w nEntry +// dw offset + +// Late SCI1.1 65535.MAP structure (uses RESOURCE.SFX): +// ========= +// 5-byte entries: +// w nEntry +// tb offset (cumulative) + +// Early SCI1.1 MAP structure: +// =============== +// 10-byte entries: +// b noun +// b verb +// b cond +// b seq +// dw offset +// w syncSize + syncAscSize + +// Late SCI1.1 MAP structure: +// =============== +// Header: +// dw baseOffset +// Followed by 7 or 11-byte entries: +// b noun +// b verb +// b cond +// b seq +// tb cOffset (cumulative offset) +// w syncSize (iff seq has bit 7 set) +// w syncAscSize (iff seq has bit 6 set) + +int ResourceManager::readAudioMapSCI11(ResourceSource *map) { + bool isEarly = true; + uint32 offset = 0; + Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->volume_number), false); if (!mapRes) { - warning("Failed to open 65535.MAP"); + warning("Failed to open %i.MAP", map->volume_number); return SCI_ERROR_RESMAP_NOT_FOUND; } ResourceSource *src = getVolume(map, 0); - if (!src) { - warning("No audio resource files found"); + if (!src) return SCI_ERROR_NO_RESOURCE_FILES_FOUND; + + byte *ptr = mapRes->data; + + if (map->volume_number == 65535) { + // Heuristic to detect late SCI1.1 map format + if ((mapRes->size >= 6) && (ptr[mapRes->size - 6] != 0xff)) + isEarly = false; + + while (ptr < mapRes->data + mapRes->size) { + uint16 n = READ_LE_UINT16(ptr); + ptr += 2; + + if (n == 0xffff) + break; + + if (isEarly) { + offset = READ_LE_UINT32(ptr); + ptr += 4; + } else { + offset += READ_LE_UINT24(ptr); + ptr += 3; + } + + addResource(ResourceId(kResourceTypeAudio, n), src, offset); + } + } else { + // Heuristic to detect late SCI1.1 map format + if ((mapRes->size >= 11) && (ptr[mapRes->size - 11] == 0xff)) + isEarly = false; + + if (!isEarly) { + offset = READ_LE_UINT32(ptr); + ptr += 4; + } + + while (ptr < mapRes->data + mapRes->size) { + uint32 n = READ_BE_UINT32(ptr); + int syncSize = 0; + ptr += 4; + + if (n == 0xffffffff) + break; + + if (isEarly) { + offset = READ_LE_UINT32(ptr); + ptr += 4; + } else { + offset += READ_LE_UINT24(ptr); + ptr += 3; + } + + if (isEarly || (n & 0x80)) { + syncSize = READ_LE_UINT16(ptr); + ptr += 2; + + if (syncSize > 0) + addResource(ResourceId(kResourceTypeSync36, map->volume_number, n & 0xffffff3f), src, offset, syncSize); + } + + if (n & 0x40) { + syncSize += READ_LE_UINT16(ptr); + ptr += 2; + } + + addResource(ResourceId(kResourceTypeAudio36, map->volume_number, n & 0xffffff3f), src, offset + syncSize); + } } - bool isEarly = true; + return 0; +} - byte *ptr = mapRes->data; - // Heuristic to detect late SCI1.1 map format - if ((mapRes->size >= 6) && (ptr[mapRes->size - 6] != 0xff)) - isEarly = false; +// AUDIOnnn.MAP contains 10-byte entries: +// w nEntry +// dw offset+volume (as in resource.map) +// dw size +// ending with 10 0xFFs - uint32 offset = 0; +int ResourceManager::readAudioMapSCI1(ResourceSource *map, bool unload) { + Common::File file; + + if (!file.open(map->location_name)) + return SCI_ERROR_RESMAP_NOT_FOUND; + + while (1) { + uint16 n = file.readUint16LE(); + uint32 offset = file.readUint32LE(); + uint32 size = file.readUint32LE(); - while (ptr < mapRes->data + mapRes->size) { - uint16 n = READ_LE_UINT16(ptr); - ptr += 2; + if (file.ioFailed()) { + warning("Error while reading %s", map->location_name.c_str()); + return SCI_ERROR_RESMAP_NOT_FOUND; + } if (n == 0xffff) break; - if (isEarly) { - offset = READ_LE_UINT32(ptr); - ptr += 4; + byte volume_nr = offset >> 28; // most significant 4 bits + offset &= 0x0fffffff; // least significant 28 bits + + ResourceSource *src = getVolume(map, volume_nr); + + if (src) { + if (unload) + removeAudioResource(ResourceId(kResourceTypeAudio, n)); + else + addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); } else { - offset += READ_LE_UINT24(ptr); - ptr += 3; + warning("Failed to find audio volume %i", volume_nr); } + } - uint32 resId = RESOURCE_HASH(kResourceTypeAudio, n); - // Adding new resource only if it does not exist - if (_resMap.contains(resId) == false) { - Resource *res = new Resource; - _resMap.setVal(resId, res); - res->type = kResourceTypeAudio; - res->number = n; - res->id = resId; - res->source = src; - res->file_offset = offset; + return 0; +} + +void ResourceManager::setAudioLanguage(int language) { + if (_audioMapSCI1) { + if (_audioMapSCI1->volume_number == language) { + // This language is already loaded + return; } + + // We already have a map loaded, so we unload it first + readAudioMapSCI1(_audioMapSCI1, true); + + // Remove all volumes that use this map from the source list + Common::List<ResourceSource *>::iterator it = _sources.begin(); + while (it != _sources.end()) { + ResourceSource *src = *it; + if (src->associated_map == _audioMapSCI1) { + it = _sources.erase(it); + delete src; + } else { + ++it; + } + } + + // Remove the map itself from the source list + _sources.remove(_audioMapSCI1); + delete _audioMapSCI1; + + _audioMapSCI1 = NULL; } - return 0; + char filename[9]; + snprintf(filename, 9, "AUDIO%03d", language); + + Common::String fullname = Common::String(filename) + ".MAP"; + if (!Common::File::exists(fullname)) { + warning("No audio map found for language %i", language); + return; + } + + _audioMapSCI1 = addSource(NULL, kSourceExtAudioMap, fullname.c_str(), language); + + // Search for audio volumes for this language and add them to the source list + Common::ArchiveMemberList files; + SearchMan.listMatchingMembers(files, Common::String(filename) + ".0??"); + for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { + const Common::String name = (*x)->getName(); + const char *dot = strrchr(name.c_str(), '.'); + int number = atoi(dot + 1); + + addSource(_audioMapSCI1, kSourceAudioVolume, name.c_str(), number); + } + + scanNewSources(); } int ResourceManager::readResourceInfo(Resource *res, Common::File *file, @@ -1206,9 +1348,7 @@ int ResourceManager::readResourceInfo(Resource *res, Common::File *file, // check if there were errors while reading if (file->ioFailed()) return SCI_ERROR_IO_ERROR; - res->id = RESOURCE_HASH(type, number); - res->type = type; - res->number = number; + res->id = ResourceId(type, number); res->size = szUnpacked; // checking compression method switch (wCompression) { @@ -1277,8 +1417,7 @@ int ResourceManager::decompress(Resource *res, Common::File *file) { break; #endif default: - warning("Resource %s #%d: Compression method %d not supported", - getResourceTypeName(res->type), res->number, compression); + warning("Resource %s: Compression method %d not supported", res->id.toString().c_str(), compression); return SCI_ERROR_UNKNOWN_COMPRESSION; } @@ -1292,469 +1431,4 @@ int ResourceManager::decompress(Resource *res, Common::File *file) { return error; } -void ResourceSync::startSync(EngineState *s, reg_t obj) { - _syncTime = _syncCue = -1; - PUT_SEL32V(obj, syncCue, 0); - _ptr = (uint16 *)data; - //syncStarted = true; // not used -} - -void ResourceSync::nextSync(EngineState *s, reg_t obj) { - if (_ptr) { - _syncTime = (int16)READ_LE_UINT16(_ptr); - if (_syncTime == -1) { - stopSync(); - } else { - _syncCue = (int16)READ_LE_UINT16(_ptr + 1); - _ptr += 2; - } - PUT_SEL32V(obj, syncTime, _syncTime); - PUT_SEL32V(obj, syncCue, _syncCue); - } -} -//-------------------------------- -void ResourceSync::stopSync() { - _ptr = 0; - _syncCue = -1; - //syncStarted = false; // not used -} - - -AudioResource::AudioResource(ResourceManager *resMgr, int sciVersion) { - _resMgr = resMgr; - _sciVersion = sciVersion; - _audioRate = 11025; - _lang = 0; - _audioMapSCI1 = 0; - _audioMapSCI11 = 0; -} - -AudioResource::~AudioResource() { - if (_sciVersion < SCI_VERSION_1_1) { - if (_audioMapSCI1) { - delete[] _audioMapSCI1; - _audioMapSCI1 = 0; - } - } else { - if (_audioMapSCI11) - _resMgr->unlockResource(_audioMapSCI11, _audioMapSCI11->number, kResourceTypeMap); - } -} - -// Used in SCI1 games -void AudioResource::setAudioLang(int16 lang) { - if (lang != -1) { - _lang = lang; - - char filename[40]; - sprintf(filename, "AUDIO%03d.MAP", _lang); - - Common::File* audioMapFile = new Common::File(); - if (audioMapFile->open(filename)) { - // The audio map is freed in the destructor - _audioMapSCI1 = new byte[audioMapFile->size()]; - audioMapFile->read(_audioMapSCI1, audioMapFile->size()); - audioMapFile->close(); - delete audioMapFile; - } else { - _audioMapSCI1 = 0; - } - } -} - -int AudioResource::getAudioPosition() { - if (g_system->getMixer()->isSoundHandleActive(_audioHandle)) { - return g_system->getMixer()->getSoundElapsedTime(_audioHandle) * 6 / 100; // return elapsed time in ticks - } else { - return -1; // Sound finished - } -} - -bool AudioResource::findAudEntrySCI1(uint16 audioNumber, byte &volume, uint32 &offset, uint32 &size) { - // AUDIO00X.MAP contains 10-byte entries: - // w nEntry - // dw offset+volume (as in resource.map) - // dw size - // ending with 10 0xFFs - uint16 n; - uint32 off; - - if (_audioMapSCI1 == 0) - return false; - - byte *ptr = _audioMapSCI1; - while ((n = READ_LE_UINT16(ptr)) != 0xFFFF) { - if (n == audioNumber) { - off = READ_LE_UINT32(ptr + 2); - size = READ_LE_UINT32(ptr + 6); - volume = off >> 28; - offset = off & 0x0FFFFFFF; - return true; - } - ptr += 10; - } - - return false; -} - -bool AudioResource::findAudEntrySCI11Late(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size) { - // Map structure: - // =============== - // Header: - // dw baseOffset - // Followed by 7 or 11-byte entries: - // b noun - // b verb - // b cond - // b seq - // tb cOffset (cumulative offset) - // w syncSize (iff seq has bit 7 set) - // w syncAscSize (iff seq has bit 6 set) - - uint32 n; - offset = 0; - - byte *ptr = _audioMapSCI11->data; - - offset = READ_LE_UINT32(ptr); - ptr += 4; - - while (ptr < _audioMapSCI11->data + _audioMapSCI11->size) { - n = READ_BE_UINT32(ptr); - ptr += 4; - - if (n == 0xffffffff) - break; - - offset += READ_LE_UINT24(ptr); - ptr += 3; - - int syncSkip = 0; - - if (n & 0x80) { - n ^= 0x80; - - if (getSync) { - if (size) - *size = READ_LE_UINT16(ptr); - } else { - syncSkip = READ_LE_UINT16(ptr); - } - - ptr += 2; - - if (n & 0x40) { - n ^= 0x40; - - if (!getSync) - syncSkip += READ_LE_UINT16(ptr); - - ptr += 2; - } - - offset += syncSkip; - - if (n == audioNumber) - return true; - - } else { - if (n == audioNumber) - return !getSync; - } - - offset -= syncSkip; - } - - return false; -} - -bool AudioResource::findAudEntrySCI11Early(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size) { - // Map structure: - // =============== - // 10-byte entries: - // b noun - // b verb - // b cond - // b seq - // dw offset - // w syncSize + syncAscSize - - uint32 n; - offset = 0; - - byte *ptr = _audioMapSCI11->data; - - while (ptr < _audioMapSCI11->data + _audioMapSCI11->size) { - n = READ_BE_UINT32(ptr); - ptr += 4; - - if (n == 0xffffffff) - break; - - offset = READ_LE_UINT32(ptr); - ptr += 4; - - int syncSize = READ_LE_UINT16(ptr); - ptr += 2; - - if (n == audioNumber) { - if (getSync) { - if (size) - *size = syncSize; - return true; - } else { - offset += syncSize; - return true; - } - } - } - - return false; -} - -bool AudioResource::findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32 &offset, bool getSync, uint32 *size) { - if (_audioMapSCI11 && _audioMapSCI11->number != volume) { - _resMgr->unlockResource(_audioMapSCI11, _audioMapSCI11->number, kResourceTypeMap); - _audioMapSCI11 = 0; - } - - if (!_audioMapSCI11) { - _audioMapSCI11 = _resMgr->findResource(kResourceTypeMap, volume, 1); - } - - byte *ptr = _audioMapSCI11->data; - - if (volume == 65535) - return false; - - // In early SCI1.1 the map is terminated with 10x 0xff, in late SCI1.1 - // with 11x 0xff. If we look at the 11th last byte in an early SCI1.1 - // map, this will be the high byte of the Sync length of the last entry. - // As Sync resources are relative small, we should never encounter a - // Sync with a size of 0xffnn. As such, the following heuristic should be - // sufficient to tell these map formats apart. - if (_audioMapSCI11->size >= 11 && (ptr[_audioMapSCI11->size - 11] == 0xff)) - return findAudEntrySCI11Late(audioNumber, offset, getSync, size); - else { - return findAudEntrySCI11Early(audioNumber, offset, getSync, size); - } - - return false; -} - -// FIXME: Move this to sound/adpcm.cpp? -// Note that the 16-bit version is also used in coktelvideo.cpp -static const uint16 tableDPCM16[128] = { - 0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080, - 0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120, - 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0, - 0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230, - 0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280, - 0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0, - 0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, - 0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, - 0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0, - 0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480, - 0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700, - 0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, - 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 -}; - -static const byte tableDPCM8[8] = {0, 1, 2, 3, 6, 10, 15, 21}; - -static void deDPCM16(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { - int16 *out = (int16 *) soundBuf; - - int32 s = 0; - for (uint32 i = 0; i < n; i++) { - byte b = audioStream.readByte(); - if (b & 0x80) - s -= tableDPCM16[b & 0x7f]; - else - s += tableDPCM16[b]; - - s = CLIP<int32>(s, -32768, 32767); - *out++ = TO_BE_16(s); - } -} - -static void deDPCM8Nibble(byte *soundBuf, int32 &s, byte b) { - if (b & 8) - s -= tableDPCM8[7 - (b & 7)]; - else - s += tableDPCM8[b & 7]; - s = CLIP<int32>(s, 0, 255); - *soundBuf = s; -} - -static void deDPCM8(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { - int32 s = 0x80; - - for (uint i = 0; i < n; i++) { - byte b = audioStream.readByte(); - - deDPCM8Nibble(soundBuf++, s, b >> 4); - deDPCM8Nibble(soundBuf++, s, b & 0xf); - } -} - -// Sierra SOL audio file reader -// Check here for more info: http://wiki.multimedia.cx/index.php?title=Sierra_Audio -static bool readSOLHeader(Common::SeekableReadStream *audioStream, int headerSize, uint32 &size, uint16 &audioRate, byte &audioFlags) { - if (headerSize != 11 && headerSize != 12) { - warning("SOL audio header of size %i not supported", headerSize); - return false; - } - - audioStream->readUint32LE(); // skip "SOL" + 0 (4 bytes) - audioRate = audioStream->readUint16LE(); - audioFlags = audioStream->readByte(); - - size = audioStream->readUint32LE(); - return true; -} - -static byte* readSOLAudio(Common::SeekableReadStream *audioStream, uint32 &size, byte audioFlags, byte &flags) { - byte *buffer; - - // Convert the SOL stream flags to our own format - flags = 0; - if (audioFlags & kSolFlag16Bit) - flags |= Audio::Mixer::FLAG_16BITS; - if (!(audioFlags & kSolFlagIsSigned)) - flags |= Audio::Mixer::FLAG_UNSIGNED; - - if (audioFlags & kSolFlagCompressed) { - buffer = new byte[size * 2]; - - if (audioFlags & kSolFlag16Bit) - deDPCM16(buffer, *audioStream, size); - else - deDPCM8(buffer, *audioStream, size); - - size *= 2; - } else { - // We assume that the sound data is raw PCM - buffer = (byte *)malloc(size); - audioStream->read(buffer, size); - } - - return buffer; -} - -Audio::AudioStream* AudioResource::getAudioStream(uint32 audioNumber, uint32 volume, int *sampleLen) { - Audio::AudioStream *audioStream = 0; - uint32 offset; - uint32 size; - bool found = false; - byte *data = 0; - char filename[40]; - byte flags = 0; - - // Try to load from resource manager - if (volume == 65535) { - Sci::Resource* audioRes = _resMgr->findResource(kResourceTypeAudio, audioNumber, false); - - if (_sciVersion < SCI_VERSION_1_1) { - size = audioRes->size; - data = audioRes->data; - } else { - byte audioFlags; - - Common::MemoryReadStream *headerStream = - new Common::MemoryReadStream(audioRes->header, audioRes->headerSize, false); - - if (readSOLHeader(headerStream, audioRes->headerSize, size, _audioRate, audioFlags)) { - Common::MemoryReadStream *dataStream = - new Common::MemoryReadStream(audioRes->data, audioRes->size, false); - data = readSOLAudio(dataStream, size, audioFlags, flags); - delete dataStream; - } - delete headerStream; - } - - if (data) { - audioStream = Audio::makeLinearInputStream(data, size, _audioRate, - flags | Audio::Mixer::FLAG_AUTOFREE, 0, 0); - } - } else { - // Load it from the audio file - if (_sciVersion < SCI_VERSION_1_1) { - byte sci1Volume; - found = findAudEntrySCI1(audioNumber, sci1Volume, offset, size); - sprintf(filename, "AUDIO%03d.%03d", _lang, sci1Volume); - flags |= Audio::Mixer::FLAG_UNSIGNED; - } else { - found = findAudEntrySCI11(audioNumber, volume, offset); - strcpy(filename, "RESOURCE.AUD"); - } - - if (found) { - #if 0 - // TODO: This tries to load directly from the KQ5CD audio file with MP3/OGG/FLAC - // compression. Once we got a tool to compress this file AND update the map file - // at the same time, we can use this code to play compressed audio. - if (_sciVersion < SCI_VERSION_1_1) { - uint32 start = offset * 1000 / _audioRate; - uint32 duration = size * 1000 / _audioRate; - - // Try to load compressed - audioStream = Audio::AudioStream::openStreamFile(filename, start, duration); - } - #endif - - if (!audioStream) { - // Compressed file load failed, try to load original raw data - Common::File* audioFile = new Common::File(); - if (audioFile->open(filename)) { - audioFile->seek(offset); - - if (_sciVersion < SCI_VERSION_1_1) { - data = (byte *)malloc(size); - audioFile->read(data, size); - } else { - byte type = audioFile->readByte() & 0x7f; - byte audioFlags; - - if (type != kResourceTypeAudio) { - warning("Resource type mismatch"); - delete audioFile; - return NULL; - } - - byte headerSize = audioFile->readByte(); - - if (readSOLHeader(audioFile, headerSize, size, _audioRate, audioFlags)) - data = readSOLAudio(audioFile, size, audioFlags, flags); - - if (!data) { - delete audioFile; - return NULL; - } - } - - audioFile->close(); - - if (data) { - audioStream = Audio::makeLinearInputStream(data, size, _audioRate, - flags | Audio::Mixer::FLAG_AUTOFREE, 0, 0); - } - } - - delete audioFile; - } - } else { - warning("Failed to find audio entry (%i, %i, %i, %i, %i)", volume, (audioNumber >> 24) & 0xff, - (audioNumber >> 16) & 0xff, (audioNumber >> 8) & 0xff, audioNumber & 0xff); - } - } - - if (audioStream) { - *sampleLen = (flags & Audio::Mixer::FLAG_16BITS ? size >> 1 : size) * 60 / _audioRate; - return audioStream; - } - - return NULL; -} - } // End of namespace Sci diff --git a/engines/sci/resource.h b/engines/sci/resource.h index 219979b383..77c92840ee 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -72,19 +72,14 @@ enum { enum ResSourceType { kSourceDirectory = 0, - kSourcePatch = 1, - kSourceVolume = 2, - kSourceExtMap = 3, - kSourceIntMap = 4, - kSourceAudioVolume = 5, - kSourceMask = 127 + kSourcePatch, + kSourceVolume, + kSourceExtMap, + kSourceIntMap, + kSourceAudioVolume, + kSourceExtAudioMap }; -#define RESSOURCE_ADDRESSING_BASIC 0 -#define RESSOURCE_ADDRESSING_EXTENDED 128 -#define RESSOURCE_ADDRESSING_MASK 128 - -#define RESOURCE_HASH(type, number) (uint32)((type<<16) | number) #define SCI0_RESMAP_ENTRIES_SIZE 6 #define SCI1_RESMAP_ENTRIES_SIZE 6 #define SCI11_RESMAP_ENTRIES_SIZE 5 @@ -136,11 +131,60 @@ struct ResourceSource { Common::String location_name; // FIXME: Replace by FSNode ? int volume_number; ResourceSource *associated_map; - ResourceSource *next; }; class ResourceManager; +class ResourceId { +public: + ResourceType type; + uint16 number; + uint32 tuple; // Only used for audio36 and sync36 + + ResourceId() : type(kResourceTypeInvalid), number(0), tuple(0) { }; + + ResourceId(ResourceType type_, uint16 number_, uint32 tuple_ = 0) : type(type_), number(number_), tuple(tuple_) { + if ((type < kResourceTypeView) || (type > kResourceTypeInvalid)) + type = kResourceTypeInvalid; + } + + ResourceId(ResourceType type_, uint16 number_, byte noun, byte verb, byte cond, byte seq) : type(type_), number(number_) { + tuple = (noun << 24) | (verb << 16) | (cond << 8) | seq; + + if ((type < kResourceTypeView) || (type > kResourceTypeInvalid)) + type = kResourceTypeInvalid; + } + + Common::String toString() { + char buf[32]; + + snprintf(buf, 32, "%s.%i", getResourceTypeName(type), number); + Common::String retStr = buf; + + if (tuple != 0) { + snprintf(buf, 32, "(%i, %i, %i, %i)", tuple >> 24, (tuple >> 16) & 0xff, (tuple >> 8) & 0xff, tuple & 0xff); + retStr += buf; + } + + return retStr; + } +}; + +struct ResourceIdHash : public Common::UnaryFunction<ResourceId, uint> { + uint operator()(ResourceId val) const { return ((uint)((val.type << 16) | val.number)) ^ val.tuple; } +}; + +struct ResourceIdEqualTo : public Common::BinaryFunction<ResourceId, ResourceId, bool> { + bool operator()(const ResourceId &x, const ResourceId &y) const { return (x.type == y.type) && (x.number == y.number) && (x.tuple == y.tuple); } +}; + +struct ResourceIdLess : public Common::BinaryFunction<ResourceId, ResourceId, bool> { + bool operator()(const ResourceId &x, const ResourceId &y) const { + return (x.type < y.type) || ((x.type == y.type) && (x.number < y.number)) + || ((x.type == y.type) && (x.number == y.number) && (x.tuple < y.tuple)); + } +}; + /** Class for storing resources in memory */ class Resource { friend class ResourceManager; @@ -153,9 +197,7 @@ public: // to let the rest of the engine compile without changes public: byte *data; - uint16 number; - ResourceType type; - uint32 id; //!< contains number and type. + ResourceId id; uint32 size; byte *header; uint32 headerSize; @@ -166,6 +208,7 @@ protected: ResourceSource *source; }; +typedef Common::HashMap<ResourceId, Resource *, ResourceIdHash, ResourceIdEqualTo> ResourceMap; class ResourceManager { public: @@ -188,26 +231,22 @@ public: /** * Looks up a resource's data. - * @param type: The resource type to look for - * @param number: The resource number to search + * @param id: The resource type to look for * @param lock: non-zero iff the resource should be locked * @return (Resource *): The resource, or NULL if it doesn't exist * @note Locked resources are guaranteed not to have their contents freed until * they are unlocked explicitly (by unlockResource). */ - Resource *findResource(ResourceType type, int number, bool lock); + Resource *findResource(ResourceId id, bool lock); /* Unlocks a previously locked resource ** (Resource *) res: The resource to free - ** (int) number: Number of the resource to check (ditto) - ** (ResourceType) type: Type of the resource to check (for error checking) ** Returns : (void) */ - void unlockResource(Resource *res, int restype, ResourceType resnum); + void unlockResource(Resource *res); /* Tests whether a resource exists - ** (ResourceType) type: Type of the resource to check - ** (int) number: Number of the resource to check + ** (ResourceId) id: Id of the resource to check ** Returns : (Resource *) non-NULL if the resource exists, NULL otherwise ** This function may often be much faster than finding the resource ** and should be preferred for simple tests. @@ -215,16 +254,27 @@ public: ** it should be used with care, as it may be unallocated. ** Use scir_find_resource() if you want to use the data contained in the resource. */ - Resource *testResource(ResourceType type, int number); + Resource *testResource(ResourceId id); + + /** + * Returns a list of all resources of the specified type. + * @param type: The resource type to look for + * @param mapNumber: For audio36 and sync36, limit search to this map + * @return: The resource list + */ + Common::List<ResourceId> *listResources(ResourceType type, int mapNumber = -1); + + void setAudioLanguage(int language); protected: int _maxMemory; //!< Config option: Maximum total byte number allocated - ResourceSource *_sources; + Common::List<ResourceSource *> _sources; int _memoryLocked; //!< Amount of resource bytes in locked memory int _memoryLRU; //!< Amount of resource bytes under LRU control Common::List<Resource *> _LRU; //!< Last Resource Used list - Common::HashMap<uint32, Resource *> _resMap; + ResourceMap _resMap; Common::List<Common::File *> _volumeFiles; //!< list of opened volume files + ResourceSource *_audioMapSCI1; //!< Currently loaded audio map for SCI1 /** * Add a path to the resource manager's list of sources. @@ -263,19 +313,22 @@ protected: * used during startup. May be NULL. * @return One of SCI_ERROR_*. */ - int scanNewSources(ResourceSource *source); + void scanNewSources(); int addAppropriateSources(); int addInternalSources(); - void freeResourceSources(ResourceSource *rss); + void freeResourceSources(); Common::File *getVolumeFile(const char *filename); void loadResource(Resource *res); bool loadPatch(Resource *res, Common::File &file); bool loadFromPatchFile(Resource *res); - bool loadFromAudioVolume(Resource *res); - void freeOldResources(int last_invulnerable); + bool loadFromAudioVolumeSCI1(Resource *res, Common::File &file); + bool loadFromAudioVolumeSCI11(Resource *res, Common::File &file); + void freeOldResources(); int decompress(Resource *res, Common::File *file); int readResourceInfo(Resource *res, Common::File *file, uint32&szPacked, ResourceCompression &compression); + void addResource(ResourceId resId, ResourceSource *src, uint32 offset, uint32 size = 0); + void removeAudioResource(ResourceId resId); /**--- Resource map decoding functions ---*/ int detectMapVersion(); @@ -283,21 +336,32 @@ protected: /** * Reads the SCI0 resource.map file from a local directory. + * @param map The map * @return 0 on success, an SCI_ERROR_* code otherwise */ int readResourceMapSCI0(ResourceSource *map); /** * Reads the SCI1 resource.map file from a local directory. + * @param map The map * @return 0 on success, an SCI_ERROR_* code otherwise */ int readResourceMapSCI1(ResourceSource *map); /** - * Reads the SCI1.1 65535.map resource + * Reads SCI1.1 audio map resources + * @param map The map * @return 0 on success, an SCI_ERROR_* code otherwise */ - int readMap65535(ResourceSource *map); + int readAudioMapSCI11(ResourceSource *map); + + /** + * Reads SCI1 audio map files + * @param map The map + * @param unload Unload the map instead of loading it + * @return 0 on success, an SCI_ERROR_* code otherwise + */ + int readAudioMapSCI1(ResourceSource *map, bool unload = false); /**--- Patch management functions ---*/ @@ -314,60 +378,6 @@ protected: int guessSciVersion(); }; -/** - * Used for lip and animation syncing in CD talkie games - */ -class ResourceSync : public Resource { -public: - ResourceSync() {} - ~ResourceSync() {} - - void startSync(EngineState *s, reg_t obj); - void nextSync(EngineState *s, reg_t obj); - void stopSync(); - -protected: - uint16 *_ptr; - int16 _syncTime, _syncCue; - //bool _syncStarted; // not used -}; - -/** - * Used for speech playback and digital music playback - * in CD talkie games - */ -class AudioResource { -public: - AudioResource(ResourceManager *resMgr, int sciVersion); - ~AudioResource(); - - void setAudioRate(uint16 audioRate) { _audioRate = audioRate; } - void setAudioLang(int16 lang); - - Audio::SoundHandle* getAudioHandle() { return &_audioHandle; } - int getAudioPosition(); - - Audio::AudioStream* getAudioStream(uint32 audioNumber, uint32 volume, int *sampleLen); - - void stop() { g_system->getMixer()->stopHandle(_audioHandle); } - void pause() { g_system->getMixer()->pauseHandle(_audioHandle, true); } - void resume() { g_system->getMixer()->pauseHandle(_audioHandle, false); } - -private: - Audio::SoundHandle _audioHandle; - uint16 _audioRate; - int16 _lang; - byte *_audioMapSCI1; - Resource *_audioMapSCI11; - ResourceManager *_resMgr; - int _sciVersion; - - bool findAudEntrySCI1(uint16 audioNumber, byte &volume, uint32 &offset, uint32 &size); - bool findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32 &offset, bool getSync = false, uint32 *size = NULL); - bool findAudEntrySCI11Late(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size); - bool findAudEntrySCI11Early(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size); -}; - } // End of namespace Sci #endif // SCI_SCICORE_RESOURCE_H diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index adcf302f51..c5bf3f5a32 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -29,6 +29,7 @@ #include "engines/advancedDetector.h" #include "sci/sci.h" +#include "sci/debug.h" #include "sci/console.h" #include "sci/engine/state.h" @@ -164,7 +165,6 @@ Common::Error SciEngine::run() { // SCI1 if (flags & GF_SCI0_OLD || - flags & GF_SCI0_OLDGFXFUNCS || flags & GF_SCI0_OLDGETTIME) { error("This game entry is erroneous. It's marked as SCI1, but it has SCI0 flags set"); } @@ -176,7 +176,6 @@ Common::Error SciEngine::run() { } if (flags & GF_SCI0_OLD || - flags & GF_SCI0_OLDGFXFUNCS || flags & GF_SCI0_OLDGETTIME) { error("This game entry is erroneous. It's marked as SCI1.1/SCI32, but it has SCI0 flags set"); } @@ -261,7 +260,19 @@ Common::Error SciEngine::run() { return Common::kNoError; } +// Invoked by error() when a severe error occurs GUI::Debugger *SciEngine::getDebugger() { + ExecStack *xs = &(_gamestate->_executionStack.back()); + debugState.runningStep = 0; // Stop multiple execution + debugState.seeking = kDebugSeekNothing; // Stop special seeks + xs->addr.pc.offset = debugState.old_pc_offset; + xs->sp = debugState.old_sp; + + return _console; +} + +// Used to obtain the engine's console in order to print messages to it +Console *SciEngine::getSciDebugger() { return _console; } diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 7cadfd0d7b..ea50976df4 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -96,18 +96,10 @@ enum SciGameFlags { */ GF_SCI0_OLD = (1 << 0), - /* Applies to all versions before 0.000.502 - ** Old SCI versions used to interpret the third DrawPic() parameter inversely, - ** with the opposite default value (obviously). - ** Also, they used 15 priority zones from 42 to 200 instead of 14 priority - ** zones from 42 to 190. - */ - GF_SCI0_OLDGFXFUNCS = (1 << 1), - /* Applies to all versions before 0.000.629 ** Older SCI versions had simpler code for GetTime() */ - GF_SCI0_OLDGETTIME = (1 << 2), + GF_SCI0_OLDGETTIME = (1 << 1), // ---------------------------------------------------------------------------- @@ -118,21 +110,22 @@ enum SciGameFlags { /* ** Used to distinguish SCI1 EGA games */ - GF_SCI1_EGA = (1 << 3), + GF_SCI1_EGA = (1 << 2), /* Applies to all SCI1 versions after 1.000.200 ** In late SCI1 versions, the argument of lofs[as] instructions ** is absolute rather than relative. */ - GF_SCI1_LOFSABSOLUTE = (1 << 4), + GF_SCI1_LOFSABSOLUTE = (1 << 3), /* Applies to all versions from 1.000.510 onwards ** kDoSound() is different than in earlier SCI1 versions. */ - GF_SCI1_NEWDOSOUND = (1 << 5) + GF_SCI1_NEWDOSOUND = (1 << 4) }; class SciEngine : public Engine { + friend class Console; public: SciEngine(OSystem *syst, const SciGameDescription *desc); ~SciEngine(); @@ -141,6 +134,7 @@ public: virtual Common::Error run(); void pauseEngineIntern(bool pause); virtual GUI::Debugger *getDebugger(); + Console *getSciDebugger(); const char* getGameID() const; int getResourceVersion() const; diff --git a/engines/sci/sfx/core.cpp b/engines/sci/sfx/core.cpp index 7e3395b7d3..95d79b3666 100644 --- a/engines/sci/sfx/core.cpp +++ b/engines/sci/sfx/core.cpp @@ -47,6 +47,15 @@ class SfxPlayer; SfxPlayer *player = NULL; // FIXME: Avoid non-const global vars +/* Plays a song iterator that found a PCM through a PCM device, if possible +** Parameters: (SongIterator *) it: The iterator to play +** (SongHandle) handle: Debug handle +** Returns : (int) 0 if the effect will not be played, nonzero if it will +** This assumes that the last call to 'it->next()' returned SI_PCM. +*/ +static int sfx_play_iterator_pcm(SongIterator *it, SongHandle handle); + + #pragma mark - @@ -337,53 +346,54 @@ int sfx_get_player_polyphony() { SfxState::SfxState() { _it = NULL; _flags = 0; - memset(&_songlib, 0, sizeof(_songlib)); _song = NULL; _suspended = 0; - _soundSync = 0; - _audioResource = 0; + _syncResource = NULL; + _audioRate = 11025; } SfxState::~SfxState() { + if (_syncResource) + _resMgr->unlockResource(_syncResource); } void SfxState::freezeTime() { /* Freezes the top song delay time */ const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC); - song_t *song = _song; + Song *song = _song; while (song) { song->_delay = song->_wakeupTime.frameDiff(ctime); if (song->_delay < 0) song->_delay = 0; - song = song->next_playing; + song = song->_nextPlaying; } } void SfxState::thawTime() { /* inverse of freezeTime() */ const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC); - song_t *song = _song; + Song *song = _song; while (song) { song->_wakeupTime = ctime.addFrames(song->_delay); - song = song->next_playing; + song = song->_nextPlaying; } } #if 0 // Unreferenced - removed static void _dump_playing_list(SfxState *self, char *msg) { - song_t *song = self->_song; + Song *song = self->_song; fprintf(stderr, "[] Song list : [ "); song = *(self->_songlib.lib); while (song) { - fprintf(stderr, "%08lx:%d ", song->handle, song->status); - song = song->next_playing; + fprintf(stderr, "%08lx:%d ", song->handle, song->_status); + song = song->_nextPlaying; } fprintf(stderr, "]\n"); @@ -391,7 +401,7 @@ static void _dump_playing_list(SfxState *self, char *msg) { while (song) { fprintf(stderr, "%08lx ", song->handle); - song = song->next_playing; + song = song->_nextPlaying; } fprintf(stderr, "]\n"); @@ -400,15 +410,15 @@ static void _dump_playing_list(SfxState *self, char *msg) { #if 0 static void _dump_songs(SfxState *self) { - song_t *song = self->_song; + Song *song = self->_song; fprintf(stderr, "Cue iterators:\n"); song = *(self->_songlib.lib); while (song) { fprintf(stderr, " **\tHandle %08x (p%d): status %d\n", - song->handle, song->priority, song->status); - SIMSG_SEND(song->it, SIMSG_PRINT(1)); - song = song->next; + song->handle, song->_priority, song->_status); + SIMSG_SEND(song->_it, SIMSG_PRINT(1)); + song = song->_next; } if (player) { @@ -418,32 +428,32 @@ static void _dump_songs(SfxState *self) { } #endif -bool SfxState::isPlaying(song_t *song) { - song_t *playing_song = _song; +bool SfxState::isPlaying(Song *song) { + Song *playing_song = _song; /* _dump_playing_list(this, "is-playing");*/ while (playing_song) { if (playing_song == song) return true; - playing_song = playing_song->next_playing; + playing_song = playing_song->_nextPlaying; } return false; } -void SfxState::setSongStatus(song_t *song, int status) { +void SfxState::setSongStatus(Song *song, int status) { const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC); switch (status) { case SOUND_STATUS_STOPPED: // Reset - song->it->init(); + song->_it->init(); break; case SOUND_STATUS_SUSPENDED: case SOUND_STATUS_WAITING: - if (song->status == SOUND_STATUS_PLAYING) { + if (song->_status == SOUND_STATUS_PLAYING) { // Update delay, set wakeup_time song->_delay += song->_wakeupTime.frameDiff(ctime); song->_wakeupTime = ctime; @@ -454,7 +464,7 @@ void SfxState::setSongStatus(song_t *song, int status) { /* otherwise... */ case SOUND_STATUS_PLAYING: - if (song->status == SOUND_STATUS_STOPPED) { + if (song->_status == SOUND_STATUS_STOPPED) { // Starting anew song->_wakeupTime = ctime; } @@ -471,12 +481,12 @@ void SfxState::setSongStatus(song_t *song, int status) { return; } - song->status = status; + song->_status = status; } /* Update internal state iff only one song may be played */ void SfxState::updateSingleSong() { - song_t *newsong = song_lib_find_active(_songlib); + Song *newsong = _songlib.findFirstActive(); if (newsong != _song) { freezeTime(); /* Store song delay time */ @@ -485,11 +495,11 @@ void SfxState::updateSingleSong() { player->stop(); if (newsong) { - if (!newsong->it) + if (!newsong->_it) return; /* Restore in progress and not ready for this yet */ /* Change song */ - if (newsong->status == SOUND_STATUS_WAITING) + if (newsong->_status == SOUND_STATUS_WAITING) setSongStatus(newsong, SOUND_STATUS_PLAYING); /* Change instrument mappings */ @@ -497,7 +507,7 @@ void SfxState::updateSingleSong() { /* Turn off sound */ } if (_song) { - if (_song->status == SOUND_STATUS_PLAYING) + if (_song->_status == SOUND_STATUS_PLAYING) setSongStatus(newsong, SOUND_STATUS_WAITING); } @@ -506,25 +516,25 @@ void SfxState::updateSingleSong() { debugMessage += " New song:"; } else { char tmp[50]; - sprintf(tmp, " pausing %08lx, now playing ", _song->handle); + sprintf(tmp, " pausing %08lx, now playing ", _song->_handle); debugMessage += tmp; } if (newsong) { char tmp[20]; - sprintf(tmp, "%08lx\n", newsong->handle); + sprintf(tmp, "%08lx\n", newsong->_handle); debugMessage += tmp; } else { debugMessage += " none\n"; } - debugC(2, kDebugLevelSound, debugMessage.c_str()); + debugC(2, kDebugLevelSound, "%s", debugMessage.c_str()); _song = newsong; thawTime(); /* Recover song delay time */ if (newsong && player) { - SongIterator *clonesong = newsong->it->clone(newsong->_delay); + SongIterator *clonesong = newsong->_it->clone(newsong->_delay); player->add_iterator(clonesong, newsong->_wakeupTime.msecs()); } @@ -533,11 +543,11 @@ void SfxState::updateSingleSong() { void SfxState::updateMultiSong() { - song_t *oldfirst = _song; - song_t *oldseeker; - song_t *newsong = song_lib_find_active(_songlib); - song_t *newseeker; - song_t not_playing_anymore; /* Dummy object, referenced by + Song *oldfirst = _song; + Song *oldseeker; + Song *newsong = _songlib.findFirstActive(); + Song *newseeker; + Song not_playing_anymore; /* Dummy object, referenced by ** songs which are no longer ** active. */ @@ -548,30 +558,28 @@ void SfxState::updateMultiSong() { return; for (newseeker = newsong; newseeker; - newseeker = newseeker->next_playing) { - if (!newseeker || !newseeker->it) + newseeker = newseeker->_nextPlaying) { + if (!newseeker || !newseeker->_it) return; /* Restore in progress and not ready for this yet */ } /* First, put all old songs into the 'stopping' list and ** mark their 'next-playing' as not_playing_anymore. */ for (oldseeker = oldfirst; oldseeker; - oldseeker = oldseeker->next_stopping) { - oldseeker->next_stopping = oldseeker->next_playing; - oldseeker->next_playing = ¬_playing_anymore; + oldseeker = oldseeker->_nextStopping) { + oldseeker->_nextStopping = oldseeker->_nextPlaying; + oldseeker->_nextPlaying = ¬_playing_anymore; - if (oldseeker == oldseeker->next_playing) { + if (oldseeker == oldseeker->_nextPlaying) { error("updateMultiSong() failed. Breakpoint in %s, line %d", __FILE__, __LINE__); } } /* Second, re-generate the new song queue. */ - for (newseeker = newsong; newseeker; - newseeker = newseeker->next_playing) { - newseeker->next_playing - = song_lib_find_next_active(_songlib, newseeker); + for (newseeker = newsong; newseeker; newseeker = newseeker->_nextPlaying) { + newseeker->_nextPlaying = _songlib.findNextActive(newseeker); - if (newseeker == newseeker->next_playing) { + if (newseeker == newseeker->_nextPlaying) { error("updateMultiSong() failed. Breakpoint in %s, line %d", __FILE__, __LINE__); } } @@ -582,21 +590,21 @@ void SfxState::updateMultiSong() { /* Third, stop all old songs */ for (oldseeker = oldfirst; oldseeker; - oldseeker = oldseeker->next_stopping) - if (oldseeker->next_playing == ¬_playing_anymore) { + oldseeker = oldseeker->_nextStopping) + if (oldseeker->_nextPlaying == ¬_playing_anymore) { setSongStatus(oldseeker, SOUND_STATUS_SUSPENDED); - debugC(2, kDebugLevelSound, "[SFX] Stopping song %lx\n", oldseeker->handle); + debugC(2, kDebugLevelSound, "[SFX] Stopping song %lx\n", oldseeker->_handle); - if (player && oldseeker->it) - player->iterator_message(SongIterator::Message(oldseeker->it->ID, SIMSG_STOP)); - oldseeker->next_playing = NULL; /* Clear this pointer; we don't need the tag anymore */ + if (player && oldseeker->_it) + player->iterator_message(SongIterator::Message(oldseeker->_it->ID, SIMSG_STOP)); + oldseeker->_nextPlaying = NULL; /* Clear this pointer; we don't need the tag anymore */ } - for (newseeker = newsong; newseeker; newseeker = newseeker->next_playing) { - if (newseeker->status != SOUND_STATUS_PLAYING && player) { - debugC(2, kDebugLevelSound, "[SFX] Adding song %lx\n", newseeker->it->ID); + for (newseeker = newsong; newseeker; newseeker = newseeker->_nextPlaying) { + if (newseeker->_status != SOUND_STATUS_PLAYING && player) { + debugC(2, kDebugLevelSound, "[SFX] Adding song %lx\n", newseeker->_it->ID); - SongIterator *clonesong = newseeker->it->clone(newseeker->_delay); + SongIterator *clonesong = newseeker->_it->clone(newseeker->_delay); player->add_iterator(clonesong, g_system->getMillis()); } setSongStatus(newseeker, SOUND_STATUS_PLAYING); @@ -615,7 +623,7 @@ void SfxState::update() { updateSingleSong(); } -int sfx_play_iterator_pcm(SongIterator *it, song_handle_t handle) { +static int sfx_play_iterator_pcm(SongIterator *it, SongHandle handle) { #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Playing PCM: %08lx\n", handle); #endif @@ -632,11 +640,11 @@ int sfx_play_iterator_pcm(SongIterator *it, song_handle_t handle) { #define DELAY (1000000 / SFX_TICKS_PER_SEC) void SfxState::sfx_init(ResourceManager *resmgr, int flags) { - song_lib_init(&_songlib); + _songlib._lib = 0; _song = NULL; _flags = flags; - _soundSync = NULL; - _audioResource = NULL; + _syncResource = NULL; + _syncOffset = 0; player = NULL; @@ -670,6 +678,8 @@ void SfxState::sfx_init(ResourceManager *resmgr, int flags) { delete player; player = NULL; } + + _resMgr = resmgr; } void SfxState::sfx_exit() { @@ -682,13 +692,7 @@ void SfxState::sfx_exit() { g_system->getMixer()->stopAll(); - song_lib_free(_songlib); - - // Delete audio resources for CD talkie games - if (_audioResource) { - delete _audioResource; - _audioResource = 0; - } + _songlib.freeSounds(); } void SfxState::sfx_suspend(bool suspend) { @@ -716,11 +720,11 @@ void SfxState::sfx_suspend(bool suspend) { _suspended = suspend; } -int SfxState::sfx_poll(song_handle_t *handle, int *cue) { +int SfxState::sfx_poll(SongHandle *handle, int *cue) { if (!_song) return 0; /* No milk today */ - *handle = _song->handle; + *handle = _song->_handle; #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Polling any (%08lx)\n", *handle); @@ -728,12 +732,12 @@ int SfxState::sfx_poll(song_handle_t *handle, int *cue) { return sfx_poll_specific(*handle, cue); } -int SfxState::sfx_poll_specific(song_handle_t handle, int *cue) { +int SfxState::sfx_poll_specific(SongHandle handle, int *cue) { const Audio::Timestamp ctime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC); - song_t *song = _song; + Song *song = _song; - while (song && song->handle != handle) - song = song->next_playing; + while (song && song->_handle != handle) + song = song->_nextPlaying; if (!song) return 0; /* Song not playing */ @@ -745,7 +749,7 @@ int SfxState::sfx_poll_specific(song_handle_t handle, int *cue) { return 0; /* Patience, young hacker! */ byte buf[8]; - int result = songit_next(&(song->it), buf, cue, IT_READER_MASK_ALL); + int result = songit_next(&(song->_it), buf, cue, IT_READER_MASK_ALL); switch (result) { @@ -783,8 +787,8 @@ int SfxState::sfx_poll_specific(song_handle_t handle, int *cue) { /* Song basics */ /*****************/ -void SfxState::sfx_add_song(SongIterator *it, int priority, song_handle_t handle, int number) { - song_t *song = song_lib_find(_songlib, handle); +void SfxState::sfx_add_song(SongIterator *it, int priority, SongHandle handle, int number) { + Song *song = _songlib.findSong(handle); #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Adding song: %08lx at %d, it=%p\n", handle, priority, it); @@ -807,37 +811,37 @@ void SfxState::sfx_add_song(SongIterator *it, int priority, song_handle_t handle setSongStatus( song, SOUND_STATUS_STOPPED); fprintf(stderr, "Overwriting old song (%08lx) ...\n", handle); - if (song->status == SOUND_STATUS_PLAYING || song->status == SOUND_STATUS_SUSPENDED) { + if (song->_status == SOUND_STATUS_PLAYING || song->_status == SOUND_STATUS_SUSPENDED) { delete it; error("Unexpected (error): Song %ld still playing/suspended (%d)", - handle, song->status); + handle, song->_status); return; } else { - song_lib_remove(_songlib, handle); /* No duplicates */ + _songlib.removeSong(handle); /* No duplicates */ } } - song = song_new(handle, it, priority); - song->resource_num = number; - song->hold = 0; - song->loops = 0; + song = new Song(handle, it, priority); + song->_resourceNum = number; + song->_hold = 0; + song->_loops = 0; song->_wakeupTime = Audio::Timestamp(g_system->getMillis(), SFX_TICKS_PER_SEC); - song_lib_add(_songlib, song); + _songlib.addSong(song); _song = NULL; /* As above */ update(); return; } -void SfxState::sfx_remove_song(song_handle_t handle) { +void SfxState::sfx_remove_song(SongHandle handle) { #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Removing song: %08lx\n", handle); #endif - if (_song && _song->handle == handle) + if (_song && _song->_handle == handle) _song = NULL; - song_lib_remove(_songlib, handle); + _songlib.removeSong(handle); update(); } @@ -849,8 +853,8 @@ void SfxState::sfx_remove_song(song_handle_t handle) { #define ASSERT_SONG(s) if (!(s)) { warning("Looking up song handle %08lx failed in %s, L%d", handle, __FILE__, __LINE__); return; } -void SfxState::sfx_song_set_status(song_handle_t handle, int status) { - song_t *song = song_lib_find(_songlib, handle); +void SfxState::sfx_song_set_status(SongHandle handle, int status) { + Song *song = _songlib.findSong(handle); ASSERT_SONG(song); #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Setting song status to %d" @@ -862,11 +866,11 @@ void SfxState::sfx_song_set_status(song_handle_t handle, int status) { update(); } -void SfxState::sfx_song_set_fade(song_handle_t handle, fade_params_t *params) { +void SfxState::sfx_song_set_fade(SongHandle handle, fade_params_t *params) { #ifdef DEBUG_SONG_API static const char *stopmsg[] = {"??? Should not happen", "Do not stop afterwards", "Stop afterwards"}; #endif - song_t *song = song_lib_find(_songlib, handle); + Song *song = _songlib.findSong(handle); ASSERT_SONG(song); @@ -877,52 +881,52 @@ void SfxState::sfx_song_set_fade(song_handle_t handle, fade_params_t *params) { stopmsg[fade->action]); #endif - SIMSG_SEND_FADE(song->it, params); + SIMSG_SEND_FADE(song->_it, params); update(); } -void SfxState::sfx_song_renice(song_handle_t handle, int priority) { - song_t *song = song_lib_find(_songlib, handle); +void SfxState::sfx_song_renice(SongHandle handle, int priority) { + Song *song = _songlib.findSong(handle); ASSERT_SONG(song); #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Renicing song %08lx to %d\n", handle, priority); #endif - song->priority = priority; + song->_priority = priority; update(); } -void SfxState::sfx_song_set_loops(song_handle_t handle, int loops) { - song_t *song = song_lib_find(_songlib, handle); +void SfxState::sfx_song_set_loops(SongHandle handle, int loops) { + Song *song = _songlib.findSong(handle); SongIterator::Message msg = SongIterator::Message(handle, SIMSG_SET_LOOPS(loops)); ASSERT_SONG(song); - song->loops = loops; + song->_loops = loops; #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Setting loops on %08lx to %d\n", handle, loops); #endif - songit_handle_message(&(song->it), msg); + songit_handle_message(&(song->_it), msg); if (player/* && player->send_iterator_message*/) /* FIXME: The above should be optional! */ player->iterator_message(msg); } -void SfxState::sfx_song_set_hold(song_handle_t handle, int hold) { - song_t *song = song_lib_find(_songlib, handle); +void SfxState::sfx_song_set_hold(SongHandle handle, int hold) { + Song *song = _songlib.findSong(handle); SongIterator::Message msg = SongIterator::Message(handle, SIMSG_SET_HOLD(hold)); ASSERT_SONG(song); - song->hold = hold; + song->_hold = hold; #ifdef DEBUG_SONG_API fprintf(stderr, "[sfx-core] Setting hold on %08lx to %d\n", handle, hold); #endif - songit_handle_message(&(song->it), msg); + songit_handle_message(&(song->_it), msg); if (player/* && player->send_iterator_message*/) /* FIXME: The above should be optional! */ @@ -934,9 +938,9 @@ static const int MIDI_cmdlen[16] = {0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0, 3, 2, 0, 3, 0 }; -static const song_handle_t midi_send_base = 0xffff0000; +static const SongHandle midi_send_base = 0xffff0000; -Common::Error SfxState::sfx_send_midi(song_handle_t handle, int channel, +Common::Error SfxState::sfx_send_midi(SongHandle handle, int channel, int command, int arg1, int arg2) { byte buffer[5]; @@ -994,8 +998,191 @@ void SfxState::sfx_all_stop() { fprintf(stderr, "[sfx-core] All stop\n"); #endif - song_lib_free(_songlib); + _songlib.freeSounds(); update(); } +int SfxState::startAudio(uint16 module, uint32 number) { + int sampleLen; + Audio::AudioStream *audioStream = getAudioStream(number, module, &sampleLen); + + if (audioStream) { + g_system->getMixer()->playInputStream(Audio::Mixer::kSpeechSoundType, &_audioHandle, audioStream); + return sampleLen; + } + + return 0; +} + +int SfxState::getAudioPosition() { + if (g_system->getMixer()->isSoundHandleActive(_audioHandle)) + return g_system->getMixer()->getSoundElapsedTime(_audioHandle) * 6 / 100; // return elapsed time in ticks + else + return -1; // Sound finished +} + +enum SolFlags { + kSolFlagCompressed = 1 << 0, + kSolFlagUnknown = 1 << 1, + kSolFlag16Bit = 1 << 2, + kSolFlagIsSigned = 1 << 3 +}; + +// FIXME: Move this to sound/adpcm.cpp? +// Note that the 16-bit version is also used in coktelvideo.cpp +static const uint16 tableDPCM16[128] = { + 0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080, + 0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120, + 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0, + 0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230, + 0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280, + 0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0, + 0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, + 0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, + 0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0, + 0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480, + 0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700, + 0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, + 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 +}; + +static const byte tableDPCM8[8] = {0, 1, 2, 3, 6, 10, 15, 21}; + +static void deDPCM16(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { + int16 *out = (int16 *) soundBuf; + + int32 s = 0; + for (uint32 i = 0; i < n; i++) { + byte b = audioStream.readByte(); + if (b & 0x80) + s -= tableDPCM16[b & 0x7f]; + else + s += tableDPCM16[b]; + + s = CLIP<int32>(s, -32768, 32767); + *out++ = TO_BE_16(s); + } +} + +static void deDPCM8Nibble(byte *soundBuf, int32 &s, byte b) { + if (b & 8) + s -= tableDPCM8[7 - (b & 7)]; + else + s += tableDPCM8[b & 7]; + s = CLIP<int32>(s, 0, 255); + *soundBuf = s; +} + +static void deDPCM8(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { + int32 s = 0x80; + + for (uint i = 0; i < n; i++) { + byte b = audioStream.readByte(); + + deDPCM8Nibble(soundBuf++, s, b >> 4); + deDPCM8Nibble(soundBuf++, s, b & 0xf); + } +} + +// Sierra SOL audio file reader +// Check here for more info: http://wiki.multimedia.cx/index.php?title=Sierra_Audio +static bool readSOLHeader(Common::SeekableReadStream *audioStream, int headerSize, uint32 &size, uint16 &audioRate, byte &audioFlags) { + if (headerSize != 11 && headerSize != 12) { + warning("SOL audio header of size %i not supported", headerSize); + return false; + } + + audioStream->readUint32LE(); // skip "SOL" + 0 (4 bytes) + audioRate = audioStream->readUint16LE(); + audioFlags = audioStream->readByte(); + + size = audioStream->readUint32LE(); + return true; +} + +static byte* readSOLAudio(Common::SeekableReadStream *audioStream, uint32 &size, byte audioFlags, byte &flags) { + byte *buffer; + + // Convert the SOL stream flags to our own format + flags = 0; + if (audioFlags & kSolFlag16Bit) + flags |= Audio::Mixer::FLAG_16BITS; + if (!(audioFlags & kSolFlagIsSigned)) + flags |= Audio::Mixer::FLAG_UNSIGNED; + + if (audioFlags & kSolFlagCompressed) { + buffer = (byte *)malloc(size * 2); + + if (audioFlags & kSolFlag16Bit) + deDPCM16(buffer, *audioStream, size); + else + deDPCM8(buffer, *audioStream, size); + + size *= 2; + } else { + // We assume that the sound data is raw PCM + buffer = (byte *)malloc(size); + audioStream->read(buffer, size); + } + + return buffer; +} + +Audio::AudioStream* SfxState::getAudioStream(uint32 number, uint32 volume, int *sampleLen) { + Audio::AudioStream *audioStream = 0; + uint32 size = 0; + byte *data = 0; + byte flags = 0; + Sci::Resource* audioRes; + + if (volume == 65535) { + audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio, number), false); + if (!audioRes) { + warning("Failed to find audio entry %i", number); + return NULL; + } + } else { + audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio36, volume, number), false); + if (!audioRes) { + warning("Failed to find audio entry (%i, %i, %i, %i, %i)", volume, (number >> 24) & 0xff, + (number >> 16) & 0xff, (number >> 8) & 0xff, number & 0xff); + return NULL; + } + } + + byte audioFlags; + + if (audioRes->headerSize > 0) { + // SCI1.1 + Common::MemoryReadStream *headerStream = + new Common::MemoryReadStream(audioRes->header, audioRes->headerSize, false); + + if (readSOLHeader(headerStream, audioRes->headerSize, size, _audioRate, audioFlags)) { + Common::MemoryReadStream *dataStream = + new Common::MemoryReadStream(audioRes->data, audioRes->size, false); + data = readSOLAudio(dataStream, size, audioFlags, flags); + delete dataStream; + } + delete headerStream; + } else { + // SCI1 + size = audioRes->size; + data = (byte *)malloc(size); + assert(data); + memcpy(data, audioRes->data, size); + flags = Audio::Mixer::FLAG_UNSIGNED; + } + + if (data) { + audioStream = Audio::makeLinearInputStream(data, size, _audioRate, + flags | Audio::Mixer::FLAG_AUTOFREE, 0, 0); + if (audioStream) { + *sampleLen = (flags & Audio::Mixer::FLAG_16BITS ? size >> 1 : size) * 60 / _audioRate; + return audioStream; + } + } + + return NULL; +} + } // End of namespace Sci diff --git a/engines/sci/sfx/core.h b/engines/sci/sfx/core.h index 69e30b43d8..e7eba85c99 100644 --- a/engines/sci/sfx/core.h +++ b/engines/sci/sfx/core.h @@ -47,11 +47,12 @@ class SfxState { public: // FIXME, make private SongIterator *_it; /**< The song iterator at the heart of things */ uint _flags; /**< SFX_STATE_FLAG_* */ - songlib_t _songlib; /**< Song library */ - song_t *_song; /**< Active song, or start of active song chain */ + SongLibrary _songlib; /**< Song library */ + Song *_song; /**< Active song, or start of active song chain */ bool _suspended; /**< Whether we are suspended */ - ResourceSync *_soundSync; /**< Used by kDoSync for speech syncing in CD talkie games */ - AudioResource *_audioResource; /**< Used for audio resources in CD talkie games */ + Resource *_syncResource; /**< Used by kDoSync for speech syncing in CD talkie games */ + uint _syncOffset; + ResourceManager *_resMgr; public: SfxState(); @@ -77,17 +78,17 @@ public: /* Polls the sound server for cues etc. ** Returns : (int) 0 if the cue queue is empty, SI_LOOP, SI_CUE, or SI_FINISHED otherwise - ** (song_handle_t) *handle: The affected handle + ** (SongHandle) *handle: The affected handle ** (int) *cue: The sound cue number (if SI_CUE), or the loop number (if SI_LOOP) */ - int sfx_poll(song_handle_t *handle, int *cue); + int sfx_poll(SongHandle *handle, int *cue); /* Polls the sound server for cues etc. - ** Parameters: (song_handle_t) handle: The handle to poll + ** Parameters: (SongHandle) handle: The handle to poll ** Returns : (int) 0 if the cue queue is empty, SI_LOOP, SI_CUE, or SI_FINISHED otherwise ** (int) *cue: The sound cue number (if SI_CUE), or the loop number (if SI_LOOP) */ - int sfx_poll_specific(song_handle_t handle, int *cue); + int sfx_poll_specific(SongHandle handle, int *cue); /* Determines the current global volume settings ** Returns : (int) The global volume, between 0 (silent) and 127 (max. volume) @@ -111,15 +112,15 @@ public: /* Adds a song to the internal sound library ** Parameters: (SongIterator *) it: The iterator describing the song ** (int) priority: Initial song priority (higher <-> more important) - ** (song_handle_t) handle: The handle to associate with the song + ** (SongHandle) handle: The handle to associate with the song */ - void sfx_add_song(SongIterator *it, int priority, song_handle_t handle, int resnum); + void sfx_add_song(SongIterator *it, int priority, SongHandle handle, int resnum); /* Deletes a song and its associated song iterator from the song queue - ** Parameters: (song_handle_t) handle: The song to remove + ** Parameters: (SongHandle) handle: The song to remove */ - void sfx_remove_song(song_handle_t handle); + void sfx_remove_song(SongHandle handle); /**********************/ @@ -128,53 +129,66 @@ public: /* Sets the song status, i.e. whether it is playing, suspended, or stopped. - ** Parameters: (song_handle_t) handle: Handle of the song to modify + ** Parameters: (SongHandle) handle: Handle of the song to modify ** (int) status: The song status the song should assume ** WAITING and PLAYING are set implicitly and essentially describe the same state ** as far as this function is concerned. */ - void sfx_song_set_status(song_handle_t handle, int status); + void sfx_song_set_status(SongHandle handle, int status); /* Sets the new song priority - ** Parameters: (song_handle_t) handle: The handle to modify + ** Parameters: (SongHandle) handle: The handle to modify ** (int) priority: The priority to set */ - void sfx_song_renice(song_handle_t handle, int priority); + void sfx_song_renice(SongHandle handle, int priority); /* Sets the number of loops for the specified song - ** Parameters: (song_handle_t) handle: The song handle to reference + ** Parameters: (SongHandle) handle: The song handle to reference ** (int) loops: Number of loops to set */ - void sfx_song_set_loops(song_handle_t handle, int loops); + void sfx_song_set_loops(SongHandle handle, int loops); /* Sets the number of loops for the specified song - ** Parameters: (song_handle_t) handle: The song handle to reference + ** Parameters: (SongHandle) handle: The song handle to reference ** (int) hold: Number of loops to setn */ - void sfx_song_set_hold(song_handle_t handle, int hold); + void sfx_song_set_hold(SongHandle handle, int hold); /* Instructs a song to be faded out - ** Parameters: (song_handle_t) handle: The song handle to reference + ** Parameters: (SongHandle) handle: The song handle to reference ** (fade_params_t *) fade_setup: The precise fade-out configuration to use */ - void sfx_song_set_fade(song_handle_t handle, fade_params_t *fade_setup); + void sfx_song_set_fade(SongHandle handle, fade_params_t *fade_setup); // Previously undocumented: - Common::Error sfx_send_midi(song_handle_t handle, int channel, + Common::Error sfx_send_midi(SongHandle handle, int channel, int command, int arg1, int arg2); + // Functions for digital sound + void setAudioRate(uint16 rate) { _audioRate = rate; } + Audio::SoundHandle* getAudioHandle() { return &_audioHandle; } + int getAudioPosition(); + int startAudio(uint16 module, uint32 tuple); + void stopAudio() { g_system->getMixer()->stopHandle(_audioHandle); } + void pauseAudio() { g_system->getMixer()->pauseHandle(_audioHandle, true); } + void resumeAudio() { g_system->getMixer()->pauseHandle(_audioHandle, false); } + protected: void freezeTime(); void thawTime(); - bool isPlaying(song_t *song); - void setSongStatus(song_t *song, int status); + bool isPlaying(Song *song); + void setSongStatus(Song *song, int status); void updateSingleSong(); void updateMultiSong(); void update(); -}; +private: + uint16 _audioRate; + Audio::SoundHandle _audioHandle; + Audio::AudioStream* getAudioStream(uint32 number, uint32 volume, int *sampleLen); +}; } // End of namespace Sci diff --git a/engines/sci/sfx/iterator.cpp b/engines/sci/sfx/iterator.cpp index 1743b787fc..ad33bc8dfb 100644 --- a/engines/sci/sfx/iterator.cpp +++ b/engines/sci/sfx/iterator.cpp @@ -68,8 +68,8 @@ BaseSongIterator::BaseSongIterator(byte *data, uint size, songit_id_t id) #define SCI0_PCM_DATA_OFFSET 0x2c #define CHECK_FOR_END_ABSOLUTE(offset) \ - if (offset > self->_data.size()) { \ - warning("Reached end of song without terminator (%x/%x) at %d", offset, self->_data.size(), __LINE__); \ + if (offset > _data.size()) { \ + warning("Reached end of song without terminator (%x/%x) at %d", offset, _data.size(), __LINE__); \ return SI_FINISHED; \ } @@ -145,8 +145,7 @@ void SongIteratorChannel::resetSynthChannels() { } } -static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, - int *result, SongIteratorChannel *channel, int flags) { +int BaseSongIterator::parseMidiCommand(byte *buf, int *result, SongIteratorChannel *channel, int flags) { byte cmd; int paramsleft; int midi_op; @@ -154,7 +153,7 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, channel->state = SI_STATE_DELTA_TIME; - cmd = self->_data[channel->offset++]; + cmd = _data[channel->offset++]; if (!(cmd & 0x80)) { /* 'Running status' mode */ @@ -177,12 +176,12 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, fprintf(stderr, "[IT]: off=%x, cmd=%02x, takes %d args ", channel->offset - 1, cmd, paramsleft); fprintf(stderr, "[%02x %02x <%02x> %02x %02x %02x]\n", - self->_data[channel->offset-3], - self->_data[channel->offset-2], - self->_data[channel->offset-1], - self->_data[channel->offset], - self->_data[channel->offset+1], - self->_data[channel->offset+2]); + _data[channel->offset-3], + _data[channel->offset-2], + _data[channel->offset-1], + _data[channel->offset], + _data[channel->offset+1], + _data[channel->offset+2]); } #endif @@ -190,7 +189,7 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, CHECK_FOR_END(paramsleft); - memcpy(buf + 1, self->_data.begin() + channel->offset, paramsleft); + memcpy(buf + 1, _data.begin() + channel->offset, paramsleft); *result = 1 + paramsleft; channel->offset += paramsleft; @@ -208,24 +207,24 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, /* Next, check if the channel is allowed */ && (!((1 << midi_channel) & channel->playmask))) return /* Execute next command */ - self->nextCommand(buf, result); + nextCommand(buf, result); if (cmd == SCI_MIDI_EOT) { /* End of track? */ channel->resetSynthChannels(); - /* fprintf(stderr, "eot; loops = %d, notesplayed=%d\n", self->loops, channel->notes_played);*/ - if (self->loops > 1 /* && channel->notes_played*/) { + /* fprintf(stderr, "eot; loops = %d, notesplayed=%d\n", loops, channel->notes_played);*/ + if (_loops > 1 /* && channel->notes_played*/) { /* If allowed, decrement the number of loops */ if (!(flags & PARSE_FLAG_LOOPS_UNLIMITED)) - *result = --self->loops; + *result = --_loops; #ifdef DEBUG_DECODING - fprintf(stderr, "%s L%d: (%p):%d Looping ", __FILE__, __LINE__, self, channel->id); + fprintf(stderr, "%s L%d: (%p):%d Looping ", __FILE__, __LINE__, this, channel->id); if (flags & PARSE_FLAG_LOOPS_UNLIMITED) fprintf(stderr, "(indef.)"); else - fprintf(stderr, "(%d)", self->loops); + fprintf(stderr, "(%d)", _loops); fprintf(stderr, " %x -> %x\n", channel->offset, channel->loop_offset); #endif @@ -234,15 +233,15 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, channel->state = SI_STATE_DELTA_TIME; channel->total_timepos = channel->loop_timepos; channel->last_cmd = 0xfe; - fprintf(stderr, "Looping song iterator %08lx.\n", self->ID); + fprintf(stderr, "Looping song iterator %08lx.\n", ID); return SI_LOOP; } else { channel->state = SI_STATE_FINISHED; #ifdef DEBUG_DECODING fprintf(stderr, "%s L%d: (%p):%d EOT because" " %d notes, %d loops\n", - __FILE__, __LINE__, self, channel->id, - channel->notes_played, self->loops); + __FILE__, __LINE__, this, channel->id, + channel->notes_played, _loops); #endif return SI_FINISHED; } @@ -253,7 +252,7 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, channel->loop_timepos = channel->total_timepos; return /* Execute next command */ - self->nextCommand(buf, result); + nextCommand(buf, result); } else { /* Used to be conditional <= 127 */ *result = buf[1]; /* Absolute cue */ @@ -264,37 +263,38 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, case SCI_MIDI_CUMULATIVE_CUE: if (flags & PARSE_FLAG_PARAMETRIC_CUE) - self->ccc += buf[2]; + _ccc += buf[2]; else { /* No parameter to CC */ - self->ccc++; + _ccc++; /* channel->offset--; */ } - *result = self->ccc; + *result = _ccc; return SI_RELATIVE_CUE; case SCI_MIDI_RESET_ON_SUSPEND: - self->resetflag = buf[2]; + _resetflag = buf[2]; break; case SCI_MIDI_SET_POLYPHONY: - self->polyphony[midi_channel] = buf[2]; + _polyphony[midi_channel] = buf[2]; #if 0 { + Sci1SongIterator *self1 = (Sci1SongIterator *)this; int i; int voices = 0; - for (i = 0; i < ((Sci1SongIterator *) self)->_numChannels; i++) { - voices += self->polyphony[i]; + for (i = 0; i < self1->_numChannels; i++) { + voices += _polyphony[i]; } sciprintf("SET_POLYPHONY(%d, %d) for a total of %d voices\n", midi_channel, buf[2], voices); sciprintf("[iterator-1] DEBUG: Polyphony = [ "); - for (i = 0; i < ((Sci1SongIterator *) self)->_numChannels; i++) - sciprintf("%d ", self->polyphony[i]); + for (i = 0; i < self1->_numChannels; i++) + sciprintf("%d ", _polyphony[i]); sciprintf("]\n"); sciprintf("[iterator-1] DEBUG: Importance = [ "); - for (i = 0; i < ((Sci1SongIterator *) self)->_numChannels; i++) - sciprintf("%d ", self->importance[i]); + for (i = 0; i < self1->_numChannels; i++) + sciprintf("%d ", _importance[i]); sciprintf("]\n"); } #endif @@ -309,7 +309,7 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, case SCI_MIDI_HOLD: { // Safe cast: This controller is only used in SCI1 - Sci1SongIterator *self1 = (Sci1SongIterator *)self; + Sci1SongIterator *self1 = (Sci1SongIterator *)this; if (buf[2] == self1->_hold) { channel->offset = channel->initial_offset; @@ -317,7 +317,7 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, channel->state = SI_STATE_COMMAND; channel->total_timepos = 0; - self1->_numLoopedChannels = self1->active_channels - 1; + self1->_numLoopedChannels = self1->_numActiveChannels - 1; return SI_LOOP; } @@ -330,7 +330,7 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, case 0x73: /* UNKNOWN NYI (happens in Hoyle) */ case 0xd1: /* UNKNOWN NYI (happens in KQ4 when riding the unicorn) */ return /* Execute next command */ - self->nextCommand(buf, result); + nextCommand(buf, result); case 0x01: /* modulation */ case 0x07: /* volume */ @@ -353,15 +353,15 @@ static int _parse_sci_midi_command(BaseSongIterator *self, byte *buf, } } -static int _sci_midi_process_state(BaseSongIterator *self, byte *buf, int *result, +int BaseSongIterator::processMidi(byte *buf, int *result, SongIteratorChannel *channel, int flags) { CHECK_FOR_END(0); switch (channel->state) { case SI_STATE_PCM: { - if (self->_data[channel->offset] == 0 - && self->_data[channel->offset + 1] == SCI_MIDI_EOT) + if (_data[channel->offset] == 0 + && _data[channel->offset + 1] == SCI_MIDI_EOT) /* Fake one extra tick to trick the interpreter into not killing the song iterator right away */ channel->state = SI_STATE_PCM_MAGIC_DELTA; else @@ -374,7 +374,7 @@ static int _sci_midi_process_state(BaseSongIterator *self, byte *buf, int *resul int offset; uint size; int delay; - if (_sci0_get_pcm_data((Sci0SongIterator *) self, &format, &offset, &size)) + if (_sci0_get_pcm_data((Sci0SongIterator *)this, &format, &offset, &size)) return SI_FINISHED; /* 'tis broken */ channel->state = SI_STATE_FINISHED; delay = (size * 50 + format.rate - 1) / format.rate; /* number of ticks to completion*/ @@ -385,17 +385,17 @@ static int _sci_midi_process_state(BaseSongIterator *self, byte *buf, int *resul case SI_STATE_UNINITIALISED: warning("Attempt to read command from uninitialized iterator"); - self->init(); - return self->nextCommand(buf, result); + init(); + return nextCommand(buf, result); case SI_STATE_FINISHED: return SI_FINISHED; case SI_STATE_DELTA_TIME: { int offset; - int ticks = _parse_ticks(self->_data.begin() + channel->offset, + int ticks = _parse_ticks(_data.begin() + channel->offset, &offset, - self->_data.size() - channel->offset); + _data.size() - channel->offset); channel->offset += offset; channel->delay += ticks; @@ -416,47 +416,36 @@ static int _sci_midi_process_state(BaseSongIterator *self, byte *buf, int *resul channel->total_timepos += channel->timepos_increment; channel->timepos_increment = 0; - retval = _parse_sci_midi_command(self, buf, result, - channel, flags); + retval = parseMidiCommand(buf, result, channel, flags); if (retval == SI_FINISHED) { - if (self->active_channels) - --(self->active_channels); + if (_numActiveChannels) + --(_numActiveChannels); #ifdef DEBUG_DECODING fprintf(stderr, "%s L%d: (%p):%d Finished channel, %d channels left\n", - __FILE__, __LINE__, self, channel->id, - self->active_channels); + __FILE__, __LINE__, this, channel->id, + _numActiveChannels); #endif /* If we still have channels left... */ - if (self->active_channels) { - return self->nextCommand(buf, result); + if (_numActiveChannels) { + return nextCommand(buf, result); } /* Otherwise, we have reached the end */ - self->loops = 0; + _loops = 0; } return retval; } default: - warning("Invalid iterator state %d", channel->state); - error("Breakpoint in %s, line %d", __FILE__, __LINE__); + error("Invalid iterator state %d", channel->state); return SI_FINISHED; } } -static int _sci_midi_process(BaseSongIterator *self, byte *buf, int *result, - SongIteratorChannel *channel, int flags) { - return _sci_midi_process_state(self, buf, result, - channel, - flags); -} - int Sci0SongIterator::nextCommand(byte *buf, int *result) { - return _sci_midi_process(this, buf, result, - &channel, - PARSE_FLAG_PARAMETRIC_CUE); + return processMidi(buf, result, &_channel, PARSE_FLAG_PARAMETRIC_CUE); } static int _sci0_header_magic_p(byte *data, int offset, int size) { @@ -563,7 +552,7 @@ Audio::AudioStream *Sci0SongIterator::getAudioStream() { if (_sci0_get_pcm_data(this, &conf, &offset, &size)) return NULL; - channel.state = SI_STATE_FINISHED; /* Don't play both PCM and music */ + _channel.state = SI_STATE_FINISHED; /* Don't play both PCM and music */ return makeStream(_data.begin() + offset + SCI0_PCM_DATA_OFFSET, size, conf); } @@ -575,18 +564,18 @@ SongIterator *Sci0SongIterator::handleMessage(Message msg) { case _SIMSG_BASEMSG_PRINT: print_tabs_id(msg._arg.i, ID); fprintf(stderr, "SCI0: dev=%d, active-chan=%d, size=%d, loops=%d\n", - _deviceId, active_channels, _data.size(), loops); + _deviceId, _numActiveChannels, _data.size(), _loops); break; case _SIMSG_BASEMSG_SET_LOOPS: - loops = msg._arg.i; + _loops = msg._arg.i; break; case _SIMSG_BASEMSG_STOP: { songit_id_t sought_id = msg.ID; if (sought_id == ID) - channel.state = SI_STATE_FINISHED; + _channel.state = SI_STATE_FINISHED; break; } @@ -595,19 +584,19 @@ SongIterator *Sci0SongIterator::handleMessage(Message msg) { _deviceId = msg._arg.i; /* Set all but the rhytm channel mask bits */ - channel.playmask &= ~(1 << MIDI_RHYTHM_CHANNEL); + _channel.playmask &= ~(1 << MIDI_RHYTHM_CHANNEL); for (i = 0; i < MIDI_CHANNELS; i++) if (_data[2 + (i << 1)] & _deviceId && i != MIDI_RHYTHM_CHANNEL) - channel.playmask |= (1 << i); + _channel.playmask |= (1 << i); } break; case _SIMSG_BASEMSG_SET_RHYTHM: - channel.playmask &= ~(1 << MIDI_RHYTHM_CHANNEL); + _channel.playmask &= ~(1 << MIDI_RHYTHM_CHANNEL); if (msg._arg.i) - channel.playmask |= (1 << MIDI_RHYTHM_CHANNEL); + _channel.playmask |= (1 << MIDI_RHYTHM_CHANNEL); break; case _SIMSG_BASEMSG_SET_FADE: { @@ -629,33 +618,33 @@ SongIterator *Sci0SongIterator::handleMessage(Message msg) { } int Sci0SongIterator::getTimepos() { - return channel.total_timepos; + return _channel.total_timepos; } Sci0SongIterator::Sci0SongIterator(byte *data, uint size, songit_id_t id) : BaseSongIterator(data, size, id) { channel_mask = 0xffff; // Allocate all channels by default - channel.state = SI_STATE_UNINITIALISED; + _channel.state = SI_STATE_UNINITIALISED; for (int i = 0; i < MIDI_CHANNELS; i++) - polyphony[i] = data[1 + (i << 1)]; + _polyphony[i] = data[1 + (i << 1)]; init(); } void Sci0SongIterator::init() { fade.action = FADE_ACTION_NONE; - resetflag = 0; - loops = 0; + _resetflag = 0; + _loops = 0; priority = 0; - ccc = 0; /* Reset cumulative cue counter */ - active_channels = 1; - channel.init(0, SCI0_MIDI_OFFSET, _data.size()); - channel.resetSynthChannels(); + _ccc = 0; /* Reset cumulative cue counter */ + _numActiveChannels = 1; + _channel.init(0, SCI0_MIDI_OFFSET, _data.size()); + _channel.resetSynthChannels(); if (_data[0] == 2) /* Do we have an embedded PCM? */ - channel.state = SI_STATE_PCM; + _channel.state = SI_STATE_PCM; } SongIterator *Sci0SongIterator::clone(int delta) { @@ -682,7 +671,7 @@ static const int sci0_to_sci1_device_map[][2] = { {0xff, 0xff}, }; /* Maps bit number to device ID */ -static int _sci1_sample_init(Sci1SongIterator *self, const int offset) { +int Sci1SongIterator::initSample(const int offset) { Sci1Sample sample; int rate; int length; @@ -690,24 +679,24 @@ static int _sci1_sample_init(Sci1SongIterator *self, const int offset) { int end; CHECK_FOR_END_ABSOLUTE((uint)offset + 10); - if (self->_data[offset + 1] != 0) + if (_data[offset + 1] != 0) sciprintf("[iterator-1] In sample at offset 0x04x: Byte #1 is %02x instead of zero\n", - self->_data[offset + 1]); + _data[offset + 1]); - rate = (int16)READ_LE_UINT16(self->_data.begin() + offset + 2); - length = READ_LE_UINT16(self->_data.begin() + offset + 4); - begin = (int16)READ_LE_UINT16(self->_data.begin() + offset + 6); - end = (int16)READ_LE_UINT16(self->_data.begin() + offset + 8); + rate = (int16)READ_LE_UINT16(_data.begin() + offset + 2); + length = READ_LE_UINT16(_data.begin() + offset + 4); + begin = (int16)READ_LE_UINT16(_data.begin() + offset + 6); + end = (int16)READ_LE_UINT16(_data.begin() + offset + 8); CHECK_FOR_END_ABSOLUTE((uint)(offset + 10 + length)); sample.delta = begin; sample.size = length; - sample._data = self->_data.begin() + offset + 10; + sample._data = _data.begin() + offset + 10; #ifdef DEBUG_VERBOSE fprintf(stderr, "[SAMPLE] %x/%x/%x/%x l=%x\n", - offset + 10, begin, end, self->_data.size(), length); + offset + 10, begin, end, _data.size(), length); #endif sample.format.format = SFX_PCM_FORMAT_U8; @@ -717,86 +706,85 @@ static int _sci1_sample_init(Sci1SongIterator *self, const int offset) { sample.announced = false; /* Insert into the sample list at the right spot, keeping it sorted by delta */ - Common::List<Sci1Sample>::iterator seeker = self->_samples.begin(); - while (seeker != self->_samples.end() && seeker->delta < begin) + Common::List<Sci1Sample>::iterator seeker = _samples.begin(); + while (seeker != _samples.end() && seeker->delta < begin) ++seeker; - self->_samples.insert(seeker, sample); + _samples.insert(seeker, sample); return 0; /* Everything's fine */ } -static int _sci1_song_init(Sci1SongIterator *self) { +int Sci1SongIterator::initSong() { int last_time; uint offset = 0; - self->_numChannels = 0; - self->_samples.clear(); -// self->_deviceId = 0x0c; + _numChannels = 0; + _samples.clear(); +// _deviceId = 0x0c; - if (self->_data[offset] == 0xf0) { - self->priority = self->_data[offset + 1]; + if (_data[offset] == 0xf0) { + priority = _data[offset + 1]; offset += 8; } - while (self->_data[offset] != 0xff - && self->_data[offset] != self->_deviceId) { + while (_data[offset] != 0xff + && _data[offset] != _deviceId) { offset++; CHECK_FOR_END_ABSOLUTE(offset + 1); - while (self->_data[offset] != 0xff) { + while (_data[offset] != 0xff) { CHECK_FOR_END_ABSOLUTE(offset + 7); offset += 6; } offset++; } - if (self->_data[offset] == 0xff) { + if (_data[offset] == 0xff) { sciprintf("[iterator-1] Song does not support" " hardware 0x%02x\n", - self->_deviceId); + _deviceId); return 1; } offset++; - while (self->_data[offset] != 0xff) { /* End of list? */ + while (_data[offset] != 0xff) { /* End of list? */ uint track_offset; int end; offset += 2; CHECK_FOR_END_ABSOLUTE(offset + 4); - track_offset = READ_LE_UINT16(self->_data.begin() + offset); - end = READ_LE_UINT16(self->_data.begin() + offset + 2); + track_offset = READ_LE_UINT16(_data.begin() + offset); + end = READ_LE_UINT16(_data.begin() + offset + 2); CHECK_FOR_END_ABSOLUTE(track_offset - 1); - if (self->_data[track_offset] == 0xfe) { - if (_sci1_sample_init(self, track_offset)) + if (_data[track_offset] == 0xfe) { + if (initSample(track_offset)) return 1; /* Error */ } else { /* Regular MIDI channel */ - if (self->_numChannels >= MIDI_CHANNELS) { + if (_numChannels >= MIDI_CHANNELS) { sciprintf("[iterator-1] Warning: Song has more than %d channels, cutting them off\n", MIDI_CHANNELS); break; /* Scan for remaining samples */ } else { - int channel_nr = self->_data[track_offset] & 0xf; - SongIteratorChannel &channel = - self->_channels[self->_numChannels++]; + int channel_nr = _data[track_offset] & 0xf; + SongIteratorChannel &channel = _channels[_numChannels++]; - if (self->_data[track_offset] & 0xf0) + if (_data[track_offset] & 0xf0) printf("Channel %d has mapping bits %02x\n", - channel_nr, self->_data[track_offset] & 0xf0); + channel_nr, _data[track_offset] & 0xf0); // Add 2 to skip over header bytes */ channel.init(channel_nr, track_offset + 2, track_offset + end); channel.resetSynthChannels(); - self->polyphony[self->_numChannels - 1] = self->_data[channel.offset - 1] & 15; - self->importance[self->_numChannels - 1] = self->_data[channel.offset - 1] >> 4; + _polyphony[_numChannels - 1] = _data[channel.offset - 1] & 15; + _importance[_numChannels - 1] = _data[channel.offset - 1] >> 4; channel.playmask = ~0; /* Enable all */ - self->channel_mask |= (1 << channel_nr); + channel_mask |= (1 << channel_nr); CHECK_FOR_END_ABSOLUTE(offset + end); } @@ -805,13 +793,13 @@ static int _sci1_song_init(Sci1SongIterator *self) { CHECK_FOR_END_ABSOLUTE(offset); } - /* Now ensure that samüle deltas are relative to the previous sample */ + /* Now ensure that sample deltas are relative to the previous sample */ last_time = 0; - self->active_channels = self->_numChannels; - self->_numLoopedChannels = 0; + _numActiveChannels = _numChannels; + _numLoopedChannels = 0; - for (Common::List<Sci1Sample>::iterator seeker = self->_samples.begin(); - seeker != self->_samples.end(); ++seeker) { + for (Common::List<Sci1Sample>::iterator seeker = _samples.begin(); + seeker != _samples.end(); ++seeker) { int prev_last_time = last_time; sciprintf("[iterator-1] Detected sample: %d Hz, %d bytes at time %d\n", seeker->format.rate, seeker->size, seeker->delta); @@ -899,7 +887,7 @@ int Sci1SongIterator::nextCommand(byte *buf, int *result) { sciprintf("[iterator-1] DEBUG: Initialising for %d\n", _deviceId); _initialised = true; - if (_sci1_song_init(this)) + if (initSong()) return SI_FINISHED; } @@ -937,17 +925,16 @@ int Sci1SongIterator::nextCommand(byte *buf, int *result) { } } else { /* Not a PCM */ - retval = _sci_midi_process(this, - buf, result, - &(_channels[chan]), - PARSE_FLAG_LOOPS_UNLIMITED); + retval = processMidi(buf, result, + &(_channels[chan]), + PARSE_FLAG_LOOPS_UNLIMITED); if (retval == SI_LOOP) { _numLoopedChannels++; _channels[chan].state = SI_STATE_PENDING; _channels[chan].delay = 0; - if (_numLoopedChannels == active_channels) { + if (_numLoopedChannels == _numActiveChannels) { int i; /* Everyone's ready: Let's loop */ @@ -1041,7 +1028,7 @@ SongIterator *Sci1SongIterator::handleMessage(Message msg) { /* Find an active channel so that we can ** get the correct time offset */ - _sci1_song_init(this); + initSong(); toffset -= _delayRemaining; _delayRemaining = 0; @@ -1049,7 +1036,7 @@ SongIterator *Sci1SongIterator::handleMessage(Message msg) { if (toffset > 0) return new_fast_forward_iterator(this, toffset); } else { - _sci1_song_init(this); + initSong(); _initialised = true; } @@ -1059,7 +1046,7 @@ SongIterator *Sci1SongIterator::handleMessage(Message msg) { case _SIMSG_BASEMSG_SET_LOOPS: if (msg.ID == ID) - loops = (msg._arg.i > 32767) ? 99 : 0; + _loops = (msg._arg.i > 32767) ? 99 : 0; /* 99 is arbitrary, but we can't use '1' because of ** the way we're testing in the decoding section. */ break; @@ -1093,26 +1080,26 @@ Sci1SongIterator::Sci1SongIterator(byte *data, uint size, songit_id_t id) channel_mask = 0; // Defer channel allocation for (int i = 0; i < MIDI_CHANNELS; i++) - polyphony[i] = 0; // Unknown + _polyphony[i] = 0; // Unknown init(); } void Sci1SongIterator::init() { fade.action = FADE_ACTION_NONE; - resetflag = 0; - loops = 0; + _resetflag = 0; + _loops = 0; priority = 0; - ccc = 127; + _ccc = 127; _deviceId = 0x00; // Default to Sound Blaster/Adlib for purposes of cue computation _numChannels = 0; _initialised = false; _delayRemaining = 0; - loops = 0; + _loops = 0; _hold = 0; - memset(polyphony, 0, sizeof(polyphony)); - memset(importance, 0, sizeof(importance)); + memset(_polyphony, 0, sizeof(_polyphony)); + memset(_importance, 0, sizeof(_importance)); } Sci1SongIterator::~Sci1SongIterator() { diff --git a/engines/sci/sfx/iterator.h b/engines/sci/sfx/iterator.h index 1a25b4afa1..547c479bbf 100644 --- a/engines/sci/sfx/iterator.h +++ b/engines/sci/sfx/iterator.h @@ -253,7 +253,6 @@ enum SongIteratorType { | IT_READER_MASK_CUE \ | IT_READER_MASK_PCM ) -int songit_next(SongIterator **it, byte *buf, int *result, int mask); /* Convenience wrapper around it->next ** Parameters: (SongIterator **it) Reference to the iterator to access ** (byte *) buf: The buffer to write to (needs to be able to @@ -270,8 +269,8 @@ int songit_next(SongIterator **it, byte *buf, int *result, int mask); ** to the lower layers) for 0, the cue value for SI_CUE, ** or the number of loops remaining for SI_LOOP. */ +int songit_next(SongIterator **it, byte *buf, int *result, int mask); -SongIterator *songit_new(byte *data, uint size, SongIteratorType type, songit_id_t id); /* Constructs a new song iterator object ** Parameters: (byte *) data: The song data to iterate over ** (uint) size: Number of bytes in the song @@ -280,26 +279,17 @@ SongIterator *songit_new(byte *data, uint size, SongIteratorType type, songit_id ** Returns : (SongIterator *) A newly allocated but uninitialized song ** iterator, or NULL if 'type' was invalid or unsupported */ +SongIterator *songit_new(byte *data, uint size, SongIteratorType type, songit_id_t id); -int songit_handle_message(SongIterator **it_reg, SongIterator::Message msg); /* Handles a message to the song iterator ** Parameters: (SongIterator **): A reference to the variable storing the song iterator ** Returns : (int) Non-zero if the message was understood ** The song iterator may polymorph as result of msg, so a writeable reference is required. */ +int songit_handle_message(SongIterator **it_reg, SongIterator::Message msg); -int sfx_play_iterator_pcm(SongIterator *it, unsigned long handle); -/* Plays a song iterator that found a PCM through a PCM device, if possible -** Parameters: (SongIterator *) it: The iterator to play -** (song_handle_t) handle: Debug handle -** Returns : (int) 0 if the effect will not be played, nonzero if it will -** This assumes that the last call to 'it->next()' returned SI_PCM. -*/ - - -SongIterator *new_fast_forward_iterator(SongIterator *it, int delta); /* Creates a new song iterator which fast-forwards ** Parameters: (SongIterator *) it: The iterator to wrap ** (int) delta: The number of ticks to skip @@ -307,6 +297,7 @@ SongIterator *new_fast_forward_iterator(SongIterator *it, int delta); ** which skips all delta times ** until 'delta' has been used up */ +SongIterator *new_fast_forward_iterator(SongIterator *it, int delta); diff --git a/engines/sci/sfx/iterator_internal.h b/engines/sci/sfx/iterator_internal.h index 88103ad8c9..7d5a17fd25 100644 --- a/engines/sci/sfx/iterator_internal.h +++ b/engines/sci/sfx/iterator_internal.h @@ -49,7 +49,7 @@ enum { struct SongIteratorChannel { int state; //!< State of this song iterator channel - int offset; //!< Offset into the data chunk */ + int offset; //!< Offset into the data chunk */ int end; //!< Last allowed byte in track */ int id; //!< Some channel ID */ @@ -64,14 +64,14 @@ struct SongIteratorChannel { int loop_offset; int initial_offset; - int playmask; //!< Active playmask (MIDI channels to play in here) */ - int notes_played; //!< #of notes played since the last loop start */ - int loop_timepos; //!< Total delay for this channel's loop marker */ - int total_timepos; //!< Number of ticks since the beginning, ignoring loops */ - int timepos_increment; //!< Number of ticks until the next command (to add) */ + int playmask; //!< Active playmask (MIDI channels to play in here) */ + int notes_played; //!< #of notes played since the last loop start */ + int loop_timepos; //!< Total delay for this channel's loop marker */ + int total_timepos; //!< Number of ticks since the beginning, ignoring loops */ + int timepos_increment; //!< Number of ticks until the next command (to add) */ - int saw_notes; //!< Bitmask of channels we have currently played notes on */ - byte last_cmd; //!< Last operation executed, for running status */ + int saw_notes; //!< Bitmask of channels we have currently played notes on */ + byte last_cmd; //!< Last operation executed, for running status */ public: void init(int id, int offset, int end); @@ -80,21 +80,24 @@ public: class BaseSongIterator : public SongIterator { public: - int polyphony[MIDI_CHANNELS]; //!< # of simultaneous notes on each - int importance[MIDI_CHANNELS]; //!< priority rating for each channel, 0 means unrated. + int _polyphony[MIDI_CHANNELS]; //!< # of simultaneous notes on each + int _importance[MIDI_CHANNELS]; //!< priority rating for each channel, 0 means unrated. - int ccc; //!< Cumulative cue counter, for those who need it - byte resetflag; //!< for 0x4C -- on DoSound StopSound, do we return to start? - int _deviceId; //!< ID of the device we generating events for - int active_channels; //!< Number of active channels + int _ccc; //!< Cumulative cue counter, for those who need it + byte _resetflag; //!< for 0x4C -- on DoSound StopSound, do we return to start? + int _deviceId; //!< ID of the device we generating events for + int _numActiveChannels; //!< Number of active channels Common::Array<byte> _data; //!< Song data - int loops; //!< Number of loops remaining - int recover_delay; + int _loops; //!< Number of loops remaining public: BaseSongIterator(byte *data, uint size, songit_id_t id); + +protected: + int parseMidiCommand(byte *buf, int *result, SongIteratorChannel *channel, int flags); + int processMidi(byte *buf, int *result, SongIteratorChannel *channel, int flags); }; /********************************/ @@ -103,7 +106,7 @@ public: class Sci0SongIterator : public BaseSongIterator { public: - SongIteratorChannel channel; + SongIteratorChannel _channel; public: Sci0SongIterator(byte *data, uint size, songit_id_t id); @@ -142,12 +145,12 @@ public: /* Invariant: Whenever channels[i].delay == CHANNEL_DELAY_MISSING, ** channel_offset[i] points to a delta time object. */ - bool _initialised; /* Whether the MIDI channel setup has been initialised */ - int _numChannels; /* Number of channels actually used */ + bool _initialised; /**!< Whether the MIDI channel setup has been initialised */ + int _numChannels; /**!< Number of channels actually used */ Common::List<Sci1Sample> _samples; - int _numLoopedChannels; /* Number of channels that are ready to loop */ + int _numLoopedChannels; /**!< Number of channels that are ready to loop */ - int _delayRemaining; /* Number of ticks that haven't been polled yet */ + int _delayRemaining; /**!< Number of ticks that haven't been polled yet */ int _hold; public: @@ -162,6 +165,9 @@ public: SongIterator *clone(int delta); private: + int initSample(const int offset); + int initSong(); + int getSmallestDelta() const; void updateDelta(int delta); @@ -186,7 +192,7 @@ private: class FastForwardSongIterator : public SongIterator { protected: SongIterator *_delegate; - int _delta; /**< Remaining time */ + int _delta; /**!< Remaining time */ public: FastForwardSongIterator(SongIterator *capsit, int delta); @@ -208,8 +214,8 @@ enum { TEE_RIGHT = 1, TEE_LEFT_ACTIVE = (1<<0), TEE_RIGHT_ACTIVE = (1<<1), - TEE_LEFT_READY = (1<<2), /**< left result is ready */ - TEE_RIGHT_READY = (1<<3), /**< right result is ready */ + TEE_LEFT_READY = (1<<2), /**!< left result is ready */ + TEE_RIGHT_READY = (1<<3), /**!< right result is ready */ TEE_LEFT_PCM = (1<<4), TEE_RIGHT_PCM = (1<<5) }; @@ -221,7 +227,7 @@ class TeeSongIterator : public SongIterator { public: int _status; - bool _readyToMorph; /* One of TEE_MORPH_* above */ + bool _readyToMorph; /**!< One of TEE_MORPH_* above */ struct { SongIterator *it; @@ -229,8 +235,8 @@ public: int result; int retval; - byte channel_remap[MIDI_CHANNELS]; /* Remapping for channels */ + byte channel_remap[MIDI_CHANNELS]; } _children[2]; diff --git a/engines/sci/sfx/softseq/adlib.cpp b/engines/sci/sfx/softseq/adlib.cpp index d5debdd995..41c7c63fc9 100644 --- a/engines/sci/sfx/softseq/adlib.cpp +++ b/engines/sci/sfx/softseq/adlib.cpp @@ -482,7 +482,7 @@ void MidiDriver_Adlib::setNote(int voice, int note, bool key) { if (bend < 8192) bend = 8192 - bend; - delta = pow(2.0, (float)(bend % 8192) / 8192.0); + delta = (float)pow(2.0, (bend % 8192) / 8192.0); if (bend > 8192) fre = (int)(ym3812_note[n] * delta); @@ -627,7 +627,7 @@ int MidiPlayer_Adlib::open(ResourceManager *resmgr) { assert(resmgr != NULL); // Load up the patch.003 file, parse out the instruments - Resource *res = resmgr->findResource(kResourceTypePatch, 3, 0); + Resource *res = resmgr->findResource(ResourceId(kResourceTypePatch, 3), 0); if (!res) { warning("ADLIB: Failed to load patch.003"); diff --git a/engines/sci/sfx/softseq/adlib.h b/engines/sci/sfx/softseq/adlib.h index 13cf1e2d95..38f755bec0 100644 --- a/engines/sci/sfx/softseq/adlib.h +++ b/engines/sci/sfx/softseq/adlib.h @@ -35,7 +35,7 @@ public: kRhythmKeys = 62 }; - MidiDriver_Adlib(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15), _rhythmKeyMap(0) { } + MidiDriver_Adlib(Audio::Mixer *mixer) : MidiDriver_Emulated(mixer), _playSwitch(true), _masterVolume(15), _rhythmKeyMap(0), _opl(0) { } ~MidiDriver_Adlib() { } // MidiDriver diff --git a/engines/sci/sfx/songlib.cpp b/engines/sci/sfx/songlib.cpp index e1185aa039..3a6549a0d4 100644 --- a/engines/sci/sfx/songlib.cpp +++ b/engines/sci/sfx/songlib.cpp @@ -31,169 +31,169 @@ namespace Sci { #define debug_stream stderr -song_t *song_new(song_handle_t handle, SongIterator *it, int priority) { - song_t *retval; - retval = (song_t*) malloc(sizeof(song_t)); - -#ifdef SATISFY_PURIFY - memset(retval, 0, sizeof(song_t)); -#endif - - retval->handle = handle; - retval->priority = priority; - retval->next = NULL; - retval->_delay = 0; - retval->_wakeupTime = Audio::Timestamp(); - retval->it = it; - retval->status = SOUND_STATUS_STOPPED; - retval->next_playing = NULL; - retval->next_stopping = NULL; - retval->restore_behavior = RESTORE_BEHAVIOR_CONTINUE; - retval->restore_time = 0; +Song::Song() { + _handle = 0; + _priority = 0; + _status = SOUND_STATUS_STOPPED; - return retval; + _restoreBehavior = RESTORE_BEHAVIOR_CONTINUE; + _restoreTime = 0; + + _loops = 0; + _hold = 0; + + _it = 0; + _delay = 0; + + _next = NULL; + _nextPlaying = NULL; + _nextStopping = NULL; } -void song_lib_add(const songlib_t &songlib, song_t *song) { - song_t **seeker = NULL; - int pri = song->priority; +Song::Song(SongHandle handle, SongIterator *it, int priority) { + _handle = handle; + _priority = priority; + _status = SOUND_STATUS_STOPPED; - if (NULL == song) { - sciprintf("song_lib_add(): NULL passed for song\n"); - return; - } + _restoreBehavior = RESTORE_BEHAVIOR_CONTINUE; + _restoreTime = 0; + + _loops = 0; + _hold = 0; - if (*(songlib.lib) == NULL) { - *(songlib.lib) = song; - song->next = NULL; + _it = it; + _delay = 0; + _next = NULL; + _nextPlaying = NULL; + _nextStopping = NULL; +} + +void SongLibrary::addSong(Song *song) { + Song **seeker = NULL; + int pri = song->_priority; + + if (NULL == song) { + sciprintf("addSong(): NULL passed for song\n"); return; } - seeker = (songlib.lib); - while (*seeker && ((*seeker)->priority > pri)) - seeker = &((*seeker)->next); + seeker = &_lib; + while (*seeker && ((*seeker)->_priority > pri)) + seeker = &((*seeker)->_next); - song->next = *seeker; + song->_next = *seeker; *seeker = song; } -static void _songfree_chain(song_t *song) { - /* Recursively free a chain of songs */ - if (song) { - _songfree_chain(song->next); - delete song->it; - song->it = NULL; - free(song); +void SongLibrary::freeSounds() { + Song *next = _lib; + while (next) { + Song *song = next; + delete song->_it; + song->_it = NULL; + next = song->_next; + delete song; } -} - -void song_lib_init(songlib_t *songlib) { - songlib->lib = &(songlib->_s); - songlib->_s = NULL; -} - -void song_lib_free(const songlib_t &songlib) { - _songfree_chain(*(songlib.lib)); - *(songlib.lib) = NULL; + _lib = NULL; } -song_t *song_lib_find(const songlib_t &songlib, song_handle_t handle) { - song_t *seeker = *(songlib.lib); +Song *SongLibrary::findSong(SongHandle handle) { + Song *seeker = _lib; while (seeker) { - if (seeker->handle == handle) + if (seeker->_handle == handle) break; - seeker = seeker->next; + seeker = seeker->_next; } return seeker; } -song_t *song_lib_find_next_active(const songlib_t &songlib, song_t *other) { - song_t *seeker = other ? other->next : *(songlib.lib); +Song *SongLibrary::findNextActive(Song *other) { + Song *seeker = other ? other->_next : _lib; while (seeker) { - if ((seeker->status == SOUND_STATUS_WAITING) || - (seeker->status == SOUND_STATUS_PLAYING)) + if ((seeker->_status == SOUND_STATUS_WAITING) || + (seeker->_status == SOUND_STATUS_PLAYING)) break; - seeker = seeker->next; + seeker = seeker->_next; } /* Only return songs that have equal priority */ - if (other && seeker && other->priority > seeker->priority) + if (other && seeker && other->_priority > seeker->_priority) return NULL; return seeker; } -song_t *song_lib_find_active(const songlib_t &songlib) { - return song_lib_find_next_active(songlib, NULL); +Song *SongLibrary::findFirstActive() { + return findNextActive(NULL); } -int song_lib_remove(const songlib_t &songlib, song_handle_t handle) { +int SongLibrary::removeSong(SongHandle handle) { int retval; - song_t *goner = *(songlib.lib); + Song *goner = _lib; if (!goner) return -1; - if (goner->handle == handle) - *(songlib.lib) = goner->next; + if (goner->_handle == handle) + _lib = goner->_next; else { - while ((goner->next) && (goner->next->handle != handle)) - goner = goner->next; + while ((goner->_next) && (goner->_next->_handle != handle)) + goner = goner->_next; - if (goner->next) { /* Found him? */ - song_t *oldnext = goner->next; + if (goner->_next) { /* Found him? */ + Song *oldnext = goner->_next; - goner->next = goner->next->next; + goner->_next = goner->_next->_next; goner = oldnext; } else return -1; /* No. */ } - retval = goner->status; + retval = goner->_status; - delete goner->it; - free(goner); + delete goner->_it; + delete goner; return retval; } -void song_lib_resort(const songlib_t &songlib, song_t *song) { - if (*(songlib.lib) == song) - *(songlib.lib) = song->next; +void SongLibrary::resortSong(Song *song) { + if (_lib == song) + _lib = song->_next; else { - song_t *seeker = *(songlib.lib); + Song *seeker = _lib; - while (seeker->next && (seeker->next != song)) - seeker = seeker->next; + while (seeker->_next && (seeker->_next != song)) + seeker = seeker->_next; - if (seeker->next) - seeker->next = seeker->next->next; + if (seeker->_next) + seeker->_next = seeker->_next->_next; } - song_lib_add(songlib, song); + addSong(song); } -int song_lib_count(const songlib_t &songlib) { - song_t *seeker = *(songlib.lib); +int SongLibrary::countSongs() { + Song *seeker = _lib; int retval = 0; while (seeker) { retval++; - seeker = seeker->next; + seeker = seeker->_next; } return retval; } -void song_lib_set_restore_behavior(const songlib_t &songlib, song_handle_t handle, RESTORE_BEHAVIOR action) { - song_t *seeker = song_lib_find(songlib, handle); +void SongLibrary::setSongRestoreBehavior(SongHandle handle, RESTORE_BEHAVIOR action) { + Song *seeker = findSong(handle); - seeker->restore_behavior = action; + seeker->_restoreBehavior = action; } } // End of namespace Sci diff --git a/engines/sci/sfx/songlib.h b/engines/sci/sfx/songlib.h index b9849fbfe3..53b32e6747 100644 --- a/engines/sci/sfx/songlib.h +++ b/engines/sci/sfx/songlib.h @@ -42,7 +42,7 @@ class SongIterator; #define SOUND_STATUS_WAITING 3 /* "waiting" means "tagged for playing, but not active right now" */ -typedef unsigned long song_handle_t; +typedef unsigned long SongHandle; enum RESTORE_BEHAVIOR { RESTORE_BEHAVIOR_CONTINUE, /* restart a song when restored from @@ -50,123 +50,122 @@ enum RESTORE_BEHAVIOR { RESTORE_BEHAVIOR_RESTART /* continue it from where it was */ }; -struct song_t { - song_handle_t handle; - int resource_num; /* Resource number */ - int priority; /* Song priority (more important if priority is higher) */ - int status; /* See above */ +class Song { +public: + SongHandle _handle; + int _resourceNum; /**<! Resource number */ + int _priority; /**!< Song priority (more important if priority is higher) */ + int _status; /* See above */ - int restore_behavior; - int restore_time; + int _restoreBehavior; + int _restoreTime; /* Grabbed from the sound iterator, for save/restore purposes */ - int loops; - int hold; + int _loops; + int _hold; - SongIterator *it; - int _delay; /* Delay before accessing the iterator, in ticks */ + SongIterator *_it; + int _delay; /**!< Delay before accessing the iterator, in ticks */ - Audio::Timestamp _wakeupTime; /**< Timestamp indicating the next MIDI event */ + Audio::Timestamp _wakeupTime; /**!< Timestamp indicating the next MIDI event */ - song_t *next; /* Next song or NULL if this is the last one */ - song_t *next_playing; /* Next playing song; used by the - ** core song system */ - song_t *next_stopping; /* Next song pending stopping; used exclusively by - ** the core song system's _update_multi_song() */ -}; + Song *_next; /**!< Next song or NULL if this is the last one */ + + /** + * Next playing song. Used by the core song system. + */ + Song *_nextPlaying; + + /** + * Next song pending stopping. Used exclusively by the core song system's + * _update_multi_song() + */ + Song *_nextStopping; +public: -struct songlib_t { - song_t **lib; - song_t *_s; + Song(); + + /** + * Initializes a new song. + * @param handle the sound handle + * @param it the song + * @param priority the song's priority + * @return a freshly allocated song + */ + Song(SongHandle handle, SongIterator *it, int priority); }; -/**************************/ -/* Song library commands: */ -/**************************/ - -song_t *song_new(song_handle_t handle, SongIterator *it, int priority); -/* Initializes a new song -** Parameters: (song_handle_t) handle: The sound handle -** (SongIterator *) it: The song -** (int) priority: The song's priority -** Returns : (song_t *) A freshly allocated song -** Other values are set to predefined defaults. -*/ - - -void song_lib_init(songlib_t *songlib); -/* Initializes a static song library -** Parameters: (songlib_t *) songlib: Pointer to the library -** to initialize -** Returns : (void) -*/ - -void song_lib_free(const songlib_t &songlib); -/* Frees a song library -** Parameters: (songlib_t) songlib: The library to free -** Returns : (void) -*/ - -void song_lib_add(const songlib_t &songlib, song_t *song); -/* Adds a song to a song library. -** Parameters: (songlib_t) songlib: An existing sound library, or NULL -** (song_t *) song: The song to add -** Returns : (void) -*/ - -song_t *song_lib_find(const songlib_t &songlib, song_handle_t handle); -/* Looks up the song with the specified handle -** Parameters: (songlib_t) songlib: An existing sound library, may point to NULL -** (song_handle_t) handle: The sound handle to look for -** Returns : (song_t *) The song or NULL if it wasn't found -*/ - -song_t *song_lib_find_active(const songlib_t &songlib); -/* Finds the first song playing with the highest priority -** Parameters: (songlib_t) songlib: An existing sound library -** Returns : (song_t *) The song that should be played next, or NULL if there is none -*/ - -song_t *song_lib_find_next_active(const songlib_t &songlib, song_t *song); -/* Finds the next song playing with the highest priority -** Parameters: (songlib_t) songlib: The song library to operate on -** (song_t *) song: A song previously returned from the song library -** Returns : (song_t *) The next song to play relative to 'song', or -** NULL if none are left -** The functions 'song_lib_find_active' and 'song_lib_find_next_active -** allow to iterate over all songs that satisfy the requirement of -** being 'playable'. -*/ - -int song_lib_remove(const songlib_t &songlib, song_handle_t handle); -/* Removes a song from the library -** Parameters: (songlib_t) songlib: An existing sound library -** (song_handle_t) handle: Handle of the song to remove -** Returns : (int) The status of the song that was removed -*/ - -void song_lib_resort(const songlib_t &songlib, song_t *song); -/* Removes a song from the library and sorts it in again; for use after renicing -** Parameters: (songlib_t) songlib: An existing sound library -** (song_t *) song: The song to work on -** Returns : (void) -*/ - -int song_lib_count(const songlib_t &songlib); -/* Counts the number of songs in a song library -** Parameters: (songlib_t) songlib: The library to count -** Returns : (int) The number of songs -*/ - -void song_lib_set_restore_behavior(const songlib_t &songlib, song_handle_t handle, - RESTORE_BEHAVIOR action); -/* Determines what should be done with the song "handle" when -** restoring it from a saved game. -** Parameters: (songlib_t) songlib: The library that contains the song -** (song_handle_t) handle: Its handle -** (RESTORE_BEHAVIOR) action: The desired action -*/ + +class SongLibrary { +public: + Song *_lib; + +public: + SongLibrary() : _lib(0) {} + + /** Frees a song library. */ + void freeSounds(); + + /** + * Adds a song to a song library. + * @param song song to add + */ + void addSong(Song *song); + + /** + * Looks up the song with the specified handle. + * @param handle sound handle to look for + * @return the song or NULL if it wasn't found + */ + Song *findSong(SongHandle handle); + + /** + * Finds the first song playing with the highest priority. + * @return the song that should be played next, or NULL if there is none + */ + Song *findFirstActive(); + + /** + * Finds the next song playing with the highest priority. + * + * The functions 'findFirstActive' and 'findNextActive' + * allow to iterate over all songs that satisfy the requirement of + * being 'playable'. + * + * @param song a song previously returned from the song library + * @return the next song to play relative to 'song', or NULL if none are left + */ + Song *findNextActive(Song *song); + + /** + * Removes a song from the library. + * @param handle handle of the song to remove + * @return the status of the song that was removed + */ + int removeSong(SongHandle handle); + + /** + * Removes a song from the library and sorts it in again; for use after renicing. + * @param son song to work on + */ + void resortSong(Song *song); + + /** + * Counts the number of songs in a song library. + * @return the number of songs + */ + int countSongs(); + + /** + * Determines what should be done with the song "handle" when restoring + * it from a saved game. + * @param handle sound handle being restored + * @param action desired action + */ + void setSongRestoreBehavior(SongHandle handle, + RESTORE_BEHAVIOR action); +}; } // End of namespace Sci diff --git a/engines/sci/tools.cpp b/engines/sci/tools.cpp index 589ce298d7..d0e11aca09 100644 --- a/engines/sci/tools.cpp +++ b/engines/sci/tools.cpp @@ -70,7 +70,7 @@ void sciprintf(const char *fmt, ...) { // Display the result suitably if (g_redirect_sciprintf_to_gui) - ((SciEngine *)g_engine)->getDebugger()->DebugPrintf("%s", buf); + ((SciEngine *)g_engine)->getSciDebugger()->DebugPrintf("%s", buf); printf("%s", buf); free(buf); diff --git a/engines/sci/vocabulary.cpp b/engines/sci/vocabulary.cpp index b12114d845..6616ac362d 100644 --- a/engines/sci/vocabulary.cpp +++ b/engines/sci/vocabulary.cpp @@ -62,7 +62,7 @@ int *vocab_get_classes(ResourceManager *resmgr, int* count) { int *c; unsigned int i; - if ((r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES, 0)) == NULL) + if ((r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES), 0)) == NULL) return 0; c = (int *)malloc(sizeof(int) * r->size / 2); @@ -77,7 +77,7 @@ int *vocab_get_classes(ResourceManager *resmgr, int* count) { int vocab_get_class_count(ResourceManager *resmgr) { Resource* r; - if ((r = resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES, 0)) == 0) + if ((r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_CLASSES), 0)) == 0) return 0; return r->size / 4; @@ -115,11 +115,11 @@ bool Vocabulary::loadParserWords() { int currentwordpos = 0; // First try to load the SCI0 vocab resource. - Resource *resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB, 0); + Resource *resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_MAIN_VOCAB), 0); if (!resource) { warning("SCI0: Could not find a main vocabulary, trying SCI01"); - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_MAIN_VOCAB), 0); _vocabVersion = kVocabularySCI1; } @@ -198,9 +198,9 @@ bool Vocabulary::loadSuffixes() { Resource* resource = NULL; if (_vocabVersion == kVocabularySCI0) - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB, 1); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB), 1); else - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB, 1); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB), 1); if (!resource) return false; // No vocabulary found @@ -237,12 +237,12 @@ void Vocabulary::freeSuffixes() { Resource* resource = NULL; if (_vocabVersion == kVocabularySCI0) - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_SUFFIX_VOCAB), 0); else - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_SUFFIX_VOCAB), 0); if (resource) - _resmgr->unlockResource(resource, resource->number, kResourceTypeVocab); + _resmgr->unlockResource(resource); _parserSuffixes.clear(); } @@ -251,9 +251,9 @@ bool Vocabulary::loadBranches() { Resource *resource = NULL; if (_vocabVersion == kVocabularySCI0) - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI0_PARSE_TREE_BRANCHES), 0); else - resource = _resmgr->findResource(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES, 0); + resource = _resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_SCI1_PARSE_TREE_BRANCHES), 0); _parserBranches.clear(); @@ -438,7 +438,7 @@ bool Vocabulary::tokenizeString(ResultWordList &retval, const char *sentence, ch void Vocabulary::printSuffixes() const { char word_buf[256], alt_buf[256]; - GUI::Debugger *con = ((SciEngine *)g_engine)->getDebugger(); + Console *con = ((SciEngine *)g_engine)->getSciDebugger(); int i = 0; for (SuffixList::const_iterator suf = _parserSuffixes.begin(); suf != _parserSuffixes.end(); ++suf) { @@ -453,7 +453,7 @@ void Vocabulary::printSuffixes() const { } void Vocabulary::printParserWords() const { - GUI::Debugger *con = ((SciEngine *)g_engine)->getDebugger(); + Console *con = ((SciEngine *)g_engine)->getSciDebugger(); int j = 0; for (WordMap::iterator i = _parserWords.begin(); i != _parserWords.end(); ++i) { @@ -488,7 +488,7 @@ void _vocab_recursive_ptree_dump_treelike(parse_tree_node_t *nodes, int nr, int return; } - if (nodes[nr].type == PARSE_TREE_NODE_LEAF) + if (nodes[nr].type == kParseTreeLeafNode) //sciprintf("[%03x]%04x", nr, nodes[nr].content.value); sciprintf("%x", nodes[nr].content.value); else { @@ -518,7 +518,7 @@ void _vocab_recursive_ptree_dump(parse_tree_node_t *nodes, int nr, int prevnr, i int rbranch = nodes[nr].content.branches[1]; int i; - if (nodes[nr].type == PARSE_TREE_NODE_LEAF) { + if (nodes[nr].type == kParseTreeLeafNode) { sciprintf("vocab_dump_parse_tree: Error: consp is nil for element %03x\n", nr); return; } @@ -529,7 +529,7 @@ void _vocab_recursive_ptree_dump(parse_tree_node_t *nodes, int nr, int prevnr, i } if (lbranch) { - if (nodes[lbranch].type == PARSE_TREE_NODE_BRANCH) { + if (nodes[lbranch].type == kParseTreeBranchNode) { sciprintf("\n"); for (i = 0; i < blanks; i++) sciprintf(" "); @@ -544,7 +544,7 @@ void _vocab_recursive_ptree_dump(parse_tree_node_t *nodes, int nr, int prevnr, i }/* else sciprintf ("nil");*/ if (rbranch) { - if (nodes[rbranch].type == PARSE_TREE_NODE_BRANCH) + if (nodes[rbranch].type == kParseTreeBranchNode) _vocab_recursive_ptree_dump(nodes, rbranch, nr, blanks); else sciprintf("%x", nodes[rbranch].content.value); diff --git a/engines/sci/vocabulary.h b/engines/sci/vocabulary.h index 9f0d277ef2..ce6d48c570 100644 --- a/engines/sci/vocabulary.h +++ b/engines/sci/vocabulary.h @@ -160,9 +160,10 @@ struct parse_tree_branch_t { int data[10]; }; -#define PARSE_TREE_NODE_LEAF 0 -#define PARSE_TREE_NODE_BRANCH 1 - +enum ParseTypes { + kParseTreeLeafNode = 0, + kParseTreeBranchNode = 1 +}; struct parse_tree_node_t { short type; /* leaf or branch */ |