aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm
diff options
context:
space:
mode:
authorDavid Corrales2007-07-08 16:58:54 +0000
committerDavid Corrales2007-07-08 16:58:54 +0000
commit9bfe5d53540af7dc9bf0214202f4e35b272320ea (patch)
tree69dcaf6f735e9fd0913a3e2f163852d4b9af87e3 /engines/scumm
parent256e4d9521b79160d1f9ed670656097a96dc5a34 (diff)
parent17da12ca07a1f18f3fe1ef5b0c2c0cd9fd8359b4 (diff)
downloadscummvm-rg350-9bfe5d53540af7dc9bf0214202f4e35b272320ea.tar.gz
scummvm-rg350-9bfe5d53540af7dc9bf0214202f4e35b272320ea.tar.bz2
scummvm-rg350-9bfe5d53540af7dc9bf0214202f4e35b272320ea.zip
Merged the FSNode branch with trunk r27681:27969
svn-id: r27970
Diffstat (limited to 'engines/scumm')
-rw-r--r--engines/scumm/akos.cpp4
-rw-r--r--engines/scumm/base-costume.h2
-rw-r--r--engines/scumm/boxes.cpp2
-rw-r--r--engines/scumm/detection.cpp21
-rw-r--r--engines/scumm/dialogs.cpp32
-rw-r--r--engines/scumm/dialogs.h14
-rw-r--r--engines/scumm/file.cpp3
-rw-r--r--engines/scumm/he/intern_he.h2
-rw-r--r--engines/scumm/he/resource_he.h40
-rw-r--r--engines/scumm/imuse/instrument.cpp8
-rw-r--r--engines/scumm/input.cpp150
-rw-r--r--engines/scumm/intern.h4
-rw-r--r--engines/scumm/module.mk6
-rw-r--r--engines/scumm/object.h6
-rw-r--r--engines/scumm/player_v2.h2
-rw-r--r--engines/scumm/saveload.cpp7
-rw-r--r--engines/scumm/script.cpp32
-rw-r--r--engines/scumm/scumm-md5.h5
-rw-r--r--engines/scumm/scumm.cpp48
-rw-r--r--engines/scumm/scumm.h20
-rw-r--r--engines/scumm/smush/codec47.cpp19
-rw-r--r--engines/scumm/smush/codec47ARM.s372
-rw-r--r--engines/scumm/verbs.cpp14
-rw-r--r--engines/scumm/verbs.h12
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