aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorTravis Howell2009-08-05 02:26:51 +0000
committerTravis Howell2009-08-05 02:26:51 +0000
commitbaa31cd83dd021a8842e7778c0b0892768553ae0 (patch)
tree2bdb122d9d7f23998b4c3b93e042082887f7e591 /engines
parenta565441f0cce65b6a3bee713c1e88f2ad7c67c76 (diff)
parent4af0cfbdbdc9feafca2728cee8deca7ae9b472b1 (diff)
downloadscummvm-rg350-baa31cd83dd021a8842e7778c0b0892768553ae0.tar.gz
scummvm-rg350-baa31cd83dd021a8842e7778c0b0892768553ae0.tar.bz2
scummvm-rg350-baa31cd83dd021a8842e7778c0b0892768553ae0.zip
Merged revisions 42578,42587-42593,42596-42599,42606,42608-42611,42614-42615,42619,42623-42626,42632-42642,42645,42654-42656,42658-42664,42668,42671-42677,42679,42681,42685,42690,42693,42695-42697,42699,42701,42704-42729,42736-42740,42742-42744,42746-42748,42751-42753,42755,42757,42759,42761,42765-42768,42771,42773,42776,42780,42782-42783,42785,42787,42790-42793,42795,42798-42799,42801,42807,42809,42812-42826,42842-42845,42847,42849,42851,42856-42859,42861,42863,42866,42868,42870,42880-42881,42886-42887,42889-42890,42892,42894-42895,42898,42900,42904,42907,42910-42912,42918,42920,42922-42924,42926,42929,42932,42934-42935,42937-42941,42943,42946-42947,42950-42953,42955,42958-42959,42964-42965,42973-42974,42995-42996,42999,43001,43003,43005,43007-43008,43010-43011,43013,43020,43023,43025,43027,43029,43033,43035,43037,43039,43041-43043,43048,43056 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk ........ r42578 | dreammaster | 2009-07-18 11:22:43 +1000 (Sat, 18 Jul 2009) | 1 line Minor tweak to prevent mouse clicks that close a user wait message also being further interpreted as a user walk destination ........ r42587 | wjpalenstijn | 2009-07-18 22:51:12 +1000 (Sat, 18 Jul 2009) | 1 line SCI: Fix stepping in debugger ........ r42588 | drmccoy | 2009-07-18 23:05:36 +1000 (Sat, 18 Jul 2009) | 1 line Adding a workaround for the guard house card game "game over" screen in Woodruff ........ r42589 | wjpalenstijn | 2009-07-18 23:05:39 +1000 (Sat, 18 Jul 2009) | 1 line SCI: don't leave debugger after bt ........ r42590 | Kirben | 2009-07-18 23:39:21 +1000 (Sat, 18 Jul 2009) | 1 line Add workaround for bug #1668393 - ZAK FM-TOWNS: Crash when entering Hostel from outside. ........ r42591 | fingolfin | 2009-07-19 01:11:19 +1000 (Sun, 19 Jul 2009) | 1 line AGOS: Fixed backspace under OS X in Personal Nightmare ........ r42592 | fingolfin | 2009-07-19 01:12:54 +1000 (Sun, 19 Jul 2009) | 1 line AGOS: Get rid of one setjmp in PN code (needs testing) ........ r42593 | fingolfin | 2009-07-19 01:15:26 +1000 (Sun, 19 Jul 2009) | 1 line AGOS: Removed second setjmp in PN code (untested!) ........ r42596 | cyx | 2009-07-19 07:26:44 +1000 (Sun, 19 Jul 2009) | 2 lines add "-IQ" suffix test to SO_LOAD_STRING (same as SO_SAVE_STRING) ; fixes french version of atlantis ........ r42597 | wjpalenstijn | 2009-07-19 08:17:56 +1000 (Sun, 19 Jul 2009) | 1 line Fix crash in tab completion if one command is a prefix of another. ........ r42598 | wjpalenstijn | 2009-07-19 08:19:07 +1000 (Sun, 19 Jul 2009) | 1 line SCI: Fix disasm_addr option parsing ........ r42599 | wjpalenstijn | 2009-07-19 08:46:07 +1000 (Sun, 19 Jul 2009) | 1 line SCI: Fix breakpoints ........ r42606 | Kirben | 2009-07-19 19:09:56 +1000 (Sun, 19 Jul 2009) | 1 line Add patch #2823590 - Fix music crashes in Waxworks (PC). ........ r42608 | Kirben | 2009-07-19 19:13:17 +1000 (Sun, 19 Jul 2009) | 1 line Update Waxworks. ........ r42609 | wjpalenstijn | 2009-07-19 20:50:14 +1000 (Sun, 19 Jul 2009) | 1 line SCI: check shouldQuit() in main loop ........ r42610 | cyx | 2009-07-19 21:07:17 +1000 (Sun, 19 Jul 2009) | 2 lines fix bug #2597980 - TUCKER: Sprite glitch ........ r42611 | dreammaster | 2009-07-19 22:52:19 +1000 (Sun, 19 Jul 2009) | 1 line Added the GUIO_NOSFX and GUIO_NOMUSIC flags to the first Discworld 1 demo entry ........ r42614 | Kirben | 2009-07-20 00:03:35 +1000 (Mon, 20 Jul 2009) | 1 line Change generic save game name. ........ r42615 | knakos | 2009-07-20 00:46:11 +1000 (Mon, 20 Jul 2009) | 1 line remove dead code leftover ........ r42619 | knakos | 2009-07-20 02:10:55 +1000 (Mon, 20 Jul 2009) | 1 line whoops, fix non-arm build (why? :-) ) ........ r42623 | wjpalenstijn | 2009-07-20 07:06:25 +1000 (Mon, 20 Jul 2009) | 1 line Fix compilation with USE_CONSOLE = 0 ........ r42624 | fingolfin | 2009-07-20 15:02:17 +1000 (Mon, 20 Jul 2009) | 1 line AGOS: Fixed badload(); some whitespace cleanup ........ r42625 | sev | 2009-07-20 18:31:40 +1000 (Mon, 20 Jul 2009) | 3 lines Moved new ports section to more appropriate place. And force buildbot to recompile :) ........ r42626 | dreammaster | 2009-07-20 19:19:27 +1000 (Mon, 20 Jul 2009) | 1 line Bugfix for hangs on scene changes in Discworld 1 after having loaded a savegame from the GMM when the title screens are displayed ........ r42632 | wjpalenstijn | 2009-07-21 06:55:28 +1000 (Tue, 21 Jul 2009) | 4 lines Make ScummFile::eos() consistent with Stream::eos(). Remove usage of ioFailed from SCUMM engine. Fix reading up to the end of a SCUMM SubFile. This hopefully fixes #2820957. ........ r42633 | mthreepwood | 2009-07-21 06:59:35 +1000 (Tue, 21 Jul 2009) | 1 line Fixing bug #2823854: Mickey's space adventure crash. There's one too many space characters in a string which causes it to be drawn off the screen. ........ r42634 | sev | 2009-07-21 08:15:37 +1000 (Tue, 21 Jul 2009) | 2 lines Proper implementation of microscope puzzle. ........ r42635 | lordhoto | 2009-07-21 08:26:41 +1000 (Tue, 21 Jul 2009) | 2 lines Fix gcc warning (hopefully this is correct). ........ r42636 | Kirben | 2009-07-21 17:02:18 +1000 (Tue, 21 Jul 2009) | 1 line Update GUI flags for AGOS game engine. ........ r42637 | wjpalenstijn | 2009-07-21 19:39:58 +1000 (Tue, 21 Jul 2009) | 1 line Use a BufferedReadStream to buffer ArjFile's input to reduce memory usage ........ r42638 | Kirben | 2009-07-21 20:37:58 +1000 (Tue, 21 Jul 2009) | 1 line Fix fade effects in Waxworks. ........ r42639 | Kirben | 2009-07-21 20:48:32 +1000 (Tue, 21 Jul 2009) | 1 line Fix bug #2823818 - GUI: unable to select subtitles and speech for Simon 2. ........ r42640 | drmccoy | 2009-07-21 21:26:31 +1000 (Tue, 21 Jul 2009) | 1 line Making some static const uint32s public, older GCC versions don't seem to like nested classes to access their parents' protected members ........ r42641 | drmccoy | 2009-07-21 21:58:58 +1000 (Tue, 21 Jul 2009) | 1 line Fixing "Game "hangs" after first level" (bug #2824414) ........ r42642 | drmccoy | 2009-07-21 22:14:36 +1000 (Tue, 21 Jul 2009) | 1 line Fixing the text input in Gob1 (the loading code wasn't printed as you typed anymore) ........ r42645 | robinwatts | 2009-07-22 05:39:24 +1000 (Wed, 22 Jul 2009) | 4 lines Add ARM code implementation of Scaler2x, and enable it for the WinCE port. ........ r42654 | Kirben | 2009-07-22 19:52:44 +1000 (Wed, 22 Jul 2009) | 1 line Simplify fade code. ........ r42655 | Kirben | 2009-07-22 20:23:58 +1000 (Wed, 22 Jul 2009) | 1 line Change the default target to CD version, for games which offer floppy and CD versions. So all GUI options are still available in fan translations. ........ r42656 | Kirben | 2009-07-22 20:32:35 +1000 (Wed, 22 Jul 2009) | 1 line Update video script debug table for Waxworks. ........ r42658 | sev | 2009-07-22 21:48:51 +1000 (Wed, 22 Jul 2009) | 2 lines Fix bug #2823762: "AGI: PQ1 All function keys are broken after restart" ........ r42659 | sev | 2009-07-22 22:24:55 +1000 (Wed, 22 Jul 2009) | 2 lines Fix bug #2823759: "AGI: PQ1 help not showing the first time you press F1" ........ r42660 | sev | 2009-07-22 22:36:08 +1000 (Wed, 22 Jul 2009) | 2 lines Mention microscope puzzle improvement in T7G ........ r42661 | lordhoto | 2009-07-22 22:38:34 +1000 (Wed, 22 Jul 2009) | 1 line Since Kyra PC98 version is japanese only don't mention it explicitly. ........ r42662 | sev | 2009-07-23 01:55:33 +1000 (Thu, 23 Jul 2009) | 2 lines Move functions from agi.cpp to more appropriate files. ........ r42663 | sev | 2009-07-23 02:26:53 +1000 (Thu, 23 Jul 2009) | 2 lines Fix bug #2798797: "AGI: larry 1 doesn't restart after dying" ........ r42664 | sev | 2009-07-23 05:25:53 +1000 (Thu, 23 Jul 2009) | 7 lines Fix bug #1745396: "MI: Saved game from the credits sequence fails to load". Now we specifically disallow saves in room 0 for all v4+ games. Original has exactly this check in all versions, and such games are impossible to load. Still the problem is not resolved for v0-v3 and HE games. ........ r42668 | sev | 2009-07-23 06:37:48 +1000 (Thu, 23 Jul 2009) | 2 lines Fix bug #2825252: "GUI: Low Res Bugs" ........ r42671 | Kirben | 2009-07-23 15:48:20 +1000 (Thu, 23 Jul 2009) | 1 line Simplify the code to check whether loading or saving a game is possible. ........ r42672 | Kirben | 2009-07-23 15:57:00 +1000 (Thu, 23 Jul 2009) | 1 line Simplify the code to check whether loading or saving a game is possible. ........ r42673 | Kirben | 2009-07-23 17:49:28 +1000 (Thu, 23 Jul 2009) | 1 line Correct error in revision 26678. ........ r42674 | Kirben | 2009-07-23 20:31:06 +1000 (Thu, 23 Jul 2009) | 1 line Remove keyboard support for mouse buttons, since it interferes with load/save scripts in HE games and input scripts in others games (COMI, FT). It isn't much use anyway, since we dropped support for cursor movement via keyboard long ago. ........ r42675 | Kirben | 2009-07-23 20:33:13 +1000 (Thu, 23 Jul 2009) | 1 line Fix bug #1726909 - HE Games: Glitches after loading saved games, by restircting HE games to their original load/save interface. ........ r42676 | dreammaster | 2009-07-23 20:49:30 +1000 (Thu, 23 Jul 2009) | 1 line Bugfix for player blocking room entrance causing NPCs trying to enter getting an excessive number of action entries ........ r42677 | Kirben | 2009-07-23 20:54:12 +1000 (Thu, 23 Jul 2009) | 1 line Only autosave in supported scenes. ........ r42679 | drmccoy | 2009-07-24 05:50:13 +1000 (Fri, 24 Jul 2009) | 1 line Fixing a bug in the V4 save file handler, produced by a "neat" feature in Woodruff: The saves remember their position within the list and use that information to load the "correct" screen properties, making it impossible to load reordered saves correctly -.- ........ r42681 | Kirben | 2009-07-24 14:59:21 +1000 (Fri, 24 Jul 2009) | 1 line Bear Stormin' is the full mini game, and not a demo. ........ r42685 | Kirben | 2009-07-24 15:20:44 +1000 (Fri, 24 Jul 2009) | 1 line Fix cursor position, when entering a save game name in HE games. ........ r42690 | drmccoy | 2009-07-24 20:45:25 +1000 (Fri, 24 Jul 2009) | 1 line Adding transparency for VMD video block type 2, fixing bug #2037158 ("n-Game animation shifted(?)"). The problem was that the animation in question has an one pixel wide transparent bar on the left ........ r42693 | Kirben | 2009-07-24 22:28:53 +1000 (Fri, 24 Jul 2009) | 1 line Add workaround for bug #2826144 - SAM: Game hangs when talking to bigfoot guard. ........ r42695 | Kirben | 2009-07-24 23:30:26 +1000 (Fri, 24 Jul 2009) | 1 line Adjust workaround for bug #2826144, to use hard coded offset, that should be safe in all language versions. ........ r42696 | wjpalenstijn | 2009-07-25 04:58:15 +1000 (Sat, 25 Jul 2009) | 3 lines SAGA: Instead of trying to detect duplicate glyphs, simply generate duplicate outline glyphs. This should fix #2826697. ........ r42697 | eriktorbjorn | 2009-07-25 05:24:15 +1000 (Sat, 25 Jul 2009) | 2 lines Removed unused variable. ........ r42699 | sev | 2009-07-25 05:56:46 +1000 (Sat, 25 Jul 2009) | 2 lines This is 1.1.0svn ........ r42701 | sev | 2009-07-25 06:21:49 +1000 (Sat, 25 Jul 2009) | 2 lines re-enable SCI engine ........ r42704 | drmccoy | 2009-07-25 07:29:41 +1000 (Sat, 25 Jul 2009) | 1 line Adding support for ADPCM sound data (yet another IMA ADPCM variant). What we've called ADPCM before is more like DPCM ........ r42705 | drmccoy | 2009-07-25 07:31:00 +1000 (Sat, 25 Jul 2009) | 1 line Adding subtitle support to Woodruff ........ r42706 | drmccoy | 2009-07-25 07:31:58 +1000 (Sat, 25 Jul 2009) | 1 line Caching the subtitle font and color, because some don't assign those ........ r42707 | drmccoy | 2009-07-25 07:32:45 +1000 (Sat, 25 Jul 2009) | 1 line Calculating the number of data bytes per initial sound slice, because relying on the standard amount doesn't work for some videos ........ r42708 | drmccoy | 2009-07-25 07:33:22 +1000 (Sat, 25 Jul 2009) | 1 line Properly reading the video codec fourcc, in case we need other codecs in the future ........ r42709 | drmccoy | 2009-07-25 07:33:55 +1000 (Sat, 25 Jul 2009) | 1 line Adding ADL playback to the demoplayer ........ r42710 | drmccoy | 2009-07-25 07:34:17 +1000 (Sat, 25 Jul 2009) | 1 line Adding stubs for newer VMDs found in Addy 5 ........ r42711 | drmccoy | 2009-07-25 07:34:43 +1000 (Sat, 25 Jul 2009) | 1 line Added a method to easily dump resources to file ........ r42712 | drmccoy | 2009-07-25 07:35:06 +1000 (Sat, 25 Jul 2009) | 1 line Fixing bytes per pixel detection ........ r42713 | drmccoy | 2009-07-25 07:35:57 +1000 (Sat, 25 Jul 2009) | 1 line Renaming getAnchor() to getFrameCoords() ........ r42714 | drmccoy | 2009-07-25 07:36:16 +1000 (Sat, 25 Jul 2009) | 1 line Moving all implementations into the cpp ........ r42715 | drmccoy | 2009-07-25 07:36:42 +1000 (Sat, 25 Jul 2009) | 1 line CoktelVideo cleanup: Splitting up some IMD methods and removing the obsolete notifyPaused() ........ r42716 | drmccoy | 2009-07-25 07:36:59 +1000 (Sat, 25 Jul 2009) | 1 line Merging Map_v4 into Map_v2 ........ r42717 | lordhoto | 2009-07-25 10:58:44 +1000 (Sat, 25 Jul 2009) | 1 line Add new event dispatching API. ........ r42718 | lordhoto | 2009-07-25 10:59:03 +1000 (Sat, 25 Jul 2009) | 1 line Replace "EventProvider" class of the DefaultEventManager implementation with "Common::EventSource". ........ r42719 | lordhoto | 2009-07-25 10:59:18 +1000 (Sat, 25 Jul 2009) | 1 line Got rid of EventManger::artificialEventQueue. ........ r42720 | lordhoto | 2009-07-25 10:59:30 +1000 (Sat, 25 Jul 2009) | 1 line Add function "allowMapping" to EventSource, for testing whether the event source allows mapping (via the Keymapper for example.) ........ r42721 | lordhoto | 2009-07-25 10:59:39 +1000 (Sat, 25 Jul 2009) | 1 line Prevent EventMapper events from being mapped. ........ r42722 | lordhoto | 2009-07-25 10:59:53 +1000 (Sat, 25 Jul 2009) | 1 line Replaced "_artificialEventQueue" by an EventSource. ........ r42723 | lordhoto | 2009-07-25 11:00:12 +1000 (Sat, 25 Jul 2009) | 1 line Made DefaultEventManager a subclass of EventObserver. ........ r42724 | lordhoto | 2009-07-25 11:00:24 +1000 (Sat, 25 Jul 2009) | 2 lines - Add marco to easily access the EventDispatcher instance. - Add events.cpp to module.mk ........ r42725 | lordhoto | 2009-07-25 11:00:37 +1000 (Sat, 25 Jul 2009) | 1 line Change DefaultEventManager to use EventDispatcher. ........ r42726 | lordhoto | 2009-07-25 11:00:47 +1000 (Sat, 25 Jul 2009) | 1 line Moved ArtificialEventSource to common/events.h. ........ r42727 | lordhoto | 2009-07-25 11:01:05 +1000 (Sat, 25 Jul 2009) | 2 lines - Adapt DefaultEventManager to use Common::ArtificialEventSource - Adapt Keymapper to implement EventMapper interface ........ r42728 | lordhoto | 2009-07-25 11:01:22 +1000 (Sat, 25 Jul 2009) | 2 lines - EventDispatcher is no longer a singleton. - Add "getEventDispatcher" method to EventManager. ........ r42729 | lordhoto | 2009-07-25 11:01:41 +1000 (Sat, 25 Jul 2009) | 1 line Add enum which marks global priorites of the EventManager event dispatcher. ........ r42736 | Kirben | 2009-07-25 15:39:57 +1000 (Sat, 25 Jul 2009) | 1 line Add patch #2816140 - MM C64 Costume Animation. ........ r42737 | Kirben | 2009-07-25 16:27:41 +1000 (Sat, 25 Jul 2009) | 1 line Add patch #2821100 - MM C64 Objects / Verb fixes, with minor clean up applied. ........ r42738 | Kirben | 2009-07-25 16:36:41 +1000 (Sat, 25 Jul 2009) | 1 line Update credits. ........ r42739 | eriktorbjorn | 2009-07-25 16:55:28 +1000 (Sat, 25 Jul 2009) | 2 lines Fixed GCC warnings. ........ r42740 | Kirben | 2009-07-25 17:17:37 +1000 (Sat, 25 Jul 2009) | 1 line Whitespace changes. ........ r42742 | fingolfin | 2009-07-25 19:36:16 +1000 (Sat, 25 Jul 2009) | 1 line Whitespace fixes ........ r42743 | wjpalenstijn | 2009-07-25 20:25:57 +1000 (Sat, 25 Jul 2009) | 1 line Add Common::String::printf to format a string ........ r42744 | wjpalenstijn | 2009-07-25 20:26:17 +1000 (Sat, 25 Jul 2009) | 1 line Use new Common::String::printf ........ r42746 | sev | 2009-07-25 20:37:20 +1000 (Sat, 25 Jul 2009) | 2 lines Formatting ........ r42747 | joostp | 2009-07-25 22:28:45 +1000 (Sat, 25 Jul 2009) | 1 line fix unaligned writes ........ r42748 | joostp | 2009-07-25 22:41:46 +1000 (Sat, 25 Jul 2009) | 1 line remove implicit SoundDigital::Sound ctor call, which is redundant because the required initialisation is done below -- this fixes a linker error with mipspro ........ r42751 | lordhoto | 2009-07-25 22:59:46 +1000 (Sat, 25 Jul 2009) | 1 line Move the event recorder to its own class (EventRecoder inside common/EventRecorder.[h/cpp]). ........ r42752 | lordhoto | 2009-07-25 23:00:09 +1000 (Sat, 25 Jul 2009) | 1 line Strip trailing whitespaces. ........ r42753 | joostp | 2009-07-25 23:07:17 +1000 (Sat, 25 Jul 2009) | 1 line fix another aligned write ........ r42755 | eriktorbjorn | 2009-07-25 23:07:50 +1000 (Sat, 25 Jul 2009) | 2 lines Added word-wrapping to Drascula's conversation options. Fixes bug #2826607. ........ r42757 | eriktorbjorn | 2009-07-25 23:17:31 +1000 (Sat, 25 Jul 2009) | 2 lines Don't hog the CPU while waiting for the player to pick a conversation option. ........ r42759 | lordhoto | 2009-07-25 23:23:51 +1000 (Sat, 25 Jul 2009) | 1 line Fix gp2x port building. ........ r42761 | lordhoto | 2009-07-26 00:09:58 +1000 (Sun, 26 Jul 2009) | 1 line Yet another fix for the GP2x backend. ........ r42765 | lordhoto | 2009-07-26 01:31:11 +1000 (Sun, 26 Jul 2009) | 1 line Adept savegame name creation code to use Common::String::printf. ........ r42766 | drmccoy | 2009-07-26 02:07:29 +1000 (Sun, 26 Jul 2009) | 1 line Added a workaround to fix the Last Dynasty video greenness for now ........ r42767 | drmccoy | 2009-07-26 02:08:31 +1000 (Sun, 26 Jul 2009) | 1 line Moved the decision whether subtitles should be displayed, so that the broken subtitles in The Last Dynasty aren't shown ........ r42768 | drmccoy | 2009-07-26 02:09:19 +1000 (Sun, 26 Jul 2009) | 1 line Fixing Woodruff videos again after enabling block type 2 transparency ........ r42771 | lordhoto | 2009-07-26 02:34:01 +1000 (Sun, 26 Jul 2009) | 1 line Fix palette regression in Kyra2. ........ r42773 | lordhoto | 2009-07-26 02:37:25 +1000 (Sun, 26 Jul 2009) | 1 line Implement missing bits in KyraEngine_HoF::setCauldronState. ........ r42776 | eriktorbjorn | 2009-07-26 03:48:51 +1000 (Sun, 26 Jul 2009) | 5 lines Make sure that "buf" is properly terminated. Actually, we could probably get rid of "buf" completely, and replace it with face = syncChar[p] - '0', assuming that syncChar only contains digits. But for now, let's make a minimal change. This might fix bug #2826611 ("DRASCULA: Crash when smashing church window"). ........ r42780 | joostp | 2009-07-26 04:35:27 +1000 (Sun, 26 Jul 2009) | 2 lines use READ_UINT16 macro ........ r42782 | drmccoy | 2009-07-26 04:44:06 +1000 (Sun, 26 Jul 2009) | 1 line Adding support for (new-style) stereo in DPCM audio ........ r42783 | drmccoy | 2009-07-26 04:44:24 +1000 (Sun, 26 Jul 2009) | 1 line Adding more sanity checks to Vmd::renderFrame() ........ r42785 | djwillis | 2009-07-26 05:07:28 +1000 (Sun, 26 Jul 2009) | 1 line GP2X Backend: Volume control code cleanup. ........ r42787 | wjpalenstijn | 2009-07-26 09:36:24 +1000 (Sun, 26 Jul 2009) | 2 lines Add optional readline support to the text debugger console. Make text/graphical console selectable with an option to configure. ........ r42790 | dreammaster | 2009-07-26 10:27:32 +1000 (Sun, 26 Jul 2009) | 1 line Changed the events.cpp file to EventDispatcher.cpp, to avoid MSVC name clashes with sdl/events.cpp ........ r42791 | dreammaster | 2009-07-26 10:31:28 +1000 (Sun, 26 Jul 2009) | 1 line Fixed compilation from file changes to common and gob engine ........ r42792 | lordhoto | 2009-07-26 17:07:35 +1000 (Sun, 26 Jul 2009) | 1 line Formatting. ........ r42793 | peres001 | 2009-07-26 18:37:03 +1000 (Sun, 26 Jul 2009) | 1 line Moved parser functions arrays to file scope, as they were tripping up the obsolete gcc used for the BeOS/Haiku port. If anybody can work out a better solution please apply it, because this makes me sick. ........ r42795 | dreammaster | 2009-07-26 19:09:07 +1000 (Sun, 26 Jul 2009) | 1 line Added a delay to the in-game menu loop to prevent 100% CPU usage ........ r42798 | dreammaster | 2009-07-26 19:40:35 +1000 (Sun, 26 Jul 2009) | 1 line Bugfix for mouse button clicks getting counted multiple times ........ r42799 | dreammaster | 2009-07-26 19:48:52 +1000 (Sun, 26 Jul 2009) | 1 line Added a debug line to allow tracking of script execution ........ r42801 | eriktorbjorn | 2009-07-26 20:10:08 +1000 (Sun, 26 Jul 2009) | 4 lines 78 bytes isn't enough for some of the longer conversation options. 128 might not be enough either, but at least it fixes bug #2827170 ("DRASCULA: Conversation error"). ........ r42807 | djwillis | 2009-07-26 22:58:22 +1000 (Sun, 26 Jul 2009) | 2 lines Virtual Keyboard: Update default keyboard pack using slightly tweaked versions of the graphics very kindly provided by Carl Mitchell. Also update xml file to make best use of the keyboard graphics and add the 'delete' event in addition the passing backspace back to the calling textarea. ........ r42809 | drmccoy | 2009-07-26 23:50:18 +1000 (Sun, 26 Jul 2009) | 1 line Reverting my fix for bug #2037158 ("In-Game animation shifted(?)"), because it breaks Woodruff's intro ........ r42812 | lordhoto | 2009-07-27 00:16:51 +1000 (Mon, 27 Jul 2009) | 1 line Create base class FontSJIS16x16 for our own SJIS font. ........ r42813 | lordhoto | 2009-07-27 00:17:06 +1000 (Mon, 27 Jul 2009) | 1 line Add support for our custom SJIS font. ........ r42814 | lordhoto | 2009-07-27 00:17:21 +1000 (Mon, 27 Jul 2009) | 1 line Change KYRA to use our SJIS font, when it's available. ........ r42815 | lordhoto | 2009-07-27 00:17:40 +1000 (Mon, 27 Jul 2009) | 1 line Change the way the font data for SJIS fonts is load. ........ r42816 | lordhoto | 2009-07-27 00:17:54 +1000 (Mon, 27 Jul 2009) | 1 line Add a factory method, which tries to open different SJIS fonts/ROMs and returns a font for the first present data. ........ r42817 | lordhoto | 2009-07-27 00:18:06 +1000 (Mon, 27 Jul 2009) | 1 line Print warning, when client code does try to draw an unsupported SJIS char. ........ r42818 | lordhoto | 2009-07-27 00:18:21 +1000 (Mon, 27 Jul 2009) | 1 line Specify that the chars passed to FontSJIS::drawChar should be little endian. ........ r42819 | lordhoto | 2009-07-27 00:18:34 +1000 (Mon, 27 Jul 2009) | 1 line Add way to overwrite default SJIS font. ........ r42820 | lordhoto | 2009-07-27 00:18:49 +1000 (Mon, 27 Jul 2009) | 1 line Simplify KYRA's SJIS font loading code. ........ r42821 | lordhoto | 2009-07-27 00:19:02 +1000 (Mon, 27 Jul 2009) | 1 line Reflect code to test the magic bytes in the sjis.fnt header. ........ r42822 | lordhoto | 2009-07-27 00:24:45 +1000 (Mon, 27 Jul 2009) | 1 line Add NEWS entry about new SJIS code. ........ r42823 | lordhoto | 2009-07-27 00:40:03 +1000 (Mon, 27 Jul 2009) | 1 line Instead of only printing a warning, when no SJIS char data is present, just return to the caller. ........ r42824 | lordhoto | 2009-07-27 00:40:44 +1000 (Mon, 27 Jul 2009) | 1 line Add a todo to FontSJIS::drawChar taking an Graphics::Surface. ........ r42825 | marcus_c | 2009-07-27 06:41:33 +1000 (Mon, 27 Jul 2009) | 1 line Create IP.BIN. ........ r42826 | joostp | 2009-07-27 07:06:53 +1000 (Mon, 27 Jul 2009) | 1 line fix/workaround for cruise crash on OSX ........ r42842 | wjpalenstijn | 2009-07-28 02:04:35 +1000 (Tue, 28 Jul 2009) | 2 lines Fix format string issues (and compiler warnings). Patch by salty-horse. ........ r42843 | robinwatts | 2009-07-28 02:29:36 +1000 (Tue, 28 Jul 2009) | 7 lines Add ARM code version of Normal2x scaler. Add ARM only aspect ratio correcting version of Normal2x scaler. Make WinCE port use Normal2x by default if the screen is large enough. Make WinCE port use aspect ratio correcting version if panel is hidden. ........ r42844 | lordhoto | 2009-07-28 03:04:06 +1000 (Tue, 28 Jul 2009) | 1 line Formatting. ........ r42845 | lordhoto | 2009-07-28 03:48:40 +1000 (Tue, 28 Jul 2009) | 1 line Fix bug #2827459 "ITE: Ingame GUI does not list slots 96-99", by defining in SagaMetaEngine that the last valid save slot for SAGA is slot 95. ........ r42847 | djwillis | 2009-07-28 04:05:16 +1000 (Tue, 28 Jul 2009) | 1 line GP2XWiz: Update GP2X Wiz bundle.sh to copy libraries into the distribution file from the tool chain where the libraries are broken on the device. Also add LD_LIBRARY_PATH 'hack' to launch script to ensure bundled libraries are used over system ones. ........ r42849 | lordhoto | 2009-07-28 04:19:16 +1000 (Tue, 28 Jul 2009) | 1 line Oops enabled HACK to prevent multiple OPL instances again. ........ r42851 | drmccoy | 2009-07-28 05:01:17 +1000 (Tue, 28 Jul 2009) | 1 line Abstracting off the block types from Imd::renderFrame() and Vmd::renderFrame() ........ r42856 | drmccoy | 2009-07-29 01:05:44 +1000 (Wed, 29 Jul 2009) | 1 line Silencing two "empty loop body" warnings ........ r42857 | drmccoy | 2009-07-29 01:19:55 +1000 (Wed, 29 Jul 2009) | 1 line Changing stuff around a bit so alignment requirements won't increase ........ r42858 | drmccoy | 2009-07-29 02:28:32 +1000 (Wed, 29 Jul 2009) | 1 line More alignment-related changes ........ r42859 | eriktorbjorn | 2009-07-29 03:19:33 +1000 (Wed, 29 Jul 2009) | 3 lines Fixed drawing subtitles for cutscenes that are narrower than the screen, and erase the subtitles manually if they are drawn outside the frame. ........ r42861 | eriktorbjorn | 2009-07-29 03:53:59 +1000 (Wed, 29 Jul 2009) | 3 lines Broken Sword 2, unsurprisingly, had the same subtitle drawing glitch for small cutscenes that Broken Sword 1 had. And a memory leak. This should fix both. ........ r42863 | djwillis | 2009-07-29 06:22:38 +1000 (Wed, 29 Jul 2009) | 1 line GP2XWiz: Add downscale support to the backend using the PocketPCHalfARM scaler from the WinCE backend (Maybe this should be moved into /graphics/scalers at some point?). Also enable all the ARM optemised routines in this and the GP2X backend. ........ r42866 | fingolfin | 2009-07-29 08:28:40 +1000 (Wed, 29 Jul 2009) | 1 line SCI: Avoid using perror (it's not portable) ........ r42868 | fingolfin | 2009-07-29 08:42:08 +1000 (Wed, 29 Jul 2009) | 1 line Patch #2828644: Support for mingw32ce 0.5.1 toolchain in configure script ........ r42870 | fingolfin | 2009-07-29 09:19:33 +1000 (Wed, 29 Jul 2009) | 2 lines SCUMM: Moved _inventoryOffset to ScummEngine_v2 and save it. Fixes bug #2828417: Zak V2: inventory position isn't reset when loading. ........ r42880 | fingolfin | 2009-07-29 18:55:04 +1000 (Wed, 29 Jul 2009) | 1 line SCUMM: cleanup ........ r42881 | fingolfin | 2009-07-29 18:55:17 +1000 (Wed, 29 Jul 2009) | 1 line GUI: When clicking in a scrollbar to page up/down, don't scroll a full page; rather scroll a full page minus one line (see FR #2821508). This matches the behavior of the page up/down keys ........ r42886 | fingolfin | 2009-07-29 19:19:56 +1000 (Wed, 29 Jul 2009) | 1 line Sort audio output rates numerically (see FR #2821525) ........ r42887 | drmccoy | 2009-07-29 20:17:44 +1000 (Wed, 29 Jul 2009) | 1 line Adding a SoundType parameter to SmackerDecoder, defaulting to kSFXSoundType ........ r42889 | fingolfin | 2009-07-29 21:48:20 +1000 (Wed, 29 Jul 2009) | 1 line SCUMM: Rewrote ScummEngine::inventoryScriptIndy3Mac for clarity ........ r42890 | lordhoto | 2009-07-30 00:54:27 +1000 (Thu, 30 Jul 2009) | 1 line Fix animation script sound effect opcode implementation in Kyra3. ........ r42892 | lordhoto | 2009-07-30 01:31:23 +1000 (Thu, 30 Jul 2009) | 1 line Fix saving of item in hand in HoF and MR. ........ r42894 | drmccoy | 2009-07-30 01:57:50 +1000 (Thu, 30 Jul 2009) | 1 line Oops, fixing a regression I created with the Map_v4/Map_v2-merge ........ r42895 | lordhoto | 2009-07-30 02:24:07 +1000 (Thu, 30 Jul 2009) | 1 line Fix a little bug in KyraEngine_MR::showBadConscience, which prevented Gunther's mouse shapes from showing up. ........ r42898 | fingolfin | 2009-07-30 04:35:34 +1000 (Thu, 30 Jul 2009) | 1 line SCUMM: Enable looping in Indy3Mac sound effects ........ r42900 | lordhoto | 2009-07-30 05:39:03 +1000 (Thu, 30 Jul 2009) | 1 line Fix regression, which prevented saving in COMI. ........ r42904 | lordhoto | 2009-07-30 06:03:46 +1000 (Thu, 30 Jul 2009) | 1 line Fix typo, which made our "floorf" macro use "floorf" instead of "floor" on systems without "floorf". ........ r42907 | fingolfin | 2009-07-30 06:35:50 +1000 (Thu, 30 Jul 2009) | 1 line SCUMM: Fix verb/sentence handling in Indy3 mac (there, a double click must be used to trigger a verb/sentence) ........ r42910 | fingolfin | 2009-07-30 07:39:00 +1000 (Thu, 30 Jul 2009) | 1 line Removed last traces of clearIOFailed. Yay :) ........ r42911 | fingolfin | 2009-07-30 07:39:16 +1000 (Thu, 30 Jul 2009) | 1 line Removed redundant File::ioFailed() implementation; also turned ReadStream::ioFailed from a virtual into an inline method ........ r42912 | fingolfin | 2009-07-30 07:39:34 +1000 (Thu, 30 Jul 2009) | 1 line SWORD1 & SWORD2: Replaced ioFailed by err+eos ........ r42918 | fingolfin | 2009-07-30 19:36:50 +1000 (Thu, 30 Jul 2009) | 1 line Patch #2818501: enable scale2x mmx on x86_64 ........ r42920 | dreammaster | 2009-07-30 21:03:16 +1000 (Thu, 30 Jul 2009) | 1 line Added the character lookup table for the Spanish font ........ r42922 | peres001 | 2009-07-30 23:41:22 +1000 (Thu, 30 Jul 2009) | 1 line Use SaveFileMan::listSaveFiles() to build list of old savegames for Nippon Safes. ........ r42923 | peres001 | 2009-07-30 23:42:08 +1000 (Thu, 30 Jul 2009) | 1 line Fixed typo in user message. ........ r42924 | peres001 | 2009-07-30 23:44:50 +1000 (Thu, 30 Jul 2009) | 1 line Cleanup the header file as I removed one function in r42922. ........ r42926 | lordhoto | 2009-07-31 00:24:23 +1000 (Fri, 31 Jul 2009) | 1 line Fix bug which caused the mouse cursor not to update in some cases. ........ r42929 | lordhoto | 2009-07-31 01:12:42 +1000 (Fri, 31 Jul 2009) | 1 line Add tanoku to our GUI credits section. ........ r42932 | lordhoto | 2009-07-31 01:19:15 +1000 (Fri, 31 Jul 2009) | 1 line Prevent our "credits" make target updating Credits.rtf, which in fact is not present in SVN anymore, and the outdated docbook. ........ r42934 | lordhoto | 2009-07-31 02:43:25 +1000 (Fri, 31 Jul 2009) | 1 line Fix bug #2829737: "GUI: Wrong background colours on dialog screens (IRIX)". ........ r42935 | lordhoto | 2009-07-31 02:51:53 +1000 (Fri, 31 Jul 2009) | 1 line Fixed missing clearing of the low bit of the alpha mask in the "dim" screen shading function. ........ r42937 | fingolfin | 2009-07-31 03:48:03 +1000 (Fri, 31 Jul 2009) | 1 line NDS: Changed jtypes.h to ndstypes.h (this 'newer' name has been in effect even in the older versions of DevKitPro used for compiling ScummVM...) ........ r42938 | fingolfin | 2009-07-31 03:52:44 +1000 (Fri, 31 Jul 2009) | 1 line minor cleanup to scale2x, to avoid confusing the compiler about potential pointer aliasing (only the tip of the iceberg, of course... ;) ........ r42939 | fingolfin | 2009-07-31 04:27:50 +1000 (Fri, 31 Jul 2009) | 1 line DS: Started work on a new build system for the Nintendo DS port, based on configure (and thus suitable for buildbot). Currently only the ARM7 part is 'done' ........ r42940 | lordhoto | 2009-07-31 05:43:36 +1000 (Fri, 31 Jul 2009) | 1 line Change code to use our fractional utilities. ........ r42941 | lordhoto | 2009-07-31 05:43:53 +1000 (Fri, 31 Jul 2009) | 1 line Fix Browser dialog name. ........ r42943 | fingolfin | 2009-07-31 06:46:43 +1000 (Fri, 31 Jul 2009) | 1 line Overhauled the credits: Retired members are now (partially) back to their old sections, to make sure people really see all people who contribute to an engine/backend. Also added&fixed some entries, and moved the FreeSCI section ........ r42946 | fingolfin | 2009-07-31 06:58:32 +1000 (Fri, 31 Jul 2009) | 1 line Changed 10rdH070's nick back to LordHoto, and added Hkz to the credits ........ r42947 | fingolfin | 2009-07-31 07:04:46 +1000 (Fri, 31 Jul 2009) | 1 line Added Strangerke to credits, and moved wjp from Gob to SCI on his request ........ r42950 | fingolfin | 2009-07-31 07:45:09 +1000 (Fri, 31 Jul 2009) | 1 line Patch #2828669: CRUISE: Fix cruise compilation with mingw32ce toolchain ........ r42951 | fingolfin | 2009-07-31 07:56:04 +1000 (Fri, 31 Jul 2009) | 1 line SCUMM: Properly detect & distinguish the three FM-TOWNS double-demos ........ r42952 | fingolfin | 2009-07-31 07:56:18 +1000 (Fri, 31 Jul 2009) | 1 line cleanup ........ r42953 | tanoku | 2009-07-31 09:42:12 +1000 (Fri, 31 Jul 2009) | 2 lines Fixed corrupted theme files. ........ r42955 | tanoku | 2009-07-31 10:22:46 +1000 (Fri, 31 Jul 2009) | 2 lines Prevent high-resolution layouts to be loaded on low resolutions. ........ r42958 | peres001 | 2009-07-31 22:39:31 +1000 (Fri, 31 Jul 2009) | 1 line When renaming old savefiles for Nippon Safes, don't assert if a file that matches the pattern game.* and is not a savefile is found in the savepath. ........ r42959 | djwillis | 2009-07-31 23:01:28 +1000 (Fri, 31 Jul 2009) | 1 line GP2X: Clean up README-GP2X and remove HTML version of it from SVN (no one ever reads it and the WiKi is more upto date). ........ r42964 | djwillis | 2009-08-01 03:10:20 +1000 (Sat, 01 Aug 2009) | 1 line GP2XWiz: Small cleanup of render code to slave as much of loadGFXMode() code back to the OSystem_SDL::loadGFXMode(). version. Also update README-GP2XWIZ. ........ r42965 | dreammaster | 2009-08-01 09:27:19 +1000 (Sat, 01 Aug 2009) | 1 line Fix bug with the event loop that was discarding pending events rather than leaving them to be processed in the following frame ........ r42973 | buddha_ | 2009-08-01 19:53:21 +1000 (Sat, 01 Aug 2009) | 1 line Remove obsolete comment from Cine::Palette::saturatedAddColor. ........ r42974 | eriktorbjorn | 2009-08-02 01:42:42 +1000 (Sun, 02 Aug 2009) | 4 lines Added some more information to the "Compressed sound ... invalid" error. Maybe this will help in determining what's causing bug #2830364. (It sounds like a bad data file, but who knows...) ........ r42995 | drmccoy | 2009-08-02 20:40:27 +1000 (Sun, 02 Aug 2009) | 1 line When ESCing videos, seek to the last frame that was meant to be played. Fixes graphical glitches (bug #2830985) and crashes (bug #2830988) ........ r42996 | drmccoy | 2009-08-02 20:40:48 +1000 (Sun, 02 Aug 2009) | 1 line Removing _frameWaitLag. It broke normal animation speed in pre-v4 games and didn't even do what it was supposed to in v4+ games anyway. (bug #2830985) ........ r42999 | eriktorbjorn | 2009-08-02 22:49:57 +1000 (Sun, 02 Aug 2009) | 2 lines Show a message if saving or loading a game fails. ........ r43001 | drmccoy | 2009-08-02 23:54:06 +1000 (Sun, 02 Aug 2009) | 1 line Show a message if saving or loading a game fails. ........ r43003 | knakos | 2009-08-03 03:34:57 +1000 (Mon, 03 Aug 2009) | 1 line rework mixer (re)init. fixes bug #2694722 ........ r43005 | joostp | 2009-08-03 03:58:48 +1000 (Mon, 03 Aug 2009) | 1 line align memory handles to sizeof(void*) instead of 4 (which is just good enough for 32-bit) - this fixes DW2 on 64-bit systems that require alignment ........ r43007 | djwillis | 2009-08-03 05:46:18 +1000 (Mon, 03 Aug 2009) | 1 line GP2XWiz: More cleanup of render code and fix silly screen update bug when reverting to a 320*2xx game from a 640*4xx game. Dirty rect code for downscaled images still needs work. ........ r43008 | knakos | 2009-08-03 05:50:24 +1000 (Mon, 03 Aug 2009) | 1 line clean up and fix vga aspect scaler routines ........ r43010 | djwillis | 2009-08-03 07:18:25 +1000 (Mon, 03 Aug 2009) | 1 line GP2XWiz/SDL: Fix 2 small typos. ........ r43011 | joostp | 2009-08-03 07:22:46 +1000 (Mon, 03 Aug 2009) | 1 line Fix AGI crashes on 64-bit systems that require alignment ........ r43013 | joostp | 2009-08-03 07:44:21 +1000 (Mon, 03 Aug 2009) | 1 line Make MemoryReAlloc() 64-bit alignment safe ........ r43020 | scott_t | 2009-08-03 11:19:36 +1000 (Mon, 03 Aug 2009) | 1 line T7G: Fix bug #2831046 where save names not shown after loading a save from launcher ........ r43023 | dreammaster | 2009-08-03 19:28:06 +1000 (Mon, 03 Aug 2009) | 1 line Bugfix to correctly reset the music tempo when loading a savegame ........ r43025 | buddha_ | 2009-08-04 03:18:18 +1000 (Tue, 04 Aug 2009) | 6 lines Fix for bug #2828333 (AGI: KQ1: Greensleeves always plays): - Made all savegame loading in AGI do the same pre-load and post-load stuff. - Moved load/saveGameState from AgiBase to AgiEngine - Added rudimentary error handling to load/saveGameState - Incidentally also fixes the hanging note from bug #2798797. ........ r43027 | buddha_ | 2009-08-04 03:52:07 +1000 (Tue, 04 Aug 2009) | 8 lines Fix for #2824798 (FW: crash when clicking "load" in the GUI): - Fixed CineMetaEngine::listSaves(const char *target) which was broken. - Also added explicit initialization of savegame descriptions to empty strings for safety reasons (e.g. arrays on stack aren't initialized to zero). - Added explicit trailing zero setting to savegame descriptions (Previously using GMM you could write a description of length >= 20 that had no trailing zero when written to description file (e.g. fw.dir)). ........ r43029 | djwillis | 2009-08-04 04:38:46 +1000 (Tue, 04 Aug 2009) | 1 line GP2XWiz: Fix bug with downscaled cursors. ........ r43033 | knakos | 2009-08-04 22:02:07 +1000 (Tue, 04 Aug 2009) | 1 line add bindings for cruise engine ........ r43035 | knakos | 2009-08-04 22:19:30 +1000 (Tue, 04 Aug 2009) | 1 line support made engine ........ r43037 | knakos | 2009-08-04 22:39:33 +1000 (Tue, 04 Aug 2009) | 1 line update Makefile ........ r43039 | knakos | 2009-08-04 22:51:17 +1000 (Tue, 04 Aug 2009) | 1 line update readme (draft) ........ r43041 | knakos | 2009-08-04 23:17:33 +1000 (Tue, 04 Aug 2009) | 1 line commit slightly modified patch #2828646: WINCE: Integrate Windows CE with the master build system ........ r43042 | thebluegr | 2009-08-05 00:20:38 +1000 (Wed, 05 Aug 2009) | 1 line Cleaned up the MSVC project files of the gob engine ........ r43043 | knakos | 2009-08-05 00:53:43 +1000 (Wed, 05 Aug 2009) | 1 line got rid of superfluous semicolons ........ r43048 | thebluegr | 2009-08-05 03:22:18 +1000 (Wed, 05 Aug 2009) | 1 line Removed the superfluous VGA buffer, replacing it with direct writes to the video buffer ........ r43056 | thebluegr | 2009-08-05 07:56:59 +1000 (Wed, 05 Aug 2009) | 1 line Cleanup ........ svn-id: r43062
Diffstat (limited to 'engines')
-rw-r--r--engines/agi/agi.cpp165
-rw-r--r--engines/agi/agi.h4
-rw-r--r--engines/agi/cycle.cpp2
-rw-r--r--engines/agi/detection.cpp29
-rw-r--r--engines/agi/keyboard.cpp31
-rw-r--r--engines/agi/menu.cpp62
-rw-r--r--engines/agi/preagi_mickey.cpp2
-rw-r--r--engines/agi/saveload.cpp82
-rw-r--r--engines/agi/sprite.cpp5
-rw-r--r--engines/agos/agos.cpp3
-rw-r--r--engines/agos/agos.h44
-rw-r--r--engines/agos/debug.h2
-rw-r--r--engines/agos/detection_tables.h160
-rw-r--r--engines/agos/draw.cpp10
-rw-r--r--engines/agos/input.cpp5
-rw-r--r--engines/agos/midiparser_s1d.cpp4
-rw-r--r--engines/agos/pn.cpp50
-rw-r--r--engines/agos/res_snd.cpp4
-rw-r--r--engines/agos/saveload.cpp25
-rw-r--r--engines/agos/script_pn.cpp126
-rw-r--r--engines/agos/script_s1.cpp13
-rw-r--r--engines/agos/vga_e2.cpp44
-rw-r--r--engines/agos/vga_ww.cpp22
-rw-r--r--engines/cine/cine.cpp6
-rw-r--r--engines/cine/detection.cpp52
-rw-r--r--engines/cine/pal.cpp3
-rw-r--r--engines/cine/saveload.cpp9
-rw-r--r--engines/cruise/cruise.cpp3
-rw-r--r--engines/cruise/cruise_main.cpp42
-rw-r--r--engines/cruise/cruise_main.h8
-rw-r--r--engines/cruise/dataLoader.cpp2
-rw-r--r--engines/cruise/linker.cpp21
-rw-r--r--engines/cruise/mainDraw.cpp32
-rw-r--r--engines/cruise/mainDraw.h4
-rw-r--r--engines/cruise/menu.cpp1
-rw-r--r--engines/cruise/script.cpp7
-rw-r--r--engines/cruise/sound.cpp4
-rw-r--r--engines/cruise/staticres.cpp53
-rw-r--r--engines/cruise/staticres.h4
-rw-r--r--engines/drascula/converse.cpp26
-rw-r--r--engines/drascula/drascula.cpp11
-rw-r--r--engines/drascula/drascula.h4
-rw-r--r--engines/drascula/graphics.cpp62
-rw-r--r--engines/drascula/rooms.cpp39
-rw-r--r--engines/drascula/talk.cpp1
-rw-r--r--engines/gob/demos/demoplayer.cpp45
-rw-r--r--engines/gob/demos/demoplayer.h2
-rw-r--r--engines/gob/demos/scnplayer.cpp2
-rw-r--r--engines/gob/detection.cpp52
-rw-r--r--engines/gob/draw.cpp2
-rw-r--r--engines/gob/draw.h5
-rw-r--r--engines/gob/draw_v1.cpp2
-rw-r--r--engines/gob/draw_v2.cpp28
-rw-r--r--engines/gob/game.cpp6
-rw-r--r--engines/gob/global.cpp2
-rw-r--r--engines/gob/global.h2
-rw-r--r--engines/gob/gob.cpp183
-rw-r--r--engines/gob/gob.h3
-rw-r--r--engines/gob/init.cpp7
-rw-r--r--engines/gob/init.h38
-rw-r--r--engines/gob/init_v1.cpp3
-rw-r--r--engines/gob/init_v2.cpp3
-rw-r--r--engines/gob/init_v3.cpp3
-rw-r--r--engines/gob/init_v4.cpp45
-rw-r--r--engines/gob/init_v6.cpp3
-rw-r--r--engines/gob/inter_v1.cpp13
-rw-r--r--engines/gob/inter_v2.cpp66
-rw-r--r--engines/gob/map.h8
-rw-r--r--engines/gob/map_v2.cpp26
-rw-r--r--engines/gob/map_v4.cpp159
-rw-r--r--engines/gob/module.mk2
-rw-r--r--engines/gob/resources.cpp44
-rw-r--r--engines/gob/resources.h6
-rw-r--r--engines/gob/save/saveconverter.cpp6
-rw-r--r--engines/gob/save/saveload.h28
-rw-r--r--engines/gob/save/saveload_v4.cpp20
-rw-r--r--engines/gob/scenery.cpp13
-rw-r--r--engines/gob/script.cpp2
-rw-r--r--engines/gob/sound/bgatmosphere.cpp3
-rw-r--r--engines/gob/sound/sounddesc.cpp6
-rw-r--r--engines/gob/sound/soundmixer.cpp25
-rw-r--r--engines/gob/sound/soundmixer.h4
-rw-r--r--engines/gob/util.cpp12
-rw-r--r--engines/gob/util.h1
-rw-r--r--engines/gob/variables.cpp32
-rw-r--r--engines/gob/variables.h12
-rw-r--r--engines/gob/videoplayer.cpp16
-rw-r--r--engines/gob/videoplayer.h2
-rw-r--r--engines/groovie/cell.cpp819
-rw-r--r--engines/groovie/cell.h48
-rw-r--r--engines/groovie/script.cpp44
-rw-r--r--engines/groovie/script.h3
-rw-r--r--engines/kyra/gui.cpp10
-rw-r--r--engines/kyra/gui_hof.cpp2
-rw-r--r--engines/kyra/gui_mr.cpp2
-rw-r--r--engines/kyra/items_mr.cpp3
-rw-r--r--engines/kyra/kyra_hof.cpp6
-rw-r--r--engines/kyra/kyra_mr.h1
-rw-r--r--engines/kyra/kyra_v1.cpp3
-rw-r--r--engines/kyra/saveload.cpp6
-rw-r--r--engines/kyra/screen.cpp23
-rw-r--r--engines/kyra/script_mr.cpp8
-rw-r--r--engines/kyra/sequences_mr.cpp3
-rw-r--r--engines/kyra/sound_digital.cpp2
-rw-r--r--engines/kyra/sprites.cpp4
-rw-r--r--engines/lure/hotspots.cpp25
-rw-r--r--engines/lure/res.cpp3
-rw-r--r--engines/lure/scripts.cpp3
-rw-r--r--engines/m4/m4.cpp3
-rw-r--r--engines/made/made.cpp3
-rw-r--r--engines/parallaction/parallaction.cpp3
-rw-r--r--engines/parallaction/parser.h14
-rw-r--r--engines/parallaction/parser_br.cpp37
-rw-r--r--engines/parallaction/parser_ns.cpp33
-rw-r--r--engines/parallaction/saveload.cpp88
-rw-r--r--engines/parallaction/saveload.h1
-rw-r--r--engines/queen/display.cpp3
-rw-r--r--engines/queen/music.cpp3
-rw-r--r--engines/queen/queen.cpp3
-rw-r--r--engines/saga/detection.cpp4
-rw-r--r--engines/saga/font.cpp48
-rw-r--r--engines/saga/saga.cpp3
-rw-r--r--engines/sci/console.cpp25
-rw-r--r--engines/sci/debug.h1
-rw-r--r--engines/sci/engine/scriptdebug.cpp29
-rw-r--r--engines/sci/engine/seg_manager.cpp13
-rw-r--r--engines/sci/engine/seg_manager.h7
-rw-r--r--engines/sci/engine/vm.cpp14
-rw-r--r--engines/sci/engine/vm.h5
-rw-r--r--engines/sci/gfx/operations.cpp1
-rw-r--r--engines/sci/resource.cpp8
-rw-r--r--engines/sci/sci.cpp4
-rw-r--r--engines/scumm/actor.cpp65
-rw-r--r--engines/scumm/actor.h8
-rw-r--r--engines/scumm/boxes.cpp2
-rw-r--r--engines/scumm/costume.cpp207
-rw-r--r--engines/scumm/costume.h6
-rw-r--r--engines/scumm/detection.cpp72
-rw-r--r--engines/scumm/detection_tables.h12
-rw-r--r--engines/scumm/dialogs.cpp9
-rw-r--r--engines/scumm/dialogs.h4
-rw-r--r--engines/scumm/file.cpp9
-rw-r--r--engines/scumm/file.h5
-rw-r--r--engines/scumm/gfx.cpp14
-rw-r--r--engines/scumm/he/cup_player_he.cpp23
-rw-r--r--engines/scumm/he/intern_he.h2
-rw-r--r--engines/scumm/he/script_v100he.cpp4
-rw-r--r--engines/scumm/he/script_v60he.cpp23
-rw-r--r--engines/scumm/he/script_v72he.cpp10
-rw-r--r--engines/scumm/he/script_v80he.cpp6
-rw-r--r--engines/scumm/he/script_v90he.cpp2
-rw-r--r--engines/scumm/he/wiz_he.cpp4
-rw-r--r--engines/scumm/imuse_digi/dimuse_bndmgr.cpp2
-rw-r--r--engines/scumm/input.cpp17
-rw-r--r--engines/scumm/object.cpp64
-rw-r--r--engines/scumm/resource.cpp11
-rw-r--r--engines/scumm/resource_v2.cpp2
-rw-r--r--engines/scumm/resource_v3.cpp2
-rw-r--r--engines/scumm/resource_v4.cpp9
-rw-r--r--engines/scumm/saveload.cpp56
-rw-r--r--engines/scumm/saveload.h2
-rw-r--r--engines/scumm/script.cpp130
-rw-r--r--engines/scumm/script_v0.cpp153
-rw-r--r--engines/scumm/script_v5.cpp18
-rw-r--r--engines/scumm/script_v6.cpp8
-rw-r--r--engines/scumm/scumm-md5.h130
-rw-r--r--engines/scumm/scumm.cpp21
-rw-r--r--engines/scumm/scumm.h12
-rw-r--r--engines/scumm/scumm_v0.h30
-rw-r--r--engines/scumm/scumm_v2.h5
-rw-r--r--engines/scumm/sound.cpp14
-rw-r--r--engines/scumm/string.cpp5
-rw-r--r--engines/scumm/vars.cpp4
-rw-r--r--engines/scumm/verbs.cpp473
-rw-r--r--engines/sky/logic.cpp3
-rw-r--r--engines/sword1/animation.cpp42
-rw-r--r--engines/sword1/control.cpp2
-rw-r--r--engines/sword1/logic.cpp3
-rw-r--r--engines/sword1/resman.cpp6
-rw-r--r--engines/sword1/sound.cpp3
-rw-r--r--engines/sword2/animation.cpp39
-rw-r--r--engines/sword2/animation.h2
-rw-r--r--engines/sword2/resman.cpp6
-rw-r--r--engines/sword2/startup.cpp4
-rw-r--r--engines/sword2/sword2.cpp3
-rw-r--r--engines/tinsel/detection.cpp4
-rw-r--r--engines/tinsel/heapmem.cpp5
-rw-r--r--engines/tinsel/saveload.cpp27
-rw-r--r--engines/tinsel/tinsel.cpp3
-rw-r--r--engines/touche/touche.cpp3
-rw-r--r--engines/tucker/locations.cpp2
191 files changed, 3572 insertions, 1841 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp
index e373dd3e6d..69b27e10f9 100644
--- a/engines/agi/agi.cpp
+++ b/engines/agi/agi.cpp
@@ -25,6 +25,7 @@
#include "common/md5.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -271,19 +272,6 @@ void AgiEngine::processEvents() {
}
}
-void AgiEngine::checkQuickLoad() {
- if (ConfMan.hasKey("save_slot")) {
- char saveNameBuffer[256];
-
- snprintf (saveNameBuffer, 256, "%s.%03d", _targetName.c_str(), ConfMan.getInt("save_slot"));
-
- if (loadGame(saveNameBuffer, false) == errOK) { // Do not check game id
- _game.exitAllLogics = 1;
- _menu->enableAll();
- }
- }
-}
-
void AgiEngine::pollTimer(void) {
static uint32 m = 0;
uint32 dm;
@@ -301,40 +289,10 @@ void AgiEngine::pollTimer(void) {
m = g_tickTimer;
}
-bool AgiEngine::isKeypress(void) {
- processEvents();
- return _keyQueueStart != _keyQueueEnd;
-}
-
-int AgiEngine::getKeypress(void) {
- int k;
-
- while (_keyQueueStart == _keyQueueEnd) // block
- pollTimer();
-
- keyDequeue(k);
-
- return k;
-}
-
-void AgiEngine::clearKeyQueue(void) {
- while (isKeypress()) {
- getKeypress();
- }
-}
-
void AgiEngine::agiTimerFunctionLow(void *refCon) {
g_tickTimer++;
}
-void AgiEngine::clearImageStack(void) {
- _imageStack.clear();
-}
-
-void AgiEngine::releaseImageStack(void) {
- _imageStack.clear();
-}
-
void AgiEngine::pause(uint32 msec) {
uint32 endTime = _system->getMillis() + msec;
@@ -348,38 +306,6 @@ void AgiEngine::pause(uint32 msec) {
_gfx->setCursor(_renderMode == Common::kRenderAmiga);
}
-void AgiEngine::recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
- int16 p4, int16 p5, int16 p6, int16 p7) {
- ImageStackElement pnew;
-
- pnew.type = type;
- pnew.pad = 0;
- pnew.parm1 = p1;
- pnew.parm2 = p2;
- pnew.parm3 = p3;
- pnew.parm4 = p4;
- pnew.parm5 = p5;
- pnew.parm6 = p6;
- pnew.parm7 = p7;
-
- _imageStack.push(pnew);
-}
-
-void AgiEngine::replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
- int16 p4, int16 p5, int16 p6, int16 p7) {
- switch (type) {
- case ADD_PIC:
- debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1);
- agiLoadResource(rPICTURE, p1);
- _picture->decodePicture(p1, p2, p3 != 0);
- break;
- case ADD_VIEW:
- agiLoadResource(rVIEW, p1);
- _sprites->addToPic(p1, p2, p3, p4, p5, p6, p7);
- break;
- }
-}
-
void AgiEngine::initPriTable() {
int i, p, y = 0;
@@ -489,11 +415,6 @@ int AgiEngine::agiInit() {
_game.mouseFence.setWidth(0); // Reset
- _game.lastController = 0;
- for (i = 0; i < MAX_DIRS; i++)
- _game.controllerOccured[i] = false;
-
-
return ec;
}
@@ -530,21 +451,6 @@ int AgiEngine::agiDeinit() {
return ec;
}
-int AgiEngine::agiDetectGame() {
- int ec = errOK;
-
- assert(_gameDescription != NULL);
-
- if (getVersion() <= 0x2999) {
- _loader = new AgiLoader_v2(this);
- } else {
- _loader = new AgiLoader_v3(this);
- }
- ec = _loader->detectGame();
-
- return ec;
-}
-
int AgiEngine::agiLoadResource(int r, int n) {
int i;
@@ -587,67 +493,6 @@ static const GameSettings agiSettings[] = {
{NULL, NULL, 0, 0, NULL}
};
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, bool positive) const {
- if (_amigaStyle) {
- if (positive) {
- if (pressed) { // Positive pressed Amiga-style button
- if (_olderAgi) {
- return AgiTextColor(amigaBlack, amigaOrange);
- } else {
- return AgiTextColor(amigaBlack, amigaPurple);
- }
- } else { // Positive unpressed Amiga-style button
- return AgiTextColor(amigaWhite, amigaGreen);
- }
- } else { // _amigaStyle && !positive
- if (pressed) { // Negative pressed Amiga-style button
- return AgiTextColor(amigaBlack, amigaCyan);
- } else { // Negative unpressed Amiga-style button
- return AgiTextColor(amigaWhite, amigaRed);
- }
- }
- } else { // PC-style button
- if (hasFocus || pressed) { // A pressed or in focus PC-style button
- return AgiTextColor(pcWhite, pcBlack);
- } else { // An unpressed PC-style button without focus
- return AgiTextColor(pcBlack, pcWhite);
- }
- }
-}
-
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const {
- return getColor(hasFocus, pressed, AgiTextColor(baseFgColor, baseBgColor));
-}
-
-AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const {
- if (hasFocus || pressed)
- return baseColor.swap();
- else
- return baseColor;
-}
-
-int AgiButtonStyle::getTextOffset(bool hasFocus, bool pressed) const {
- return (pressed && !_amigaStyle) ? 1 : 0;
-}
-
-bool AgiButtonStyle::getBorder(bool hasFocus, bool pressed) const {
- return _amigaStyle && !_authenticAmiga && (hasFocus || pressed);
-}
-
-void AgiButtonStyle::setAmigaStyle(bool amigaStyle, bool olderAgi, bool authenticAmiga) {
- _amigaStyle = amigaStyle;
- _olderAgi = olderAgi;
- _authenticAmiga = authenticAmiga;
-}
-
-void AgiButtonStyle::setPcStyle(bool pcStyle) {
- setAmigaStyle(!pcStyle);
-}
-
-AgiButtonStyle::AgiButtonStyle(Common::RenderMode renderMode) {
- setAmigaStyle(renderMode == Common::kRenderAmiga);
-}
-
AgiBase::AgiBase(OSystem *syst, const AGIGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
_noSaveLoadAllowed = false;
@@ -671,7 +516,7 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
parseFeatures();
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "agi");
+ g_eventRec.registerRandomSource(*_rnd, "agi");
Common::addDebugChannel(kDebugLevelMain, "Main", "Generic debug level");
Common::addDebugChannel(kDebugLevelResources, "Resources", "Resources debugging");
@@ -718,6 +563,12 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas
_predictiveDictLine = NULL;
_predictiveDictLineCount = 0;
_firstSlot = 0;
+
+ // NOTE: On game reload the keys do not get set again,
+ // thus it is incorrect to reset it in agiInit(). Fixes bug #2823762
+ _game.lastController = 0;
+ for (int i = 0; i < MAX_DIRS; i++)
+ _game.controllerOccured[i] = false;
}
void AgiEngine::initialize() {
diff --git a/engines/agi/agi.h b/engines/agi/agi.h
index 14e1fd448b..ab572b0dd0 100644
--- a/engines/agi/agi.h
+++ b/engines/agi/agi.h
@@ -760,8 +760,6 @@ public:
void initVersion(void);
void setVersion(uint16 version);
- Common::Error loadGameState(int slot);
- Common::Error saveGameState(int slot, const char *desc);
bool canLoadGameStateCurrently();
bool canSaveGameStateCurrently();
};
@@ -785,6 +783,8 @@ public:
return _gameId;
}
+ Common::Error loadGameState(int slot);
+ Common::Error saveGameState(int slot, const char *desc);
private:
diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp
index bf4622bc08..d212f8c2e0 100644
--- a/engines/agi/cycle.cpp
+++ b/engines/agi/cycle.cpp
@@ -328,7 +328,7 @@ int AgiEngine::playGame() {
_game.vars[vKey] = 0;
debugC(2, kDebugLevelMain, "Entering main loop");
- bool firstLoop = true;
+ bool firstLoop = !getflag(fRestartGame); // Do not restore on game restart
do {
diff --git a/engines/agi/detection.cpp b/engines/agi/detection.cpp
index 910f6e0e55..553e42f88e 100644
--- a/engines/agi/detection.cpp
+++ b/engines/agi/detection.cpp
@@ -1290,20 +1290,6 @@ const ADGameDescription *AgiMetaEngine::fallbackDetect(const Common::FSList &fsl
namespace Agi {
-Common::Error AgiBase::loadGameState(int slot) {
- static char saveLoadSlot[12];
- sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
- loadGame(saveLoadSlot);
- return Common::kNoError; // TODO: return success/failure
-}
-
-Common::Error AgiBase::saveGameState(int slot, const char *desc) {
- static char saveLoadSlot[12];
- sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
- saveGame(saveLoadSlot, desc);
- return Common::kNoError; // TODO: return success/failure
-}
-
bool AgiBase::canLoadGameStateCurrently() {
return (!(getGameType() == GType_PreAGI) && getflag(fMenusWork) && !_noSaveLoadAllowed);
}
@@ -1312,4 +1298,19 @@ bool AgiBase::canSaveGameStateCurrently() {
return (!(getGameType() == GType_PreAGI) && getflag(fMenusWork) && !_noSaveLoadAllowed && _game.inputEnabled);
}
+int AgiEngine::agiDetectGame() {
+ int ec = errOK;
+
+ assert(_gameDescription != NULL);
+
+ if (getVersion() <= 0x2999) {
+ _loader = new AgiLoader_v2(this);
+ } else {
+ _loader = new AgiLoader_v3(this);
+ }
+ ec = _loader->detectGame();
+
+ return ec;
+}
+
} // End of namespace Agi
diff --git a/engines/agi/keyboard.cpp b/engines/agi/keyboard.cpp
index 6604587051..b47a39e592 100644
--- a/engines/agi/keyboard.cpp
+++ b/engines/agi/keyboard.cpp
@@ -393,6 +393,11 @@ int AgiEngine::waitKey() {
_gfx->doUpdate();
}
+
+ // Have to clear it as original did not set this variable, and we do it in doPollKeyboard()
+ // Fixes bug #2823759
+ _game.keypress = 0;
+
return key;
}
@@ -409,7 +414,33 @@ int AgiEngine::waitAnyKey() {
break;
_gfx->doUpdate();
}
+
+ // Have to clear it as original did not set this variable, and we do it in doPollKeyboard()
+ _game.keypress = 0;
+
return key;
}
+bool AgiEngine::isKeypress(void) {
+ processEvents();
+ return _keyQueueStart != _keyQueueEnd;
+}
+
+int AgiEngine::getKeypress(void) {
+ int k;
+
+ while (_keyQueueStart == _keyQueueEnd) // block
+ pollTimer();
+
+ keyDequeue(k);
+
+ return k;
+}
+
+void AgiEngine::clearKeyQueue(void) {
+ while (isKeypress()) {
+ getKeypress();
+ }
+}
+
} // End of namespace Agi
diff --git a/engines/agi/menu.cpp b/engines/agi/menu.cpp
index 27e234ebc9..5d30eda81d 100644
--- a/engines/agi/menu.cpp
+++ b/engines/agi/menu.cpp
@@ -493,4 +493,66 @@ void Menu::enableAll() {
}
}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, bool positive) const {
+ if (_amigaStyle) {
+ if (positive) {
+ if (pressed) { // Positive pressed Amiga-style button
+ if (_olderAgi) {
+ return AgiTextColor(amigaBlack, amigaOrange);
+ } else {
+ return AgiTextColor(amigaBlack, amigaPurple);
+ }
+ } else { // Positive unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaGreen);
+ }
+ } else { // _amigaStyle && !positive
+ if (pressed) { // Negative pressed Amiga-style button
+ return AgiTextColor(amigaBlack, amigaCyan);
+ } else { // Negative unpressed Amiga-style button
+ return AgiTextColor(amigaWhite, amigaRed);
+ }
+ }
+ } else { // PC-style button
+ if (hasFocus || pressed) { // A pressed or in focus PC-style button
+ return AgiTextColor(pcWhite, pcBlack);
+ } else { // An unpressed PC-style button without focus
+ return AgiTextColor(pcBlack, pcWhite);
+ }
+ }
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, int baseFgColor, int baseBgColor) const {
+ return getColor(hasFocus, pressed, AgiTextColor(baseFgColor, baseBgColor));
+}
+
+AgiTextColor AgiButtonStyle::getColor(bool hasFocus, bool pressed, const AgiTextColor &baseColor) const {
+ if (hasFocus || pressed)
+ return baseColor.swap();
+ else
+ return baseColor;
+}
+
+int AgiButtonStyle::getTextOffset(bool hasFocus, bool pressed) const {
+ return (pressed && !_amigaStyle) ? 1 : 0;
+}
+
+bool AgiButtonStyle::getBorder(bool hasFocus, bool pressed) const {
+ return _amigaStyle && !_authenticAmiga && (hasFocus || pressed);
+}
+
+void AgiButtonStyle::setAmigaStyle(bool amigaStyle, bool olderAgi, bool authenticAmiga) {
+ _amigaStyle = amigaStyle;
+ _olderAgi = olderAgi;
+ _authenticAmiga = authenticAmiga;
+}
+
+void AgiButtonStyle::setPcStyle(bool pcStyle) {
+ setAmigaStyle(!pcStyle);
+}
+
+AgiButtonStyle::AgiButtonStyle(Common::RenderMode renderMode) {
+ setAmigaStyle(renderMode == Common::kRenderAmiga);
+}
+
} // End of namespace Agi
diff --git a/engines/agi/preagi_mickey.cpp b/engines/agi/preagi_mickey.cpp
index e728f2f695..7a6608d0d0 100644
--- a/engines/agi/preagi_mickey.cpp
+++ b/engines/agi/preagi_mickey.cpp
@@ -1267,7 +1267,7 @@ void Mickey::pressOB(int iButton) {
}
// print pressed buttons
- printLine("MICKEY HAS PRESSED: ");
+ printLine("MICKEY HAS PRESSED: ");
_vm->drawStr(20, 22, IDA_DEFAULT, szButtons);
waitAnyKey();
}
diff --git a/engines/agi/saveload.cpp b/engines/agi/saveload.cpp
index 7c84f1dd72..50b329c0b6 100644
--- a/engines/agi/saveload.cpp
+++ b/engines/agi/saveload.cpp
@@ -32,6 +32,7 @@
#include "common/file.h"
#include "graphics/thumbnail.h"
+#include "common/config-manager.h"
#include "agi/agi.h"
#include "agi/graphics.h"
@@ -925,4 +926,85 @@ int AgiEngine::loadGameSimple() {
return rc;
}
+void AgiEngine::recordImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
+ int16 p4, int16 p5, int16 p6, int16 p7) {
+ ImageStackElement pnew;
+
+ pnew.type = type;
+ pnew.pad = 0;
+ pnew.parm1 = p1;
+ pnew.parm2 = p2;
+ pnew.parm3 = p3;
+ pnew.parm4 = p4;
+ pnew.parm5 = p5;
+ pnew.parm6 = p6;
+ pnew.parm7 = p7;
+
+ _imageStack.push(pnew);
+}
+
+void AgiEngine::replayImageStackCall(uint8 type, int16 p1, int16 p2, int16 p3,
+ int16 p4, int16 p5, int16 p6, int16 p7) {
+ switch (type) {
+ case ADD_PIC:
+ debugC(8, kDebugLevelMain, "--- decoding picture %d ---", p1);
+ agiLoadResource(rPICTURE, p1);
+ _picture->decodePicture(p1, p2, p3 != 0);
+ break;
+ case ADD_VIEW:
+ agiLoadResource(rVIEW, p1);
+ _sprites->addToPic(p1, p2, p3, p4, p5, p6, p7);
+ break;
+ }
+}
+
+void AgiEngine::clearImageStack(void) {
+ _imageStack.clear();
+}
+
+void AgiEngine::releaseImageStack(void) {
+ _imageStack.clear();
+}
+
+void AgiEngine::checkQuickLoad() {
+ if (ConfMan.hasKey("save_slot")) {
+ char saveNameBuffer[256];
+
+ snprintf (saveNameBuffer, 256, "%s.%03d", _targetName.c_str(), ConfMan.getInt("save_slot"));
+
+ _sprites->eraseBoth();
+ _sound->stopSound();
+
+ if (loadGame(saveNameBuffer, false) == errOK) { // Do not check game id
+ _game.exitAllLogics = 1;
+ _menu->enableAll();
+ }
+ }
+}
+
+Common::Error AgiEngine::loadGameState(int slot) {
+ static char saveLoadSlot[12];
+ sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
+
+ _sprites->eraseBoth();
+ _sound->stopSound();
+
+ if (loadGame(saveLoadSlot) == errOK) {
+ _game.exitAllLogics = 1;
+ _menu->enableAll();
+ return Common::kNoError;
+ } else {
+ return Common::kUnknownError;
+ }
+}
+
+Common::Error AgiEngine::saveGameState(int slot, const char *desc) {
+ static char saveLoadSlot[12];
+ sprintf(saveLoadSlot, "%s.%.3d", _targetName.c_str(), slot);
+ if (saveGame(saveLoadSlot, desc) == errOK)
+ return Common::kNoError;
+ else
+ return Common::kUnknownError;
+}
+
} // End of namespace Agi
diff --git a/engines/agi/sprite.cpp b/engines/agi/sprite.cpp
index f3c0b7365c..63ac880267 100644
--- a/engines/agi/sprite.cpp
+++ b/engines/agi/sprite.cpp
@@ -56,9 +56,10 @@ struct Sprite {
void *SpritesMgr::poolAlloc(int size) {
uint8 *x;
- // Adjust size to 32-bit boundary to prevent data misalignment
+ // Adjust size to sizeof(void *) boundary to prevent data misalignment
// errors.
- size = (size + 3) & ~3;
+ const int alignPadding = sizeof(void*) - 1;
+ size = (size + alignPadding) & ~alignPadding;
x = _poolTop;
_poolTop += size;
diff --git a/engines/agos/agos.cpp b/engines/agos/agos.cpp
index 9903952577..0e53698b59 100644
--- a/engines/agos/agos.cpp
+++ b/engines/agos/agos.cpp
@@ -27,6 +27,7 @@
#include "common/file.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "agos/debugger.h"
#include "agos/intern.h"
@@ -528,7 +529,7 @@ AGOSEngine::AGOSEngine(OSystem *syst)
File::addDefaultDirectory(_gameDataDir.getChild("speech"));
File::addDefaultDirectory(_gameDataDir.getChild("SPEECH"));
- syst->getEventManager()->registerRandomSource(_rnd, "agos");
+ g_eventRec.registerRandomSource(_rnd, "agos");
}
Common::Error AGOSEngine::init() {
diff --git a/engines/agos/agos.h b/engines/agos/agos.h
index 263811b78a..ac1f33428b 100644
--- a/engines/agos/agos.h
+++ b/engines/agos/agos.h
@@ -1248,6 +1248,7 @@ protected:
void hitarea_stuff_helper_2();
void fastFadeIn();
void slowFadeIn();
+ void fullFade();
virtual void vcStopAnimation(uint16 zone, uint16 sprite);
@@ -1265,20 +1266,6 @@ protected:
#ifdef ENABLE_PN
class AGOSEngine_PN : public AGOSEngine {
- struct StackFrame {
- StackFrame *nextframe;
- int16 flag[6];
- int16 param[8];
- int16 classnum;
- uint8 *linpos;
- uint8 *lbase;
- int16 ll;
- int16 linenum;
- int16 process;
- jmp_buf *savearea;
- StackFrame() { memset(this, 0, sizeof(*this)); }
- };
-
virtual Common::Error go();
void demoSeq();
@@ -1358,8 +1345,30 @@ public:
void opn_opcode62();
void opn_opcode63();
+protected:
+ struct StackFrame {
+ StackFrame *nextframe;
+ int16 flag[6];
+ int16 param[8];
+ int16 classnum;
+ uint8 *linpos;
+ uint8 *lbase;
+ int16 ll;
+ int16 linenum;
+ int16 process;
+ int tagOfParentDoline; ///< tag of the doline "instance" to which this StackFrame belongs
+ StackFrame() { memset(this, 0, sizeof(*this)); }
+ };
+
+
StackFrame *_stackbase;
+ int _tagOfActiveDoline; ///< tag of the active doline "instance"
+ int _dolineReturnVal;
+
+ jmp_buf _loadfail;
+
+
byte *_dataBase, *_textBase;
uint32 _dataBaseSize, _textBaseSize;
@@ -1404,8 +1413,6 @@ public:
int _linembr;
uint8 *_linebase;
uint8 *_workptr;
- jmp_buf *_cjmpbuff;
- jmp_buf _loadfail;
uint16 getptr(uint32 pos);
uint32 getlong(uint32 pos);
@@ -1429,7 +1436,6 @@ public:
void addstack(int type);
void dumpstack();
- void junkstack();
void popstack(int type);
void funccpy(int *store);
void funcentry(int *storestore, int procn);
@@ -1465,8 +1471,8 @@ public:
virtual void windowPutChar(WindowBlock *window, byte c, byte b = 0);
bool badload(int8 errorNum);
- int loadfl(char *name);
- int savfl(char *name);
+ int loadFile(char *name);
+ int saveFile(char *name);
void getFilename();
void sysftodb();
void dbtosysf();
diff --git a/engines/agos/debug.h b/engines/agos/debug.h
index 375878a4bc..38674de765 100644
--- a/engines/agos/debug.h
+++ b/engines/agos/debug.h
@@ -2549,7 +2549,7 @@ const char *const ww_videoOpcodeNameTable[] = {
"j|IF_EGA",
/* 60 */
"d|STOP_ANIMATE",
- "d|VC_61",
+ "d|INTRO",
"|FASTFADEOUT",
"|FASTFADEIN",
};
diff --git a/engines/agos/detection_tables.h b/engines/agos/detection_tables.h
index ec21acc0a1..0c672aef52 100644
--- a/engines/agos/detection_tables.h
+++ b/engines/agos/detection_tables.h
@@ -26,6 +26,8 @@
namespace AGOS {
using Common::GUIO_NONE;
+using Common::GUIO_NOMIDI;
+using Common::GUIO_NOMUSIC;
using Common::GUIO_NOSPEECH;
using Common::GUIO_NOSUBTITLES;
@@ -45,7 +47,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_PN,
@@ -68,7 +70,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_PN,
@@ -91,7 +93,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_PN,
@@ -137,7 +139,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -158,7 +160,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -179,7 +181,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -200,7 +202,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -223,7 +225,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -246,7 +248,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -269,7 +271,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA1,
@@ -410,7 +412,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -436,7 +438,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -462,7 +464,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -488,7 +490,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -514,7 +516,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -540,7 +542,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -566,7 +568,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAtariST,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_ELVIRA2,
@@ -802,7 +804,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_WW,
@@ -829,7 +831,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_WW,
@@ -992,7 +994,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAcorn,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1017,7 +1019,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAcorn,
ADGF_DEMO,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1042,7 +1044,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAcorn,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1066,7 +1068,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1090,7 +1092,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1114,7 +1116,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1138,7 +1140,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1162,7 +1164,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1186,7 +1188,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1210,7 +1212,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1234,7 +1236,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES | GUIO_NOMIDI
},
GType_SIMON1,
@@ -1523,7 +1525,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1548,7 +1550,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1573,7 +1575,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1598,7 +1600,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::RU_RUS,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1623,7 +1625,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1648,7 +1650,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1673,7 +1675,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::HB_ISR,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1698,7 +1700,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1724,7 +1726,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1749,7 +1751,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1774,7 +1776,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1799,7 +1801,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_SIMON1,
@@ -1824,7 +1826,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSPEECH
},
GType_SIMON2,
@@ -1949,7 +1951,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -1974,7 +1976,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -1999,7 +2001,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2024,7 +2026,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2049,7 +2051,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2074,7 +2076,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2099,7 +2101,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2124,7 +2126,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2175,7 +2177,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2200,7 +2202,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2225,7 +2227,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::CZ_CZE,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2250,7 +2252,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2275,7 +2277,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2300,7 +2302,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2325,7 +2327,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NONE
},
GType_SIMON2,
@@ -2346,7 +2348,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2367,7 +2369,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2391,7 +2393,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2415,7 +2417,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformAmiga,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2439,7 +2441,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2463,7 +2465,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2487,7 +2489,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2511,7 +2513,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformMacintosh,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2534,7 +2536,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2557,7 +2559,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::PL_POL,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2580,7 +2582,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2603,7 +2605,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2626,7 +2628,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2649,7 +2651,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2672,7 +2674,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_FF,
@@ -2693,7 +2695,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES | GUIO_NOMUSIC
},
GType_PP,
@@ -2714,7 +2716,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2735,7 +2737,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2756,7 +2758,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2777,7 +2779,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
@@ -2798,7 +2800,7 @@ static const AGOSGameDescription gameDescriptions[] = {
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_NO_FLAGS,
- GUIO_NONE
+ GUIO_NOSUBTITLES
},
GType_PP,
diff --git a/engines/agos/draw.cpp b/engines/agos/draw.cpp
index 45443aa335..368da5db83 100644
--- a/engines/agos/draw.cpp
+++ b/engines/agos/draw.cpp
@@ -871,13 +871,11 @@ void AGOSEngine::slowFadeIn() {
_fastFadeInFlag &= ~0x8000;
_paletteFlag = false;
- memset(_videoBuf1, 0, 1024);
- memcpy(_currentPalette, _displayPalette, 1024);
- memcpy(_videoBuf1 + 1024, _displayPalette, 1024);
+ memset(_currentPalette, 0, sizeof(_currentPalette));
for (c = 255; c >= 0; c -= 4) {
- src = _videoBuf1 + 1024;
- dst = _videoBuf1;
+ src = _displayPalette;
+ dst = _currentPalette;
for (p = _fastFadeInFlag; p !=0 ; p -= 3) {
if (src[0] >= c)
@@ -889,7 +887,7 @@ void AGOSEngine::slowFadeIn() {
src += 4;
dst += 4;
}
- _system->setPalette(_videoBuf1, 0, _fastFadeCount);
+ _system->setPalette(_currentPalette, 0, _fastFadeCount);
delay(5);
}
_fastFadeInFlag = 0;
diff --git a/engines/agos/input.cpp b/engines/agos/input.cpp
index cf6e808384..5c37fe620a 100644
--- a/engines/agos/input.cpp
+++ b/engines/agos/input.cpp
@@ -664,10 +664,11 @@ void AGOSEngine_PN::handleKeyboard() {
}
}
if (chr == -1) {
- chr = _keyPressed.ascii;
- if (chr == 8 || chr == 13) {
+ if (_keyPressed.keycode == Common::KEYCODE_BACKSPACE || _keyPressed.keycode == Common::KEYCODE_RETURN) {
+ chr = _keyPressed.keycode;
addChar(chr);
} else if (!(_videoLockOut & 0x10)) {
+ chr = _keyPressed.ascii;
if (chr >= 32)
addChar(chr);
}
diff --git a/engines/agos/midiparser_s1d.cpp b/engines/agos/midiparser_s1d.cpp
index d77621cc7b..568135ef8c 100644
--- a/engines/agos/midiparser_s1d.cpp
+++ b/engines/agos/midiparser_s1d.cpp
@@ -126,6 +126,10 @@ void MidiParser_S1D::parseNextEvent(EventInfo &info) {
switch (info.event & 0x0F) {
case 0x0:
// Trigged by MOD2/MOD6/MOD15 in Waxworks
+ // Pure guesswork
+ info.ext.type = *(_position._play_pos++);
+ info.length = readVLQ(_position._play_pos);
+ info.ext.data = _position._play_pos;
break;
case 0x3: // Not sure, Song Select?
diff --git a/engines/agos/pn.cpp b/engines/agos/pn.cpp
index d92efa9077..e8135f56cd 100644
--- a/engines/agos/pn.cpp
+++ b/engines/agos/pn.cpp
@@ -35,6 +35,10 @@ namespace AGOS {
AGOSEngine_PN::AGOSEngine_PN(OSystem *system)
: AGOSEngine(system) {
+ _stackbase = 0;
+ _tagOfActiveDoline = 0;
+ _dolineReturnVal = 0;
+
_dataBase = 0;
_dataBaseSize = 0;
_textBase = 0;
@@ -70,7 +74,7 @@ AGOSEngine_PN::AGOSEngine_PN(OSystem *system)
_objects = 0;
_objectCountS = 0;
- _bp = 0;
+ _bp = 0;
_xofs = 0;
_havinit = 0;
_seed = 0;
@@ -84,16 +88,12 @@ AGOSEngine_PN::AGOSEngine_PN(OSystem *system)
_linebase = 0;
_workptr = 0;
-
- _cjmpbuff = NULL;
}
AGOSEngine_PN::~AGOSEngine_PN() {
free(_dataBase);
free(_textBase);
- free(_cjmpbuff);
- free(_stackbase);
}
const byte egaPalette[48] = {
@@ -251,29 +251,33 @@ void AGOSEngine_PN::setupBoxes() {
}
void AGOSEngine_PN::processor() {
- int q;
-
setqptrs();
- q = setjmp(_loadfail);
- _variableArray[6] = 0;
+ _tagOfActiveDoline = 0;
+ int q = 0;
+ do {
+ assert(_tagOfActiveDoline == 0);
+ _dolineReturnVal = 0;
- if (getPlatform() == Common::kPlatformAtariST) {
- _variableArray[21] = 2;
- } else if (getPlatform() == Common::kPlatformAmiga) {
- _variableArray[21] = 0;
- } else {
- _variableArray[21] = 1;
- }
+ _variableArray[6] = 0;
+
+ if (getPlatform() == Common::kPlatformAtariST) {
+ _variableArray[21] = 2;
+ } else if (getPlatform() == Common::kPlatformAmiga) {
+ _variableArray[21] = 0;
+ } else {
+ _variableArray[21] = 1;
+ }
- _variableArray[16] = _quickshort[6];
- _variableArray[17] = _quickshort[7];
- _variableArray[19] = getptr(55L);
+ _variableArray[16] = _quickshort[6];
+ _variableArray[17] = _quickshort[7];
+ _variableArray[19] = getptr(55L);
- // q indicates the process to run and is 0 the first time,
- // but 1 later on (i.e., when we are "called" from badload()).
- setposition(q, 0);
- doline(0);
+ // q indicates the process to run and is 0 the first time,
+ // but 1 later on (i.e., when we are "called" from badload()).
+ setposition(0, 0);
+ q = doline(0);
+ } while (q);
}
void AGOSEngine_PN::setqptrs() {
diff --git a/engines/agos/res_snd.cpp b/engines/agos/res_snd.cpp
index e85440d8e1..4f3582b55d 100644
--- a/engines/agos/res_snd.cpp
+++ b/engines/agos/res_snd.cpp
@@ -285,10 +285,6 @@ void AGOSEngine_Simon1::playMusic(uint16 music, uint16 track) {
void AGOSEngine::playMusic(uint16 music, uint16 track) {
stopMusic();
- // FIXME: Music too unstable, when switching locations.
- if (getPlatform() == Common::kPlatformPC && getGameType() == GType_WW)
- return;
-
if (getPlatform() == Common::kPlatformAmiga) {
playModule(music);
} else if (getPlatform() == Common::kPlatformAtariST) {
diff --git a/engines/agos/saveload.cpp b/engines/agos/saveload.cpp
index 16bde0097b..3787617be7 100644
--- a/engines/agos/saveload.cpp
+++ b/engines/agos/saveload.cpp
@@ -23,8 +23,6 @@
*
*/
-
-
#include "common/savefile.h"
#include "common/system.h"
@@ -231,7 +229,7 @@ bool AGOSEngine::confirmOverWrite(WindowBlock *window) {
break;
case Common::DE_DEU:
message1 = "\rDatei existiert bereits.\r\r";
- message2 = " berschreiben ?\r\r";
+ message2 = " Ueberschreiben ?\r\r";
message3 = " Ja Nein";
break;
default:
@@ -1555,13 +1553,16 @@ bool AGOSEngine_Elvira2::saveGame(uint slot, const char *caption) {
bool AGOSEngine_PN::badload(int8 errorNum) {
if (errorNum == -2)
return 0;
- /* Load error recovery routine */
+ // Load error recovery routine
+
+ // Clear any stack
while (_stackbase != NULL) {
- /* Clear any stack */
dumpstack();
}
- /* Restart from process 1 */
- longjmp(_loadfail, 1);
+
+ // Restart from process 1
+ _tagOfActiveDoline = 1;
+ _dolineReturnVal = 3;
return 1;
}
@@ -1572,7 +1573,7 @@ void AGOSEngine_PN::getFilename() {
memset(_saveFile, 0, sizeof(_saveFile));
while (!shouldQuit() && !strlen(_saveFile)) {
const char *msg = "File name : ";
- pcf((unsigned char)'\n');
+ pcf((unsigned char)'\n');
while (*msg)
pcf((unsigned char)*msg++);
@@ -1582,7 +1583,7 @@ void AGOSEngine_PN::getFilename() {
}
}
-int AGOSEngine_PN::loadfl(char *name) {
+int AGOSEngine_PN::loadFile(char *name) {
Common::InSaveFile *f;
haltAnimation();
@@ -1609,13 +1610,13 @@ int AGOSEngine_PN::loadfl(char *name) {
delete f;
return -1;
}
- delete f;
+ delete f;
restartAnimation();
dbtosysf();
return 0;
}
-int AGOSEngine_PN::savfl(char *name) {
+int AGOSEngine_PN::saveFile(char *name) {
Common::OutSaveFile *f;
sysftodb();
haltAnimation();
@@ -1625,7 +1626,7 @@ int AGOSEngine_PN::savfl(char *name) {
restartAnimation();
const char *msg = "Couldn't save. ";
- pcf((unsigned char)'\n');
+ pcf((unsigned char)'\n');
while (*msg)
pcf((unsigned char)*msg++);
diff --git a/engines/agos/script_pn.cpp b/engines/agos/script_pn.cpp
index 4f9aab2965..2885781a9f 100644
--- a/engines/agos/script_pn.cpp
+++ b/engines/agos/script_pn.cpp
@@ -324,8 +324,8 @@ void AGOSEngine_PN::opn_opcode24() {
// That value then is returned to actCallD, which once again
// returns it. In the end, this amounts to a setScriptReturn(true)
// (but possibly in a different level than the current one).
- longjmp(*(_stackbase->savearea), 2);
- setScriptReturn(false);
+ _dolineReturnVal = 2;
+ _tagOfActiveDoline = _stackbase->tagOfParentDoline;
}
void AGOSEngine_PN::opn_opcode25() {
@@ -334,13 +334,13 @@ void AGOSEngine_PN::opn_opcode25() {
// That value then is returned to actCallD, which once again
// returns it. In the end, this amounts to a setScriptReturn(false)
// (but possibly in a different level than the current one).
- longjmp(*(_stackbase->savearea), 1);
- setScriptReturn(false);
+ _dolineReturnVal = 1;
+ _tagOfActiveDoline = _stackbase->tagOfParentDoline;
}
void AGOSEngine_PN::opn_opcode26() {
while ((_stackbase != NULL) && (_stackbase->classnum != kJmpClassNum))
- junkstack();
+ dumpstack();
dumpstack();
setScriptReturn(true);
}
@@ -353,16 +353,16 @@ void AGOSEngine_PN::opn_opcode27() {
void AGOSEngine_PN::opn_opcode28() {
addstack(varval());
- _stackbase->savearea = _cjmpbuff;
+ _stackbase->tagOfParentDoline = _tagOfActiveDoline;
setScriptReturn(false);
}
void AGOSEngine_PN::opn_opcode29() {
popstack(varval());
- // Jump back to the last doline indicated by the top stackfram.
+ // Jump back to the last doline indicated by the top stackframe.
// The -1 tells it to simply go on with its business.
- longjmp(*(_stackbase->savearea), -1);
- setScriptReturn(false);
+ _dolineReturnVal = -1;
+ _tagOfActiveDoline = _stackbase->tagOfParentDoline;
}
void AGOSEngine_PN::opn_opcode30() {
@@ -386,7 +386,7 @@ void AGOSEngine_PN::opn_opcode31() {
strcpy(bf, genSaveName(slot));
break;
case 1:
- strcpy(bf, "test.sav");
+ strcpy(bf, "pn.sav");
break;
case 2:
// NOTE: Is this case ever used?
@@ -397,7 +397,7 @@ void AGOSEngine_PN::opn_opcode31() {
if (slot == -1) {
setScriptReturn(false);
} else {
- a = loadfl(bf);
+ a = loadFile(bf);
if (a)
setScriptReturn(badload(a));
else
@@ -426,7 +426,7 @@ void AGOSEngine_PN::opn_opcode32() {
strcpy(bf, genSaveName(curSlot));
break;
case 1:
- strcpy(bf, "test.sav");
+ strcpy(bf, "pn.sav");
break;
case 2:
// NOTE: Is this case ever used?
@@ -434,7 +434,7 @@ void AGOSEngine_PN::opn_opcode32() {
break;
}
- a = savfl(bf);
+ a = saveFile(bf);
setScriptReturn(a);
}
@@ -520,19 +520,32 @@ void AGOSEngine_PN::opn_opcode39() {
}
void AGOSEngine_PN::opn_opcode40() {
- setScriptReturn(doaction() | doaction());
+ int a = doaction();
+ if (_dolineReturnVal != 0)
+ return;
+ int b = doaction();
+ setScriptReturn(a | b);
}
void AGOSEngine_PN::opn_opcode41() {
- setScriptReturn(doaction() & doaction());
+ int a = doaction();
+ if (_dolineReturnVal != 0)
+ return;
+ int b = doaction();
+ setScriptReturn(a & b);
}
void AGOSEngine_PN::opn_opcode42() {
- setScriptReturn(doaction() ^ doaction());
+ int a = doaction();
+ if (_dolineReturnVal != 0)
+ return;
+ int b = doaction();
+ setScriptReturn(a ^ b);
}
void AGOSEngine_PN::opn_opcode43() {
- setScriptReturn(!(doaction()));
+ int a = doaction();
+ setScriptReturn(!a);
}
void AGOSEngine_PN::opn_opcode44() {
@@ -874,41 +887,14 @@ int AGOSEngine_PN::doaction() {
}
int AGOSEngine_PN::doline(int needsave) {
- int x;
- jmp_buf *old_jmpbuf = NULL;
- jmp_buf *mybuf;
+ assert(!_stackbase == !needsave);
- mybuf = (jmp_buf *)malloc(sizeof(jmp_buf));
- if (mybuf == NULL)
- error("doline: Out of memory - stack overflow");
-
- x = setjmp(*mybuf);
- // Looking at the longjmp calls below, x can be -1, 1 or 2
- // (and of course 0 when it returns directly, as always).
- if (x > 0) {
- dumpstack();
- // Restore the active jmpbuf to its previous value,
- // then return the longjmp value (will be 2-1=1 or 1-1=0).
- _cjmpbuff = old_jmpbuf;
- free((char *)mybuf);
- return (x - 1);
- }
+ int x;
+ int myTag = ++_tagOfActiveDoline; // Obtain a unique tag for this doline invocation
+ _dolineReturnVal = 0;
- if (x == -1) {
- // Make this doline instance the active one (again).
- // This is used to "return" over possibly multiple
- // layers of nested script invocations.
- // Kind of like throwing an exception.
- _cjmpbuff = mybuf;
- goto carryon;
- }
-
- // Remember the previous active jmpbuf (gets restored
- // above when a longjmp with a positive param occurs).
- old_jmpbuf = _cjmpbuff;
- _cjmpbuff = mybuf;
if (needsave)
- _stackbase->savearea = mybuf;
+ _stackbase->tagOfParentDoline = myTag;
do {
_linct = ((*_linebase) & 127) - 1;
@@ -919,9 +905,26 @@ int AGOSEngine_PN::doline(int needsave) {
goto skipln;
}
-carryon:
do {
x = doaction();
+
+ if (_dolineReturnVal != 0) {
+ if (_tagOfActiveDoline != myTag)
+ return 0;
+
+ x = _dolineReturnVal;
+ _dolineReturnVal = 0;
+
+ if (x > 0) {
+ if (x != 3)
+ dumpstack();
+ // Restore the active jmpbuf to its previous value,
+ // then return _dolineReturnVal-1 (will be 2-1=1 or 1-1=0).
+ _tagOfActiveDoline = myTag - 1;
+ return (x - 1);
+ }
+ }
+
} while (x && !shouldQuit());
skipln:
@@ -1063,7 +1066,7 @@ void AGOSEngine_PN::addstack(int type) {
StackFrame *a;
int i;
- a = (StackFrame *)malloc(sizeof(StackFrame));
+ a = (StackFrame *)calloc(1, sizeof(StackFrame));
if (a == NULL)
error("addstack: Out of memory - stack overflow");
@@ -1093,24 +1096,13 @@ void AGOSEngine_PN::dumpstack() {
_stackbase = a;
}
-void AGOSEngine_PN::junkstack() {
- StackFrame *a;
-
- if (_stackbase == NULL)
- error("junkstack: Stack underflow or unknown longjmp");
-
- a = _stackbase->nextframe;
- if (_stackbase->classnum == kJmpClassNum)
- free((char *)_stackbase->savearea);
- free((char *)_stackbase);
- _stackbase = a;
-}
-
void AGOSEngine_PN::popstack(int type) {
- int i;
+ int i = 0;
- while ((_stackbase != NULL) && (_stackbase->classnum != type))
- junkstack();
+ while ((_stackbase != NULL) && (_stackbase->classnum != type)) {
+ dumpstack();
+ ++i;
+ }
if (_stackbase == NULL)
error("popstack: Stack underflow or unknown longjmp");
diff --git a/engines/agos/script_s1.cpp b/engines/agos/script_s1.cpp
index 2e3d936037..81efb5cd81 100644
--- a/engines/agos/script_s1.cpp
+++ b/engines/agos/script_s1.cpp
@@ -576,18 +576,15 @@ void AGOSEngine_Simon1::os1_specialFade() {
// 187: fade to black
uint i;
- memcpy(_videoBuf1, _currentPalette, 4 * 256);
-
for (i = 32; i != 0; --i) {
- paletteFadeOut(_videoBuf1, 32, 8);
- paletteFadeOut(_videoBuf1 + 4 * 48, 144, 8);
- paletteFadeOut(_videoBuf1 + 4 * 208, 48, 8);
- _system->setPalette(_videoBuf1, 0, 256);
+ paletteFadeOut(_currentPalette, 32, 8);
+ paletteFadeOut(_currentPalette + 4 * 48, 144, 8);
+ paletteFadeOut(_currentPalette + 4 * 208, 48, 8);
+ _system->setPalette(_currentPalette, 0, 256);
delay(5);
}
- memcpy(_currentPalette, _videoBuf1, 1024);
- memcpy(_displayPalette, _videoBuf1, 1024);
+ memcpy(_displayPalette, _currentPalette, 1024);
}
void AGOSEngine::scriptMouseOff() {
diff --git a/engines/agos/vga_e2.cpp b/engines/agos/vga_e2.cpp
index f6e6630d43..de3cb55963 100644
--- a/engines/agos/vga_e2.cpp
+++ b/engines/agos/vga_e2.cpp
@@ -353,9 +353,32 @@ void AGOSEngine::vc55_moveBox() {
_needHitAreaRecalc++;
}
-void AGOSEngine::vc56_fullScreen() {
- uint8 palette[1024];
+void AGOSEngine::fullFade() {
+ uint8 *srcPal, *dstPal;
+ int c, p;
+
+ for (c = 64; c != 0; c --) {
+ srcPal = _curVgaFile2 + 32;
+ dstPal = _currentPalette;
+ for (p = 768; p !=0 ; p -= 3) {
+ uint8 r = srcPal[0] * 4;
+ if (dstPal[0] != r)
+ dstPal[0] += 4;
+ uint8 g = srcPal[1] * 4;
+ if (dstPal[1] != g)
+ dstPal[1] += 4;
+ uint8 b = srcPal[2] * 4;
+ if (dstPal[2] != b)
+ dstPal[2] += 4;
+ srcPal += 3;
+ dstPal += 4;
+ }
+ _system->setPalette(_currentPalette, 0, 256);
+ delay(5);
+ }
+}
+void AGOSEngine::vc56_fullScreen() {
Graphics::Surface *screen = _system->lockScreen();
byte *dst = (byte *)screen->pixels;
byte *src = _curVgaFile2 + 800;
@@ -367,23 +390,12 @@ void AGOSEngine::vc56_fullScreen() {
}
_system->unlockScreen();
- //fullFade();
-
- src = _curVgaFile2 + 32;
- for (int i = 0; i < 256; i++) {
- palette[i * 4 + 0] = *src++ * 4;
- palette[i * 4 + 1] = *src++ * 4;
- palette[i * 4 + 2] = *src++ * 4;
- palette[i * 4 + 3] = 0;
- }
-
- _system->setPalette(palette, 0, 256);
+ fullFade();
}
void AGOSEngine::vc57_blackPalette() {
- uint8 palette[1024];
- memset(palette, 0, sizeof(palette));
- _system->setPalette(palette, 0, 256);
+ memset(_currentPalette, 0, sizeof(_currentPalette));
+ _system->setPalette(_currentPalette, 0, 256);
}
void AGOSEngine::vc58_checkCodeWheel() {
diff --git a/engines/agos/vga_ww.cpp b/engines/agos/vga_ww.cpp
index e7f2ad7807..afc05f7869 100644
--- a/engines/agos/vga_ww.cpp
+++ b/engines/agos/vga_ww.cpp
@@ -193,20 +193,8 @@ void AGOSEngine::vc61() {
_system->unlockScreen();
- if (a == 6) {
- //fullFade();
- src = _curVgaFile2 + 32;
-
- uint8 palette[1024];
- for (int i = 0; i < 256; i++) {
- palette[i * 4 + 0] = *src++ * 4;
- palette[i * 4 + 1] = *src++ * 4;
- palette[i * 4 + 2] = *src++ * 4;
- palette[i * 4 + 3] = 0;
- }
-
- _system->setPalette(palette, 0, 256);
- }
+ if (a == 6)
+ fullFade();
}
void AGOSEngine::vc62_fastFadeOut() {
@@ -221,8 +209,6 @@ void AGOSEngine::vc62_fastFadeOut() {
_fastFadeCount = 208;
}
- memcpy(_videoBuf1, _currentPalette, _fastFadeCount * 4);
-
if (getGameType() == GType_FF || getGameType() == GType_PP) {
if (getGameType() == GType_FF && getBitFlag(75)) {
fadeCount = 4;
@@ -237,8 +223,8 @@ void AGOSEngine::vc62_fastFadeOut() {
}
for (i = fadeCount; i != 0; --i) {
- paletteFadeOut(_videoBuf1, _fastFadeCount, fadeSize);
- _system->setPalette(_videoBuf1, 0, _fastFadeCount);
+ paletteFadeOut(_currentPalette, _fastFadeCount, fadeSize);
+ _system->setPalette(_currentPalette, 0, _fastFadeCount);
delay(5);
}
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 64a9a9dfb8..8756a2fc3c 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -64,7 +65,7 @@ CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Eng
g_cine = this;
- syst->getEventManager()->registerRandomSource(_rnd, "cine");
+ g_eventRec.registerRandomSource(_rnd, "cine");
}
CineEngine::~CineEngine() {
@@ -113,6 +114,9 @@ int CineEngine::modifyGameSpeed(int speedChange) {
}
void CineEngine::initialize() {
+ // Initialize all savegames' descriptions to empty strings
+ memset(currentSaveName, 0, sizeof(currentSaveName));
+
// Resize object table to its correct size and reset all its elements
objectTable.resize(NUM_MAX_OBJECT);
resetObjectTable();
diff --git a/engines/cine/detection.cpp b/engines/cine/detection.cpp
index 4786005647..3bc26ab417 100644
--- a/engines/cine/detection.cpp
+++ b/engines/cine/detection.cpp
@@ -607,35 +607,37 @@ SaveStateList CineMetaEngine::listSaves(const char *target) const {
pattern += ".?";
Common::StringList filenames = saveFileMan->listSavefiles(pattern);
sort(filenames.begin(), filenames.end());
- Common::StringList::const_iterator file = filenames.begin();
+ Common::StringList::const_iterator file;
Common::String filename = target;
filename += ".dir";
Common::InSaveFile *in = saveFileMan->openForLoading(filename);
if (in) {
- int8 ch;
- char saveDesc[20];
- do {
+ typedef char CommandeType[20];
+ CommandeType saveNames[10];
+
+ // Initialize all savegames' descriptions to empty strings
+ // so that if the savegames' descriptions can only be partially read from file
+ // then the missing ones are correctly set to empty strings.
+ memset(saveNames, 0, sizeof(saveNames));
+
+ in->read(saveNames, 10 * 20);
+ CommandeType saveDesc;
+
+ for (file = filenames.begin(); file != filenames.end(); ++file) {
+ // Jump over savegame files that don't end with a digit (e.g. "fw.3" is ok, "fw.a" is not).
+ if (!isdigit(file->lastChar()))
+ continue;
+
// Obtain the last digit of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 1);
- uint pos = 0;
- do {
- ch = in->readByte();
- if (pos < (sizeof(saveDesc) - 1)) {
- if (ch < 32 || in->eos()) {
- saveDesc[pos++] = '\0';
- }
- else if (ch >= 32) {
- saveDesc[pos++] = ch;
- }
- }
- } while (ch >= 32 && !in->eos());
- if (saveDesc[0] != 0) {
- saveList.push_back(SaveStateDescriptor(slotNum, saveDesc));
- file++;
- }
- } while (!in->eos());
+ // Copy the savegame description making sure it ends with a trailing zero
+ strncpy(saveDesc, saveNames[slotNum], 20);
+ saveDesc[sizeof(CommandeType) - 1] = 0;
+
+ saveList.push_back(SaveStateDescriptor(slotNum, saveDesc));
+ }
}
delete in;
@@ -650,6 +652,11 @@ void CineMetaEngine::removeSaveState(const char *target, int slot) const {
typedef char CommandeType[20];
CommandeType saveNames[10];
+ // Initialize all savegames' descriptions to empty strings
+ // so that if the savegames' descriptions can only be partially read from file
+ // then the missing ones are correctly set to empty strings.
+ memset(saveNames, 0, sizeof(saveNames));
+
Common::InSaveFile *in;
char tmp[80];
@@ -707,8 +714,9 @@ Common::Error CineEngine::saveGameState(int slot, const char *desc) {
// Load savegame descriptions from index file
loadSaveDirectory();
- // Set description for selected slot
+ // Set description for selected slot making sure it ends with a trailing zero
strncpy(currentSaveName[slot], desc, 20);
+ currentSaveName[slot][sizeof(CommandeType) - 1] = 0;
// Update savegame descriptions
char indexFile[80];
diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp
index b3e3629239..757419ef87 100644
--- a/engines/cine/pal.cpp
+++ b/engines/cine/pal.cpp
@@ -239,9 +239,6 @@ Palette &Palette::saturatedAddNormalizedGray(Palette& output, byte firstIndex, b
}
// a.k.a. transformColor
-// Parameter color components (i.e. r, g and b) are in range [-7, 7]
-// e.g. r = 7 sets the resulting color's red component to maximum
-// e.g. r = -7 sets the resulting color's red component to minimum (i.e. zero)
Cine::Palette::Color Palette::saturatedAddColor(Cine::Palette::Color baseColor, signed r, signed g, signed b) const {
Cine::Palette::Color result;
result.r = CLIP<int>(baseColor.r + r, 0, _format.rMax());
diff --git a/engines/cine/saveload.cpp b/engines/cine/saveload.cpp
index be1e19b229..158d209289 100644
--- a/engines/cine/saveload.cpp
+++ b/engines/cine/saveload.cpp
@@ -468,9 +468,18 @@ bool CineEngine::loadSaveDirectory(void) {
return false;
}
+ // Initialize all savegames' descriptions to empty strings
+ // so that if the savegames' descriptions can only be partially read from file
+ // then the missing ones are correctly set to empty strings.
+ memset(currentSaveName, 0, sizeof(currentSaveName));
+
fHandle->read(currentSaveName, 10 * 20);
delete fHandle;
+ // Make sure all savegames' descriptions end with a trailing zero.
+ for (int i = 0; i < ARRAYSIZE(currentSaveName); i++)
+ currentSaveName[i][sizeof(CommandeType) - 1] = 0;
+
return true;
}
diff --git a/engines/cruise/cruise.cpp b/engines/cruise/cruise.cpp
index 3d3a44a36c..7abf83f054 100644
--- a/engines/cruise/cruise.cpp
+++ b/engines/cruise/cruise.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/config-manager.h"
@@ -65,7 +66,7 @@ CruiseEngine::CruiseEngine(OSystem * syst, const CRUISEGameDescription *gameDesc
_debugger = new Debugger();
_sound = new PCSound(_mixer, this);
- syst->getEventManager()->registerRandomSource(_rnd, "cruise");
+ g_eventRec.registerRandomSource(_rnd, "cruise");
}
CruiseEngine::~CruiseEngine() {
diff --git a/engines/cruise/cruise_main.cpp b/engines/cruise/cruise_main.cpp
index e5864ebb31..94dfc95cb5 100644
--- a/engines/cruise/cruise_main.cpp
+++ b/engines/cruise/cruise_main.cpp
@@ -1390,7 +1390,7 @@ int CruiseEngine::processInput(void) {
}
// Player Menu - test for both buttons or the F10 key
- if (((button & MB_BOTH) == MB_BOTH) || (keyboardCode == Common::KEYCODE_F10)) {
+ if (((button & CRS_MB_BOTH) == CRS_MB_BOTH) || (keyboardCode == Common::KEYCODE_F10)) {
changeCursor(CURSOR_NORMAL);
keyboardCode = Common::KEYCODE_INVALID;
return (playerMenu(mouseX, mouseY));
@@ -1398,7 +1398,7 @@ int CruiseEngine::processInput(void) {
if (userWait) {
// Check for left mouse button click or Space to end user waiting
- if ((keyboardCode == Common::KEYCODE_SPACE) || (button == MB_LEFT))
+ if ((keyboardCode == Common::KEYCODE_SPACE) || (button == CRS_MB_LEFT))
userWait = 0;
keyboardCode = Common::KEYCODE_INVALID;
@@ -1450,7 +1450,7 @@ int CruiseEngine::processInput(void) {
menuDown = 0;
}
} else {
- if ((button & MB_LEFT) && (buttonDown == 0)) {
+ if ((button & CRS_MB_LEFT) && (buttonDown == 0)) {
if (menuTable[0]) {
callRelation(getSelectedEntryInMenu(menuTable[0]), dialogueObj);
@@ -1472,7 +1472,7 @@ int CruiseEngine::processInput(void) {
}
}
- } else if ((button & MB_LEFT) && (buttonDown == 0)) {
+ } else if ((button & CRS_MB_LEFT) && (buttonDown == 0)) {
// left click
buttonDown = 1;
@@ -1538,20 +1538,17 @@ int CruiseEngine::processInput(void) {
aniX = mouseX;
aniY = mouseY;
animationStart = true;
- buttonDown = 0;
}
} else {
aniX = mouseX;
aniY = mouseY;
animationStart = true;
- buttonDown = 0;
}
} else {
// No object found, we move the character to the cursor
aniX = mouseX;
aniY = mouseY;
animationStart = true;
- buttonDown = 0;
}
} else {
// handle click in menu
@@ -1590,7 +1587,7 @@ int CruiseEngine::processInput(void) {
}
}
}
- } else if ((button & MB_RIGHT) || (keyboardCode == Common::KEYCODE_F9)) {
+ } else if ((button & CRS_MB_RIGHT) || (keyboardCode == Common::KEYCODE_F9)) {
if (buttonDown == 0) {
keyboardCode = Common::KEYCODE_INVALID;
@@ -1628,29 +1625,28 @@ bool bFastMode = false;
bool manageEvents() {
Common::Event event;
- bool result = false;
Common::EventManager * eventMan = g_system->getEventManager();
- while (eventMan->pollEvent(event) && !result) {
- result = true;
+ while (eventMan->pollEvent(event)) {
+ bool abortFlag = true;
switch (event.type) {
case Common::EVENT_LBUTTONDOWN:
- currentMouseButton |= MB_LEFT;
+ currentMouseButton |= CRS_MB_LEFT;
break;
case Common::EVENT_LBUTTONUP:
- currentMouseButton &= ~MB_LEFT;
+ currentMouseButton &= ~CRS_MB_LEFT;
break;
case Common::EVENT_RBUTTONDOWN:
- currentMouseButton |= MB_RIGHT;
+ currentMouseButton |= CRS_MB_RIGHT;
break;
case Common::EVENT_RBUTTONUP:
- currentMouseButton &= ~MB_RIGHT;
+ currentMouseButton &= ~CRS_MB_RIGHT;
break;
case Common::EVENT_MOUSEMOVE:
currentMouseX = event.mouse.x;
currentMouseY = event.mouse.y;
- result = false;
+ abortFlag = false;
break;
case Common::EVENT_QUIT:
case Common::EVENT_RTL:
@@ -1659,7 +1655,7 @@ bool manageEvents() {
case Common::EVENT_KEYUP:
switch (event.kbd.keycode) {
case Common::KEYCODE_ESCAPE:
- currentMouseButton &= ~MB_MIDDLE;
+ currentMouseButton &= ~CRS_MB_MIDDLE;
break;
default:
break;
@@ -1668,7 +1664,7 @@ bool manageEvents() {
case Common::EVENT_KEYDOWN:
switch (event.kbd.keycode) {
case Common::KEYCODE_ESCAPE:
- currentMouseButton |= MB_MIDDLE;
+ currentMouseButton |= CRS_MB_MIDDLE;
break;
default:
keyboardCode = event.kbd.keycode;
@@ -1689,9 +1685,12 @@ bool manageEvents() {
default:
break;
}
+
+ if (abortFlag)
+ return true;
}
- return result;
+ return false;
}
void getMouseStatus(int16 *pMouseVar, int16 *pMouseX, int16 *pMouseButton, int16 *pMouseY) {
@@ -1798,6 +1797,9 @@ void CruiseEngine::mainLoop(void) {
// User waiting has ended
changeScriptParamInList(-1, -1, &procHead, 9999, 0);
changeScriptParamInList(-1, -1, &relHead, 9999, 0);
+
+ // Disable any mouse click used to end the user wait
+ currentMouseButton = 0;
}
manageScripts(&relHead);
@@ -1899,8 +1901,6 @@ void CruiseEngine::mainLoop(void) {
g_system->updateScreen();
}
- manageEvents();
-
} while (!playerDontAskQuit && quitValue2 && quitValue != 7);
}
diff --git a/engines/cruise/cruise_main.h b/engines/cruise/cruise_main.h
index d2e9350d70..5f4d5c5c13 100644
--- a/engines/cruise/cruise_main.h
+++ b/engines/cruise/cruise_main.h
@@ -56,10 +56,10 @@
namespace Cruise {
enum MouseButton {
- MB_LEFT = 1,
- MB_RIGHT = 2,
- MB_MIDDLE = 4,
- MB_BOTH = MB_LEFT | MB_RIGHT
+ CRS_MB_LEFT = 1,
+ CRS_MB_RIGHT = 2,
+ CRS_MB_MIDDLE = 4,
+ CRS_MB_BOTH = CRS_MB_LEFT | CRS_MB_RIGHT
};
/*#define DUMP_SCRIPT
diff --git a/engines/cruise/dataLoader.cpp b/engines/cruise/dataLoader.cpp
index 3cf3957703..1202d06fbc 100644
--- a/engines/cruise/dataLoader.cpp
+++ b/engines/cruise/dataLoader.cpp
@@ -382,7 +382,7 @@ int loadFNTSub(uint8 *ptr, int destIdx) {
currentPtr = destPtr + 14;
- for (i = 0; i < *(int16 *)(destPtr + 8); i++) {
+ for (i = 0; i < (int16)READ_UINT16(destPtr + 8); i++) {
bigEndianLongToNative((int32 *) currentPtr);
currentPtr += 4;
diff --git a/engines/cruise/linker.cpp b/engines/cruise/linker.cpp
index bb6f682e1e..2d14d46ce3 100644
--- a/engines/cruise/linker.cpp
+++ b/engines/cruise/linker.cpp
@@ -23,6 +23,7 @@
*
*/
+#include "common/endian.h"
#include "cruise/cruise_main.h"
namespace Cruise {
@@ -182,9 +183,7 @@ int updateScriptImport(int ovlIdx) {
uint8 *ptr = ptrData + temp;
*(ptr + 1) = out2;
- *(int16 *)(ptr + 2) = ptrDest2->idx;
-
- bigEndianShortToNative((int16 *)(ptr + 2));
+ WRITE_BE_UINT16(ptr + 2, ptrDest2->idx);
} else {
if (param2 == 20 || param2 == 30 || param2 == 40 || param2 == 50) { // this patch a double push
uint8 *ptr = ptrData + temp;
@@ -192,9 +191,7 @@ int updateScriptImport(int ovlIdx) {
*(ptr + 1) = 0;
*(ptr + 2) = out2; // update the overlay number
- *(int16 *)(ptr + 4) = ptrDest2->idx;
-
- bigEndianShortToNative((int16 *)(ptr + 4));
+ WRITE_BE_UINT16(ptr + 4, ptrDest2->idx);
} else {
int var_4 = ptrDest2->var4;
@@ -213,17 +210,7 @@ int updateScriptImport(int ovlIdx) {
*(ptrData + temp) = param2;
*(ptrData + temp + 1) = out2;
- *(int16 *)(ptrData + temp + 2) = ptrDest2->idx;
-
- bigEndianShortToNative
- (
- (int16
- *)
- (ptrData
- +
- temp
- +
- 2));
+ WRITE_BE_UINT16(ptrData + temp + 2, ptrDest2->idx);
}
}
}
diff --git a/engines/cruise/mainDraw.cpp b/engines/cruise/mainDraw.cpp
index 2932e6dc7d..047f00ee90 100644
--- a/engines/cruise/mainDraw.cpp
+++ b/engines/cruise/mainDraw.cpp
@@ -206,10 +206,34 @@ int m_first_Y;
int m_scaleValue;
int m_color;
-int16 DIST_3D[512];
-int16 polyBuffer2[512];
-int16 XMIN_XMAX[404];
-int16 polyBuffer4[512];
+/*
+ FIXME: Whether intentional or not, the game often seems to use negative indexing
+ of one or more of the arrays below and expects(?) to end up in the preceding one.
+ This "worked" on many platforms so far, but on OSX apparently the buffers don't
+ occupy contiguous memory, and this causes severe corruption and subsequent crashes.
+ Since I'm not really familiar with how the strange drawing code is supposed to work,
+ or whether this behaviour is intentional or not, the short-term fix is to allocate a big
+ buffer and setup pointers within it. This fixes the crashes I'm seeing without causing any
+ (visual) side-effects.
+ If anyone wants to look, this is easily reproduced by starting the game and examining the rug.
+ drawPolyMode1() will then (indirectly) negatively index polyBuffer4. Good luck!
+*/
+
+//int16 DIST_3D[512];
+//int16 polyBuffer2[512];
+//int16 XMIN_XMAX[404];
+//int16 polyBuffer4[512];
+
+int16 bigPolyBuf[512 + 512 + 404 + 512]; /* consolidates the 4 separate buffers above */
+
+//set up the replacement index pointers.
+int16 *DIST_3D = &bigPolyBuf[0];
+int16 *polyBuffer2 = &bigPolyBuf[512];
+int16 *XMIN_XMAX = &bigPolyBuf[512 + 512];
+int16 *polyBuffer4 = &bigPolyBuf[512 + 512 + 404];
+
+
+
// this function fills the sizeTable for the poly (OLD: mainDrawSub1Sub2)
void getPolySize(int positionX, int positionY, int scale, int sizeTable[4], unsigned char *dataPtr) {
diff --git a/engines/cruise/mainDraw.h b/engines/cruise/mainDraw.h
index dc988b551d..620ac6e4d7 100644
--- a/engines/cruise/mainDraw.h
+++ b/engines/cruise/mainDraw.h
@@ -29,8 +29,8 @@
namespace Cruise {
extern int currentTransparent;
-extern int16 polyBuffer2[512];
-extern int16 XMIN_XMAX[404];
+extern int16 *polyBuffer2;
+extern int16 *XMIN_XMAX;
extern int m_color;
int upscaleValue(int value, int scale);
diff --git a/engines/cruise/menu.cpp b/engines/cruise/menu.cpp
index 54f686f32a..7e454e78f8 100644
--- a/engines/cruise/menu.cpp
+++ b/engines/cruise/menu.cpp
@@ -179,6 +179,7 @@ int processMenu(menuStruct *pMenu) {
flipScreen();
manageEvents();
+ g_system->delayMillis(10);
// readKeyboard();
} while (!si);
diff --git a/engines/cruise/script.cpp b/engines/cruise/script.cpp
index 9f89f04069..761bba3673 100644
--- a/engines/cruise/script.cpp
+++ b/engines/cruise/script.cpp
@@ -23,6 +23,7 @@
*
*/
+#include "cruise/cruise.h"
#include "cruise/cruise_main.h"
#include "common/endian.h"
@@ -632,7 +633,11 @@ int executeScripts(scriptInstanceStruct *ptr) {
#endif
opcodeType = getByteFromScript();
- // printf("opType: %d\n",(opcodeType&0xFB)>>3);
+ debugC(5, kCruiseDebugScript, "Script %s/%d ip=%d opcode=%d",
+ overlayTable[currentScriptPtr->overlayNumber].overlayName,
+ currentScriptPtr->scriptNumber,
+ currentScriptPtr->scriptOffset,
+ (opcodeType & 0xFB) >> 3);
currentScriptOpcodeType = opcodeType & 7;
diff --git a/engines/cruise/sound.cpp b/engines/cruise/sound.cpp
index 92c2ac6256..7ca4246785 100644
--- a/engines/cruise/sound.cpp
+++ b/engines/cruise/sound.cpp
@@ -766,6 +766,10 @@ void PCSoundFxPlayer::doSync(Common::Serializer &s) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
_instrumentsChannelTable[i] = -1;
}
+
+ _numOrders = _sfxData[470];
+ _eventsDelay = (244 - _sfxData[471]) * 100 / 1060;
+ _updateTicksCounter = 0;
}
s.syncAsSint16LE(_songPlayed);
diff --git a/engines/cruise/staticres.cpp b/engines/cruise/staticres.cpp
index d49d12c05b..595ac5a38b 100644
--- a/engines/cruise/staticres.cpp
+++ b/engines/cruise/staticres.cpp
@@ -168,6 +168,59 @@ int16 german_fontCharacterTable[256] = {
-1, -1, -1, -1
};
+int16 spanish_fontCharacterTable[256] = {
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1,
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43,
+ 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85,
+ 86, 87, 88, 89, 90, 91, 92,
+ -1, -1, -1,
+ 0x72, 0x80
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 0x7f, 0x79, 0x7b, 0x81, 0x82, 0x83,
+ -1, -1,
+ 0x7d,
+ -1, -1, -1, -1,
+ 0x7E,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1,
+ 0x6A, 0x69,
+ -1, -1, -1, -1,
+ 0x6B, 0x6C,
+ -1, -1,
+ 0x6D, 0x6E,
+ -1, -1, -1, -1, -1, -1,
+ 0x6F,
+ -1,
+ 0x70,
+ -1, -1,
+ 0x71, 0x72,
+ -1, -1,
+ 0x74, 0x5D,
+ -1,
+ 0x76,
+ -1,
+ 0x5E,
+ -1,
+ 0x75, 0x73, 0x60, 0x5F, 0x61, 0x62, 0x79, 0x78, 0x63, 0x64,
+ -1, -1,
+ 0x7B, 0x7A,
+ 0x65,
+ -1,
+ 0x66,
+ -1, -1,
+ 0x67,
+ -1,
+ 0x68,
+ -1, -1, -1, -1
+};
+
//
// Mouse data
//
diff --git a/engines/cruise/staticres.h b/engines/cruise/staticres.h
index ef9a1b47e9..964bf294dc 100644
--- a/engines/cruise/staticres.h
+++ b/engines/cruise/staticres.h
@@ -41,9 +41,11 @@ extern int actor_invstat[][13];
extern short int english_fontCharacterTable[256];
extern short int german_fontCharacterTable[256];
+extern short int spanish_fontCharacterTable[256];
#define fontCharacterTable (_vm->getLanguage() == Common::DE_DEU ? \
- german_fontCharacterTable : english_fontCharacterTable)
+ german_fontCharacterTable : (_vm->getLanguage() == Common::ES_ESP ? \
+ spanish_fontCharacterTable : english_fontCharacterTable))
// Mouse cursor data
extern const byte mouseCursorNormal[];
diff --git a/engines/drascula/converse.cpp b/engines/drascula/converse.cpp
index 4aa8ee0d9e..006f16ab45 100644
--- a/engines/drascula/converse.cpp
+++ b/engines/drascula/converse.cpp
@@ -141,8 +141,9 @@ void DrasculaEngine::converse(int index) {
int game1 = kDialogOptionUnselected,
game2 = kDialogOptionUnselected,
game3 = kDialogOptionUnselected;
- char phrase1[78], phrase2[78], phrase3[78], phrase4[78];
+ char phrase1[128], phrase2[128], phrase3[128], phrase4[128];
char sound1[13], sound2[13], sound3[13], sound4[13];
+ int phrase1_bottom, phrase2_bottom, phrase3_bottom, phrase4_bottom;
int answer1, answer2, answer3;
char buffer[256];
@@ -207,12 +208,12 @@ void DrasculaEngine::converse(int index) {
updateEvents();
- print_abc_opc(phrase1, 2, game1);
- print_abc_opc(phrase2, 10, game2);
- print_abc_opc(phrase3, 18, game3);
- print_abc_opc(phrase4, 26, kDialogOptionUnselected);
+ phrase1_bottom = 8 * print_abc_opc(phrase1, 2, game1);
+ phrase2_bottom = phrase1_bottom + 8 * print_abc_opc(phrase2, phrase1_bottom + 2, game2);
+ phrase3_bottom = phrase2_bottom + 8 * print_abc_opc(phrase3, phrase2_bottom + 2, game3);
+ phrase4_bottom = phrase3_bottom + 8 * print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionUnselected);
- if (mouseY > 0 && mouseY < 9) {
+ if (mouseY > 0 && mouseY < phrase1_bottom) {
if (game1 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game1 != kDialogOptionClicked && _color != kColorLightGreen)
@@ -226,13 +227,13 @@ void DrasculaEngine::converse(int index) {
talk(phrase1, sound1);
response(answer1);
}
- } else if (mouseY > 8 && mouseY < 17) {
+ } else if (mouseY > phrase1_bottom && mouseY < phrase2_bottom) {
if (game2 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game2 != kDialogOptionClicked && _color != kColorLightGreen)
color_abc(kColorLightGreen);
- print_abc_opc(phrase2, 10, kDialogOptionSelected);
+ print_abc_opc(phrase2, phrase1_bottom + 2, kDialogOptionSelected);
if (leftMouseButton == 1) {
delay(100);
@@ -240,13 +241,13 @@ void DrasculaEngine::converse(int index) {
talk(phrase2, sound2);
response(answer2);
}
- } else if (mouseY > 16 && mouseY < 25) {
+ } else if (mouseY > phrase2_bottom && mouseY < phrase3_bottom) {
if (game3 == kDialogOptionClicked && _color != kColorWhite)
color_abc(kColorWhite);
else if (game3 != kDialogOptionClicked && _color != kColorLightGreen)
color_abc(kColorLightGreen);
- print_abc_opc(phrase3, 18, kDialogOptionSelected);
+ print_abc_opc(phrase3, phrase2_bottom + 2, kDialogOptionSelected);
if (leftMouseButton == 1) {
delay(100);
@@ -254,8 +255,8 @@ void DrasculaEngine::converse(int index) {
talk(phrase3, sound3);
response(answer3);
}
- } else if (mouseY > 24 && mouseY < 33) {
- print_abc_opc(phrase4, 26, kDialogOptionSelected);
+ } else if (mouseY > phrase3_bottom && mouseY < phrase4_bottom) {
+ print_abc_opc(phrase4, phrase3_bottom + 2, kDialogOptionSelected);
if (leftMouseButton == 1) {
delay(100);
@@ -265,6 +266,7 @@ void DrasculaEngine::converse(int index) {
} else if (_color != kColorLightGreen)
color_abc(kColorLightGreen);
+ _system->delayMillis(10);
updateScreen();
} // while (breakOut == 0)
diff --git a/engines/drascula/drascula.cpp b/engines/drascula/drascula.cpp
index a3c56be1f4..2e3db3478e 100644
--- a/engines/drascula/drascula.cpp
+++ b/engines/drascula/drascula.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/keyboard.h"
#include "common/file.h"
#include "common/savefile.h"
@@ -92,7 +93,7 @@ DrasculaEngine::DrasculaEngine(OSystem *syst, const DrasculaGameDescription *gam
*textName = 0;
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "drascula");
+ g_eventRec.registerRandomSource(*_rnd, "drascula");
int cd_num = ConfMan.getInt("cdrom");
if (cd_num >= 0)
@@ -181,10 +182,6 @@ Common::Error DrasculaEngine::run() {
for (;;) {
int i;
-
- VGA = (byte *)malloc(320 * 200);
- memset(VGA, 0, 64000);
-
takeObject = 0;
_menuBar = false;
_menuScreen = false;
@@ -295,7 +292,6 @@ void DrasculaEngine::endChapter() {
MusicFadeout();
stopMusic();
freeMemory();
- free(VGA);
}
bool DrasculaEngine::runCurrentChapter() {
@@ -716,7 +712,8 @@ bool DrasculaEngine::verify2() {
Common::KeyCode DrasculaEngine::getScan() {
updateEvents();
- if (_keyBufferHead == _keyBufferTail) return Common::KEYCODE_INVALID;
+ if (_keyBufferHead == _keyBufferTail)
+ return Common::KEYCODE_INVALID;
Common::KeyCode key = _keyBuffer[_keyBufferTail].keycode;
_keyBufferTail = (_keyBufferTail + 1) % KEYBUFSIZE;
diff --git a/engines/drascula/drascula.h b/engines/drascula/drascula.h
index b06a2c9d4b..85f31ea2d1 100644
--- a/engines/drascula/drascula.h
+++ b/engines/drascula/drascula.h
@@ -344,7 +344,6 @@ public:
byte *mouseCursor;
// Graphics buffers/pointers
- byte *VGA;
byte *bgSurface;
byte *backSurface;
byte *drawSurface3;
@@ -353,7 +352,6 @@ public:
byte *extraSurface; // not sure about this one, was "dir_hare_dch"
byte *screenSurface;
byte *frontSurface;
- byte *textSurface;
byte *memPtr;
byte *mSession;
@@ -564,7 +562,7 @@ public:
void playTalkSequence(int sequence);
void doTalkSequenceCommand(TalkSequenceCommand cmd);
void converse(int);
- void print_abc_opc(const char *, int, int);
+ int print_abc_opc(const char *, int, int);
void response(int);
void activatePendulum();
diff --git a/engines/drascula/graphics.cpp b/engines/drascula/graphics.cpp
index 76a551c980..74b9e131e3 100644
--- a/engines/drascula/graphics.cpp
+++ b/engines/drascula/graphics.cpp
@@ -24,6 +24,7 @@
*/
#include "drascula/drascula.h"
+#include "graphics/surface.h"
namespace Drascula {
@@ -47,7 +48,7 @@ void DrasculaEngine::allocMemory() {
assert(tableSurface);
extraSurface = (byte *)malloc(64000);
assert(extraSurface);
- crosshairCursor = (byte *)malloc(40 * 25);
+ crosshairCursor = (byte *)malloc(OBJWIDTH * OBJHEIGHT);
assert(crosshairCursor);
mouseCursor = (byte *)malloc(OBJWIDTH * OBJHEIGHT);
assert(mouseCursor);
@@ -126,16 +127,18 @@ void DrasculaEngine::showFrame(bool firstFrame) {
}
byte *prevFrame = (byte *)malloc(64000);
- memcpy(prevFrame, VGA, 64000);
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
+ memcpy(prevFrame, screenBuffer, 64000);
- decodeRLE(pcxData, VGA);
+ decodeRLE(pcxData, screenBuffer);
free(pcxData);
if (!firstFrame)
- mixVideo(VGA, prevFrame);
+ mixVideo(screenBuffer, prevFrame);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ _system->unlockScreen();
_system->updateScreen();
+
if (firstFrame)
setPalette(cPal);
@@ -192,8 +195,9 @@ void DrasculaEngine::copyRect(int xorg, int yorg, int xdes, int ydes, int width,
}
void DrasculaEngine::updateScreen(int xorg, int yorg, int xdes, int ydes, int width, int height, byte *buffer) {
- copyBackground(xorg, yorg, xdes, ydes, width, height, buffer, VGA);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
+ copyBackground(xorg, yorg, xdes, ydes, width, height, buffer, screenBuffer);
+ _system->unlockScreen();
_system->updateScreen();
}
@@ -235,13 +239,30 @@ void DrasculaEngine::print_abc(const char *said, int screenX, int screenY) {
} // for
}
-void DrasculaEngine::print_abc_opc(const char *said, int screenY, int game) {
+int DrasculaEngine::print_abc_opc(const char *said, int screenY, int game) {
int signY, letterY, letterX = 0;
uint len = strlen(said);
int screenX = 1;
+ int lines = 1;
for (uint h = 0; h < len; h++) {
+ int wordLength;
+
+ // Look ahead to the end of the word.
+ wordLength = 0;
+ int pos = h;
+ while (said[pos] && said[pos] != ' ') {
+ wordLength++;
+ pos++;
+ }
+
+ if (screenX + wordLength * CHAR_WIDTH_OPC > 317) {
+ screenX = 0;
+ screenY += (CHAR_HEIGHT + 2);
+ lines++;
+ }
+
if (game == 1) {
letterY = 6;
signY = 15;
@@ -281,6 +302,8 @@ void DrasculaEngine::print_abc_opc(const char *said, int screenY, int game) {
screenX = screenX + CHAR_WIDTH_OPC;
}
+
+ return lines;
}
bool DrasculaEngine::textFitsCentered(char *text, int x) {
@@ -402,6 +425,7 @@ void DrasculaEngine::screenSaver() {
int x1_, y1_, off1, off2;
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
for (int i = 0; i < 200; i++) {
for (int j = 0; j < 320; j++) {
x1_ = j + tempRow[i];
@@ -419,10 +443,11 @@ void DrasculaEngine::screenSaver() {
y1_ = checkWrapY(y1_);
off2 = 320 * y1_ + x1_;
- VGA[320 * i + j] = ghost[bgSurface[off2] + (copia[off1] << 8)];
+ screenBuffer[320 * i + j] = ghost[bgSurface[off2] + (copia[off1] << 8)];
}
}
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+
+ _system->unlockScreen();
_system->updateScreen();
_system->delayMillis(20);
@@ -515,11 +540,14 @@ int DrasculaEngine::playFrameSSN() {
decodeRLE(BufferSSN, screenSurface);
free(BufferSSN);
waitFrameSSN();
+
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
if (FrameSSN)
- mixVideo(VGA, screenSurface);
+ mixVideo(screenBuffer, screenSurface);
else
- memcpy(VGA, screenSurface, 64000);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ memcpy(screenBuffer, screenSurface, 64000);
+
+ _system->unlockScreen();
_system->updateScreen();
FrameSSN++;
} else {
@@ -534,11 +562,13 @@ int DrasculaEngine::playFrameSSN() {
decodeOffset(BufferSSN, screenSurface, length);
free(BufferSSN);
waitFrameSSN();
+ byte *screenBuffer = (byte *)_system->lockScreen()->pixels;
if (FrameSSN)
- mixVideo(VGA, screenSurface);
+ mixVideo(screenBuffer, screenSurface);
else
- memcpy(VGA, screenSurface, 64000);
- _system->copyRectToScreen((const byte *)VGA, 320, 0, 0, 320, 200);
+ memcpy(screenBuffer, screenSurface, 64000);
+
+ _system->unlockScreen();
_system->updateScreen();
FrameSSN++;
}
diff --git a/engines/drascula/rooms.cpp b/engines/drascula/rooms.cpp
index 8284112c1e..c9912f25d2 100644
--- a/engines/drascula/rooms.cpp
+++ b/engines/drascula/rooms.cpp
@@ -1866,69 +1866,68 @@ void DrasculaEngine::enterRoom(int roomIndex) {
}
void DrasculaEngine::clearRoom() {
- memset(VGA, 0, 64000);
_system->fillScreen(0);
_system->updateScreen();
}
-bool DrasculaEngine::exitRoom(int l) {
- debug(2, "Exiting room from door %d", l);
+bool DrasculaEngine::exitRoom(int doorNumber) {
+ debug(2, "Exiting room from door %d", doorNumber);
int roomNum = 0;
// Player can't exit the inn in chapter 1
- if (currentChapter == 1 && objectNum[l] == 104) {
+ if (currentChapter == 1 && objectNum[doorNumber] == 104) {
return false;
}
- if (currentChapter == 1 && objectNum[l] == 105 && flags[0] == 0) {
+ if (currentChapter == 1 && objectNum[doorNumber] == 105 && flags[0] == 0) {
talk(442);
return false;
}
- updateDoor(l);
- if (isDoor[l] != 0 &&
- ((currentChapter != 3 && currentChapter != 5) || visible[l] == 1)) {
+ updateDoor(doorNumber);
+ if (isDoor[doorNumber] != 0 &&
+ ((currentChapter != 3 && currentChapter != 5) || visible[doorNumber] == 1)) {
hideCursor();
- gotoObject(roomObjX[l], roomObjY[l]);
+ gotoObject(roomObjX[doorNumber], roomObjY[doorNumber]);
if (currentChapter != 2) {
- trackProtagonist = trackObj[l];
+ trackProtagonist = trackObj[doorNumber];
updateRoom();
updateScreen();
}
characterMoved = 0;
- trackProtagonist = trackCharacter_alkeva[l];
- objExit = roomExits[l];
+ trackProtagonist = trackCharacter_alkeva[doorNumber];
+ objExit = roomExits[doorNumber];
doBreak = 1;
previousMusic = roomMusic;
// Object specific actions
- if (currentChapter == 1 && objectNum[l] == 105) {
+ if (currentChapter == 1 && objectNum[doorNumber] == 105) {
animation_2_1();
return true;
} else if (currentChapter == 2) {
- if (objectNum[l] == 136)
+ if (objectNum[doorNumber] == 136)
animation_2_2();
- if (objectNum[l] == 124) {
+ if (objectNum[doorNumber] == 124) {
gotoObject(163, 106);
gotoObject(287, 101);
trackProtagonist = 0;
}
- if (objectNum[l] == 173) {
+ if (objectNum[doorNumber] == 173) {
animation_35_2();
return true;
}
- if (objectNum[l] == 146 && flags[39] == 1) {
+ if (objectNum[doorNumber] == 146 && flags[39] == 1) {
flags[5] = 1;
flags[11] = 1;
}
- if (objectNum[l] == 176 && flags[29] == 1) {
+ if (objectNum[doorNumber] == 176 && flags[29] == 1) {
flags[29] = 0;
removeObject(kItemEarWithEarPlug);
addObject(kItemEarplugs);
}
- } else if (currentChapter == 4 && objectNum[l] == 108) {
+ } else if (currentChapter == 4 && objectNum[doorNumber] == 108) {
gotoObject(171, 78);
}
@@ -1936,7 +1935,7 @@ bool DrasculaEngine::exitRoom(int l) {
hare_se_ve = 1;
clearRoom();
- sscanf(_targetSurface[l], "%d", &roomNum);
+ sscanf(_targetSurface[doorNumber], "%d", &roomNum);
curX = -1;
enterRoom(roomNum);
diff --git a/engines/drascula/talk.cpp b/engines/drascula/talk.cpp
index 7c94938c9b..4b649ce8db 100644
--- a/engines/drascula/talk.cpp
+++ b/engines/drascula/talk.cpp
@@ -803,6 +803,7 @@ void DrasculaEngine::talk_sync(const char *said, const char *filename, const cha
p = 0;
+ memset(buf, 0, sizeof(buf));
talkInit(filename);
do {
diff --git a/engines/gob/demos/demoplayer.cpp b/engines/gob/demos/demoplayer.cpp
index 7f65721ce5..13b7aa5327 100644
--- a/engines/gob/demos/demoplayer.cpp
+++ b/engines/gob/demos/demoplayer.cpp
@@ -34,6 +34,7 @@
#include "gob/draw.h"
#include "gob/inter.h"
#include "gob/videoplayer.h"
+#include "gob/sound/sound.h"
namespace Gob {
@@ -186,6 +187,30 @@ void DemoPlayer::playVideo(const char *fileName) {
free(filePtr);
}
+void DemoPlayer::playADL(const char *params) {
+ const char *end;
+
+ end = strchr(params, ' ');
+ if (!end)
+ end = params + strlen(params);
+
+ Common::String fileName(params, end);
+ bool waitEsc = true;
+ int32 repeat = -1;
+
+ if (*end != '\0') {
+ const char *start = end + 1;
+
+ waitEsc = (*start != '0');
+
+ end = strchr(start, ' ');
+ if (end)
+ repeat = atoi(end + 1);
+ }
+
+ playADL(fileName, waitEsc, repeat);
+}
+
void DemoPlayer::playVideoNormal() {
_vm->_vidPlayer->primaryPlay();
}
@@ -233,6 +258,26 @@ void DemoPlayer::playVideoDoubled() {
}
}
+void DemoPlayer::playADL(const Common::String &fileName, bool waitEsc, int32 repeat) {
+ debugC(1, kDebugDemo, "Playing ADL \"%s\" (%d, %d)", fileName.c_str(), waitEsc, repeat);
+
+ _vm->_sound->adlibUnload();
+ _vm->_sound->adlibLoadADL(fileName.c_str());
+ _vm->_sound->adlibSetRepeating(repeat);
+ _vm->_sound->adlibPlay();
+
+ if (!waitEsc)
+ return;
+
+ int16 key = 0;
+ while (!_vm->shouldQuit() && (key != kKeyEscape) && _vm->_sound->adlibIsPlaying()) {
+ _vm->_util->longDelay(1);
+ while (_vm->_util->checkKey(key))
+ if (key == kKeyEscape)
+ break;
+ }
+}
+
void DemoPlayer::evaluateVideoMode(const char *mode) {
debugC(2, kDebugDemo, "Video mode \"%s\"", mode);
diff --git a/engines/gob/demos/demoplayer.h b/engines/gob/demos/demoplayer.h
index 64c98b58c5..f0672b9645 100644
--- a/engines/gob/demos/demoplayer.h
+++ b/engines/gob/demos/demoplayer.h
@@ -57,9 +57,11 @@ protected:
void evaluateVideoMode(const char *mode);
void clearScreen();
void playVideo(const char *fileName);
+ void playADL(const char *params);
void playVideoNormal();
void playVideoDoubled();
+ void playADL(const Common::String &fileName, bool waitEsc = true, int32 repeat = -1);
private:
enum ScriptSource {
diff --git a/engines/gob/demos/scnplayer.cpp b/engines/gob/demos/scnplayer.cpp
index 616da3272a..bf81773a15 100644
--- a/engines/gob/demos/scnplayer.cpp
+++ b/engines/gob/demos/scnplayer.cpp
@@ -66,6 +66,8 @@ bool SCNPlayer::playStream(Common::SeekableReadStream &scn) {
_rebase0 = true;
} else if (lineStartsWith(line, "REBASE0:OFF")) {
_rebase0 = false;
+ } else if (lineStartsWith(line, "ADL ")) {
+ playADL(line.c_str() + 4);
}
// Mind user input
diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp
index 61c17b16f8..6088d622f8 100644
--- a/engines/gob/detection.cpp
+++ b/engines/gob/detection.cpp
@@ -2750,7 +2750,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2764,7 +2764,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2778,7 +2778,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2792,7 +2792,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2806,7 +2806,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2820,7 +2820,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2834,7 +2834,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2848,7 +2848,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2862,7 +2862,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2876,7 +2876,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2890,7 +2890,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2904,7 +2904,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2918,7 +2918,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2932,7 +2932,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2946,7 +2946,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2960,7 +2960,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2974,7 +2974,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -2988,7 +2988,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3002,7 +3002,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3016,7 +3016,7 @@ static const GOBGameDescription gameDescriptions[] = {
EN_GRB,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3030,7 +3030,7 @@ static const GOBGameDescription gameDescriptions[] = {
DE_DEU,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3044,7 +3044,7 @@ static const GOBGameDescription gameDescriptions[] = {
FR_FRA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3058,7 +3058,7 @@ static const GOBGameDescription gameDescriptions[] = {
IT_ITA,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3072,7 +3072,7 @@ static const GOBGameDescription gameDescriptions[] = {
ES_ESP,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -3086,7 +3086,7 @@ static const GOBGameDescription gameDescriptions[] = {
PL_POL,
kPlatformPC,
ADGF_NO_FLAGS,
- GUIO_NOSUBTITLES | GUIO_NOSPEECH
+ GUIO_NOSPEECH
},
kGameTypeWoodruff,
kFeatures640,
@@ -4299,7 +4299,7 @@ static const GOBGameDescription fallbackDescs[] = {
GUIO_NONE
},
kGameTypeUrban,
- kFeatures640 | kFeaturesSCNDemo,
+ kFeaturesAdlib | kFeatures640 | kFeaturesSCNDemo,
"", "", 8
}
};
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index fb3cb9bbcd..46f75f67aa 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -303,6 +303,8 @@ void Draw::dirtiedRect(SurfaceDescPtr surface,
invalidateRect(left, top, right, bottom);
else if (surface == _frontSurface)
_vm->_video->dirtyRectsAdd(left, top, right, bottom);
+ else if (_vm->_video->_splitSurf && (surface == _vm->_video->_splitSurf))
+ _vm->_video->retrace();
}
void Draw::initSpriteSurf(int16 index, int16 width, int16 height,
diff --git a/engines/gob/draw.h b/engines/gob/draw.h
index ba32df0c3e..1da6ba4b74 100644
--- a/engines/gob/draw.h
+++ b/engines/gob/draw.h
@@ -39,7 +39,7 @@ namespace Gob {
#define RENDERFLAG_USEDELTAS 0x0010
#define RENDERFLAG_UNKNOWN 0x0080
#define RENDERFLAG_NOBLITINVALIDATED 0x0200
-#define RENDERFLAG_SKIPOPTIONALTEXT 0x0400
+#define RENDERFLAG_NOSUBTITLES 0x0400
#define RENDERFLAG_FROMSPLIT 0x0800
#define RENDERFLAG_DOUBLECOORDS 0x1000
@@ -77,6 +77,9 @@ public:
int16 _backDeltaX;
int16 _backDeltaY;
+ int16 _subtitleFont;
+ int16 _subtitleColor;
+
FontToSprite _fontToSprite[4];
Font *_fonts[kFontCount];
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index e2cfcb613d..719945fd6f 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -318,6 +318,8 @@ void Draw_v1::spriteOperation(int16 operation) {
int16 perLine;
Resource *resource;
+ operation &= 0x0F;
+
if (_sourceSurface >= 100)
_sourceSurface -= 80;
if (_destSurface >= 100)
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index 8fe70589a7..a1074d7ecb 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -216,7 +216,9 @@ void Draw_v2::printTotText(int16 id) {
dataPtr = textItem->getData();
ptr = dataPtr;
- if ((_renderFlags & RENDERFLAG_SKIPOPTIONALTEXT) && (ptr[1] & 0x80)) {
+ bool isSubtitle = (ptr[1] & 0x80) != 0;
+
+ if (isSubtitle && !_vm->_global->_doSubtitles) {
delete textItem;
return;
}
@@ -398,10 +400,15 @@ void Draw_v2::printTotText(int16 id) {
} else {
_destSpriteX = offX;
_destSpriteY = offY;
- _fontIndex = fontIndex;
- _frontColor = frontColor;
+ _fontIndex = fontIndex;
+ _frontColor = frontColor;
_textToPrint = str;
+ if (isSubtitle) {
+ _fontIndex = _subtitleFont;
+ _frontColor = _subtitleColor;
+ }
+
if (_needAdjust != 2) {
if ((_destSpriteX >= destX) && (_destSpriteY >= destY) &&
(((_fonts[_fontIndex]->getCharHeight() / 2) + _destSpriteY - 1) <= spriteBottom)) {
@@ -449,6 +456,10 @@ void Draw_v2::printTotText(int16 id) {
ptr++;
offX = destX + (int16)READ_LE_UINT16(ptr);
offY = destY + (int16)READ_LE_UINT16(ptr + 2);
+ if (_renderFlags & RENDERFLAG_DOUBLECOORDS) {
+ offX += (int16)READ_LE_UINT16(ptr);
+ offY += (int16)READ_LE_UINT16(ptr + 2);
+ }
ptr += 4;
break;
@@ -457,11 +468,19 @@ void Draw_v2::printTotText(int16 id) {
fontIndex = ((*ptr & 0xF0) >> 4) & 7;
frontColor = *ptr & 0x0F;
ptr++;
+
+ if (isSubtitle) {
+ _subtitleFont = fontIndex;
+ _subtitleColor = frontColor;
+ }
break;
case 4:
ptr++;
frontColor = *ptr++;
+
+ if (isSubtitle)
+ _subtitleColor = frontColor;
break;
case 6:
@@ -502,8 +521,7 @@ void Draw_v2::printTotText(int16 id) {
case 10:
str[0] = (char) 255;
- WRITE_LE_UINT16((uint16 *) (str + 1),
- ptr - _vm->_game->_resources->getTexts());
+ WRITE_LE_UINT16(str + 1, ptr - _vm->_game->_resources->getTexts());
str[3] = 0;
ptr++;
for (int i = *ptr++; i > 0; i--) {
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index d201019d08..4e2bd223b7 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -275,6 +275,12 @@ void Game::playTot(int16 skipPlay) {
_vm->_draw->_fontToSprite[i].height = -1;
}
+ // Gobliiins music stopping
+ if (_vm->getGameType() == kGameTypeGob1) {
+ _vm->_sound->adlibStop();
+ _vm->_sound->cdStop();
+ }
+
_vm->_mult->initAll();
_vm->_mult->zeroMultData();
diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp
index 2969ed0870..f4f1303386 100644
--- a/engines/gob/global.cpp
+++ b/engines/gob/global.cpp
@@ -124,6 +124,8 @@ Global::Global(GobEngine *vm) : _vm(vm) {
_speedFactor = 1;
+ _doSubtitles = false;
+
_noCd = false;
}
diff --git a/engines/gob/global.h b/engines/gob/global.h
index 7849490107..5830e3e58c 100644
--- a/engines/gob/global.h
+++ b/engines/gob/global.h
@@ -141,6 +141,8 @@ public:
// Can be 1, 2 or 3 for normal, double and triple speed, respectively
uint8 _speedFactor;
+ bool _doSubtitles;
+
bool _noCd;
Global(GobEngine *vm);
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index fa4f04eab8..082345e675 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -25,6 +25,7 @@
#include "common/endian.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "base/plugins.h"
#include "common/config-manager.h"
@@ -129,7 +130,7 @@ GobEngine::GobEngine(OSystem *syst) : Engine(syst) {
Common::addDebugChannel(kDebugHotspots, "Hotspots", "Hotspots debug level");
Common::addDebugChannel(kDebugDemo, "Demo", "Demo script debug level");
- syst->getEventManager()->registerRandomSource(_rnd, "gob");
+ g_eventRec.registerRandomSource(_rnd, "gob");
}
GobEngine::~GobEngine() {
@@ -302,7 +303,6 @@ void GobEngine::pauseEngineIntern(bool pause) {
} else {
uint32 duration = _system->getMillis() - _pauseStart;
- _vidPlayer->notifyPaused(duration);
_util->notifyPaused(duration);
_game->_startTimeKey += duration;
@@ -314,6 +314,12 @@ void GobEngine::pauseEngineIntern(bool pause) {
_mixer->pauseAll(pause);
}
+void GobEngine::syncSoundSettings() {
+ Engine::syncSoundSettings();
+
+ _init->updateConfig();
+}
+
void GobEngine::pauseGame() {
pauseEngineIntern(true);
@@ -329,139 +335,138 @@ bool GobEngine::initGameParts() {
_saveLoad = 0;
- _global = new Global(this);
- _util = new Util(this);
- _dataIO = new DataIO(this);
- _palAnim = new PalAnim(this);
+ _global = new Global(this);
+ _util = new Util(this);
+ _dataIO = new DataIO(this);
+ _palAnim = new PalAnim(this);
_vidPlayer = new VideoPlayer(this);
- _sound = new Sound(this);
- _game = new Game(this);
+ _sound = new Sound(this);
+ _game = new Game(this);
switch (_gameType) {
case kGameTypeGeisha:
case kGameTypeAdibouUnknown:
case kGameTypeGob1:
- _init = new Init_v1(this);
- _video = new Video_v1(this);
- _inter = new Inter_v1(this);
- _mult = new Mult_v1(this);
- _draw = new Draw_v1(this);
- _map = new Map_v1(this);
- _goblin = new Goblin_v1(this);
- _scenery = new Scenery_v1(this);
+ _init = new Init_v1(this);
+ _video = new Video_v1(this);
+ _inter = new Inter_v1(this);
+ _mult = new Mult_v1(this);
+ _draw = new Draw_v1(this);
+ _map = new Map_v1(this);
+ _goblin = new Goblin_v1(this);
+ _scenery = new Scenery_v1(this);
break;
case kGameTypeFascination:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
- _inter = new Inter_Fascination(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_Fascination(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
break;
case kGameTypeWeen:
case kGameTypeGob2:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
- _inter = new Inter_v2(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v2(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
break;
case kGameTypeBargon:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
- _inter = new Inter_Bargon(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_Bargon(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_Bargon(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_Bargon(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v2(this, _targetName.c_str());
break;
case kGameTypeGob3:
case kGameTypeInca2:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v3(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v3(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v3(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v3(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v3(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v3(this, _targetName.c_str(), SaveLoad_v3::kScreenshotTypeGob3);
break;
case kGameTypeLostInTime:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v3(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v3(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v3(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v3(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v3(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v3(this, _targetName.c_str(), SaveLoad_v3::kScreenshotTypeLost);
break;
case kGameTypeWoodruff:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v4(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v4(this);
- _goblin = new Goblin_v4(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v4(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v4(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v4(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v4(this, _targetName.c_str());
break;
case kGameTypeDynasty:
- _init = new Init_v3(this);
- _video = new Video_v2(this);
- _inter = new Inter_v5(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v4(this);
- _goblin = new Goblin_v4(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v3(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v5(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v4(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad(this);
break;
case kGameTypeAdibou4:
case kGameTypeUrban:
- _init = new Init_v6(this);
- _video = new Video_v6(this);
- _inter = new Inter_v6(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v4(this);
- _goblin = new Goblin_v4(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v6(this);
+ _video = new Video_v6(this);
+ _inter = new Inter_v6(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v4(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_v6(this, _targetName.c_str());
break;
case kGameTypePlaytoon:
case kGameTypePlaytnCk:
case kGameTypeBambou:
- _init = new Init_v2(this);
- _video = new Video_v2(this);
-// _inter = new Inter_Playtoons(this);
- _inter = new Inter_v6(this);
- _mult = new Mult_v2(this);
- _draw = new Draw_v2(this);
- _map = new Map_v2(this);
- _goblin = new Goblin_v2(this);
- _scenery = new Scenery_v2(this);
+ _init = new Init_v2(this);
+ _video = new Video_v2(this);
+ _inter = new Inter_v6(this);
+ _mult = new Mult_v2(this);
+ _draw = new Draw_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
_saveLoad = new SaveLoad_Playtoons(this);
break;
diff --git a/engines/gob/gob.h b/engines/gob/gob.h
index 02f6af51bf..84ff707877 100644
--- a/engines/gob/gob.h
+++ b/engines/gob/gob.h
@@ -75,8 +75,6 @@ class SaveLoad;
#define GET_VAR_FSTR(var) _vm->_inter->_variables->getAddressVarString(var)
#define GET_VARO_FSTR(off) _vm->_inter->_variables->getAddressOffString(off)
-#define VAR_ADDRESS(var) _vm->_inter->_variables->getAddressVar32(var)
-
#define WRITE_VAR_OFFSET(off, val) WRITE_VARO_UINT32((off), (val))
#define WRITE_VAR(var, val) WRITE_VAR_UINT32((var), (val))
#define VAR_OFFSET(off) READ_VARO_UINT32(off)
@@ -165,6 +163,7 @@ private:
virtual Common::Error run();
virtual bool hasFeature(EngineFeature f) const;
virtual void pauseEngineIntern(bool pause);
+ virtual void syncSoundSettings();
bool initGameParts();
void deinitGameParts();
diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp
index faf85a5b41..834e9b8553 100644
--- a/engines/gob/init.cpp
+++ b/engines/gob/init.cpp
@@ -49,6 +49,9 @@ Init::Init(GobEngine *vm) : _vm(vm) {
_palDesc = 0;
}
+Init::~Init() {
+}
+
void Init::cleanup() {
_vm->_video->freeDriver();
_vm->_global->_primarySurfDesc.reset();
@@ -87,6 +90,7 @@ void Init::initGame() {
char buffer[128];
initVideo();
+ updateConfig();
if (!_vm->isDemo()) {
if (_vm->_dataIO->existData(_vm->_startStk.c_str()))
@@ -206,4 +210,7 @@ void Init::initGame() {
cleanup();
}
+void Init::updateConfig() {
+}
+
} // End of namespace Gob
diff --git a/engines/gob/init.h b/engines/gob/init.h
index 60642d0189..c2784a59ac 100644
--- a/engines/gob/init.h
+++ b/engines/gob/init.h
@@ -32,12 +32,14 @@ namespace Gob {
class Init {
public:
+ Init(GobEngine *vm);
+ virtual ~Init();
+
virtual void initGame();
virtual void initVideo() = 0;
- Init(GobEngine *vm);
- virtual ~Init() {}
+ virtual void updateConfig();
protected:
Video::PalDesc *_palDesc;
@@ -50,34 +52,42 @@ protected:
class Init_v1 : public Init {
public:
- virtual void initVideo();
-
Init_v1(GobEngine *vm);
- virtual ~Init_v1() {}
+ ~Init_v1();
+
+ void initVideo();
};
class Init_v2 : public Init_v1 {
public:
- virtual void initVideo();
-
Init_v2(GobEngine *vm);
- virtual ~Init_v2() {}
+ ~Init_v2();
+
+ void initVideo();
};
class Init_v3 : public Init_v2 {
public:
- virtual void initVideo();
-
Init_v3(GobEngine *vm);
- virtual ~Init_v3() {}
+ ~Init_v3();
+
+ void initVideo();
};
-class Init_v6 : public Init_v3 {
+class Init_v4 : public Init_v3 {
public:
- virtual void initGame();
+ Init_v4(GobEngine *vm);
+ ~Init_v4();
+
+ void updateConfig();
+};
+class Init_v6 : public Init_v3 {
+public:
Init_v6(GobEngine *vm);
- virtual ~Init_v6() {}
+ ~Init_v6();
+
+ void initGame();
};
} // End of namespace Gob
diff --git a/engines/gob/init_v1.cpp b/engines/gob/init_v1.cpp
index e482104ff9..50db774734 100644
--- a/engines/gob/init_v1.cpp
+++ b/engines/gob/init_v1.cpp
@@ -35,6 +35,9 @@ namespace Gob {
Init_v1::Init_v1(GobEngine *vm) : Init(vm) {
}
+Init_v1::~Init_v1() {
+}
+
void Init_v1::initVideo() {
if (_vm->_global->_videoMode)
_vm->validateVideoMode(_vm->_global->_videoMode);
diff --git a/engines/gob/init_v2.cpp b/engines/gob/init_v2.cpp
index 4c65b8102c..f89d5a8cfb 100644
--- a/engines/gob/init_v2.cpp
+++ b/engines/gob/init_v2.cpp
@@ -36,6 +36,9 @@ namespace Gob {
Init_v2::Init_v2(GobEngine *vm) : Init_v1(vm) {
}
+Init_v2::~Init_v2() {
+}
+
void Init_v2::initVideo() {
if (_vm->_global->_videoMode)
_vm->validateVideoMode(_vm->_global->_videoMode);
diff --git a/engines/gob/init_v3.cpp b/engines/gob/init_v3.cpp
index 67304b389a..c96005ed5a 100644
--- a/engines/gob/init_v3.cpp
+++ b/engines/gob/init_v3.cpp
@@ -34,6 +34,9 @@ namespace Gob {
Init_v3::Init_v3(GobEngine *vm) : Init_v2(vm) {
}
+Init_v3::~Init_v3() {
+}
+
void Init_v3::initVideo() {
Init_v2::initVideo();
diff --git a/engines/gob/init_v4.cpp b/engines/gob/init_v4.cpp
new file mode 100644
index 0000000000..3bd50a494d
--- /dev/null
+++ b/engines/gob/init_v4.cpp
@@ -0,0 +1,45 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/endian.h"
+#include "common/config-manager.h"
+
+#include "gob/gob.h"
+#include "gob/init.h"
+#include "gob/global.h"
+
+namespace Gob {
+
+Init_v4::Init_v4(GobEngine *vm) : Init_v3(vm) {
+}
+
+Init_v4::~Init_v4() {
+}
+
+void Init_v4::updateConfig() {
+ _vm->_global->_doSubtitles = ConfMan.getBool("subtitles");
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/init_v6.cpp b/engines/gob/init_v6.cpp
index 4b14c8a29c..40b4769e78 100644
--- a/engines/gob/init_v6.cpp
+++ b/engines/gob/init_v6.cpp
@@ -34,6 +34,9 @@ namespace Gob {
Init_v6::Init_v6(GobEngine *vm) : Init_v3(vm) {
}
+Init_v6::~Init_v6() {
+}
+
void Init_v6::initGame() {
_vm->_global->_noCd = false;
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 69c392b198..446d86643d 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -972,6 +972,7 @@ bool Inter_v1::o1_loadTot(OpFuncParams &params) {
bool Inter_v1::o1_palLoad(OpFuncParams &params) {
int index1, index2;
+ int16 id;
byte cmd;
Resource *resource;
@@ -1116,7 +1117,8 @@ bool Inter_v1::o1_palLoad(OpFuncParams &params) {
case 61:
index1 = _vm->_game->_script->readByte();
index2 = (_vm->_game->_script->readByte() - index1 + 1) * 3;
- resource = _vm->_game->_resources->getResource(_vm->_game->_script->readInt16());
+ id = _vm->_game->_script->readInt16();
+ resource = _vm->_game->_resources->getResource(id);
if (!resource)
break;
@@ -1124,6 +1126,13 @@ bool Inter_v1::o1_palLoad(OpFuncParams &params) {
resource->getData() + index1 * 3, index2);
delete resource;
+ // WORKAROUND: The Last Dynasty overwrites the 0. palette entry but depends on it staying black.
+ if ((_vm->getGameType() == kGameTypeDynasty) && (index1 == 0)) {
+ _vm->_draw->_vgaPalette[0].red = 0;
+ _vm->_draw->_vgaPalette[0].green = 0;
+ _vm->_draw->_vgaPalette[0].blue = 0;
+ }
+
if (_vm->_draw->_applyPal) {
_vm->_draw->_applyPal = false;
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
@@ -2303,7 +2312,7 @@ void Inter_v1::o1_setItemPos(OpGobParams &params) {
void Inter_v1::o1_loadObjects(OpGobParams &params) {
params.extraData = _vm->_game->_script->readInt16();
- _vm->_goblin->loadObjects((char *) VAR_ADDRESS(params.extraData));
+ _vm->_goblin->loadObjects(_variables->getAddressVarString(params.extraData));
}
void Inter_v1::o1_freeObjects(OpGobParams &params) {
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 20f812bb88..19cac86465 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -25,6 +25,8 @@
#include "common/endian.h"
+#include "gui/message.h"
+
#include "sound/mixer.h"
#include "sound/mods/infogrames.h"
@@ -587,6 +589,11 @@ void Inter_v2::o2_totSub() {
if (!scumm_stricmp(totFile, "edit"))
_vm->_util->forceMouseUp();
+ // WORKAROUND: For some reason, the variable indicating which TOT to load next
+ // is overwritten in the guard house card game in Woodruff
+ if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(totFile, "6"))
+ strcpy(totFile, "EMAP2011");
+
flags = _vm->_game->_script->readByte();
_vm->_game->totSub(flags, totFile);
}
@@ -1297,16 +1304,23 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
size = -1;
handle = 1;
- mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr());
+ char *file = _vm->_game->_script->getResultStr();
+
+ // WORKAROUND: For some reason, the variable indicating which TOT to load next
+ // is overwritten in the guard house card game in Woodruff
+ if ((_vm->getGameType() == kGameTypeWoodruff) && !scumm_stricmp(file, "6.TOT"))
+ strcpy(file, "EMAP2011.TOT");
+
+ mode = _vm->_saveLoad->getSaveMode(file);
if (mode == SaveLoad::kSaveModeNone) {
- if (_vm->_dataIO->existData(_vm->_game->_script->getResultStr()))
- size = _vm->_dataIO->getDataSize(_vm->_game->_script->getResultStr());
+ if (_vm->_dataIO->existData(file))
+ size = _vm->_dataIO->getDataSize(file);
else
- warning("File \"%s\" not found", _vm->_game->_script->getResultStr());
+ warning("File \"%s\" not found", file);
} else if (mode == SaveLoad::kSaveModeSave)
- size = _vm->_saveLoad->getSize(_vm->_game->_script->getResultStr());
+ size = _vm->_saveLoad->getSize(file);
else if (mode == SaveLoad::kSaveModeExists)
size = 23;
@@ -1314,7 +1328,7 @@ bool Inter_v2::o2_checkData(OpFuncParams &params) {
handle = -1;
debugC(2, kDebugFileIO, "Requested size of file \"%s\": %d",
- _vm->_game->_script->getResultStr(), size);
+ file, size);
WRITE_VAR_OFFSET(varOff, handle);
WRITE_VAR(16, (uint32) size);
@@ -1338,21 +1352,32 @@ bool Inter_v2::o2_readData(OpFuncParams &params) {
offset = _vm->_game->_script->getResultInt();
retSize = 0;
+ char *file = _vm->_game->_script->getResultStr();
+
debugC(2, kDebugFileIO, "Read from file \"%s\" (%d, %d bytes at %d)",
- _vm->_game->_script->getResultStr(), dataVar, size, offset);
+ file, dataVar, size, offset);
- mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr());
+ mode = _vm->_saveLoad->getSaveMode(file);
if (mode == SaveLoad::kSaveModeSave) {
+
WRITE_VAR(1, 1);
- if (_vm->_saveLoad->load(_vm->_game->_script->getResultStr(), dataVar, size, offset))
+
+ if (!_vm->_saveLoad->load(file, dataVar, size, offset)) {
+
+ GUI::MessageDialog dialog("Failed to load game state from file.");
+ dialog.runModal();
+
+ } else
WRITE_VAR(1, 0);
+
return false;
+
} else if (mode == SaveLoad::kSaveModeIgnore)
return false;
if (size < 0) {
warning("Attempted to read a raw sprite from file \"%s\"",
- _vm->_game->_script->getResultStr());
+ file);
return false ;
} else if (size == 0) {
dataVar = 0;
@@ -1361,13 +1386,13 @@ bool Inter_v2::o2_readData(OpFuncParams &params) {
buf = _variables->getAddressOff8(dataVar);
- if (_vm->_game->_script->getResultStr()[0] == 0) {
+ if (file[0] == 0) {
WRITE_VAR(1, size);
return false;
}
WRITE_VAR(1, 1);
- handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr());
+ handle = _vm->_dataIO->openData(file);
if (handle < 0)
return false;
@@ -1408,17 +1433,26 @@ bool Inter_v2::o2_writeData(OpFuncParams &params) {
_vm->_game->_script->evalExpr(0);
offset = _vm->_game->_script->getResultInt();
+ char *file = _vm->_game->_script->getResultStr();
+
debugC(2, kDebugFileIO, "Write to file \"%s\" (%d, %d bytes at %d)",
- _vm->_game->_script->getResultStr(), dataVar, size, offset);
+ file, dataVar, size, offset);
WRITE_VAR(1, 1);
- mode = _vm->_saveLoad->getSaveMode(_vm->_game->_script->getResultStr());
+ mode = _vm->_saveLoad->getSaveMode(file);
if (mode == SaveLoad::kSaveModeSave) {
- if (_vm->_saveLoad->save(_vm->_game->_script->getResultStr(), dataVar, size, offset))
+
+ if (!_vm->_saveLoad->save(file, dataVar, size, offset)) {
+
+ GUI::MessageDialog dialog("Failed to save game state to file.");
+ dialog.runModal();
+
+ } else
WRITE_VAR(1, 0);
+
} else if (mode == SaveLoad::kSaveModeNone)
- warning("Attempted to write to file \"%s\"", _vm->_game->_script->getResultStr());
+ warning("Attempted to write to file \"%s\"", file);
return false;
}
diff --git a/engines/gob/map.h b/engines/gob/map.h
index 4a211f205d..ba976ff7ac 100644
--- a/engines/gob/map.h
+++ b/engines/gob/map.h
@@ -204,14 +204,6 @@ protected:
void loadGoblinStates(Common::SeekableReadStream &data, int index);
};
-class Map_v4 : public Map_v2 {
-public:
- virtual void loadMapObjects(const char *avjFile);
-
- Map_v4(GobEngine *vm);
- virtual ~Map_v4();
-};
-
} // End of namespace Gob
#endif // GOB_MAP_H
diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp
index 6ceda7ab44..51caad74b8 100644
--- a/engines/gob/map_v2.cpp
+++ b/engines/gob/map_v2.cpp
@@ -60,7 +60,10 @@ void Map_v2::loadMapObjects(const char *avjFile) {
id = _vm->_game->_script->readInt16();
- if (id == -1) {
+ if (((uint16) id) >= 65520) {
+ warning("Map_v2::loadMapObjects(): ID >= 65520");
+ return;
+ } else if (id == -1) {
_passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var);
return;
}
@@ -71,13 +74,20 @@ void Map_v2::loadMapObjects(const char *avjFile) {
Common::SeekableReadStream &mapData = *resource->stream();
- if (mapData.readByte() == 3) {
+ _widthByte = mapData.readByte();
+ if (_widthByte == 4) {
_screenWidth = 640;
+ _screenHeight = 400;
+ } else if (_widthByte == 3) {
_passWidth = 65;
+ _screenWidth = 640;
+ _screenHeight = 200;
} else {
- _screenWidth = 320;
_passWidth = 40;
+ _screenWidth = 320;
+ _screenHeight = 200;
}
+
_wayPointsCount = mapData.readByte();
_tilesWidth = mapData.readSint16LE();
_tilesHeight = mapData.readSint16LE();
@@ -85,6 +95,11 @@ void Map_v2::loadMapObjects(const char *avjFile) {
_bigTiles = !(_tilesHeight & 0xFF00);
_tilesHeight &= 0xFF;
+ if (_widthByte == 4) {
+ _screenWidth = mapData.readSint16LE();
+ _screenHeight = mapData.readSint16LE();
+ }
+
_mapWidth = _screenWidth / _tilesWidth;
_mapHeight = _screenHeight / _tilesHeight;
@@ -104,6 +119,11 @@ void Map_v2::loadMapObjects(const char *avjFile) {
_wayPoints[i].notWalkable = mapData.readSByte();
}
+ if (_widthByte == 4) {
+ _mapWidth = VAR(17);
+ _passWidth = _mapWidth;
+ }
+
// In the original asm, this writes byte-wise into the variables-array
tmpPos = mapData.pos();
mapData.seek(passPos);
diff --git a/engines/gob/map_v4.cpp b/engines/gob/map_v4.cpp
deleted file mode 100644
index 1db3d6a3f8..0000000000
--- a/engines/gob/map_v4.cpp
+++ /dev/null
@@ -1,159 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * $URL$
- * $Id$
- *
- */
-
-#include "common/stream.h"
-
-#include "gob/gob.h"
-#include "gob/map.h"
-#include "gob/global.h"
-#include "gob/goblin.h"
-#include "gob/inter.h"
-#include "gob/game.h"
-#include "gob/script.h"
-#include "gob/resources.h"
-#include "gob/mult.h"
-
-namespace Gob {
-
-Map_v4::Map_v4(GobEngine *vm) : Map_v2(vm) {
-}
-
-Map_v4::~Map_v4() {
-}
-
-void Map_v4::loadMapObjects(const char *avjFile) {
- uint8 wayPointsCount;
- int16 var;
- int16 id;
- int16 mapWidth, mapHeight;
- int16 tmp;
- byte *variables;
- uint32 tmpPos;
- uint32 passPos;
-
- var = _vm->_game->_script->readVarIndex();
- variables = _vm->_inter->_variables->getAddressOff8(var);
-
- id = _vm->_game->_script->readInt16();
-
- if (((uint16) id) >= 65520) {
- warning("Woodruff Stub: loadMapObjects ID >= 65520");
- return;
- } else if (id == -1) {
- _passMap = (int8 *) _vm->_inter->_variables->getAddressOff8(var);
- return;
- }
-
- Resource *resource = _vm->_game->_resources->getResource(id);
- if (!resource)
- return;
-
- Common::SeekableReadStream &mapData = *resource->stream();
-
- _widthByte = mapData.readByte();
- if (_widthByte == 4) {
- _screenWidth = 640;
- _screenHeight = 400;
- } else if (_widthByte == 3) {
- _screenWidth = 640;
- _screenHeight = 200;
- } else {
- _screenWidth = 320;
- _screenHeight = 200;
- }
-
- _wayPointsCount = mapData.readByte();
- _tilesWidth = mapData.readSint16LE();
- _tilesHeight = mapData.readSint16LE();
-
- _bigTiles = !(_tilesHeight & 0xFF00);
- _tilesHeight &= 0xFF;
-
- if (_widthByte == 4) {
- _screenWidth = mapData.readSint16LE();
- _screenHeight = mapData.readSint16LE();
- }
-
- _mapWidth = _screenWidth / _tilesWidth;
- _mapHeight = _screenHeight / _tilesHeight;
-
- passPos = mapData.pos();
- mapData.skip(_mapWidth * _mapHeight);
-
- if (resource->getData()[0] == 1)
- wayPointsCount = _wayPointsCount = 40;
- else
- wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount;
-
- delete[] _wayPoints;
- _wayPoints = new Point[wayPointsCount];
- for (int i = 0; i < _wayPointsCount; i++) {
- _wayPoints[i].x = mapData.readSByte();
- _wayPoints[i].y = mapData.readSByte();
- _wayPoints[i].notWalkable = mapData.readSByte();
- }
-
- if (_widthByte == 4)
- _mapWidth = VAR(17);
-
- _passWidth = _mapWidth;
-
- // In the original asm, this writes byte-wise into the variables-array
- tmpPos = mapData.pos();
- mapData.seek(passPos);
- if ((variables != 0) &&
- (variables != _vm->_inter->_variables->getAddressOff8(0))) {
-
- _passMap = (int8 *) variables;
- mapHeight = _screenHeight / _tilesHeight;
- mapWidth = _screenWidth / _tilesWidth;
-
- for (int i = 0; i < mapHeight; i++) {
- for (int j = 0; j < mapWidth; j++)
- setPass(j, i, mapData.readSByte());
- _vm->_inter->_variables->getAddressOff8(var + i * _passWidth);
- }
- }
- mapData.seek(tmpPos);
-
- tmp = mapData.readSint16LE();
- mapData.skip(tmp * 14);
- tmp = mapData.readSint16LE();
- mapData.skip(tmp * 14 + 28);
- tmp = mapData.readSint16LE();
- mapData.skip(tmp * 14);
-
- _vm->_goblin->_gobsCount = tmp;
- for (int i = 0; i < _vm->_goblin->_gobsCount; i++)
- loadGoblinStates(mapData, i);
-
- _vm->_goblin->_soundSlotsCount = _vm->_game->_script->readInt16();
- for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
- _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
-
- delete resource;
-}
-
-} // End of namespace Gob
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 611abb6038..26cc4e5d27 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -23,6 +23,7 @@ MODULE_OBJS := \
init_v1.o \
init_v2.o \
init_v3.o \
+ init_v4.o \
init_v6.o \
inter.o \
inter_v1.o \
@@ -36,7 +37,6 @@ MODULE_OBJS := \
map.o \
map_v1.o \
map_v2.o \
- map_v4.o \
mult.o \
mult_v1.o \
mult_v2.o \
diff --git a/engines/gob/resources.cpp b/engines/gob/resources.cpp
index c52b65f0d7..2f3b1b23e7 100644
--- a/engines/gob/resources.cpp
+++ b/engines/gob/resources.cpp
@@ -144,8 +144,6 @@ Resources::~Resources() {
bool Resources::load(const Common::String &fileName) {
unload();
- Common::String fileBase;
-
_totFile = TOTFile::createFileName(fileName, _hasLOM);
if (_hasLOM) {
@@ -154,9 +152,9 @@ bool Resources::load(const Common::String &fileName) {
return false;
}
- fileBase = TOTFile::getFileBase(fileName);
+ _fileBase = TOTFile::getFileBase(fileName);
- _extFile = fileBase + ".ext";
+ _extFile = _fileBase + ".ext";
bool hasTOTRes = loadTOTResourceTable();
bool hasEXTRes = loadEXTResourceTable();
@@ -165,7 +163,7 @@ bool Resources::load(const Common::String &fileName) {
return false;
if (hasTOTRes) {
- if (!loadTOTTextTable(fileBase)) {
+ if (!loadTOTTextTable(_fileBase)) {
unload();
return false;
}
@@ -195,6 +193,7 @@ void Resources::unload(bool del) {
delete[] _totData;
delete[] _imData;
+ _fileBase.clear();
_totFile.clear();
_extFile.clear();
_exFile.clear();
@@ -573,6 +572,41 @@ byte *Resources::getTexts() const {
return _totTextTable->data;
}
+bool Resources::dumpResource(const Resource &resource,
+ const Common::String &fileName) const {
+
+ Common::DumpFile dump;
+
+ if (!dump.open(fileName))
+ return false;
+
+ if (dump.write(resource.getData(), resource.getSize()) != ((uint32) resource.getSize()))
+ return false;
+
+ if (!dump.flush())
+ return false;
+ if (dump.err())
+ return false;
+
+ dump.close();
+ return true;
+}
+
+bool Resources::dumpResource(const Resource &resource, uint16 id,
+ const Common::String &ext) const {
+
+ Common::String fileName = _fileBase;
+
+ char idStr[7];
+
+ snprintf(idStr, 7, "_%05d", id);
+ fileName += idStr;
+ fileName += ".";
+ fileName += ext;
+
+ return dumpResource(resource, fileName);
+}
+
Resource *Resources::getTOTResource(uint16 id) const {
if (id >= _totResourceTable->itemsCount) {
warning("Trying to load non-existent TOT resource (%s, %d/%d)",
diff --git a/engines/gob/resources.h b/engines/gob/resources.h
index d316be83e5..7511185954 100644
--- a/engines/gob/resources.h
+++ b/engines/gob/resources.h
@@ -91,6 +91,11 @@ public:
byte *getTexts() const;
+ bool dumpResource(const Resource &resource,
+ const Common::String &fileName) const;
+ bool dumpResource(const Resource &resource, uint16 id,
+ const Common::String &ext = "dmp") const;
+
private:
// Structure sizes in the files
static const int kTOTResItemSize = 4 + 2 + 2 + 2;
@@ -166,6 +171,7 @@ private:
GobEngine *_vm;
+ Common::String _fileBase;
Common::String _totFile;
Common::String _extFile;
Common::String _exFile;
diff --git a/engines/gob/save/saveconverter.cpp b/engines/gob/save/saveconverter.cpp
index 38fec06859..7bfb2a2da2 100644
--- a/engines/gob/save/saveconverter.cpp
+++ b/engines/gob/save/saveconverter.cpp
@@ -122,14 +122,14 @@ bool SaveConverter::swapDataEndian(byte *data, const byte *sizes, uint32 count)
while (count-- > 0) {
if (*sizes == 3) // 32bit value (3 additional bytes)
- *((uint32 *) data) = SWAP_BYTES_32(*((uint32 *) data));
+ WRITE_UINT32(data, SWAP_BYTES_32(READ_UINT32(data)));
else if (*sizes == 1) // 16bit value (1 additional byte)
- *((uint16 *) data) = SWAP_BYTES_16(*((uint16 *) data));
+ WRITE_UINT16(data, SWAP_BYTES_16(READ_UINT16(data)));
else if (*sizes != 0) // else, it has to be an 8bit value
return false;
count -= *sizes;
- data += *sizes + 1;
+ data += *sizes + 1;
sizes += *sizes + 1;
}
diff --git a/engines/gob/save/saveload.h b/engines/gob/save/saveload.h
index 8d785c7233..1a1a47178b 100644
--- a/engines/gob/save/saveload.h
+++ b/engines/gob/save/saveload.h
@@ -74,15 +74,15 @@ protected:
/** Save/Load class for Gobliins 2, Ween: The Prophecy and Bargon Attack. */
class SaveLoad_v2 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 15;
+ static const uint32 kSlotNameLength = 40;
+
SaveLoad_v2(GobEngine *vm, const char *targetName);
virtual ~SaveLoad_v2();
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 15;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
@@ -136,6 +136,9 @@ protected:
/** Save/Load class for Goblins 3 and Lost in Time. */
class SaveLoad_v3 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 30;
+ static const uint32 kSlotNameLength = 40;
+
enum ScreenshotType {
kScreenshotTypeGob3, //!< Goblins 3 type screenshot
kScreenshotTypeLost //!< Lost in Time type screenshot
@@ -147,9 +150,6 @@ public:
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 30;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
@@ -264,15 +264,15 @@ protected:
/** Save/Load class for Woodruff. */
class SaveLoad_v4 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 10;
+ static const uint32 kSlotNameLength = 40;
+
SaveLoad_v4(GobEngine *vm, const char *targetName);
virtual ~SaveLoad_v4();
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 10;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
@@ -289,6 +289,8 @@ protected:
GameHandler(GobEngine *vm, const char *target);
~GameHandler();
+ int getLastSlot() const;
+
int32 getSize();
bool load(int16 dataVar, int32 size, int32 offset);
bool save(int16 dataVar, int32 size, int32 offset);
@@ -317,6 +319,8 @@ protected:
File *_slotFile;
+ int _lastSlot;
+
SaveReader *_reader;
SaveWriter *_writer;
@@ -386,15 +390,15 @@ protected:
/** Save/Load class for Urban Runner. */
class SaveLoad_v6 : public SaveLoad {
public:
+ static const uint32 kSlotCount = 60;
+ static const uint32 kSlotNameLength = 40;
+
SaveLoad_v6(GobEngine *vm, const char *targetName);
virtual ~SaveLoad_v6();
SaveMode getSaveMode(const char *fileName) const;
protected:
- static const uint32 kSlotCount = 60;
- static const uint32 kSlotNameLength = 40;
-
struct SaveFile {
const char *sourceName;
SaveMode mode;
diff --git a/engines/gob/save/saveload_v4.cpp b/engines/gob/save/saveload_v4.cpp
index 06280af2a6..16c87b9a64 100644
--- a/engines/gob/save/saveload_v4.cpp
+++ b/engines/gob/save/saveload_v4.cpp
@@ -84,6 +84,8 @@ SaveLoad_v4::GameHandler::GameHandler(GobEngine *vm, const char *target) : SaveH
_slotFile = new File(vm, target);
+ _lastSlot = -1;
+
_writer = 0;
_reader = 0;
}
@@ -94,6 +96,10 @@ SaveLoad_v4::GameHandler::~GameHandler() {
delete _writer;
}
+int SaveLoad_v4::GameHandler::getLastSlot() const {
+ return _lastSlot;
+}
+
int32 SaveLoad_v4::GameHandler::getSize() {
// Fake an empty save file for the very first query, to get clear properties
if (_firstSize) {
@@ -178,6 +184,7 @@ bool SaveLoad_v4::GameHandler::load(int16 dataVar, int32 size, int32 offset) {
if (!vars.writeInto(0, 0, varSize))
return false;
+ _lastSlot = slot;
}
return true;
@@ -261,6 +268,7 @@ bool SaveLoad_v4::GameHandler::save(int16 dataVar, int32 size, int32 offset) {
if (!_writer->writePart(1, &vars))
return false;
+ _lastSlot = slot;
}
return true;
@@ -465,7 +473,11 @@ bool SaveLoad_v4::ScreenPropsHandler::load(int16 dataVar, int32 size, int32 offs
return false;
}
- return _gameHandler->loadScreenProps(_file->getSlot(offset), _curProps->_props);
+ int slot = _gameHandler->getLastSlot();
+ if (slot == -1)
+ slot = _file->getSlot(offset);
+
+ return _gameHandler->loadScreenProps(slot, _curProps->_props);
}
bool SaveLoad_v4::ScreenPropsHandler::save(int16 dataVar, int32 size, int32 offset) {
@@ -474,7 +486,11 @@ bool SaveLoad_v4::ScreenPropsHandler::save(int16 dataVar, int32 size, int32 offs
return false;
}
- return _gameHandler->saveScreenProps(_file->getSlot(offset), _curProps->_props);
+ int slot = _gameHandler->getLastSlot();
+ if (slot == -1)
+ slot = _file->getSlot(offset);
+
+ return _gameHandler->saveScreenProps(slot, _curProps->_props);
}
diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp
index 7a4b8ad868..a6d6c06544 100644
--- a/engines/gob/scenery.cpp
+++ b/engines/gob/scenery.cpp
@@ -95,7 +95,7 @@ void Scenery::init() {
int16 Scenery::loadStatic(char search) {
int16 size;
- int16 *backsPtr;
+ byte *backsPtr;
int16 picsCount;
int16 resId;
int16 sceneryIndex;
@@ -108,7 +108,7 @@ int16 Scenery::loadStatic(char search) {
_vm->_game->_script->evalExpr(&sceneryIndex);
size = _vm->_game->_script->readInt16();
- backsPtr = (int16 *) (_vm->_game->_script->getData() + _vm->_game->_script->pos());
+ backsPtr = _vm->_game->_script->getData() + _vm->_game->_script->pos();
_vm->_game->_script->skip(size * 2);
picsCount = _vm->_game->_script->readInt16();
resId = _vm->_game->_script->readInt16();
@@ -162,7 +162,7 @@ int16 Scenery::loadStatic(char search) {
ptr->layers[i].planes = 0;
ptr->layers[i].backResId = (int16) READ_LE_UINT16(backsPtr);
- backsPtr++;
+ backsPtr += 2;
}
ptr->pieces = new PieceDesc*[picsCount];
@@ -185,7 +185,7 @@ int16 Scenery::loadStatic(char search) {
_staticPictToSprite[7 * sceneryIndex + i] = sprIndex;
_spriteRefs[sprIndex]++;
} else {
- for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; sprIndex--);
+ for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; sprIndex--) { }
_staticPictToSprite[7 * sceneryIndex + i] = sprIndex;
_spriteRefs[sprIndex] = 1;
@@ -632,6 +632,11 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
_vm->_vidPlayer->slotPlay(obj.videoSlot - 1);
}
+ // Subtitle
+ Graphics::CoktelVideo::State state = _vm->_vidPlayer->getState(obj.videoSlot - 1);
+ if (state.flags & Graphics::CoktelVideo::kStateSpeech)
+ _vm->_draw->printTotText(state.speechId);
+
destX = 0;
destY = 0;
left = *(obj.pPosX);
diff --git a/engines/gob/script.cpp b/engines/gob/script.cpp
index 38b1f8fa40..0475bb06f7 100644
--- a/engines/gob/script.cpp
+++ b/engines/gob/script.cpp
@@ -201,7 +201,7 @@ int32 Script::readInt32() {
char *Script::readString(int32 length) {
if (length < 0) {
length = 0;
- while (_totPtr[length++] != '\0');
+ while (_totPtr[length++] != '\0') { }
}
char *string = (char *) _totPtr;
diff --git a/engines/gob/sound/bgatmosphere.cpp b/engines/gob/sound/bgatmosphere.cpp
index 6ce184155e..f0977aa45b 100644
--- a/engines/gob/sound/bgatmosphere.cpp
+++ b/engines/gob/sound/bgatmosphere.cpp
@@ -25,6 +25,7 @@
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "gob/sound/bgatmosphere.h"
#include "gob/sound/sounddesc.h"
@@ -39,7 +40,7 @@ BackgroundAtmosphere::BackgroundAtmosphere(Audio::Mixer &mixer) :
_shaded = false;
_shadable = true;
- g_system->getEventManager()->registerRandomSource(_rnd, "gobBA");
+ g_eventRec.registerRandomSource(_rnd, "gobBA");
}
BackgroundAtmosphere::~BackgroundAtmosphere() {
diff --git a/engines/gob/sound/sounddesc.cpp b/engines/gob/sound/sounddesc.cpp
index b9b327d105..e8045d21f7 100644
--- a/engines/gob/sound/sounddesc.cpp
+++ b/engines/gob/sound/sounddesc.cpp
@@ -121,9 +121,9 @@ void SoundDesc::convToSigned() {
return;
if (_mixerFlags & Audio::Mixer::FLAG_16BITS) {
- uint16 *data = (uint16 *) _dataPtr;
- for (uint32 i = 0; i < _size; i++)
- data[i] ^= 0x8000;
+ byte *data = _dataPtr;
+ for (uint32 i = 0; i < _size; i++, data += 2)
+ WRITE_LE_UINT16(data, READ_LE_UINT16(data) ^ 0x8000);
} else
for (uint32 i = 0; i < _size; i++)
_dataPtr[i] ^= 0x80;
diff --git a/engines/gob/sound/soundmixer.cpp b/engines/gob/sound/soundmixer.cpp
index 68a96d3b01..eb6d7882f0 100644
--- a/engines/gob/sound/soundmixer.cpp
+++ b/engines/gob/sound/soundmixer.cpp
@@ -33,8 +33,7 @@ SoundMixer::SoundMixer(Audio::Mixer &mixer, Audio::Mixer::SoundType type) : _mix
_rate = _mixer->getOutputRate();
_end = true;
- _data8 = 0;
- _data16 = 0;
+ _data = 0;
_length = 0;
_freq = 0;
_repCount = 0;
@@ -61,9 +60,9 @@ SoundMixer::~SoundMixer() {
inline int16 SoundMixer::getData(int offset) {
if (!_16bit)
- return (int16) _data8[offset];
+ return (int16) ((int8) _data[offset]);
else
- return (int16) FROM_LE_16(_data16[offset]);
+ return (int16) READ_LE_UINT16(_data + (offset * 2));
}
bool SoundMixer::isPlaying() const {
@@ -78,8 +77,7 @@ void SoundMixer::stop(int16 fadeLength) {
Common::StackLock slock(_mutex);
if (fadeLength <= 0) {
- _data8 = 0;
- _data16 = 0;
+ _data = 0;
_end = true;
_playingSound = 0;
return;
@@ -109,13 +107,7 @@ void SoundMixer::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency,
_16bit = (sndDesc._mixerFlags & Audio::Mixer::FLAG_16BITS) != 0;
- if (_16bit) {
- _data16 = (int16 *) sndDesc.getData();
- _shift = 0;
- } else {
- _data8 = (int8 *) sndDesc.getData();
- _shift = 8;
- }
+ _data = sndDesc.getData();
_length = sndDesc.size();
_freq = frequency;
@@ -171,7 +163,7 @@ int SoundMixer::readBuffer(int16 *buffer, const int numSamples) {
Common::StackLock slock(_mutex);
for (int i = 0; i < numSamples; i++) {
- if (!_data8 && !_data16)
+ if (!_data)
return i;
if (_end || (_offset >= _length))
checkEndSample();
@@ -181,7 +173,7 @@ int SoundMixer::readBuffer(int16 *buffer, const int numSamples) {
// Linear interpolation. See sound/rate.cpp
int16 val = (_last + (((_cur - _last) * _offsetFrac +
- FRAC_HALF) >> FRAC_BITS)) << _shift;
+ FRAC_HALF) >> FRAC_BITS)) << (_16bit ? 0 : 8);
*buffer++ = (val * _fadeVol) >> 16;
_offsetFrac += _offsetInc;
@@ -211,8 +203,7 @@ int SoundMixer::readBuffer(int16 *buffer, const int numSamples) {
void SoundMixer::endFade() {
if (_fadeVolStep > 0) {
- _data8 = 0;
- _data16 = 0;
+ _data = 0;
_end = true;
_playingSound = 0;
} else {
diff --git a/engines/gob/sound/soundmixer.h b/engines/gob/sound/soundmixer.h
index 20376b5152..9e66c474e9 100644
--- a/engines/gob/sound/soundmixer.h
+++ b/engines/gob/sound/soundmixer.h
@@ -62,11 +62,9 @@ protected:
Common::Mutex _mutex;
bool _16bit;
- int _shift;
bool _end;
- int8 *_data8;
- int16 *_data16;
+ byte *_data;
uint32 _length;
uint32 _rate;
int32 _freq;
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 356eb3c643..1a8668b1c2 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -45,7 +45,6 @@ Util::Util(GobEngine *vm) : _vm(vm) {
_frameRate = 12;
_frameWaitTime = 0;
_startFrameTime = 0;
- _frameWaitLag = 0;
}
uint32 Util::getTimeKey(void) {
@@ -331,12 +330,10 @@ void Util::setFrameRate(int16 rate) {
_frameRate = rate;
_frameWaitTime = 1000 / rate;
_startFrameTime = getTimeKey();
- _frameWaitLag = 0;
}
void Util::notifyNewAnim() {
_startFrameTime = getTimeKey();
- _frameWaitLag = 0;
}
void Util::waitEndFrame() {
@@ -350,17 +347,12 @@ void Util::waitEndFrame() {
return;
}
- int32 waitTime = _frameWaitTime - _frameWaitLag;
- int32 toWait = waitTime - time;
+ int32 toWait = _frameWaitTime - time;
if (toWait > 0)
delay(toWait);
- int32 now = getTimeKey();
-
- _frameWaitLag = (now - _startFrameTime) - waitTime;
-
- _startFrameTime = now;
+ _startFrameTime = getTimeKey();
}
void Util::setScrollOffset(int16 x, int16 y) {
diff --git a/engines/gob/util.h b/engines/gob/util.h
index 82e2df94de..ef972eb68c 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -145,7 +145,6 @@ protected:
int16 _frameRate;
int16 _frameWaitTime;
uint32 _startFrameTime;
- int32 _frameWaitLag;
GobEngine *_vm;
diff --git a/engines/gob/variables.cpp b/engines/gob/variables.cpp
index 1183ec21ae..572cba0796 100644
--- a/engines/gob/variables.cpp
+++ b/engines/gob/variables.cpp
@@ -123,22 +123,6 @@ uint8 *Variables::getAddressVar8(uint32 var) {
return getAddressOff8(var * 4);
}
-const uint16 *Variables::getAddressVar16(uint32 var) const {
- return getAddressOff16(var * 4);
-}
-
-uint16 *Variables::getAddressVar16(uint32 var) {
- return getAddressOff16(var * 4);
-}
-
-const uint32 *Variables::getAddressVar32(uint32 var) const {
- return getAddressOff32(var * 4);
-}
-
-uint32 *Variables::getAddressVar32(uint32 var) {
- return getAddressOff32(var * 4);
-}
-
const char *Variables::getAddressVarString(uint32 var) const {
return getAddressOffString(var * 4);
}
@@ -155,22 +139,6 @@ uint8 *Variables::getAddressOff8(uint32 offset) {
return ((uint8 *) (_vars + offset));
}
-const uint16 *Variables::getAddressOff16(uint32 offset) const {
- return ((const uint16 *) (_vars + offset));
-}
-
-uint16 *Variables::getAddressOff16(uint32 offset) {
- return ((uint16 *) (_vars + offset));
-}
-
-const uint32 *Variables::getAddressOff32(uint32 offset) const {
- return ((const uint32 *) (_vars + offset));
-}
-
-uint32 *Variables::getAddressOff32(uint32 offset) {
- return ((uint32 *) (_vars + offset));
-}
-
const char *Variables::getAddressOffString(uint32 offset) const {
return ((const char *) (_vars + offset));
}
diff --git a/engines/gob/variables.h b/engines/gob/variables.h
index 84a4772baa..d11b91ea16 100644
--- a/engines/gob/variables.h
+++ b/engines/gob/variables.h
@@ -69,24 +69,12 @@ public:
const uint8 *getAddressVar8(uint32 var) const;
uint8 *getAddressVar8(uint32 var);
- const uint16 *getAddressVar16(uint32 var) const;
- uint16 *getAddressVar16(uint32 var);
-
- const uint32 *getAddressVar32(uint32 var) const;
- uint32 *getAddressVar32(uint32 var);
-
const char *getAddressVarString(uint32 var) const;
char *getAddressVarString(uint32 var);
const uint8 *getAddressOff8(uint32 offset) const;
uint8 *getAddressOff8(uint32 offset);
- const uint16 *getAddressOff16(uint32 offset) const;
- uint16 *getAddressOff16(uint32 offset);
-
- const uint32 *getAddressOff32(uint32 offset) const;
- uint32 *getAddressOff32(uint32 offset);
-
const char *getAddressOffString(uint32 offset) const;
char *getAddressOffString(uint32 offset);
diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp
index f708729fd8..a7399caa54 100644
--- a/engines/gob/videoplayer.cpp
+++ b/engines/gob/videoplayer.cpp
@@ -711,6 +711,9 @@ void VideoPlayer::playFrame(int16 frame, int16 breakKey,
_vm->_video->retrace();
}
+ // Subtitle
+ if (state.flags & Graphics::CoktelVideo::kStateSpeech)
+ _vm->_draw->printTotText(state.speechId);
if (modifiedPal && ((palCmd == 2) || (palCmd == 4)))
_vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0);
@@ -736,6 +739,8 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
_vm->_inter->storeKey(_vm->_util->checkKey());
if (VAR(0) == (unsigned) breakKey) {
_primaryVideo->getVideo()->disableSound();
+ // Seek to the last frame. Some scripts depend on that.
+ _primaryVideo->getVideo()->seekFrame(endFrame, SEEK_SET, true);
return true;
}
}
@@ -769,7 +774,7 @@ void VideoPlayer::writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
height = _primaryVideo->getVideo()->getHeight();
if (VAR_OFFSET(varX) == 0xFFFFFFFF)
- _primaryVideo->getVideo()->getAnchor(1, 2, x, y, width, height);
+ _primaryVideo->getVideo()->getFrameCoords(1, x, y, width, height);
WRITE_VAR_OFFSET(varX, x);
WRITE_VAR_OFFSET(varY, y);
@@ -794,13 +799,4 @@ void VideoPlayer::evalBgShading(Graphics::CoktelVideo &video) {
_vm->_sound->bgUnshade();
}
-void VideoPlayer::notifyPaused(uint32 duration) {
- if (_primaryVideo->isOpen())
- _primaryVideo->getVideo()->notifyPaused(duration);
-
- for (uint i = 0; i < _videoSlots.size(); i++)
- if (_videoSlots[i] && _videoSlots[i]->isOpen())
- _videoSlots[i]->getVideo()->notifyPaused(duration);
-}
-
} // End of namespace Gob
diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h
index 532d216d7e..28e72ab43a 100644
--- a/engines/gob/videoplayer.h
+++ b/engines/gob/videoplayer.h
@@ -103,8 +103,6 @@ public:
void writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
int16 varFrames, int16 varWidth, int16 varHeight);
- void notifyPaused(uint32 duration);
-
private:
class Video {
public:
diff --git a/engines/groovie/cell.cpp b/engines/groovie/cell.cpp
index 3bc8650aa6..c257ac108e 100644
--- a/engines/groovie/cell.cpp
+++ b/engines/groovie/cell.cpp
@@ -27,156 +27,773 @@
namespace Groovie {
-CellGame::CellGame(byte *board) :
- _board(board) {
+CellGame::CellGame() {
_startX = _startY = _endX = _endY = 255;
-}
-int8 CellGame::calcMove(byte *origboard, uint8 color, uint8 depth) {
- uint8 i, j;
- int8 di, dj;
- uint8 bestStartX, bestStartY, bestEndX, bestEndY;
- int8 bestDiff = -100;
- int8 origBoardCount = countBoard(origboard, color);
- int8 currDiff = -100;
- byte *newboard;
- uint8 boardmemsize = sizeof(byte) * BOARDSIZE * BOARDSIZE;
- uint8 oppColor = 3 - color;
+ _stack_index = _boardStackPtr = 0;
+ _flag4 = false;
+ _flag2 = false;
+ _coeff3 = 0;
- bestStartX = bestStartY = bestEndX = bestEndY = 255;
- newboard = (byte*) malloc(boardmemsize);
- memcpy(newboard, origboard, boardmemsize);
+ _moveCount = 0;
+}
- if (0 == depth) {
+byte CellGame::getStartX() {
+ if (_startX > BOARDSIZE) {
+ warning ("CellGame::getStartX: not calculated yet (%d)!", _startX);
return 0;
+ } else {
+ return _startX;
+ }
+}
+
+byte CellGame::getStartY() {
+ if (_startY > BOARDSIZE) {
+ warning ("CellGame::getStartY: not calculated yet (%d)!", _startY);
+ return 6;
+ } else {
+ return _startY;
+ }
+}
+
+byte CellGame::getEndX() {
+ if (_endX > BOARDSIZE) {
+ warning ("CellGame::getEndX: not calculated yet (%d)!", _endX);
+ return 1;
+ } else {
+ return _endX;
+ }
+}
+
+byte CellGame::getEndY() {
+ if (_endY > BOARDSIZE) {
+ warning ("CellGame::getEndY: not calculated yet (%d)!", _endY);
+ return 6;
+ } else {
+ return _endY;
+ }
+}
+
+CellGame::~CellGame() {
+}
+
+const int8 possibleMoves[][9] = {
+ { 1, 7, 8, -1 },
+ { 0, 2, 7, 8, 9, -1 },
+ { 1, 3, 8, 9, 10, -1 },
+ { 2, 4, 9, 10, 11, -1 },
+ { 3, 5, 10, 11, 12, -1 },
+ { 4, 6, 11, 12, 13, -1 }, // 5
+ { 5, 12, 13, -1 },
+ { 0, 1, 8, 14, 15, -1 },
+ { 0, 1, 2, 7, 9, 14, 15, 16, -1 },
+ { 1, 2, 3, 8, 10, 15, 16, 17, -1 },
+ { 2, 3, 4, 9, 11, 16, 17, 18, -1 }, // 10
+ { 3, 4, 5, 10, 12, 17, 18, 19, -1 },
+ { 4, 5, 6, 11, 13, 18, 19, 20, -1 },
+ { 5, 6, 12, 19, 20, -1 },
+ { 7, 8, 15, 21, 22, -1 },
+ { 7, 8, 9, 14, 16, 21, 22, 23, -1 }, // 15
+ { 8, 9, 10, 15, 17, 22, 23, 24, -1 },
+ { 9, 10, 11, 16, 18, 23, 24, 25, -1 },
+ { 10, 11, 12, 17, 19, 24, 25, 26, -1 },
+ { 11, 12, 13, 18, 20, 25, 26, 27, -1 },
+ { 12, 13, 19, 26, 27, -1 }, // 20
+ { 14, 15, 22, 28, 29, -1 },
+ { 14, 15, 16, 21, 23, 28, 29, 30, -1 },
+ { 15, 16, 17, 22, 24, 29, 30, 31, -1 },
+ { 16, 17, 18, 23, 25, 30, 31, 32, -1 },
+ { 17, 18, 19, 24, 26, 31, 32, 33, -1 }, // 25
+ { 18, 19, 20, 25, 27, 32, 33, 34, -1 },
+ { 19, 20, 26, 33, 34, -1 },
+ { 21, 22, 29, 35, 36, -1 },
+ { 21, 22, 23, 28, 30, 35, 36, 37, -1 },
+ { 22, 23, 24, 29, 31, 36, 37, 38, -1 }, // 30
+ { 23, 24, 25, 30, 32, 37, 38, 39, -1 },
+ { 24, 25, 26, 31, 33, 38, 39, 40, -1 },
+ { 25, 26, 27, 32, 34, 39, 40, 41, -1 },
+ { 26, 27, 33, 40, 41, -1 },
+ { 28, 29, 36, 42, 43, -1 }, // 35
+ { 28, 29, 30, 35, 37, 42, 43, 44, -1 },
+ { 29, 30, 31, 36, 38, 43, 44, 45, -1 },
+ { 30, 31, 32, 37, 39, 44, 45, 46, -1 },
+ { 31, 32, 33, 38, 40, 45, 46, 47, -1 },
+ { 32, 33, 34, 39, 41, 46, 47, 48, -1 }, // 40
+ { 33, 34, 40, 47, 48, -1 },
+ { 35, 36, 43, -1 },
+ { 35, 36, 37, 42, 44, -1 },
+ { 36, 37, 38, 43, 45, -1 },
+ { 37, 38, 39, 44, 46, -1 }, // 45
+ { 38, 39, 40, 45, 47, -1 },
+ { 39, 40, 41, 46, 48, -1 },
+ { 40, 41, 47, -1 }
+};
+
+
+const int8 strategy2[][17] = {
+ { 2, 9, 14, 15, 16, -1 },
+ { 3, 10, 14, 15, 16, 17, -1 },
+ { 0, 4, 7, 11, 14, 15, 16, 17, 18, -1 },
+ { 1, 5, 8, 12, 15, 16, 17, 18, 19, -1 },
+ { 2, 6, 9, 13, 16, 17, 18, 19, 20, -1 },
+ { 3, 10, 17, 18, 19, 20, -1 }, // 5
+ { 4, 11, 18, 19, 20, -1 },
+ { 2, 9, 16, 21, 22, 23, -1 },
+ { 3, 10, 17, 21, 22, 23, 24, -1 },
+ { 0, 4, 7, 11, 14, 18, 21, 22, 23, 24, 25, -1 },
+ { 1, 5, 8, 12, 15, 19, 22, 23, 24, 25, 26, -1 }, // 10
+ { 2, 6, 9, 13, 16, 20, 23, 24, 25, 26, 27, -1 },
+ { 3, 10, 17, 24, 25, 26, 27, -1 },
+ { 4, 11, 18, 25, 26, 27, -1 },
+ { 0, 1, 2, 9, 16, 23, 28, 29, 30, -1 },
+ { 0, 1, 2, 3, 10, 17, 24, 28, 29, 30, 31, -1 }, // 15
+ { 0, 1, 2, 3, 4, 7, 11, 14, 18, 21, 25, 28, 29, 30, 31, 32, -1 },
+ { 1, 2, 3, 4, 5, 8, 12, 15, 19, 22, 26, 29, 30, 31, 32, 33, -1 },
+ { 2, 3, 4, 5, 6, 9, 13, 16, 20, 23, 27, 30, 31, 32, 33, 34, -1 },
+ { 3, 4, 5, 6, 10, 17, 24, 31, 32, 33, 34, -1 },
+ { 4, 5, 6, 11, 18, 25, 32, 33, 34, -1 }, // 20
+ { 7, 8, 9, 16, 23, 30, 35, 36, 37, -1 },
+ { 7, 8, 9, 10, 17, 24, 31, 35, 36, 37, 38, -1 },
+ { 7, 8, 9, 10, 11, 14, 18, 21, 25, 28, 32, 35, 36, 37, 38, 39, -1 },
+ { 8, 9, 10, 11, 12, 15, 19, 22, 26, 29, 33, 36, 37, 38, 39, 40, -1 },
+ { 9, 10, 11, 12, 13, 16, 20, 23, 27, 30, 34, 37, 38, 39, 40, 41, -1 }, // 25
+ { 10, 11, 12, 13, 17, 24, 31, 38, 39, 40, 41, -1 },
+ { 11, 12, 13, 18, 25, 32, 39, 40, 41, -1 },
+ { 14, 15, 16, 23, 30, 37, 42, 43, 44, -1 },
+ { 14, 15, 16, 17, 24, 31, 38, 42, 43, 44, 45, -1 },
+ { 14, 15, 16, 17, 18, 21, 25, 28, 32, 35, 39, 42, 43, 44, 45, 46, -1 }, // 30
+ { 15, 16, 17, 18, 19, 22, 26, 29, 33, 36, 40, 43, 44, 45, 46, 47, -1 },
+ { 16, 17, 18, 19, 20, 23, 27, 30, 34, 37, 41, 44, 45, 46, 47, 48, -1 },
+ { 17, 18, 19, 20, 24, 31, 38, 45, 46, 47, 48, -1 },
+ { 18, 19, 20, 25, 32, 39, 46, 47, 48, -1 },
+ { 21, 22, 23, 30, 37, 44, -1 }, // 35
+ { 21, 22, 23, 24, 31, 38, 45, -1 },
+ { 21, 22, 23, 24, 25, 28, 32, 35, 39, 42, 46, -1 },
+ { 22, 23, 24, 25, 26, 29, 33, 36, 40, 43, 47, -1 },
+ { 23, 24, 25, 26, 27, 30, 34, 37, 41, 44, 48, -1 },
+ { 24, 25, 26, 27, 31, 38, 45, -1 }, // 40
+ { 25, 26, 27, 32, 39, 46, -1 },
+ { 28, 29, 30, 37, 44, -1 },
+ { 28, 29, 30, 31, 38, 45, -1 },
+ { 28, 29, 30, 31, 32, 35, 39, 42, 46, -1 },
+ { 29, 30, 31, 32, 33, 36, 40, 43, 47, -1 }, // 45
+ { 30, 31, 32, 33, 34, 37, 41, 44, 48, -1 },
+ { 31, 32, 33, 34, 38, 45, -1 },
+ { 32, 33, 34, 39, 46, -1 }
+};
+
+void CellGame::copyToTempBoard() {
+ for (int i = 0; i < 53; ++i) {
+ _tempBoard[i] = _board[i];
+ }
+}
+
+void CellGame::copyFromTempBoard() {
+ for (int i = 0; i < 53; ++i) {
+ _board[i] = _tempBoard[i];
}
+}
+
+void CellGame::copyToShadowBoard() {
+ _board[53] = 0;
+ _board[55] = 1;
+ _board[56] = 0;
+
+ for (int i = 0; i < 49; ++i) {
+ _shadowBoard[i] = _board[i];
+ }
+}
+
+void CellGame::pushBoard() {
+ assert(_boardStackPtr < 57 * 9);
- for (i = 0; BOARDSIZE > i; i++) { // For every square on the board
- for (j = 0; BOARDSIZE > j; j++) { //
- if (color == *(origboard + i + (BOARDSIZE * j))) { // If the square is the desired colour
- for (di = -2; 2 >= di; di++) { // Check every square two or less in every direction
- for (dj = -2; 2 >= dj; dj++) { //
- if (di != 0 || dj != 0) { // Don't allow a move onto itself
- debugC(7, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Testing move %d, %d-> %d, %d", depth, i, j, i+di, j+dj);
- if (validMove(origboard, color, i+di, j+dj)) {
- int8 nextlevel;
- debugC(5, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Valid move %d, %d-> %d, %d", depth, i, j, i+di, j+dj);
- execMove (newboard, color, i, j, i+di, j+dj);
-
- nextlevel = calcMove (newboard, oppColor, depth - 1);
- debugC(5, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Next level down returned %d", depth, nextlevel);
- currDiff = countBoard(newboard, color) - origBoardCount - nextlevel;
- if (currDiff > bestDiff) {
- debugC(4, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Found new best move (diff of %d): %d, %d-> %d, %d", depth, currDiff, i, j, i+di, j+dj);
- bestDiff = currDiff;
- bestStartX = i;
- bestStartY = j;
- bestEndX = i+di;
- bestEndY = j+dj;
-
- }
- // TODO: ideal would be to revert the move, rather than copy the board again. I think.
- memcpy(newboard, origboard, boardmemsize);
- }
- }
+ for (int i = 0; i < 57; ++i)
+ _boardStack[_boardStackPtr + i] = _board[i];
+ _boardStackPtr += 57;
+}
+
+void CellGame::popBoard() {
+ assert(_boardStackPtr > 0);
+
+ _boardStackPtr -= 57;
+ for (int i = 0; i < 57; ++i) {
+ _board[i] = _boardStack[_boardStackPtr + i];
+ }
+}
+
+void CellGame::pushShadowBoard() {
+ assert(_boardStackPtr < 57 * 9);
+
+ for (int i = 0; i < 57; ++i)
+ _boardStack[_boardStackPtr + i] = _shadowBoard[i];
+
+ _boardStackPtr += 57;
+}
+
+void CellGame::popShadowBoard() {
+ assert(_boardStackPtr > 0);
+
+ _boardStackPtr -= 57;
+
+ for (int i = 0; i < 57; ++i) {
+ _shadowBoard[i] = _boardStack[_boardStackPtr + i];
+ }
+}
+
+void CellGame::clearMoves() {
+ _stack_startXY[0] = _board[53];
+ _stack_endXY[0] = _board[54];
+ _stack_pass[0] = _board[55];
+
+ _stack_index = 1;
+}
+
+void CellGame::pushMove() {
+ _stack_startXY[_stack_index] = _board[53];
+ _stack_endXY[_stack_index] = _board[54];
+ _stack_pass[_stack_index] = _board[55];
+
+ _stack_index++;
+}
+
+void CellGame::resetMove() {
+ _board[53] = 0;
+ _board[54] = 0;
+ _board[55] = 0;
+}
+
+void CellGame::takeCells(uint16 whereTo, int8 color) {
+ int cellN;
+ const int8 *str;
+
+ str = possibleMoves[whereTo];
+ while (1) {
+ cellN = *str++;
+ if (cellN < 0)
+ break;
+ if (_tempBoard[cellN] > 0) {
+ --_tempBoard[_tempBoard[cellN] + 48];
+ _tempBoard[cellN] = color;
+ ++_tempBoard[color + 48];
+ }
+ }
+}
+
+void CellGame::countAllCells() {
+ _board[49] = 0;
+ _board[50] = 0;
+ _board[51] = 0;
+ _board[52] = 0;
+
+ for (int i = 0; i < 49; i++) {
+ switch (_board[i]) {
+ case 1: // CELL_BLUE
+ _board[49]++;
+ break;
+ case 2: // CELL_GREEN
+ _board[50]++;
+ break;
+ case 3:
+ _board[51]++;
+ break;
+ case 4:
+ _board[52]++;
+ break;
+ }
+ }
+}
+
+int CellGame::countCellsOnTempBoard(int8 color) {
+ const int8 *str;
+ int res = 0;
+ int i;
+
+ for (i = 0; i < 49; i++)
+ _boardSum[i] = 0;
+
+ for (i = 0; i < 49; i++) {
+ if (_tempBoard[i] == color) {
+ for (str = possibleMoves[i]; *str > 0; str++) {
+ if (!_tempBoard[*str])
+ ++_boardSum[*str];
+ }
+ }
+ }
+
+ for (i = 0; i < 49; i++)
+ res += _boardSum[i];
+
+ return res;
+}
+
+bool CellGame::canMoveFunc1(int8 color) {
+ const int8 *str;
+
+ if (_board[55] == 1) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &possibleMoves[_board[53]][_board[56]];
+ for (;_board[56] < 8; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_shadowBoard[_board[54]]) {
+ _shadowBoard[_board[54]] = -1;
+ ++_board[56];
+ return true;
}
}
+ _board[56] = 0;
+ }
+ }
+ _board[53] = 0;
+ _board[55] = 2;
+ _board[56] = 0;
+ }
+ if (_board[55] == 2) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &strategy2[_board[53]][_board[56]];
+ for (;_board[56] < 16; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_board[_board[54]]) {
+ ++_board[56];
+ return true;
+ }
+ }
+ _board[56] = 0;
}
}
}
- _startX = bestStartX;
- _startY = bestStartY;
- _endX = bestEndX;
- _endY = bestEndY;
-
- debugC(2, kGroovieDebugCell | kGroovieDebugAll, "Depth: %d: Best move is (diff of %d): %d, %d-> %d, %d", depth, bestDiff, _startX, _startY, _endX, _endY);
- free(newboard);
- debugC(5, kGroovieDebugCell | kGroovieDebugAll, "Freed newboard");
- return bestDiff;
+ return false;
}
-void CellGame::execMove(byte *board, uint8 color, int8 startX, int8 startY, int8 endX, int8 endY) {
- int8 i, j;
- uint8 colorToEat = 3 - color; // The opposite of the colour passed: 2 -> 1, 1 -> 2
+bool CellGame::canMoveFunc3(int8 color) {
+ const int8 *str;
+
+ if (_board[55] == 1) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &possibleMoves[_board[53]][_board[56]];
+ for (;_board[56] < 8; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_shadowBoard[_board[54]]) {
+ _shadowBoard[_board[54]] = -1;
+ ++_board[56];
+ return true;
+ }
+ }
+ _board[56] = 0;
+ }
+ }
- if (abs(endX - startX) == 2 || abs(endY - startY) == 2) {
- *(board + startX + BOARDSIZE * startY) = 0;
+ _board[53] = 0;
+ _board[55] = 2;
+ _board[56] = 0;
+ for (int i = 0; i < 49; ++i)
+ _shadowBoard[i] = _board[i];
+ }
+ if (_board[55] == 2) {
+ for (; _board[53] < 49; _board[53]++) {
+ if (_shadowBoard[_board[53]] == color) {
+ str = &strategy2[_board[53]][_board[56]];
+ for (;_board[56] < 16; _board[56]++) {
+ _board[54] = *str++;
+ if (_board[54] < 0)
+ break;
+ if (!_shadowBoard[_board[54]]) {
+ _shadowBoard[_board[54]] = -1;
+ ++_board[56];
+ return true;
+ }
+ }
+ _board[56] = 0;
+ }
+ }
}
- *(board + endX + BOARDSIZE * endY) = color;
+ return false;
+}
+
+bool CellGame::canMoveFunc2(int8 color) {
+ const int8 *str;
- for (i = (endX - 1); endX + 1 >= i; i++) {
- for (j = (endY - 1); endY + 1 >= j; j++) {
- if (BOARDSIZE > i && BOARDSIZE > j && 0 <= i && 0 <= j) { // Don't wrap around the board edges!
- uint8 offset = i + BOARDSIZE * j;
- if (colorToEat == *(board + offset)) {
- *(board + offset) = color;
+ while (1) {
+ while (_board[_board[54]]) {
+ ++_board[54];
+ if (_board[54] >= 49)
+ return false;
+ }
+ if (!_board[55]) {
+ str = possibleMoves[_board[54]];
+ while (1) {
+ _board[53] = *str++;
+ if (_board[53] < 0)
+ break;
+ if (_board[_board[53]] == color) {
+ _board[55] = 1;
+ return true;
+ }
+ }
+ _board[55] = 1;
+ }
+ if (_board[55] == 1) {
+ _board[55] = 2;
+ _board[56] = 0;
+ }
+ if (_board[55] == 2) {
+ str = &strategy2[_board[54]][_board[56]];
+ for (; _board[56] < 16; _board[56]++) {
+ _board[53] = *str++;
+ if (_board[53] < 0)
+ break;
+ if (_board[_board[53]] == color) {
+ ++_board[56];
+ return true;
}
}
+ ++_board[54];
+ _board[55] = 0;
+ if (_board[54] >= 49)
+ break;
}
}
+ return false;
+}
+
+void CellGame::makeMove(int8 color) {
+ copyToTempBoard();
+ _tempBoard[_board[54]] = color;
+ ++_tempBoard[color + 48];
+ if (_board[55] == 2) {
+ _tempBoard[_board[53]] = 0;
+ --_tempBoard[color + 48];
+ }
+ takeCells(_board[54], color);
}
-bool CellGame::validMove(byte *board, uint8 color, int8 endX, int8 endY) {
- if (0 > endX || 0 > endY || BOARDSIZE <= endX || BOARDSIZE <= endY) { // Move is out of bounds
- return false;
+int CellGame::getBoardWeight(int8 color1, int8 color2) {
+ int8 celln;
+ const int8 *str;
+ byte cellCnt[8];
+
+ str = possibleMoves[_board[54]];
+ cellCnt[1] = _board[49];
+ cellCnt[2] = _board[50];
+ cellCnt[3] = _board[51];
+ cellCnt[4] = _board[52];
+ if (_board[55] != 2)
+ ++cellCnt[color2];
+ celln = *str++;
+
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
}
- if (0 == *(board + endX + (BOARDSIZE * endY))) {
- return true;
+ celln = *str++;
+
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
}
- return false;
+ celln = *str++;
+
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
+ }
+ while (1) {
+ celln = *str++;
+ if (celln < 0)
+ break;
+ celln = _board[celln];
+ if (celln > 0) {
+ --cellCnt[celln];
+ ++cellCnt[color2];
+ }
+ }
+ return _coeff3 + 2 * (2 * cellCnt[color1] - cellCnt[1] - cellCnt[2] - cellCnt[3] - cellCnt[4]);
}
-uint8 CellGame::countBoard(byte *board, uint8 color) {
- uint8 total = 0;
- for (uint8 i = 0; BOARDSIZE > i; i++) {
- for (uint8 j = 0; BOARDSIZE > j; j++) {
- if (color == *(board + i + (BOARDSIZE * j))) {
- total++;
+void CellGame::chooseBestMove(int8 color) {
+ int moveIndex = 0;
+ int curWeight;
+ int bestWeight;
+
+ if (_flag2) {
+ bestWeight = 32767;
+ for (int i = 0; i < _stack_index; ++i) {
+ _board[53] = _stack_startXY[i];
+ _board[54] = _stack_endXY[i];
+ _board[55] = _stack_pass[i];
+ makeMove(color);
+ curWeight = countCellsOnTempBoard(color);
+ if (curWeight <= bestWeight) {
+ if (curWeight < bestWeight)
+ moveIndex = 0;
+ bestWeight = curWeight;
+ _stack_startXY[moveIndex] = _board[53];
+ _stack_endXY[moveIndex] = _board[54];
+ _stack_pass[moveIndex++] = _board[55];
}
}
+ _stack_index = moveIndex;
}
- return total;
+
+ _startX = _stack_startXY[0] % 7;
+ _startY = _stack_startXY[0] / 7;
+ _endX = _stack_endXY[0] % 7;
+ _endY = _stack_endXY[0] / 7;
}
-byte CellGame::getStartX() {
- if (_startX > BOARDSIZE) {
- warning ("CellGame::getStartX: not calculated yet!");
- return 0;
+int8 CellGame::calcBestWeight(int8 color1, int8 color2, uint16 depth, int bestWeight) {
+ int8 res;
+ int8 curColor;
+ bool canMove;
+ int type;
+ uint16 i;
+ int8 currBoardWeight;
+ int8 weight;
+
+ pushBoard();
+ copyFromTempBoard();
+ curColor = color2;
+ for (i = 0;; ++i) {
+ if (i >= 4) {
+ res = _coeff3 + 2 * (2 * _board[color1 + 48] - _board[49] - _board[50] - _board[51] - _board[52]);
+ popBoard();
+ return res;
+ }
+ ++curColor;
+ if (curColor > 4)
+ curColor = 1;
+
+ if (_board[curColor + 48]) {
+ if (_board[curColor + 48] >= 49 - _board[49] - _board[50] - _board[51] - _board[52]) {
+ resetMove();
+ canMove = canMoveFunc2(curColor);
+ type = 1;
+ } else {
+ copyToShadowBoard();
+ if (depth == 1) {
+ canMove = canMoveFunc3(curColor);
+ type = 3;
+ } else {
+ canMove = canMoveFunc1(curColor);
+ type = 2;
+ }
+ }
+ if (canMove)
+ break;
+ }
+ }
+ if (_flag1) {
+ popBoard();
+ return bestWeight + 1;
+ }
+
+ depth -= 1;
+ if (depth) {
+ makeMove(curColor);
+ if (type == 1) {
+ res = calcBestWeight(color1, curColor, depth, bestWeight);
+ } else {
+ pushShadowBoard();
+ res = calcBestWeight(color1, curColor, depth, bestWeight);
+ popShadowBoard();
+ }
} else {
- return _startX;
+ res = getBoardWeight(color1, curColor);
+ }
+
+ if ((res < bestWeight && color1 != curColor) || _flag4) {
+ popBoard();
+ return res;
+ }
+
+ currBoardWeight = _coeff3 + 2 * (2 * _board[color1 + 48] - _board[49] - _board[50] - _board[51] - _board[52]);
+ while (1) {
+ if (type == 1) {
+ canMove = canMoveFunc2(curColor);
+ } else if (type == 2) {
+ canMove = canMoveFunc1(curColor);
+ } else {
+ canMove = canMoveFunc3(curColor);
+ }
+
+ if (!canMove)
+ break;
+ if (_flag1) {
+ popBoard();
+ return bestWeight + 1;
+ }
+ if (_board[55] == 2) {
+ if (getBoardWeight(color1, curColor) == currBoardWeight)
+ continue;
+ }
+ if (!depth) {
+ weight = getBoardWeight(color1, curColor);
+ if (type == 1) {
+ if (_board[55] == 2)
+ _board[56] = 16;
+ }
+ } else {
+ makeMove(curColor);
+ if (type != 1) {
+ pushShadowBoard();
+ weight = calcBestWeight(color1, curColor, depth, bestWeight);
+ popShadowBoard();
+ } else {
+ weight = calcBestWeight(color1, curColor, depth, bestWeight);
+ }
+ }
+ if ((weight < res && color1 != curColor) || (weight > res && color1 == curColor))
+ res = weight;
+
+ if ((res < bestWeight && color1 != curColor) || _flag4)
+ break;
}
+ popBoard();
+
+ return res;
}
-byte CellGame::getStartY() {
- if (_startY > BOARDSIZE) {
- warning ("CellGame::getStartY: not calculated yet!");
- return 6;
+int16 CellGame::doGame(int8 color, int depth) {
+ bool canMove;
+ int type;
+ int8 currBoardWeight;
+ int8 w1;
+ int8 w2;
+
+ countAllCells();
+ if (_board[color + 48] >= 49 - _board[49] - _board[50] - _board[51] - _board[52]) {
+ resetMove();
+ canMove = canMoveFunc2(color);
+ type = true;
} else {
- return _startY;
+ copyToShadowBoard();
+ canMove = canMoveFunc1(color);
+ type = false;
}
-}
-byte CellGame::getEndX() {
- if (_endX > BOARDSIZE) {
- warning ("CellGame::getEndX: not calculated yet!");
+ if (canMove) {
+ if (_board[color + 48] - _board[49] - _board[50] - _board[51] - _board[52] == 0)
+ depth = 0;
+ _coeff3 = 0;
+ if (_board[55] == 1)
+ _coeff3 = 1;
+ clearMoves();
+ if (depth) {
+ makeMove(color);
+ _flag4 = false;
+ if (type) {
+ w2 = calcBestWeight(color, color, depth, -127);
+ } else {
+ pushShadowBoard();
+ w2 = calcBestWeight(color, color, depth, -127);
+ popShadowBoard();
+ }
+ } else {
+ w2 = getBoardWeight(color, color);
+ }
+ currBoardWeight = 2 * (2 * _board[color + 48] - _board[49] - _board[50] - _board[51] - _board[52]);
+ while (1) {
+ if (type)
+ canMove = canMoveFunc2(color);
+ else
+ canMove = canMoveFunc1(color);
+
+ if (!canMove)
+ break;
+ if (_flag1)
+ break;
+ _coeff3 = 0;
+ if (_board[55] == 2) {
+ if (getBoardWeight(color, color) == currBoardWeight)
+ continue;
+ }
+ if (_board[55] == 1)
+ _coeff3 = 1;
+ if (depth) {
+ makeMove(color);
+ _flag4 = false;
+ if (type) {
+ w1 = calcBestWeight(color, color, depth, w2);
+ } else {
+ pushShadowBoard();
+ w1 = calcBestWeight(color, color, depth, w2);
+ popShadowBoard();
+ }
+ } else {
+ w1 = getBoardWeight(color, color);
+ }
+ if (w1 == w2)
+ pushMove();
+
+ if (w1 > w2) {
+ clearMoves();
+ w2 = w1;
+ }
+ }
+ chooseBestMove(color);
return 1;
- } else {
- return _endX;
}
+
+ return 0;
}
-byte CellGame::getEndY() {
- if (_endY > BOARDSIZE) {
- warning ("CellGame::getEndY: not calculated yet!");
- return 6;
+const int8 depths[] = { 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2, 3, 2, 2, 3, 3, 2, 3, 3, 3 };
+
+int16 CellGame::calcMove(int8 color, uint16 depth) {
+ int result;
+
+ _flag1 = false;
+ ++_moveCount;
+ if (depth) {
+ if (depth == 1) {
+ _flag2 = true;
+ result = doGame(color, 0);
+ } else {
+ int newDepth;
+
+ newDepth = depths[3 * (depth - 2) + _moveCount % 3];
+ _flag2 = true;
+ if (newDepth >= 20) {
+ assert(0); // This branch is not implemented
+ } else {
+ result = doGame(color, newDepth);
+ }
+ }
} else {
- return _endY;
+ _flag2 = false;
+ result = doGame(color, depth);
}
+ return result;
}
-CellGame::~CellGame() {
+int CellGame::playStauf(byte color, uint16 depth, byte *scriptBoard) {
+ int i;
+
+ for (i = 0; i < 49; i++, scriptBoard++) {
+ _board[i] = 0;
+ if (*scriptBoard == 50)
+ _board[i] = 1;
+ if (*scriptBoard == 66)
+ _board[i] = 2;
+ }
+ for (i = 49; i < 57; i++)
+ _board[i] = 0;
+
+ return calcMove(color, depth);
}
+
} // End of Groovie namespace
diff --git a/engines/groovie/cell.h b/engines/groovie/cell.h
index 70e135b62d..39ee529beb 100644
--- a/engines/groovie/cell.h
+++ b/engines/groovie/cell.h
@@ -29,6 +29,7 @@
#include "common/file.h"
#include "common/util.h"
+#include "groovie/cell.h"
#include "groovie/groovie.h"
#define BOARDSIZE 7
@@ -43,24 +44,59 @@ class Script;
class CellGame {
public:
- CellGame(byte *board);
+ CellGame();
~CellGame();
- int8 calcMove(byte *origboard, uint8 color, uint8 depth);
byte getStartX();
byte getStartY();
byte getEndX();
byte getEndY();
+ int playStauf(byte color, uint16 depth, byte *scriptBoard);
private:
- bool validMove(byte *board, uint8 color, int8 endX, int8 endY);
- void execMove(byte *board, uint8 color, int8 startX, int8 startY, int8 endX, int8 endY);
- uint8 countBoard(byte* board, uint8 color);
- byte *_board;
+ void copyToTempBoard();
+ void copyFromTempBoard();
+ void copyToShadowBoard();
+ void pushBoard();
+ void popBoard();
+ void pushShadowBoard();
+ void popShadowBoard();
+ void clearMoves();
+ void pushMove();
+ void resetMove();
+ bool canMoveFunc1(int8 color);
+ bool canMoveFunc2(int8 color);
+ bool canMoveFunc3(int8 color);
+ void takeCells(uint16 whereTo, int8 color);
+ void countAllCells();
+ int countCellsOnTempBoard(int8 color);
+ void makeMove(int8 color);
+ int getBoardWeight(int8 color1, int8 color2);
+ void chooseBestMove(int8 color);
+ int8 calcBestWeight(int8 color1, int8 color2, uint16 depth, int bestWeight);
+ int16 doGame(int8 color, int depth);
+ int16 calcMove(int8 color, uint16 depth);
byte _startX;
byte _startY;
byte _endX;
byte _endY;
+
+ int8 _board[57];
+ int8 _tempBoard[58];
+ int8 _shadowBoard[64];
+ int8 _boardStack[570];
+ int _boardStackPtr;
+
+ int8 _boardSum[58];
+
+ int8 _stack_startXY[128];
+ int8 _stack_endXY[128];
+ int8 _stack_pass[128];
+ int _stack_index;
+
+ int _coeff3;
+ bool _flag1, _flag2, _flag4;
+ int _moveCount;
};
} // End of Groovie namespace
diff --git a/engines/groovie/script.cpp b/engines/groovie/script.cpp
index 6dd1124fce..86713ee3e6 100644
--- a/engines/groovie/script.cpp
+++ b/engines/groovie/script.cpp
@@ -33,6 +33,7 @@
#include "common/config-manager.h"
#include "common/endian.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#define NUM_OPCODES 90
@@ -61,7 +62,7 @@ static void debugScript(int level, bool nl, const char *s, ...) {
Script::Script(GroovieEngine *vm, EngineVersion version) :
_code(NULL), _savedCode(NULL), _stacktop(0),
_debugger(NULL), _vm(vm),
- _videoFile(NULL), _videoRef(0), _font(NULL) {
+ _videoFile(NULL), _videoRef(0), _font(NULL), _staufsMove(NULL) {
// Initialize the opcode set depending on the engine version
switch (version) {
case kGroovieT7G:
@@ -73,7 +74,7 @@ Script::Script(GroovieEngine *vm, EngineVersion version) :
}
// Initialize the random source
- _vm->_system->getEventManager()->registerRandomSource(_random, "GroovieScripts");
+ g_eventRec.registerRandomSource(_random, "GroovieScripts");
// Prepare the variables
_bitflags = 0;
@@ -196,6 +197,10 @@ void Script::directGameLoad(int slot) {
// TODO: We'll probably need to start by running the beginning of the
// script to let it do the soundcard initialization and then do the
// actual loading.
+
+ // Due to HACK above, the call to check valid save slots is not run.
+ // As this is where we load save names, manually call it here.
+ o_checkvalidsaves();
}
void Script::step() {
@@ -1391,32 +1396,21 @@ void Script::o_sub() {
}
void Script::o_cellmove() {
- uint16 arg = readScript8bits();
+ uint16 depth = readScript8bits();
byte *scriptBoard = &_variables[0x19];
- byte *board = (byte *) malloc (BOARDSIZE * BOARDSIZE * sizeof(byte));
byte startX, startY, endX, endY;
- debugScript(1, true, "CELL MOVE var[0x%02X]", arg);
-
- // Arguments used by the original implementation: (2, arg, scriptBoard)
- for (int y = 0; y < 7; y++) {
- for (int x = 0; x < 7; x++) {
- uint8 offset = x + BOARDSIZE * y;
- *(board + offset) = 0;
- if (*scriptBoard == 0x32) *(board + offset) = CELL_BLUE;
- if (*scriptBoard == 0x42) *(board + offset) = CELL_GREEN;
- scriptBoard++;
- debugScript(1, false, "%d", *(board + offset));
- }
- debugScript(1, false, "\n");
- }
+ debugScript(1, true, "CELL MOVE var[0x%02X]", depth);
- CellGame staufsMove((byte *) board);
- staufsMove.calcMove((byte *) board, CELL_GREEN, 2);
- startX = staufsMove.getStartX();
- startY = staufsMove.getStartY();
- endX = staufsMove.getEndX();
- endY = staufsMove.getEndY();
+ if (!_staufsMove)
+ _staufsMove = new CellGame;
+
+ _staufsMove->playStauf(2, depth, scriptBoard);
+
+ startX = _staufsMove->getStartX();
+ startY = _staufsMove->getStartY();
+ endX = _staufsMove->getEndX();
+ endY = _staufsMove->getEndY();
// Set the movement origin
setVariable(0, startY); // y
@@ -1424,8 +1418,6 @@ void Script::o_cellmove() {
// Set the movement destination
setVariable(2, endY);
setVariable(3, endX);
-
- free(board);
}
void Script::o_returnscript() {
diff --git a/engines/groovie/script.h b/engines/groovie/script.h
index 8a95f093ce..4ff79b36b6 100644
--- a/engines/groovie/script.h
+++ b/engines/groovie/script.h
@@ -40,6 +40,7 @@ enum EngineVersion {
};
class GroovieEngine;
+class CellGame;
class Script {
friend class Debugger;
@@ -121,6 +122,8 @@ private:
Common::String _debugString;
uint16 _oldInstruction;
+ CellGame *_staufsMove;
+
// Helper functions
uint8 getCodeByte(uint16 address);
uint8 readScript8bits();
diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp
index 85d974f675..d9924d233b 100644
--- a/engines/kyra/gui.cpp
+++ b/engines/kyra/gui.cpp
@@ -538,18 +538,18 @@ int MainMenu::handle(int dim) {
int item = (mouse.y - menuRect.top) / fh;
if (item != selected) {
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5);
- printString(_static.strings[item], textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5);
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
+ printString("%s", textPos, menuRect.top + item * fh, _static.menuTable[6], 0, 5, _static.strings[item]);
selected = item;
}
if (mousePressed) {
for (int i = 0; i < 3; i++) {
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5);
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[5], 0, 5, _static.strings[selected]);
_screen->updateScreen();
_system->delayMillis(50);
- printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5);
+ printString("%s", textPos, menuRect.top + selected * fh, _static.menuTable[6], 0, 5, _static.strings[selected]);
_screen->updateScreen();
_system->delayMillis(50);
}
@@ -577,7 +577,7 @@ void MainMenu::draw(int select) {
for (int i = 0; i < _static.menuTable[3]; ++i) {
int curY = top + i * _screen->getFontHeight();
int color = (i == select) ? _static.menuTable[6] : _static.menuTable[5];
- printString(_static.strings[i], ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5);
+ printString("%s", ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5, _static.strings[i]);
}
}
diff --git a/engines/kyra/gui_hof.cpp b/engines/kyra/gui_hof.cpp
index 69e7419757..cb2476ff99 100644
--- a/engines/kyra/gui_hof.cpp
+++ b/engines/kyra/gui_hof.cpp
@@ -757,7 +757,6 @@ int GUI_HoF::optionsButton(Button *button) {
initMenu(*_currentMenu);
_madeSave = false;
_loadedSave = false;
- _vm->_itemInHand = -1;
updateAllMenuButtons();
if (_isDeathMenu) {
@@ -821,6 +820,7 @@ void GUI_HoF::resetState(int item) {
_vm->setNextIdleAnimTimer();
_isDeathMenu = false;
if (!_loadedSave) {
+ _vm->_itemInHand = -1;
_vm->setHandItem(item);
} else {
_vm->setHandItem(_vm->_itemInHand);
diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp
index e7001ed31f..858e3fde94 100644
--- a/engines/kyra/gui_mr.cpp
+++ b/engines/kyra/gui_mr.cpp
@@ -1141,6 +1141,7 @@ void GUI_MR::resetState(int item) {
_vm->setNextIdleAnimTimer();
_isDeathMenu = false;
if (!_loadedSave) {
+ _vm->_itemInHand = -1;
_vm->setHandItem(item);
} else {
_vm->setHandItem(_vm->_itemInHand);
@@ -1260,7 +1261,6 @@ int GUI_MR::optionsButton(Button *button) {
initMenu(*_currentMenu);
_madeSave = false;
_loadedSave = false;
- _vm->_itemInHand = -1;
updateAllMenuButtons();
if (_isDeathMenu) {
diff --git a/engines/kyra/items_mr.cpp b/engines/kyra/items_mr.cpp
index 5397651e97..d08d58e65d 100644
--- a/engines/kyra/items_mr.cpp
+++ b/engines/kyra/items_mr.cpp
@@ -87,7 +87,8 @@ void KyraEngine_MR::setMouseCursor(uint16 item) {
shape = item+248;
}
- if ((int16)item != _itemInHand)
+ _mouseState = item;
+ if ((int16)item >= 0)
_screen->setMouseCursor(hotX, hotY, getShapePtr(shape));
}
diff --git a/engines/kyra/kyra_hof.cpp b/engines/kyra/kyra_hof.cpp
index 5c41989713..bf515498dc 100644
--- a/engines/kyra/kyra_hof.cpp
+++ b/engines/kyra/kyra_hof.cpp
@@ -1658,7 +1658,7 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) {
if (!file)
error("Couldn't load cauldron palette");
file->seek(state*18, SEEK_SET);
- _screen->getPalette(0).loadVGAPalette(*file, 241, 6);
+ _screen->getPalette(2).loadVGAPalette(*file, 241, 6);
delete file;
file = 0;
@@ -1673,8 +1673,8 @@ void KyraEngine_HoF::setCauldronState(uint8 state, bool paletteFade) {
_screen->getPalette(0).copy(_screen->getPalette(2), 241, 6);
_cauldronState = state;
_cauldronUseCount = 0;
- //if (state == 5)
- // sub_27149();
+ if (state == 5)
+ setDlgIndex(5);
}
void KyraEngine_HoF::clearCauldronTable() {
diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h
index 88bfb8c89b..2204f78b82 100644
--- a/engines/kyra/kyra_mr.h
+++ b/engines/kyra/kyra_mr.h
@@ -495,6 +495,7 @@ private:
bool _useFrameTable;
int o3a_setCharacterFrame(EMCState *script);
+ int o3a_playSoundEffect(EMCState *script);
// special shape code
int initAnimationShapes(uint8 *filedata);
diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp
index 258d0c402f..d79d9a8f32 100644
--- a/engines/kyra/kyra_v1.cpp
+++ b/engines/kyra/kyra_v1.cpp
@@ -24,6 +24,7 @@
*/
#include "common/config-manager.h"
+#include "common/EventRecorder.h"
#include "sound/mididrv.h"
#include "sound/mixer.h"
@@ -81,7 +82,7 @@ KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
Common::addDebugChannel(kDebugLevelMovie, "Movie", "Movie debug level");
Common::addDebugChannel(kDebugLevelTimer, "Timer", "Timer debug level");
- _eventMan->registerRandomSource(_rnd, "kyra");
+ g_eventRec.registerRandomSource(_rnd, "kyra");
}
::GUI::Debugger *KyraEngine_v1::getDebugger() {
diff --git a/engines/kyra/saveload.cpp b/engines/kyra/saveload.cpp
index 83230d6e3b..9e0ddcea4f 100644
--- a/engines/kyra/saveload.cpp
+++ b/engines/kyra/saveload.cpp
@@ -222,11 +222,7 @@ const char *KyraEngine_v1::getSavegameFilename(int num) {
Common::String KyraEngine_v1::getSavegameFilename(const Common::String &target, int num) {
assert(num >= 0 && num <= 999);
-
- char extension[5];
- sprintf(extension, "%03d", num);
-
- return target + "." + extension;
+ return target + Common::String::printf(".%03d", num);
}
bool KyraEngine_v1::saveFileLoadable(int slot) {
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 6c2c48cb02..7a7544a589 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -95,25 +95,10 @@ bool Screen::init() {
}
if (_useSJIS) {
- if (!_sjisFont) {
- // we use the FM-TOWNS font rom for PC-98, too, until we feel
- // like adding support for the PC-98 font
- //if (_vm->gameFlags().platform == Common::kPlatformFMTowns) {
- // FM-TOWNS
- Common::SeekableReadStream *rom = _vm->resource()->createReadStream("FMT_FNT.ROM");
- Graphics::FontTowns *townsFont = new Graphics::FontTowns();
- if (!rom || !townsFont || !townsFont->loadFromStream(*rom))
- error("Could not load font rom ('FMT_FNT.ROM') required for this version");
- _sjisFont = townsFont;
- delete rom;
- /*} else {
- // PC-98
- _sjisFontData = _vm->resource()->fileData("FONT.ROM", 0);
- if (!_sjisFontData)
- error("missing font rom ('FONT.ROM') required for this version");
- }*/
- }
-
+ _sjisFont = Graphics::FontSJIS::createFont(_vm->gameFlags().platform);
+
+ if (!_sjisFont)
+ error("Could not load any SJIS font, neither the original nor ScummVM's 'SJIS.FNT'");
_sjisFont->enableOutline(!_use16ColorMode);
}
}
diff --git a/engines/kyra/script_mr.cpp b/engines/kyra/script_mr.cpp
index 1800bd1939..819bf838ca 100644
--- a/engines/kyra/script_mr.cpp
+++ b/engines/kyra/script_mr.cpp
@@ -1114,6 +1114,12 @@ int KyraEngine_MR::o3a_setCharacterFrame(EMCState *script) {
return 0;
}
+int KyraEngine_MR::o3a_playSoundEffect(EMCState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3a_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0));
+ snd_playSoundEffect(stackPos(0), 200);
+ return 0;
+}
+
#pragma mark -
int KyraEngine_MR::o3d_updateAnim(EMCState *script) {
@@ -1374,7 +1380,7 @@ void KyraEngine_MR::setupOpcodeTable() {
// 0x00
Opcode(o2a_setAnimationShapes);
Opcode(o3a_setCharacterFrame);
- Opcode(o3_playSoundEffect);
+ Opcode(o3a_playSoundEffect);
Opcode(o3_dummy);
// 0x04
Opcode(o2a_setResetFrame);
diff --git a/engines/kyra/sequences_mr.cpp b/engines/kyra/sequences_mr.cpp
index 4d1117f3c9..a1830aec5c 100644
--- a/engines/kyra/sequences_mr.cpp
+++ b/engines/kyra/sequences_mr.cpp
@@ -42,7 +42,8 @@ void KyraEngine_MR::showBadConscience() {
_badConscienceAnim = 6;
else if (_currentChapter == 5 && _rnd.getRandomNumberRng(1, 100) <= 25)
_badConscienceAnim = 7;
- else if (_characterShapeFile == 9)
+
+ if (_characterShapeFile == 9)
_badConscienceAnim = 4;
_badConsciencePosition = (_mainCharacter.x1 <= 160);
diff --git a/engines/kyra/sound_digital.cpp b/engines/kyra/sound_digital.cpp
index 6b81b1c022..1d8bc5b03c 100644
--- a/engines/kyra/sound_digital.cpp
+++ b/engines/kyra/sound_digital.cpp
@@ -346,7 +346,7 @@ int AUDStream::readChunk(int16 *buffer, const int maxSamples) {
#pragma mark -
-SoundDigital::SoundDigital(KyraEngine_MR *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer), _sounds() {
+SoundDigital::SoundDigital(KyraEngine_MR *vm, Audio::Mixer *mixer) : _vm(vm), _mixer(mixer) {
for (uint i = 0; i < ARRAYSIZE(_sounds); ++i)
_sounds[i].stream = 0;
}
diff --git a/engines/kyra/sprites.cpp b/engines/kyra/sprites.cpp
index 3cc632a391..456dcc06f3 100644
--- a/engines/kyra/sprites.cpp
+++ b/engines/kyra/sprites.cpp
@@ -28,6 +28,8 @@
#include "common/stream.h"
#include "common/util.h"
#include "common/system.h"
+#include "common/EventRecorder.h"
+
#include "kyra/screen.h"
#include "kyra/kyra_lok.h"
#include "kyra/sprites.h"
@@ -47,7 +49,7 @@ Sprites::Sprites(KyraEngine_LoK *vm, OSystem *system) {
_spriteDefStart = 0;
memset(_drawLayerTable, 0, sizeof(_drawLayerTable));
_sceneAnimatorBeaconFlag = 0;
- _vm->getEventManager()->registerRandomSource(_rnd, "kyraSprites");
+ g_eventRec.registerRandomSource(_rnd, "kyraSprites");
}
Sprites::~Sprites() {
diff --git a/engines/lure/hotspots.cpp b/engines/lure/hotspots.cpp
index 969d8215fb..b5ec00fdf9 100644
--- a/engines/lure/hotspots.cpp
+++ b/engines/lure/hotspots.cpp
@@ -38,6 +38,7 @@
#include "lure/sound.h"
#include "lure/lure.h"
#include "common/endian.h"
+#include "common/EventRecorder.h"
namespace Lure {
@@ -600,7 +601,7 @@ void Hotspot::setRandomDest() {
Common::RandomSource rnd;
int16 xp, yp;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
if (currentActions().isEmpty())
currentActions().addFront(START_WALKING, roomNumber());
@@ -2691,7 +2692,19 @@ void HotspotTickHandlers::standardCharacterAnimHandler(Hotspot &h) {
return;
}
h.currentActions().top().setAction(WALKING);
- h.setPosition(h.x(), h.y() & 0xfff8);
+
+ // WORKAROUND: A character that had enteredg an exit area might have been blocked from entering the new room.
+ // The Y position adjust below could thus place a character further into the exit area. So don't do the
+ // position adjustment if the user is already in an exit area
+ int16 x = h.x() + (h.widthCopy() >> 1);
+ int16 y = h.y() + h.heightCopy() - (h.yCorrection() >> 1);
+
+ RoomData *roomData = Resources::getReference().getRoom(h.roomNumber());
+ RoomExitData *exitRec = roomData->exits.checkExits(x, y);
+
+ if (!exitRec)
+ h.setPosition(h.x(), h.y() & 0xfff8);
+
} else if (h.blockedState() == BS_FINAL) {
// If this point is reached, the character twice hasn't found a walking path
debugC(ERROR_DETAILED, kLureDebugAnimations, "Character is hopelessly blocked");
@@ -3135,7 +3148,7 @@ void HotspotTickHandlers::followerAnimHandler(Hotspot &h) {
Common::RandomSource rnd;
RandomActionType actionType;
uint16 scheduleId;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
int actionIndex = rnd.getRandomNumber(set->numActions() - 1);
set->getEntry(actionIndex, actionType, scheduleId);
@@ -3325,7 +3338,7 @@ void HotspotTickHandlers::prisonerAnimHandler(Hotspot &h) {
ValueTableData &fields = Resources::getReference().fieldList();
Common::RandomSource rnd;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
h.handleTalkDialog();
if (h.frameCtr() > 0) {
@@ -3368,7 +3381,7 @@ void HotspotTickHandlers::morkusAnimHandler(Hotspot &h) {
if (h.executeScript()) {
// Script is done - set new script to one of two alternates randomly
Common::RandomSource rnd;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
h.setHotspotScript(rnd.getRandomNumber(100) >= 50 ? 0x54 : 0);
h.setFrameCtr(20 + rnd.getRandomNumber(63));
@@ -3668,7 +3681,7 @@ void HotspotTickHandlers::barmanAnimHandler(Hotspot &h) {
Common::RandomSource rnd;
static bool ewanXOffset = false;
- g_system->getEventManager()->registerRandomSource(rnd, "lureHotspots");
+ g_eventRec.registerRandomSource(rnd, "lureHotspots");
h.handleTalkDialog();
if (h.delayCtr() > 0) {
diff --git a/engines/lure/res.cpp b/engines/lure/res.cpp
index 95cb0a2f1b..7eb76cad32 100644
--- a/engines/lure/res.cpp
+++ b/engines/lure/res.cpp
@@ -30,6 +30,7 @@
#include "lure/lure.h"
#include "common/endian.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
namespace Lure {
@@ -42,7 +43,7 @@ Resources &Resources::getReference() {
}
Resources::Resources() {
- g_system->getEventManager()->registerRandomSource(_rnd, "lureResources");
+ g_eventRec.registerRandomSource(_rnd, "lureResources");
int_resources = this;
reloadData();
diff --git a/engines/lure/scripts.cpp b/engines/lure/scripts.cpp
index 391147ebd5..f9d854a73b 100644
--- a/engines/lure/scripts.cpp
+++ b/engines/lure/scripts.cpp
@@ -34,6 +34,7 @@
#include "lure/sound.h"
#include "common/stack.h"
#include "common/endian.h"
+#include "common/EventRecorder.h"
namespace Lure {
@@ -739,7 +740,7 @@ void Script::addActions(uint16 hotspotId, uint16 actions, uint16 v3) {
void Script::randomToGeneral(uint16 maxVal, uint16 minVal, uint16 v3) {
Common::RandomSource rnd;
- g_system->getEventManager()->registerRandomSource(rnd, "lureScripts");
+ g_eventRec.registerRandomSource(rnd, "lureScripts");
uint16 v = minVal + rnd.getRandomNumber(maxVal - minVal);
Resources::getReference().fieldList().setField(GENERAL, v);
}
diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp
index c27f151fdf..b4973002a6 100644
--- a/engines/m4/m4.cpp
+++ b/engines/m4/m4.cpp
@@ -53,6 +53,7 @@
#include "common/file.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/endian.h"
#include "common/system.h"
#include "common/config-manager.h"
@@ -192,7 +193,7 @@ Common::Error M4Engine::run() {
_animation = new Animation(this);
//_callbacks = new Callbacks(this);
_random = new Common::RandomSource();
- g_system->getEventManager()->registerRandomSource(*_random, "m4");
+ g_eventRec.registerRandomSource(*_random, "m4");
if (isM4())
return goM4();
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index 50a14c3e34..c83f7aaf02 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -24,6 +24,7 @@
*/
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/keyboard.h"
#include "common/file.h"
#include "common/savefile.h"
@@ -74,7 +75,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_gameId = g->id;
_rnd = new Common::RandomSource();
- syst->getEventManager()->registerRandomSource(*_rnd, "made");
+ g_eventRec.registerRandomSource(*_rnd, "made");
int cd_num = ConfMan.getInt("cdrom");
if (cd_num >= 0)
diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp
index 7aee966aa6..8fadd4e462 100644
--- a/engines/parallaction/parallaction.cpp
+++ b/engines/parallaction/parallaction.cpp
@@ -25,6 +25,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/file.h"
#include "common/util.h"
#include "common/system.h"
@@ -70,7 +71,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam
Common::addDebugChannel(kDebugMenu, "menu", "Menu debug level");
Common::addDebugChannel(kDebugInventory, "inventory", "Inventory debug level");
- syst->getEventManager()->registerRandomSource(_rnd, "parallaction");
+ g_eventRec.registerRandomSource(_rnd, "parallaction");
}
diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h
index b7c8a9e029..3672fd3b09 100644
--- a/engines/parallaction/parser.h
+++ b/engines/parallaction/parser.h
@@ -172,14 +172,14 @@ protected:
DECLARE_UNQUALIFIED_COMMAND_PARSER(simple);
DECLARE_UNQUALIFIED_COMMAND_PARSER(move);
DECLARE_UNQUALIFIED_COMMAND_PARSER(endcommands);
-
+public:
virtual void parseGetData(ZonePtr z);
virtual void parseExamineData(ZonePtr z);
virtual void parseDoorData(ZonePtr z);
virtual void parseMergeData(ZonePtr z);
virtual void parseHearData(ZonePtr z);
virtual void parseSpeakData(ZonePtr z);
-
+protected:
Common::String parseComment();
Common::String parseDialogueString();
Dialogue *parseDialogue();
@@ -289,10 +289,12 @@ protected:
DECLARE_UNQUALIFIED_ANIM_PARSER(endanimation);
virtual void parseZoneTypeBlock(ZonePtr z);
- void parsePathData(ZonePtr z);
- void parseGetData(ZonePtr z);
- void parseDoorData(ZonePtr z);
- void parseAnswerCounter(Answer *answer);
+public:
+ virtual void parsePathData(ZonePtr z);
+ virtual void parseGetData(ZonePtr z);
+ virtual void parseDoorData(ZonePtr z);
+protected:
+ void parseAnswerCounter(Answer *answer);
virtual Answer *parseAnswer();
public:
diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp
index b1dd86a693..563faa16e6 100644
--- a/engines/parallaction/parser_br.cpp
+++ b/engines/parallaction/parser_br.cpp
@@ -808,26 +808,27 @@ void LocationParser_br::parseDoorData(ZonePtr z) {
}
}
+typedef void (LocationParser_br::*ZoneTypeParser)(ZonePtr);
+static ZoneTypeParser parsers[] = {
+ 0, // no type
+ &LocationParser_br::parseExamineData,
+ &LocationParser_br::parseDoorData,
+ &LocationParser_br::parseGetData,
+ &LocationParser_br::parseMergeData,
+ 0, // taste
+ &LocationParser_br::parseHearData,
+ 0, // feel
+ &LocationParser_br::parseSpeakData,
+ 0, // none
+ 0, // trap
+ 0, // you
+ 0, // command
+ &LocationParser_br::parsePathData,
+ 0, // box
+};
+
void LocationParser_br::parseZoneTypeBlock(ZonePtr z) {
debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type);
- typedef void (LocationParser_br::*ZoneTypeParser)(ZonePtr);
- ZoneTypeParser parsers[] = {
- 0, // no type
- &LocationParser_br::parseExamineData,
- &LocationParser_br::parseDoorData,
- &LocationParser_br::parseGetData,
- &LocationParser_br::parseMergeData,
- 0, // taste
- &LocationParser_br::parseHearData,
- 0, // feel
- &LocationParser_br::parseSpeakData,
- 0, // none
- 0, // trap
- 0, // you
- 0, // command
- &LocationParser_br::parsePathData,
- 0, // box
- };
ZoneTypeParser p = parsers[ACTIONTYPE(z)];
do {
diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp
index 9971828c31..1c06f86bfa 100644
--- a/engines/parallaction/parser_ns.cpp
+++ b/engines/parallaction/parser_ns.cpp
@@ -1411,24 +1411,25 @@ void LocationParser_ns::parseSpeakData(ZonePtr z) {
}
}
+typedef void (LocationParser_ns::*ZoneTypeParser)(ZonePtr);
+static ZoneTypeParser parsers[] = {
+ 0, // no type
+ &LocationParser_ns::parseExamineData,
+ &LocationParser_ns::parseDoorData,
+ &LocationParser_ns::parseGetData,
+ &LocationParser_ns::parseMergeData,
+ 0, // taste
+ &LocationParser_ns::parseHearData,
+ 0, // feel
+ &LocationParser_ns::parseSpeakData,
+ 0, // none
+ 0, // trap
+ 0, // you
+ 0 // command
+};
+
void LocationParser_ns::parseZoneTypeBlock(ZonePtr z) {
debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type);
- typedef void (LocationParser_ns::*ZoneTypeParser)(ZonePtr);
- ZoneTypeParser parsers[] = {
- 0, // no type
- &LocationParser_ns::parseExamineData,
- &LocationParser_ns::parseDoorData,
- &LocationParser_ns::parseGetData,
- &LocationParser_ns::parseMergeData,
- 0, // taste
- &LocationParser_ns::parseHearData,
- 0, // feel
- &LocationParser_ns::parseSpeakData,
- 0, // none
- 0, // trap
- 0, // you
- 0 // command
- };
ZoneTypeParser p = parsers[ACTIONTYPE(z)];
do {
diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp
index 5db0e732ee..d95decfd4f 100644
--- a/engines/parallaction/saveload.cpp
+++ b/engines/parallaction/saveload.cpp
@@ -67,16 +67,6 @@ public:
virtual void reflowLayout();
};
-Common::String SaveLoad_ns::genOldSaveFileName(uint slot) {
- assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
-
- char s[20];
- sprintf(s, "game.%i", slot);
-
- return Common::String(s);
-}
-
-
Common::String SaveLoad::genSaveFileName(uint slot) {
assert(slot < NUM_SAVESLOTS || slot == SPECIAL_SAVESLOT);
@@ -430,55 +420,55 @@ void SaveLoad_ns::getGamePartProgress(bool *complete, int size) {
complete[2] = s.contains("dough");
}
-void SaveLoad_ns::renameOldSavefiles() {
+static bool askRenameOldSavefiles() {
+ GUI::MessageDialog dialog0(
+ "ScummVM found that you have old savefiles for Nippon Safes that should be renamed.\n"
+ "The old names are no longer supported, so you will not be able to load your games if you don't convert them.\n\n"
+ "Press OK to convert them now, otherwise you will be asked next time.\n", "OK", "Cancel");
- bool exists[NUM_SAVESLOTS];
- uint num = 0;
- uint i;
+ return (dialog0.runModal() != 0);
+}
- for (i = 0; i < NUM_SAVESLOTS; i++) {
- exists[i] = false;
- Common::String name = genOldSaveFileName(i);
- Common::InSaveFile *f = _saveFileMan->openForLoading(name);
- if (f) {
- exists[i] = true;
- num++;
+void SaveLoad_ns::renameOldSavefiles() {
+ Common::StringList oldFilenames = _saveFileMan->listSavefiles("game.*");
+ uint numOldSaves = oldFilenames.size();
+
+ bool rename = false;
+ uint success = 0, id;
+ Common::String oldName, newName;
+ for (uint i = 0; i < oldFilenames.size(); ++i) {
+ oldName = oldFilenames[i];
+ int e = sscanf(oldName.c_str(), "game.%u", &id);
+ if (e != 1) {
+ // this wasn't a savefile, so adjust numOldSaves accordingly
+ --numOldSaves;
+ continue;
}
- delete f;
- }
-
- if (num == 0) {
- // there are no old savefiles: nothing to do
- return;
- }
- GUI::MessageDialog dialog0(
- "ScummVM found that you have old savefiles for Nippon Safes that should be renamed.\n"
- "The old names are no longer supported, so you will not be able to load your games if you don't convert them.\n\n"
- "Press OK to convert them now, otherwise you will be asked you next time.\n", "OK", "Cancel");
+ if (!rename) {
+ rename = askRenameOldSavefiles();
+ }
+ if (!rename) {
+ // return immediately if the user doesn't want to rename the files
+ return;
+ }
- int choice = dialog0.runModal();
- if (choice == 0) {
- // user pressed cancel
- return;
+ newName = genSaveFileName(id);
+ if (_saveFileMan->renameSavefile(oldName, newName)) {
+ success++;
+ } else {
+ warning("Error %i (%s) occurred while renaming %s to %s", _saveFileMan->getError(),
+ _saveFileMan->getErrorDesc().c_str(), oldName.c_str(), newName.c_str());
+ }
}
- uint success = 0;
- for (i = 0; i < NUM_SAVESLOTS; i++) {
- if (exists[i]) {
- Common::String oldName = genOldSaveFileName(i);
- Common::String newName = genSaveFileName(i);
- if (_saveFileMan->renameSavefile(oldName, newName)) {
- success++;
- } else {
- warning("Error %i (%s) occurred while renaming %s to %s", _saveFileMan->getError(),
- _saveFileMan->getErrorDesc().c_str(), oldName.c_str(), newName.c_str());
- }
- }
+ if (numOldSaves == 0) {
+ // there were no old savefiles: nothing to notify
+ return;
}
char msg[200];
- if (success == num) {
+ if (success == numOldSaves) {
sprintf(msg, "ScummVM successfully converted all your savefiles.");
} else {
sprintf(msg,
diff --git a/engines/parallaction/saveload.h b/engines/parallaction/saveload.h
index 2b2a7ab6a5..0bcc930c8a 100644
--- a/engines/parallaction/saveload.h
+++ b/engines/parallaction/saveload.h
@@ -62,7 +62,6 @@ public:
class SaveLoad_ns : public SaveLoad {
Parallaction_ns *_vm;
- Common::String genOldSaveFileName(uint slot);
protected:
void renameOldSavefiles();
diff --git a/engines/queen/display.cpp b/engines/queen/display.cpp
index bac7c5f419..ae223ff6cf 100644
--- a/engines/queen/display.cpp
+++ b/engines/queen/display.cpp
@@ -25,6 +25,7 @@
#include "common/system.h"
+#include "common/EventRecorder.h"
#include "common/events.h"
#include "graphics/cursorman.h"
@@ -74,7 +75,7 @@ Display::Display(QueenEngine *vm, OSystem *system)
memset(&_dynalum, 0, sizeof(_dynalum));
setupInkColors();
- system->getEventManager()->registerRandomSource(_rnd, "queenDisplay");
+ g_eventRec.registerRandomSource(_rnd, "queenDisplay");
}
Display::~Display() {
diff --git a/engines/queen/music.cpp b/engines/queen/music.cpp
index 8a50ae6b40..3d5bfbdf73 100644
--- a/engines/queen/music.cpp
+++ b/engines/queen/music.cpp
@@ -25,6 +25,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "queen/music.h"
#include "queen/queen.h"
@@ -84,7 +85,7 @@ MidiMusic::MidiMusic(QueenEngine *vm)
_parser->setMidiDriver(this);
_parser->setTimerRate(_driver->getBaseTempo());
- vm->getEventManager()->registerRandomSource(_rnd, "queenMusic");
+ g_eventRec.registerRandomSource(_rnd, "queenMusic");
}
MidiMusic::~MidiMusic() {
diff --git a/engines/queen/queen.cpp b/engines/queen/queen.cpp
index ec074190d3..7c351842c4 100644
--- a/engines/queen/queen.cpp
+++ b/engines/queen/queen.cpp
@@ -31,6 +31,7 @@
#include "common/savefile.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "queen/queen.h"
#include "queen/bankman.h"
@@ -193,7 +194,7 @@ namespace Queen {
QueenEngine::QueenEngine(OSystem *syst)
: Engine(syst), _debugger(0) {
- syst->getEventManager()->registerRandomSource(randomizer, "queen");
+ g_eventRec.registerRandomSource(randomizer, "queen");
}
QueenEngine::~QueenEngine() {
diff --git a/engines/saga/detection.cpp b/engines/saga/detection.cpp
index faf9cbed80..265008992a 100644
--- a/engines/saga/detection.cpp
+++ b/engines/saga/detection.cpp
@@ -204,7 +204,7 @@ SaveStateList SagaMetaEngine::listSaves(const char *target) const {
// Obtain the last 2 digits of the filename, since they correspond to the save slot
slotNum = atoi(file->c_str() + file->size() - 2);
- if (slotNum >= 0 && slotNum <= 99) {
+ if (slotNum >= 0 && slotNum < MAX_SAVES) {
Common::InSaveFile *in = saveFileMan->openForLoading(*file);
if (in) {
for (int i = 0; i < 3; i++)
@@ -219,7 +219,7 @@ SaveStateList SagaMetaEngine::listSaves(const char *target) const {
return saveList;
}
-int SagaMetaEngine::getMaximumSaveSlot() const { return 99; }
+int SagaMetaEngine::getMaximumSaveSlot() const { return MAX_SAVES - 1; }
void SagaMetaEngine::removeSaveState(const char *target, int slot) const {
char extension[6];
diff --git a/engines/saga/font.cpp b/engines/saga/font.cpp
index d58d1a8900..8b9b45d3ff 100644
--- a/engines/saga/font.cpp
+++ b/engines/saga/font.cpp
@@ -143,10 +143,7 @@ void Font::createOutline(FontData *font) {
int i;
int row;
int newByteWidth;
- int oldByteWidth;
int newRowLength = 0;
- size_t indexOffset = 0;
- int index;
int currentByte;
unsigned char *basePointer;
unsigned char *srcPointer;
@@ -154,57 +151,22 @@ void Font::createOutline(FontData *font) {
unsigned char *destPointer2;
unsigned char *destPointer3;
unsigned char charRep;
- int nextIndex = 0;
-
// Populate new font style character data
for (i = 0; i < FONT_CHARCOUNT; i++) {
newByteWidth = 0;
- oldByteWidth = 0;
- index = font->normal.fontCharEntry[i].index;
- if ((index > 0) || (i == FONT_FIRSTCHAR)) {
- index += indexOffset;
- }
-
- bool skip = false;
-
- if (font->normal.fontCharEntry[i].width != 0 && font->normal.fontCharEntry[i].index < nextIndex) {
- // Some characters are copies of earlier characters.
- // Look up the original, and make sure not to grow the size of
- // the outline font twice.
- skip = true;
- bool found = false;
- for (int j = 0; j < i; j++) {
- if (font->normal.fontCharEntry[i].index == font->normal.fontCharEntry[j].index) {
- index = font->outline.fontCharEntry[j].index;
- found = true;
- break;
- }
- }
- if (!found)
- error("Invalid index backreference in font char %d", i);
- }
- font->outline.fontCharEntry[i].index = index;
+ font->outline.fontCharEntry[i].index = newRowLength;
font->outline.fontCharEntry[i].tracking = font->normal.fontCharEntry[i].tracking;
font->outline.fontCharEntry[i].flag = font->normal.fontCharEntry[i].flag;
- if (font->normal.fontCharEntry[i].width != 0) {
+ if (font->normal.fontCharEntry[i].width != 0)
newByteWidth = getByteLen(font->normal.fontCharEntry[i].width + 2);
- oldByteWidth = getByteLen(font->normal.fontCharEntry[i].width);
-
- if (!skip && newByteWidth > oldByteWidth) {
- indexOffset++;
- }
- }
font->outline.fontCharEntry[i].width = font->normal.fontCharEntry[i].width + 2;
font->outline.fontCharEntry[i].byteWidth = newByteWidth;
- if (!skip) {
- newRowLength += newByteWidth;
- nextIndex = font->normal.fontCharEntry[i].index + oldByteWidth;
- }
+ newRowLength += newByteWidth;
}
debug(2, "New row length: %d", newRowLength);
@@ -220,10 +182,6 @@ void Font::createOutline(FontData *font) {
// Generate outline font representation
for (i = 0; i < FONT_CHARCOUNT; i++) {
- if (i > 0 && font->normal.fontCharEntry[i].index < font->normal.fontCharEntry[i-1].index) {
- // Skip copies
- continue;
- }
for (row = 0; row < font->normal.header.charHeight; row++) {
for (currentByte = 0; currentByte < font->outline.fontCharEntry[i].byteWidth; currentByte++) {
basePointer = font->outline.font + font->outline.fontCharEntry[i].index + currentByte;
diff --git a/engines/saga/saga.cpp b/engines/saga/saga.cpp
index 4acf93d030..2a2a4b993c 100644
--- a/engines/saga/saga.cpp
+++ b/engines/saga/saga.cpp
@@ -29,6 +29,7 @@
#include "common/config-manager.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "sound/mixer.h"
@@ -114,7 +115,7 @@ SagaEngine::SagaEngine(OSystem *syst, const SAGAGameDescription *gameDesc)
Common::File::addDefaultDirectory(_gameDataDir.getChild("video"));
_displayClip.left = _displayClip.top = 0;
- syst->getEventManager()->registerRandomSource(_rnd, "saga");
+ g_eventRec.registerRandomSource(_rnd, "saga");
}
SagaEngine::~SagaEngine() {
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index 7c1a165ec1..2ddc6979c9 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -194,6 +194,7 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {
scriptState.seekLevel = 0;
scriptState.runningStep = 0;
scriptState.stopOnEvent = false;
+ scriptState.debugging = false;
}
Console::~Console() {
@@ -2091,28 +2092,30 @@ bool Console::cmdBacktrace(int argc, const char **argv) {
printf("\n");
}
- return 0;
return true;
}
bool Console::cmdStep(int argc, const char **argv) {
if (argc == 2 && atoi(argv[1]) > 0)
scriptState.runningStep = atoi(argv[1]) - 1;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepEvent(int argc, const char **argv) {
scriptState.stopOnEvent = true;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepRet(int argc, const char **argv) {
scriptState.seeking = kDebugSeekLevelRet;
scriptState.seekLevel = _vm->_gamestate->_executionStack.size() - 1;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepGlobal(int argc, const char **argv) {
@@ -2124,8 +2127,9 @@ bool Console::cmdStepGlobal(int argc, const char **argv) {
scriptState.seeking = kDebugSeekGlobal;
scriptState.seekSpecial = atoi(argv[1]);
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdStepCallk(int argc, const char **argv) {
@@ -2156,8 +2160,9 @@ bool Console::cmdStepCallk(int argc, const char **argv) {
} else {
scriptState.seeking = kDebugSeekCallk;
}
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdDissassemble(int argc, const char **argv) {
@@ -2227,7 +2232,7 @@ bool Console::cmdDissassembleAddress(int argc, const char **argv) {
_vm->_gamestate->seg_manager->dereference(vpc, &size);
size += vpc.offset; // total segment size
- for (int i = 1; i < argc; i++) {
+ for (int i = 2; i < argc; i++) {
if (!scumm_stricmp(argv[i], "bwt"))
do_bwc = 1;
else if (!scumm_stricmp(argv[i], "bc"))
@@ -2322,14 +2327,16 @@ bool Console::cmdSend(int argc, const char **argv) {
xstack->fp += argc;
_vm->_gamestate->_executionStackPosChanged = true;
+ scriptState.debugging = true;
- return true;
+ return false;
}
bool Console::cmdGo(int argc, const char **argv) {
+ // CHECKME: is this necessary?
scriptState.seeking = kDebugSeekNothing;
- return true;
+ return Cmd_Exit(argc, argv);
}
bool Console::cmdBreakpointList(int argc, const char **argv) {
diff --git a/engines/sci/debug.h b/engines/sci/debug.h
index cd2de2b3a9..a3c4fab372 100644
--- a/engines/sci/debug.h
+++ b/engines/sci/debug.h
@@ -38,6 +38,7 @@ enum DebugSeeking {
};
struct ScriptState {
+ bool debugging;
bool stopOnEvent;
DebugSeeking seeking; // Stepping forward until some special condition is met
int runningStep; // Set to > 0 to allow multiple stepping
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp
index 92cfe9daf3..11dd56f2aa 100644
--- a/engines/sci/engine/scriptdebug.cpp
+++ b/engines/sci/engine/scriptdebug.cpp
@@ -311,11 +311,18 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod
void script_debug(EngineState *s, bool bp) {
// Do we support a separate console?
- printf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc));
- disassemble(s, scriptState.xs->addr.pc, 0, 1);
- if (scriptState.seeking == kDebugSeekGlobal)
- printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial,
- scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial]));
+ /* if (sci_debug_flags & _DEBUG_FLAG_LOGGING) { */
+ printf("%d: acc=%04x:%04x ", script_step_counter, PRINT_REG(s->r_acc));
+ disassemble(s, scriptState.xs->addr.pc, 0, 1);
+ if (scriptState.seeking == kDebugSeekGlobal)
+ printf("Global %d (0x%x) = %04x:%04x\n", scriptState.seekSpecial,
+ scriptState.seekSpecial, PRINT_REG(s->script_000->locals_block->_locals[scriptState.seekSpecial]));
+ /* } */
+
+#if 0
+ if (!scriptState.debugging)
+ return;
+#endif
if (scriptState.seeking && !bp) { // Are we looking for something special?
MemObject *mobj = GET_SEGMENT(*s->seg_manager, scriptState.xs->addr.pc.segment, MEM_OBJ_SCRIPT);
@@ -370,9 +377,19 @@ void script_debug(EngineState *s, bool bp) {
// OK, found whatever we were looking for
}
}
-
+
printf("Step #%d\n", script_step_counter);
disassemble(s, scriptState.xs->addr.pc, 0, 1);
+
+ if (scriptState.runningStep) {
+ scriptState.runningStep--;
+ return;
+ }
+
+ scriptState.debugging = false;
+
+ Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
+ con->attach();
}
} // End of namespace Sci
diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp
index 6752ba3e56..905cba9d94 100644
--- a/engines/sci/engine/seg_manager.cpp
+++ b/engines/sci/engine/seg_manager.cpp
@@ -169,7 +169,9 @@ int SegManager::initialiseScript(Script &scr, EngineState *s, int script_nr) {
setScriptSize(scr, s, script_nr);
scr.buf = (byte *)malloc(scr.buf_size);
- dbgPrint("scr.buf ", scr.buf);
+#ifdef DEBUG_SEG_MANAGER
+ printf("scr.buf = %p ", scr.buf);
+#endif
if (!scr.buf) {
scr.freeScript();
warning("SegManager: Not enough memory space for script size");
@@ -864,14 +866,5 @@ int SegManager::freeDynmem(reg_t addr) {
return 0; // OK
}
-void SegManager::dbgPrint(const char* msg, void *i) {
-#ifdef DEBUG_SEG_MANAGER
- char buf[1000];
- sprintf(buf, "%s = [0x%x], dec:[%d]", msg, i, i);
- perror(buf);
-#endif
-}
-
-
} // End of namespace Sci
diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h
index a41d820014..9d406f559f 100644
--- a/engines/sci/engine/seg_manager.h
+++ b/engines/sci/engine/seg_manager.h
@@ -362,13 +362,6 @@ private:
* 'seg' is a valid segment
*/
bool check(SegmentId seg);
-
- void dbgPrint(const char* msg, void *i); // for debug only
-
- // Perform garbage collection
- // Parameters: (EngineState *) s: The state to operate on
- // Effects : Unreachable objects in 's' are deallocated
- //void sm_gc(EngineState *s);
};
} // End of namespace Sci
diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp
index 99b5a86e53..0f8fee0876 100644
--- a/engines/sci/engine/vm.cpp
+++ b/engines/sci/engine/vm.cpp
@@ -258,6 +258,7 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP
if (bp->type == BREAK_EXPORT && bp->data.address == bpaddress) {
Console *con = ((SciEngine *)g_engine)->getSciDebugger();
con->DebugPrintf("Break on script %d, export %d\n", script, pubfunct);
+ scriptState.debugging = true;
breakpointFlag = true;
break;
}
@@ -325,6 +326,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt
con->DebugPrintf("Break on %s (in [%04x:%04x])\n", method_name, PRINT_REG(send_obj));
print_send_action = 1;
breakpointFlag = true;
+ scriptState.debugging = true;
break;
}
bp = bp->next;
@@ -652,17 +654,19 @@ void run_vm(EngineState *s, int restoring) {
}
- if (script_abort_flag)
+ if (script_abort_flag || g_engine->shouldQuit())
return; // Emergency
-// TODO: re-enable this
-#if 0
// Debug if this has been requested:
- if (script_debug_flag || sci_debug_flags) {
+ // TODO: re-implement sci_debug_flags
+ if (scriptState.debugging /* sci_debug_flags*/) {
script_debug(s, breakpointFlag);
breakpointFlag = false;
}
-#endif
+ Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
+ if (con->isAttached()) {
+ con->onFrame();
+ }
#ifndef DISABLE_VALIDATIONS
if (scriptState.xs->sp < scriptState.xs->fp)
diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h
index f711570d11..ba225a9c00 100644
--- a/engines/sci/engine/vm.h
+++ b/engines/sci/engine/vm.h
@@ -266,18 +266,19 @@ struct ExecStack {
};
+// These types are used both as identifiers and as elements of bitfields
enum BreakpointType {
/**
* Break when selector is executed. data contains (char *) selector name
* (in the format Object::Method)
*/
- BREAK_SELECTOR,
+ BREAK_SELECTOR = 1,
/**
* Break when an exported function is called. data contains
* script_no << 16 | export_no.
*/
- BREAK_EXPORT
+ BREAK_EXPORT = 2
};
struct Breakpoint {
diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp
index 5604166794..b3a1be68d1 100644
--- a/engines/sci/gfx/operations.cpp
+++ b/engines/sci/gfx/operations.cpp
@@ -1383,7 +1383,6 @@ static sci_event_t scummvm_get_event(GfxDriver *drv) {
// Open debug console
Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
con->attach();
- con->onFrame();
// Clear keyboard event
input.type = SCI_EVT_NONE;
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index d99f9f0771..943361332f 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -882,7 +882,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType restype,
if (resnumber == -1)
return;
if (!file.open(source->location_name)) {
- perror("""__FILE__"": (""__LINE__""): failed to open");
+ warning("ResourceManager::processPatch(): failed to open %s", source->location_name.c_str());
return;
}
fsize = file.size();
@@ -1007,8 +1007,7 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) {
offset = file.readUint32LE();
if (file.ioFailed()) {
- warning("Error while reading %s: ", map->location_name.c_str());
- perror("");
+ warning("Error while reading %s", map->location_name.c_str());
return SCI_ERROR_RESMAP_NOT_FOUND;
}
if (offset == 0xFFFFFFFF)
@@ -1079,8 +1078,7 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) {
}
}
if (file.ioFailed()) {
- warning("Error while reading %s: ", map->location_name.c_str());
- perror("");
+ warning("Error while reading %s", map->location_name.c_str());
return SCI_ERROR_RESMAP_NOT_FOUND;
}
resId = ResourceId((ResourceType)type, number);
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index af8aac3147..3e434e4f02 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -289,9 +289,7 @@ uint32 SciEngine::getFlags() const {
}
Common::String SciEngine::getSavegameName(int nr) const {
- char extension[6];
- snprintf(extension, sizeof(extension), ".%03d", nr);
- return _targetName + extension;
+ return _targetName + Common::String::printf(".%03d", nr);
}
Common::String SciEngine::getSavegamePattern() const {
diff --git a/engines/scumm/actor.cpp b/engines/scumm/actor.cpp
index 52866279b8..227ae1d316 100644
--- a/engines/scumm/actor.cpp
+++ b/engines/scumm/actor.cpp
@@ -527,9 +527,15 @@ void Actor_v2::walkActor() {
if (_moving & MF_TURN) {
new_dir = updateActorDirection(false);
// FIXME: is this correct?
- if (_facing != new_dir)
+ if (_facing != new_dir) {
+
+ // Actor never stops walking when an object has been selected without this
+ if (_vm->_game.version ==0)
+ _moving = 0;
+
setDirection(new_dir);
- else
+
+ } else
_moving = 0;
return;
}
@@ -817,6 +823,16 @@ void Actor::setDirection(int direction) {
if (_costume == 0)
return;
+ // V0 MM
+ if (_vm->_game.version == 0) {
+ if (_moving)
+ _vm->_costumeLoader->costumeDecodeData(this, _walkFrame, 0);
+ else
+ _vm->_costumeLoader->costumeDecodeData(this, _standFrame, 0);
+ _needRedraw = true;
+ return;
+ }
+
// Update the costume for the new direction (and mark the actor for redraw)
aMask = 0x8000;
for (i = 0; i < 16; i++, aMask >>= 1) {
@@ -1224,7 +1240,10 @@ void Actor::showActor() {
_vm->ensureResourceLoaded(rtCostume, _costume);
- if (_vm->_game.version <= 2) {
+ if (_vm->_game.version == 0) {
+ _cost.reset();
+ startAnimActor(_standFrame);
+ } else if (_vm->_game.version <= 2) {
_cost.reset();
startAnimActor(_standFrame);
startAnimActor(_initFrame);
@@ -1380,6 +1399,13 @@ void ScummEngine::processActors() {
Actor** end = _sortedActors + numactors;
for (Actor** ac = _sortedActors; ac != end; ++ac) {
Actor* a = *ac;
+
+ // V0 MM: 0x057B
+ if (_game.version == 0) {
+ ActorC64 *A = (ActorC64*) a;
+ if ((A->_speaking & 1))
+ A->_speaking ^= 0xFE;
+ }
// Draw and animate the actors, except those w/o a costume.
// Note: We could 'optimize' this a little bit by only putting
// actors with a costume into the _sortedActors array in the
@@ -1572,6 +1598,8 @@ void Actor_v2::prepareDrawActorCostume(BaseCostumeRenderer *bcr) {
// we need to shift it 8 pixels to the left
if (_facing == 90)
bcr->_actorX -= 8;
+ } else if (_vm->_game.version == 0) {
+ bcr->_actorX += 12;
} else if (_vm->_game.version <= 2) {
// HACK: We have to adjust the x position by one strip (8 pixels) in
// V2 games. However, it is not quite clear to me why. And to fully
@@ -1703,6 +1731,12 @@ void Actor::animateActor(int anim) {
case 4: // turn to new direction
turnToDirection(dir);
break;
+ case 64:
+ if (_vm->_game.version == 0) {
+ _moving &= ~MF_TURN;
+ setDirection(dir);
+ break;
+ }
default:
if (_vm->_game.version <= 2)
startAnimActor(anim / 4);
@@ -2167,21 +2201,38 @@ void Actor::setActorCostume(int c) {
}
}
-static const char* v0ActorNames[7] = {
+static const char* v0ActorNames[0x19] = {
"Syd",
"Razor",
"Dave",
"Michael",
"Bernard",
"Wendy",
- "Jeff"
+ "Jeff",
+ "",
+ "Dr Fred",
+ "Nurse Edna",
+ "Weird Ed",
+ "Dead Cousin Ted",
+ "Purple Tentacle",
+ "Green Tentacle",
+ "Meteor",
+ "Plant",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "",
+ "Sandy"
};
const byte *Actor::getActorName() {
- const byte *ptr;
+ const byte *ptr = NULL;
if (_vm->_game.version == 0) {
- ptr = (const byte *)v0ActorNames[_number - 1];
+ if (_number)
+ ptr = (const byte *)v0ActorNames[_number - 1];
} else {
ptr = _vm->getResourceAddress(rtActorName, _number);
}
diff --git a/engines/scumm/actor.h b/engines/scumm/actor.h
index d32f268b11..c3edd24a39 100644
--- a/engines/scumm/actor.h
+++ b/engines/scumm/actor.h
@@ -380,11 +380,15 @@ protected:
class ActorC64 : public Actor_v2 {
public:
- // FIXME: This flag is never saved, which might lead to broken save states.
+ // FIXME: These vars are never saved, which might lead to broken save states.
byte _miscflags;
+ byte _speaking, _speakingPrev;
+ byte _costCommand, _costFrame;
public:
- ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {}
+ ActorC64(ScummEngine *scumm, int id) : Actor_v2(scumm, id) {
+ _speaking = _speakingPrev = _costCommand = _costFrame = 0;
+ }
virtual void initActor(int mode) {
Actor_v2::initActor(mode);
if (mode == -1) {
diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp
index 472e04b5f3..d480209501 100644
--- a/engines/scumm/boxes.cpp
+++ b/engines/scumm/boxes.cpp
@@ -445,7 +445,7 @@ byte ScummEngine::getNumBoxes() {
return 0;
if (_game.version == 8)
return (byte)READ_LE_UINT32(ptr);
- else if (_game.features >= 5)
+ else if (_game.version >= 5)
return (byte)READ_LE_UINT16(ptr);
else
return ptr[0];
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp
index 39c2f73e88..6923c27b38 100644
--- a/engines/scumm/costume.cpp
+++ b/engines/scumm/costume.cpp
@@ -1043,26 +1043,25 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
if (limb >= 8)
return 0;
+ if (a->_cost.start[limb] == 0xFFFF)
+ return 0;
+
if (limb == 0) {
_draw_top = 200;
_draw_bottom = 0;
}
+
+ bool flipped = (a->_cost.start[limb] & 0x80) != 0;
+ byte frameStart = _loaded._frameOffsets[a->_cost.frame[limb]];
+ byte frame = _loaded._frameOffsets[frameStart + a->_cost.curpos[limb]];
+ if (frame == 0xFF)
+ return 0;
- // TODO:
- // get out how animations are handled
- byte state = a->_moving != 0 ? 0 : 1;
- byte unk1 = (_loaded._animCmds + (state*32) + newDirToOldDir(a->getFacing()) * 8)[limb];
- byte unk2 = _loaded._frameOffsets[_loaded._frameOffsets[limb] + (unk1 & 0x7f)];
- bool flipped = (unk1 & 0x80) != 0;
-
- byte p1 = _loaded._frameOffsets[unk2];
- byte temp1 = _loaded._baseptr[p1];
- byte temp2 = temp1 + _loaded._dataOffsets[4];
- int offL = _loaded._baseptr[temp1 + 2];
- int offH = _loaded._baseptr[temp2];
- int off = (offH << 8) + offL;
+ byte ptrLow = _loaded._baseptr[frame];
+ byte ptrHigh = ptrLow + _loaded._dataOffsets[4];
+ int frameOffset = (_loaded._baseptr[ptrHigh] << 8) + _loaded._baseptr[ptrLow + 2]; // 0x23EF / 0x2400
- const byte *data = _loaded._baseptr + off;
+ const byte *data = _loaded._baseptr + frameOffset;
// Set up the palette data
byte palette[4] = { 0, 0, 0, 0 };
@@ -1080,8 +1079,8 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
int offsetY = *data++;
// these two fields seems to be most times zero
// byte6 was one time 255 in one costume I tried
-// int byte5 = *data++;
-// int byte6 = *data++;
+// int byte5 = *data++; // 0x1F80 // This value is never used
+// int byte6 = *data++; // 0x1F86 // This value is subtracted from ?actor drawy? at 0x2383
// debug(3, "byte5: %d", byte5);
// debug(3, "byte6: %d", byte6);
data += 2;
@@ -1094,17 +1093,13 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
if (flipped) {
if (offsetX)
- xpos += (offsetX-1) * 8;
+ xpos += (offsetX - 1) * 8;
} else {
xpos += offsetX * 8;
}
- // + 4 could be commented, because maybe the _actorX position is
- // wrong, I looked at the scumm-c64 interpreter by lloyd
- // and there Bernhard is directly on the right in the intro
- // but here in ScummVM he is 4 pixel left of the other position.
- xpos += _actorX - (a->_width / 2) + 4;
- ypos += _actorY - _loaded._maxHeight;
+ xpos += _actorX - (a->_width / 2);
+ ypos += (_actorY - _loaded._maxHeight) + 1; // +1 as we appear to be 1 pixel away from the original interpreter
// This code is very similar to procC64()
for (int y = 0; y < height; ++y) {
@@ -1114,9 +1109,9 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
int realX = 0;
if (flipped) {
if (offsetX == 0||offsetX == 1) {
- realX = width-(x+1);
+ realX = width-(x + 1);
} else if (offsetX == 2) {
- realX = width-(x+2);
+ realX = width-(x + 2);
}
} else {
realX = x;
@@ -1137,10 +1132,8 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
}
_draw_top = MIN(_draw_top, ypos);
- _draw_bottom = MAX(_draw_bottom, ypos+height);
- // if +4 above is NOT commented, here "+(flipped ? 4 : 0)" can be commented out
- // and other way round
- _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos+(width*8)/*+(flipped ? 4 : 0)*/, ypos, ypos+height, _actorID);
+ _draw_bottom = MAX(_draw_bottom, ypos + height);
+ _vm->markRectAsDirty(kMainVirtScreen, xpos, xpos + (width * 8), ypos, ypos + height, _actorID);
return 0;
}
@@ -1154,6 +1147,7 @@ void C64CostumeRenderer::setCostume(int costume, int shadow) {
void C64CostumeLoader::loadCostume(int id) {
const byte *ptr = _vm->getResourceAddress(rtCostume, id);
+
_id = id;
_baseptr = ptr + 9;
@@ -1168,33 +1162,152 @@ void C64CostumeLoader::loadCostume(int id) {
_animCmds = _baseptr + READ_LE_UINT16(ptr + 7);
_maxHeight = 0;
- for (int i = 0; i < 8; ++i) {
- int pid = _frameOffsets[_frameOffsets[i]];
- byte p1 = _frameOffsets[pid];
- byte b = _baseptr[p1];
- byte c = b + _dataOffsets[4];
- int offL = _baseptr[b + 2];
- int offH = _baseptr[c];
- int off = (offH << 8) + offL;
- const byte *data = _baseptr + off;
-
- if (data[3] > _maxHeight) {
- _maxHeight = data[3]; // data[3] is libs's Y offset
+}
+
+void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) {
+ byte limbFrames = 0;
+
+ // Each costume-command has 8 limbs (0x2622)
+ cmd <<= 3;
+
+ for (int limb = 0, pos = 0; limb < 8; ++limb, pos = 0) {
+ // get a limb frames ptr from the costume command
+ limbFrames = ((_animCmds + cmd)[limb]);
+
+ // Dont change limb if entry is invalid
+ if (limbFrames == 0xFF)
+ continue;
+
+ // Has limb frames ptr changed since last update?
+ if (a->_cost.start[limb] == limbFrames)
+ continue;
+
+ // Set new limb command addresses
+ a->_cost.start[limb] = limbFrames;
+ a->_cost.frame[limb] = _frameOffsets[limb] + (limbFrames & 0x7f); // limb animation-frames ptr
+
+ // Get first entry of a limbs' frames
+ byte frameStart = _frameOffsets[ a->_cost.frame[limb]];
+
+ // Loop each frame in this limb until we reach the end marker
+ while (pos != 0xFF) { // This is just so we dont overflow
+ byte frame = _frameOffsets[frameStart + pos];
+
+ // Each animation-frame until we find end
+ if (frame == 0xFF)
+ break;
+
+ byte ptrLow = _baseptr[frame];
+ byte ptrHigh = ptrLow + _dataOffsets[4];
+ int frameOffset = (_baseptr[ptrHigh] << 8) + _baseptr[ptrLow + 2]; // 0x23EF / 0x2400
+
+ const byte *data = _baseptr + frameOffset;
+
+ if (data[3] > _maxHeight)
+ _maxHeight = data[3] + 1;
+
+ ++pos;
}
+
+ // Set ending position of limb frames
+ a->_cost.end[limb] = pos - 1;
+ a->_cost.curpos[limb] = 0;
}
- ++_maxHeight;
}
-void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
+// based on 0x2BCA, doesn't match disassembly because 'oldDir' variable
+// is not the same value as stored in the original interpreter
+int C64CostumeLoader::dirToDirStop(int oldDir) {
+ switch (oldDir) {
+ case 0:
+ return 4; // Left
+ case 1:
+ return 5; // Right
+ case 2:
+ return 6; // Face Camera
+ case 3:
+ return 7; // Face Away
+ }
+ // shouldnt' be reached
+ return 4;
}
-byte C64CostumeLoader::increaseAnims(Actor *a) {
- return 0;
+void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) {
+ if ((a->_speaking & 0x80))
+ cmd += 0x0C;
+ else
+ cmd += 0x10;
}
-byte C64CostumeLoader::increaseAnim(Actor *a, int slot) {
- return 0;
+void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
+ ActorC64 *A = (ActorC64 *)a;
+ int dir = newDirToOldDir(a->getFacing());
+ int command = dir;
+
+ loadCostume(a->_costume);
+
+ // Enable/Disable speaking flag
+ if (frame == a->_talkStartFrame) {
+ A->_speaking = 1;
+ return;
+ }
+ if (frame == a->_talkStopFrame) {
+ A->_speaking = 0;
+ return;
+ }
+
+ // Different command for stand frame
+ if (frame == a->_standFrame)
+ command = dirToDirStop(dir);
+
+ // Update the limb frames
+ frameUpdate(A, command);
+
+ // Keep current command/frame mode
+ A->_costCommand = dir;
+ A->_costFrame = frame;
+
+ // Update 'speaking' frames?
+ if (A->_speaking) {
+ command = dir; // Incase standing frame was set as cmd
+ actorSpeak(A, command);
+
+ // Update the limb speak frames
+ frameUpdate(A, command);
+ }
}
+byte C64CostumeLoader::increaseAnims(Actor *a) {
+ ActorC64 *A = (ActorC64 *)a;
+
+ // check if the actor speak flag has changed since last frame increase
+ if (A->_speaking != A->_speakingPrev) {
+ int cmd = A->_costCommand;
+ A->_speakingPrev = A->_speaking;
+
+ // Update to use speak frame
+ if (A->_speaking & 0x80) {
+ actorSpeak(A, cmd);
+
+ } else {
+ // Update to use stand frame
+ if (A->_costFrame == A->_standFrame)
+ cmd = dirToDirStop(cmd);
+ }
+
+ // Update the limb frames
+ frameUpdate(A, cmd);
+ }
+
+ // increase each frame pos
+ for (int limb = 0; limb < 8; ++limb) {
+ if (a->_cost.curpos[limb] < a->_cost.end[limb])
+ a->_cost.curpos[limb]++;
+ else
+ a->_cost.curpos[limb] = 0;
+ }
+
+ return 1;
+}
} // End of namespace Scumm
diff --git a/engines/scumm/costume.h b/engines/scumm/costume.h
index ecb12986cf..929eb8c451 100644
--- a/engines/scumm/costume.h
+++ b/engines/scumm/costume.h
@@ -79,8 +79,12 @@ public:
byte increaseAnims(Actor *a);
int _maxHeight;
+
protected:
- byte increaseAnim(Actor *a, int slot);
+ void actorSpeak(ActorC64 *a, int &cmd);
+ int dirToDirStop(int oldDir);
+ void frameUpdate(ActorC64 *A, int cmd);
+
};
class ClassicCostumeRenderer : public BaseCostumeRenderer {
diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp
index 5fa74d22c3..8beb2ef720 100644
--- a/engines/scumm/detection.cpp
+++ b/engines/scumm/detection.cpp
@@ -723,6 +723,32 @@ GameDescriptor ScummMetaEngine::findGame(const char *gameid) const {
return AdvancedDetector::findGameID(gameid, gameDescriptions, obsoleteGameIDsTable);
}
+static Common::String generatePreferredTarget(const DetectorResult &x) {
+ Common::String res(x.game.gameid);
+
+ if (x.game.preferredTag) {
+ res = res + "-" + x.game.preferredTag;
+ }
+
+ if (x.game.features & GF_DEMO) {
+ res = res + "-demo";
+ }
+
+ // Append the platform, if a non-standard one has been specified.
+ if (x.game.platform != Common::kPlatformPC && x.game.platform != Common::kPlatformUnknown) {
+ // HACK: For CoMI, it's pointless to encode the fact that it's for Windows
+ if (x.game.id != GID_CMI)
+ res = res + "-" + Common::getPlatformAbbrev(x.game.platform);
+ }
+
+ // Append the language, if a non-standard one has been specified
+ if (x.language != Common::EN_ANY && x.language != Common::UNK_LANG) {
+ res = res + "-" + Common::getLanguageCode(x.language);
+ }
+
+ return res;
+}
+
GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
GameList detectedGames;
Common::List<DetectorResult> results;
@@ -737,34 +763,34 @@ GameList ScummMetaEngine::detectGames(const Common::FSList &fslist) const {
const PlainGameDescriptor *g = findPlainGameDescriptor(x->game.gameid, gameDescriptions);
assert(g);
GameDescriptor dg(x->game.gameid, g->description, x->language, x->game.platform);
- dg.updateDesc(x->extra); // Append additional information, if set, to the description.
+
+ // Append additional information, if set, to the description.
+ dg.updateDesc(x->extra);
// Compute and set the preferred target name for this game.
// Based on generateComplexID() in advancedDetector.cpp.
- Common::String res(x->game.gameid);
-
- if (x->game.preferredTag) {
- res = res + "-" + x->game.preferredTag;
- }
-
- if (x->game.features & GF_DEMO) {
- res = res + "-demo";
- }
-
- // Append the platform, if a non-standard one has been specified.
- if (x->game.platform != Common::kPlatformPC && x->game.platform != Common::kPlatformUnknown) {
- // HACK: For CoMI, it's pointless to encode the fact that it's for Windows
- if (x->game.id != GID_CMI)
- res = res + "-" + Common::getPlatformAbbrev(x->game.platform);
- }
-
- // Append the language, if a non-standard one has been specified
- if (x->language != Common::EN_ANY && x->language != Common::UNK_LANG) {
- res = res + "-" + Common::getLanguageCode(x->language);
+ dg["preferredtarget"] = generatePreferredTarget(*x);
+
+ // HACK: Detect and distinguish the FM-TOWNS demos
+ if (x->game.platform == Common::kPlatformFMTowns && (x->game.features & GF_DEMO)) {
+ if (x->md5 == "2d388339d6050d8ccaa757b64633954e") {
+ // Indy + Loom demo
+ dg.description() = "Indiana Jones and the Last Crusade & Loom";
+ dg.updateDesc(x->extra);
+ dg["preferredtarget"] = "indyloom";
+ } else if (x->md5 == "77f5c9cc0986eb729c1a6b4c8823bbae") {
+ // Zak + Loom demo
+ dg.description() = "Zak McKracken & Loom";
+ dg.updateDesc(x->extra);
+ dg["preferredtarget"] = "zakloom";
+ } else if (x->md5 == "3938ee1aa4433fca9d9308c9891172b1") {
+ // Indy + Zak demo
+ dg.description() = "Indiana Jones and the Last Crusade & Zak McKracken";
+ dg.updateDesc(x->extra);
+ dg["preferredtarget"] = "indyzak";
+ }
}
- dg["preferredtarget"] = res;
-
dg.setGUIOptions(x->game.guioptions);
detectedGames.push_back(dg);
diff --git a/engines/scumm/detection_tables.h b/engines/scumm/detection_tables.h
index 92024a21cc..5054bffd30 100644
--- a/engines/scumm/detection_tables.h
+++ b/engines/scumm/detection_tables.h
@@ -230,14 +230,14 @@ static const GameSettings gameVariantsTable[] = {
{"monkey2", 0, 0, GID_MONKEY2, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH},
- {"atlantis", "", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH},
- {"atlantis", "CD" , 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NONE},
+ {"atlantis", "" , 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NONE},
+ {"atlantis", "Floppy", 0, GID_INDY4, 5, 0, MDT_ADLIB | MDT_MIDI, 0, UNK, GUIO_NOSPEECH},
- {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
- {"tentacle", "CD", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"tentacle", "", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"tentacle", "Floppy", 0, GID_TENTACLE, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
- {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
- {"samnmax", "CD", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"samnmax", "", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NONE},
+ {"samnmax", "Floppy", 0, GID_SAMNMAX, 6, 0, MDT_ADLIB | MDT_MIDI, GF_USE_KEY, UNK, GUIO_NOSPEECH},
#ifdef ENABLE_SCUMM_7_8
{"ft", 0, 0, GID_FT, 7, 0, MDT_NONE, 0, UNK, GUIO_NOMIDI},
diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp
index 880fab04a5..42e49afcc1 100644
--- a/engines/scumm/dialogs.cpp
+++ b/engines/scumm/dialogs.cpp
@@ -439,7 +439,7 @@ ScummMenuDialog::ScummMenuDialog(ScummEngine *scumm)
new GUI::ButtonWidget(this, "ScummMain.Resume", "Resume", kPlayCmd, 'P');
new GUI::ButtonWidget(this, "ScummMain.Load", "Load", kLoadCmd, 'L');
- new GUI::ButtonWidget(this, "ScummMain.Save", "Save", kSaveCmd, 'S');
+ _saveButton = new GUI::ButtonWidget(this, "ScummMain.Save", "Save", kSaveCmd, 'S');
new GUI::ButtonWidget(this, "ScummMain.Options", "Options", kOptionsCmd, 'O');
#ifndef DISABLE_HELP
@@ -471,6 +471,13 @@ ScummMenuDialog::~ScummMenuDialog() {
delete _loadDialog;
}
+void ScummMenuDialog::reflowLayout() {
+ if (!_vm->canSaveGameStateCurrently())
+ _saveButton->setEnabled(false);
+
+ Dialog::reflowLayout();
+}
+
void ScummMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) {
switch (cmd) {
case kSaveCmd:
diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h
index af844272fa..d4ecbde534 100644
--- a/engines/scumm/dialogs.h
+++ b/engines/scumm/dialogs.h
@@ -88,6 +88,8 @@ public:
~ScummMenuDialog();
virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data);
+ virtual void reflowLayout();
+
protected:
ScummEngine *_vm;
@@ -99,6 +101,8 @@ protected:
SaveLoadChooser *_saveDialog;
SaveLoadChooser *_loadDialog;
+ GUI::ButtonWidget *_saveButton;
+
void save();
void load();
};
diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp
index 3f101691c7..6dc31b09ef 100644
--- a/engines/scumm/file.cpp
+++ b/engines/scumm/file.cpp
@@ -126,7 +126,7 @@ bool ScummFile::openSubFile(const Common::String &filename) {
bool ScummFile::eos() const {
- return _subFileLen ? (pos() >= _subFileLen) : File::eos(); // FIXME
+ return _subFileLen ? _myEos : File::eos();
}
int32 ScummFile::pos() const {
@@ -154,7 +154,10 @@ bool ScummFile::seek(int32 offs, int whence) {
assert((int32)_subFileStart <= offs && offs <= (int32)(_subFileStart + _subFileLen));
whence = SEEK_SET;
}
- return File::seek(offs, whence);
+ bool ret = File::seek(offs, whence);
+ if (ret)
+ _myEos = false;
+ return ret;
}
uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
@@ -167,7 +170,7 @@ uint32 ScummFile::read(void *dataPtr, uint32 dataSize) {
int32 newPos = curPos + dataSize;
if (newPos > _subFileLen) {
dataSize = _subFileLen - curPos;
- _myIoFailed = true;
+ _myEos = true;
}
}
diff --git a/engines/scumm/file.h b/engines/scumm/file.h
index aa52dd069f..c37c2f036e 100644
--- a/engines/scumm/file.h
+++ b/engines/scumm/file.h
@@ -55,7 +55,7 @@ private:
byte _encbyte;
int32 _subFileStart;
int32 _subFileLen;
- bool _myIoFailed;
+ bool _myEos; // Have we read past the end of the subfile?
void setSubfileRange(int32 start, int32 len);
void resetSubfile();
@@ -67,8 +67,7 @@ public:
bool open(const Common::String &filename);
bool openSubFile(const Common::String &filename);
- bool ioFailed() const { return _myIoFailed || BaseScummFile::ioFailed(); }
- void clearIOFailed() { _myIoFailed = false; BaseScummFile::clearIOFailed(); }
+ void clearErr() { _myEos = false; BaseScummFile::clearErr(); }
bool eos() const;
int32 pos() const;
diff --git a/engines/scumm/gfx.cpp b/engines/scumm/gfx.cpp
index a54199272f..3839a75261 100644
--- a/engines/scumm/gfx.cpp
+++ b/engines/scumm/gfx.cpp
@@ -774,18 +774,18 @@ void ditherHerc(byte *src, byte *hercbuf, int srcPitch, int *x, int *y, int *wid
}
void scale2x(byte *dst, int dstPitch, const byte *src, int srcPitch, int w, int h) {
- byte *dstL1 = dst;
- byte *dstL2 = dst + dstPitch;
+ uint16 *dstL1 = (uint16 *)dst;
+ uint16 *dstL2 = (uint16 *)(dst + dstPitch);
- int dstAdd = dstPitch * 2 - w * 2;
- int srcAdd = srcPitch - w;
+ const int dstAdd = dstPitch - w;
+ const int srcAdd = srcPitch - w;
while (h--) {
- for (int x = 0; x < w; ++x, dstL1 += 2, dstL2 += 2) {
+ for (int x = 0; x < w; ++x) {
uint16 col = *src++;
col |= col << 8;
- *(uint16*)(dstL1) = col;
- *(uint16*)(dstL2) = col;
+ *dstL1++ = col;
+ *dstL2++ = col;
}
dstL1 += dstAdd; dstL2 += dstAdd;
src += srcAdd;
diff --git a/engines/scumm/he/cup_player_he.cpp b/engines/scumm/he/cup_player_he.cpp
index 51176c5df9..39615edb6a 100644
--- a/engines/scumm/he/cup_player_he.cpp
+++ b/engines/scumm/he/cup_player_he.cpp
@@ -91,20 +91,19 @@ void CUP_Player::close() {
}
void CUP_Player::play() {
- while (parseNextHeaderTag(_fileStream)) {
- if (_fileStream.ioFailed()) {
- return;
- }
- }
+ while (parseNextHeaderTag(_fileStream)) { }
+
+ if (_fileStream.eos() || _fileStream.err())
+ return;
+
debug(1, "rate %d width %d height %d", _playbackRate, _width, _height);
int ticks = _system->getMillis();
while (_dataSize != 0 && !_vm->shouldQuit()) {
- while (parseNextBlockTag(_fileStream)) {
- if (_fileStream.ioFailed()) {
- return;
- }
- }
+ while (parseNextBlockTag(_fileStream)) { }
+ if (_fileStream.eos() || _fileStream.err())
+ return;
+
int diff = _system->getMillis() - ticks;
if (diff >= 0 && diff <= _playbackRate) {
_system->delayMillis(_playbackRate - diff);
@@ -200,6 +199,10 @@ void CUP_Player::waitForSfxChannel(int channel) {
bool CUP_Player::parseNextHeaderTag(Common::SeekableReadStream &dataStream) {
uint32 tag = dataStream.readUint32BE();
uint32 size = dataStream.readUint32BE() - 8;
+
+ if (dataStream.eos())
+ return false;
+
uint32 next = dataStream.pos() + size;
debug(1, "New header tag %s %d dataSize %d", tag2str(tag), size, _dataSize);
switch (tag) {
diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h
index 8aa8a8d3f5..2f7f539ee3 100644
--- a/engines/scumm/he/intern_he.h
+++ b/engines/scumm/he/intern_he.h
@@ -78,7 +78,7 @@ protected:
int virtScreenSave(byte *dst, int x1, int y1, int x2, int y2);
void virtScreenLoad(int resIdx, int x1, int y1, int x2, int y2);
- int convertFilePath(byte *dst);
+ int convertFilePath(byte *dst, int dstSize);
virtual void decodeParseString(int a, int b);
void swapObjects(int object1, int object2);
diff --git a/engines/scumm/he/script_v100he.cpp b/engines/scumm/he/script_v100he.cpp
index 58a858ede4..2748633bdc 100644
--- a/engines/scumm/he/script_v100he.cpp
+++ b/engines/scumm/he/script_v100he.cpp
@@ -1624,7 +1624,7 @@ void ScummEngine_v100he::o100_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer));
- r = convertFilePath(buffer);
+ r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o100_roomOps: case 137: filename %s", _saveLoadFileName);
@@ -2243,7 +2243,7 @@ void ScummEngine_v100he::o100_videoOps() {
if (_videoParams.flags == 0)
_videoParams.flags = 4;
- const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename);
+ const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags == 2) {
VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
} else {
diff --git a/engines/scumm/he/script_v60he.cpp b/engines/scumm/he/script_v60he.cpp
index b416a0e75d..79b589df00 100644
--- a/engines/scumm/he/script_v60he.cpp
+++ b/engines/scumm/he/script_v60he.cpp
@@ -93,7 +93,7 @@ void ScummEngine_v60he::setupOpcodes() {
_opcodes[0xed].setProc(0, 0);
}
-int ScummEngine_v60he::convertFilePath(byte *dst) {
+int ScummEngine_v60he::convertFilePath(byte *dst, int dstSize) {
debug(1, "convertFilePath: original filePath is %s", dst);
int len = resStrLen(dst);
@@ -113,18 +113,27 @@ int ScummEngine_v60he::convertFilePath(byte *dst) {
// Strip path
int r = 0;
- if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
+ if (dst[len - 3] == 's' && dst[len - 2] == 'g') { // Save Game File
+ // Change filename prefix to target name, for save game files.
+ char saveName[20];
+ sprintf(saveName, "%s.sg%c", _targetName.c_str(), dst[len - 1]);
+ memcpy(dst, saveName, 20);
+ } else if (dst[0] == '.' && dst[1] == '/') { // Game Data Path
+ // The default game data path is set to './' by ScummVM
r = 2;
} else if (dst[2] == 'b' && dst[5] == 'k') { // Backyard Basketball INI
r = 13;
} else if (dst[0] == '*' && dst[1] == '/') { // Save Game Path (HE72 - HE100)
+ // The default save game path is set to '*/' by ScummVM
r = 2;
} else if (dst[0] == 'c' && dst[1] == ':') { // Save Game Path (HE60 - HE71)
+ // The default save path is game path (DOS) or 'c:/hegames/' (Windows)
for (r = len; r != 0; r--) {
if (dst[r - 1] == '/')
break;
}
} else if (dst[0] == 'u' && dst[1] == 's') { // Save Game Path (Moonbase Commander)
+ // The default save path is 'user/'
r = 5;
}
@@ -271,7 +280,7 @@ void ScummEngine_v60he::o60_roomOps() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- r = convertFilePath(buffer);
+ r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o60_roomOps: case 221: filename %s", _saveLoadFileName);
@@ -686,7 +695,7 @@ void ScummEngine_v60he::o60_openFile() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- filename = (char *)buffer + convertFilePath(buffer);
+ filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "Final filename to %s", filename);
mode = pop();
@@ -740,7 +749,7 @@ void ScummEngine_v60he::o60_deleteFile() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- filename = (char *)buffer + convertFilePath(buffer);
+ filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "o60_deleteFile (\"%s\")", filename);
@@ -762,8 +771,8 @@ void ScummEngine_v60he::o60_rename() {
len = resStrLen(_scriptPointer);
_scriptPointer += len + 1;
- oldFilename = (char *)buffer1 + convertFilePath(buffer1);
- newFilename = (char *)buffer2 + convertFilePath(buffer2);
+ oldFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
+ newFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
debug(1, "o60_rename (\"%s\" to \"%s\")", oldFilename, newFilename);
diff --git a/engines/scumm/he/script_v72he.cpp b/engines/scumm/he/script_v72he.cpp
index 9d5bd0b23d..c6489004d7 100644
--- a/engines/scumm/he/script_v72he.cpp
+++ b/engines/scumm/he/script_v72he.cpp
@@ -713,7 +713,7 @@ void ScummEngine_v72he::o72_roomOps() {
copyScriptString((byte *)buffer, sizeof(buffer));
- r = convertFilePath(buffer);
+ r = convertFilePath(buffer, sizeof(buffer));
memcpy(_saveLoadFileName, buffer + r, sizeof(buffer) - r);
debug(1, "o72_roomOps: case 221: filename %s", _saveLoadFileName);
@@ -1401,7 +1401,7 @@ void ScummEngine_v72he::o72_openFile() {
strcpy((char *)buffer, "moonbase.ini");
}
- const char *filename = (char *)buffer + convertFilePath(buffer);
+ const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "Final filename to %s", filename);
slot = -1;
@@ -1548,7 +1548,7 @@ void ScummEngine_v72he::o72_deleteFile() {
byte buffer[256];
copyScriptString(buffer, sizeof(buffer));
- const char *filename = (char *)buffer + convertFilePath(buffer);
+ const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
debug(1, "o72_deleteFile(%s)", filename);
@@ -1563,8 +1563,8 @@ void ScummEngine_v72he::o72_rename() {
copyScriptString(buffer1, sizeof(buffer1));
copyScriptString(buffer2, sizeof(buffer2));
- const char *newFilename = (char *)buffer1 + convertFilePath(buffer1);
- const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2);
+ const char *newFilename = (char *)buffer1 + convertFilePath(buffer1, sizeof(buffer1));
+ const char *oldFilename = (char *)buffer2 + convertFilePath(buffer2, sizeof(buffer2));
_saveFileMan->renameSavefile(oldFilename, newFilename);
diff --git a/engines/scumm/he/script_v80he.cpp b/engines/scumm/he/script_v80he.cpp
index 4b759dec53..fb63568e9f 100644
--- a/engines/scumm/he/script_v80he.cpp
+++ b/engines/scumm/he/script_v80he.cpp
@@ -89,7 +89,7 @@ void ScummEngine_v80he::o80_getFileSize() {
byte buffer[256];
copyScriptString(buffer, sizeof(buffer));
- const char *filename = (char *)buffer + convertFilePath(buffer);
+ const char *filename = (char *)buffer + convertFilePath(buffer, sizeof(buffer));
Common::SeekableReadStream *f = 0;
if (!_saveFileMan->listSavefiles(filename).empty()) {
@@ -154,7 +154,7 @@ void ScummEngine_v80he::o80_readConfigFile() {
copyScriptString(section, sizeof(section));
copyScriptString(filename, sizeof(filename));
- r = convertFilePath(filename);
+ r = convertFilePath(filename, sizeof(filename));
if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters
@@ -222,7 +222,7 @@ void ScummEngine_v80he::o80_writeConfigFile() {
error("o80_writeConfigFile: default type %d", subOp);
}
- r = convertFilePath(filename);
+ r = convertFilePath(filename, sizeof(filename));
if (_game.id == GID_TREASUREHUNT) {
// WORKAROUND: Remove invalid characters
diff --git a/engines/scumm/he/script_v90he.cpp b/engines/scumm/he/script_v90he.cpp
index 7a7a1ff58b..8c50dfecc3 100644
--- a/engines/scumm/he/script_v90he.cpp
+++ b/engines/scumm/he/script_v90he.cpp
@@ -1427,7 +1427,7 @@ void ScummEngine_v90he::o90_videoOps() {
if (_videoParams.flags == 0)
_videoParams.flags = 4;
- const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename);
+ const char *filename = (char *)_videoParams.filename + convertFilePath(_videoParams.filename, sizeof(_videoParams.filename));
if (_videoParams.flags & 2) {
VAR(119) = _moviePlay->load(filename, _videoParams.flags, _videoParams.wizResNum);
} else {
diff --git a/engines/scumm/he/wiz_he.cpp b/engines/scumm/he/wiz_he.cpp
index a6dab366ee..b79c35740e 100644
--- a/engines/scumm/he/wiz_he.cpp
+++ b/engines/scumm/he/wiz_he.cpp
@@ -2345,7 +2345,7 @@ void Wiz::processWizImage(const WizParameters *params) {
if (params->processFlags & kWPFUseFile) {
Common::SeekableReadStream *f = NULL;
memcpy(buffer, params->filename, 260);
- const char *filename = (char *)buffer + _vm->convertFilePath(buffer);
+ const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer));
if (!_vm->_saveFileMan->listSavefiles(filename).empty()) {
f = _vm->_saveFileMan->openForLoading(filename);
@@ -2390,7 +2390,7 @@ void Wiz::processWizImage(const WizParameters *params) {
if (params->processFlags & kWPFUseFile) {
Common::OutSaveFile *f;
memcpy(buffer, params->filename, 260);
- const char *filename = (char *)buffer + _vm->convertFilePath(buffer);
+ const char *filename = (char *)buffer + _vm->convertFilePath(buffer, sizeof(buffer));
switch (params->fileWriteMode) {
case 2:
diff --git a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
index 4577a11fe1..be5f7623ca 100644
--- a/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
+++ b/engines/scumm/imuse_digi/dimuse_bndmgr.cpp
@@ -225,7 +225,7 @@ bool BundleMgr::loadCompTable(int32 index) {
_file->seek(8, SEEK_CUR);
if (tag != MKID_BE('COMP')) {
- error("BundleMgr::loadCompTable() Compressed sound %d invalid (%s)", index, tag2str(tag));
+ error("BundleMgr::loadCompTable() Compressed sound %d (%s:%d) invalid (%s)", index, _file->getName(), _bundleTable[index].offset, tag2str(tag));
return false;
}
diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp
index 61b714a3e2..ab32992b03 100644
--- a/engines/scumm/input.cpp
+++ b/engines/scumm/input.cpp
@@ -110,9 +110,9 @@ void ScummEngine_v80he::parseEvent(Common::Event event) {
void ScummEngine::parseEvent(Common::Event event) {
switch (event.type) {
case Common::EVENT_KEYDOWN:
- if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9'
- && (event.kbd.flags == Common::KBD_ALT ||
- event.kbd.flags == Common::KBD_CTRL)) {
+ if (event.kbd.keycode >= '0' && event.kbd.keycode <= '9' &&
+ ((event.kbd.flags == Common::KBD_ALT && canSaveGameStateCurrently()) ||
+ (event.kbd.flags == Common::KBD_CTRL && canLoadGameStateCurrently()))) {
_saveLoadSlot = event.kbd.keycode - '0';
// don't overwrite autosave (slot 0)
@@ -302,17 +302,6 @@ void ScummEngine::processInput() {
//
_mouseAndKeyboardStat = 0;
- // Interpret 'return' as left click and 'tab' as right click
- if (lastKeyHit.keycode && _cursor.state > 0) {
- if (lastKeyHit.keycode == Common::KEYCODE_TAB) {
- _mouseAndKeyboardStat = MBS_RIGHT_CLICK;
- lastKeyHit.reset();
- } else if (lastKeyHit.keycode == Common::KEYCODE_RETURN) {
- _mouseAndKeyboardStat = MBS_LEFT_CLICK;
- lastKeyHit.reset();
- }
- }
-
if ((_leftBtnPressed & msClicked) && (_rightBtnPressed & msClicked) && _game.version >= 4) {
// Pressing both mouse buttons is treated as if you pressed
// the cutscene exit key (ESC) in V4+ games. That mimicks
diff --git a/engines/scumm/object.cpp b/engines/scumm/object.cpp
index f29be071e0..2eab2cfa3a 100644
--- a/engines/scumm/object.cpp
+++ b/engines/scumm/object.cpp
@@ -181,7 +181,11 @@ void ScummEngine::clearOwnerOf(int obj) {
// Alternatively, scan the inventory to see if the object is in there...
for (i = 0; i < _numInventory; i++) {
if (_inventory[i] == obj) {
- assert(WIO_INVENTORY == whereIsObject(obj));
+ if (_game.version == 0)
+ assert(WIO_INVENTORY == whereIsObjectInventory(obj));
+ else
+ assert(WIO_INVENTORY == whereIsObject(obj));
+
// Found the object! Nuke it from the inventory.
_res->nukeResource(rtInventory, i);
_inventory[i] = 0;
@@ -286,7 +290,7 @@ int ScummEngine::getState(int obj) {
// it. Fortunately this does not prevent frustrated players from
// blowing up the mansion, should they feel the urge to.
- if (_game.id == GID_MANIAC && (obj == 182 || obj == 193))
+ if (_game.id == GID_MANIAC && _game.version != 0 && (obj == 182 || obj == 193))
_objectStateTable[obj] |= kObjectState_08;
}
@@ -317,6 +321,15 @@ int ScummEngine::getObjectIndex(int object) const {
return -1;
}
+int ScummEngine::whereIsObjectInventory(int object) {
+ int res = 0;
+ _v0ObjectInInventory = true;
+ res = whereIsObject(object);
+ _v0ObjectInInventory = false;
+
+ return res;
+}
+
int ScummEngine::whereIsObject(int object) const {
int i;
@@ -326,7 +339,7 @@ int ScummEngine::whereIsObject(int object) const {
if (object < 1)
return WIO_NOT_FOUND;
- if (_objectOwnerTable[object] != OF_OWNER_ROOM) {
+ if ((_objectOwnerTable[object] != OF_OWNER_ROOM && _game.version != 0) || _v0ObjectInInventory) {
for (i = 0; i < _numInventory; i++)
if (_inventory[i] == object)
return WIO_INVENTORY;
@@ -334,7 +347,7 @@ int ScummEngine::whereIsObject(int object) const {
}
for (i = (_numLocalObjects-1); i > 0; i--)
- if (_objs[i].obj_nr == object) {
+ if ((_objs[i].obj_nr == object && !_v0ObjectIndex) || (_v0ObjectIndex && i == object)) {
if (_objs[i].fl_object_index)
return WIO_FLOBJECT;
return WIO_ROOM;
@@ -379,7 +392,7 @@ int ScummEngine::getObjectOrActorXY(int object, int &x, int &y) {
* Returns X, Y and direction in angles
*/
void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
- int idx = getObjectIndex(object);
+ int idx = (_v0ObjectIndex) ? object : getObjectIndex(object);
assert(idx >= 0);
ObjectData &od = _objs[idx];
int state;
@@ -434,7 +447,7 @@ void ScummEngine::getObjectXYPos(int object, int &x, int &y, int &dir) {
dir = oldDirToNewDir(od.actordir & 3);
}
-static int getDist(int x, int y, int x2, int y2) {
+int ScummEngine::getDist(int x, int y, int x2, int y2) {
int a = ABS(y - y2);
int b = ABS(x - x2);
return MAX(a, b);
@@ -475,6 +488,14 @@ int ScummEngine::getObjActToObjActDist(int a, int b) {
return getDist(x, y, x2, y2);
}
+int ScummEngine_v0::findObjectIndex(int x, int y) {
+ int objIdx;
+ _v0ObjectIndex = true;
+ objIdx = findObject(x, y);
+ _v0ObjectIndex = false;
+ return objIdx;
+}
+
int ScummEngine::findObject(int x, int y) {
int i, b;
byte a;
@@ -504,8 +525,12 @@ int ScummEngine::findObject(int x, int y) {
}
#endif
if (_objs[i].x_pos <= x && _objs[i].width + _objs[i].x_pos > x &&
- _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y)
- return _objs[i].obj_nr;
+ _objs[i].y_pos <= y && _objs[i].height + _objs[i].y_pos > y) {
+ if (_game.version == 0 && _v0ObjectIndex)
+ return i;
+ else
+ return _objs[i].obj_nr;
+ }
break;
}
} while ((_objs[b].state & mask) == a);
@@ -811,6 +836,9 @@ void ScummEngine_v3old::resetRoomObjects() {
if (_dumpScripts) {
char buf[32];
sprintf(buf, "roomobj-%d-", _roomResource);
+ if (_game.version == 0)
+ sprintf(buf + 11, "%d-", od->flags);
+
dumpResource(buf, od->obj_nr, room + od->OBCDoffset);
}
}
@@ -1033,6 +1061,10 @@ void ScummEngine::updateObjectStates() {
int i;
ObjectData *od = &_objs[1];
for (i = 1; i < _numLocalObjects; i++, od++) {
+ // V0 MM, Room objects with Flag == 1 are objects with 'no-state' (room specific objects, non-pickup)
+ if (_game.version == 0 && od->flags == 1)
+ continue;
+
if (od->obj_nr > 0)
od->state = getState(od->obj_nr);
}
@@ -1155,7 +1187,7 @@ const byte *ScummEngine::getObjOrActorName(int obj) {
void ScummEngine::setObjectName(int obj) {
int i;
- if (obj < _numActors)
+ if (obj < _numActors && _game.version != 0)
error("Can't set actor %d name with new-name-of", obj);
for (i = 0; i < _numNewNames; i++) {
@@ -1181,8 +1213,13 @@ void ScummEngine::setObjectName(int obj) {
uint32 ScummEngine::getOBCDOffs(int object) const {
int i;
- if (_objectOwnerTable[object] != OF_OWNER_ROOM)
+ if ((_objectOwnerTable[object] != OF_OWNER_ROOM && (_game.version != 0)) || _v0ObjectInInventory)
return 0;
+
+ // V0 MM Return by Index
+ if (_v0ObjectIndex)
+ return _objs[object].OBCDoffset;
+
for (i = (_numLocalObjects-1); i > 0; i--) {
if (_objs[i].obj_nr == object) {
if (_objs[i].fl_object_index != 0)
@@ -1194,17 +1231,20 @@ uint32 ScummEngine::getOBCDOffs(int object) const {
}
byte *ScummEngine::getOBCDFromObject(int obj) {
+ bool useInventory = _v0ObjectInInventory;
int i;
byte *ptr;
- if (_objectOwnerTable[obj] != OF_OWNER_ROOM) {
+ _v0ObjectInInventory = false;
+
+ if ((_objectOwnerTable[obj] != OF_OWNER_ROOM && (_game.version != 0)) || useInventory) {
for (i = 0; i < _numInventory; i++) {
if (_inventory[i] == obj)
return getResourceAddress(rtInventory, i);
}
} else {
for (i = (_numLocalObjects-1); i > 0; --i) {
- if (_objs[i].obj_nr == obj) {
+ if ((_objs[i].obj_nr == obj && !_v0ObjectIndex) || (_v0ObjectIndex && i == obj)) {
if (_objs[i].fl_object_index) {
assert(_objs[i].OBCDoffset == 8);
ptr = getResourceAddress(rtFlObject, _objs[i].fl_object_index);
diff --git a/engines/scumm/resource.cpp b/engines/scumm/resource.cpp
index 8359675032..d3faa15c10 100644
--- a/engines/scumm/resource.cpp
+++ b/engines/scumm/resource.cpp
@@ -229,7 +229,7 @@ void ScummEngine::askForDisk(const char *filename, int disknum) {
sprintf(buf, "Cannot find file: '%s'\nInsert disc %d into drive %s\nPress OK to retry, Quit to exit", filename, disknum, _gameDataDir.getPath().c_str());
#endif
- result = displayMessage("Quit", buf);
+ result = displayMessage("Quit", "%s", buf);
if (!result) {
error("Cannot find file: '%s'", filename);
}
@@ -253,10 +253,10 @@ void ScummEngine::readIndexFile() {
if (_game.version <= 5) {
// Figure out the sizes of various resources
- while (!_fileHandle->eos()) {
+ while (true) {
blocktype = _fileHandle->readUint32BE();
itemsize = _fileHandle->readUint32BE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
switch (blocktype) {
case MKID_BE('DOBJ'):
@@ -285,7 +285,6 @@ void ScummEngine::readIndexFile() {
}
_fileHandle->seek(itemsize - 8, SEEK_CUR);
}
- _fileHandle->clearIOFailed();
_fileHandle->seek(0, SEEK_SET);
}
@@ -300,7 +299,7 @@ void ScummEngine::readIndexFile() {
blocktype = _fileHandle->readUint32BE();
itemsize = _fileHandle->readUint32BE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
numblock++;
@@ -689,7 +688,7 @@ int ScummEngine::loadResource(int type, int idx) {
dumpResource("script-", idx, getResourceAddress(rtScript, idx));
}
- if (!_fileHandle->ioFailed()) {
+ if (!_fileHandle->err() && !_fileHandle->eos()) {
return 1;
}
diff --git a/engines/scumm/resource_v2.cpp b/engines/scumm/resource_v2.cpp
index 184f3d94df..e469c721b1 100644
--- a/engines/scumm/resource_v2.cpp
+++ b/engines/scumm/resource_v2.cpp
@@ -138,7 +138,7 @@ void ScummEngine_v2::readEnhancedIndexFile() {
_fileHandle->seek(_numScripts * 3, SEEK_CUR);
_numSounds = _fileHandle->readByte();
- _fileHandle->clearIOFailed();
+ _fileHandle->clearErr();
_fileHandle->seek(0, SEEK_SET);
readMAXS(0);
diff --git a/engines/scumm/resource_v3.cpp b/engines/scumm/resource_v3.cpp
index 420f71cf03..0728395055 100644
--- a/engines/scumm/resource_v3.cpp
+++ b/engines/scumm/resource_v3.cpp
@@ -80,7 +80,7 @@ void ScummEngine_v3old::readIndexFile() {
_fileHandle->seek(_numScripts * 3, SEEK_CUR);
_numSounds = _fileHandle->readByte();
- _fileHandle->clearIOFailed();
+ _fileHandle->clearErr();
_fileHandle->seek(0, SEEK_SET);
readMAXS(0);
diff --git a/engines/scumm/resource_v4.cpp b/engines/scumm/resource_v4.cpp
index 28e0fb05b5..75858f7b42 100644
--- a/engines/scumm/resource_v4.cpp
+++ b/engines/scumm/resource_v4.cpp
@@ -61,11 +61,11 @@ void ScummEngine_v4::readIndexFile() {
closeRoom();
openRoom(0);
- while (!_fileHandle->eos()) {
+ while (true) {
// Figure out the sizes of various resources
itemsize = _fileHandle->readUint32LE();
blocktype = _fileHandle->readUint16LE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
switch (blocktype) {
@@ -95,16 +95,15 @@ void ScummEngine_v4::readIndexFile() {
_fileHandle->seek(itemsize - 8, SEEK_CUR);
}
- _fileHandle->clearIOFailed();
_fileHandle->seek(0, SEEK_SET);
readMAXS(0);
allocateArrays();
- while (1) {
+ while (true) {
itemsize = _fileHandle->readUint32LE();
- if (_fileHandle->ioFailed())
+ if (_fileHandle->eos() || _fileHandle->err())
break;
blocktype = _fileHandle->readUint16LE();
diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp
index 144de2f5f1..7bf61a8762 100644
--- a/engines/scumm/saveload.cpp
+++ b/engines/scumm/saveload.cpp
@@ -86,6 +86,19 @@ bool ScummEngine::canLoadGameStateCurrently() {
// FIXME: Actually, we might wish to support loading in more places.
// As long as we are sure it won't cause any problems... Are we
// aware of *any* spots where loading is not supported?
+
+ // HE games are limited to original load and save interface only,
+ // due to numerous glitches (see bug #1726909) that can occur.
+ if (_game.heversion >= 60)
+ return false;
+
+ // COMI always disables saving/loading (to tell the truth:
+ // the main menu) via its scripts, thus we need to make an
+ // exception here. This the same forced overwriting of the
+ // script decisions as in ScummEngine::processKeyboard.
+ if (_game.id == GID_CMI)
+ return true;
+
return (VAR_MAINMENU_KEY == 0xFF || VAR(VAR_MAINMENU_KEY) != 0);
}
@@ -99,7 +112,22 @@ bool ScummEngine::canSaveGameStateCurrently() {
// TODO: Should we disallow saving in some more places,
// e.g. when a SAN movie is playing? Not sure whether the
// original EXE allowed this.
- return (VAR_MAINMENU_KEY == 0xFF || VAR(VAR_MAINMENU_KEY) != 0);
+
+ // HE games are limited to original load and save interface only,
+ // due to numerous glitches (see bug #1726909) that can occur.
+ if (_game.heversion >= 60)
+ return false;
+
+ // COMI always disables saving/loading (to tell the truth:
+ // the main menu) via its scripts, thus we need to make an
+ // exception here. This the same forced overwriting of the
+ // script decisions as in ScummEngine::processKeyboard.
+ if (_game.id == GID_CMI)
+ return true;
+
+ // SCUMM v4+ doesn't allow saving in room 0 or if
+ // VAR(VAR_MAINMENU_KEY) to set to zero.
+ return (VAR_MAINMENU_KEY == 0xFF || (VAR(VAR_MAINMENU_KEY) != 0 && _currentRoom != 0));
}
@@ -1368,11 +1396,31 @@ void ScummEngine::saveOrLoad(Serializer *s) {
}
void ScummEngine_v0::saveOrLoad(Serializer *s) {
+ ScummEngine_v2::saveOrLoad(s);
+
+ const SaveLoadEntry v0Entrys[] = {
+ MKLINE(ScummEngine_v0, _currentMode, sleByte, VER(78)),
+ MKLINE(ScummEngine_v0, _currentLights, sleByte, VER(78)),
+ MKEND()
+ };
+ s->saveLoadEntries(this, v0Entrys);
+}
+
+
+void ScummEngine_v2::saveOrLoad(Serializer *s) {
ScummEngine::saveOrLoad(s);
- // TODO: Save additional variables
- // _currentMode
- // _currentLights
+ const SaveLoadEntry v2Entrys[] = {
+ MKLINE(ScummEngine_v2, _inventoryOffset, sleUint16, VER(79)),
+ MKEND()
+ };
+ s->saveLoadEntries(this, v2Entrys);
+
+ // In old saves we didn't store _inventoryOffset -> reset it to
+ // a sane default when loading one of those.
+ if (s->getVersion() < 79 && s->isLoading()) {
+ _inventoryOffset = 0;
+ }
}
void ScummEngine_v5::saveOrLoad(Serializer *s) {
diff --git a/engines/scumm/saveload.h b/engines/scumm/saveload.h
index 49bfe39b21..4f6adc5570 100644
--- a/engines/scumm/saveload.h
+++ b/engines/scumm/saveload.h
@@ -50,7 +50,7 @@ namespace Scumm {
* only saves/loads those which are valid for the version of the savegame
* which is being loaded/saved currently.
*/
-#define CURRENT_VER 78
+#define CURRENT_VER 79
/**
* An auxillary macro, used to specify savegame versions. We use this instead
diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp
index 4d9447bee5..2c3fe09db2 100644
--- a/engines/scumm/script.cpp
+++ b/engines/scumm/script.cpp
@@ -23,10 +23,9 @@
*
*/
-
-
#include "common/config-manager.h"
#include "common/util.h"
+#include "common/system.h"
#include "scumm/actor.h"
#include "scumm/object.h"
@@ -133,6 +132,8 @@ void ScummEngine::runObjectScript(int object, int entry, bool freezeResistant, b
initializeLocals(slot, vars);
+ // V0 Ensure we don't try and access objects via index inside the script
+ _v0ObjectIndex = false;
runScriptNested(slot);
}
@@ -786,92 +787,65 @@ void ScummEngine::runInventoryScript(int i) {
}
void ScummEngine::inventoryScriptIndy3Mac() {
- VerbSlot *vs;
- int args[24];
- int j, slot;
+ int slot;
- memset(args, 0, sizeof(args));
+ // VAR(67) controls the scroll offset of the inventory in Indy3 for Macintosh.
+ // The inventory consists of two columns with three items visible in each,
+ // so a maximum of six items are visible at once.
- if (VAR(67) < 0) {
- VAR(67) = 0;
- }
- args[5] = getInventoryCount(VAR(VAR_EGO));
- if (args[5] <= 6) {
+ // The scroll offset must be non-negative and if there are six or less items
+ // in the inventory, the inventory is fixed in the top position.
+ const int invCount = getInventoryCount(VAR(VAR_EGO));
+ if (VAR(67) < 0 || invCount <= 6) {
VAR(67) = 0;
}
- if (args[5] >= 6) {
- args[5] -= 6;
- }
- args[6] = 0;
- if (VAR(67) >= args[5]) {
- VAR(67) = args[5];
- args[4] = args[5];
- args[5] /= 2;
- args[5] *= 2;
- args[4] -= args[5];
- if (args[4]) {
+
+ // If there are more than six items in the inventory, clamp the scroll position
+ // to be at most invCount-6, rounded up to the next even integer.
+ bool scrolledToBottom = false;
+ if (invCount > 6 && VAR(67) >= invCount - 6) {
+ VAR(67) = invCount - 6;
+ // Odd number of inventory items? -> increment VAR(67) to make it even
+ if (invCount & 1) {
VAR(67)++;
}
- args[6]++;
- }
- args[2] = 1;
- for (j = 1; j < 7; j++) {
- args[1] = (VAR(67) + args[2]);
- args[3] = findInventory(VAR(VAR_EGO),args[1]);
- VAR(82 + args[2]) = args[3];
- args[2]++;
+ scrolledToBottom = true;
}
- byte tmp[6];
-
- tmp[0] = 0xFF;
- tmp[1] = 0x06;
- tmp[3] = 0x00;
- tmp[4] = 0x00;
-
- for (j = 0; j < 6; j++) {
- tmp[2] = 0x53 + j;
-
- slot = getVerbSlot(101 + j, 0);
- vs = &_verbs[slot];
+ // Now update var 83 till 89 to contain the inventory IDs of the
+ // corresponding inventory slots.
+ // Also setup fake verbs for the inventory
+ byte tmp[6] = { 0xFF, 0x06, 0x52, 0x00, 0x00, 0x00 };
+ for (int j = 1; j < 7; j++) {
+ int tmpA = (VAR(67) + j);
+ int tmpB = findInventory(VAR(VAR_EGO), tmpA);
+ VAR(82 + j) = tmpB;
+
+ // Setup fake verb
+ tmp[2] = 0x52 + j;
+ slot = getVerbSlot(100 + j, 0);
loadPtrToResource(rtVerb, slot, tmp);
+
+ VerbSlot *vs = &_verbs[slot];
vs->type = kTextVerbType;
vs->imgindex = 0;
vs->curmode = 1;
drawVerb(slot, 0);
}
- args[5] = getInventoryCount(VAR(VAR_EGO));
- if (args[5] > 6) {
- slot = getVerbSlot(107, 0);
- if (VAR(67)) {
- vs = &_verbs[slot];
- vs->curmode = 1;
- } else {
- vs = &_verbs[slot];
- vs->curmode = 0;
- }
- drawVerb(slot, 0);
- slot = getVerbSlot(108, 0);
- if (!args[6]) {
- vs = &_verbs[slot];
- vs->curmode = 1;
- } else {
- vs = &_verbs[slot];
- vs->curmode = 0;
- }
- drawVerb(slot, 0);
- } else {
- slot = getVerbSlot(107, 0);
- vs = &_verbs[slot];
- vs->curmode = 0;
- drawVerb(slot, 0);
- slot = getVerbSlot(108, 0);
- vs = &_verbs[slot];
- vs->curmode = 0;
- drawVerb(slot, 0);
- }
+ // Enable up arrow if there are more than six items and we are not already
+ // scrolled all the way up.
+ slot = getVerbSlot(107, 0);
+ _verbs[slot].curmode = (invCount > 6 && VAR(67)) ? 1 : 0;
+ drawVerb(slot, 0);
+
+ // Enable down arrow if there are more than six items and we are not already
+ // scrolled all the way down.
+ slot = getVerbSlot(108, 0);
+ _verbs[slot].curmode = (invCount > 6 && !scrolledToBottom) ? 1 : 0;
+ drawVerb(slot, 0);
+ // Redraw!
verbMouseOver(0);
}
@@ -1204,7 +1178,7 @@ void ScummEngine::runInputScript(int clickArea, int val, int mode) {
args[4] = VAR(VAR_VIRT_MOUSE_Y);
}
- // Macintosh verison of indy3ega used different interface, so adjust values.
+ // Macintosh version of indy3ega used different interface, so adjust values.
if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh) {
if (clickArea == kVerbClickArea && (val >= 101 && val <= 108)) {
if (val == 107) {
@@ -1216,10 +1190,16 @@ void ScummEngine::runInputScript(int clickArea, int val, int mode) {
inventoryScriptIndy3Mac();
return;
} else {
- args[0] = 3;
- args[1] = VAR(83 + (val - 101));
+ args[0] = kInventoryClickArea;
+ args[1] = VAR(82 + (val - 100));
}
}
+
+ // Clicks are handled differently in Indy3 mac: param 2 of the
+ // input script is set to 0 for normal clicks, and to 1 for double clicks.
+ uint32 time = _system->getMillis();
+ args[2] = (time < _lastInputScriptTime + 500); // 500 ms double click delay
+ _lastInputScriptTime = time;
}
if (verbScript)
diff --git a/engines/scumm/script_v0.cpp b/engines/scumm/script_v0.cpp
index 1b8368d636..873f2fa281 100644
--- a/engines/scumm/script_v0.cpp
+++ b/engines/scumm/script_v0.cpp
@@ -410,41 +410,43 @@ void ScummEngine_v0::decodeParseString() {
actorTalk(buffer);
}
-void ScummEngine_v0::drawSentence() {
- Common::Rect sentenceline;
+void ScummEngine_v0::drawSentenceWord(int object, bool usePrep, bool objInInventory) {
const byte *temp;
int sentencePrep = 0;
+
+ // If object not in inventory, we except an index
+ if (!objInInventory)
+ _v0ObjectIndex = true;
+ else
+ _v0ObjectInInventory = true;
- if (!(_userState & 32))
- return;
+ temp = getObjOrActorName(object);
- if (getResourceAddress(rtVerb, _activeVerb)) {
- strcpy(_sentenceBuf, (char*)getResourceAddress(rtVerb, _activeVerb));
- } else {
- return;
+ _v0ObjectInInventory = false;
+ _v0ObjectIndex = false;
+
+ // Append the 'object-name'
+ if (temp) {
+ strcat(_sentenceBuf, " ");
+ strcat(_sentenceBuf, (const char*)temp);
}
- if (_activeObject > 0) {
- temp = getObjOrActorName(_activeObject);
- if (temp) {
- strcat(_sentenceBuf, " ");
- strcat(_sentenceBuf, (const char*)temp);
- }
+ // Append the modifier? (With / On / To / In)
+ if (!usePrep)
+ return;
- if (_verbs[_activeVerb].prep == 0xFF) {
- byte *ptr = getOBCDFromObject(_activeObject);
- assert(ptr);
- sentencePrep = (*(ptr + 11) >> 5);
- } else {
- sentencePrep = _verbs[_activeVerb].prep;
- }
+ if (_verbs[_activeVerb].prep == 0xFF) {
+ _v0ObjectInInventory = objInInventory;
+ sentencePrep = verbPrep(object);
+ } else {
+ sentencePrep = _verbs[_activeVerb].prep;
}
if (sentencePrep > 0 && sentencePrep <= 4) {
// The prepositions, like the fonts, were hard code in the engine. Thus
// we have to do that, too, and provde localized versions for all the
// languages MM/Zak are available in.
- const char *prepositions[][5] = {
+ static const char *prepositions[][5] = {
{ " ", " in", " with", " on", " to" }, // English
{ " ", " mit", " mit", " mit", " zu" }, // German
{ " ", " dans", " avec", " sur", " <" }, // French
@@ -471,13 +473,65 @@ void ScummEngine_v0::drawSentence() {
strcat(_sentenceBuf, prepositions[lang][sentencePrep]);
}
+}
+
+void ScummEngine_v0::drawSentence() {
+ Common::Rect sentenceline;
+ bool inventoryFirst = false;
+
+ if (!(_userState & 32))
+ return;
+
+ // Current Verb, Walk/Use
+ if (getResourceAddress(rtVerb, _activeVerb)) {
+ strcpy(_sentenceBuf, (char*)getResourceAddress(rtVerb, _activeVerb));
+ } else {
+ return;
+ }
- if (_activeInventory > 0) {
- temp = getObjOrActorName(_activeInventory);
- if (temp) {
- strcat(_sentenceBuf, " ");
- strcat(_sentenceBuf, (const char*)temp);
+ // If using inventory first, draw it first
+ if (_activeInvExecute && _activeInventory) {
+ drawSentenceWord(_activeInventory, true, true);
+ } else {
+ // Not using inventory, use selected object
+ if (_activeObject)
+ drawSentenceWord(_activeObjectIndex, true, false);
+ else
+ inventoryFirst = true;
+ }
+
+
+ // Draw the inventory?
+ if (_activeInventory > 0 && _activeObject2 == 0) {
+ // Only if inventory isnt first (it will already be drawn by now)
+ if (!_activeInvExecute) {
+ drawSentenceWord(_activeInventory, inventoryFirst, true);
+ } else {
+ // Draw the active object, which could be inventory based, or room based
+ if (_activeObject && !_activeObjectIndex) {
+ drawSentenceWord(_activeObject, inventoryFirst, true);
+ } else // Room based
+ drawSentenceWord(_activeObjectIndex, inventoryFirst, false);
}
+
+ // Draw the 2nd active object
+ } else if (_activeObject2) {
+
+ // 2nd Object is in inventory
+ if (_activeObject2Inv) {
+ _v0ObjectInInventory = true;
+ drawSentenceWord(_activeObject2, inventoryFirst, true);
+ } else {
+ drawSentenceWord(_activeObject2Index, inventoryFirst, false);
+ }
+ }
+
+ // Draw the active actor
+ if (_activeActor) {
+ Actor *a = derefActor(_activeActor, "");
+
+ strcat(_sentenceBuf, " ");
+ strcat(_sentenceBuf, (const char*)a->getActorName());
}
_string[2].charset = 1;
@@ -664,9 +718,22 @@ void ScummEngine_v0::o_animateActor() {
int act = getVarOrDirectByte(PARAM_1);
int anim = getVarOrDirectByte(PARAM_2);
int unk = fetchScriptByte();
+
debug(0,"o_animateActor: unk %d", unk);
- Actor *a = derefActor(act, "o_animateActor");
+ ActorC64 *a = (ActorC64*) derefActor(act, "o_animateActor");
+
+ // 0x6993
+ if (anim == 0xFE) {
+ a->_speaking = 0x80; // Enabled, but not switching
+ return;
+ }
+ // 0x69A3
+ if (anim == 0xFD) {
+ a->_speaking = 0x00;
+ return;
+ }
+
a->animateActor(anim);
}
@@ -713,9 +780,9 @@ void ScummEngine_v0::o_pickupObject() {
if (getObjectIndex(obj) == -1)
return;
- if (whereIsObject(obj) == WIO_INVENTORY) /* Don't take an */
+ if (whereIsObjectInventory(_activeObject2) == WIO_INVENTORY) /* Don't take an */
return; /* object twice */
-
+
addObjectToInventory(obj, _roomResource);
markObjectRectAsDirty(obj);
putOwner(obj, VAR(VAR_EGO));
@@ -738,8 +805,13 @@ void ScummEngine_v0::o_setActorBitVar() {
byte act = getVarOrDirectByte(PARAM_1);
byte mask = getVarOrDirectByte(PARAM_2);
byte mod = getVarOrDirectByte(PARAM_3);
+
+ // 0x63ED
+ if (act >= _numActors)
+ return;
ActorC64 *a = (ActorC64 *)derefActor(act, "o_setActorBitVar");
+
if (mod)
a->_miscflags |= mask;
else
@@ -900,10 +972,25 @@ void ScummEngine_v0::o_setOwnerOf() {
setOwnerOf(obj, owner);
}
-void ScummEngine_v0::resetSentence() {
- _activeInventory = 0;
- _activeObject = 0;
+void ScummEngine_v0::resetSentence(bool walking) {
_activeVerb = 13;
+
+ if (!walking) {
+ _activeInventory = 0;
+ _activeObject = 0;
+ _activeObject2 = 0;
+ _activeObjectIndex = 0;
+ _activeObject2Index = 0;
+ }
+
+ _verbExecuting = false;
+ _verbPickup = false;
+
+ _activeActor = 0;
+ _activeInvExecute = false;
+ _activeObject2Inv = false;
+ _activeObjectObtained = false;
+ _activeObject2Obtained = false;
}
} // End of namespace Scumm
diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp
index 1ce38fd800..f83e7f2879 100644
--- a/engines/scumm/script_v5.cpp
+++ b/engines/scumm/script_v5.cpp
@@ -1138,9 +1138,19 @@ void ScummEngine_v5::o5_ifClassOfIs() {
while ((_opcode = fetchScriptByte()) != 0xFF) {
cls = getVarOrDirectWord(PARAM_1);
- b = getClass(obj, cls);
- if (((cls & 0x80) && !b) || (!(cls & 0x80) && b))
- cond = false;
+
+ // WORKAROUND bug #1668393: Due to a script bug, the wrong opcode is used
+ // to check the state of the inside door (object 465) of the Hostel on Mars,
+ // when opening the Hostel door from the outside.
+ if (_game.id == GID_ZAK && _game.platform == Common::kPlatformFMTowns &&
+ vm.slot[_currentScript].number == 205 && _currentRoom == 185 &&
+ obj == 465 && cls == 0) {
+ cond = (getState(obj) == 0);
+ } else {
+ b = getClass(obj, cls);
+ if (((cls & 0x80) && !b) || (!(cls & 0x80) && b))
+ cond = false;
+ }
}
jumpRelative(cond);
}
@@ -1775,7 +1785,7 @@ void ScummEngine_v5::o5_roomOps() {
while ((chr = fetchScriptByte()))
filename += chr;
- if (filename.hasPrefix("iq-") || filename.hasPrefix("IQ-") || filename.hasSuffix("-iq")) {
+ if (filename.hasPrefix("iq-") || filename.hasPrefix("IQ-") || filename.hasSuffix("-iq") || filename.hasSuffix("-IQ")) {
filename = _targetName + ".iq";
} else {
error("SO_LOAD_STRING: Unsupported filename %s", filename.c_str());
diff --git a/engines/scumm/script_v6.cpp b/engines/scumm/script_v6.cpp
index dcd60352c7..6df3c0c494 100644
--- a/engines/scumm/script_v6.cpp
+++ b/engines/scumm/script_v6.cpp
@@ -701,6 +701,14 @@ void ScummEngine_v6::o6_ifNot() {
void ScummEngine_v6::o6_jump() {
int offset = fetchScriptWordSigned();
+
+ // WORKAROUND bug #2826144: Talking to the guard at the bigfoot party, after
+ // he's let you inside, will cause the game to hang, if you end the conversation.
+ // This is a script bug, due to a missing jump in one segment of the script.
+ if (_game.id == GID_SAMNMAX && vm.slot[_currentScript].number == 101 && readVar(0x8000 + 97) == 1 && offset == 1) {
+ offset = -18;
+ }
+
_scriptPointer += offset;
}
diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h
index 5bb0e097dc..cb7f906f13 100644
--- a/engines/scumm/scumm-md5.h
+++ b/engines/scumm/scumm-md5.h
@@ -1,5 +1,5 @@
/*
- This file was generated by the md5table tool on Sat Jul 11 01:37:44 2009
+ This file was generated by the md5table tool on Thu Jul 30 10:23:41 2009
DO NOT EDIT MANUALLY!
*/
@@ -17,20 +17,20 @@ static const MD5Table md5table[] = {
{ "008e76ec3ae58d0add637ea7aa299a2c", "freddi3", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "02cae0e7ff8504f73618391873d5781a", "freddi3", "HE 98.5", "", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "0305e850382b812fec6e5998ef88a966", "pajama", "", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "035deab53b47bc43abc763560d0f8d4b", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "035deab53b47bc43abc763560d0f8d4b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "037385a953789190298494d92b89b3d0", "catalog", "HE 72", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "03d3b18ee3fd68114e2a687c871e38d5", "freddi4", "HE 99", "Mini Game", -1, Common::EN_USA, Common::kPlatformWindows },
- { "0425954a9db5c340861672892c3e678d", "samnmax", "CD", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
+ { "0425954a9db5c340861672892c3e678d", "samnmax", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "04401d747f1a2c1c4b388daff71ed378", "ft", "", "", 535405461, Common::DE_DEU, Common::kPlatformMacintosh },
{ "04687cdf7f975a89d2474929f7b80946", "indy3", "FM-TOWNS", "", 7552, Common::EN_ANY, Common::kPlatformFMTowns },
{ "0557df19f046a84c2fdc63507c6616cb", "farm", "HE 72", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "055ffe4f47753e47594ac67823220c54", "puttrace", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "057c9b456dedcc4d71b991a3072a20b3", "monkey", "SEGA", "", 9465, Common::JA_JPN, Common::kPlatformSegaCD },
{ "0650e8ab1432564607cd651c0fa3f344", "loom", "PC-Engine", "", -1, Common::EN_ANY, Common::kPlatformPCEngine },
- { "06b187468113f9ae5a400b148a847fac", "atlantis", "", "Floppy", 12075, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "06b187468113f9ae5a400b148a847fac", "atlantis", "Floppy", "Floppy", 12075, Common::EN_ANY, Common::kPlatformMacintosh },
{ "06c3cf4f31daad8b1cd93153491db9e6", "pajama3", "", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "07433205acdca3bc553d0e731588b35f", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
- { "07a1eefd8ca95d77310311446c0f53d0", "brstorm", "", "Demo", 5433, Common::EN_ANY, Common::kPlatformUnknown },
+ { "07a1eefd8ca95d77310311446c0f53d0", "brstorm", "", "", 5433, Common::EN_ANY, Common::kPlatformUnknown },
{ "07b810e37be7489263f7bc7627d4765d", "freddi4", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "084ed0fa98a6d1e9368d67fe9cfbd417", "freddi", "HE 71", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "0855496dde35356b1a9691e22ba84cdc", "freddi", "HE 73", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -49,14 +49,14 @@ static const MD5Table md5table[] = {
{ "0c45eb4baff0c12c3d9dfa889c8070ab", "pajama3", "", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "0cccfa5223099a60e76cfcca57a1a141", "freddi3", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "0d1b69471605201ef2fa9cec1f5f02d2", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformPC },
- { "0e4c5d54a0ad4b26132e78b5ea76642a", "samnmax", "", "Demo", 6485, Common::EN_ANY, Common::kPlatformPC },
+ { "0e4c5d54a0ad4b26132e78b5ea76642a", "samnmax", "Floppy", "Demo", 6485, Common::EN_ANY, Common::kPlatformPC },
{ "0e96ab45a4eb72acc1b46813976589fd", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "0e9b01430e31d9fcd94071d433bbc6bf", "loom", "No Adlib", "EGA", -1, Common::FR_FRA, Common::kPlatformAtariST },
{ "0f5935bd5e88ba6f09e558d64459746d", "thinker1", "", "Demo", 30919, Common::EN_USA, Common::kPlatformWindows },
- { "0f6f2e716ba896a44e5059bba1de7ca9", "samnmax", "CD", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
+ { "0f6f2e716ba896a44e5059bba1de7ca9", "samnmax", "", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "0f9c7a76657f0840b8f7ccb5bffeb9f4", "indy3", "No Adlib", "EGA", -1, Common::FR_FRA, Common::kPlatformAtariST },
{ "0f9d3317910ac7a9f449243118884ada", "puttzoo", "", "", 42070, Common::DE_DEU, Common::kPlatformWindows },
- { "0fb73eddfcf584c02ba097984df131ba", "samnmax", "CD", "CD", 9080, Common::DE_DEU, Common::kPlatformUnknown },
+ { "0fb73eddfcf584c02ba097984df131ba", "samnmax", "", "CD", 9080, Common::DE_DEU, Common::kPlatformUnknown },
{ "1005456bfe351c1b679e1ff2dc2849e9", "puttzoo", "", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
{ "100b4c8403ad6a83d4bf7dbf83e44dc4", "spyfox", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "10d8e66cd11049ce64815ebb9fd76eb3", "spyozon", "", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
@@ -72,22 +72,22 @@ static const MD5Table md5table[] = {
{ "15240c59d3681ed53f714f8d925cb2d6", "maniac", "V2", "V2", -1, Common::ES_ESP, Common::kPlatformAtariST },
{ "157367c3c21e0d03a0cba44361b4cf65", "indy3", "No Adlib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
{ "15e03ffbfeddb9c2aebc13dcb2a4a8f4", "monkey", "VGA", "VGA", 8357, Common::EN_ANY, Common::kPlatformPC },
- { "15f588e887e857e8c56fe6ade4956168", "atlantis", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformAmiga },
+ { "15f588e887e857e8c56fe6ade4956168", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "16542a7342a918bfe4ba512007d36c47", "FreddisFunShop", "HE 99L", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "166553538ff320c69edafeee29525419", "samnmax", "CD", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "166553538ff320c69edafeee29525419", "samnmax", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "16effd200aa6b8abe9c569c3e578814d", "freddi4", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "179879b6e35c1ead0d93aab26db0951b", "fbear", "HE 70", "", 13381, Common::EN_ANY, Common::kPlatformWindows },
{ "17b5d5e6af4ae89d62631641d66d5a05", "indy3", "VGA", "VGA", -1, Common::IT_ITA, Common::kPlatformPC },
{ "17f7296f63c78642724f057fd8e736a7", "maniac", "NES", "extracted", -1, Common::EN_GRB, Common::kPlatformNES },
- { "17fa250eb72dae2dad511ba79c0b6b0a", "tentacle", "CD", "Demo", -1, Common::FR_FRA, Common::kPlatformPC },
- { "182344899c2e2998fca0bebcd82aa81a", "atlantis", "CD", "CD", 12035, Common::EN_ANY, Common::kPlatformPC },
+ { "17fa250eb72dae2dad511ba79c0b6b0a", "tentacle", "", "Demo", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "182344899c2e2998fca0bebcd82aa81a", "atlantis", "", "CD", 12035, Common::EN_ANY, Common::kPlatformPC },
{ "183d7464902d40d00800e8ee1f04117c", "maniac", "V2", "V2", 1988, Common::DE_DEU, Common::kPlatformPC },
{ "1875b90fade138c9253a8e967007031a", "indy3", "VGA", "VGA", 6295, Common::EN_ANY, Common::kPlatformPC },
{ "187d315f6b5168f68680dfe8c3d76a3e", "loom", "EGA", "EGA", -1, Common::HB_ISR, Common::kPlatformPC },
{ "1900e501a52fbf55bde6e4196f6d2aa6", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "19263586f749a560c1adf8b3393a9593", "socks", "HE 85", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "19bf6938a94698296bcb0c99c31c91a7", "spyfox2", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
- { "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "CD", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "1a6e5ae2777a6a33f06ffc0226210934", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "1c792d28376d45e145cb916bca0400a2", "spyfox2", "", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "1c7e7db2cfab1ad62746ab680a634204", "maniac", "NES", "extracted", -1, Common::FR_FRA, Common::kPlatformNES },
{ "1ca86e2cf9aaa2068738a1e5ba477e60", "zak", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
@@ -97,12 +97,12 @@ static const MD5Table md5table[] = {
{ "1dd7aa088e09f96d06818aa9a9deabe0", "indy3", "No Adlib", "EGA", 5361, Common::EN_ANY, Common::kPlatformMacintosh },
{ "1ed22f601f8b3695804a6583cc3083f1", "puttrace", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "1f2e62b5a9c50589fc342285a6bb3a27", "freddi", "HE 73", "", -1, Common::HB_ISR, Common::kPlatformWindows },
- { "1fbebd7b2b692df5297870447a80cfed", "atlantis", "", "Floppy", 12030, Common::DE_DEU, Common::kPlatformPC },
+ { "1fbebd7b2b692df5297870447a80cfed", "atlantis", "Floppy", "Floppy", 12030, Common::DE_DEU, Common::kPlatformPC },
{ "1ff5997c78fbd0a841a75ef15a05d9d5", "BluesBirthday", "", "Red", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "2012f854d83d9cc6f73b2b544cd8bbf8", "water", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "20176076d708bf14407bcc9bdcd7a418", "pajama3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "204453e33456c4faa26e276229fe5b76", "spyfox2", "", "Demo", 14689, Common::DE_DEU, Common::kPlatformWindows },
- { "20da6fce37805423966aaa8f3c2426aa", "atlantis", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformAmiga },
+ { "20da6fce37805423966aaa8f3c2426aa", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "2108d83dcf09f8adb4bc524669c8cf51", "PuttTime", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "21a6592322f92550f144f68a8a4e685e", "dig", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "21abe302e1b1e2b66d6f5c12e241ebfd", "freddicove", "unenc", "Unencrypted", -1, Common::RU_RUS, Common::kPlatformWindows },
@@ -114,14 +114,14 @@ static const MD5Table md5table[] = {
{ "22f4ea88a09da12df9308ba30bcb7d0f", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformPC },
{ "23394c8d29cc63c61313959431a12476", "spyfox", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "257f8c14d8c584f7ddd601bcb00920c7", "maniac", "NES", "", 262144, Common::DE_DEU, Common::kPlatformNES },
- { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "", "Floppy", 7932, Common::EN_ANY, Common::kPlatformPC },
+ { "2723fea3dae0cb47768c424b145ae0e7", "tentacle", "Floppy", "Floppy", 7932, Common::EN_ANY, Common::kPlatformPC },
{ "27b2ef1653089fe5b897d9cc89ce784f", "balloon", "HE 80", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "27b3a4224ad63d5b04627595c1c1a025", "zak", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformAmiga },
- { "28d24a33448fab6795850bc9f159a4a2", "atlantis", "CD", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns },
+ { "28d24a33448fab6795850bc9f159a4a2", "atlantis", "", "Demo", 11170, Common::JA_JPN, Common::kPlatformFMTowns },
{ "28ef68ee3ed76d7e2ee8ee13c15fbd5b", "loom", "EGA", "EGA", 5748, Common::EN_ANY, Common::kPlatformPC },
{ "28f07458f1b6c24e118a1ea056827701", "lost", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "2a208ffbcd0e83e86f4356e6f64aa6e1", "loom", "EGA", "EGA", -1, Common::ES_ESP, Common::kPlatformPC },
- { "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", "CD", "Demo", 2439158, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "2a41b53cf1a90b6e6f26c10cc6041084", "tentacle", "", "Demo", 2439158, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2a446817ffcabfef8716e0c456ecaf81", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "2a8658dbd13d84d1bce64a71a35995eb", "pajama2", "HE 99", "Demo", -1, Common::HB_ISR, Common::kPlatformWindows },
{ "2c04aacffb8428f30ccf4f734fbe3adc", "activity", "", "", -1, Common::EN_ANY, Common::kPlatformPC },
@@ -130,7 +130,7 @@ static const MD5Table md5table[] = {
{ "2d388339d6050d8ccaa757b64633954e", "zak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "2d4536a56e01da4b02eb021e7770afa2", "zak", "FM-TOWNS", "", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "2d4acbdcfd8e374c9da8c2e7303a5cd0", "BluesBirthday", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "2d9d46f23cb07bbc90b8ad464d3e4ff8", "atlantis", "CD", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "2d9d46f23cb07bbc90b8ad464d3e4ff8", "atlantis", "", "CD", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "2e85f7aa054930c692a5b1bed1dfc295", "football2002", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "2e8a1f76ea33bc5e04347646feee173d", "pajama3", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "2fe369ad70f52a8cf7ad6077ee64f81a", "loom", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformAmiga },
@@ -157,18 +157,18 @@ static const MD5Table md5table[] = {
{ "3824e60cdf639d22f6df92a03dc4b131", "fbear", "HE 61", "", 7732, Common::EN_ANY, Common::kPlatformPC },
{ "387a544b8b10b26912d8413bab63a853", "monkey2", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "3905799e081b80a61d4460b7b733c206", "maniac", "NES", "", 262144, Common::EN_USA, Common::kPlatformNES },
- { "3938ee1aa4433fca9d9308c9891172b1", "zak", "FM-TOWNS", "Demo", -1, Common::EN_ANY, Common::kPlatformFMTowns },
+ { "3938ee1aa4433fca9d9308c9891172b1", "zak", "FM-TOWNS", "Demo", 7520, Common::EN_ANY, Common::kPlatformFMTowns },
{ "399b217b0c8d65d0398076da486363a9", "indy3", "VGA", "VGA", 6295, Common::DE_DEU, Common::kPlatformPC },
{ "39cb9dec16fa16f38d79acd80effb059", "loom", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "39cb9dec16fa16f38d79acd80effb059", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "39fd6db10d0222d817025c4d3346e3b4", "farm", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "3a03dab514e4038df192d8a8de469788", "atlantis", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformAmiga },
+ { "3a03dab514e4038df192d8a8de469788", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "3a0c35f3c147b98a2bdf8d400cfc4ab5", "indy3", "FM-TOWNS", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
{ "3a3e592b074f595489f7f11e150c398d", "puttzoo", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformWindows },
- { "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "CD", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
+ { "3a5d13675e9a23aedac0bac7730f0ac1", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "3a5ec90d556d4920976c5578bfbfaf79", "maniac", "NES", "extracted", -1, Common::DE_DEU, Common::kPlatformNES },
{ "3af61c5edf8e15b43dbafd285b2e9777", "puttcircus", "", "Demo", -1, Common::HB_ISR, Common::kPlatformWindows },
- { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "3b301b7892f883ce42ab4be6a274fea6", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
{ "3b832f4a90740bf22e9b8ed42ca0128c", "freddi4", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "3cce1913a3bc586b51a75c3892ff18dd", "indy3", "VGA", "VGA", -1, Common::RU_RUS, Common::kPlatformPC },
{ "3d219e7546039543307b55a91282bf18", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatformPC },
@@ -176,7 +176,7 @@ static const MD5Table md5table[] = {
{ "3df6ead57930488bc61e6e41901d0e97", "fbear", "HE 61", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "3e48298920fab9b7aec5a971e1bd1fab", "pajama3", "", "Demo", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "40564ec47da48a67787d1f9bd043902a", "maniac", "V2 Demo", "V2 Demo", 1988, Common::EN_ANY, Common::kPlatformPC },
- { "4167a92a1d46baa4f4127d918d561f88", "tentacle", "CD", "CD", 7932, Common::EN_ANY, Common::kPlatformUnknown },
+ { "4167a92a1d46baa4f4127d918d561f88", "tentacle", "", "CD", 7932, Common::EN_ANY, Common::kPlatformUnknown },
{ "41958e24d03181ff9a381a66d048a581", "ft", "", "", -1, Common::PT_BRA, Common::kPlatformUnknown },
{ "425205754fa749f4f0b0dd9d09fa45fd", "football", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "430bc518017b6fac046f58bab6baad5d", "monkey2", "", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
@@ -195,13 +195,13 @@ static const MD5Table md5table[] = {
{ "4aa93cb30e485b728504ba3a693f12bf", "pajama", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "4af4a6b248103c1fe9edef619677f540", "puttmoon", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "4ba37f835be11a59d969f90f272f575b", "water", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "4ba7fb331296c283e73d8f5b2096e551", "samnmax", "CD", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
+ { "4ba7fb331296c283e73d8f5b2096e551", "samnmax", "", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
{ "4bedb49943df95a9c900a5a82ccbe9de", "ft", "", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "4bfa4a43684bcb437f7fb47f457a0aa5", "socks", "HE 99", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "4c4820518e16e1a0e3616a3b021a04f3", "catalog", "HE CUP", "Preview", 10927456, Common::DE_DEU, Common::kPlatformUnknown },
{ "4cb9c3618f71668f8e4346c8f323fa82", "monkey2", "", "", 10700, Common::EN_ANY, Common::kPlatformMacintosh },
{ "4ce2d5b355964bbcb5e5ce73236ef868", "freddicove", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows },
- { "4d34042713958b971cb139fba4658586", "atlantis", "CD", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
+ { "4d34042713958b971cb139fba4658586", "atlantis", "", "", -1, Common::JA_JPN, Common::kPlatformFMTowns },
{ "4dbff3787aedcd96b0b325f2d92d7ad9", "maze", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "4dc780f1bc587a193ce8a97652791438", "loom", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "4e5867848ee61bc30d157e2c94eee9b4", "PuttTime", "HE 90", "Demo", 18394, Common::EN_USA, Common::kPlatformUnknown },
@@ -209,15 +209,15 @@ static const MD5Table md5table[] = {
{ "4f04b321a95d4315ce6d65f8e1dd0368", "maze", "HE 80", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "4f138ac6f9b2ac5a41bc68b2c3296064", "freddi4", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "4f1d6f8b38343dba405472538b5037ed", "fbear", "HE 61", "", 7717, Common::EN_ANY, Common::kPlatformPC },
- { "4f267a901719623de7dde83e47d5b474", "atlantis", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
+ { "4f267a901719623de7dde83e47d5b474", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "4f580a021eee026f3b4589e17d130d78", "freddi4", "", "", -1, Common::UNK_LANG, Common::kPlatformUnknown },
{ "4fa6870d9bc8c313b65d54b1da5a1891", "pajama", "", "", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "4fbbe9f64b8bc547503a379a301183ce", "tentacle", "CD", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
+ { "4fbbe9f64b8bc547503a379a301183ce", "tentacle", "", "CD", -1, Common::IT_ITA, Common::kPlatformUnknown },
{ "4fe6a2e8df3c4536b278fdd2fbcb181e", "pajama3", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "5057fb0e99e5aa29df1836329232f101", "freddi2", "HE 80", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
{ "507bb360688dc4180fdf0d7597352a69", "freddi", "HE 73", "", 26402, Common::SE_SWE, Common::kPlatformWindows },
{ "50b831f11b8c4b83784cf81f4dcc69ea", "spyfox", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
- { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
+ { "50fcdc982a25063b78ad46bf389b8e8d", "tentacle", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
{ "51305e929e330e24a75a0351c8f9975e", "freddi2", "HE 99", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "513f91a9dbe8d5490b39e56a3ac5bbdf", "pajama2", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "5262a27afcaee04e5c4900220bd463e7", "PuttsFunShop", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -229,10 +229,10 @@ static const MD5Table md5table[] = {
{ "55e4cc866ff9046824e1c638ba2b8c7f", "ft", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "566165a7338fa11029e7c14d94fa70d0", "freddi", "HE 73", "Demo", 9800, Common::EN_ANY, Common::kPlatformWindows },
{ "5719fc8a13b4638b78d9d8d12f091f94", "puttrace", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
- { "5798972220cd458be2626d54c80f71d7", "atlantis", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga },
+ { "5798972220cd458be2626d54c80f71d7", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformAmiga },
{ "57a17febe2183f521250e55d55b83e60", "PuttTime", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "57a5cfec9ef231a007043cc1917e8988", "freddi", "HE 100", "", -1, Common::EN_ANY, Common::kPlatformWii },
- { "57b0d89af79befe1cabce3bece869e7f", "tentacle", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "57b0d89af79befe1cabce3bece869e7f", "tentacle", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
{ "58436e634f4fae1d9973591c2ffa1fcb", "spyfox", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "589601b676c98b1c0c987bc031ab68b3", "chase", "HE 95", "", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "58fdf4c7ad13540a734e18f8584cad89", "puttzoo", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
@@ -289,9 +289,9 @@ static const MD5Table md5table[] = {
{ "6bf70eee5de3d24d2403e0dd3d267e8a", "spyfox", "", "", 49221, Common::UNK_LANG, Common::kPlatformWindows },
{ "6c2bff0e327f2962e809c2e1a82d7309", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
{ "6d1baa1065ac5f7b210be8ebe4235e49", "freddi", "HE 73", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
- { "6dead580b0ff14d5f7b33b4219f04159", "samnmax", "CD", "Demo", 16556335, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "6dead580b0ff14d5f7b33b4219f04159", "samnmax", "", "Demo", 16556335, Common::EN_ANY, Common::kPlatformMacintosh },
{ "6df20c50c1ab19799de9be7ae7716881", "fbear", "HE 61", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "CD", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown },
+ { "6e959d65358eedf9b68b81e304b97fa4", "tentacle", "", "CD", 7932, Common::DE_DEU, Common::kPlatformUnknown },
{ "6ea966b4d660c870b9ee790d1fbfc535", "monkey2", "", "", -1, Common::ES_ESP, Common::kPlatformAmiga },
{ "6f0be328c64d689bb606d22a389e1b0f", "loom", "No Adlib", "EGA", 5748, Common::EN_ANY, Common::kPlatformMacintosh },
{ "6f6ef668c608c7f534fea6e6d3878dde", "indy3", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformPC },
@@ -332,7 +332,7 @@ static const MD5Table md5table[] = {
{ "7ddeaf52c8b9a50551ce0aa2ac811d07", "BluesABCTime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "7e151c17adf624f1966c8fc5827c95e9", "puttputt", "HE 61", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "7ea2da67ebabea4ac20cee9f4f9d2934", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "CD", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown },
+ { "7edd665bbede7ea8b7233f8e650be6f8", "samnmax", "", "CD", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7f45ddd6dbfbf8f80c0c0efea4c295bc", "maniac", "V1", "V1", 1972, Common::EN_ANY, Common::kPlatformPC },
{ "7f945525abcd48015adf1632637a44a1", "pajama", "", "Demo", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "7fc6cdb46b4c9d384c52327f4bca6416", "football", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -354,12 +354,12 @@ static const MD5Table md5table[] = {
{ "87df3e0074624040407764b7c5e710b9", "pajama", "", "Demo", 18354, Common::NL_NLD, Common::kPlatformWindows },
{ "87f6e8037b7cc996e13474b491a7a98e", "maniac", "V2", "V2", -1, Common::IT_ITA, Common::kPlatformPC },
{ "8801fb4a1200b347f7a38523339526dd", "jungle", "", "", -1, Common::EN_ANY, Common::kPlatformWindows },
- { "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", "CD", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
+ { "883af4b0af4f77a92f1dcf1d0a283140", "tentacle", "", "CD", -1, Common::ES_ESP, Common::kPlatformUnknown },
{ "898ce8eb1234a955ef75e87141902bb3", "freddi3", "", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "898eaa21f79cf8d4f08db856244689ff", "pajama", "HE 99", "Updated", 66505, Common::EN_ANY, Common::kPlatformWindows },
{ "89cfc425566003ff74b7dc7b3e6fd469", "indy3", "EGA", "EGA", -1, Common::FR_FRA, Common::kPlatformPC },
{ "8a484262363a8e18be87112454f1456b", "pjgames", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "8aa05d3cdb0e795436043f0546af2da2", "tentacle", "CD", "CD?", -1, Common::FR_FRA, Common::kPlatformUnknown },
+ { "8aa05d3cdb0e795436043f0546af2da2", "tentacle", "", "CD?", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "8aed489aba45d2b9fb8a04079c9c6e6a", "baseball", "HE CUP", "Preview", 12876596, Common::UNK_LANG, Common::kPlatformUnknown },
{ "8afb3cf9f95abf208358e984f0c9e738", "funpack", "", "", -1, Common::EN_ANY, Common::kPlatform3DO },
{ "8bdb0bf87b5e303dd35693afb9351215", "ft", "", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
@@ -367,11 +367,11 @@ static const MD5Table md5table[] = {
{ "8de13897f0121c79d29a2377159f9ad0", "socks", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "8e3241ddd6c8dadf64305e8740d45e13", "balloon", "HE 100", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "8e4ee4db46954bfe2912e259a16fad82", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformPC },
- { "8e9417564f33790815445b2136efa667", "atlantis", "CD", "CD", 11915, Common::JA_JPN, Common::kPlatformMacintosh },
+ { "8e9417564f33790815445b2136efa667", "atlantis", "", "CD", 11915, Common::JA_JPN, Common::kPlatformMacintosh },
{ "8e9830a6f2702be5b22c8fa0a6aaf977", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformMacintosh },
{ "8eb84cee9b429314c7f0bdcf560723eb", "monkey", "FM-TOWNS", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
{ "8ee63cafb1fe9d62aa0d5a23117e70e7", "freddi2", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
+ { "8f3758ff98c9c5d78e5d635222cad026", "atlantis", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
{ "8fec68383202d38c0d25e9e3b757c5df", "comi", "Demo", "Demo", 18041, Common::UNK_LANG, Common::kPlatformWindows },
{ "8ffd618a776a4c0d8922bb28b09f8ce8", "airport", "", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "90a329d8ad5b7ce0690429e98cfbb32f", "funpack", "", "", -1, Common::HB_ISR, Common::kPlatformPC },
@@ -381,10 +381,10 @@ static const MD5Table md5table[] = {
{ "91469353f7be1b122fa88d23480a1320", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformAmiga },
{ "91d5db93187fab54d823f73bd6441cb6", "maniac", "NES", "extracted", -1, Common::EN_USA, Common::kPlatformNES },
{ "927a764615c7fcdd72f591355e089d8c", "monkey", "No Adlib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
- { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "92b078d9d6d9d751da9c26b8b3075779", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "92e7727e67f5cd979d8a1070e4eb8cb3", "puttzoo", "HE 98.5", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "92fc0073a4cf259ff36070ecb8628ba8", "thinkerk", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "94aaedbb8f26d71ed3ad6dd34490e29e", "tentacle", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "94db6519da85b8d08c976d8e9a858ea7", "baseball", "HE CUP", "Preview", 10044774, Common::UNK_LANG, Common::kPlatformUnknown },
{ "95818b178d473c989ac753574e8892aa", "readtime", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "95b3806e043be08668c54c3ffe98650f", "BluesABCTime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -392,13 +392,13 @@ static const MD5Table md5table[] = {
{ "9708cf716ed8bcc9ff3fcfc69413b746", "puttputt", "HE 61", "", -1, Common::EN_ANY, Common::kPlatformPC },
{ "9781422e4288dbc090720e4563168ba7", "puttzoo", "", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "981e1e1891f2be7e25a01f50ae55a5af", "puttrace", "HE 98", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "98744fe66ff730e8c2b3b1f58803ab0b", "atlantis", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "99128b6a5bdd9831d9682fb8b5cbf8d4", "BluesBirthday", "", "Yellow", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "99a3699f80b8f776efae592b44b9b991", "maniac", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC },
- { "99b6f822b0b2612415407865438697d6", "atlantis", "CD", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "99b6f822b0b2612415407865438697d6", "atlantis", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "9b7452b5cd6d3ffb2b2f5118010af84f", "ft", "Demo", "Demo", 116463537, Common::EN_ANY, Common::kPlatformMacintosh },
{ "9bc548e179cdb0767009401c094d0895", "maniac", "V2", "V2", -1, Common::DE_DEU, Common::kPlatformAmiga },
- { "9bd2a8f72613e715c199246dd511e10f", "atlantis", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "9bd2a8f72613e715c199246dd511e10f", "atlantis", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
{ "9bda5fee51d2fda5253d02c642016bf4", "spyfox", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "9c0ee9c252785e9fca0143e42ac4b256", "freddi2", "HE 99", "Updated", -1, Common::DE_DEU, Common::kPlatformWindows },
{ "9c0fee288ad564a7d25ec3e841810d79", "indy3", "EGA", "EGA", -1, Common::EN_ANY, Common::kPlatformAmiga },
@@ -420,7 +420,7 @@ static const MD5Table md5table[] = {
{ "a2386da005672cbd5136f4f27a626c5f", "farm", "", "", 87061, Common::NL_NLD, Common::kPlatformWindows },
{ "a28135a7ade38cc0208b04507c46efd1", "spyfox", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "a2bb6aa0537402c1b3c2ea899ccef64b", "lost", "HE 99", "Demo", 15540, Common::EN_ANY, Common::kPlatformWindows },
- { "a3036878840720fbefa41e6965fa4a0a", "samnmax", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "a3036878840720fbefa41e6965fa4a0a", "samnmax", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
{ "a336134914eaab4892d35625aa15ad1d", "freddi4", "HE 99", "", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "a525c1753c1db5011c00417da37887ef", "PuttTime", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "a561d2e2413cc1c71d5a1bf87bf493ea", "lost", "HE 100", "Updated", -1, Common::EN_USA, Common::kPlatformUnknown },
@@ -441,16 +441,16 @@ static const MD5Table md5table[] = {
{ "aaa587701cde7e74692c68c1024b85eb", "puttrace", "HE 99", "Demo", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "aaa7f36a253f277dd29dd1c051b0e4b9", "indy3", "No Adlib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
{ "ab0693e9324cfcf498fdcbb12acf8bb4", "puttcircus", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "ac1642b6edfb8521ca03760126f1c250", "tentacle", "CD", "Demo", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "ac1642b6edfb8521ca03760126f1c250", "tentacle", "", "Demo", -1, Common::DE_DEU, Common::kPlatformPC },
{ "ac62d50e39492ee3738b4e83a5ac780f", "freddi2", "HE 80", "", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "acad97ab1c6fc2a5b2d98abf6db4a190", "tentacle", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformUnknown },
+ { "ae94f110a14ce71fc515d5b648827a8f", "tentacle", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
{ "aefa244ea034b7cd2041f0a44be7d9ba", "pajama3", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "af2bd1a43b50b55915d87994e093203d", "freddi", "HE 99", "Updated", 34829, Common::DE_DEU, Common::kPlatformWindows },
{ "b100abf7ff83146df50db78dbd5e9cfa", "freddicove", "HE 100", "", -1, Common::FR_FRA, Common::kPlatformUnknown },
{ "b23f7cd7c304d7dff08e92a96120d5b4", "zak", "V1", "V1", -1, Common::EN_ANY, Common::kPlatformPC },
{ "b250d0f9cc83f80ced56fe11a4fb057c", "maniac", "V2", "V2", 1988, Common::EN_ANY, Common::kPlatformPC },
- { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
+ { "b289a2a8cbedbf45786e0b4ad2f510f1", "samnmax", "Floppy", "Floppy", -1, Common::IT_ITA, Common::kPlatformPC },
{ "b47be81e39a9710f6f595f7b527b60f8", "puttrace", "HE 99", "", -1, Common::EN_GRB, Common::kPlatformWindows },
{ "b5298a5c15ffbe8b381d51ea4e26d35c", "freddi4", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "b597e0403cc0002f69170e6caba7edd9", "indy3", "EGA", "EGA Demo", 5361, Common::EN_ANY, Common::kPlatformPC },
@@ -479,7 +479,7 @@ static const MD5Table md5table[] = {
{ "c24c490373aeb48fbd54caa8e7ae376d", "loom", "No Adlib", "EGA", -1, Common::DE_DEU, Common::kPlatformAtariST },
{ "c25755b08a8d0d47695e05f1e2111bfc", "freddi4", "", "Demo", -1, Common::EN_USA, Common::kPlatformUnknown },
{ "c30ef068add4277104243c31ce46c12b", "monkey2", "", "", -1, Common::FR_FRA, Common::kPlatformAmiga },
- { "c3196c5349e53e387aaff1533d95e53a", "samnmax", "", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "c3196c5349e53e387aaff1533d95e53a", "samnmax", "Floppy", "Demo", -1, Common::EN_ANY, Common::kPlatformPC },
{ "c3b22fa4654bb580b20325ebf4174841", "puttzoo", "", "", -1, Common::NL_NLD, Common::kPlatformWindows },
{ "c3df37df9d3b481b45f75283a9907c47", "loom", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformPC },
{ "c4787c3e8b5e2dfda90850ee800af00f", "zak", "V2", "V2", -1, Common::FR_FRA, Common::kPlatformPC },
@@ -487,22 +487,22 @@ static const MD5Table md5table[] = {
{ "c4ffae9fac495475d6bc3343ccc8faf9", "Soccer2004", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "c5cc7cba02a2fbd539c4439e775b0536", "puttzoo", "HE 99", "Updated", 43470, Common::DE_DEU, Common::kPlatformWindows },
{ "c5d10e190d4b4d59114b824f2fdbd00e", "loom", "FM-TOWNS", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
- { "c63ee46143ba65f9ce14cf539ca51bd7", "atlantis", "", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
+ { "c63ee46143ba65f9ce14cf539ca51bd7", "atlantis", "Floppy", "Floppy", -1, Common::EN_ANY, Common::kPlatformPC },
{ "c666a998af90d81db447eccba9f72c8d", "monkey", "No Adlib", "EGA", -1, Common::EN_ANY, Common::kPlatformAtariST },
{ "c6907d44f1166941d982864cd42cdc89", "pajama2", "HE 99", "", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "c782fbbe74a987c3df8ac73cd3e289ed", "freddi", "HE 73", "", -1, Common::SE_SWE, Common::kPlatformMacintosh },
{ "c7890e038806df2bb5c0c8c6f1986ea2", "monkey", "VGA", "VGA", -1, Common::EN_ANY, Common::kPlatformPC },
- { "c7be10f775404fd9785a8b92a06d240c", "atlantis", "CD", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
+ { "c7be10f775404fd9785a8b92a06d240c", "atlantis", "", "", -1, Common::EN_ANY, Common::kPlatformFMTowns },
{ "c7c492a107ec520d7a7943037d0ca54a", "freddi", "HE 71", "Demo", -1, Common::NL_NLD, Common::kPlatformWindows },
- { "c83079157ec765a28de445aec9768d60", "tentacle", "CD", "Demo", 7477, Common::EN_ANY, Common::kPlatformUnknown },
+ { "c83079157ec765a28de445aec9768d60", "tentacle", "", "Demo", 7477, Common::EN_ANY, Common::kPlatformUnknown },
{ "c8575e0b973ff1723aba6cd92c642db2", "puttrace", "HE 99", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "c8aac5e3e701874e2fa4117896f9e1b1", "freddi", "HE 73", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "c8c5baadcbfc8d0372ed4335abace8a7", "pajama3", "", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "c9717ee6059f1e43b768b464493d2fba", "fbpack", "", "", -1, Common::JA_JPN, Common::kPlatform3DO },
{ "cb1559e8405d17a5a278a6b5ad9338d1", "freddi3", "", "Demo", 22718, Common::EN_ANY, Common::kPlatformUnknown },
- { "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", "CD", "CD", 282467632, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "cc04a076779379524ed4d9c5ee3c6fb1", "tentacle", "", "CD", 282467632, Common::EN_ANY, Common::kPlatformMacintosh },
{ "cc0c4111449054f1692bb3c0c5e04629", "BluesBirthday", "", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "", "Demo", 7485, Common::DE_DEU, Common::kPlatformPC },
+ { "cc8ba2b0df2f9c450bcf055fe2711979", "samnmax", "Floppy", "Demo", 7485, Common::DE_DEU, Common::kPlatformPC },
{ "cd424f143a141bc59226ad83a6e40f51", "maze", "HE 98.5", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "cd46c9f122272d02bbf79332ff521898", "loom", "EGA", "EGA", 5748, Common::RU_RUS, Common::kPlatformPC },
{ "cd9c05e755d7bf8e9b9590ad1ebe273e", "dig", "Demo", "Demo", 45156007, Common::EN_ANY, Common::kPlatformMacintosh },
@@ -525,7 +525,7 @@ static const MD5Table md5table[] = {
{ "d220d154aafbfa12bd6f3ab1b2dae420", "puttzoo", "", "Demo", -1, Common::DE_DEU, Common::kPlatformMacintosh },
{ "d2cc8e31bce61e6cf2951249e10638fe", "basketball", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "d37c55388294b66e53e7ced3af88fa68", "freddi2", "HE 100", "Updated Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
- { "d43352a805d78b5f4936c6d7779bf575", "samnmax", "CD", "CD", -1, Common::RU_RUS, Common::kPlatformPC },
+ { "d43352a805d78b5f4936c6d7779bf575", "samnmax", "", "CD", -1, Common::RU_RUS, Common::kPlatformPC },
{ "d4aac997e2f4e15341f0bfbf905419bd", "PuttTime", "HE 99", "", 62698, Common::EN_GRB, Common::kPlatformWindows },
{ "d4b8ee426b1afd3e53bc0cf020418cf6", "dog", "HE 99", "", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "d4cccb5af88f3e77f370896e9ba8c5f9", "freddi", "HE 71", "", -1, Common::UNK_LANG, Common::kPlatformWindows },
@@ -535,7 +535,7 @@ static const MD5Table md5table[] = {
{ "d62047a6729349ab36f7ee065bf26509", "dig", "", "", -1, Common::RU_RUS, Common::kPlatformUnknown },
{ "d62d248c3df6ec177405e2cb23d923b2", "indy3", "EGA", "EGA", -1, Common::IT_ITA, Common::kPlatformPC },
{ "d6334a5a9b61afe18c368540fdf522ca", "airport", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
- { "d6dd0646404768a63e963891a96daadd", "atlantis", "", "Floppy", 12035, Common::EN_ANY, Common::kPlatformMacintosh },
+ { "d6dd0646404768a63e963891a96daadd", "atlantis", "Floppy", "Floppy", 12035, Common::EN_ANY, Common::kPlatformMacintosh },
{ "d73c851b942af44deb9b6d5f416a0972", "freddi3", "HE 99", "Demo", -1, Common::HB_ISR, Common::kPlatformWindows },
{ "d74122362a77ec24525fdd50297dfd82", "freddi4", "", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
{ "d7ab7cd6105546016e6a0d46fb36b964", "pajama", "HE 100", "Demo", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -543,8 +543,8 @@ static const MD5Table md5table[] = {
{ "d831f7c048574dd9d5d85db2a1468099", "maniac", "C64", "", -1, Common::EN_ANY, Common::kPlatformC64 },
{ "d8323015ecb8b10bf53474f6e6b0ae33", "dig", "", "", 16304, Common::UNK_LANG, Common::kPlatformUnknown },
{ "d8d07efcb88f396bee0b402b10c3b1c9", "maniac", "NES", "", 262144, Common::EN_GRB, Common::kPlatformNES },
- { "d917f311a448e3cc7239c31bddb00dd2", "samnmax", "CD", "CD", 9080, Common::EN_ANY, Common::kPlatformUnknown },
- { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "CD", "Demo", 6478, Common::EN_ANY, Common::kPlatformPC },
+ { "d917f311a448e3cc7239c31bddb00dd2", "samnmax", "", "CD", 9080, Common::EN_ANY, Common::kPlatformUnknown },
+ { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "", "Demo", 6478, Common::EN_ANY, Common::kPlatformPC },
{ "da09e666fc8f5b78d7b0ac65d1a3b56e", "monkey2", "", "", 11135, Common::EN_ANY, Common::kPlatformFMTowns },
{ "da6269b18fcb08189c0aa9c95533cce2", "monkey", "CD", "CD", 8955, Common::IT_ITA, Common::kPlatformPC },
{ "da669b20271b85182e9c17a2a37ea02e", "monkey2", "", "", -1, Common::DE_DEU, Common::kPlatformAmiga },
@@ -566,7 +566,7 @@ static const MD5Table md5table[] = {
{ "e361a7058ed8e8ebb462663c0a3ae8d6", "puttputt", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC },
{ "e41de1c2a15abbcdbf9977e2d7e8a340", "freddi2", "HE 100", "Updated", -1, Common::RU_RUS, Common::kPlatformWindows },
{ "e44ea295a3f8fe4f41983080dab1e9ce", "freddi", "HE 90", "Updated", -1, Common::FR_FRA, Common::kPlatformMacintosh },
- { "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
+ { "e534d29afb3c6e0ee9dc3d53c5956714", "atlantis", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformAmiga },
{ "e5563c8358443c4352fcddf7402a5e0a", "pajama2", "HE 98.5", "", -1, Common::FR_FRA, Common::kPlatformWindows },
{ "e5c112140ad6574997de033a8e2a2964", "readtime", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "e62056ba675ad65d8854ab3c5ad4b3c0", "spyfox2", "", "Mini Game", -1, Common::EN_ANY, Common::kPlatformWindows },
@@ -584,11 +584,11 @@ static const MD5Table md5table[] = {
{ "ecc4340c2b801f5af8da4e00c0e432d9", "puttcircus", "", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
{ "ed2b074bc3166087a747acb2a3c6abb0", "freddi3", "HE 98.5", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "ed361270102e355afe5236954216aba2", "lost", "", "", -1, Common::EN_USA, Common::kPlatformUnknown },
- { "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "CD", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
- { "edfdb24a499d92c59f824c52987c0eec", "atlantis", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "ede149fda3edfc1dbd7347e0737cb583", "tentacle", "", "CD", -1, Common::FR_FRA, Common::kPlatformMacintosh },
+ { "edfdb24a499d92c59f824c52987c0eec", "atlantis", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "ee41f6afbc5b26fa475754b56fe92048", "puttputt", "HE 61", "", 8032, Common::JA_JPN, Common::kPlatform3DO },
{ "ee785fe2569bc9965526e774f7ab86f1", "spyfox", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
- { "ef347474f3c7be3b29584eaa133cca05", "samnmax", "", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
+ { "ef347474f3c7be3b29584eaa133cca05", "samnmax", "Floppy", "Floppy", -1, Common::FR_FRA, Common::kPlatformPC },
{ "ef71a322b6530ac45b1a070f7c0795f7", "moonbase", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformWindows },
{ "ef74d9071d4e564b037cb44bd6774de7", "fbear", "HE 61", "", -1, Common::HB_ISR, Common::kPlatformPC },
{ "efe0a04a703e765ebebe92b6c8aa6b86", "baseball2003", "", "", -1, Common::EN_ANY, Common::kPlatformUnknown },
@@ -598,11 +598,11 @@ static const MD5Table md5table[] = {
{ "f163cf53f7850e43fb482471e5c52e1a", "maniac", "NES", "", 262144, Common::ES_ESP, Common::kPlatformNES },
{ "f1b0e0d587b85052de5534a3847e68fe", "water", "HE 99", "Updated", -1, Common::EN_ANY, Common::kPlatformUnknown },
{ "f237bf8a5ef9af78b2a6a4f3901da341", "pajama", "", "Demo", 18354, Common::EN_ANY, Common::kPlatformUnknown },
- { "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
+ { "f27b1ba0eadaf2a6617b2b58192d1dbf", "samnmax", "Floppy", "Floppy", -1, Common::DE_DEU, Common::kPlatformPC },
{ "f3d55aea441e260e9e9c7d2a187097e0", "puttzoo", "", "Demo", 14337, Common::EN_ANY, Common::kPlatformWindows },
{ "f40a7f495f59188ca57a9d1d50301bb6", "puttputt", "Demo", "Demo", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "f5228b0cc1c19e6ea8268ba2eeb61f60", "freddi", "HE 73", "Demo", -1, Common::FR_FRA, Common::kPlatformWindows },
- { "f73883f13b5a302749a5bad31d909780", "tentacle", "CD", "CD", -1, Common::DE_DEU, Common::kPlatformMacintosh },
+ { "f73883f13b5a302749a5bad31d909780", "tentacle", "", "CD", -1, Common::DE_DEU, Common::kPlatformMacintosh },
{ "f7711f9264d4d43c2a1518ec7c10a607", "pajama3", "", "", 79382, Common::EN_USA, Common::kPlatformUnknown },
{ "f79e60c17cca601e411f1f75e8ee9b5a", "spyfox2", "", "", 51286, Common::UNK_LANG, Common::kPlatformUnknown },
{ "f8be685007a8b425ba2a455da732f59f", "pajama2", "HE 99", "", -1, Common::FR_FRA, Common::kPlatformMacintosh },
@@ -613,7 +613,7 @@ static const MD5Table md5table[] = {
{ "fbb697d89d2beca87360a145f467bdae", "PuttTime", "HE 90", "Demo", -1, Common::DE_DEU, Common::kPlatformUnknown },
{ "fbbbb38a81fc9d6a61d509278390a290", "farm", "", "", -1, Common::EN_ANY, Common::kPlatformMacintosh },
{ "fbdd947d21e8f5bac6d6f7a316af1c5a", "spyfox", "", "Demo", 15693, Common::EN_ANY, Common::kPlatformUnknown },
- { "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", "", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
+ { "fc53ce0e5f6562b1c1e1b4b8203acafb", "samnmax", "Floppy", "Floppy", -1, Common::ES_ESP, Common::kPlatformPC },
{ "fc6b6148e80d67939d9a18697c0f626a", "monkey", "EGA", "EGA", -1, Common::DE_DEU, Common::kPlatformPC },
{ "fc8d197a22146e74766e9cb0cfcaf1da", "freddi2", "HE 80", "Demo", 27298, Common::EN_ANY, Common::kPlatformUnknown },
{ "fcb78ebecab2757264c590890c319cc5", "PuttTime", "HE 85", "", -1, Common::NL_NLD, Common::kPlatformUnknown },
diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp
index 70b2d7285e..1beda85456 100644
--- a/engines/scumm/scumm.cpp
+++ b/engines/scumm/scumm.cpp
@@ -26,6 +26,7 @@
#include "common/config-manager.h"
#include "common/md5.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "gui/message.h"
@@ -136,6 +137,8 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
// Init all vars
+ _v0ObjectIndex = false;
+ _v0ObjectInInventory = false;
_imuse = NULL;
_imuseDigital = NULL;
_musicEngine = NULL;
@@ -183,6 +186,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_mouseAndKeyboardStat = 0;
_leftBtnPressed = 0;
_rightBtnPressed = 0;
+ _lastInputScriptTime = 0;
_bootParam = 0;
_dumpScripts = false;
_debugMode = 0;
@@ -216,7 +220,6 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
_roomResource = 0;
OF_OWNER_ROOM = 0;
_verbMouseOver = 0;
- _inventoryOffset = 0;
_classData = NULL;
_actorToPrintStrFor = 0;
_sentenceNum = 0;
@@ -542,7 +545,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr)
for (int i = 0; i < ARRAYSIZE(debugChannels); ++i)
Common::addDebugChannel(debugChannels[i].flag, debugChannels[i].channel, debugChannels[i].desc);
- syst->getEventManager()->registerRandomSource(_rnd, "scumm");
+ g_eventRec.registerRandomSource(_rnd, "scumm");
}
@@ -651,6 +654,8 @@ ScummEngine_v3old::ScummEngine_v3old(OSystem *syst, const DetectorResult &dr)
ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
: ScummEngine_v3old(syst, dr) {
+ _inventoryOffset = 0;
+
_activeInventory = 0;
_activeObject = 0;
_activeVerb = 0;
@@ -669,7 +674,17 @@ ScummEngine_v2::ScummEngine_v2(OSystem *syst, const DetectorResult &dr)
ScummEngine_v0::ScummEngine_v0(OSystem *syst, const DetectorResult &dr)
: ScummEngine_v2(syst, dr) {
+ _verbExecuting = false;
+ _verbPickup = false;
_currentMode = 0;
+
+ _activeObject2 = 0;
+ _activeObjectIndex = 0;
+ _activeObject2Index = 0;
+ _activeInvExecute = false;
+ _activeObject2Inv = false;
+ _activeObjectObtained = false;
+ _activeObject2Obtained = false;
}
ScummEngine_v6::ScummEngine_v6(OSystem *syst, const DetectorResult &dr)
@@ -1907,7 +1922,7 @@ void ScummEngine::scummLoop(int delta) {
}
// Trigger autosave if necessary.
- if (!_saveLoadFlag && shouldPerformAutoSave(_lastSaveTime)) {
+ if (!_saveLoadFlag && shouldPerformAutoSave(_lastSaveTime) && canSaveGameStateCurrently()) {
_saveLoadSlot = 0;
sprintf(_saveLoadName, "Autosave %d", _saveLoadSlot);
_saveLoadFlag = 1;
diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h
index 6491f8a171..0e2031eea5 100644
--- a/engines/scumm/scumm.h
+++ b/engines/scumm/scumm.h
@@ -565,6 +565,9 @@ protected:
int32 *_scummVars;
byte *_bitVars;
+ bool _v0ObjectIndex; // V0 Use object index, instead of object number
+ bool _v0ObjectInInventory; // V0 Use object number from inventory
+
/* Global resource tables */
int _numVariables, _numBitVariables, _numLocalObjects;
int _numGlobalObjects, _numArray, _numVerbs, _numFlObject;
@@ -612,6 +615,12 @@ protected:
uint16 _mouseAndKeyboardStat;
byte _leftBtnPressed, _rightBtnPressed;
+ /**
+ * Last time runInputScript was run (measured in terms of OSystem::getMillis()).
+ * This is currently only used for Indy3 mac to detect "double clicks".
+ */
+ uint32 _lastInputScriptTime;
+
/** The bootparam, to be passed to the script 1, the bootscript. */
int _bootParam;
@@ -858,12 +867,14 @@ protected:
int getObjNewDir(int obj);
int getObjectIndex(int object) const;
int getObjectImageCount(int object);
+ int whereIsObjectInventory(int object);
int whereIsObject(int object) const;
int findObject(int x, int y);
void findObjectInRoom(FindObjectInRoom *fo, byte findWhat, uint object, uint room);
public:
int getObjectOrActorXY(int object, int &x, int &y); // Used in actor.cpp, hence public
protected:
+ int getDist(int x, int y, int x2, int y2);
int getObjActToObjActDist(int a, int b); // Not sure how to handle
const byte *getObjOrActorName(int obj); // these three..
void setObjectName(int obj);
@@ -884,7 +895,6 @@ protected:
protected:
/* Should be in Verb class */
uint16 _verbMouseOver;
- int _inventoryOffset;
int8 _userPut;
uint16 _userState;
diff --git a/engines/scumm/scumm_v0.h b/engines/scumm/scumm_v0.h
index ccca5df0d3..19260b6429 100644
--- a/engines/scumm/scumm_v0.h
+++ b/engines/scumm/scumm_v0.h
@@ -35,7 +35,20 @@ namespace Scumm {
*/
class ScummEngine_v0 : public ScummEngine_v2 {
protected:
- int _currentMode;
+ byte _currentMode;
+ bool _verbExecuting; // is a verb executing
+ bool _verbPickup; // are we picking up an object during a verb execute
+
+ int _activeActor; // Actor Number
+ int _activeObject2; // 2nd Object Number
+
+ bool _activeInvExecute; // is activeInventory first to be executed
+ bool _activeObject2Inv; // is activeobject2 in the inventory
+ bool _activeObjectObtained; // collected _activeobject?
+ bool _activeObject2Obtained; // collected _activeObject2?
+
+ int _activeObjectIndex;
+ int _activeObject2Index;
public:
ScummEngine_v0(OSystem *syst, const DetectorResult &dr);
@@ -53,12 +66,25 @@ protected:
virtual void processInput();
+ virtual void runObject(int obj, int entry);
virtual void saveOrLoad(Serializer *s);
+ // V0 MM Verb commands
+ int verbPrep(int object);
+ bool verbMove(int object, int objectIndex, bool invObject);
+ bool verbMoveToActor(int actor);
+ bool verbObtain(int object, int objIndex);
+ bool verbExecutes(int object, bool inventory = false);
+ bool verbExec();
+
+ int findObjectIndex(int x, int y);
+
virtual void checkExecVerbs();
virtual void handleMouseOver(bool updateInventory);
void resetVerbs();
void setNewKidVerbs();
+
+ void drawSentenceWord(int object, bool usePrep, bool objInInventory);
void drawSentence();
void switchActor(int slot);
@@ -68,7 +94,7 @@ protected:
virtual int getActiveObject();
- virtual void resetSentence();
+ virtual void resetSentence(bool walking = false);
/* Version C64 script opcodes */
void o_stopCurrentScript();
diff --git a/engines/scumm/scumm_v2.h b/engines/scumm/scumm_v2.h
index 338b5f6167..ee9591bc45 100644
--- a/engines/scumm/scumm_v2.h
+++ b/engines/scumm/scumm_v2.h
@@ -45,6 +45,7 @@ protected:
int8 _mouseOverBoxV2;
char _sentenceBuf[256];
+ uint16 _inventoryOffset;
int _activeInventory;
int _activeObject;
@@ -66,6 +67,8 @@ protected:
virtual void resetScummVars();
virtual void decodeParseString();
+ virtual void saveOrLoad(Serializer *s);
+
virtual void processKeyboard(Common::KeyState lastKeyHit);
virtual void readIndexFile();
@@ -100,7 +103,7 @@ protected:
virtual void setBuiltinCursor(int index);
- void runObject(int obj, int entry);
+ virtual void runObject(int obj, int entry);
/* Version 2 script opcodes */
void o2_actorFromPos();
diff --git a/engines/scumm/sound.cpp b/engines/scumm/sound.cpp
index ad48029bd2..2362427779 100644
--- a/engines/scumm/sound.cpp
+++ b/engines/scumm/sound.cpp
@@ -23,6 +23,9 @@
*
*/
+#include "common/config-manager.h"
+#include "common/timer.h"
+#include "common/util.h"
#include "scumm/actor.h"
#include "scumm/file.h"
@@ -32,10 +35,6 @@
#include "scumm/sound.h"
#include "scumm/util.h"
-#include "common/config-manager.h"
-#include "common/timer.h"
-#include "common/util.h"
-
#include "sound/adpcm.h"
#include "sound/audiocd.h"
#include "sound/flac.h"
@@ -46,8 +45,6 @@
#include "sound/vorbis.h"
#include "sound/wave.h"
-
-
namespace Scumm {
struct MP3OffsetTable { /* Compressed Sound (.SO3) */
@@ -420,17 +417,16 @@ void Sound::playSound(int soundID) {
sound = (char *)malloc(size);
int vol = ptr[24] * 4;
int loopStart = 0, loopEnd = 0;
-#if 0 // Disabling this until after 0.11.0
int loopcount = ptr[27];
if (loopcount > 1) {
// TODO: We can only loop once, or infinitely many times, but
// have no support for a finite number of repetitions.
- // This is
+ // So far, I have seen only 1 and 255 (for infinite repetitions),
+ // so maybe this is not really a problem.
loopStart = READ_BE_UINT16(ptr + 10) - READ_BE_UINT16(ptr + 8);
loopEnd = READ_BE_UINT16(ptr + 14);
flags |= Audio::Mixer::FLAG_LOOP;
}
-#endif
memcpy(sound, ptr + READ_BE_UINT16(ptr + 8), size);
_mixer->playRaw(Audio::Mixer::kSFXSoundType, NULL, sound, size, rate,
diff --git a/engines/scumm/string.cpp b/engines/scumm/string.cpp
index f00f4ff33b..e99bea87de 100644
--- a/engines/scumm/string.cpp
+++ b/engines/scumm/string.cpp
@@ -995,6 +995,11 @@ void ScummEngine::drawString(int a, const byte *msg) {
}
_string[a].xpos = _charset->_str.right;
+
+ if (_game.heversion >= 60) {
+ _string[a]._default.xpos = _string[a].xpos;
+ _string[a]._default.ypos = _string[a].ypos;
+ }
}
int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize) {
diff --git a/engines/scumm/vars.cpp b/engines/scumm/vars.cpp
index 22487b43a3..98e088365e 100644
--- a/engines/scumm/vars.cpp
+++ b/engines/scumm/vars.cpp
@@ -538,9 +538,7 @@ void ScummEngine_v8::setupScummVars() {
#endif
void ScummEngine_v0::resetScummVars() {
- _activeInventory = 0;
- _activeObject = 0;
- _activeVerb = 13;
+ resetSentence();
VAR(VAR_EGO) = 3;
diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp
index 81b28ce563..1ab9d72a58 100644
--- a/engines/scumm/verbs.cpp
+++ b/engines/scumm/verbs.cpp
@@ -155,6 +155,7 @@ void ScummEngine_v0::switchActor(int slot) {
VAR(VAR_EGO) = VAR(97 + slot);
actorFollowCamera(VAR(VAR_EGO));
resetVerbs();
+ resetSentence(false);
setUserState(247);
}
@@ -376,14 +377,8 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) {
if (object > 0) {
if (_game.version == 0) {
- if (_activeInventory != object) {
- _activeInventory = object;
- } else if (_activeVerb != 3 && _activeVerb != 13) {
- if (_activeObject)
- runObject(_activeObject, _activeVerb);
- else
- runObject(_activeInventory, _activeVerb);
- }
+ _activeInventory = object;
+
} else {
runInputScript(kInventoryClickArea, object, 0);
}
@@ -425,7 +420,9 @@ void ScummEngine_v2::redrawV2Inventory() {
_string[1].right = _mouseOverBoxesV2[i].rect.right - 1;
_string[1].color = _mouseOverBoxesV2[i].color;
+ _v0ObjectInInventory = true;
const byte *tmp = getObjOrActorName(obj);
+ _v0ObjectInInventory = false;
assert(tmp);
// Prevent inventory entries from overflowing by truncating the text
@@ -629,14 +626,14 @@ void ScummEngine_v2::checkExecVerbs() {
if (vs->verbid && vs->saveid == 0 && vs->curmode == 1) {
if (_mouseAndKeyboardStat == vs->key) {
// Trigger verb as if the user clicked it
- runInputScript(1, vs->verbid, 1);
+ runInputScript(kVerbClickArea, vs->verbid, 1);
return;
}
}
}
// Generic keyboard input
- runInputScript(4, _mouseAndKeyboardStat, 1);
+ runInputScript(kKeyClickArea, _mouseAndKeyboardStat, 1);
} else if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
VirtScreen *zone = findVirtScreen(_mouse.y);
const byte code = _mouseAndKeyboardStat & MBS_LEFT_CLICK ? 1 : 2;
@@ -649,7 +646,7 @@ void ScummEngine_v2::checkExecVerbs() {
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
// Click into V2 sentence line
- runInputScript(5, 0, 0);
+ runInputScript(kSentenceClickArea, 0, 0);
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + inventoryArea) {
// Click into V2 inventory
checkV2Inventory(_mouse.x, _mouse.y);
@@ -657,7 +654,7 @@ void ScummEngine_v2::checkExecVerbs() {
over = findVerbAtPos(_mouse.x, _mouse.y);
if (over != 0) {
// Verb was clicked
- runInputScript(1, _verbs[over].verbid, code);
+ runInputScript(kVerbClickArea, _verbs[over].verbid, code);
} else {
// Scene was clicked
runInputScript((zone->number == kMainVirtScreen) ? kSceneClickArea : kVerbClickArea, 0, code);
@@ -666,6 +663,25 @@ void ScummEngine_v2::checkExecVerbs() {
}
}
+void ScummEngine_v0::runObject(int obj, int entry) {
+ int prev = _v0ObjectInInventory;
+
+ if (getVerbEntrypoint(obj, entry) != 0) {
+ _v0ObjectInInventory = prev;
+ runObjectScript(obj, entry, false, false, NULL);
+ } else if (entry != 13 && entry != 15) {
+ if (_activeVerb != 3) {
+ VAR(9) = entry;
+ runScript(3, 0, 0, 0);
+
+ // For some reasons, certain objects don't have a "give" script
+ } else if (VAR(5) > 0 && VAR(5) < 8) {
+ if (_activeInventory)
+ setOwnerOf(_activeInventory, VAR(5));
+ }
+ }
+}
+
void ScummEngine_v2::runObject(int obj, int entry) {
if (getVerbEntrypoint(obj, entry) != 0) {
runObjectScript(obj, entry, false, false, NULL);
@@ -679,10 +695,293 @@ void ScummEngine_v2::runObject(int obj, int entry) {
_activeVerb = 13;
}
+bool ScummEngine_v0::verbMoveToActor(int actor) {
+ Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+ Actor *a2 =derefActor(actor, "checkExecVerbs");
+
+ if (!a->_moving) {
+ int dist = getDist(a->getRealPos().x, a->getRealPos().y, a2->getRealPos().x, a2->getRealPos().y);
+ if (dist > 5)
+ a->startWalkActor(a2->getRealPos().x, a2->getRealPos().y, 1);
+ else
+ return false;
+
+ return true;
+ }
+
+ return true;
+}
+
+bool ScummEngine_v0::verbMove(int object, int objectIndex, bool invObject) {
+ int x, y, dir;
+ Actor *a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+
+ if (_currentMode != 3 && _currentMode != 2)
+ return false;
+
+ if (a->_moving)
+ return true;
+
+ _v0ObjectIndex = true;
+ getObjectXYPos(objectIndex, x, y, dir);
+ _v0ObjectIndex = false;
+ // Detect distance from target object
+ int dist = getDist(a->getRealPos().x, a->getRealPos().y, x, y);
+
+ // FIXME: This should be changed once the walkbox problem is fixed
+ if (dist > 0x5) {
+ a->startWalkActor(x, y, dir);
+ VAR(6) = x;
+ VAR(7) = y;
+ return true;
+ } else {
+ // Finished walk, are we picking up the item?
+ if (_verbPickup) {
+ int oldActive = _activeObject, oldIndex = _activeObjectIndex;
+ _activeObject = object;
+ _activeObjectIndex = objectIndex;
+
+ _v0ObjectIndex = true;
+ // Execute pickup
+ runObject(objectIndex, 14);
+ _v0ObjectIndex = false;
+
+ _activeObject = oldActive;
+ _activeObjectIndex = oldIndex;
+
+ // Finished picking up
+ _verbPickup = false;
+ }
+ }
+
+ return false;
+}
+
+bool ScummEngine_v0::verbObtain(int obj, int objIndex) {
+ bool didPickup = false;
+
+ int prep, where = whereIsObjectInventory(obj);
+
+ if (objIndex == 0)
+ return false;
+
+ if (where != WIO_INVENTORY) {
+ _v0ObjectIndex = true;
+ prep = verbPrep(objIndex);
+
+ if (prep == 1 || prep == 4) {
+ if (_activeVerb != 13 && _activeVerb != 14) {
+ _verbPickup = true;
+ didPickup = true;
+ }
+ } else {
+ _verbPickup = false;
+ }
+
+ if (verbMove(obj, objIndex, false))
+ return true;
+
+ if (didPickup && (prep == 1 || prep == 4))
+ if (_activeVerb != 13 && _activeVerb != 14)
+ _activeInventory = obj;
+ }
+
+ return false;
+}
+
+int ScummEngine_v0::verbPrep(int object) {
+ if (!_v0ObjectInInventory)
+ _v0ObjectIndex = true;
+ else
+ _v0ObjectIndex = false;
+ byte *ptr = getOBCDFromObject(object);
+ _v0ObjectIndex = false;
+ assert(ptr);
+ return (*(ptr + 11) >> 5);
+}
+
+bool ScummEngine_v0::verbExecutes(int object, bool inventory) {
+ _v0ObjectInInventory = inventory;
+ int prep = verbPrep(object);
+
+ if (prep == 2 || prep == 0) {
+ return true;
+ }
+
+ return false;
+}
+
+bool ScummEngine_v0::verbExec() {
+ int prep = 0;
+ int entry = (_currentMode != 0 && _currentMode != 1) ? _activeVerb : 15;
+
+ if ((!_activeInvExecute && _activeObject && getObjectIndex(_activeObject) == -1)) {
+ resetSentence();
+ return false;
+ }
+
+ // Lets try walk to the object
+ if (_activeObject && _activeObjectIndex && !_activeObjectObtained && _currentMode != 0) {
+ prep = verbPrep(_activeObjectIndex);
+
+ if (verbObtain(_activeObject, _activeObjectIndex))
+ return true;
+
+ _activeObjectObtained = true;
+ }
+
+ if (_activeObject2 && _activeObject2Index && !_activeObject2Obtained && _currentMode != 0) {
+ prep = verbPrep(_activeObject2Index);
+
+ _v0ObjectInInventory = false;
+ if (verbObtain(_activeObject2, _activeObject2Index))
+ return true;
+
+ if (prep != 1 && prep != 4) {
+ _activeInventory = _activeObject;
+ _activeObject = _activeObject2;
+ _activeObjectIndex = _activeObject2Index;
+ _activeObject2 = 0;
+ _activeObject2Index = 0;
+ }
+
+ _activeObject2Obtained = true;
+ }
+
+ // Give-To
+ if (_activeVerb == 3 && _activeInventory && _activeActor) {
+ // FIXME: Actors need to turn and face each other
+ // And walk to each other
+ if (verbMoveToActor(_activeActor))
+ return true;
+
+ _v0ObjectInInventory = true;
+ VAR(5) = _activeActor;
+ runObject(_activeInventory , 3);
+ _v0ObjectInInventory = false;
+
+ resetSentence();
+ return false;
+ }
+
+ if (_activeActor) {
+ _v0ObjectIndex = true;
+ runObject(_activeActor, entry);
+ _v0ObjectIndex = false;
+ _verbExecuting = false;
+
+ resetSentence();
+ return false;
+ }
+
+ // If we've finished walking (now near target), execute the action
+ if (_activeObject && _activeObjectIndex && verbPrep(_activeObjectIndex) == 2) {
+ _v0ObjectIndex = true;
+ runObject(_activeObjectIndex, entry);
+ _v0ObjectIndex = false;
+ _verbExecuting = false;
+
+ if ((_currentMode == 3 || _currentMode == 2) && _activeVerb == 13)
+ return false;
+
+ resetSentence();
+ return false;
+ }
+
+ // We acted on an inventory item
+ if (_activeInventory && verbExecutes(_activeInventory, true) && _activeVerb != 3) {
+ _v0ObjectInInventory = true;
+ runObject(_activeInventory, _activeVerb);
+
+ _verbExecuting = false;
+
+ if (_currentMode == 3 && _activeVerb == 13) {
+ resetSentence(true);
+ return false;
+ }
+
+ resetSentence();
+ return false;
+ }
+
+ if (_activeObject) {
+ _v0ObjectIndex = true;
+ runObject(_activeObjectIndex, entry);
+ _v0ObjectIndex = false;
+ } else if (_activeInventory) {
+ if (verbExecutes(_activeInventory, true) == false) {
+ if (_activeObject2 && verbExecutes(_activeObject2, true)) {
+ _v0ObjectInInventory = true;
+
+ _activeObject = _activeInventory;
+ _activeInventory = _activeObject2;
+
+ runObject(_activeObject, _activeVerb);
+ } else {
+ _v0ObjectInInventory = true;
+ runObject(_activeInventory, _activeVerb);
+ }
+ } else {
+ runObject(_activeInventory, _activeVerb);
+ _v0ObjectInInventory = true;
+ }
+ }
+
+ _verbExecuting = false;
+
+ if (_activeVerb == 13) {
+ resetSentence(true);
+ return false;
+ }
+
+ resetSentence();
+
+ return false;
+}
+
void ScummEngine_v0::checkExecVerbs() {
Actor *a;
VirtScreen *zone = findVirtScreen(_mouse.y);
+ // Is a verb currently executing
+ if (_verbExecuting) {
+ // Check if mouse click
+ if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) {
+ int over = findVerbAtPos(_mouse.x, _mouse.y);
+ int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
+ int obj = findObject(_virtualMouse.x, _virtualMouse.y);
+
+ if (over && over != _activeVerb) {
+ _activeVerb = over;
+ _verbExecuting = false;
+ return;
+ }
+
+ if (!obj && !act && !over) {
+ resetSentence(false);
+ } else {
+ a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+ a->stopActorMoving();
+ }
+ } else {
+ if (_verbExecuting && !verbExec())
+ return;
+ }
+ }
+
+ // What-Is selected, any object we hover over is selected, on mouse press we set to WalkTo
+ if (_activeVerb == 15) {
+ int obj = findObject(_virtualMouse.x, _virtualMouse.y);
+ int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
+ _activeObject = obj;
+ _activeObjectIndex = objIdx;
+
+ if ((_mouseAndKeyboardStat & MBS_MOUSE_MASK))
+ _activeVerb = 13; // Walk-To
+
+ return;
+ }
+
if (_userPut <= 0 || _mouseAndKeyboardStat == 0)
return;
@@ -693,61 +992,147 @@ void ScummEngine_v0::checkExecVerbs() {
if (zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) {
// TODO
} else if (zone->number == kVerbVirtScreen && _mouse.y > zone->topline + 32) {
+ int prevInventory = _activeInventory;
+
// Click into V2 inventory
checkV2Inventory(_mouse.x, _mouse.y);
+ if (!_activeInventory)
+ return;
+
+ // Did we just change the selected inventory item?
+ if (prevInventory && prevInventory != _activeInventory && _activeInventory != _activeObject2) {
+ _activeObject = 0;
+ _activeInvExecute = true;
+ _activeObject2Inv = true;
+ _activeObject2 = _activeInventory;
+ _activeInventory = prevInventory;
+ return;
+ }
+
+ // is the new selected inventory the same as the last selected?, reset to previous if it is
+ if (_activeInventory == _activeObject2)
+ _activeInventory = prevInventory;
+
+ // Inventory Selected changed
+ if (prevInventory != _activeInventory)
+ if (!_activeObject2 || prevInventory != _activeObject2)
+ return;
+
+ if (_activeVerb == 11 && !((!(_activeObject || _activeInventory)) || !_activeObject2))
+ return;
} else {
int over = findVerbAtPos(_mouse.x, _mouse.y);
+ int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
+ int obj = findObject(_virtualMouse.x, _virtualMouse.y);
+ int objIdx = findObjectIndex(_virtualMouse.x, _virtualMouse.y);
+
+ if ((_activeObject || _activeInventory) && act) {
+ obj = 0;
+ objIdx = 0;
+ }
// Handle New Kid verb options
- if (_activeVerb == 7) {
+ if (_activeVerb == 7 || over == 7) {
+ // Disable New-Kid (in the secret lab)
+ if (_currentMode == 2 || _currentMode == 0)
+ return;
+
+ if (_activeVerb != 7) {
+ _activeVerb = over;
+ over = 0;
+ }
+
if (over) {
_activeVerb = 13;
switchActor(_verbs[over].verbid - 1);
+ return;
}
+
+ setNewKidVerbs();
+
return;
}
+
+ // Clicked on nothing, walk here?
+ if (!over && !act && _activeVerb == 13 && !obj && _currentMode != 0) {
+ // Clear all selected
+ resetSentence();
- if (over) {
- _activeVerb = _verbs[over].verbid;
- // Selected New Kid verb
- if (_activeVerb == 7)
- setNewKidVerbs();
+ // 0xB31
+ VAR(6) = _virtualMouse.x / V12_X_MULTIPLIER;
+ VAR(7) = _virtualMouse.y / V12_Y_MULTIPLIER;
+ if (zone->number == kMainVirtScreen) {
+ a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
+ a->stopActorMoving();
+ a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1);
+ }
return;
}
- int act = getActorFromPos(_virtualMouse.x, _virtualMouse.y);
- int obj = findObject(_virtualMouse.x, _virtualMouse.y);
- if (act != 0 && _activeVerb == 3 && _activeInventory != 0) {
- // Give inventory item to actor
- VAR(5) = act;
- runObject(_activeInventory, _activeVerb);
- } else if (obj) {
- if (_currentMode == 3 && _activeVerb != 13 && obj != _activeObject) {
- _activeObject = obj;
- return;
- }
+ // No new verb, use previous
+ if (over == 0)
+ over = _activeVerb;
- _activeObject = obj;
- if (_currentMode == 3) {
- int x, y, dir;
- a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
- getObjectXYPos(obj, x, y, dir);
- a->startWalkActor(x, y, dir);
+ // No verb selected, use walk-to
+ if (!_activeVerb)
+ _activeVerb = over = 13; // Walk-To
+
+ // New verb selected
+ if (_activeVerb != over) {
+ _activeVerb = over;
+ if (_activeVerb == 13) {
+ resetSentence();
}
+ return;
+ }
- int entry = (_currentMode == 3) ? _activeVerb : 15;
- runObject(_activeObject, entry);
- } else if (zone->number == kMainVirtScreen) {
- a = derefActor(VAR(VAR_EGO), "checkExecVerbs");
- a->startWalkActor(_virtualMouse.x / V12_X_MULTIPLIER, _virtualMouse.y / V12_Y_MULTIPLIER, -1);
+ // Only allowing targetting actors if its the GIVE/USE verb
+ if (_activeVerb == 3 || _activeVerb == 11) {
+ // Different actor selected?
+ if (act) {
+ if (_activeActor != act) {
+ _activeActor = act;
+ return;
+ }
+ }
}
- _activeInventory = 0;
- _activeObject = 0;
- _activeVerb = 13;
+ if (obj && obj != _activeObject) {
+ if (!_activeObject)
+ if (_activeInventory)
+ _activeInvExecute = true;
+
+ // USE
+ if (_activeVerb == 11 || _activeVerb == 8) {
+ if (obj != _activeObject || obj != _activeObject2) {
+ if (!_activeObject || _activeInventory) {
+ _activeObject = obj;
+ _activeObjectIndex = objIdx;
+ return;
+ } else {
+ if (_activeObject2 != obj) {
+ _activeObject2 = obj;
+ _activeObject2Index = objIdx;
+ return;
+ }
+ }
+ }
+ } else {
+ _activeObject = obj;
+ _activeObjectIndex = objIdx;
+
+ if (_activeVerb != 13)
+ return;
+
+ //return;
+ }
+ }
}
- }
+
+ _verbExecuting = true;
+
+ } // mouse k/b action
}
void ScummEngine::verbMouseOver(int verb) {
diff --git a/engines/sky/logic.cpp b/engines/sky/logic.cpp
index 991fbe19d0..5924197d96 100644
--- a/engines/sky/logic.cpp
+++ b/engines/sky/logic.cpp
@@ -27,6 +27,7 @@
#include "common/endian.h"
#include "common/rect.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "sky/autoroute.h"
@@ -73,7 +74,7 @@ void Logic::setupLogicTable() {
}
Logic::Logic(SkyCompact *skyCompact, Screen *skyScreen, Disk *skyDisk, Text *skyText, MusicBase *skyMusic, Mouse *skyMouse, Sound *skySound) {
- g_system->getEventManager()->registerRandomSource(_rnd, "sky");
+ g_eventRec.registerRandomSource(_rnd, "sky");
_skyCompact = skyCompact;
_skyScreen = skyScreen;
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index 2d0d081ef6..7ed50461af 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -160,6 +160,9 @@ void MoviePlayer::play(void) {
stopEvent.kbd = Common::KEYCODE_ESCAPE;
stopEvents.push_back(stopEvent);
+ _textX = 0;
+ _textY = 0;
+
terminated = !playVideo(stopEvents);
if (terminated)
@@ -200,12 +203,15 @@ void MoviePlayer::performPostProcessing(byte *screen) {
}
}
+ byte *src, *dst;
+ int x, y;
+
if (_textMan->giveSpriteData(2)) {
- byte *src = (byte *)_textMan->giveSpriteData(2) + sizeof(FrameHeader);
- byte *dst = screen + _textY * _decoder->getWidth() + _textX * 1;
+ src = (byte *)_textMan->giveSpriteData(2) + sizeof(FrameHeader);
+ dst = screen + _textY * SCREEN_WIDTH + _textX * 1;
- for (int y = 0; y < _textHeight; y++) {
- for (int x = 0; x < _textWidth; x++) {
+ for (y = 0; y < _textHeight; y++) {
+ for (x = 0; x < _textWidth; x++) {
switch (src[x]) {
case BORDER_COL:
dst[x] = _decoder->getBlack();
@@ -216,8 +222,34 @@ void MoviePlayer::performPostProcessing(byte *screen) {
}
}
src += _textWidth;
- dst += _decoder->getWidth();
+ dst += SCREEN_WIDTH;
+ }
+ } else if (_textX && _textY) {
+ // If the frame doesn't cover the entire screen, we have to
+ // erase the subtitles manually.
+
+ int frameWidth = _decoder->getWidth();
+ int frameHeight = _decoder->getHeight();
+ int frameX = (_system->getWidth() - frameWidth) / 2;
+ int frameY = (_system->getHeight() - frameHeight) / 2;
+
+ dst = screen + _textY * _system->getWidth();
+
+ for (y = 0; y < _textHeight; y++) {
+ if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
+ memset(dst + _textX, _decoder->getBlack(), _textWidth);
+ } else {
+ if (frameX > _textX)
+ memset(dst + _textX, _decoder->getBlack(), frameX - _textX);
+ if (frameX + frameWidth < _textX + _textWidth)
+ memset(dst + frameX + frameWidth, _decoder->getBlack(), _textX + _textWidth - (frameX + frameWidth));
+ }
+
+ dst += _system->getWidth();
}
+
+ _textX = 0;
+ _textY = 0;
}
}
diff --git a/engines/sword1/control.cpp b/engines/sword1/control.cpp
index 756ce3a5cc..09d2197f2a 100644
--- a/engines/sword1/control.cpp
+++ b/engines/sword1/control.cpp
@@ -1207,7 +1207,7 @@ bool Control::restoreGameFromFile(uint8 slot) {
for (uint32 cnt2 = 0; cnt2 < playerSize; cnt2++)
playerBuf[cnt2] = inf->readUint32LE();
- if (inf->ioFailed()) {
+ if (inf->err() || inf->eos()) {
displayMessage(0, "Can't read from file '%s'. (%s)", fName, _saveFileMan->popErrorDesc().c_str());
delete inf;
free(_restoreBuf);
diff --git a/engines/sword1/logic.cpp b/engines/sword1/logic.cpp
index 7e911bd197..be3797b0bd 100644
--- a/engines/sword1/logic.cpp
+++ b/engines/sword1/logic.cpp
@@ -28,6 +28,7 @@
#include "common/util.h"
#include "common/system.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "sword1/logic.h"
#include "sword1/text.h"
@@ -55,7 +56,7 @@ namespace Sword1 {
uint32 Logic::_scriptVars[NUM_SCRIPT_VARS];
Logic::Logic(SwordEngine *vm, ObjectMan *pObjMan, ResMan *resMan, Screen *pScreen, Mouse *pMouse, Sound *pSound, Music *pMusic, Menu *pMenu, OSystem *system, Audio::Mixer *mixer) {
- g_system->getEventManager()->registerRandomSource(_rnd, "sword1");
+ g_eventRec.registerRandomSource(_rnd, "sword1");
_vm = vm;
_objMan = pObjMan;
diff --git a/engines/sword1/resman.cpp b/engines/sword1/resman.cpp
index 979bd3210a..90ea5fe677 100644
--- a/engines/sword1/resman.cpp
+++ b/engines/sword1/resman.cpp
@@ -263,9 +263,9 @@ void ResMan::resOpen(uint32 id) { // load resource ID into memory
_memMan->alloc(memHandle, size);
Common::File *clusFile = resFile(id);
assert(clusFile);
- clusFile->seek( resOffset(id) );
- clusFile->read( memHandle->data, size);
- if (clusFile->ioFailed()) {
+ clusFile->seek(resOffset(id));
+ clusFile->read(memHandle->data, size);
+ if (clusFile->err() || clusFile->eos()) {
error("Can't read %d bytes from offset %d from cluster file %s\nResource ID: %d (%08X)", size, resOffset(id), _prj.clu[(id >> 24) - 1].label, id, id);
}
} else
diff --git a/engines/sword1/sound.cpp b/engines/sword1/sound.cpp
index b23bf71445..6ad946b28d 100644
--- a/engines/sword1/sound.cpp
+++ b/engines/sword1/sound.cpp
@@ -28,6 +28,7 @@
#include "common/util.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "sword1/sound.h"
@@ -47,7 +48,7 @@ namespace Sword1 {
#define SPEECH_FLAGS (Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_AUTOFREE | Audio::Mixer::FLAG_LITTLE_ENDIAN)
Sound::Sound(const char *searchPath, Audio::Mixer *mixer, ResMan *pResMan) {
- g_system->getEventManager()->registerRandomSource(_rnd, "sword1sound");
+ g_eventRec.registerRandomSource(_rnd, "sword1sound");
strcpy(_filePath, searchPath);
_mixer = mixer;
_resMan = pResMan;
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 21ab645bfe..4a235315b6 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -116,7 +116,7 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI
terminated = !playVideo(stopEvents);
- closeTextObject(_currentMovieText);
+ closeTextObject(_currentMovieText, NULL);
if (terminated) {
_snd->stopHandle(*_bgSoundHandle);
@@ -171,7 +171,7 @@ void MoviePlayer::openTextObject(uint32 index) {
}
}
-void MoviePlayer::closeTextObject(uint32 index) {
+void MoviePlayer::closeTextObject(uint32 index, byte *screen) {
if (index < _numMovieTexts) {
MovieText *text = &_movieTexts[index];
@@ -179,6 +179,32 @@ void MoviePlayer::closeTextObject(uint32 index) {
text->_textMem = NULL;
if (_textSurface) {
+ if (screen) {
+ // If the frame doesn't cover the entire
+ // screen, we have to erase the subtitles
+ // manually.
+
+ int frameWidth = _decoder->getWidth();
+ int frameHeight = _decoder->getHeight();
+ int frameX = (_system->getWidth() - frameWidth) / 2;
+ int frameY = (_system->getHeight() - frameHeight) / 2;
+
+ byte *dst = screen + _textY * _system->getWidth();
+
+ for (int y = 0; y < text->_textSprite.h; y++) {
+ if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
+ memset(dst + _textX, _decoder->getBlack(), text->_textSprite.w);
+ } else {
+ if (frameX > _textX)
+ memset(dst + _textX, _decoder->getBlack(), frameX - _textX);
+ if (frameX + frameWidth < _textX + text->_textSprite.w)
+ memset(dst + frameX + frameWidth, _decoder->getBlack(), _textX + text->_textSprite.w - (frameX + frameWidth));
+ }
+
+ dst += _system->getWidth();
+ }
+ }
+
_vm->_screen->deleteSurface(_textSurface);
_textSurface = NULL;
}
@@ -204,7 +230,7 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
src = buffer;
}
- byte *dst = screen + _textY * _decoder->getWidth() + _textX;
+ byte *dst = screen + _textY * RENDERWIDE + _textX;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
@@ -214,15 +240,11 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen) {
dst[x] = white;
}
src += width;
- dst += _decoder->getWidth();
+ dst += RENDERWIDE;
}
}
}
-// FIXME: This assumes that the subtitles always fit within the frame of the
-// movie. In Broken Sword 2, that's a fairly safe assumption, but not
-// necessarily in all other games.
-
void MoviePlayer::performPostProcessing(byte *screen) {
MovieText *text;
int frame = _decoder->getCurFrame();
@@ -247,6 +269,7 @@ void MoviePlayer::performPostProcessing(byte *screen) {
if (frame <= text->_endFrame) {
drawTextObject(_currentMovieText, screen);
} else {
+ closeTextObject(_currentMovieText, screen);
_currentMovieText++;
}
}
diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h
index 032350d2d6..f2b44baaa0 100644
--- a/engines/sword2/animation.h
+++ b/engines/sword2/animation.h
@@ -98,7 +98,7 @@ protected:
void performPostProcessing(byte *screen);
void openTextObject(uint32 index);
- void closeTextObject(uint32 index);
+ void closeTextObject(uint32 index, byte *screen);
void drawTextObject(uint32 index, byte *screen);
};
diff --git a/engines/sword2/resman.cpp b/engines/sword2/resman.cpp
index 6741be33f1..c49fb8e786 100644
--- a/engines/sword2/resman.cpp
+++ b/engines/sword2/resman.cpp
@@ -151,7 +151,7 @@ bool ResourceManager::init() {
for (i = 0; i < size / 2; i++)
_resConvTable[i] = file.readUint16LE();
- if (file.ioFailed()) {
+ if (file.eos() || file.err()) {
file.close();
GUIErrorMessage("Broken Sword 2: Cannot read resource.tab");
return false;
@@ -178,7 +178,7 @@ bool ResourceManager::init() {
cdInf[i].cd = file.readByte();
- if (file.ioFailed()) {
+ if (file.eos() || file.err()) {
delete cdInf;
file.close();
GUIErrorMessage("Broken Sword 2: Cannot read cd.inf");
@@ -477,7 +477,7 @@ void ResourceManager::readCluIndex(uint16 fileNum, Common::File *file) {
_resFiles[fileNum].entryTab = (uint32*)malloc(tableSize);
_resFiles[fileNum].numEntries = tableSize / 8;
file->read(_resFiles[fileNum].entryTab, tableSize);
- if (file->ioFailed())
+ if (file->eos() || file->err())
error("unable to read index table from file %s", _resFiles[fileNum].fileName);
#ifdef SCUMM_BIG_ENDIAN
diff --git a/engines/sword2/startup.cpp b/engines/sword2/startup.cpp
index 09bf65bf75..e4572d3c1a 100644
--- a/engines/sword2/startup.cpp
+++ b/engines/sword2/startup.cpp
@@ -66,7 +66,7 @@ bool Sword2Engine::initStartMenu() {
int start_ids[MAX_starts];
int lineno = 0;
- while (!fp.eos() && !fp.ioFailed()) {
+ while (!fp.eos() && !fp.err()) {
Common::String line = fp.readLine();
// Skip empty lines or, more likely, the end of the stream.
@@ -103,7 +103,7 @@ bool Sword2Engine::initStartMenu() {
}
// An I/O error before EOS? That's bad, but this is not a vital file.
- if (fp.ioFailed() && !fp.eos())
+ if (fp.err() && !fp.eos())
warning("I/O error while reading startup.inf");
fp.close();
diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
index cf44b4c99c..e368f257a2 100644
--- a/engines/sword2/sword2.cpp
+++ b/engines/sword2/sword2.cpp
@@ -33,6 +33,7 @@
#include "common/file.h"
#include "common/fs.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/savefile.h"
#include "common/system.h"
@@ -305,7 +306,7 @@ Sword2Engine::Sword2Engine(OSystem *syst) : Engine(syst) {
_gmmLoadSlot = -1; // Used to manage GMM Loading
- syst->getEventManager()->registerRandomSource(_rnd, "sword2");
+ g_eventRec.registerRandomSource(_rnd, "sword2");
}
Sword2Engine::~Sword2Engine() {
diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp
index a3f921505a..df3f95ca13 100644
--- a/engines/tinsel/detection.cpp
+++ b/engines/tinsel/detection.cpp
@@ -79,6 +79,8 @@ namespace Tinsel {
using Common::GUIO_NONE;
using Common::GUIO_NOSPEECH;
+using Common::GUIO_NOSFX;
+using Common::GUIO_NOMUSIC;
static const TinselGameDescription gameDescriptions[] = {
@@ -101,7 +103,7 @@ static const TinselGameDescription gameDescriptions[] = {
Common::EN_ANY,
Common::kPlatformPC,
ADGF_DEMO,
- GUIO_NOSPEECH
+ GUIO_NOSPEECH | GUIO_NOSFX | GUIO_NOMUSIC
},
GID_DW1,
0,
diff --git a/engines/tinsel/heapmem.cpp b/engines/tinsel/heapmem.cpp
index e77f505edb..5db2918d2f 100644
--- a/engines/tinsel/heapmem.cpp
+++ b/engines/tinsel/heapmem.cpp
@@ -285,7 +285,8 @@ MEM_NODE *MemoryAlloc(int flags, long size) {
}
#ifdef SCUMM_NEED_ALIGNMENT
- size = (size + 3) & ~3; //round up to nearest multiple of 4, this ensures the addresses that are returned are 4-byte aligned as well.
+ const int alignPadding = sizeof(void*) - 1;
+ size = (size + alignPadding) & ~alignPadding; //round up to nearest multiple of sizeof(void*), this ensures the addresses that are returned are alignment-safe.
#endif
while ((flags & DWM_NOALLOC) == 0 && bCompacted) {
@@ -521,7 +522,7 @@ MEM_NODE *MemoryReAlloc(MEM_NODE *pMemNode, long size, int flags) {
assert(flags & (DWM_FIXED | DWM_MOVEABLE));
// align the size to machine boundary requirements
- size = (size + sizeof(int) - 1) & ~(sizeof(int) - 1);
+ size = (size + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
// validate the size
assert(size);
diff --git a/engines/tinsel/saveload.cpp b/engines/tinsel/saveload.cpp
index 62bcc732a8..0069778531 100644
--- a/engines/tinsel/saveload.cpp
+++ b/engines/tinsel/saveload.cpp
@@ -37,6 +37,8 @@
#include "common/serializer.h"
#include "common/savefile.h"
+#include "gui/message.h"
+
namespace Tinsel {
@@ -84,6 +86,8 @@ extern void syncGlobInfo(Common::Serializer &s);
// in POLYGONS.C
extern void syncPolyInfo(Common::Serializer &s);
+extern int sceneCtr;
+
//----------------- LOCAL DEFINES --------------------
struct SaveGameHeader {
@@ -450,6 +454,11 @@ static bool DoRestore() {
delete f;
+ if (failed) {
+ GUI::MessageDialog dialog("Failed to load game state from file.");
+ dialog.runModal();
+ }
+
return !failed;
}
@@ -471,11 +480,11 @@ static void DoSave(void) {
fname = SaveSceneName;
f = _vm->getSaveFileMan()->openForSaving(fname);
- if (f == NULL)
- return;
-
Common::Serializer s(0, f);
+ if (f == NULL)
+ goto save_failure;
+
// Write out a savegame header
SaveGameHeader hdr;
hdr.id = SAVEGAME_ID;
@@ -500,8 +509,12 @@ static void DoSave(void) {
return;
save_failure:
- delete f;
- _vm->getSaveFileMan()->removeSavefile(fname);
+ if (f) {
+ delete f;
+ _vm->getSaveFileMan()->removeSavefile(fname);
+ }
+ GUI::MessageDialog dialog("Failed to save game state to file.");
+ dialog.runModal();
}
/**
@@ -510,6 +523,10 @@ save_failure:
void ProcessSRQueue(void) {
switch (SRstate) {
case SR_DORESTORE:
+ // If a load has been done directly from title screens, set a larger value for scene ctr so the
+ // code used to skip the title screens in Discworld 1 gets properly disabled
+ if (sceneCtr < 10) sceneCtr = 10;
+
if (DoRestore()) {
DoRestoreScene(srsd, false);
}
diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp
index 95541e3287..5f056351b6 100644
--- a/engines/tinsel/tinsel.cpp
+++ b/engines/tinsel/tinsel.cpp
@@ -26,6 +26,7 @@
#include "common/endian.h"
#include "common/error.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/keyboard.h"
#include "common/file.h"
#include "common/savefile.h"
@@ -934,7 +935,7 @@ Common::Error TinselEngine::run() {
_screenSurface.create(320, 200, 1);
}
- g_system->getEventManager()->registerRandomSource(_random, "tinsel");
+ g_eventRec.registerRandomSource(_random, "tinsel");
_console = new Console();
diff --git a/engines/touche/touche.cpp b/engines/touche/touche.cpp
index 5d79e0fb9a..1a6546cb4c 100644
--- a/engines/touche/touche.cpp
+++ b/engines/touche/touche.cpp
@@ -26,6 +26,7 @@
#include "common/config-manager.h"
#include "common/events.h"
+#include "common/EventRecorder.h"
#include "common/system.h"
#include "graphics/cursorman.h"
@@ -73,7 +74,7 @@ ToucheEngine::ToucheEngine(OSystem *system, Common::Language language)
Common::addDebugChannel(kDebugOpcodes, "Opcodes", "Opcodes debug level");
Common::addDebugChannel(kDebugMenu, "Menu", "Menu debug level");
- _eventMan->registerRandomSource(_rnd, "touche");
+ g_eventRec.registerRandomSource(_rnd, "touche");
}
ToucheEngine::~ToucheEngine() {
diff --git a/engines/tucker/locations.cpp b/engines/tucker/locations.cpp
index 4117391cdf..011410fe07 100644
--- a/engines/tucker/locations.cpp
+++ b/engines/tucker/locations.cpp
@@ -1671,7 +1671,7 @@ void TuckerEngine::execData3PreUpdate_locationNum26() {
void TuckerEngine::updateSprite_locationNum27(int i) {
int state;
- if (_flagsTable[155] < 3 || _flagsTable[125] == 5) {
+ if (_flagsTable[155] < 3 || _flagsTable[155] == 5) {
state = -1;
} else if (_flagsTable[155] == 3) {
state = 1;