aboutsummaryrefslogtreecommitdiff
path: root/engines/sci/event.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci/event.cpp')
-rw-r--r--engines/sci/event.cpp174
1 files changed, 121 insertions, 53 deletions
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
index b1c002413d..4ad2a0cfa3 100644
--- a/engines/sci/event.cpp
+++ b/engines/sci/event.cpp
@@ -29,6 +29,9 @@
#include "sci/console.h"
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
+#ifdef ENABLE_SCI32
+#include "sci/graphics/frameout.h"
+#endif
#include "sci/graphics/screen.h"
namespace Sci {
@@ -38,13 +41,13 @@ struct ScancodeRow {
const char *keys;
};
-const ScancodeRow s_scancodeRows[] = {
+static const ScancodeRow scancodeAltifyRows[] = {
{ 0x10, "QWERTYUIOP[]" },
{ 0x1e, "ASDFGHJKL;'\\" },
{ 0x2c, "ZXCVBNM,./" }
};
-const byte codepagemap_88591toDOS[0x80] = {
+static const byte codePageMap88591ToDOS[0x80] = {
'?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', // 0x8x
'?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', '?', // 0x9x
'?', 0xad, 0x9b, 0x9c, '?', 0x9d, '?', 0x9e, '?', '?', 0xa6, 0xae, 0xaa, '?', '?', '?', // 0xAx
@@ -61,7 +64,7 @@ struct SciKeyConversion {
int sciKeyNumlockOn;
};
-const SciKeyConversion keyMappings[] = {
+static const SciKeyConversion keyMappings[] = {
{ Common::KEYCODE_UP , SCI_KEY_UP , SCI_KEY_UP },
{ Common::KEYCODE_DOWN , SCI_KEY_DOWN , SCI_KEY_DOWN },
{ Common::KEYCODE_RIGHT , SCI_KEY_RIGHT , SCI_KEY_RIGHT },
@@ -94,16 +97,15 @@ const SciKeyConversion keyMappings[] = {
struct MouseEventConversion {
Common::EventType commonType;
short sciType;
- short data;
};
-const MouseEventConversion mouseEventMappings[] = {
- { Common::EVENT_LBUTTONDOWN, SCI_EVENT_MOUSE_PRESS, 1 },
- { Common::EVENT_RBUTTONDOWN, SCI_EVENT_MOUSE_PRESS, 2 },
- { Common::EVENT_MBUTTONDOWN, SCI_EVENT_MOUSE_PRESS, 3 },
- { Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 1 },
- { Common::EVENT_RBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 2 },
- { Common::EVENT_MBUTTONUP, SCI_EVENT_MOUSE_RELEASE, 3 }
+static const MouseEventConversion mouseEventMappings[] = {
+ { Common::EVENT_LBUTTONDOWN, SCI_EVENT_MOUSE_PRESS },
+ { Common::EVENT_RBUTTONDOWN, SCI_EVENT_MOUSE_PRESS },
+ { Common::EVENT_MBUTTONDOWN, SCI_EVENT_MOUSE_PRESS },
+ { Common::EVENT_LBUTTONUP, SCI_EVENT_MOUSE_RELEASE },
+ { Common::EVENT_RBUTTONUP, SCI_EVENT_MOUSE_RELEASE },
+ { Common::EVENT_MBUTTONUP, SCI_EVENT_MOUSE_RELEASE }
};
EventManager::EventManager(bool fontIsExtended) : _fontIsExtended(fontIsExtended) {
@@ -117,9 +119,9 @@ static int altify(int ch) {
int row;
int c = toupper((char)ch);
- for (row = 0; row < ARRAYSIZE(s_scancodeRows); row++) {
- const char *keys = s_scancodeRows[row].keys;
- int offset = s_scancodeRows[row].offset;
+ for (row = 0; row < ARRAYSIZE(scancodeAltifyRows); row++) {
+ const char *keys = scancodeAltifyRows[row].keys;
+ int offset = scancodeAltifyRows[row].offset;
while (*keys) {
if (*keys == c)
@@ -134,8 +136,13 @@ static int altify(int ch) {
}
SciEvent EventManager::getScummVMEvent() {
- SciEvent input = { SCI_EVENT_NONE, 0, 0, 0, Common::Point(0, 0) };
- SciEvent noEvent = { SCI_EVENT_NONE, 0, 0, 0, Common::Point(0, 0) };
+#ifdef ENABLE_SCI32
+ SciEvent input = { SCI_EVENT_NONE, 0, 0, Common::Point(), Common::Point() };
+ SciEvent noEvent = { SCI_EVENT_NONE, 0, 0, Common::Point(), Common::Point() };
+#else
+ SciEvent input = { SCI_EVENT_NONE, 0, 0, Common::Point() };
+ SciEvent noEvent = { SCI_EVENT_NONE, 0, 0, Common::Point() };
+#endif
Common::EventManager *em = g_system->getEventManager();
Common::Event ev;
@@ -156,7 +163,20 @@ SciEvent EventManager::getScummVMEvent() {
// via pollEvent.
// We also adjust the position based on the scaling of the screen.
Common::Point mousePos = em->getMousePos();
- g_sci->_gfxScreen->adjustBackUpscaledCoordinates(mousePos.y, mousePos.x);
+
+#if ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2) {
+ const Buffer &screen = g_sci->_gfxFrameout->getCurrentBuffer();
+
+ Common::Point mousePosSci = mousePos;
+ mulru(mousePosSci, Ratio(screen.scriptWidth, screen.screenWidth), Ratio(screen.scriptHeight, screen.screenHeight));
+ noEvent.mousePosSci = input.mousePosSci = mousePosSci;
+ } else {
+#endif
+ g_sci->_gfxScreen->adjustBackUpscaledCoordinates(mousePos.y, mousePos.x);
+#if ENABLE_SCI32
+ }
+#endif
noEvent.mousePos = input.mousePos = mousePos;
@@ -174,11 +194,50 @@ SciEvent EventManager::getScummVMEvent() {
return input;
}
+ int scummVMKeyFlags;
+
+ switch (ev.type) {
+ case Common::EVENT_KEYDOWN:
+ case Common::EVENT_KEYUP:
+ // Use keyboard modifiers directly in case this is a keyboard event
+ scummVMKeyFlags = ev.kbd.flags;
+ break;
+ default:
+ // Otherwise get them from EventManager
+ scummVMKeyFlags = em->getModifierState();
+ break;
+ }
+
+ input.modifiers =
+ ((scummVMKeyFlags & Common::KBD_ALT) ? SCI_KEYMOD_ALT : 0) |
+ ((scummVMKeyFlags & Common::KBD_CTRL) ? SCI_KEYMOD_CTRL : 0) |
+ ((scummVMKeyFlags & Common::KBD_SHIFT) ? SCI_KEYMOD_LSHIFT | SCI_KEYMOD_RSHIFT : 0);
+ // Caps lock and Scroll lock have been removed, cause we already handle upper
+ // case keys and Scroll lock doesn't seem to be used anywhere
+ //((ourModifiers & Common::KBD_CAPS) ? SCI_KEYMOD_CAPSLOCK : 0) |
+ //((ourModifiers & Common::KBD_SCRL) ? SCI_KEYMOD_SCRLOCK : 0) |
+
// Handle mouse events
for (int i = 0; i < ARRAYSIZE(mouseEventMappings); i++) {
if (mouseEventMappings[i].commonType == ev.type) {
input.type = mouseEventMappings[i].sciType;
- input.data = mouseEventMappings[i].data;
+ // Sierra passed keyboard modifiers for mouse events, too.
+
+ // Sierra also set certain modifiers within their mouse interrupt handler
+ // This whole thing was probably meant for people using a mouse, that only featured 1 button
+ // So the user was able to press Ctrl and click the mouse button to create a right click.
+ switch (ev.type) {
+ case Common::EVENT_RBUTTONDOWN: // right button
+ case Common::EVENT_RBUTTONUP:
+ input.modifiers |= (SCI_KEYMOD_RSHIFT | SCI_KEYMOD_LSHIFT); // this value was hardcoded in the mouse interrupt handler
+ break;
+ case Common::EVENT_MBUTTONDOWN: // middle button
+ case Common::EVENT_MBUTTONUP:
+ input.modifiers |= SCI_KEYMOD_CTRL; // this value was hardcoded in the mouse interrupt handler
+ break;
+ default:
+ break;
+ }
return input;
}
}
@@ -187,7 +246,7 @@ SciEvent EventManager::getScummVMEvent() {
if (ev.type != Common::EVENT_KEYDOWN)
return noEvent;
- // Check for Control-D (debug console)
+ // Check for Control-Shift-D (debug console)
if (ev.kbd.hasFlags(Common::KBD_CTRL | Common::KBD_SHIFT) && ev.kbd.keycode == Common::KEYCODE_d) {
// Open debug console
Console *con = g_sci->getSciDebugger();
@@ -197,24 +256,23 @@ SciEvent EventManager::getScummVMEvent() {
// Process keyboard events
- int modifiers = em->getModifierState();
bool numlockOn = (ev.kbd.flags & Common::KBD_NUM);
- input.data = ev.kbd.keycode;
+ Common::KeyCode scummVMKeycode = ev.kbd.keycode;
+
input.character = ev.kbd.ascii;
input.type = SCI_EVENT_KEYBOARD;
- input.modifiers =
- ((modifiers & Common::KBD_ALT) ? SCI_KEYMOD_ALT : 0) |
- ((modifiers & Common::KBD_CTRL) ? SCI_KEYMOD_CTRL : 0) |
- ((modifiers & Common::KBD_SHIFT) ? SCI_KEYMOD_LSHIFT | SCI_KEYMOD_RSHIFT : 0);
-
- // Caps lock and Scroll lock have been removed, cause we already handle upper
- // case keys ad Scroll lock doesn't seem to be used anywhere
- //((ev.kbd.flags & Common::KBD_CAPS) ? SCI_KEYMOD_CAPSLOCK : 0) |
- //((ev.kbd.flags & Common::KBD_SCRL) ? SCI_KEYMOD_SCRLOCK : 0) |
+ if (scummVMKeycode >= Common::KEYCODE_KP0 && scummVMKeycode <= Common::KEYCODE_KP9) {
+ if (!(scummVMKeyFlags & Common::KBD_NUM)) {
+ // HACK: Num-Lock not enabled
+ // We shouldn't get a valid ascii code in these cases. We fix it here, so that cursor keys
+ // on the numpad work properly.
+ input.character = 0;
+ }
+ }
- if (!(input.data & 0xFF00)) {
+ if ((input.character) && (input.character <= 0xFF)) {
// Directly accept most common keys without conversion
if ((input.character >= 0x80) && (input.character <= 0xFF)) {
// If there is no extended font, we will just clear the
@@ -228,26 +286,27 @@ SciEvent EventManager::getScummVMEvent() {
return noEvent;
// Convert 8859-1 characters to DOS (cp850/437) for
// multilingual SCI01 games
- input.character = codepagemap_88591toDOS[input.character & 0x7f];
+ input.character = codePageMap88591ToDOS[input.character & 0x7f];
}
- if (input.data == Common::KEYCODE_TAB) {
- input.character = input.data = SCI_KEY_TAB;
- if (modifiers & Common::KBD_SHIFT)
+ if (scummVMKeycode == Common::KEYCODE_TAB) {
+ input.character = SCI_KEY_TAB;
+ if (scummVMKeyFlags & Common::KBD_SHIFT)
input.character = SCI_KEY_SHIFT_TAB;
}
- if (input.data == Common::KEYCODE_DELETE)
- input.data = input.character = SCI_KEY_DELETE;
- } else if ((input.data >= Common::KEYCODE_F1) && input.data <= Common::KEYCODE_F10) {
+ if (scummVMKeycode == Common::KEYCODE_DELETE)
+ input.character = SCI_KEY_DELETE;
+ } else if ((scummVMKeycode >= Common::KEYCODE_F1) && scummVMKeycode <= Common::KEYCODE_F10) {
// SCI_K_F1 == 59 << 8
// SCI_K_SHIFT_F1 == 84 << 8
- input.character = input.data = SCI_KEY_F1 + ((input.data - Common::KEYCODE_F1)<<8);
- if (modifiers & Common::KBD_SHIFT)
- input.character = input.data + 0x1900;
+ if (!(scummVMKeyFlags & Common::KBD_SHIFT))
+ input.character = SCI_KEY_F1 + ((scummVMKeycode - Common::KEYCODE_F1)<<8);
+ else
+ input.character = SCI_KEY_SHIFT_F1 + ((scummVMKeycode - Common::KEYCODE_F1)<<8);
} else {
// Special keys that need conversion
for (int i = 0; i < ARRAYSIZE(keyMappings); i++) {
- if (keyMappings[i].scummVMKey == ev.kbd.keycode) {
- input.character = input.data = numlockOn ? keyMappings[i].sciKeyNumlockOn : keyMappings[i].sciKeyNumlockOff;
+ if (keyMappings[i].scummVMKey == scummVMKeycode) {
+ input.character = numlockOn ? keyMappings[i].sciKeyNumlockOn : keyMappings[i].sciKeyNumlockOff;
break;
}
}
@@ -256,14 +315,19 @@ SciEvent EventManager::getScummVMEvent() {
// When Ctrl AND Alt are pressed together with a regular key, Linux will give us control-key, Windows will give
// us the actual key. My opinion is that windows is right, because under DOS the keys worked the same, anyway
// we support the other case as well
- if ((modifiers & Common::KBD_ALT) && input.character > 0 && input.character < 27)
+ if ((scummVMKeyFlags & Common::KBD_ALT) && input.character > 0 && input.character < 27)
input.character += 96; // 0x01 -> 'a'
// Scancodify if appropriate
- if (modifiers & Common::KBD_ALT)
+ if (scummVMKeyFlags & Common::KBD_ALT)
input.character = altify(input.character);
- if (getSciVersion() <= SCI_VERSION_1_MIDDLE && (modifiers & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
+ if (getSciVersion() <= SCI_VERSION_1_MIDDLE && (scummVMKeyFlags & Common::KBD_CTRL) && input.character > 0 && input.character < 27)
input.character += 96; // 0x01 -> 'a'
+#ifdef ENABLE_SCI32
+ if (getSciVersion() >= SCI_VERSION_2 && (scummVMKeyFlags & Common::KBD_CTRL) && input.character == 'c') {
+ input.character = SCI_KEY_ETX;
+ }
+#endif
// If no actual key was pressed (e.g. if only a modifier key was pressed),
// ignore the event
@@ -290,8 +354,12 @@ void EventManager::updateScreen() {
}
}
-SciEvent EventManager::getSciEvent(unsigned int mask) {
- SciEvent event = { 0, 0, 0, 0, Common::Point(0, 0) };
+SciEvent EventManager::getSciEvent(uint32 mask) {
+#ifdef ENABLE_SCI32
+ SciEvent event = { SCI_EVENT_NONE, 0, 0, Common::Point(), Common::Point() };
+#else
+ SciEvent event = { SCI_EVENT_NONE, 0, 0, Common::Point() };
+#endif
EventManager::updateScreen();
@@ -304,7 +372,7 @@ SciEvent EventManager::getSciEvent(unsigned int mask) {
// Search for matching event in queue
Common::List<SciEvent>::iterator iter = _events.begin();
- while (iter != _events.end() && !((*iter).type & mask))
+ while (iter != _events.end() && !(iter->type & mask))
++iter;
if (iter != _events.end()) {
@@ -326,17 +394,17 @@ SciEvent EventManager::getSciEvent(unsigned int mask) {
void SciEngine::sleep(uint32 msecs) {
uint32 time;
- const uint32 wakeup_time = g_system->getMillis() + msecs;
+ const uint32 wakeUpTime = g_system->getMillis() + msecs;
while (true) {
// let backend process events and update the screen
_eventMan->getSciEvent(SCI_EVENT_PEEK);
time = g_system->getMillis();
- if (time + 10 < wakeup_time) {
+ if (time + 10 < wakeUpTime) {
g_system->delayMillis(10);
} else {
- if (time < wakeup_time)
- g_system->delayMillis(wakeup_time - time);
+ if (time < wakeUpTime)
+ g_system->delayMillis(wakeUpTime - time);
break;
}