diff options
author | Vicent Marti | 2008-08-16 00:08:12 +0000 |
---|---|---|
committer | Vicent Marti | 2008-08-16 00:08:12 +0000 |
commit | 146be8e16b0abd43f87274a305d9d65b594d1d7f (patch) | |
tree | 8c019cf6c35345de29946d681102cd036876b425 /engines/parallaction | |
parent | 2ae7dc0e32342a0b770bc67883f9b5b77967cb71 (diff) | |
parent | f2111eeb45dc8c41afb3e63bf3b86a09bf9a3532 (diff) | |
download | scummvm-rg350-146be8e16b0abd43f87274a305d9d65b594d1d7f.tar.gz scummvm-rg350-146be8e16b0abd43f87274a305d9d65b594d1d7f.tar.bz2 scummvm-rg350-146be8e16b0abd43f87274a305d9d65b594d1d7f.zip |
Merged revisions 33490,33492,33495-33496,33509-33512,33518-33519,33522-33527,33529-33530,33537,33541,33544,33546,33550,33552-33554,33556,33558,33561-33562,33565,33568,33570,33574,33576,33578-33581,33584-33587,33590,33596,33604-33611,33614-33615,33617-33618,33620-33621,33623,33626-33627,33632-33633,33635,33637,33639-33640,33642-33645,33648,33654-33655,33664,33667-33670,33673-33674,33678,33682,33686-33691,33693,33696,33698,33700,33703,33708,33710,33712-33714,33716,33719,33721-33723,33725-33727,33729-33730,33733,33736,33742,33754,33756,33758,33761,33763,33766,33777,33781-33788,33790,33792-33793,33795,33797,33805,33807-33812,33815-33817,33819,33822,33826,33829,33837,33839,33844,33847,33858-33861,33864,33871-33873,33875,33877-33879,33886,33889-33892,33894,33896,33900,33902-33903,33919 via svnmerge from
https://scummvm.svn.sourceforge.net/svnroot/scummvm/scummvm/trunk
........
r33490 | thebluegr | 2008-08-01 16:03:20 +0200 (Fri, 01 Aug 2008) | 2 lines
Added load confirmation dialog for IHNM, like in the original.
Fixes bug #1971699 - "IHNM: No Load Game Confirmation"
........
r33492 | thebluegr | 2008-08-01 16:27:40 +0200 (Fri, 01 Aug 2008) | 1 line
Fixed crash on exit from commit #32742 - the memory leak was only in IHNM, not ITE (in ITE, the 4 sprite lists are actually one)
........
r33495 | fingolfin | 2008-08-01 18:31:40 +0200 (Fri, 01 Aug 2008) | 1 line
Print a warning if unsupported XMIDI controllers are used
........
r33496 | fingolfin | 2008-08-01 18:33:22 +0200 (Fri, 01 Aug 2008) | 1 line
Moved Ludde & yaz0r to a new credits section, retired project leaders
........
r33509 | peres001 | 2008-08-02 04:24:36 +0200 (Sat, 02 Aug 2008) | 2 lines
* Added a preprocessor to deal with the crappy location scripts in BRA.
* Added some comments on how the parser and related code should be changed to make things smoother.
........
r33510 | peres001 | 2008-08-02 04:26:09 +0200 (Sat, 02 Aug 2008) | 1 line
Removed debug code I forgot a long time ago ;)
........
r33511 | peres001 | 2008-08-02 04:43:05 +0200 (Sat, 02 Aug 2008) | 1 line
Fixed issues detected by DrMcCoy's obnoxious compiler. ;)
........
r33512 | peres001 | 2008-08-02 05:19:45 +0200 (Sat, 02 Aug 2008) | 2 lines
* Increasing max number of allowed token on one line.
* Increasing buffer size to match old parser.
........
r33518 | lordhoto | 2008-08-02 13:40:09 +0200 (Sat, 02 Aug 2008) | 2 lines
Fix for bug #2035459 "KYRA1: long savegame names cause garbage".
........
r33519 | lordhoto | 2008-08-02 13:57:06 +0200 (Sat, 02 Aug 2008) | 2 lines
Proper fix for bug #2035459 "KYRA1: long savegame names cause garbage".
........
r33522 | lordhoto | 2008-08-02 16:32:05 +0200 (Sat, 02 Aug 2008) | 2 lines
Fixed regressions in kyra1 amiga.
........
r33523 | athrxx | 2008-08-02 16:35:38 +0200 (Sat, 02 Aug 2008) | 1 line
HOF: bug fix for FM-Towns music when using output rates other than 22050 khz
........
r33524 | lordhoto | 2008-08-02 16:35:43 +0200 (Sat, 02 Aug 2008) | 2 lines
Add warning when a voc file is not found.
........
r33525 | Kirben | 2008-08-02 16:37:10 +0200 (Sat, 02 Aug 2008) | 1 line
Detect both HOF non-interactive demos.
........
r33526 | lordhoto | 2008-08-02 16:42:44 +0200 (Sat, 02 Aug 2008) | 2 lines
Fixed yet another crash in kyra1 amiga.
........
r33527 | lordhoto | 2008-08-02 17:05:19 +0200 (Sat, 02 Aug 2008) | 2 lines
Added a member function loadSoundFile to Sound which accepts a filename string instead of a filename list id.
........
r33529 | buddha_ | 2008-08-02 17:47:25 +0200 (Sat, 02 Aug 2008) | 7 lines
- Combined loadAbs and loadResource into one function.
- Made resource loading functions (loadSpl, loadMsk etc)
return the number of the animDataTable entry right after
the loaded data.
- Made resource loading functions always load multiframe
data into directly sequential animDataTable entries
(Hopefully this won't break anything).
........
r33530 | buddha_ | 2008-08-02 17:59:38 +0200 (Sat, 02 Aug 2008) | 3 lines
Made loadResourcesFromSave internally use the loadResource-function.
Fixes Operation Stealth savegame loading! HURRAH! FINALLY!
........
r33537 | sev | 2008-08-02 23:05:46 +0200 (Sat, 02 Aug 2008) | 2 lines
Fix crash when drascula.dat file is missing
........
r33541 | sev | 2008-08-02 23:22:05 +0200 (Sat, 02 Aug 2008) | 2 lines
Fix bug #2007170: "DRASCULA: No Spaces in SaveGames Names"
........
r33544 | sev | 2008-08-02 23:36:08 +0200 (Sat, 02 Aug 2008) | 2 lines
Fix bug #2023727: "MONKEY2: Misplaced Text"
........
r33546 | sev | 2008-08-02 23:57:35 +0200 (Sat, 02 Aug 2008) | 2 lines
Fix bug #1879606: "MANIACNES: Crash when game ends"
........
r33550 | fingolfin | 2008-08-03 00:32:32 +0200 (Sun, 03 Aug 2008) | 1 line
Fix for bug #1972625 'ALL: On-the-fly targets are written to the config file'
........
r33552 | sev | 2008-08-03 00:51:53 +0200 (Sun, 03 Aug 2008) | 3 lines
Fix for bug #1945335: "SCUMM: Invalid charset id can be stored".
Regressions possible.
........
r33553 | fingolfin | 2008-08-03 01:01:14 +0200 (Sun, 03 Aug 2008) | 1 line
Renamed Tinsel v1->v0 (used in the demo only), and v2->v1, to avoid confusion with DW2
........
r33554 | sev | 2008-08-03 01:05:38 +0200 (Sun, 03 Aug 2008) | 2 lines
Fix bug #2035390: "GUI: setting game id to "scummvm" messes up list"
........
r33556 | athrxx | 2008-08-03 01:11:31 +0200 (Sun, 03 Aug 2008) | 1 line
add non-interactive lol demo
........
r33558 | eriktorbjorn | 2008-08-03 09:40:04 +0200 (Sun, 03 Aug 2008) | 3 lines
Fixed #2021902 ("DRASCULA: Can't adjust the volume inside the game"). I can't
verify that this matches the original behaviour, but at least it's better now.
........
r33561 | buddha_ | 2008-08-03 10:01:11 +0200 (Sun, 03 Aug 2008) | 1 line
Shut up MSVC warning about mgY being an unreferenced local variable.
........
r33562 | fingolfin | 2008-08-03 10:05:19 +0200 (Sun, 03 Aug 2008) | 1 line
Proper fix for bug #2035390: Check for ConfigManager::kApplicationDomain, and also forbid targets starting with an underscore
........
r33565 | eriktorbjorn | 2008-08-03 11:41:10 +0200 (Sun, 03 Aug 2008) | 4 lines
Fixed bug that prevented upper-case letters from being used in savegame names.
Apparently, strchr(..., 0) will find the string terminator - at least for me -
and when that's added to the name, it will terminate the string.
........
r33568 | eriktorbjorn | 2008-08-03 11:51:13 +0200 (Sun, 03 Aug 2008) | 2 lines
Fixed bug #1995022 ("BASS: wrong displayed 2 line text").
........
r33570 | eriktorbjorn | 2008-08-03 12:16:17 +0200 (Sun, 03 Aug 2008) | 5 lines
Fixed bug #1995033 ("BASS: BG Sound stopped on opening item list"). Apparently
the sound is supposed to be paused and then unpaused, but the pause function is
called many more times than the unpause function. In the original, this
presumably didn't matter. In ScummVM's mixer, it does.
........
r33574 | sev | 2008-08-03 13:42:05 +0200 (Sun, 03 Aug 2008) | 2 lines
Fix bug #2017432: "DRASCULA: Typing is slow when you save a game"
........
r33576 | sev | 2008-08-03 14:02:09 +0200 (Sun, 03 Aug 2008) | 2 lines
Fix bug #2011470: "DRASCULA: slowdown when you hold mouse buttons"
........
r33578 | athrxx | 2008-08-03 14:09:48 +0200 (Sun, 03 Aug 2008) | 1 line
add support for HOF Italian fan translation to kyra.dat
........
r33579 | lordhoto | 2008-08-03 14:16:53 +0200 (Sun, 03 Aug 2008) | 2 lines
Added detection entries for kyra2 cd italian fan translation (see fr#2003504 "KYRA: add support for Italian version of Kyrandia 2&3"). (totally untested!)
........
r33580 | athrxx | 2008-08-03 14:50:56 +0200 (Sun, 03 Aug 2008) | 1 line
fix last commit (invalid kyra.dat game features for HOFCD)
........
r33581 | lordhoto | 2008-08-03 14:53:12 +0200 (Sun, 03 Aug 2008) | 2 lines
Removed comment.
........
r33584 | fingolfin | 2008-08-03 18:54:18 +0200 (Sun, 03 Aug 2008) | 1 line
New OSystem API for loading/storing default config file
........
r33585 | fingolfin | 2008-08-03 19:05:01 +0200 (Sun, 03 Aug 2008) | 1 line
OSYSTEM: Pushed some SDL/Symbian specific code to the respective backends; made openConfigFileForReading/openConfigFileForWriting return 0 if they failed to open a file
........
r33586 | fingolfin | 2008-08-03 20:11:27 +0200 (Sun, 03 Aug 2008) | 1 line
Implemented DumpFile::open(FSNode)
........
r33587 | fingolfin | 2008-08-03 20:29:37 +0200 (Sun, 03 Aug 2008) | 1 line
cleanup
........
r33590 | fingolfin | 2008-08-03 20:35:51 +0200 (Sun, 03 Aug 2008) | 1 line
FilesystemNode code: some comment cleanup; added FilesystemNode::openForReading() and openForWriting() methods (for now these are simple wrappers around Common::File)
........
r33596 | Kirben | 2008-08-04 03:57:50 +0200 (Mon, 04 Aug 2008) | 1 line
Remove debug left over.
........
r33604 | fingolfin | 2008-08-04 13:30:47 +0200 (Mon, 04 Aug 2008) | 1 line
Moved the OutSaveFile::finalize method to WriteStream; implemented DumpFile::flush()
........
r33605 | fingolfin | 2008-08-04 13:32:42 +0200 (Mon, 04 Aug 2008) | 1 line
Removed join_paths from default save manager, and use FSNode API instead (may lead to regressions, watch out)
........
r33606 | fingolfin | 2008-08-04 13:38:25 +0200 (Mon, 04 Aug 2008) | 1 line
Turned InSaveFile & OutSaveFile into simple typedefs
........
r33607 | fingolfin | 2008-08-04 13:46:52 +0200 (Mon, 04 Aug 2008) | 1 line
SCUMM: Only try to load savefile metadata from slots >= 0
........
r33608 | fingolfin | 2008-08-04 13:48:33 +0200 (Mon, 04 Aug 2008) | 1 line
DefaultSaveFileManager: Killed class StdioSaveFile, used FilesystemNode::openForReading()/openForWriting() instead (may cause regressions, watch out)
........
r33609 | fingolfin | 2008-08-04 15:25:30 +0200 (Mon, 04 Aug 2008) | 1 line
Modified DumpFile::open to accept non-existing nodes, and to actually open files in write mode -- d'oh
........
r33610 | thebluegr | 2008-08-04 17:01:41 +0200 (Mon, 04 Aug 2008) | 1 line
Fixing compilation under MSVC
........
r33611 | thebluegr | 2008-08-04 17:23:08 +0200 (Mon, 04 Aug 2008) | 1 line
Added Italian translation for the load confirmation window in IHNM
........
r33614 | fingolfin | 2008-08-04 19:17:37 +0200 (Mon, 04 Aug 2008) | 1 line
Moved ConfMan.registerDefault calls for savepath to DefaultSaveFileManager (eventually, should be pushed into backends/platform/ code)
........
r33615 | fingolfin | 2008-08-04 19:41:07 +0200 (Mon, 04 Aug 2008) | 1 line
Modified DefaultSaveFileManager::checkPath to perform at least basic checks on non-UNIX, non-Symbian systems
........
r33617 | fingolfin | 2008-08-04 19:46:22 +0200 (Mon, 04 Aug 2008) | 1 line
Remove some code which was rendered obsolete by md5's commit r33610
........
r33618 | anotherguest | 2008-08-04 20:14:17 +0200 (Mon, 04 Aug 2008) | 3 lines
List the correct engines in about,
updated actions with Lure (from WinCE).
Increased min heap size to 5MB
........
r33620 | buddha_ | 2008-08-04 21:32:52 +0200 (Mon, 04 Aug 2008) | 7 lines
Fix for misplaced objects in mouse object selection (Operation Stealth specific).
- Implemented Operation Stealth specific part of getObjectUnderCursor
which handles negative frame values.
- Fixed a test case (Should test for ydif <= 0 although tested for ydif < 0).
- Made part-value be anded with 0x0F in a test case to comply with disassembly.
- Added comment about a test case which isn't present in the disassembly.
Removing it makes things crash sometimes so letting it be.
........
r33621 | fingolfin | 2008-08-04 21:38:28 +0200 (Mon, 04 Aug 2008) | 1 line
Pushed some port specific code from DefaultSaveFileManager out to port specific code in backends/platform/
........
r33623 | anotherguest | 2008-08-04 22:00:56 +0200 (Mon, 04 Aug 2008) | 1 line
Symbian build package should now contain drascula.dat also
........
r33626 | Kirben | 2008-08-05 02:21:46 +0200 (Tue, 05 Aug 2008) | 1 line
Fix win32 compile.
........
r33627 | Kirben | 2008-08-05 02:27:25 +0200 (Tue, 05 Aug 2008) | 1 line
Removed unneeded #includes.
........
r33632 | lordhoto | 2008-08-05 13:32:16 +0200 (Tue, 05 Aug 2008) | 2 lines
Changed implementation parameters/return values to match definition.
........
r33633 | Kirben | 2008-08-05 13:42:04 +0200 (Tue, 05 Aug 2008) | 1 line
Remove file attribute check, since getChild() can be called on file path that doesn'r exist.
........
r33635 | lordhoto | 2008-08-05 14:13:01 +0200 (Tue, 05 Aug 2008) | 2 lines
Output errors on (some) missing files.
........
r33637 | buddha_ | 2008-08-05 14:58:23 +0200 (Tue, 05 Aug 2008) | 7 lines
Fix prompt updating regression introduced in r32257:
Previously prompt didn't get updated all the time,
like e.g. when selecting EXAMINE and moving the
cursor over to DOOR and then moving the cursor to
a place where there was no selectable object. The
prompt would've still shown "EXAMINE DOOR", now
it shows just "EXAMINE" which is correct AFAIK.
........
r33639 | fingolfin | 2008-08-05 15:08:07 +0200 (Tue, 05 Aug 2008) | 1 line
SCUMM: Don't try to load metadata for slot -1 (i.e. don't try to load metadata if nothing is selected)
........
r33640 | fingolfin | 2008-08-05 15:11:22 +0200 (Tue, 05 Aug 2008) | 1 line
SCUMM: cleanup SaveLoadChooser::updateInfos code
........
r33642 | buddha_ | 2008-08-05 20:17:55 +0200 (Tue, 05 Aug 2008) | 1 line
Add detection entry for a previously unrecognized 16 color PC version of Operation Stealth (The John Glames variant).
........
r33643 | buddha_ | 2008-08-05 21:30:16 +0200 (Tue, 05 Aug 2008) | 5 lines
Made rest of resource loading functions used in loadResource return -1 on error.
This fixed a crash in Operation Stealth when walking out of the airport
(Some file couldn't be opened and the game crashed because of that.
Now it doesn't crash but handles the missing file gracefully).
........
r33644 | buddha_ | 2008-08-05 23:20:11 +0200 (Tue, 05 Aug 2008) | 1 line
Workaround for missing player character animation when exiting the airport in Santa Paragua in at least the 256 color PC version of Operation Stealth.
........
r33645 | fingolfin | 2008-08-05 23:26:04 +0200 (Tue, 05 Aug 2008) | 1 line
Patch #2014663: Do not mark stack as executable in HQx scaler
........
r33648 | eriktorbjorn | 2008-08-05 23:43:10 +0200 (Tue, 05 Aug 2008) | 4 lines
Committed my patch #2026097 ("ALSA: Try both 65:0 and 17:0 by default"), with a
slight modification to the README changes. (I don't know how to interpret all
the output from aconnect, so I'm only documenting "the most important bit".)
........
r33654 | fingolfin | 2008-08-06 11:13:57 +0200 (Wed, 06 Aug 2008) | 1 line
SCUMM: Renamed inventoryScript -> inventoryScriptIndy3Mac
........
r33655 | fingolfin | 2008-08-06 12:32:20 +0200 (Wed, 06 Aug 2008) | 1 line
Workaround for bug #2016521 (DOTT: Bernard impersonating LaVerne)
........
r33664 | fingolfin | 2008-08-06 18:03:06 +0200 (Wed, 06 Aug 2008) | 1 line
Do not query savestates which obviously do not exist (to shut up bogus console warnings)
........
r33667 | buddha_ | 2008-08-06 22:41:53 +0200 (Wed, 06 Aug 2008) | 5 lines
HACK: Force oxygen to maximum during Operation Stealth's first arcade sequence.
This way the arcade sequence is completable now.
This hack should be removed later and the first
arcade sequence be made properly playable!
........
r33668 | buddha_ | 2008-08-06 22:47:59 +0200 (Wed, 06 Aug 2008) | 5 lines
Add 320x200 screen bounds checking to Operation Stealth's checkCollision function.
Fixes teleporting bug when getting out of the water after first arcade sequence.
The player previously got teleported to the beach near the hotel. Now it doesn't happen.
The player is still caught motionless and can't move after this fix though...
........
r33669 | buddha_ | 2008-08-06 22:54:38 +0200 (Wed, 06 Aug 2008) | 1 line
Renamed page3Raw to collisionPage so it's more apparent what it does.
........
r33670 | buddha_ | 2008-08-06 22:58:02 +0200 (Wed, 06 Aug 2008) | 1 line
Tiny comment update to loadCt-opcodes: Load collision table data.
........
r33673 | buddha_ | 2008-08-07 01:12:25 +0200 (Thu, 07 Aug 2008) | 4 lines
HACK: In Operation Stealth after the first arcade sequence jump player's position to avoid getting stuck.
The player's position is changed only by *one* pixel but it helps
and makes it possible to carry on with the game (Previously the player was totally stuck).
........
r33674 | knakos | 2008-08-07 11:10:42 +0200 (Thu, 07 Aug 2008) | 1 line
smartphone-specific code not needed anymore
........
r33678 | eriktorbjorn | 2008-08-07 15:36:02 +0200 (Thu, 07 Aug 2008) | 3 lines
Initialise the _sound object. Otherwise, ScummVM crashes for me if I use a native
MIDI driver instead of Adlib.
........
r33682 | knakos | 2008-08-07 20:36:12 +0200 (Thu, 07 Aug 2008) | 1 line
setup interface for later kyra games
........
r33686 | buddha_ | 2008-08-07 21:04:19 +0200 (Thu, 07 Aug 2008) | 7 lines
Fix for popup boxes sometimes blocking animation when they shouldn't in Operation Stealth:
- Made waitForPlayerClick updating more like in the original.
- Moved removeMessages to after the frame drawing in main loop hoping to be more like the original.
- Added an additional test to Operation Stealth's implementation of overlay type 2 drawing.
- Added an additional parameter incrementing and testing to Operation Stealth's removeMessages.
Hopefully this won't cause any regressions in Future Wars!
........
r33687 | buddha_ | 2008-08-07 21:31:12 +0200 (Thu, 07 Aug 2008) | 1 line
Made drawPlainBox handle border cases so it won't corrupt memory so easily. This may help with some memory corruption issues when for an example trying to draw the player's command string out of screen.
........
r33688 | buddha_ | 2008-08-07 21:46:06 +0200 (Thu, 07 Aug 2008) | 1 line
Added precautionary tests to background scrolling function in Operation Stealth to avoid possible memory corruptions.
........
r33689 | buddha_ | 2008-08-07 23:46:56 +0200 (Thu, 07 Aug 2008) | 1 line
Implemented game speed changing by pressing - or + to e.g. ease testing.
........
r33690 | cyx | 2008-08-07 23:49:55 +0200 (Thu, 07 Aug 2008) | 1 line
fix for bug #2040311: TOUCHE: Missing characters in the spanish version
........
r33691 | cyx | 2008-08-07 23:50:12 +0200 (Thu, 07 Aug 2008) | 1 line
fix for bug #2040484: TOUCHE: Graphic glitch with long answer options
........
r33693 | Kirben | 2008-08-08 04:18:17 +0200 (Fri, 08 Aug 2008) | 1 line
Hopefully allow quiting at any stage AGOS engines games again.
........
r33696 | Kirben | 2008-08-08 04:49:51 +0200 (Fri, 08 Aug 2008) | 1 line
Remove debug leftover.
........
r33698 | buddha_ | 2008-08-08 15:30:01 +0200 (Fri, 08 Aug 2008) | 9 lines
Added basic moving using keyboard (Only works in Operation Stealth at the moment):
- Should make it possible to complete the first arcade sequence legitimately
Renamed input variables (Their names were mixed up between Future Wars and Operation Stealth):
- Future Wars's inputVar1 -> egoMovedWithKeyboard
- Future Wars's inputVar2 -> xMoveKeyb
- Future Wars's inputVar3 -> yMoveKeyb
- Operation Stealth's inputVar0 -> xMoveKeyb
- Operation Stealth's inputVar1 -> yMoveKeyb
........
r33700 | buddha_ | 2008-08-08 16:46:19 +0200 (Fri, 08 Aug 2008) | 1 line
Partially fix Adlib volume setting in Cine (Now uses music volume for Adlib volume, previously always played with full volume. Doesn't differentiate between playing sound effects and music!).
........
r33703 | buddha_ | 2008-08-08 20:28:13 +0200 (Fri, 08 Aug 2008) | 4 lines
Added detection entry for the Sony published CD version of Future Wars.
Also added decrypting of the crypted AUTO00.PRC for this particular version.
Now this version should work but no CD audio support for it yet though.
........
r33708 | buddha_ | 2008-08-09 12:44:12 +0200 (Sat, 09 Aug 2008) | 1 line
Small cleanup: Renamed rol to rolByte and made it handle all cases.
........
r33710 | buddha_ | 2008-08-09 12:52:48 +0200 (Sat, 09 Aug 2008) | 1 line
Removing moving with keys qweasdzxc for now because they messed with savegame name typing. One can move with the cursor keys anyway.
........
r33712 | buddha_ | 2008-08-09 17:17:32 +0200 (Sat, 09 Aug 2008) | 1 line
Added updating of global variable var5 to Operation Stealth's renderOverlay function's type 20 overlay case (Previously var5 wasn't updated anywhere!). Also added a lower bound for var5's value into a comparison (Previously only the upper bound was tested for).
........
r33713 | buddha_ | 2008-08-09 18:07:08 +0200 (Sat, 09 Aug 2008) | 1 line
Added preliminary version of drawing type 22 overlays (Such overlays are added with opcode 0xA4 (o2_loadMask22) and removed with opcode 0xA5 (o2_unloadMask22)). Things might be wrong so needs testing! WIP!
........
r33714 | knakos | 2008-08-09 20:09:24 +0200 (Sat, 09 Aug 2008) | 1 line
fix MR on ce: allocate large buffer on the heap instead and of the stack, and improve the workaround
........
r33716 | knakos | 2008-08-09 20:12:43 +0200 (Sat, 09 Aug 2008) | 1 line
hotfix around drascula mem leak problems. see also bug report
........
r33719 | dhewg | 2008-08-09 20:37:18 +0200 (Sat, 09 Aug 2008) | 1 line
Updates to the recent OSystem API changes
........
r33721 | buddha_ | 2008-08-09 21:47:05 +0200 (Sat, 09 Aug 2008) | 7 lines
Made drawPlainBox's effective width and height always at least one.
- Makes oxygen gauge during first arcade sequence visible as it gave drawPlainBox a height of zero.
Made type 21 overlays be drawn as type 22 (Filled rectangle).
- For an example the oxygen gauge during the first arcade sequence is a type 21 overlay.
Flipped type 21 & 22 overlays as it looks correct for the oxygen gauge.
These features are quite WIP, they need testing to see if they're correct.
........
r33722 | buddha_ | 2008-08-09 21:57:46 +0200 (Sat, 09 Aug 2008) | 1 line
Made type 21 & 22 overlays not be flipped (The oxygen gauge looks actually better when it reaches zero this way although in its fully charged state it still does look a bit off. Disassembly seems to agree with not flipping the overlays so I'm going with this one for now).
........
r33723 | dhewg | 2008-08-09 22:02:56 +0200 (Sat, 09 Aug 2008) | 3 lines
Updated the Makefile to the new build system.
Introduced a Makefile variable to build a gamecube version.
........
r33725 | buddha_ | 2008-08-09 22:50:10 +0200 (Sat, 09 Aug 2008) | 1 line
Converted objectTable from a plain array to a Common::Array. Should help to catch out of bounds access errors that may cause memory corruption.
........
r33726 | buddha_ | 2008-08-09 22:55:01 +0200 (Sat, 09 Aug 2008) | 1 line
Converted animDataTable from a plain array to a Common::Array. Should help to catch out of bounds access errors which may cause memory corruption.
........
r33727 | buddha_ | 2008-08-10 00:38:03 +0200 (Sun, 10 Aug 2008) | 1 line
Converted zoneData and zoneQuery tables from plain array types to Common::Array. Should help catch out of bounds access errors that may cause memory corruption.
........
r33729 | fingolfin | 2008-08-10 00:42:03 +0200 (Sun, 10 Aug 2008) | 1 line
If no default config file is present, just don't load it, instead of crashing
........
r33730 | fingolfin | 2008-08-10 01:07:32 +0200 (Sun, 10 Aug 2008) | 1 line
Use FSNode API in default OSystem::openConfigFileForReading & OSystem::openConfigFileForWriting method implementations
........
r33733 | lordhoto | 2008-08-10 02:17:56 +0200 (Sun, 10 Aug 2008) | 2 lines
Fixed crash in KyraEngine_HoF::pauseEngineIntern.
........
r33736 | lordhoto | 2008-08-10 02:36:46 +0200 (Sun, 10 Aug 2008) | 2 lines
Fixed kyra to support properly support restarting of engine (for GSoC RTL, based on a patch from Chris Page).
........
r33742 | lordhoto | 2008-08-10 03:28:00 +0200 (Sun, 10 Aug 2008) | 2 lines
Added fallback to text only mode when voice files are not found.
........
r33754 | knakos | 2008-08-10 19:10:09 +0200 (Sun, 10 Aug 2008) | 1 line
add support for drascula engine
........
r33756 | knakos | 2008-08-10 19:13:24 +0200 (Sun, 10 Aug 2008) | 1 line
hint the backend to show the VK
........
r33758 | knakos | 2008-08-10 19:15:30 +0200 (Sun, 10 Aug 2008) | 1 line
address the ignored events and bad inventory screen handling 'features'
........
r33761 | sev | 2008-08-10 19:35:42 +0200 (Sun, 10 Aug 2008) | 2 lines
Add checksums for ScummVM repacked Italian and Spanish versions.
........
r33763 | eriktorbjorn | 2008-08-10 19:59:42 +0200 (Sun, 10 Aug 2008) | 5 lines
Committed my patch #2040074 ("XMIDI callback control events"). At the moment, I'm
not aware of any game that actually uses this XMIDI feature, so its primary
function right now is to silence lots of warnings while running the DOS version
of Simon the Sorcerer 2.
........
r33766 | eriktorbjorn | 2008-08-10 20:44:00 +0200 (Sun, 10 Aug 2008) | 5 lines
Fixed a bunch of Valgrind warnings (mostly uninitialised variables, but also an
invalid free()), so that I can start and quit the game without any unexpected
warnings. (The obvious next step, of course, would be to actually *play* the game
for a bit...)
........
r33777 | athrxx | 2008-08-11 16:47:50 +0200 (Mon, 11 Aug 2008) | 2 lines
LOL: add support for floppy installer files
(startup will fail nonethelesse since we have different pak file names)
........
r33781 | buddha_ | 2008-08-11 22:09:03 +0200 (Mon, 11 Aug 2008) | 1 line
Changed readBundleFile to unpack data in-place and added debugging messages to the function.
........
r33782 | buddha_ | 2008-08-11 22:18:33 +0200 (Mon, 11 Aug 2008) | 1 line
Added a safeguard to readBundleFile so it shouldn't corrupt memory even if the input says the data's unpacked size is less than its packed size (This shouldn't ever happen with non-corrupted data).
........
r33783 | buddha_ | 2008-08-11 22:41:13 +0200 (Mon, 11 Aug 2008) | 1 line
Changed partBuffer from a pointer to a Common::Array. Removed numElementInPart variable as it's now equivalent with partBuffer.size().
........
r33784 | buddha_ | 2008-08-11 23:26:41 +0200 (Mon, 11 Aug 2008) | 1 line
Removed textDataPtr pointer as it's not used beyond the loadTextData function. Reworked loadTextData a bit so there are no two loops for the same thing (Also renamed some of the local variables).
........
r33785 | buddha_ | 2008-08-11 23:45:47 +0200 (Mon, 11 Aug 2008) | 1 line
Changed palPtr from a pointer to a Common::Array named palArray. Removed palEntriesCount variable as it's now equivalent to palArray.size().
........
r33786 | buddha_ | 2008-08-12 00:26:25 +0200 (Tue, 12 Aug 2008) | 1 line
Moved fontParamTable inside TextHandler struct and made it a constant size as that's what it is (No need for using malloc & free anymore). Previously we would've tried to free an array that wasn't heap-allocated in freePoldatDat (Freeing fontParamTable_standard or fontParamTable_alt), that's fixed.
........
r33787 | dhewg | 2008-08-12 00:43:00 +0200 (Tue, 12 Aug 2008) | 7 lines
video mode polishing:
* proper fullscreen video mode
* multiple graphic modes with different overscan values
* "fullscreen mode" stretches the picture on 16:9 displays
* fixed broken sword 1/2 gfx garbage
* support for setShakePos()
........
r33788 | dhewg | 2008-08-12 00:44:29 +0200 (Tue, 12 Aug 2008) | 1 line
build a wii binary per default
........
r33790 | buddha_ | 2008-08-12 01:01:32 +0200 (Tue, 12 Aug 2008) | 1 line
Implemented drawMessage changes for Operation Stealth's timed cutscenes (Negative colors are used for timed text boxes that are totally transparent, only the text is drawn).
........
r33792 | buddha_ | 2008-08-12 01:20:10 +0200 (Tue, 12 Aug 2008) | 1 line
Made Operation Stealth's action failure messages use a background color set by the opcode 0x49 'o1_setDefaultMenuBgColor'. Should fix the 'text hard to read' problems.
........
r33793 | buddha_ | 2008-08-12 02:13:27 +0200 (Tue, 12 Aug 2008) | 1 line
Changed commandBuffer from a char[80] to Common::String and made FWRenderer::setCommand use a Common::String. Hopefully this might help with the command buffer overflow stuff, although this isn't a fix for the problem behind it, just a bandaid.
........
r33795 | buddha_ | 2008-08-12 16:44:44 +0200 (Tue, 12 Aug 2008) | 1 line
Implemented Operation Stealth specific parts of processInventory and added another mouse button waiting loop into the function's end (It's in both Future Wars and Operation Stealth). Fixes inventory showing in Operation Stealth.
........
r33797 | aquadran | 2008-08-12 16:52:44 +0200 (Tue, 12 Aug 2008) | 1 line
added few ignores for build dirs
........
r33805 | buddha_ | 2008-08-12 21:33:17 +0200 (Tue, 12 Aug 2008) | 1 line
Implemented Operation Stealth's makeCommandLine.
........
r33807 | buddha_ | 2008-08-12 22:27:49 +0200 (Tue, 12 Aug 2008) | 1 line
Tiny comment fix.
........
r33808 | buddha_ | 2008-08-12 22:58:26 +0200 (Tue, 12 Aug 2008) | 1 line
Fix for GCC warning in OSRenderer::renderOverlay: declaration of 'len' shadows a previous local.
........
r33809 | joostp | 2008-08-12 23:23:40 +0200 (Tue, 12 Aug 2008) | 2 lines
fix typo 'baclup' -> 'backup'
........
r33810 | buddha_ | 2008-08-13 00:45:38 +0200 (Wed, 13 Aug 2008) | 1 line
Added possibility to get the read resource's size from readBundleFile. Made loadMsg handle input data that has empty strings residing just beyond the input buffer (Thanks Valgrind :-)).
........
r33811 | buddha_ | 2008-08-13 01:44:39 +0200 (Wed, 13 Aug 2008) | 1 line
Fixed drawPlainBox's boundary checking (It wrote outside the screen occasionally). Now using the Common::Rect for clipping, yay! It's good.
........
r33812 | buddha_ | 2008-08-13 01:56:13 +0200 (Wed, 13 Aug 2008) | 1 line
Hopefully fixes 'Conditional jump or move depends on uninitialised value(s)' Valgrind warning at sound.cpp:611.
........
r33815 | buddha_ | 2008-08-13 03:02:00 +0200 (Wed, 13 Aug 2008) | 1 line
Changed Agi::SoundMgr's sound buffer to a member array of size BUFFER_SIZE. Also added initialization of _playing to false in SoundMgr's constructor. Hopefully helps with the occasional crashes in the sound code when starting the first sound in an AGI game.
........
r33816 | buddha_ | 2008-08-13 03:10:03 +0200 (Wed, 13 Aug 2008) | 1 line
Shutting up Valgrind about using uninitialised values from array _chn in function stopNote.
........
r33817 | fingolfin | 2008-08-13 12:13:22 +0200 (Wed, 13 Aug 2008) | 1 line
Clarify SCUMM MD5 message: We do not want reports on fanmade translations
........
r33819 | buddha_ | 2008-08-13 13:36:45 +0200 (Wed, 13 Aug 2008) | 1 line
Reverted r33815 (But not r33816).
........
r33822 | buddha_ | 2008-08-13 13:57:48 +0200 (Wed, 13 Aug 2008) | 1 line
Fixed initialization of some SoundMgr-class's member variables. Moved _sndBuffer's allocation to SoundMgr's constructor and its deallocation to the destructor. Made fillAudio SoundMgr's method and removed a superfluous global static variable 'int16 *buffer'. Should help with the occasional crashes when starting the first sound in an AGI game.
........
r33826 | buddha_ | 2008-08-13 15:40:28 +0200 (Wed, 13 Aug 2008) | 1 line
Type 21 overlay comment update (Found the drawing routine in the disassembly and checked the original for how the oxygen gauge during the first arcade sequence looks like. They're some kind of sprites most likely and not just simply filled rectangles).
........
r33829 | knakos | 2008-08-13 17:16:38 +0200 (Wed, 13 Aug 2008) | 1 line
fix bug #2038992 by saving and restoring channel volumes
........
r33837 | lordhoto | 2008-08-13 21:10:31 +0200 (Wed, 13 Aug 2008) | 2 lines
Added detection entries for kyra3 Mac.
........
r33839 | knakos | 2008-08-13 21:13:53 +0200 (Wed, 13 Aug 2008) | 1 line
fix bug #1910057: FT multifunction
........
r33844 | knakos | 2008-08-13 21:32:25 +0200 (Wed, 13 Aug 2008) | 1 line
fix a small bug in the quit dialog
........
r33847 | fingolfin | 2008-08-13 22:37:54 +0200 (Wed, 13 Aug 2008) | 1 line
cleanup
........
r33858 | peres001 | 2008-08-14 09:10:42 +0200 (Thu, 14 Aug 2008) | 1 line
Removed cross-references between the general parser and the text formatter. To achieve this, I have rewritten the latter for both NS and BRA.
........
r33859 | peres001 | 2008-08-14 09:14:34 +0200 (Thu, 14 Aug 2008) | 1 line
Finally moved parseNextToken to Script, where it belongs!
........
r33860 | peres001 | 2008-08-14 12:04:43 +0200 (Thu, 14 Aug 2008) | 1 line
Cleanup.
........
r33861 | peres001 | 2008-08-14 12:24:39 +0200 (Thu, 14 Aug 2008) | 1 line
More cleanup.
........
r33864 | peres001 | 2008-08-14 15:45:32 +0200 (Thu, 14 Aug 2008) | 1 line
Some variable renamed to make more sense.
........
r33871 | buddha_ | 2008-08-14 22:18:13 +0200 (Thu, 14 Aug 2008) | 1 line
Added debug showing of the collision page when pressing the Alt key. Alt isn't used for anything else so one might as well use it for this.
........
r33872 | buddha_ | 2008-08-14 22:49:34 +0200 (Thu, 14 Aug 2008) | 1 line
Fix for bugging moving at the bottom of the ocean when trying to free the girl from the ropes and swimming to the surface. Some global variables related to mouse position weren't being updated in executePlayerInput, now they are and things seem to work. Also enables moving in the labyrinth arcade sequence at the palace.
........
r33873 | athrxx | 2008-08-14 23:21:04 +0200 (Thu, 14 Aug 2008) | 1 line
- HOF: another Italian fan translation
........
r33875 | athrxx | 2008-08-14 23:34:29 +0200 (Thu, 14 Aug 2008) | 1 line
- HOF: forgot french and german entries in last commit
........
r33877 | buddha_ | 2008-08-15 00:01:56 +0200 (Fri, 15 Aug 2008) | 1 line
Moved showing of the collision page from Alt-key to F11-key because Alt conflicted with taking screenshots using Alt-s. Great. Hopefully F11 doesn't conflict with anything useful.
........
r33878 | lordhoto | 2008-08-15 00:09:36 +0200 (Fri, 15 Aug 2008) | 2 lines
Improved version of my resource loading patch from -devel (check also r33876).
........
r33879 | lordhoto | 2008-08-15 00:11:56 +0200 (Fri, 15 Aug 2008) | 2 lines
Formatting.
........
r33886 | athrxx | 2008-08-15 01:46:37 +0200 (Fri, 15 Aug 2008) | 1 line
lol: new detection entry (german floppy extracted)
........
r33889 | peres001 | 2008-08-15 04:52:42 +0200 (Fri, 15 Aug 2008) | 2 lines
Simplified handling of script variables (especially locals).
........
r33890 | peres001 | 2008-08-15 05:36:01 +0200 (Fri, 15 Aug 2008) | 1 line
Disabled lip syncing code in BRA, since I couldn't find any scripts actually using it. Some warnings have been added as a sentinel.
........
r33891 | peres001 | 2008-08-15 05:59:45 +0200 (Fri, 15 Aug 2008) | 1 line
Made scripts access Animation fields via accessors and mutators, instead of using raw pointers.
........
r33892 | peres001 | 2008-08-15 06:30:45 +0200 (Fri, 15 Aug 2008) | 1 line
Made coordinates and frame number protected into Zone and Animation, and changed client code to use get/set. This will allow various simplifications (e.g. when calculating Z), and is a step towards correct handling of interactive zones of Zone/Animation in BRA.
........
r33894 | peres001 | 2008-08-15 10:44:41 +0200 (Fri, 15 Aug 2008) | 1 line
Updated layer calculation: animations are now hidden properly by background elements (but not items yet).
........
r33896 | drmccoy | 2008-08-15 12:47:42 +0200 (Fri, 15 Aug 2008) | 2 lines
Fixing a segfault in the Bargon Attack menu
........
r33900 | peres001 | 2008-08-15 16:25:43 +0200 (Fri, 15 Aug 2008) | 1 line
Added routines to load and handle item masks: animation are now correctly hidden when they are behind any object. The masks of items that are not explicitly activated (even if visible) still are handled (e.g. the crown in the museum is not visible in the foreground).
........
r33902 | anotherguest | 2008-08-15 16:38:25 +0200 (Fri, 15 Aug 2008) | 2 lines
UpdUpdated actions and Readme for Symbian OS port!
........
r33903 | peres001 | 2008-08-15 17:08:08 +0200 (Fri, 15 Aug 2008) | 1 line
Implemented raster operation for masks and postponed blitting of zones after everything in the location has been loaded. This fixes the remaining problems with animations not being masked by items.
........
r33919 | fingolfin | 2008-08-16 00:06:15 +0200 (Sat, 16 Aug 2008) | 1 line
SCUMM: Made some potentially ambiguous (to the reader, at least) checks slightly less ambiguous
........
svn-id: r33920
Diffstat (limited to 'engines/parallaction')
24 files changed, 1120 insertions, 616 deletions
diff --git a/engines/parallaction/balloons.cpp b/engines/parallaction/balloons.cpp index 81b32adb15..222954ec3a 100644 --- a/engines/parallaction/balloons.cpp +++ b/engines/parallaction/balloons.cpp @@ -30,6 +30,183 @@ namespace Parallaction { +class WrappedLineFormatter { + +protected: + Common::String _line; + Font *_font; + uint16 _lines, _lineWidth; + + virtual void setup() = 0; + virtual void action() = 0; + virtual void end() = 0; + virtual Common::String expand(const Common::String &token) { return token; } + + void textAccum(const Common::String &token, uint16 width) { + if (token.empty()) { + return; + } + + _lineWidth += width; + _line += token; + } + + void textNewLine() { + _lines++; + _lineWidth = 0; + _line.clear(); + } + +public: + WrappedLineFormatter(Font *font) : _font(font) { } + virtual ~WrappedLineFormatter() { } + + virtual void calc(const char *text, uint16 maxwidth) { + setup(); + + _lineWidth = 0; + _line.clear(); + _lines = 0; + + Common::StringTokenizer tokenizer(text, " "); + Common::String token; + Common::String blank(" "); + + uint16 blankWidth = _font->getStringWidth(" "); + uint16 tokenWidth = 0; + + while (!tokenizer.empty()) { + token = tokenizer.nextToken(); + token = expand(token); + + if (token == '/') { + tokenWidth = 0; + action(); + textNewLine(); + } else { + // todo: expand '%' + tokenWidth = _font->getStringWidth(token.c_str()); + + if (_lineWidth == 0) { + textAccum(token, tokenWidth); + } else { + if (_lineWidth + blankWidth + tokenWidth <= maxwidth) { + textAccum(blank, blankWidth); + textAccum(token, tokenWidth); + } else { + action(); + textNewLine(); + textAccum(token, tokenWidth); + } + } + } + } + + end(); + } +}; + +class StringExtent_NS : public WrappedLineFormatter { + + uint _width, _height; + +protected: + virtual Common::String expand(const Common::String &token) { + if (token.compareToIgnoreCase("%p") == 0) { + return Common::String("/"); + } + + return token; + } + + virtual void setup() { + _width = _height = 0; + + _line.clear(); + _lines = 0; + _width = 0; + } + + virtual void action() { + if (_lineWidth > _width) { + _width = _lineWidth; + } + _height = _lines * _font->height(); + } + + virtual void end() { + action(); + } + +public: + StringExtent_NS(Font *font) : WrappedLineFormatter(font) { } + + uint width() const { return _width; } + uint height() const { return _height; } +}; + + +class StringWriter_NS : public WrappedLineFormatter { + + uint _width, _height; + byte _color; + + Graphics::Surface *_surf; + +protected: + virtual Common::String expand(const Common::String& token) { + if (token.compareToIgnoreCase("%p") == 0) { + Common::String t("......."); + for (int i = 0; _password[i]; i++) { + t.setChar(_password[i], i); + } + return Common::String("> ") + t; + } else + if (token.compareToIgnoreCase("%s") == 0) { + char buf[20]; + sprintf(buf, "%i", _score); + return Common::String(buf); + } + + return token; + } + + virtual void setup() { + } + + virtual void action() { + if (_line.empty()) { + return; + } + uint16 rx = 10; + uint16 ry = 4 + _lines * _font->height(); // y + + byte *dst = (byte*)_surf->getBasePtr(rx, ry); + _font->setColor(_color); + _font->drawString(dst, _surf->w, _line.c_str()); + } + + virtual void end() { + action(); + } + +public: + StringWriter_NS(Font *font) : WrappedLineFormatter(font) { } + + void write(const char *text, uint maxWidth, byte color, Graphics::Surface *surf) { + StringExtent_NS se(_font); + se.calc(text, maxWidth); + _width = se.width() + 10; + _height = se.height() + 20; + _color = color; + _surf = surf; + + calc(text, maxWidth); + } + +}; + + #define BALLOON_TRANSPARENT_COLOR_NS 2 #define BALLOON_TRANSPARENT_COLOR_BR 0 @@ -78,8 +255,6 @@ class BalloonManager_ns : public BalloonManager { uint _numBalloons; - void getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height); - void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness); Balloon *getBalloon(uint id); @@ -152,12 +327,16 @@ int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w int16 w, h; - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + StringExtent_NS se(_vm->_dialogueFont); + se.calc(text, MAX_BALLOON_WIDTH); + w = se.width() + 14; + h = se.height() + 20; int id = createBalloon(w+5, h, winding, 1); Balloon *balloon = &_intBalloons[id]; - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -172,12 +351,17 @@ int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textC int16 w, h; - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + StringExtent_NS se(_vm->_dialogueFont); + se.calc(text, MAX_BALLOON_WIDTH); + w = se.width() + 14; + h = se.height() + 20; + int id = createBalloon(w+5, h, winding, 1); Balloon *balloon = &_intBalloons[id]; - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -196,7 +380,9 @@ int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textC void BalloonManager_ns::setBalloonText(uint id, char *text, byte textColor) { Balloon *balloon = getBalloon(id); balloon->surface->fillRect(balloon->innerBox, 1); - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); } @@ -204,11 +390,15 @@ int BalloonManager_ns::setLocationBalloon(char *text, bool endGame) { int16 w, h; - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + StringExtent_NS se(_vm->_dialogueFont); + se.calc(text, MAX_BALLOON_WIDTH); + w = se.width() + 14; + h = se.height() + 20; int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR_NS); Balloon *balloon = &_intBalloons[id]; - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH); + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, 0, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -245,106 +435,99 @@ void BalloonManager_ns::freeBalloons() { _numBalloons = 0; } -void BalloonManager_ns::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth) { - uint16 lines = 0; - uint16 linewidth = 0; - uint16 rx = 10; - uint16 ry = 4; - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; - char token[MAX_TOKEN_LEN]; - if (wrapwidth == -1) - wrapwidth = _vm->_screenWidth; - while (strlen(text) > 0) { - text = parseNextToken(text, token, MAX_TOKEN_LEN, " ", true); - if (!scumm_stricmp(token, "%p")) { - lines++; - rx = 10; - ry = 4 + lines*10; // y - strcpy(token, "> ......."); - strncpy(token+2, _password, strlen(_password)); - tokenWidth = font->getStringWidth(token); - } else { - tokenWidth = font->getStringWidth(token); - linewidth += tokenWidth; +class StringExtent_BR : public WrappedLineFormatter { - if (linewidth > wrapwidth) { - // wrap line - lines++; - rx = 10; // x - ry = 4 + lines*10; // y - linewidth = tokenWidth; - } + uint _width, _height; - if (!scumm_stricmp(token, "%s")) { - sprintf(token, "%d", _score); - } +protected: + virtual void setup() { + _width = _height = 0; - } - - _gfx->drawText(font, surf, rx, ry, token, color); + _line.clear(); + _lines = 0; + _width = 0; + } - rx += tokenWidth + blankWidth; - linewidth += blankWidth; + virtual void action() { + if (_lineWidth > _width) { + _width = _lineWidth; + } + _height = _lines * _font->height(); + } - text = Common::ltrim(text); + virtual void end() { + action(); } -} +public: + StringExtent_BR(Font *font) : WrappedLineFormatter(font) { } -void BalloonManager_ns::getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height) { + uint width() const { return _width; } + uint height() const { return _height; } +}; - uint16 lines = 0; - uint16 w = 0; - *width = 0; - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; +class StringWriter_BR : public WrappedLineFormatter { - char token[MAX_TOKEN_LEN]; + uint _width, _height; + byte _color; + uint _x, _y; - while (strlen(text) != 0) { + Graphics::Surface *_surf; - text = parseNextToken(text, token, MAX_TOKEN_LEN, " ", true); - tokenWidth = font->getStringWidth(token); +protected: + StringWriter_BR(Font *font, byte color) : WrappedLineFormatter(font) { - w += tokenWidth; + } - if (!scumm_stricmp(token, "%p")) { - lines++; - } else { - if (w > maxwidth) { - w -= tokenWidth; - lines++; - if (w > *width) - *width = w; + virtual void setup() { + } - w = tokenWidth; - } + virtual void action() { + if (_line.empty()) { + return; } + uint16 rx = _x + (_surf->w - _lineWidth) / 2; + uint16 ry = _y + _lines * _font->height(); // y - w += blankWidth; - text = Common::ltrim(text); + byte *dst = (byte*)_surf->getBasePtr(rx, ry); + _font->setColor(_color); + _font->drawString(dst, _surf->w, _line.c_str()); } - if (*width < w) *width = w; - *width += 10; + virtual void end() { + action(); + } - *height = lines * 10 + 20; +public: + StringWriter_BR(Font *font) : WrappedLineFormatter(font) { } - return; -} + void write(const char *text, uint maxWidth, byte color, Graphics::Surface *surf) { + maxWidth = 216; + + StringExtent_BR se(_font); + se.calc(text, maxWidth); + _width = se.width() + 10; + _height = se.height() + 12; + _color = color; + _surf = surf; + + _x = 0; + _y = (_surf->h - _height) / 2; + calc(text, maxWidth); + } +}; @@ -366,29 +549,12 @@ class BalloonManager_br : public BalloonManager { Frames *_rightBalloon; void cacheAnims(); - void getStringExtent(Font *font, const char *text, uint16 maxwidth, int16* width, int16* height); void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness); Balloon *getBalloon(uint id); Graphics::Surface *expandBalloon(Frames *data, int frameNum); - void textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color); - void textEmitCenteredLine(); - void textAccum(const Common::String &token, uint16 width); - void textNewLine(); - - Common::String _textLine; - Graphics::Surface *_textSurf; - Font *_textFont; - uint16 _textX, _textY; - byte _textColor; - uint16 _textLines, _textWidth; - - void extentSetup(Font *font, int16 *width, int16 *height); - void extentAction(); - - int16 *_extentWidth, *_extentHeight; - + StringWriter_BR _writer; public: BalloonManager_br(Disk *disk, Gfx *gfx); @@ -447,7 +613,7 @@ int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w balloon->surface = expandBalloon(src, srcFrame); src->getRect(srcFrame, balloon->box); - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + _writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -455,8 +621,6 @@ int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w balloon->obj->y = y + balloon->box.top; balloon->obj->transparentKey = BALLOON_TRANSPARENT_COLOR_BR; - printf("balloon (%i, %i)\n", balloon->obj->x, balloon->obj->y); - _numBalloons++; return id; @@ -485,7 +649,7 @@ int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textC balloon->surface = expandBalloon(src, srcFrame); src->getRect(srcFrame, balloon->box); - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + _writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -556,155 +720,9 @@ void BalloonManager_br::cacheAnims() { } -void BalloonManager_br::extentSetup(Font *font, int16 *width, int16 *height) { - _extentWidth = width; - _extentHeight = height; - - _textLine.clear(); - _textLines = 0; - _textWidth = 0; - _textFont = font; -} - -void BalloonManager_br::extentAction() { - if (_textWidth > *_extentWidth) { - *_extentWidth = _textWidth; - } - *_extentHeight = _textLines * _textFont->height(); -} - -void BalloonManager_br::textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color) { - uint16 maxWidth = 216; - - int16 w, h; - getStringExtent(font, text.c_str(), maxWidth, &w, &h); - - w += 10; - h += 12; - - _textLine.clear(); - _textSurf = dest; - _textFont = font; - _textX = 0; - _textY = (_textSurf->h - h) / 2; - _textColor = color; - _textLines = 0; - _textWidth = 0; -} - -void BalloonManager_br::textEmitCenteredLine() { - if (_textLine.empty()) { - return; - } - uint16 rx = _textX + (_textSurf->w - _textWidth) / 2; - uint16 ry = _textY + _textLines * _textFont->height(); // y - _gfx->drawText(_textFont, _textSurf, rx, ry, _textLine.c_str(), _textColor); -} - -void BalloonManager_br::textAccum(const Common::String &token, uint16 width) { - if (token.empty()) { - return; - } - - _textWidth += width; - _textLine += token; -} - -void BalloonManager_br::textNewLine() { - _textLines++; - _textWidth = 0; - _textLine.clear(); -} - - -// TODO: really, base this and getStringExtent on some kind of LineTokenizer, instead of -// repeating the algorithm and changing a couple of lines. -void BalloonManager_br::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapWidth) { - textSetupRendering(text, surf, font, color); - - wrapWidth = 216; - - Common::StringTokenizer tokenizer(text, " "); - Common::String token; - Common::String blank(" "); - - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; - - while (!tokenizer.empty()) { - token = tokenizer.nextToken(); - - if (token == '/') { - tokenWidth = 0; - textEmitCenteredLine(); - textNewLine(); - } else { - // todo: expand '%' - tokenWidth = font->getStringWidth(token.c_str()); - - if (_textWidth == 0) { - textAccum(token, tokenWidth); - } else { - if (_textWidth + blankWidth + tokenWidth <= wrapWidth) { - textAccum(blank, blankWidth); - textAccum(token, tokenWidth); - } else { - textEmitCenteredLine(); - textNewLine(); - textAccum(token, tokenWidth); - } - } - } - } - - textEmitCenteredLine(); -} - - - -void BalloonManager_br::getStringExtent(Font *font, const char *text, uint16 maxwidth, int16* width, int16* height) { - extentSetup(font, width, height); - - Common::StringTokenizer tokenizer(text, " "); - Common::String token; - Common::String blank(" "); - - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; - - while (!tokenizer.empty()) { - token = tokenizer.nextToken(); - - if (token == '/') { - tokenWidth = 0; - extentAction(); - textNewLine(); - } else { - // todo: expand '%' - tokenWidth = font->getStringWidth(token.c_str()); - - if (_textWidth == 0) { - textAccum(token, tokenWidth); - } else { - if (_textWidth + blankWidth + tokenWidth <= maxwidth) { - textAccum(blank, blankWidth); - textAccum(token, tokenWidth); - } else { - extentAction(); - textNewLine(); - textAccum(token, tokenWidth); - } - } - } - } - - extentAction(); -} - - - -BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx), _leftBalloon(0), _rightBalloon(0) { +BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx), + _leftBalloon(0), _rightBalloon(0), _writer(_vm->_dialogueFont) { } BalloonManager_br::~BalloonManager_br() { diff --git a/engines/parallaction/callables_br.cpp b/engines/parallaction/callables_br.cpp index 628ba0c1f1..a4aec8e93e 100644 --- a/engines/parallaction/callables_br.cpp +++ b/engines/parallaction/callables_br.cpp @@ -41,7 +41,7 @@ void Parallaction_br::_c_ferrcycle(void*) { } void Parallaction_br::_c_lipsinc(void*) { - warning("Parallaction_br::_c_lipsinc() not yet implemented"); + warning("Unexpected lipsinc routine call! Please notify the team!"); } void Parallaction_br::_c_albcycle(void*) { diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 761e11dc7d..0f89ca22d1 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -211,21 +211,17 @@ void Parallaction_ns::_c_moveSarc(void *parm) { } } - _introSarcData1 = _introSarcData3 - _moveSarcZone1->_left; - a->_z = _introSarcData3; - a->_frame = _moveSarcZone1->_top - (_introSarcData1 / 20); - _introSarcData3 = _moveSarcZone1->_left; + _introSarcData1 = _introSarcData3 - _moveSarcZone1->getX(); + a->setZ(_introSarcData3); + a->setF(_moveSarcZone1->getY() - (_introSarcData1 / 20)); + _introSarcData3 = _moveSarcZone1->getX(); if (_introSarcData1 > 0) { - a->_left = _introSarcData1 / 2; + a->setX(_introSarcData1 / 2); + a->setY(2); } else { - a->_left = -_introSarcData1 / 2; - } - - if (_introSarcData1 > 0) { - a->_top = 2; - } else { - a->_top = -2; + a->setX(-_introSarcData1 / 2); + a->setY(-2); } return; @@ -236,11 +232,11 @@ void Parallaction_ns::_c_moveSarc(void *parm) { _moveSarcZone1->translate(_introSarcData1, -_introSarcData1 / 20); _moveSarcZone0->translate(_introSarcData1, -_introSarcData1 / 20); - if (_moveSarcZones[0]->_left == 35 && - _moveSarcZones[1]->_left == 68 && - _moveSarcZones[2]->_left == 101 && - _moveSarcZones[3]->_left == 134 && - _moveSarcZones[4]->_left == 167) { + if (_moveSarcZones[0]->getX() == 35 && + _moveSarcZones[1]->getX() == 68 && + _moveSarcZones[2]->getX() == 101 && + _moveSarcZones[3]->getX() == 134 && + _moveSarcZones[4]->getX() == 167) { a = findAnimation("finito"); @@ -261,7 +257,7 @@ void Parallaction_ns::_c_contaFoglie(void *parm) { if (num_foglie != 6) return; - _commandFlags |= 0x1000; + _globalFlags |= 0x1000; return; } @@ -482,8 +478,8 @@ void Parallaction_ns::_c_sketch(void *parm) { Graphics::drawLine(oldx, oldy, newx, newy, 0, zeroMask, &_gfx->_backgroundInfo); - _rightHandAnim->_left = newx; - _rightHandAnim->_top = newy - 20; + _rightHandAnim->setX(newx); + _rightHandAnim->setY(newy - 20); index++; @@ -496,10 +492,10 @@ void Parallaction_ns::_c_sketch(void *parm) { void Parallaction_ns::_c_shade(void *parm) { Common::Rect r( - _rightHandAnim->_left - 36, - _rightHandAnim->_top - 36, - _rightHandAnim->_left, - _rightHandAnim->_top + _rightHandAnim->getX() - 36, + _rightHandAnim->getY() - 36, + _rightHandAnim->getX(), + _rightHandAnim->getY() ); uint16 _di = r.left/4 + r.top * _gfx->_backgroundInfo->mask.internalWidth; diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp index f57976594e..0ff38913f7 100644 --- a/engines/parallaction/debug.cpp +++ b/engines/parallaction/debug.cpp @@ -101,14 +101,14 @@ bool Debugger::Cmd_Locations(int argc, const char **argv) { bool Debugger::Cmd_GlobalFlags(int argc, const char **argv) { - uint32 flags = _commandFlags; + uint32 flags = _globalFlags; DebugPrintf("+------------------------------+---------+\n" "| flag name | value |\n" "+------------------------------+---------+\n"); - for (uint i = 0; i < _vm->_globalTable->count(); i++) { + for (uint i = 0; i < _vm->_globalFlagsNames->count(); i++) { const char *value = ((flags & (1 << i)) == 0) ? "OFF" : "ON"; - DebugPrintf("|%-30s| %-6s|\n", _vm->_globalTable->item(i), value); + DebugPrintf("|%-30s| %-6s|\n", _vm->_globalFlagsNames->item(i), value); } DebugPrintf("+------------------------------+---------+\n"); @@ -157,7 +157,7 @@ bool Debugger::Cmd_Zones(int argc, const char **argv) { "+--------------------+---+---+---+---+--------+--------+\n"); for ( ; b != e; b++) { ZonePtr z = *b; - DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, z->_left, z->_top, z->_right, z->_bottom, z->_type, z->_flags ); + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, z->getX(), z->getY(), z->getX() + z->width(), z->getY() + z->height(), z->_type, z->_flags ); } DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); @@ -175,7 +175,7 @@ bool Debugger::Cmd_Animations(int argc, const char **argv) { "+--------------------+---+---+---+---+--------+--------+\n"); for ( ; b != e; b++) { AnimationPtr a = *b; - DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", a->_name, a->_left, a->_top, a->_z, a->_frame, a->_type, a->_flags ); + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", a->_name, a->getX(), a->getY(), a->getZ(), a->getF(), a->_type, a->_flags ); } DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); @@ -187,19 +187,19 @@ bool Debugger::Cmd_GfxObjects(int argc, const char **argv) { const char *objType[] = { "DOOR", "GET", "ANIM" }; - DebugPrintf("+--------------------+-----+-----+-----+-----+--------+--------+\n" - "| name | x | y | z | f | type | visi |\n" - "+--------------------+-----+-----+-----+-----+--------+--------+\n"); + DebugPrintf("+--------------------+-----+-----+-----+-------+-----+--------+--------+\n" + "| name | x | y | z | layer | f | type | visi |\n" + "+--------------------+-----+-----+-----+-------+-----+--------+--------+\n"); GfxObjList::iterator b = _vm->_gfx->_gfxobjList.begin(); GfxObjList::iterator e = _vm->_gfx->_gfxobjList.end(); for ( ; b != e; b++) { GfxObj *obj = *b; - DebugPrintf("|%-20s|%5i|%5i|%5i|%5i|%8s|%8x|\n", obj->getName(), obj->x, obj->y, obj->z, obj->frame, objType[obj->type], obj->isVisible() ); + DebugPrintf("|%-20s|%5i|%5i|%5i|%7i|%5i|%8s|%8x|\n", obj->getName(), obj->x, obj->y, obj->z, obj->layer, obj->frame, objType[obj->type], obj->isVisible() ); } - DebugPrintf("+--------------------+-----+-----+-----+-----+--------+--------+\n"); + DebugPrintf("+--------------------+-----+-----+-----+-------+-----+--------+--------+\n"); return true; } diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index 21584a0525..205d702aa0 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -168,7 +168,7 @@ bool DialogueManager::displayAnswer(uint16 i) { uint32 flags = _vm->getLocationFlags(); if (a->_yesFlags & kFlagsGlobal) - flags = _commandFlags | kFlagsGlobal; + flags = _globalFlags | kFlagsGlobal; // display suitable answers if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) { diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h index 341229a649..2923f239d4 100644 --- a/engines/parallaction/disk.h +++ b/engines/parallaction/disk.h @@ -69,6 +69,7 @@ public: virtual Table* loadTable(const char* name) = 0; virtual Common::SeekableReadStream* loadMusic(const char* name) = 0; virtual Common::ReadStream* loadSound(const char* name) = 0; + virtual void loadMask(const char *name, MaskBuffer &buffer) { } }; @@ -248,6 +249,7 @@ public: Table* loadTable(const char* name); Common::SeekableReadStream* loadMusic(const char* name); Common::ReadStream* loadSound(const char* name); + void loadMask(const char *name, MaskBuffer &buffer); }; class DosDemo_br : public DosDisk_br { diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp index cd57ec8822..f52567bea2 100644 --- a/engines/parallaction/disk_br.cpp +++ b/engines/parallaction/disk_br.cpp @@ -357,6 +357,29 @@ void DosDisk_br::loadSlide(BackgroundInfo& info, const char *name) { return; } +void DosDisk_br::loadMask(const char *name, MaskBuffer &buffer) { + if (!name) { + return; + } + + Common::String filepath; + FilesystemNode node; + Common::File stream; + + filepath = Common::String(name) + ".msk"; + node = _mskDir.getChild(filepath); + if (!node.exists()) { + errorFileNotFound(_mskDir, filepath); + } + stream.open(node); + + // NOTE: info.width and info.height are only valid if the background graphics + // have already been loaded + buffer.bigEndian = false; + stream.read(buffer.data, buffer.size); + stream.close(); +} + void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char *mask, const char* path) { debugC(5, kDebugDisk, "DosDisk_br::loadScenery"); @@ -733,8 +756,6 @@ Font* AmigaDisk_br::loadFont(const char* name) { while ((ch = stream.readByte()) != 0) fontFile += ch; stream.close(); - printf("fontDir = %s, fontFile = %s\n", fontDir.c_str(), fontFile.c_str()); - node = _fntDir.getChild(fontDir); if (!node.exists()) { errorFileNotFound(_fntDir, fontDir); diff --git a/engines/parallaction/exec.h b/engines/parallaction/exec.h index 22e75744f1..4239857ec0 100644 --- a/engines/parallaction/exec.h +++ b/engines/parallaction/exec.h @@ -84,8 +84,6 @@ class CommandExec_ns : public CommandExec { Parallaction_ns *_vm; protected: - void updateGetZone(ZonePtr z, bool visible); - DECLARE_UNQUALIFIED_COMMAND_OPCODE(invalid); DECLARE_UNQUALIFIED_COMMAND_OPCODE(set); DECLARE_UNQUALIFIED_COMMAND_OPCODE(clear); diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index 0b7400f0f7..fe7b1b2903 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -97,8 +97,9 @@ void Parallaction_br::setupSubtitles(char *s, char *s2, int y) { } else { _subtitle[1] = -1; } - +#if 0 // disabled because no references to lip sync has been found in the scripts _subtitleLipSync = 0; +#endif } void Parallaction_br::clearSubtitles() { @@ -122,48 +123,23 @@ DECLARE_COMMAND_OPCODE(location) { DECLARE_COMMAND_OPCODE(open) { warning("Parallaction_br::cmdOp_open command not yet implemented"); - _ctxt.cmd->u._zone->_flags &= ~kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, false); } DECLARE_COMMAND_OPCODE(close) { warning("Parallaction_br::cmdOp_close not yet implemented"); - _ctxt.cmd->u._zone->_flags |= kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, true); } DECLARE_COMMAND_OPCODE(on) { - CommandData *data = &_ctxt.cmd->u; - ZonePtr z = data->_zone; - - if (z) { - z->_flags |= kFlagsActive; - z->_flags &= ~kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, true); - } - } + _vm->showZone(_ctxt.cmd->u._zone, true); } DECLARE_COMMAND_OPCODE(off) { - CommandData *data = &_ctxt.cmd->u; - ZonePtr z = data->_zone; - - if (z) { - z->_flags |= kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, false); - } - } + _vm->showZone(_ctxt.cmd->u._zone, false); } @@ -335,42 +311,18 @@ DECLARE_COMMAND_OPCODE(offsave) { DECLARE_INSTRUCTION_OPCODE(on) { - InstructionPtr inst = *_ctxt.inst; - ZonePtr z = inst->_z; - - if (z) { - z->_flags |= kFlagsActive; - z->_flags &= ~kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, true); - } - } + _vm->showZone((*_ctxt.inst)->_z, true); } DECLARE_INSTRUCTION_OPCODE(off) { - InstructionPtr inst = *_ctxt.inst; - ZonePtr z = inst->_z; - - if (z) { - z->_flags |= kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, false); - } - } + _vm->showZone((*_ctxt.inst)->_z, false); } DECLARE_INSTRUCTION_OPCODE(set) { InstructionPtr inst = *_ctxt.inst; - - int16 rvalue = inst->_opB.getRValue(); - int16* lvalue = inst->_opA.getLValue(); - - *lvalue = rvalue; - + inst->_opA.setValue(inst->_opB.getValue()); } @@ -378,7 +330,7 @@ DECLARE_INSTRUCTION_OPCODE(set) { DECLARE_INSTRUCTION_OPCODE(inc) { InstructionPtr inst = *_ctxt.inst; - int16 rvalue = inst->_opB.getRValue(); + int16 rvalue = inst->_opB.getValue(); if (inst->_flags & kInstMod) { // mod int16 _bx = (rvalue > 0 ? rvalue : -rvalue); @@ -387,32 +339,30 @@ DECLARE_INSTRUCTION_OPCODE(inc) { rvalue = (rvalue > 0 ? 1 : -1); } - int16 *lvalue = inst->_opA.getLValue(); + int16 lvalue = inst->_opA.getValue(); switch (inst->_index) { case INST_INC: - *lvalue += rvalue; + lvalue += rvalue; break; case INST_DEC: - *lvalue -= rvalue; + lvalue -= rvalue; break; case INST_MUL: - *lvalue *= rvalue; + lvalue *= rvalue; break; case INST_DIV: - *lvalue /= rvalue; + lvalue /= rvalue; break; default: error("This should never happen. Report immediately"); } - if (inst->_opA._flags & kParaLocal) { - inst->_opA._local->wrap(); - } + inst->_opA.setValue(lvalue); } @@ -445,11 +395,7 @@ DECLARE_INSTRUCTION_OPCODE(move) { DECLARE_INSTRUCTION_OPCODE(color) { InstructionPtr inst = *_ctxt.inst; - - int16 entry = inst->_opB.getRValue(); - - _vm->_gfx->_palette.setEntry(entry, inst->_colors[0], inst->_colors[1], inst->_colors[2]); - + _vm->_gfx->_palette.setEntry(inst->_opB.getValue(), inst->_colors[0], inst->_colors[1], inst->_colors[2]); } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 99a492863b..4ea7d601e0 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -80,7 +80,7 @@ DECLARE_INSTRUCTION_OPCODE(off) { DECLARE_INSTRUCTION_OPCODE(loop) { InstructionPtr inst = *_ctxt.inst; - _ctxt.program->_loopCounter = inst->_opB.getRValue(); + _ctxt.program->_loopCounter = inst->_opB.getValue(); _ctxt.program->_loopStart = _ctxt.ip; } @@ -93,7 +93,7 @@ DECLARE_INSTRUCTION_OPCODE(endloop) { DECLARE_INSTRUCTION_OPCODE(inc) { InstructionPtr inst = *_ctxt.inst; - int16 _si = inst->_opB.getRValue(); + int16 _si = inst->_opB.getValue(); if (inst->_flags & kInstMod) { // mod int16 _bx = (_si > 0 ? _si : -_si); @@ -102,29 +102,22 @@ DECLARE_INSTRUCTION_OPCODE(inc) { _si = (_si > 0 ? 1 : -1); } - int16* lvalue = inst->_opA.getLValue(); + int16 lvalue = inst->_opA.getValue(); if (inst->_index == INST_INC) { - *lvalue += _si; + lvalue += _si; } else { - *lvalue -= _si; + lvalue -= _si; } - if (inst->_opA._flags & kParaLocal) { - inst->_opA._local->wrap(); - } + inst->_opA.setValue(lvalue); } DECLARE_INSTRUCTION_OPCODE(set) { InstructionPtr inst = *_ctxt.inst; - - int16 _si = inst->_opB.getRValue(); - int16 *lvalue = inst->_opA.getLValue(); - - *lvalue = _si; - + inst->_opA.setValue(inst->_opB.getValue()); } @@ -133,10 +126,10 @@ DECLARE_INSTRUCTION_OPCODE(put) { Graphics::Surface v18; v18.w = inst->_a->width(); v18.h = inst->_a->height(); - v18.pixels = inst->_a->getFrameData(inst->_a->_frame); + v18.pixels = inst->_a->getFrameData(inst->_a->getF()); - int16 x = inst->_opA.getRValue(); - int16 y = inst->_opB.getRValue(); + int16 x = inst->_opA.getValue(); + int16 y = inst->_opB.getValue(); bool mask = (inst->_flags & kInstMaskedPut) == kInstMaskedPut; _vm->_gfx->patchBackground(v18, x, y, mask); @@ -176,8 +169,8 @@ DECLARE_INSTRUCTION_OPCODE(sound) { DECLARE_INSTRUCTION_OPCODE(move) { InstructionPtr inst = (*_ctxt.inst); - int16 x = inst->_opA.getRValue(); - int16 y = inst->_opB.getRValue(); + int16 x = inst->_opA.getValue(); + int16 y = inst->_opB.getValue(); _vm->_char.scheduleWalk(x, y); } @@ -203,7 +196,7 @@ DECLARE_COMMAND_OPCODE(invalid) { DECLARE_COMMAND_OPCODE(set) { if (_ctxt.cmd->u._flags & kFlagsGlobal) { _ctxt.cmd->u._flags &= ~kFlagsGlobal; - _commandFlags |= _ctxt.cmd->u._flags; + _globalFlags |= _ctxt.cmd->u._flags; } else { _vm->setLocationFlags(_ctxt.cmd->u._flags); } @@ -213,7 +206,7 @@ DECLARE_COMMAND_OPCODE(set) { DECLARE_COMMAND_OPCODE(clear) { if (_ctxt.cmd->u._flags & kFlagsGlobal) { _ctxt.cmd->u._flags &= ~kFlagsGlobal; - _commandFlags &= ~_ctxt.cmd->u._flags; + _globalFlags &= ~_ctxt.cmd->u._flags; } else { _vm->clearLocationFlags(_ctxt.cmd->u._flags); } @@ -246,48 +239,47 @@ DECLARE_COMMAND_OPCODE(location) { DECLARE_COMMAND_OPCODE(open) { - _ctxt.cmd->u._zone->_flags &= ~kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, false); } DECLARE_COMMAND_OPCODE(close) { - _ctxt.cmd->u._zone->_flags |= kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, true); } -void CommandExec_ns::updateGetZone(ZonePtr z, bool visible) { +void Parallaction::showZone(ZonePtr z, bool visible) { if (!z) { return; } + if (visible) { + z->_flags &= ~kFlagsRemove; + z->_flags |= kFlagsActive; + } else { + z->_flags |= kFlagsRemove; + } + if ((z->_type & 0xFFFF) == kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, visible); + _gfx->showGfxObj(z->u.get->gfxobj, visible); + + GetData *data = z->u.get; + if (data->hasMask && _gfx->_backgroundInfo->hasMask) { + if (visible) { + _gfx->_backgroundInfo->mask.bltOr(data->gfxobj->x, data->gfxobj->y, data->_mask[0], 0, 0, data->_mask->w, data->_mask->h); + } else { + _gfx->_backgroundInfo->mask.bltCopy(data->gfxobj->x, data->gfxobj->y, data->_mask[1], 0, 0, data->_mask->w, data->_mask->h); + } + } } } DECLARE_COMMAND_OPCODE(on) { - ZonePtr z = _ctxt.cmd->u._zone; - - if (z) { - z->_flags &= ~kFlagsRemove; - z->_flags |= kFlagsActive; - updateGetZone(z, true); - } + _vm->showZone(_ctxt.cmd->u._zone, true); } DECLARE_COMMAND_OPCODE(off) { - ZonePtr z = _ctxt.cmd->u._zone; - - if (z) { - _ctxt.cmd->u._zone->_flags |= kFlagsRemove; - updateGetZone(z, false); - } + _vm->showZone(_ctxt.cmd->u._zone, false); } @@ -299,7 +291,7 @@ DECLARE_COMMAND_OPCODE(call) { DECLARE_COMMAND_OPCODE(toggle) { if (_ctxt.cmd->u._flags & kFlagsGlobal) { _ctxt.cmd->u._flags &= ~kFlagsGlobal; - _commandFlags ^= _ctxt.cmd->u._flags; + _globalFlags ^= _ctxt.cmd->u._flags; } else { _vm->toggleLocationFlags(_ctxt.cmd->u._flags); } @@ -345,23 +337,31 @@ void Parallaction_ns::drawAnimations() { if ((anim->_flags & kFlagsActive) && ((anim->_flags & kFlagsRemove) == 0)) { if (anim->_flags & kFlagsNoMasked) - layer = 3; - else - layer = _gfx->_backgroundInfo->getLayer(anim->_top + anim->height()); + layer = LAYER_FOREGROUND; + else { + if (getGameType() == GType_Nippon) { + // Layer in NS depends on where the animation is on the screen, for each animation. + layer = _gfx->_backgroundInfo->getLayer(anim->getFrameY() + anim->height()); + } else { + // Layer in BRA is calculated from Z value. For characters it is the same as NS, + // but other animations can have Z set from scripts independently from their + // position on the screen. + layer = _gfx->_backgroundInfo->getLayer(anim->getZ()); + } + } if (obj) { _gfx->showGfxObj(obj, true); - obj->frame = anim->_frame; - obj->x = anim->_left; - obj->y = anim->_top; - obj->z = anim->_z; + obj->frame = anim->getF(); + obj->x = anim->getX(); + obj->y = anim->getY(); + obj->z = anim->getZ(); obj->layer = layer; } } if (((anim->_flags & kFlagsActive) == 0) && (anim->_flags & kFlagsRemove)) { anim->_flags &= ~kFlagsRemove; - anim->_oldPos.x = -1000; } if ((anim->_flags & kFlagsActive) && (anim->_flags & kFlagsRemove)) { @@ -418,7 +418,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator AnimationPtr a = (*it)->_anim; if (a->_flags & kFlagsCharacter) - a->_z = a->_top + a->height(); + a->setZ(a->getFrameY() + a->height()); if ((a->_flags & kFlagsActing) == 0) continue; @@ -426,7 +426,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator runScript(*it, a); if (a->_flags & kFlagsCharacter) - a->_z = a->_top + a->height(); + a->setZ(a->getFrameY() + a->height()); } _modCounter++; @@ -448,7 +448,7 @@ void CommandExec::runList(CommandList::iterator first, CommandList::iterator las CommandPtr cmd = *first; if (cmd->_flagsOn & kFlagsGlobal) { - useFlags = _commandFlags | kFlagsGlobal; + useFlags = _globalFlags | kFlagsGlobal; useLocalFlags = false; } else { useFlags = _vm->getLocationFlags(); @@ -601,7 +601,7 @@ void Parallaction::runCommentFrame() { } -uint16 Parallaction::runZone(ZonePtr z) { +void Parallaction::runZone(ZonePtr z) { debugC(3, kDebugExec, "runZone (%s)", z->_name); uint16 subtype = z->_type & 0xFFFF; @@ -611,20 +611,15 @@ uint16 Parallaction::runZone(ZonePtr z) { case kZoneExamine: enterCommentMode(z); - return 0; + return; case kZoneGet: - if (z->_flags & kFlagsFixed) break; - if (pickupItem(z) != 0) { - return 1; - } - z->_flags |= kFlagsRemove; + pickupItem(z); break; case kZoneDoor: if (z->_flags & kFlagsLocked) break; - z->_flags ^= kFlagsClosed; - updateDoor(z); + updateDoor(z, !(z->_flags & kFlagsClosed)); break; case kZoneHear: @@ -633,23 +628,24 @@ uint16 Parallaction::runZone(ZonePtr z) { case kZoneSpeak: enterDialogueMode(z); - return 0; + return; } debugC(3, kDebugExec, "runZone completed"); _cmdExec->run(z->_commands, z); - return 0; + return; } // // ZONE TYPE: DOOR // -void Parallaction::updateDoor(ZonePtr z) { +void Parallaction::updateDoor(ZonePtr z, bool close) { + z->_flags = close ? (z->_flags |= kFlagsClosed) : (z->_flags &= ~kFlagsClosed); if (z->u.door->gfxobj) { - uint frame = (z->_flags & kFlagsClosed ? 0 : 1); + uint frame = (close ? 0 : 1); // z->u.door->gfxobj->setFrame(frame); z->u.door->gfxobj->frame = frame; } @@ -663,13 +659,17 @@ void Parallaction::updateDoor(ZonePtr z) { // ZONE TYPE: GET // -int16 Parallaction::pickupItem(ZonePtr z) { - int r = addInventoryItem(z->u.get->_icon); - if (r != -1) { - _gfx->showGfxObj(z->u.get->gfxobj, false); +bool Parallaction::pickupItem(ZonePtr z) { + if (z->_flags & kFlagsFixed) { + return false; + } + + int slot = addInventoryItem(z->u.get->_icon); + if (slot != -1) { + showZone(z, false); } - return (r == -1); + return (slot != -1); } @@ -688,7 +688,7 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { if (z->_flags & kFlagsRemove) continue; Common::Rect r; - z->getRect(r); + z->getBox(r); r.right++; // adjust border because Common::Rect doesn't include bottom-right edge r.bottom++; @@ -697,7 +697,7 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { if (!r.contains(_si, _di)) { // out of Zone, so look for special values - if ((z->_left == -2) || (z->_left == -3)) { + if ((z->getX() == -2) || (z->getX() == -3)) { // WORKAROUND: this huge condition is needed because we made TypeData a collection of structs // instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine, @@ -716,15 +716,15 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { } } - if (z->_left != -1) + if (z->getX() != -1) continue; - if (_si < _char._ani->_left) + if (_si < _char._ani->getFrameX()) continue; - if (_si > (_char._ani->_left + _char._ani->width())) + if (_si > (_char._ani->getFrameX() + _char._ani->width())) continue; - if (_di < _char._ani->_top) + if (_di < _char._ani->getFrameY()) continue; - if (_di > (_char._ani->_top + _char._ani->height())) + if (_di > (_char._ani->getFrameY() + _char._ani->height())) continue; } @@ -746,8 +746,8 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { AnimationPtr a = *ait; _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation - _e = ((_si >= a->_left + a->width()) || (_si <= a->_left)) ? 0 : 1; // _e: horizontal range - _f = ((_di >= a->_top + a->height()) || (_di <= a->_top)) ? 0 : 1; // _f: vertical range + _e = ((_si >= a->getFrameX() + a->width()) || (_si <= a->getFrameX())) ? 0 : 1; // _e: horizontal range + _f = ((_di >= a->getFrameY() + a->height()) || (_di <= a->getFrameY())) ? 0 : 1; // _f: vertical range _b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character) _c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index c19d6ae5e5..1c2cb58b5b 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -377,6 +377,12 @@ void Gfx::beginFrame() { *data++ = _backgroundInfo->mask.getValue(x, y); } } +#if 1 + Common::DumpFile dump; + dump.open("maskdump.bin"); + dump.write(_bitmapMask.pixels, _bitmapMask.w * _bitmapMask.h); + dump.close(); +#endif break; } } @@ -441,7 +447,7 @@ void Gfx::updateScreen() { for (; b != e; b++) { ZonePtr z = *b; if (z->_type & kZonePath) { - surf->frameRect(Common::Rect(z->_left, z->_top, z->_right, z->_bottom), 2); + surf->frameRect(Common::Rect(z->getX(), z->getY(), z->getX() + z->width(), z->getY() + z->height()), 2); } } g_system->unlockScreen(); diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 23b4569c6a..471f71dfa8 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -209,6 +209,42 @@ public: return (m >> n) & 3; } + inline byte* getPtr(uint16 x, uint16 y) const { + return data + (x >> 2) + y * internalWidth; + } + + void bltOr(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { + assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); + + byte *s = src.getPtr(sx, sy); + byte *d = getPtr(dx, dy); + + // this code assumes buffers are aligned on 4-pixels boundaries, as the original does + uint16 linewidth = width >> 2; + for (uint16 i = 0; i < height; i++) { + for (uint16 j = 0; j < linewidth; j++) { + *d++ |= *s++; + } + d += internalWidth - linewidth; + s += src.internalWidth - linewidth; + } + } + + void bltCopy(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { + assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); + + byte *s = src.getPtr(sx, sy); + byte *d = getPtr(dx, dy); + + // this code assumes buffers are aligned on 4-pixels boundaries, as the original does + for (uint16 i = 0; i < height; i++) { + memcpy(d, s, (width >> 2)); + d += internalWidth; + s += src.internalWidth; + } + } + + }; @@ -419,7 +455,9 @@ struct BackgroundInfo { int layers[4]; PaletteFxRange ranges[6]; - BackgroundInfo() : x(0), y(0), width(0), height(0) { + bool hasMask; + + BackgroundInfo() : x(0), y(0), width(0), height(0), hasMask(false) { layers[0] = layers[1] = layers[2] = layers[3] = 0; memset(ranges, 0, sizeof(ranges)); } diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index c387484de7..d2332643ed 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -71,6 +71,20 @@ uint16 Animation::height() const { return r.height(); } +int16 Animation::getFrameX() const { + if (!gfxobj) return _left; + Common::Rect r; + gfxobj->getRect(_frame, r); + return r.left + _left; +} + +int16 Animation::getFrameY() const { + if (!gfxobj) return _top; + Common::Rect r; + gfxobj->getRect(_frame, r); + return r.top + _top; +} + uint16 Animation::getFrameNum() const { if (!gfxobj) return 0; return gfxobj->getNum(); @@ -115,24 +129,29 @@ int16 Program::addLocal(const char *name, int16 value, int16 min, int16 max) { assert(_numLocals < NUM_LOCALS); strcpy(_localNames[_numLocals], name); - _locals[_numLocals]._value = value; - - _locals[_numLocals]._min = min; - _locals[_numLocals]._max = max; + _locals[_numLocals].setRange(min, max); + _locals[_numLocals].setValue(value); return _numLocals++; } -void LocalVariable::wrap() { +void LocalVariable::setValue(int16 value) { + if (value >= _max) + value = _min; + if (value < _min) + value = _max - 1; - if (_value >= _max) - _value = _min; - if (_value < _min) - _value = _max - 1; + _value = value; +} - return; +void LocalVariable::setRange(int16 min, int16 max) { + _max = max; + _min = min; } +int16 LocalVariable::getValue() const { + return _value; +} Zone::Zone() { @@ -193,13 +212,6 @@ Zone::~Zone() { free(_linkedName); } -void Zone::getRect(Common::Rect& r) const { - r.left = _left; - r.right = _right; - r.top = _top; - r.bottom = _bottom; -} - void Zone::translate(int16 x, int16 y) { _left += x; _right += x; @@ -273,18 +285,18 @@ Instruction::~Instruction() { free(_text2); } -int16 ScriptVar::getRValue() { +int16 ScriptVar::getValue() { if (_flags & kParaImmediate) { return _value; } if (_flags & kParaLocal) { - return _local->_value; + return _local->getValue(); } if (_flags & kParaField) { - return *_pvalue; + return _field->getValue(); } if (_flags & kParaRandom) { @@ -296,27 +308,33 @@ int16 ScriptVar::getRValue() { return 0; } -int16* ScriptVar::getLValue() { +void ScriptVar::setValue(int16 value) { + if ((_flags & kParaLValue) == 0) { + error("Only l-value can be set"); + } if (_flags & kParaLocal) { - return &_local->_value; + _local->setValue(value); } if (_flags & kParaField) { - return _pvalue; + _field->setValue(value); } - error("Parameter is not an l-value"); - } void ScriptVar::setLocal(LocalVariable *local) { _local = local; - _flags |= kParaLocal; + _flags |= (kParaLocal | kParaLValue); } -void ScriptVar::setField(int16 *field) { - _pvalue = field; +void ScriptVar::setField(Animation *anim, AnimationField::AccessorFunc accessor, AnimationField::MutatorFunc mutator) { + _field = new AnimationField(anim, accessor, mutator); + _flags |= (kParaField | kParaLValue); +} + +void ScriptVar::setField(Animation *anim, AnimationField::AccessorFunc accessor) { + _field = new AnimationField(anim, accessor); _flags |= kParaField; } @@ -335,9 +353,14 @@ ScriptVar::ScriptVar() { _flags = 0; _local = 0; _value = 0; - _pvalue = 0; + _field = 0; } +ScriptVar::~ScriptVar() { + delete _field; +} + + Table::Table(uint32 size) : _size(size), _used(0), _disposeMemory(true) { _data = (char**)calloc(size, sizeof(char*)); } diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index a3bf757bdb..15550c65c6 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -198,11 +198,14 @@ struct GetData { // size = 24 byte *_backup; uint16 field_14; // unused uint16 field_16; // unused + MaskBuffer _mask[2]; + bool hasMask; GetData() { _icon = 0; _backup = NULL; gfxobj = NULL; + hasMask = false; } }; struct SpeakData { // size = 36 @@ -297,17 +300,19 @@ struct TypeData { #define ZONENAME_LENGTH 32 struct Zone { - char _name[ZONENAME_LENGTH]; - +protected: int16 _left; int16 _top; int16 _right; int16 _bottom; + +public: + char _name[ZONENAME_LENGTH]; + uint32 _type; uint32 _flags; uint _label; - uint16 field_2C; // unused - uint16 field_2E; // unused + TypeData u; CommandList _commands; Common::Point _moveTo; @@ -320,32 +325,101 @@ struct Zone { Zone(); virtual ~Zone(); - void getRect(Common::Rect& r) const; void translate(int16 x, int16 y); virtual uint16 width() const; virtual uint16 height() const; + + void setBox(int16 left, int16 top, int16 right, int16 bottom) { + setX(left); + setY(top); + _right = right; + _bottom = bottom; + } + + void getBox(Common::Rect& r) { + r.left = getX(); + r.right = getX() + width(); + r.top = getY(); + r.bottom = getY() + height(); + } + + + // getters/setters + virtual int16 getX() { return _left; } + virtual void setX(int16 value) { _left = value; } + + virtual int16 getY() { return _top; } + virtual void setY(int16 value) { _top = value; } }; struct LocalVariable { +protected: int16 _value; int16 _min; int16 _max; +public: + LocalVariable() { _value = 0; _min = -10000; _max = 10000; } - void wrap(); + void setRange(int16 min, int16 max); + + int16 getValue() const; + void setValue(int16 value); }; + enum ParaFlags { kParaImmediate = 1, // instruction is using an immediate parameter kParaLocal = 2, // instruction is using a local variable kParaField = 0x10, // instruction is using an animation's field - kParaRandom = 0x100 + kParaRandom = 0x100, + + kParaLValue = 0x20 +}; + + +struct AnimationField { + typedef Common::Functor0Mem<int16, Animation> Accessor; + typedef Common::Functor1Mem<int16, void, Animation> Mutator; + + typedef Accessor::FuncType AccessorFunc; + typedef Mutator::FuncType MutatorFunc; + +protected: + Accessor *_accessor; + Mutator *_mutator; + +public: + AnimationField(Animation* instance, AccessorFunc accessor, MutatorFunc mutator) { + _accessor = new Accessor(instance, accessor); + _mutator = new Mutator(instance, mutator); + } + + AnimationField(Animation* instance, AccessorFunc accessor) { + _accessor = new Accessor(instance, accessor); + _mutator = 0; + } + + ~AnimationField() { + delete _accessor; + delete _mutator; + } + + int16 getValue() const { + assert(_accessor); + return _accessor->operator()(); + } + + void setValue(int16 value) { + assert(_mutator); + _mutator->operator()(value); + } }; @@ -353,16 +427,18 @@ struct ScriptVar { uint32 _flags; int16 _value; - int16* _pvalue; LocalVariable* _local; + AnimationField* _field; ScriptVar(); + ~ScriptVar(); - int16 getRValue(); - int16* getLValue(); + int16 getValue(); + void setValue(int16 value); void setLocal(LocalVariable *local); - void setField(int16 *field); + void setField(Animation *anim, AnimationField::AccessorFunc accessor, AnimationField::MutatorFunc mutator); + void setField(Animation *anim, AnimationField::AccessorFunc accessor); void setImmediate(int16 value); void setRandom(int16 seed); }; @@ -430,19 +506,13 @@ typedef Common::SharedPtr<Program> ProgramPtr; typedef Common::List<ProgramPtr> ProgramList; struct Animation : public Zone { +protected: + int16 _frame; + int16 _z; +public: - Common::Point _oldPos; GfxObj *gfxobj; char *_scriptName; - int16 _frame; - uint16 field_50; // unused - int16 _z; - uint16 field_54; // unused - uint16 field_56; // unused - uint16 field_58; // unused - uint16 field_5A; // unused - uint16 field_5C; // unused - uint16 field_5E; // unused Animation(); virtual ~Animation(); @@ -452,6 +522,22 @@ struct Animation : public Zone { byte* getFrameData(uint32 index) const; void validateScriptVars(); + + int16 getFrameX() const; + int16 getFrameY() const; + + // getters/setters used by scripts + int16 getX() { return _left; } + void setX(int16 value) { _left = value; } + + int16 getY() { return _top; } + void setY(int16 value) { _top = value; } + + int16 getZ() { return _z; } + void setZ(int16 value) { _z = value; } + + int16 getF() { return _frame; } + void setF(int16 value) { _frame = value; } }; class Table { diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index bb306c3299..c810d22b33 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -53,7 +53,7 @@ uint32 _engineFlags = 0; uint16 _score = 1; char _password[8]; -uint32 _commandFlags = 0; +uint32 _globalFlags = 0; // private stuff @@ -85,7 +85,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam Parallaction::~Parallaction() { delete _debugger; - delete _globalTable; + delete _globalFlagsNames; delete _callableNames; delete _cmdExec; delete _programExec; @@ -114,7 +114,7 @@ int Parallaction::init() { _engineFlags = 0; _objectsNames = NULL; - _globalTable = NULL; + _globalFlagsNames = NULL; _location._hasSound = false; _baseTime = 0; _numLocations = 0; @@ -352,9 +352,9 @@ void Parallaction::runGame() { if (_input->_inputMode == Input::kInputModeGame) { _programExec->runScripts(_location._programs.begin(), _location._programs.end()); - _char._ani->_z = _char._ani->height() + _char._ani->_top; + _char._ani->setZ(_char._ani->height() + _char._ani->getFrameY()); if (_char._ani->gfxobj) { - _char._ani->gfxobj->z = _char._ani->_z; + _char._ani->gfxobj->z = _char._ani->getZ(); } _char._walker->walk(); drawAnimations(); @@ -452,7 +452,7 @@ void Parallaction::freeZones() { // NOTE : this condition has been relaxed compared to the original, to allow the engine // to retain special - needed - zones that were lost across location switches. ZonePtr z = *it; - if (((z->_top == -1) || (z->_left == -2)) && ((_engineFlags & kEngineQuit) == 0)) { + if (((z->getY() == -1) || (z->getX() == -2)) && ((_engineFlags & kEngineQuit) == 0)) { debugC(2, kDebugExec, "freeZones preserving zone '%s'", z->_name); it++; } else { @@ -510,12 +510,10 @@ Character::Character(Parallaction *vm) : _vm(vm), _ani(new Animation) { _dummy = false; - _ani->_left = 150; - _ani->_top = 100; - _ani->_z = 10; - _ani->_oldPos.x = -1000; - _ani->_oldPos.y = -1000; - _ani->_frame = 0; + _ani->setX(150); + _ani->setY(100); + _ani->setZ(10); + _ani->setF(0); _ani->_flags = kFlagsActive | kFlagsNoName; _ani->_type = kZoneYou; strncpy(_ani->_name, "yourself", ZONENAME_LENGTH); @@ -542,18 +540,18 @@ Character::~Character() { void Character::getFoot(Common::Point &foot) { Common::Rect rect; - _ani->gfxobj->getRect(_ani->_frame, rect); + _ani->gfxobj->getRect(_ani->getF(), rect); - foot.x = _ani->_left + (rect.left + rect.width() / 2); - foot.y = _ani->_top + (rect.top + rect.height()); + foot.x = _ani->getX() + (rect.left + rect.width() / 2); + foot.y = _ani->getY() + (rect.top + rect.height()); } void Character::setFoot(const Common::Point &foot) { Common::Rect rect; - _ani->gfxobj->getRect(_ani->_frame, rect); + _ani->gfxobj->getRect(_ani->getF(), rect); - _ani->_left = foot.x - (rect.left + rect.width() / 2); - _ani->_top = foot.y - (rect.top + rect.height()); + _ani->setX(foot.x - (rect.left + rect.width() / 2)); + _ani->setY(foot.y - (rect.top + rect.height())); } #if 0 @@ -677,7 +675,7 @@ void Character::updateDirection(const Common::Point& pos, const Common::Point& t _step++; if (dist.x == 0 && dist.y == 0) { - _ani->_frame = frames->stillFrame[_direction]; + _ani->setF(frames->stillFrame[_direction]); return; } @@ -687,7 +685,7 @@ void Character::updateDirection(const Common::Point& pos, const Common::Point& t dist.y = -dist.y; _direction = (dist.x > dist.y) ? ((to.x > pos.x) ? WALK_LEFT : WALK_RIGHT) : ((to.y > pos.y) ? WALK_DOWN : WALK_UP); - _ani->_frame = frames->firstWalkFrame[_direction] + (_step / frames->frameRepeat[_direction]) % frames->numWalkFrames[_direction]; + _ani->setF(frames->firstWalkFrame[_direction] + (_step / frames->frameRepeat[_direction]) % frames->numWalkFrames[_direction]); } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index e5c5221414..fb004a25b7 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -136,7 +136,7 @@ extern uint16 _score; extern uint16 _language; extern uint32 _engineFlags; extern char _saveData1[]; -extern uint32 _commandFlags; +extern uint32 _globalFlags; extern const char *_dinoName; extern const char *_donnaName; extern const char *_doughName; @@ -263,7 +263,7 @@ public: ZonePtr findZone(const char *name); ZonePtr hitZone(uint32 type, uint16 x, uint16 y); - uint16 runZone(ZonePtr z); + void runZone(ZonePtr z); void freeZones(); AnimationPtr findAnimation(const char *name); @@ -272,7 +272,7 @@ public: void setBackground(const char *background, const char *mask, const char *path); void freeBackground(); - Table *_globalTable; + Table *_globalFlagsNames; Table *_objectsNames; Table *_callableNames; Table *_localFlagNames; @@ -354,7 +354,7 @@ protected: // members void freeCharacter(); - int16 pickupItem(ZonePtr z); + bool pickupItem(ZonePtr z); void clearSet(OpcodeSet &opcodes); @@ -370,7 +370,7 @@ public: virtual void parseLocation(const char* name) = 0; - void updateDoor(ZonePtr z); + void updateDoor(ZonePtr z, bool close); virtual void drawAnimations() = 0; @@ -424,6 +424,8 @@ public: void setInternLanguage(uint id); uint getInternLanguage(); + + void showZone(ZonePtr z, bool visible); }; @@ -623,8 +625,10 @@ public: int _part; int _progress; +#if 0 // disabled since I couldn't find any references to lip sync in the scripts int16 _lipSyncVal; uint _subtitleLipSync; +#endif int _subtitleY; int _subtitle[2]; diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index 761c8d1b74..bb8ddc5654 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -193,7 +193,7 @@ void Parallaction_br::initPart() { memset(_counters, 0, ARRAYSIZE(_counters)); - _globalTable = _disk->loadTable("global"); + _globalFlagsNames = _disk->loadTable("global"); _objectsNames = _disk->loadTable("objects"); _countersNames = _disk->loadTable("counters"); @@ -208,11 +208,11 @@ void Parallaction_br::initPart() { void Parallaction_br::freePart() { - delete _globalTable; + delete _globalFlagsNames; delete _objectsNames; delete _countersNames; - _globalTable = 0; + _globalFlagsNames = 0; _objectsNames = 0; _countersNames = 0; } diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index e81492e655..61f2859e8a 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -218,7 +218,7 @@ void Parallaction_ns::callFunction(uint index, void* parm) { int Parallaction_ns::go() { renameOldSavefiles(); - _globalTable = _disk->loadTable("global"); + _globalFlagsNames = _disk->loadTable("global"); startGui(); @@ -318,14 +318,10 @@ void Parallaction_ns::changeLocation(char *location) { strcpy(_saveData1, locname.location()); parseLocation(_saveData1); - _char._ani->_oldPos.x = -1000; - _char._ani->_oldPos.y = -1000; - - _char._ani->field_50 = 0; if (_location._startPosition.x != -1000) { - _char._ani->_left = _location._startPosition.x; - _char._ani->_top = _location._startPosition.y; - _char._ani->_frame = _location._startFrame; + _char._ani->setX(_location._startPosition.x); + _char._ani->setY(_location._startPosition.y); + _char._ani->setF(_location._startFrame); _location._startPosition.y = -1000; _location._startPosition.x = -1000; } @@ -438,7 +434,7 @@ void Parallaction_ns::cleanupGame() { // this code saves main character animation from being removed from the following code _location._animations.remove(_char._ani); _numLocations = 0; - _commandFlags = 0; + _globalFlags = 0; memset(_localFlags, 0, sizeof(_localFlags)); memset(_locationNames, 0, sizeof(_locationNames)); diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp index 6de0a7d7f5..8e30a631e4 100644 --- a/engines/parallaction/parser.cpp +++ b/engines/parallaction/parser.cpp @@ -28,7 +28,10 @@ namespace Parallaction { -char _tokens[20][MAX_TOKEN_LEN]; +#define MAX_TOKENS 50 + +int _numTokens; +char _tokens[MAX_TOKENS][MAX_TOKEN_LEN]; Script::Script(Common::ReadStream *input, bool disposeSource) : _input(input), _disposeSource(disposeSource), _line(0) {} @@ -65,9 +68,11 @@ char *Script::readLine(char *buf, size_t bufSize) { void Script::clearTokens() { - for (uint16 i = 0; i < 20; i++) + for (uint16 i = 0; i < MAX_TOKENS; i++) _tokens[i][0] = '\0'; + _numTokens = 0; + return; } @@ -88,7 +93,7 @@ void Script::skip(const char* endToken) { // // The routine returns the unparsed portion of the input string 's'. // -char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes) { +char *Script::parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes) { enum STATES { NORMAL, QUOTED }; @@ -151,12 +156,14 @@ char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ign uint16 Script::fillTokens(char* line) { uint16 i = 0; - while (strlen(line) > 0 && i < 20) { + while (strlen(line) > 0 && i < MAX_TOKENS) { line = parseNextToken(line, _tokens[i], MAX_TOKEN_LEN, " \t\n"); line = Common::ltrim(line); i++; } + _numTokens = i; + return i; } @@ -243,4 +250,185 @@ void Parser::parseStatement() { } +#define BLOCK_BASE 100 + +class StatementDef { +protected: + Common::String makeLineFromTokens() { + Common::String space(" "); + Common::String newLine("\n"); + Common::String text; + for (int i = 0; i < _numTokens; i++) + text += (Common::String(_tokens[i]) + space); + text.deleteLastChar(); + text += newLine; + return text; + } + +public: + uint _score; + const char* _name; + + + StatementDef(uint score, const char *name) : _score(score), _name(name) { } + virtual ~StatementDef() { } + + virtual Common::String makeLine(Script &script) = 0; + +}; + + +class SimpleStatementDef : public StatementDef { + +public: + SimpleStatementDef(uint score, const char *name) : StatementDef(score, name) { } + + Common::String makeLine(Script &script) { + return makeLineFromTokens(); + } + +}; + + + +class BlockStatementDef : public StatementDef { + + const char* _ending1; + const char* _ending2; + +public: + BlockStatementDef(uint score, const char *name, const char *ending1, const char *ending2 = 0) : StatementDef(score, name), _ending1(ending1), + _ending2(ending2) { } + + Common::String makeLine(Script &script) { + Common::String text = makeLineFromTokens(); + bool end; + do { + script.readLineToken(true); + text += makeLineFromTokens(); + end = !scumm_stricmp(_ending1, _tokens[0]) || (_ending2 && !scumm_stricmp(_ending2, _tokens[0])); + } while (!end); + return text; + } + +}; + +class CommentStatementDef : public StatementDef { + + Common::String parseComment(Script &script) { + Common::String result; + char buf[401]; + + do { + script.readLine(buf, 400); + buf[strlen(buf)-1] = '\0'; + if (!scumm_stricmp(buf, "endtext")) + break; + result += Common::String(buf) + "\n"; + } while (true); + result += "endtext\n"; + return result; + } + +public: + CommentStatementDef(uint score, const char *name) : StatementDef(score, name) { } + + Common::String makeLine(Script &script) { + Common::String text = makeLineFromTokens(); + text += parseComment(script); + return text; + } + +}; + + + + +PreProcessor::PreProcessor() { + _defs.push_back(new SimpleStatementDef(1, "disk" )); + _defs.push_back(new SimpleStatementDef(2, "location" )); + _defs.push_back(new SimpleStatementDef(3, "localflags" )); + _defs.push_back(new SimpleStatementDef(4, "flags" )); + _defs.push_back(new SimpleStatementDef(5, "zeta" )); + _defs.push_back(new SimpleStatementDef(6, "music" )); + _defs.push_back(new SimpleStatementDef(7, "sound" )); + _defs.push_back(new SimpleStatementDef(8, "mask" )); + _defs.push_back(new SimpleStatementDef(9, "path" )); + _defs.push_back(new SimpleStatementDef(10, "character" )); + _defs.push_back(new CommentStatementDef(11, "comment" )); + _defs.push_back(new CommentStatementDef(12, "endcomment" )); + _defs.push_back(new BlockStatementDef(13, "ifchar", "endif" )); + _defs.push_back(new BlockStatementDef(BLOCK_BASE, "zone", "endanimation", "endzone" )); + _defs.push_back(new BlockStatementDef(BLOCK_BASE, "animation", "endanimation", "endzone" )); + _defs.push_back(new BlockStatementDef(1000, "commands", "endcommands" )); + _defs.push_back(new BlockStatementDef(1001, "acommands", "endcommands" )); + _defs.push_back(new BlockStatementDef(1002, "escape", "endcommands" )); + _defs.push_back(new SimpleStatementDef(2000, "endlocation")); +} + +PreProcessor::~PreProcessor() { + DefList::iterator it = _defs.begin(); + for (; it != _defs.end(); it++) { + delete *it; + } +} + +StatementDef* PreProcessor::findDef(const char* name) { + DefList::iterator it = _defs.begin(); + for (; it != _defs.end(); it++) { + if (!scumm_stricmp((*it)->_name, name)) { + return *it; + } + } + return 0; +} + + + +uint PreProcessor::getDefScore(StatementDef* def) { + if (def->_score == BLOCK_BASE) { + _numZones++; + return (_numZones + BLOCK_BASE); + } + return def->_score; +} + + +void PreProcessor::preprocessScript(Script &script, StatementList &list) { + _numZones = 0; + Common::String text; + do { + script.readLineToken(false); + if (_numTokens == 0) + break; + + StatementDef *def = findDef(_tokens[0]); + assert(def); + + text = def->makeLine(script); + int score = getDefScore(def); + list.push_back(StatementListNode(score, def->_name, text)); + } while (true); + Common::sort(list.begin(), list.end()); +} + + + + +void testPreprocessing(Parallaction *vm, const char *filename) { + Script *script = vm->_disk->loadLocation(filename); + StatementList list; + PreProcessor pp; + pp.preprocessScript(*script, list); + delete script; + Common::DumpFile dump; + dump.open(filename); + StatementList::iterator it = list.begin(); + for ( ; it != list.end(); it++) { + dump.write((*it)._text.c_str(), (*it)._text.size()); + } + dump.close(); +} + + } // namespace Parallaction diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index 79e6cf6640..e622bfd81f 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -32,9 +32,8 @@ namespace Parallaction { -char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes = false); - #define MAX_TOKEN_LEN 50 +extern int _numTokens; extern char _tokens[][MAX_TOKEN_LEN]; class Script { @@ -45,6 +44,7 @@ class Script { void clearTokens(); uint16 fillTokens(char* line); + char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes = false); public: Script(Common::ReadStream *, bool _disposeSource = false); @@ -63,6 +63,7 @@ typedef Common::Functor0<void> Opcode; typedef Common::Array<const Opcode*> OpcodeSet; + class Parser { public: @@ -95,6 +96,7 @@ public: class Parallaction_ns; class Parallaction_br; + class LocationParser_ns { protected: @@ -129,9 +131,6 @@ protected: // BRA specific int numZones; BackgroundInfo *info; - char *bgName; - char *maskName; - char *pathName; char *characterName; } ctxt; @@ -240,6 +239,23 @@ public: }; +/* + TODO: adapt the parser to effectively use the + statement list provided by preprocessor as its + input, instead of relying on the current Script + class. + + This would need a major rewrite of the parsing + system! + + parseNextToken could then be sealed into the + PreProcessor class forever, together with the + _tokens[] and _numTokens stuff, now dangling as + global objects. + + NS balloons code should be dealt with before, + though. +*/ class LocationParser_br : public LocationParser_ns { protected: @@ -287,6 +303,7 @@ protected: virtual void parseZoneTypeBlock(ZonePtr z); void parsePathData(ZonePtr z); + void parseGetData(ZonePtr z); public: LocationParser_br(Parallaction_br *vm) : LocationParser_ns((Parallaction_ns*)vm), _vm(vm) { @@ -402,6 +419,117 @@ public: }; + +/* + This simple stream is temporarily needed to hook the + preprocessor output to the parser. It will go away + when the parser is rewritten to fully exploit the + statement list provided by the preprocessor. +*/ + +class ReadStringStream : public Common::ReadStream { + + char *_text; + uint32 _pos; + uint32 _size; + +public: + ReadStringStream(const Common::String &text) { + _text = new char[text.size() + 1]; + strcpy(_text, text.c_str()); + _size = text.size(); + _pos = 0; + } + + ~ReadStringStream() { + delete []_text; + } + + uint32 read(void *buffer, uint32 size) { + if (_pos + size > _size) { + size = _size - _pos; + } + memcpy(buffer, _text + _pos, size); + _pos += size; + return size; + } + + bool eos() const { + return _pos == _size; + } + +}; + + +/* + Demented as it may sound, the success of a parsing operation in the + original BRA depends on what has been parsed before. The game features + an innovative chaos system that involves the parser and the very game + engine, in order to inflict the user an unforgettable game experience. + + Ok, now for the serious stuff. + + The PreProcessor implemented here fixes the location scripts before + they are fed to the parser. It tries to do so by a preliminary scan + of the text file, during which a score is assigned to each statement + (more on this later). When the whole file has been analyzed, the + statements are sorted according to their score, to create a parsable + sequence. + + For parsing, the statements in location scripts can be conveniently + divided into 3 groups: + + * location definitions + * element definitions + * start-up commands + + Since the parsing of element definitions requires location parameters + to be set, location definitions should be encountered first in the + script. Start-up commands in turn may reference elements, so they can + be parsed last. The first goal is to make sure the parser gets these + three sets in this order. + + Location definitions must also be presented in a certain sequence, + because resource files are not fully self-describing. In short, some + critical game data in contained in certain files, that must obviously + be read before any other can be analyzed. This is the second goal. + + TODO: some words about actual implementation. +*/ + +class StatementDef; + +struct StatementListNode { + int _score; + Common::String _name; + Common::String _text; + + StatementListNode(int score, const Common::String &name, const Common::String &text) : _score(score), _name(name), _text(text) { } + + bool operator<(const StatementListNode& node) const { + return _score < node._score; + } +}; +typedef Common::List<StatementListNode> StatementList; + + +class PreProcessor { + typedef Common::List<StatementDef*> DefList; + + int _numZones; + DefList _defs; + + StatementDef* findDef(const char* name); + uint getDefScore(StatementDef*); + +public: + PreProcessor(); + ~PreProcessor(); + void preprocessScript(Script &script, StatementList &list); +}; + + + } // namespace Parallaction #endif diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index 3b446805d7..20800abc33 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -25,6 +25,7 @@ #include "parallaction/parallaction.h" + #include "parallaction/sound.h" namespace Parallaction { @@ -104,6 +105,7 @@ namespace Parallaction { #define INST_ENDIF 30 #define INST_STOP 31 + const char *_zoneTypeNamesRes_br[] = { "examine", "door", @@ -314,7 +316,6 @@ DECLARE_LOCATION_PARSER(location) { debugC(7, kDebugParser, "LOCATION_PARSER(location) "); strcpy(_vm->_location._name, _tokens[1]); - ctxt.bgName = strdup(_tokens[1]); bool flip = false; int nextToken; @@ -329,15 +330,17 @@ DECLARE_LOCATION_PARSER(location) { // TODO: handle background horizontal flip (via a context parameter) if (_tokens[nextToken][0] != '\0') { - _vm->_char._ani->_left = atoi(_tokens[nextToken]); + _vm->_char._ani->setX(atoi(_tokens[nextToken])); nextToken++; - _vm->_char._ani->_top = atoi(_tokens[nextToken]); + _vm->_char._ani->setY(atoi(_tokens[nextToken])); nextToken++; } if (_tokens[nextToken][0] != '\0') { - _vm->_char._ani->_frame = atoi(_tokens[nextToken]); + _vm->_char._ani->setF(atoi(_tokens[nextToken])); } + + _vm->_disk->loadScenery(*ctxt.info, _tokens[1], 0, 0); } @@ -463,17 +466,20 @@ DECLARE_LOCATION_PARSER(null) { DECLARE_LOCATION_PARSER(mask) { debugC(7, kDebugParser, "LOCATION_PARSER(mask) "); - ctxt.maskName = strdup(_tokens[1]); - ctxt.info->layers[0] = atoi(_tokens[2]); - ctxt.info->layers[1] = atoi(_tokens[3]); - ctxt.info->layers[2] = atoi(_tokens[4]); + ctxt.info->layers[0] = 0; + ctxt.info->layers[1] = atoi(_tokens[2]); + ctxt.info->layers[2] = atoi(_tokens[3]); + ctxt.info->layers[3] = atoi(_tokens[4]); + + _vm->_disk->loadScenery(*ctxt.info, 0, _tokens[1], 0); + ctxt.info->hasMask = true; } DECLARE_LOCATION_PARSER(path) { debugC(7, kDebugParser, "LOCATION_PARSER(path) "); - ctxt.pathName = strdup(_tokens[1]); + _vm->_disk->loadScenery(*ctxt.info, 0, 0, _tokens[1]); } @@ -714,10 +720,7 @@ DECLARE_ZONE_PARSER(limits) { ctxt.z->_linkedAnim = _vm->findAnimation(_tokens[1]); ctxt.z->_linkedName = strdup(_tokens[1]); } else { - ctxt.z->_left = atoi(_tokens[1]); - ctxt.z->_top = atoi(_tokens[2]); - ctxt.z->_right = atoi(_tokens[3]); - ctxt.z->_bottom = atoi(_tokens[4]); + ctxt.z->setBox(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4])); } } @@ -768,6 +771,49 @@ void LocationParser_br::parsePathData(ZonePtr z) { z->u.path = data; } +void LocationParser_br::parseGetData(ZonePtr z) { + + GetData *data = new GetData; + + do { + + if (!scumm_stricmp(_tokens[0], "file")) { + + GfxObj *obj = _vm->_gfx->loadGet(_tokens[1]); + obj->frame = 0; + obj->x = z->getX(); + obj->y = z->getY(); + data->gfxobj = obj; + } + + if (!scumm_stricmp(_tokens[0], "mask")) { + if (ctxt.info->hasMask) { + Common::Rect rect; + data->gfxobj->getRect(0, rect); + data->_mask[0].create(rect.width(), rect.height()); + _vm->_disk->loadMask(_tokens[1], data->_mask[0]); + data->_mask[1].create(rect.width(), rect.height()); + data->_mask[1].bltCopy(0, 0, ctxt.info->mask, data->gfxobj->x, data->gfxobj->y, data->_mask->w, data->_mask->h); + data->hasMask = true; + } else { + warning("Mask for zone '%s' ignored, since background doesn't have one", z->_name); + } + } + + if (!scumm_stricmp(_tokens[0], "path")) { + + } + + if (!scumm_stricmp(_tokens[0], "icon")) { + data->_icon = 4 + _vm->_objectsNames->lookup(_tokens[1]); + } + + _script->readLineToken(true); + } while (scumm_stricmp(_tokens[0], "endzone")); + + z->u.get = data; +} + void LocationParser_br::parseZoneTypeBlock(ZonePtr z) { debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type); @@ -822,10 +868,10 @@ DECLARE_ANIM_PARSER(file) { DECLARE_ANIM_PARSER(position) { debugC(7, kDebugParser, "ANIM_PARSER(position) "); - ctxt.a->_left = atoi(_tokens[1]); - ctxt.a->_top = atoi(_tokens[2]); - ctxt.a->_z = atoi(_tokens[3]); - ctxt.a->_frame = atoi(_tokens[4]); + ctxt.a->setX(atoi(_tokens[1])); + ctxt.a->setY(atoi(_tokens[2])); + ctxt.a->setZ(atoi(_tokens[3])); + ctxt.a->setF(atoi(_tokens[4])); } @@ -841,15 +887,14 @@ DECLARE_ANIM_PARSER(moveto) { DECLARE_ANIM_PARSER(endanimation) { debugC(7, kDebugParser, "ANIM_PARSER(endanimation) "); - +#if 0 + // I have disabled the following code since it seems useless. + // I will remove it after mask processing is done. if (ctxt.a->gfxobj) { ctxt.a->_right = ctxt.a->width(); ctxt.a->_bottom = ctxt.a->height(); } - - ctxt.a->_oldPos.x = -1000; - ctxt.a->_oldPos.y = -1000; - +#endif ctxt.a->_flags |= 0x1000000; _parser->popTables(); @@ -992,16 +1037,16 @@ void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) { a = AnimationPtr(ctxt.a); if (str[0] == 'X') { - v.setField(&a->_left); + v.setField(a.get(), &Animation::getX); } else if (str[0] == 'Y') { - v.setField(&a->_top); + v.setField(a.get(), &Animation::getY); } else if (str[0] == 'Z') { - v.setField(&a->_z); + v.setField(a.get(), &Animation::getZ); } else if (str[0] == 'F') { - v.setField(&a->_frame); + v.setField(a.get(), &Animation::getF); } else if (str[0] == 'N') { v.setImmediate(a->getFrameNum()); @@ -1010,7 +1055,10 @@ void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) { v.setRandom(atoi(&str[1])); } else if (str[0] == 'L') { +#if 0 // disabled because no references to lip sync has been found in the scripts v.setField(&_vm->_lipSyncVal); +#endif + warning("Lip sync instruction encountered! Please notify the team!"); } } @@ -1168,31 +1216,50 @@ void ProgramParser_br::init() { INSTRUCTION_PARSER(endscript); } + +/* + Ancillary routine to support hooking preprocessor and + parser. +*/ +Common::ReadStream *getStream(StatementList &list) { + Common::String text; + StatementList::iterator it = list.begin(); + for ( ; it != list.end(); it++) { + text += (*it)._text; + } + return new ReadStringStream(text); +} + void LocationParser_br::parse(Script *script) { + PreProcessor pp; + StatementList list; + pp.preprocessScript(*script, list); + Script *script2 = new Script(getStream(list), true); + ctxt.numZones = 0; - ctxt.bgName = 0; - ctxt.maskName = 0; - ctxt.pathName = 0; ctxt.characterName = 0; ctxt.info = new BackgroundInfo; - LocationParser_ns::parse(script); + LocationParser_ns::parse(script2); - _vm->_disk->loadScenery(*ctxt.info, ctxt.bgName, ctxt.maskName, ctxt.pathName); _vm->_gfx->setBackground(kBackgroundLocation, ctxt.info); _vm->_pathBuffer = &ctxt.info->path; + ZoneList::iterator it = _vm->_location._zones.begin(); + for ( ; it != _vm->_location._zones.end(); it++) { + bool visible = ((*it)->_flags & kFlagsRemove) == 0; + _vm->showZone((*it), visible); + } + if (ctxt.characterName) { _vm->changeCharacter(ctxt.characterName); } - free(ctxt.bgName); - free(ctxt.maskName); - free(ctxt.pathName); free(ctxt.characterName); + delete script2; } } // namespace Parallaction diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index ad0f714fdc..4b90e2364f 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -221,9 +221,6 @@ DECLARE_ANIM_PARSER(type) { } } - ctxt.a->_oldPos.x = -1000; - ctxt.a->_oldPos.y = -1000; - ctxt.a->_flags |= 0x1000000; _parser->popTables(); @@ -267,9 +264,9 @@ DECLARE_ANIM_PARSER(file) { DECLARE_ANIM_PARSER(position) { debugC(7, kDebugParser, "ANIM_PARSER(position) "); - ctxt.a->_left = atoi(_tokens[1]); - ctxt.a->_top = atoi(_tokens[2]); - ctxt.a->_z = atoi(_tokens[3]); + ctxt.a->setX(atoi(_tokens[1])); + ctxt.a->setY(atoi(_tokens[2])); + ctxt.a->setZ(atoi(_tokens[3])); } @@ -284,10 +281,6 @@ DECLARE_ANIM_PARSER(moveto) { DECLARE_ANIM_PARSER(endanimation) { debugC(7, kDebugParser, "ANIM_PARSER(endanimation) "); - - ctxt.a->_oldPos.x = -1000; - ctxt.a->_oldPos.y = -1000; - ctxt.a->_flags |= 0x1000000; _parser->popTables(); @@ -523,7 +516,7 @@ DECLARE_INSTRUCTION_PARSER(defLocal) { } ctxt.inst->_opA.setLocal(&ctxt.locals[index]); - ctxt.inst->_opB.setImmediate(ctxt.locals[index]._value); + ctxt.inst->_opB.setImmediate(ctxt.locals[index].getValue()); ctxt.inst->_index = INST_SET; } @@ -558,16 +551,16 @@ void ProgramParser_ns::parseRValue(ScriptVar &v, const char *str) { } if (str[0] == 'X') { - v.setField(&a->_left); + v.setField(a.get(), &Animation::getX); } else if (str[0] == 'Y') { - v.setField(&a->_top); + v.setField(a.get(), &Animation::getY); } else if (str[0] == 'Z') { - v.setField(&a->_z); + v.setField(a.get(), &Animation::getZ); } else if (str[0] == 'F') { - v.setField(&a->_frame); + v.setField(a.get(), &Animation::getF); } } @@ -588,16 +581,16 @@ void ProgramParser_ns::parseLValue(ScriptVar &v, const char *str) { } if (str[0] == 'X') { - v.setField(&a->_left); + v.setField(a.get(), &Animation::getX, &Animation::setX); } else if (str[0] == 'Y') { - v.setField(&a->_top); + v.setField(a.get(), &Animation::getY, &Animation::setY); } else if (str[0] == 'Z') { - v.setField(&a->_z); + v.setField(a.get(), &Animation::getZ, &Animation::setZ); } else if (str[0] == 'F') { - v.setField(&a->_frame); + v.setField(a.get(), &Animation::getF, &Animation::setF); } } @@ -608,7 +601,7 @@ DECLARE_COMMAND_PARSER(flags) { createCommand(_parser->_lookup); - if (_vm->_globalTable->lookup(_tokens[1]) == Table::notFound) { + if (_vm->_globalFlagsNames->lookup(_tokens[1]) == Table::notFound) { do { char _al = _vm->_localFlagNames->lookup(_tokens[ctxt.nextToken]); ctxt.nextToken++; @@ -618,7 +611,7 @@ DECLARE_COMMAND_PARSER(flags) { } else { ctxt.cmd->u._flags |= kFlagsGlobal; do { - char _al = _vm->_globalTable->lookup(_tokens[1]); + char _al = _vm->_globalFlagsNames->lookup(_tokens[1]); ctxt.nextToken++; ctxt.cmd->u._flags |= 1 << (_al - 1); } while (!scumm_stricmp(_tokens[ctxt.nextToken++], "|")); @@ -759,11 +752,11 @@ void LocationParser_ns::parseCommandFlags() { cmd->_flagsOn |= kFlagsEnter; } else if (!scumm_strnicmp(_tokens[_si], "no", 2)) { - byte _al = _vm->_globalTable->lookup(&_tokens[_si][2]); + byte _al = _vm->_globalFlagsNames->lookup(&_tokens[_si][2]); assert(_al != Table::notFound); cmd->_flagsOff |= 1 << (_al - 1); } else { - byte _al = _vm->_globalTable->lookup(_tokens[_si]); + byte _al = _vm->_globalFlagsNames->lookup(_tokens[_si]); assert(_al != Table::notFound); cmd->_flagsOn |= 1 << (_al - 1); } @@ -880,7 +873,7 @@ Answer *LocationParser_ns::parseAnswer() { if (!scumm_stricmp(_tokens[1], "global")) { token = 2; - flagNames = _vm->_globalTable; + flagNames = _vm->_globalFlagsNames; answer->_yesFlags |= kFlagsGlobal; } else { token = 1; @@ -992,12 +985,12 @@ DECLARE_LOCATION_PARSER(location) { _vm->switchBackground(_vm->_location._name, mask); if (_tokens[2][0] != '\0') { - _vm->_char._ani->_left = atoi(_tokens[2]); - _vm->_char._ani->_top = atoi(_tokens[3]); + _vm->_char._ani->setX(atoi(_tokens[2])); + _vm->_char._ani->setY(atoi(_tokens[3])); } if (_tokens[4][0] != '\0') { - _vm->_char._ani->_frame = atoi(_tokens[4]); + _vm->_char._ani->setF(atoi(_tokens[4])); } } @@ -1316,11 +1309,7 @@ DECLARE_ZONE_PARSER(endzone) { DECLARE_ZONE_PARSER(limits) { debugC(7, kDebugParser, "ZONE_PARSER(limits) "); - - ctxt.z->_left = atoi(_tokens[1]); - ctxt.z->_top = atoi(_tokens[2]); - ctxt.z->_right = atoi(_tokens[3]); - ctxt.z->_bottom = atoi(_tokens[4]); + ctxt.z->setBox(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4])); } @@ -1411,8 +1400,8 @@ void LocationParser_ns::parseGetData(ZonePtr z) { GfxObj *obj = _vm->_gfx->loadGet(_tokens[1]); obj->frame = 0; - obj->x = z->_left; - obj->y = z->_top; + obj->x = z->getX(); + obj->y = z->getY(); _vm->_gfx->showGfxObj(obj, visible); data->gfxobj = obj; @@ -1474,8 +1463,8 @@ void LocationParser_ns::parseDoorData(ZonePtr z) { GfxObj *obj = _vm->_gfx->loadDoor(_tokens[1]); obj->frame = frame; - obj->x = z->_left; - obj->y = z->_top; + obj->x = z->getX(); + obj->y = z->getY(); _vm->_gfx->showGfxObj(obj, true); data->gfxobj = obj; diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 87a556182e..44613c970c 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -125,7 +125,7 @@ void Parallaction_ns::doLoadGame(uint16 slot) { _score = atoi(s); f->readLine(s, 15); - _commandFlags = atoi(s); + _globalFlags = atoi(s); f->readLine(s, 15); @@ -207,13 +207,13 @@ void Parallaction_ns::doSaveGame(uint16 slot, const char* name) { sprintf(s, "%s\n", _saveData1); f->writeString(s); - sprintf(s, "%d\n", _char._ani->_left); + sprintf(s, "%d\n", _char._ani->getX()); f->writeString(s); - sprintf(s, "%d\n", _char._ani->_top); + sprintf(s, "%d\n", _char._ani->getY()); f->writeString(s); sprintf(s, "%d\n", _score); f->writeString(s); - sprintf(s, "%u\n", _commandFlags); + sprintf(s, "%u\n", _globalFlags); f->writeString(s); sprintf(s, "%d\n", _numLocations); diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index bf8f423fd5..5fd67d26dc 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -479,7 +479,7 @@ void PathWalker_BR::finalizeWalk() { _char.setFoot(foot); #endif - _ch->_ani->_frame = _dirFrame; // temporary solution + _ch->_ani->setF(_dirFrame); // temporary solution #if 0 // TODO: support scrolling ;) @@ -515,7 +515,7 @@ void PathWalker_BR::walk() { GfxObj *obj = _ch->_ani->gfxobj; Common::Rect rect; - obj->getRect(_ch->_ani->_frame, rect); + obj->getRect(_ch->_ani->getF(), rect); uint scale; if (rect.bottom > _vm->_location._zeta0) { @@ -609,11 +609,11 @@ void PathWalker_BR::walk() { if (_fieldC) { debugC(9, kDebugWalk, "PathWalker_BR::walk, foot moved from (%i, %i) to (%i, %i)\n", _startFoot.x, _startFoot.y, newpos.x, newpos.y); - _ch->_ani->_frame = walkFrame + _dirFrame + 1; + _ch->_ani->setF(walkFrame + _dirFrame + 1); _startFoot.x = newpos.x; _startFoot.y = newpos.y; _ch->setFoot(_startFoot); - _ch->_ani->_z = newpos.y; + _ch->_ani->setZ(newpos.y); } if (_fieldC || !_ch->_walkPath.empty()) { |