diff options
Diffstat (limited to 'engines/scumm')
-rw-r--r-- | engines/scumm/akos.cpp | 4 | ||||
-rw-r--r-- | engines/scumm/base-costume.h | 2 | ||||
-rw-r--r-- | engines/scumm/boxes.cpp | 2 | ||||
-rw-r--r-- | engines/scumm/detection.cpp | 21 | ||||
-rw-r--r-- | engines/scumm/dialogs.cpp | 32 | ||||
-rw-r--r-- | engines/scumm/dialogs.h | 14 | ||||
-rw-r--r-- | engines/scumm/file.cpp | 3 | ||||
-rw-r--r-- | engines/scumm/he/intern_he.h | 2 | ||||
-rw-r--r-- | engines/scumm/he/resource_he.h | 40 | ||||
-rw-r--r-- | engines/scumm/imuse/instrument.cpp | 8 | ||||
-rw-r--r-- | engines/scumm/input.cpp | 150 | ||||
-rw-r--r-- | engines/scumm/intern.h | 4 | ||||
-rw-r--r-- | engines/scumm/module.mk | 6 | ||||
-rw-r--r-- | engines/scumm/object.h | 6 | ||||
-rw-r--r-- | engines/scumm/player_v2.h | 2 | ||||
-rw-r--r-- | engines/scumm/saveload.cpp | 7 | ||||
-rw-r--r-- | engines/scumm/script.cpp | 32 | ||||
-rw-r--r-- | engines/scumm/scumm-md5.h | 5 | ||||
-rw-r--r-- | engines/scumm/scumm.cpp | 48 | ||||
-rw-r--r-- | engines/scumm/scumm.h | 20 | ||||
-rw-r--r-- | engines/scumm/smush/codec47.cpp | 19 | ||||
-rw-r--r-- | engines/scumm/smush/codec47ARM.s | 372 | ||||
-rw-r--r-- | engines/scumm/verbs.cpp | 14 | ||||
-rw-r--r-- | engines/scumm/verbs.h | 12 |
24 files changed, 610 insertions, 215 deletions
diff --git a/engines/scumm/akos.cpp b/engines/scumm/akos.cpp index 2a51464341..c8667d7ab2 100644 --- a/engines/scumm/akos.cpp +++ b/engines/scumm/akos.cpp @@ -47,12 +47,12 @@ struct AkosHeader { uint16 num_anims; uint16 unk_3; uint16 codec; -}; +} PACKED_STRUCT; struct AkosOffset { uint32 akcd; // offset into the akcd data uint16 akci; // offset into the akci data -}; +} PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/base-costume.h b/engines/scumm/base-costume.h index e6ef618a3e..155bbff97f 100644 --- a/engines/scumm/base-costume.h +++ b/engines/scumm/base-costume.h @@ -37,7 +37,7 @@ struct CostumeInfo { uint16 width, height; int16 rel_x, rel_y; int16 move_x, move_y; -}; +} PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp index 424e5d891e..e79cea4359 100644 --- a/engines/scumm/boxes.cpp +++ b/engines/scumm/boxes.cpp @@ -80,7 +80,7 @@ struct Box { /* Internal walkbox file format */ uint32 unk3; } v8; }; -}; +} PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 8624f80fe7..e9430337ff 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -765,19 +765,22 @@ PluginError Engine_SCUMM_create(OSystem *syst, Engine **engine) { // narrow down the list a bit more. if (results.size() > 1 && ConfMan.hasKey("platform")) { Common::Platform platform = Common::parsePlatform(ConfMan.get("platform")); + Common::List<DetectorResult> tmp; + + // Copy only those candidates which match the platform setting for (Common::List<DetectorResult>::iterator x = results.begin(); x != results.end(); ) { - if (x->game.platform != platform) { - x = results.erase(x); - } else { - ++x; + if (x->game.platform == platform) { + tmp.push_back(*x); } } - } - // If we narrowed it down too much, abort - if (results.empty()) { - warning("Engine_SCUMM_create: Game data inconsistent with platform override"); - return kNoGameDataFoundError; + // If we narrowed it down too much, print a warning, else use the list + // we just computed as new candidates list. + if (tmp.empty()) { + warning("Engine_SCUMM_create: Game data inconsistent with platform override"); + } else { + results = tmp; + } } // Still no unique match found -> print a warning diff --git a/engines/scumm/dialogs.cpp b/engines/scumm/dialogs.cpp index 85a7a4b675..16fe72531b 100644 --- a/engines/scumm/dialogs.cpp +++ b/engines/scumm/dialogs.cpp @@ -825,26 +825,26 @@ PauseDialog::PauseDialog(ScummEngine *scumm, int res) : InfoDialog(scumm, res) { } -void PauseDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { - if (ascii == ' ') // Close pause dialog if space key is pressed +void PauseDialog::handleKeyDown(Common::KeyState state) { + if (state.ascii == ' ') // Close pause dialog if space key is pressed close(); else - ScummDialog::handleKeyDown(ascii, keycode, modifiers); + ScummDialog::handleKeyDown(state); } ConfirmDialog::ConfirmDialog(ScummEngine *scumm, int res) : InfoDialog(scumm, res) { } -void ConfirmDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { - if (tolower(ascii) == 'n') { +void ConfirmDialog::handleKeyDown(Common::KeyState state) { + if (state.keycode == Common::KEYCODE_n) { setResult(0); close(); - } else if (tolower(ascii) == 'y') { + } else if (state.keycode == Common::KEYCODE_y) { setResult(1); close(); } else - ScummDialog::handleKeyDown(ascii, keycode, modifiers); + ScummDialog::handleKeyDown(state); } #pragma mark - @@ -892,11 +892,11 @@ void ValueDisplayDialog::reflowLayout() { _h = height; } -void ValueDisplayDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { - if (ascii == _incKey || ascii == _decKey) { - if (ascii == _incKey && _value < _max) +void ValueDisplayDialog::handleKeyDown(Common::KeyState state) { + if (state.ascii == _incKey || state.ascii == _decKey) { + if (state.ascii == _incKey && _value < _max) _value++; - else if (ascii == _decKey && _value > _min) + else if (state.ascii == _decKey && _value > _min) _value--; setResult(_value); @@ -924,8 +924,8 @@ void SubtitleSettingsDialog::handleTickle() { close(); } -void SubtitleSettingsDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { - if (keycode == 't' && modifiers == Common::KBD_CTRL) { +void SubtitleSettingsDialog::handleKeyDown(Common::KeyState state) { + if (state.keycode == 't' && state.flags == Common::KBD_CTRL) { cycleValue(); reflowLayout(); @@ -959,11 +959,11 @@ Indy3IQPointsDialog::Indy3IQPointsDialog(ScummEngine *scumm, char* text) : InfoDialog(scumm, text) { } -void Indy3IQPointsDialog::handleKeyDown(uint16 ascii, int keycode, int modifiers) { - if (ascii == 'i') +void Indy3IQPointsDialog::handleKeyDown(Common::KeyState state) { + if (state.ascii == 'i') close(); else - ScummDialog::handleKeyDown(ascii, keycode, modifiers); + ScummDialog::handleKeyDown(state); } } // End of namespace Scumm diff --git a/engines/scumm/dialogs.h b/engines/scumm/dialogs.h index b69e989f8a..23c63d8992 100644 --- a/engines/scumm/dialogs.h +++ b/engines/scumm/dialogs.h @@ -169,8 +169,8 @@ public: setResult(0); close(); } - virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers) { - setResult(ascii); + virtual void handleKeyDown(Common::KeyState state) { + setResult(state.ascii); close(); } @@ -189,7 +189,7 @@ protected: class PauseDialog : public InfoDialog { public: PauseDialog(ScummEngine *scumm, int res); - virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers); + virtual void handleKeyDown(Common::KeyState state); }; /** @@ -199,7 +199,7 @@ public: class ConfirmDialog : public InfoDialog { public: ConfirmDialog(ScummEngine *scumm, int res); - virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers); + virtual void handleKeyDown(Common::KeyState state); }; /** @@ -216,7 +216,7 @@ public: virtual void handleMouseDown(int x, int y, int button, int clickCount) { close(); } - virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers); + virtual void handleKeyDown(Common::KeyState state); virtual void reflowLayout(); @@ -247,7 +247,7 @@ public: virtual void handleMouseDown(int x, int y, int button, int clickCount) { close(); } - virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers); + virtual void handleKeyDown(Common::KeyState state); protected: int _value; uint32 _timer; @@ -259,7 +259,7 @@ protected: class Indy3IQPointsDialog : public InfoDialog { public: Indy3IQPointsDialog(ScummEngine *scumm, char* text); - virtual void handleKeyDown(uint16 ascii, int keycode, int modifiers); + virtual void handleKeyDown(Common::KeyState state); }; } // End of namespace Scumm diff --git a/engines/scumm/file.cpp b/engines/scumm/file.cpp index 3ab3e1a2e0..2c7f9ead5b 100644 --- a/engines/scumm/file.cpp +++ b/engines/scumm/file.cpp @@ -1257,10 +1257,11 @@ struct _lfl_index { uint16 script_addr[200]; byte sound_lfl[100]; uint16 sound_addr[100]; -} lfl_index; +} PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING +_lfl_index lfl_index; bool ScummNESFile::generateResource(int res) { const LFL *lfl = &lfls[res - 1]; diff --git a/engines/scumm/he/intern_he.h b/engines/scumm/he/intern_he.h index 54eb470c26..84ad8adb3b 100644 --- a/engines/scumm/he/intern_he.h +++ b/engines/scumm/he/intern_he.h @@ -250,7 +250,7 @@ protected: int32 dim2start; //0C int32 dim2end; //10 byte data[1]; //14 - }; + } PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/he/resource_he.h b/engines/scumm/he/resource_he.h index 757cf13b7c..d7f4d99754 100644 --- a/engines/scumm/he/resource_he.h +++ b/engines/scumm/he/resource_he.h @@ -172,7 +172,7 @@ class Win32ResExtractor : public ResExtractor { byte *memory; byte *first_resource; int total_size; - }; + } PACKED_STRUCT; struct WinResource { char id[256]; @@ -183,7 +183,7 @@ class Win32ResExtractor : public ResExtractor { bool is_directory; char *get_resource_id_quoted(); - }; + } PACKED_STRUCT; struct Win32IconResDir { @@ -191,12 +191,12 @@ class Win32ResExtractor : public ResExtractor { byte height; byte color_count; byte reserved; - }; + } PACKED_STRUCT; struct Win32CursorDir { uint16 width; uint16 height; - }; + } PACKED_STRUCT; struct Win32CursorIconDirEntry { union { @@ -207,14 +207,14 @@ class Win32ResExtractor : public ResExtractor { uint16 bit_count; uint32 bytes_in_res; uint16 res_id; - }; + } PACKED_STRUCT; struct Win32CursorIconDir { uint16 reserved; uint16 type; uint16 count; Win32CursorIconDirEntry entries[1]; - }; + } PACKED_STRUCT; struct Win32CursorIconFileDirEntry { byte width; @@ -225,14 +225,14 @@ class Win32ResExtractor : public ResExtractor { uint16 hotspot_y; uint32 dib_size; uint32 dib_offset; - }; + } PACKED_STRUCT; struct Win32CursorIconFileDir { uint16 reserved; uint16 type; uint16 count; Win32CursorIconFileDirEntry entries[1]; - }; + } PACKED_STRUCT; struct Win32BitmapInfoHeader { uint32 size; @@ -246,25 +246,25 @@ class Win32ResExtractor : public ResExtractor { int32 y_pels_per_meter; uint32 clr_used; uint32 clr_important; - }; + } PACKED_STRUCT; struct Win32RGBQuad { byte blue; byte green; byte red; byte reserved; - }; + } PACKED_STRUCT; struct Win32ImageResourceDirectoryEntry { uint32 name; uint32 offset_to_data; - }; + } PACKED_STRUCT; struct Win16NETypeInfo { uint16 type_id; uint16 count; uint32 resloader; // FARPROC16 - smaller? uint16? - }; + } PACKED_STRUCT; struct DOSImageHeader { uint16 magic; @@ -286,7 +286,7 @@ class Win32ResExtractor : public ResExtractor { uint16 oeminfo; uint16 res2[10]; uint32 lfanew; - }; + } PACKED_STRUCT; struct Win32ImageFileHeader { uint16 machine; @@ -296,12 +296,12 @@ class Win32ResExtractor : public ResExtractor { uint32 number_of_symbols; uint16 size_of_optional_header; uint16 characteristics; - }; + } PACKED_STRUCT; struct Win32ImageDataDirectory { uint32 virtual_address; uint32 size; - }; + } PACKED_STRUCT; struct Win32ImageOptionalHeader { uint16 magic; @@ -335,13 +335,13 @@ class Win32ResExtractor : public ResExtractor { uint32 loader_flags; uint32 number_of_rva_and_sizes; Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; - }; + } PACKED_STRUCT; struct Win32ImageNTHeaders { uint32 signature; Win32ImageFileHeader file_header; Win32ImageOptionalHeader optional_header; - }; + } PACKED_STRUCT; struct Win32ImageSectionHeader { byte name[IMAGE_SIZEOF_SHORT_NAME]; @@ -357,14 +357,14 @@ class Win32ResExtractor : public ResExtractor { uint16 number_of_relocations; uint16 number_of_linenumbers; uint32 characteristics; - }; + } PACKED_STRUCT; struct Win32ImageResourceDataEntry { uint32 offset_to_data; uint32 size; uint32 code_page; uint32 resource_handle; - }; + } PACKED_STRUCT; struct Win32ImageResourceDirectory { uint32 characteristics; @@ -373,7 +373,7 @@ class Win32ResExtractor : public ResExtractor { uint16 minor_version; uint16 number_of_named_entries; uint16 number_of_id_entries; - }; + } PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/imuse/instrument.cpp b/engines/scumm/imuse/instrument.cpp index 23b325c20b..b6ed064bc9 100644 --- a/engines/scumm/imuse/instrument.cpp +++ b/engines/scumm/imuse/instrument.cpp @@ -149,7 +149,7 @@ private: #include "common/pack-start.h" // START STRUCT PACKING - struct { + struct AdlibInstrument { byte flags_1; byte oplvl_1; byte atdec_1; @@ -166,10 +166,12 @@ private: byte flags_b; struct { byte a,b,c,d,e,f,g,h; } extra_b; byte duration; - } _instrument; + } PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING + AdlibInstrument _instrument; + public: Instrument_Adlib(const byte *data); Instrument_Adlib(Serializer *s); @@ -241,7 +243,7 @@ private: byte tva_env_sustain_level; } partial[4]; byte checksum; - }; + } PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/input.cpp b/engines/scumm/input.cpp index 2d7401fe57..ffcb7d03f2 100644 --- a/engines/scumm/input.cpp +++ b/engines/scumm/input.cpp @@ -75,83 +75,53 @@ void ScummEngine::parseEvents() { sprintf(_saveLoadName, "Quicksave %d", _saveLoadSlot); _saveLoadFlag = (event.kbd.flags == Common::KBD_ALT) ? 1 : 2; _saveTemporaryState = false; - } else if (event.kbd.flags == Common::KBD_CTRL) { - if (event.kbd.keycode == 'f') - _fastMode ^= 1; - else if (event.kbd.keycode == 'g') - _fastMode ^= 2; - else if (event.kbd.keycode == 'd') - _debugger->attach(); - else if (event.kbd.keycode == 's') - _res->resourceStats(); - else - _keyPressed = event.kbd; // Normal key press, pass on to the game. - } else if (event.kbd.flags & Common::KBD_ALT) { - // Handle KBD_ALT combos. We know that the result must be 273 for Alt-W - // because that's what MI2 looks for in its "instant win" cheat. - - // FIXME: Handle this specific property of MI2 inside processKeyboard ? - _keyPressed = event.kbd; - _keyPressed.ascii = event.kbd.keycode + 154; + } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'f') { + _fastMode ^= 1; + } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'g') { + _fastMode ^= 2; + } else if ((event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 'd') || + event.kbd.ascii == '~' || event.kbd.ascii == '#') { + _debugger->attach(); + } else if (event.kbd.flags == Common::KBD_CTRL && event.kbd.keycode == 's') { + _res->resourceStats(); } else { // Normal key press, pass on to the game. _keyPressed = event.kbd; } - if (event.kbd.keycode >= Common::KEYCODE_UP && event.kbd.keycode <= Common::KEYCODE_LEFT) { - if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) { - _keyPressed = event.kbd; - _keyPressed.ascii = event.kbd.ascii - Common::KEYCODE_UP + 54; - } else if (_game.version < 7) { - // FIXME: Handle this specific property inside processKeyboard ? - - // Don't let game see arrow keys. This fixes bug with up arrow (273) - // corresponding to the "instant win" cheat in MI2 mentioned above. - // - // This is not applicable to V7+ games, which need to see the arrow keys, - // too, else certain things (derby scene, asterorid lander) won't work. - _keyPressed.reset(); - } - } - if (_game.heversion >= 80) { // Keyboard is controlled via variable - int _keyState = 0; + int keyState = 0; if (event.kbd.keycode == Common::KEYCODE_LEFT) // Left - _keyState = 1; + keyState = 1; if (event.kbd.keycode == Common::KEYCODE_RIGHT) // Right - _keyState |= 2; + keyState |= 2; if (event.kbd.keycode == Common::KEYCODE_UP) // Up - _keyState |= 4; + keyState |= 4; if (event.kbd.keycode == Common::KEYCODE_DOWN) // Down - _keyState |= 8; + keyState |= 8; if (event.kbd.flags == Common::KBD_SHIFT) - _keyState |= 16; + keyState |= 16; if (event.kbd.flags == Common::KBD_CTRL) - _keyState |= 32; + keyState |= 32; - VAR(VAR_KEY_STATE) = _keyState; + VAR(VAR_KEY_STATE) = keyState; } - // FIXME: There is a discrepancy between EVENT_KEYDOWN and EVENT_KEYUP here: - // For EVENT_KEYDOWN, we use _keyPressed.keycode, which has potentially been - // modified, while for EVENT_KEYUP we use the unfiltered event.kbd.keycode. - // This could lead problems (like a key becoming 'stuck'). - - // FIXME #2: We are mixing ascii and keycode values here. We probably should - // be using keycodes, but at least INSANE checks for "Shift-V" by looking for - // the 'V' key being pressed. It would be easy to solve that by also storing the - // the modifier flags. However, since getKeyState() is also called by scripts, - // we have to be very careful with semantic changes. - // Nevertheless, it's bad to rely on "ascii" holdoing keycode values for special - // keys (like the function keys), so this should be fixed. - + // FIXME: We are using ASCII values to index the _keyDownMap here, + // yet later one code which checks _keyDownMap will use KEYCODEs + // to do so. That is, we are mixing ascii and keycode values here, + // which is bad. We probably should be only using keycodes, but at + // least INSANE checks for "Shift-V" by looking for the 'V' key + // being pressed. It would be easy to solve that by also storing + // the modifier flags. However, since getKeyState() is also called + // by scripts, we have to be careful with semantic changes. if (_keyPressed.ascii >= 512) debugC(DEBUG_GENERAL, "_keyPressed > 512 (%d)", _keyPressed.ascii); else @@ -159,11 +129,9 @@ void ScummEngine::parseEvents() { break; case Common::EVENT_KEYUP: - // FIXME: for some reason Common::KBD_ALT is set sometimes - // possible to a bug in sdl-common.cpp - if (event.kbd.ascii >= 512) + if (event.kbd.ascii >= 512) { debugC(DEBUG_GENERAL, "keyPressed > 512 (%d)", event.kbd.ascii); - else { + } else { _keyDownMap[event.kbd.ascii] = false; // Due to some weird bug with capslock key pressed @@ -173,6 +141,8 @@ void ScummEngine::parseEvents() { // both upper and lower letters are unpressed on keyup event // // Fixes bug #1709430: "FT: CAPSLOCK + V enables cheating for all fights" + // + // Fingolfin remarks: This wouldn't be a problem if we used keycodes. _keyDownMap[toupper(event.kbd.ascii)] = false; } break; @@ -204,24 +174,21 @@ void ScummEngine::parseEvents() { _rightBtnPressed &= ~msDown; break; - // The following two cases enable dialog choices to be - // scrolled through in the SegaCD version of MI - // as nothing else uses the wheel don't bother - // checking the gameid. Values are taken from script-14. - + // The following two cases enable dialog choices to be scrolled + // through in the SegaCD version of MI. Values are taken from script-14. + // See bug report #1193185 for details. case Common::EVENT_WHEELDOWN: - _keyPressed = Common::KeyState(Common::KEYCODE_7, 55); // '7' + if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) + _keyPressed = Common::KeyState(Common::KEYCODE_7, 55); // '7' break; case Common::EVENT_WHEELUP: - _keyPressed = Common::KeyState(Common::KEYCODE_6, 54); // '6' + if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) + _keyPressed = Common::KeyState(Common::KEYCODE_6, 54); // '6' break; case Common::EVENT_QUIT: - if (ConfMan.getBool("confirm_exit")) - confirmExitDialog(); - else - _quit = true; + _quit = true; break; default: @@ -446,11 +413,6 @@ void ScummEngine_v2::processKeyboard(Common::KeyState lastKeyHit) { // Fall back to default behavior ScummEngine::processKeyboard(lastKeyHit); - // Store the input type. So far we can't distinguish - // between 1, 3 and 5. - // 1) Verb 2) Scene 3) Inv. 4) Key - // 5) Sentence Bar - if (VAR_KEYPRESS != 0xFF && _mouseAndKeyboardStat) { // Key Input if (315 <= _mouseAndKeyboardStat && _mouseAndKeyboardStat <= 323) { // Convert F-Keys for V1/V2 games (they start at 1) @@ -503,12 +465,6 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) { if (_game.id == GID_CMI) mainmenuKeyEnabled = true; -/* - FIXME: We also used to force-enable F5 in Sam&Max and HE >= 72 games -- why? - if ((_game.version <= 3) || (_game.id == GID_SAMNMAX) || (_game.id == GID_CMI) || (_game.heversion >= 72)) - mainmenuKeyEnabled = true; -*/ - if (mainmenuKeyEnabled && (lastKeyHit.keycode == Common::KEYCODE_F5 && lastKeyHit.flags == 0)) { if (VAR_SAVELOAD_SCRIPT != 0xFF && _currentRoom != 0) runScript(VAR(VAR_SAVELOAD_SCRIPT), 0, 0, 0); @@ -569,15 +525,35 @@ void ScummEngine::processKeyboard(Common::KeyState lastKeyHit) { if (VAR_CHARINC != 0xFF) VAR(VAR_CHARINC) = _defaultTalkDelay; - } else if (lastKeyHit.ascii == '~' || lastKeyHit.ascii == '#') { // Debug console - _debugger->attach(); - } else { - // FIXME: Possibly convert even more keycode/ascii pairs to their SCUMM counterparts? - if (lastKeyHit.keycode >= Common::KEYCODE_F1 && lastKeyHit.keycode <= Common::KEYCODE_F9) + + if (lastKeyHit.keycode >= Common::KEYCODE_F1 && + lastKeyHit.keycode <= Common::KEYCODE_F9) { _mouseAndKeyboardStat = lastKeyHit.keycode - Common::KEYCODE_F1 + 315; - else + + } else if (_game.id == GID_MONKEY2 && (lastKeyHit.flags & Common::KBD_ALT)) { + // Handle KBD_ALT combos in MI2. We know that the result must be 273 for Alt-W + // because that's what MI2 looks for in its "instant win" cheat. + _mouseAndKeyboardStat = lastKeyHit.keycode + 154; + + } else if (lastKeyHit.keycode >= Common::KEYCODE_UP && + lastKeyHit.keycode <= Common::KEYCODE_LEFT) { + if (_game.id == GID_MONKEY && _game.platform == Common::kPlatformSegaCD) { + // Map arrow keys to number keys in the SEGA version of MI to support + // scrolling to conversation choices. See bug report #1193185 for details. + _mouseAndKeyboardStat = lastKeyHit.keycode - Common::KEYCODE_UP + 54; + } else if (_game.version >= 7) { + // Don't let pre-V7 game see arrow keys. This fixes bug with up arrow (273) + // corresponding to the "instant win" cheat in MI2 mentioned above. + // + // This is not applicable to V7+ games, which need to see the arrow keys, + // too, else certain things (derby scene, asterorid lander) won't work. + _mouseAndKeyboardStat = lastKeyHit.ascii; + } + + } else { _mouseAndKeyboardStat = lastKeyHit.ascii; + } } } diff --git a/engines/scumm/intern.h b/engines/scumm/intern.h index 008c2995e5..6723081dfe 100644 --- a/engines/scumm/intern.h +++ b/engines/scumm/intern.h @@ -313,7 +313,7 @@ protected: virtual void readGlobalObjects(); virtual void loadCharset(int no); - virtual void runInputScript(int a, int cmd, int mode); + virtual void runInputScript(int clickArea, int val, int mode); virtual void runInventoryScript(int i); virtual int getVar(); @@ -554,7 +554,7 @@ protected: int16 type; int16 dim2; byte data[1]; - }; + } PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/module.mk b/engines/scumm/module.mk index d7b858a312..d8ef669410 100644 --- a/engines/scumm/module.mk +++ b/engines/scumm/module.mk @@ -82,6 +82,12 @@ MODULE_OBJS += \ smush/saud_channel.o \ smush/smush_mixer.o \ smush/smush_font.o + +ifdef USE_ARM_SMUSH_ASM +MODULE_OBJS += \ + smush/codec47ARM.o +endif + endif ifndef DISABLE_HE diff --git a/engines/scumm/object.h b/engines/scumm/object.h index bf38d42289..f27e6a501e 100644 --- a/engines/scumm/object.h +++ b/engines/scumm/object.h @@ -91,7 +91,7 @@ struct RoomHeader { uint32 transparency; } v8; }; -}; +} PACKED_STRUCT; struct CodeHeader { union { @@ -123,7 +123,7 @@ struct CodeHeader { } v7; }; -}; +} PACKED_STRUCT; struct ImageHeader { /* file format */ union { @@ -172,7 +172,7 @@ struct ImageHeader { /* file format */ } hotspot[15]; } v8; }; -}; +} PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/player_v2.h b/engines/scumm/player_v2.h index 43771d295f..cd88d57602 100644 --- a/engines/scumm/player_v2.h +++ b/engines/scumm/player_v2.h @@ -61,7 +61,7 @@ struct channel_data { uint16 unknown[4]; // 38 - 44 uint16 music_timer; // 46 uint16 music_script_nr; // 48 -}; +} PACKED_STRUCT; #include "common/pack-end.h" // END STRUCT PACKING diff --git a/engines/scumm/saveload.cpp b/engines/scumm/saveload.cpp index 9578b05c1f..9d0d0ad654 100644 --- a/engines/scumm/saveload.cpp +++ b/engines/scumm/saveload.cpp @@ -200,8 +200,6 @@ bool ScummEngine::loadState(int slot, bool compat) { _engineStartTime = _system->getMillis() / 1000; } - _dialogStartTime = _system->getMillis() / 1000; - // Due to a bug in scummvm up to and including 0.3.0, save games could be saved // in the V8/V9 format but were tagged with a V7 mark. Ouch. So we just pretend V7 == V8 here if (hdr.ver == VER(7)) @@ -213,7 +211,7 @@ bool ScummEngine::loadState(int slot, bool compat) { // state for temporary state saves - such as certain cutscenes in DOTT, // FOA, Sam and Max, etc. // - // Thusly, we should probably not stop music when restoring from one of + // Thus, we should probably not stop music when restoring from one of // these saves. This change stops the Mole Man theme from going quiet in // Sam & Max when Doug tells you about the Ball of Twine, as mentioned in // patch #886058. @@ -378,9 +376,6 @@ bool ScummEngine::loadState(int slot, bool compat) { _sound->pauseSounds(false); - _engineStartTime += _system->getMillis() / 1000 - _dialogStartTime; - _dialogStartTime = 0; - return true; } diff --git a/engines/scumm/script.cpp b/engines/scumm/script.cpp index 46e4e64347..cc56adf622 100644 --- a/engines/scumm/script.cpp +++ b/engines/scumm/script.cpp @@ -1156,39 +1156,39 @@ void ScummEngine::checkAndRunSentenceScript() { runScript(sentenceScript, 0, 0, localParamList); } -void ScummEngine_v2::runInputScript(int a, int cmd, int mode) { +void ScummEngine_v2::runInputScript(int clickArea, int val, int mode) { int args[24]; int verbScript; verbScript = 4; - VAR(VAR_CLICK_AREA) = a; - switch (a) { - case 1: // Verb clicked - VAR(VAR_CLICK_VERB) = cmd; + VAR(VAR_CLICK_AREA) = clickArea; + switch (clickArea) { + case kVerbClickArea: // Verb clicked + VAR(VAR_CLICK_VERB) = val; break; - case 3: // Inventory clicked - VAR(VAR_CLICK_OBJECT) = cmd; + case kInventoryClickArea: // Inventory clicked + VAR(VAR_CLICK_OBJECT) = val; break; } memset(args, 0, sizeof(args)); - args[0] = a; - args[1] = cmd; + args[0] = clickArea; + args[1] = val; args[2] = mode; if (verbScript) runScript(verbScript, 0, 0, args); } -void ScummEngine::runInputScript(int a, int cmd, int mode) { +void ScummEngine::runInputScript(int clickArea, int val, int mode) { int args[24]; int verbScript; verbScript = VAR(VAR_VERB_SCRIPT); memset(args, 0, sizeof(args)); - args[0] = a; - args[1] = cmd; + args[0] = clickArea; + args[1] = val; args[2] = mode; // All HE 72+ games but only some HE 71 games. if (_game.heversion >= 71) { @@ -1198,18 +1198,18 @@ void ScummEngine::runInputScript(int a, int cmd, int mode) { // Macintosh verison of indy3ega used different interface, so adjust values. if (_game.id == GID_INDY3 && _game.platform == Common::kPlatformMacintosh) { - if (a == 1 && (cmd >= 101 && cmd <= 108)) { - if (cmd == 107) { + if (clickArea == kVerbClickArea && (val >= 101 && val <= 108)) { + if (val == 107) { VAR(67) -= 2; inventoryScript(); return; - } else if (cmd == 108) { + } else if (val == 108) { VAR(67) += 2; inventoryScript(); return; } else { args[0] = 3; - args[1] = VAR(83 + (cmd - 101)); + args[1] = VAR(83 + (val - 101)); } } } diff --git a/engines/scumm/scumm-md5.h b/engines/scumm/scumm-md5.h index 840940caa3..cd48ef4d02 100644 --- a/engines/scumm/scumm-md5.h +++ b/engines/scumm/scumm-md5.h @@ -1,5 +1,5 @@ /* - This file was generated by the md5table tool on Fri Jun 08 10:51:50 2007 + This file was generated by the md5table tool on Mon Jul 2 22:44:41 2007 DO NOT EDIT MANUALLY! */ @@ -254,6 +254,7 @@ static const MD5Table md5table[] = { { "6886e5d08cee329b1f2e743ae2e3ceed", "monkey2", "", "", 11135, Common::DE_DEU, Common::kPlatformPC }, { "695fe0b3963333b7e15b37514db3c745", "thinkerk", "", "Demo", 29789, Common::EN_USA, Common::kPlatformUnknown }, { "697c9b7c55a05d8199c48b48e379d2c8", "puttmoon", "", "", -1, Common::HB_ISR, Common::kPlatformPC }, + { "69d70269fafc4445adbb0d223e4f9a3f", "indy3", "EGA", "EGA", 5361, Common::EN_ANY, Common::kPlatformPC }, { "69ea626f1f87eecb78ea0d6c6b983a1d", "monkey2", "", "", -1, Common::IT_ITA, Common::kPlatformPC }, { "69ffe29185b8d71f09f6199f8b2a87cb", "lost", "HE 100", "", -1, Common::RU_RUS, Common::kPlatformWindows }, { "6a30a07f353a75cdc602db27d73e1b42", "puttputt", "HE 70", "", -1, Common::EN_ANY, Common::kPlatformWindows }, @@ -486,7 +487,7 @@ static const MD5Table md5table[] = { { "d8d07efcb88f396bee0b402b10c3b1c9", "maniac", "NES", "", -1, Common::EN_USA, Common::kPlatformNES }, { "d917f311a448e3cc7239c31bddb00dd2", "samnmax", "", "CD", 9080, Common::EN_ANY, Common::kPlatformUnknown }, { "d9d0dd93d16ab4dec55cabc2b86bbd17", "samnmax", "", "Demo", 6478, Common::EN_ANY, Common::kPlatformPC }, - { "da09e666fc8f5b78d7b0ac65d1a3b56e", "monkey2", "", "", -1, Common::EN_ANY, Common::kPlatformFMTowns }, + { "da09e666fc8f5b78d7b0ac65d1a3b56e", "monkey2", "", "", 11135, Common::EN_ANY, Common::kPlatformFMTowns }, { "da6269b18fcb08189c0aa9c95533cce2", "monkey", "CD", "CD", 8955, Common::IT_ITA, Common::kPlatformPC }, { "da669b20271b85182e9c17a2a37ea02e", "monkey2", "", "", -1, Common::DE_DEU, Common::kPlatformAmiga }, { "db21a6e338fe3b70c2723b6530865bf2", "PuttTime", "HE 85", "", -1, Common::FR_FRA, Common::kPlatformUnknown }, diff --git a/engines/scumm/scumm.cpp b/engines/scumm/scumm.cpp index 4b3a365394..2140b15544 100644 --- a/engines/scumm/scumm.cpp +++ b/engines/scumm/scumm.cpp @@ -120,7 +120,7 @@ ScummEngine::ScummEngine(OSystem *syst, const DetectorResult &dr) _gdi = new Gdi(this); } _res = new ResourceManager(this); - + // Convert MD5 checksum back into a digest for (int i = 0; i < 16; ++i) { char tmpStr[3] = "00"; @@ -2236,31 +2236,39 @@ void ScummEngine::startManiac() { #pragma mark --- GUI --- #pragma mark - -int ScummEngine::runDialog(Dialog &dialog) { - _dialogStartTime = _system->getMillis() / 1000; - - // Pause sound & video - bool old_soundsPaused = _sound->_soundsPaused; - _sound->pauseSounds(true); +void ScummEngine::pauseEngineIntern(bool pause) { + if (pause) { + // Record start of the pause, so that we can later + // adjust _engineStartTime accordingly. + _pauseStartTime = _system->getMillis(); - bool visible = CursorMan.isVisible(); + // Pause sound & video + _oldSoundsPaused = _sound->_soundsPaused; + _sound->pauseSounds(true); + + } else { + // Update the screen to make it less likely that the player will see a + // brief cursor palette glitch when the GUI is disabled. + _system->updateScreen(); - // Open & run the dialog - int result = dialog.runModal(); + // Resume sound & video + _sound->pauseSounds(_oldSoundsPaused); - // Restore old cursor - updateCursor(); - CursorMan.showMouse(visible); + // Adjust engine start time + _engineStartTime += (_system->getMillis() - _pauseStartTime) / 1000; + _pauseStartTime = 0; + } +} - // Update the screen to make it less likely that the player will see a - // brief cursor palette glitch when the GUI is disabled. - _system->updateScreen(); +int ScummEngine::runDialog(Dialog &dialog) { + // Pause engine + pauseEngine(true); - // Resume sound & video - _sound->pauseSounds(old_soundsPaused); + // Open & run the dialog + int result = dialog.runModal(); - _engineStartTime += (_system->getMillis() / 1000) - _dialogStartTime; - _dialogStartTime = 0; + // Resume engine + pauseEngine(false); // Return the result return result; diff --git a/engines/scumm/scumm.h b/engines/scumm/scumm.h index 8c8124714d..4146846856 100644 --- a/engines/scumm/scumm.h +++ b/engines/scumm/scumm.h @@ -406,9 +406,6 @@ class ScummEngine : public Engine { friend class CharsetRenderer; friend class ResourceManager; - GUI::Debugger *getDebugger(); - void errorString(const char *buf_input, char *buf_output); - public: /* Put often used variables at the top. * That results in a shorter form of the opcode @@ -437,17 +434,20 @@ public: protected: VirtualMachineState vm; + + bool _oldSoundsPaused; public: // Constructor / Destructor ScummEngine(OSystem *syst, const DetectorResult &dr); virtual ~ScummEngine(); - /** Startup function, main loop. */ - int go(); - - // Init functions - int init(); + // Engine APIs + virtual int init(); + virtual int go(); + virtual void errorString(const char *buf_input, char *buf_output); + virtual GUI::Debugger *getDebugger(); + virtual void pauseEngineIntern(bool pause); protected: virtual void setupScumm(); @@ -638,7 +638,7 @@ protected: void saveInfos(Common::OutSaveFile* file); int32 _engineStartTime; - int32 _dialogStartTime; + int32 _pauseStartTime; protected: /* Script VM - should be in Script class */ @@ -863,7 +863,7 @@ protected: void verbMouseOver(int verb); int findVerbAtPos(int x, int y) const; virtual void drawVerb(int verb, int mode); - virtual void runInputScript(int a, int cmd, int mode); + virtual void runInputScript(int clickArea, int val, int mode); void restoreVerbBG(int verb); void drawVerbBitmap(int verb, int x, int y); int getVerbSlot(int id, int mode) const; diff --git a/engines/scumm/smush/codec47.cpp b/engines/scumm/smush/codec47.cpp index 34d61d1c8a..6904e96c11 100644 --- a/engines/scumm/smush/codec47.cpp +++ b/engines/scumm/smush/codec47.cpp @@ -342,6 +342,24 @@ void Codec47Decoder::makeTables47(int width) { } while (c < 32768); } +#ifdef USE_ARM_SMUSH_ASM + +extern "C" void ARM_Smush_decode2( byte *dst, + const byte *src, + int width, + int height, + const byte *param_ptr, + int16 *_table, + byte *_tableBig, + int32 offset1, + int32 offset2, + byte *_tableSmall); + +#define decode2(SRC,DST,WIDTH,HEIGHT,PARAM) \ + ARM_Smush_decode2(SRC,DST,WIDTH,HEIGHT,PARAM,_table,_tableBig, \ + _offset1,_offset2,_tableSmall) + +#else void Codec47Decoder::level3(byte *d_dst) { int32 tmp; byte code = *_d_src++; @@ -503,6 +521,7 @@ void Codec47Decoder::decode2(byte *dst, const byte *src, int width, int height, dst += next_line; } while (--bh); } +#endif Codec47Decoder::Codec47Decoder(int width, int height) { _width = width; diff --git a/engines/scumm/smush/codec47ARM.s b/engines/scumm/smush/codec47ARM.s new file mode 100644 index 0000000000..d96049a32c --- /dev/null +++ b/engines/scumm/smush/codec47ARM.s @@ -0,0 +1,372 @@ +@ ScummVM - Graphic Adventure Engine +@ +@ ScummVM is the legal property of its developers, whose names +@ are too numerous to list here. Please refer to the COPYRIGHT +@ file distributed with this source distribution. +@ +@ This program is free software@ you can redistribute it and/or +@ modify it under the terms of the GNU General Public License +@ as published by the Free Software Foundation@ either version 2 +@ of the License, or (at your option) any later version. +@ +@ This program is distributed in the hope that it will be useful, +@ but WITHOUT ANY WARRANTY@ without even the implied warranty of +@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +@ GNU General Public License for more details. +@ +@ You should have received a copy of the GNU General Public License +@ along with this program@ if not, write to the Free Software +@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +@ +@ $URL:$ +@ $Id:$ +@ +@ @author Robin Watts (robin@wss.co.uk) +@ +@ This file, provides an ARM optimised version of sections of codec47.cpp. +@ The algorithm is essentially the same as that within codec47.cpp +@ so to understand this file you should understand codec47.cpp first. + + .text + + .global ARM_Smush_decode2 + +ARM_Smush_decode2: + @ r0 = dst + @ r1 = src + @ r2 = width + @ r3 = height + @ r4 = param + @ <> = _table + @ <> = _tableBig + @ <> = _offset1 + @ <> = _offset2 + @ <> = _tableSmall + STMFD r13!,{r2,r4-r11,R14} + + LDR r4,[r13,#(9+1)*4] @ r4 = param + @ stall + @ stall + SUB r4,r4,#0xF8 + + @ r0 = dst + @ r1 = _d_src + @ r2 = _d_pitch + @ r3 = height + @ r4 = param + ADD r7,r2,#7 @ r14 = bw + MOV r7,r7,LSR #3 +y_loop: +x_loop: + @ LEVEL 1 + LDRB r6,[r1],#1 @ r6 = *_d_src++ + @ stall + @ stall + CMP r6,#0xF8 + BLT level1codeSMALL + CMP r6,#0xFC + BLT level1codeMID + BEQ level1codeFC + CMP r6,#0xFE + BGT level1codeFF + BEQ level1codeFE +level1codeFD: + LDRB r6,[r1],#1 @ r6 = tmp = *_d_src++ + LDR r8,[r13,#(9+1+2)*4] @ r8 = _tableBig + @ stall + ADD r12,r6,r6,LSL #1 @ r12= tmp*3 + ADD r6,r6,r12,LSL #5 @ r6 = tmp*97 + ADD r8,r8,r6,LSL #2 @ r8 = _tableBig + tmp*388 + LDRB r9,[r8,#384] @ r9 = l = tmp_ptr[384] + LDRB r6,[r1],#1 @ r6 = val = *_d_src++ + ADD r12,r8,#384 @ r12= &tmp_ptr[384] + @ I don't really believe the next 2 lines are necessary, but... + CMP r9,#0 + BEQ level1codeFD_over1 +level1codeFD_loop1: + LDRB r10,[r8],#1 + LDRB r11,[r8],#1 + SUBS r9,r9,#1 + ADD r10,r10,r0 + STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val + BGT level1codeFD_loop1 +level1codeFD_over1: + LDRB r9,[r12,#1] @ r9 = l = tmp_ptr[385] + LDRB r6,[r1],#1 @ r6 = val = *_d_src++ + SUB r12,r12,#384-128 @ r12= &tmp_ptr[128] + @ I don't really believe the next 2 lines are necessary, but... + CMP r9,#0 + BEQ level1codeFD_over2 +level1codeFD_loop2: + LDRB r10,[r12],#1 + LDRB r11,[r12],#1 + SUBS r9,r9,#1 + ADD r10,r10,r0 + STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val + BGT level1codeFD_loop2 +level1codeFD_over2: +level1_end: + + ADD r0,r0,#8 + SUBS r7,r7,#1 + BGT x_loop + + ADD r7,r2,#7 + MOV r7,r7,LSR #3 + ADD r0,r0,r2,LSL #3 + SUB r0,r0,r7,LSL #3 @ r0 = dst += next_line + SUBS r3,r3,#8 @ if (--bh > 0) + BGT y_loop @ loop back + + LDMFD r13!,{r2,r4-r11,PC} + +level1codeSMALL: + LDR r8,[r13,#(9+1+1)*4] @ r8 = _table + LDR r9,[r13,#(9+1+3)*4] @ r9 = _offset1 + MOV r6,r6,LSL #1 @ r6 = code<<1 + LDRSH r8,[r8,r6] @ tmp2 = _table[code] +level1codeFC: + @ EQ => FC + LDREQ r9,[r13,#(9+1+4)*4] @ r9 = _offset2 + MOVEQ r8,#0 + SUB r11,r2,#7 @ r11 = _d_pitch-7 + ADD r9,r9,r0 @ tmp2 = _d_dst+_offset + ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset + @ r8 = &_dst[tmp2] + MOV r12,#8 +level1codeSMALL_loop: + LDRB r5, [r8],#1 @ r5 = d_dst[tmp2] + LDRB r6, [r8],#1 @ r10 = d_dst[tmp2] + LDRB r9, [r8],#1 @ r10 = d_dst[tmp2] + LDRB r10,[r8],#1 @ r10 = d_dst[tmp2] + STRB r5, [r0],#1 @ d_dst[0] = r5 + STRB r6, [r0],#1 @ d_dst[1] = r6 + STRB r9, [r0],#1 @ d_dst[2] = r9 + STRB r10,[r0],#1 @ d_dst[3] = r10 + LDRB r5, [r8],#1 @ r5 = d_dst[tmp2] + LDRB r6, [r8],#1 @ r10 = d_dst[tmp2] + LDRB r9, [r8],#1 @ r10 = d_dst[tmp2] + LDRB r10,[r8],r11 @ r10 = d_dst[tmp2] + STRB r5, [r0],#1 @ d_dst[4] = r5 + STRB r6, [r0],#1 @ d_dst[5] = r6 + STRB r9, [r0],#1 @ d_dst[6] = r9 + STRB r10,[r0],r11 @ d_dst[7] = r10 d_dst += d_pitch + SUBS r12,r12,#1 + BGT level1codeSMALL_loop + SUB r0,r0,r2,LSL #3 @ revert d_dst + B level1_end + +level1codeMID: + @ LT => F8<=code<FC case + @ EQ => FE case + LDRB r6,[r4,r6] @ r6 = t = _paramPtr[code] +level1codeFE: + LDREQB r6,[r1],#1 @ r6 = t = *_d_src++ + MOV r12,#8 + SUB r11,r2,#7 @ r11 = _d_pitch-7 +level1codeMID_loop: + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],r11 + SUBS r12,r12,#1 + BGT level1codeMID_loop + SUB r0,r0,r2,LSL #3 @ revert d_dst + B level1_end + +level1codeFF: + BL level2 + ADD r0,r0,#4 + BL level2 + ADD r0,r0,r2,LSL #2 + SUB r0,r0,#4 + BL level2 + ADD r0,r0,#4 + BL level2 + SUB r0,r0,#4 + SUB r0,r0,r2,LSL #2 + B level1_end + +level2: + @ r0 = _d_dst + @ r1 = _d_src + @ r2 = _d_pitch + @ r3 = PRESERVE + @ r4 = param + @ r7 = PRESERVE + @ r14= return address + LDRB r6,[r1],#1 @ r6 = *_d_src++ + @ stall + @ stall + CMP r6,#0xF8 + BLT level2codeSMALL + CMP r6,#0xFC + BLT level2codeMID + BEQ level2codeFC + CMP r6,#0xFE + BGT level2codeFF + BEQ level2codeFE +level2codeFD: + LDRB r6,[r1],#1 @ r6 = tmp = *_d_src++ + LDR r8,[r13,#(9+1+5)*4] @ r8 = _tableSmall + @ stall + @ stall + ADD r8,r8,r6,LSL #7 @ r8 = _tableSmall + tmp*128 + LDRB r9,[r8,#96] @ r9 = l = tmp_ptr[96] + LDRB r6,[r1],#1 @ r6 = val = *_d_src++ + ADD r12,r8,#32 @ r12 = tmp_ptr + 32 + @ I don't really believe the next 2 lines are necessary, but... + CMP r9,#0 + BEQ level2codeFD_over1 +level2codeFD_loop1: + LDRB r10,[r8],#1 + LDRB r11,[r8],#1 + SUBS r9,r9,#1 + ADD r10,r10,r0 + STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val + BGT level2codeFD_loop1 +level2codeFD_over1: + LDRB r9,[r12,#97-32] @ r9 = l = tmp_ptr[97] + LDRB r6,[r1],#1 @ r6 = val = *_d_src++ + @ I don't really believe the next 2 lines are necessary, but... + CMP r9,#0 + MOVEQ PC,R14 +level2codeFD_loop2: + LDRB r10,[r12],#1 + LDRB r11,[r12],#1 + SUBS r9,r9,#1 + ADD r10,r10,r0 + STRB r6,[r10,r11,LSL #8] @ *(_d_dst + (*tmp_ptr2++)) = val + BGT level2codeFD_loop2 + + MOV PC,R14 + +level2codeSMALL: + LDR r8,[r13,#(9+1+1)*4] @ r8 = _table + LDR r9,[r13,#(9+1+3)*4] @ r9 = _offset1 + MOV r6,r6,LSL #1 @ r6 = code<<1 + LDRSH r8,[r8,r6] @ tmp2 = _table[code] +level2codeFC: + @ EQ => FC + LDREQ r9,[r13,#(9+1+4)*4] @ r9 = _offset2 + MOVEQ r8,#0 + SUB r11,r2,#3 @ r11 = _d_pitch-3 + ADD r9,r9,r0 @ tmp2 = _d_dst + _table[code] + ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset1 + @ r8 = &_dst[tmp2] + MOV r12,#4 +level2codeSMALL_loop: + LDRB r5, [r8],#1 @ r5 = d_dst[tmp2] + LDRB r6, [r8],#1 @ r10 = d_dst[tmp2] + LDRB r9, [r8],#1 @ r10 = d_dst[tmp2] + LDRB r10,[r8],r11 @ r10 = d_dst[tmp2] + STRB r5, [r0],#1 @ d_dst[4] = r5 + STRB r6, [r0],#1 @ d_dst[5] = r6 + STRB r9, [r0],#1 @ d_dst[6] = r9 + STRB r10,[r0],r11 @ d_dst[7] = r10 d_dst += d_pitch + SUBS r12,r12,#1 + BGT level2codeSMALL_loop + SUB r0,r0,r2,LSL #2 @ revert d_dst + MOV PC,R14 + +level2codeMID: + @ LT => F8<=code<FC case + @ EQ => FE case + LDRB r6,[r4,r6] @ r6 = t = _paramPtr[code] +level2codeFE: + LDREQB r6,[r1],#1 @ r6 = t = *_d_src++ + MOV r12,#4 + SUB r11,r2,#3 @ r11 = _d_pitch-7 +level2codeMID_loop: + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],#1 + STRB r6,[r0],r11 + SUBS r12,r12,#1 + BGT level2codeMID_loop + SUB r0,r0,r2,LSL #2 @ revert d_dst + MOV PC,R14 + +level2codeFF: + MOV r5,r14 + BL level3 + ADD r0,r0,#2 + BL level3 + ADD r0,r0,r2,LSL #1 + SUB r0,r0,#2 + BL level3 + ADD r0,r0,#2 + BL level3 + SUB r0,r0,#2 + SUB r0,r0,r2,LSL #1 + MOV PC,R5 + +level3: + @ r0 = _d_dst + @ r1 = _d_src + @ r2 = _d_pitch + @ r3 = PRESERVE + @ r4 = param + @ r5 = preserve + @ r7 = PRESERVE + @ r14= return address + LDRB r6,[r1],#1 @ r6 = code = *_d_src++ + @ stall + @ stall + CMP r6,#0xF8 + BLT level3codeSMALL + CMP r6,#0xFC + BLT level3codeMID + BEQ level3codeFC + CMP r6,#0xFE + BGT level3codeFF +level3codeFE: + LDRB r6,[r1],#1 @ r6 = t = *_d_src++ +level3codeMID: + @ LT => F8<=code<FC case + @ EQ => FE case + LDRLTB r6,[r4,r6] @ r6 = t = _paramPtr[code] + @ stall + @ stall + STRB r6,[r0,#1] + STRB r6,[r0],r2 + STRB r6,[r0,#1] + STRB r6,[r0],-r2 + MOV PC,R14 + +level3codeFF: + LDRB r6,[r1],#1 + LDRB r9,[r1],#1 + LDRB r10,[r1],#1 + LDRB r11,[r1],#1 + STRB r9, [r0,#1] + STRB r6, [r0],r2 + STRB r11,[r0,#1] + STRB r10,[r0],-r2 + MOV PC,R14 + +level3codeSMALL: + LDR r8,[r13,#(9+1+1)*4] @ r8 = _table + LDR r9,[r13,#(9+1+3)*4] @ r9 = _offset1 + MOV r6,r6,LSL #1 @ r6 = code<<1 + LDRSH r8,[r8,r6] @ tmp2 = _table[code] +level3codeFC: + @ EQ => FC + LDREQ r9,[r13,#(9+1+4)*4] @ r9 = _offset2 + MOVEQ r8,#0 + ADD r9,r9,r0 @ tmp2 = _d_dst+offset + ADD r8,r8,r9 @ tmp2 = _d_dst+_table[code]+_offset + @ r8 = &_dst[tmp2] + LDRB r6, [r8,#1] @ r6 = d_dst[tmp2+1] + LDRB r9, [r8],r2 @ r9 = d_dst[tmp2+0] + LDRB r10,[r8,#1] @ r10= d_dst[tmp2+dst+1] + LDRB r11,[r8],-r2 @ r11= d_dst[tmp2+dst] + STRB r6, [r0,#1] @ d_dst[1 ] = r6 + STRB r9, [r0],r2 @ d_dst[0 ] = r9 + STRB r10,[r0,#1] @ d_dst[dst+1] = r10 + STRB r11,[r0],-r2 @ d_dst[dst ] = r11 + MOV PC,R14 diff --git a/engines/scumm/verbs.cpp b/engines/scumm/verbs.cpp index edd8004d30..56ee454240 100644 --- a/engines/scumm/verbs.cpp +++ b/engines/scumm/verbs.cpp @@ -385,7 +385,7 @@ void ScummEngine_v2::checkV2Inventory(int x, int y) { runObject(_activeInventory, _activeVerb); } } else { - runInputScript(3, object, 0); + runInputScript(kInventoryClickArea, object, 0); } } } @@ -537,7 +537,7 @@ void ScummEngine::checkExecVerbs() { if (vs->verbid && vs->saveid == 0 && vs->curmode == 1) { if (_mouseAndKeyboardStat == vs->key) { // Trigger verb as if the user clicked it - runInputScript(1, vs->verbid, 1); + runInputScript(kVerbClickArea, vs->verbid, 1); return; } } @@ -580,14 +580,14 @@ void ScummEngine::checkExecVerbs() { // Check if person is available (see script 23 from ZAK_FM-TOWNS and script 4 from ZAK_PC). // Zak: Var[144 Bit 15], Annie: Var[145 Bit 0], Melissa: Var[145 Bit 1], Leslie: Var[145 Bit 2] if (!readVar(0x890E + fKey)) { - runInputScript(1, 36 + fKey, 0); + runInputScript(kVerbClickArea, 36 + fKey, 0); } } return; } // Generic keyboard input - runInputScript(4, _mouseAndKeyboardStat, 1); + runInputScript(kKeyClickArea, _mouseAndKeyboardStat, 1); } else if (_mouseAndKeyboardStat & MBS_MOUSE_MASK) { VirtScreen *zone = findVirtScreen(_mouse.y); byte code = _mouseAndKeyboardStat & MBS_LEFT_CLICK ? 1 : 2; @@ -600,7 +600,7 @@ void ScummEngine::checkExecVerbs() { if (_game.version <= 2 && zone->number == kVerbVirtScreen && _mouse.y <= zone->topline + 8) { // Click into V2 sentence line - runInputScript(5, 0, 0); + runInputScript(kSentenceClickArea, 0, 0); } else if (_game.version <= 2 && zone->number == kVerbVirtScreen && _mouse.y > zone->topline + inventoryArea) { // Click into V2 inventory ((ScummEngine_v2 *)this)->checkV2Inventory(_mouse.x, _mouse.y); @@ -608,10 +608,10 @@ void ScummEngine::checkExecVerbs() { over = findVerbAtPos(_mouse.x, _mouse.y); if (over != 0) { // Verb was clicked - runInputScript(1, _verbs[over].verbid, code); + runInputScript(kVerbClickArea, _verbs[over].verbid, code); } else { // Scene was clicked - runInputScript((zone->number == kMainVirtScreen) ? 2 : 1, 0, code); + runInputScript((zone->number == kMainVirtScreen) ? kSceneClickArea : kVerbClickArea, 0, code); } } } diff --git a/engines/scumm/verbs.h b/engines/scumm/verbs.h index 47fa98a9de..96a49a7ced 100644 --- a/engines/scumm/verbs.h +++ b/engines/scumm/verbs.h @@ -30,6 +30,18 @@ namespace Scumm { +/** + * The area in which some click (or key press) occured and which is passed + * to the input script. + */ +enum ClickArea { + kVerbClickArea = 1, + kSceneClickArea = 2, + kInventoryClickArea = 3, + kKeyClickArea = 4, + kSentenceClickArea = 5 +}; + enum { kTextVerbType = 0, kImageVerbType = 1 |