aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/sci/console.cpp7
-rw-r--r--engines/sci/engine/kernel.cpp22
-rw-r--r--engines/sci/engine/kernel.h1
-rw-r--r--engines/sci/engine/kevent.cpp70
-rw-r--r--engines/sci/engine/kmisc.cpp5
-rw-r--r--engines/sci/engine/state.h3
-rw-r--r--engines/sci/event.cpp426
-rw-r--r--engines/sci/event.h135
-rw-r--r--engines/sci/gfx/menubar.cpp1
-rw-r--r--engines/sci/gfx/operations.cpp395
-rw-r--r--engines/sci/gfx/operations.h24
-rw-r--r--engines/sci/gui/gui.cpp9
-rw-r--r--engines/sci/gui/gui_controls.cpp1
-rw-r--r--engines/sci/gui/gui_menu.cpp11
-rw-r--r--engines/sci/gui/gui_menu.h3
-rw-r--r--engines/sci/gui32/gui32.cpp57
-rw-r--r--engines/sci/module.mk1
-rw-r--r--engines/sci/sci.cpp3
-rw-r--r--engines/sci/uinput.h4
19 files changed, 659 insertions, 519 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp
index b95158126d..1e9fef6bc4 100644
--- a/engines/sci/console.cpp
+++ b/engines/sci/console.cpp
@@ -28,6 +28,7 @@
#include "sci/sci.h"
#include "sci/console.h"
#include "sci/debug.h"
+#include "sci/event.h"
#include "sci/resource.h"
#include "sci/vocabulary.h"
#include "sci/engine/savegame.h"
@@ -789,7 +790,7 @@ bool Console::cmdRedrawScreen(int argc, const char **argv) {
_vm->_gamestate->visual->draw(Common::Point(0, 0));
gfxop_update_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200));
gfxop_update(_vm->_gamestate->gfx_state);
- gfxop_sleep(_vm->_gamestate->gfx_state, 0);
+ kernel_sleep(_vm->_gamestate->_event, 0);
#endif
return false;
}
@@ -1018,7 +1019,7 @@ bool Console::cmdDrawPic(int argc, const char **argv) {
gfxop_new_pic(_vm->_gamestate->gfx_state, atoi(argv[1]), flags, default_palette);
gfxop_clear_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200));
gfxop_update(_vm->_gamestate->gfx_state);
- gfxop_sleep(_vm->_gamestate->gfx_state, 0);
+ kernel_sleep(_vm->_gamestate->_event, 0);
#endif
return false;
@@ -1190,7 +1191,7 @@ bool Console::cmdPropagateZone(int argc, const char **argv) {
else
gfxop_update_box(_vm->_gamestate->gfx_state, rect);
gfxop_update(_vm->_gamestate->gfx_state);
- gfxop_sleep(_vm->_gamestate->gfx_state, 0);
+ kernel_sleep(_vm->_gamestate->_event, 0);
#endif
return false;
diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp
index 9766043b8e..c334d6af0b 100644
--- a/engines/sci/engine/kernel.cpp
+++ b/engines/sci/engine/kernel.cpp
@@ -25,6 +25,7 @@
#include "sci/sci.h"
#include "sci/engine/kernel.h"
+#include "sci/event.h"
#include "sci/resource.h"
#include "sci/engine/state.h"
#include "sci/engine/kernel_types.h"
@@ -671,6 +672,27 @@ bool kernel_matches_signature(SegManager *segMan, const char *sig, int argc, con
return (*sig == 0 || (*sig & KSIG_ELLIPSIS));
}
+void kernel_sleep(SciEvent *event, uint32 msecs ) {
+ uint32 time;
+ const uint32 wakeup_time = g_system->getMillis() + msecs;
+
+ while (true) {
+ // let backend process events and update the screen
+ event->get(SCI_EVT_PEEK);
+ // TODO: we need to call SciGuiCursor::refreshPosition() before each screen update to limit the mouse cursor position
+ g_system->updateScreen();
+ time = g_system->getMillis();
+ if (time + 10 < wakeup_time) {
+ g_system->delayMillis(10);
+ } else {
+ if (time < wakeup_time)
+ g_system->delayMillis(wakeup_time - time);
+ break;
+ }
+
+ }
+}
+
void Kernel::setDefaultKernelNames() {
_kernelNames = Common::StringList(sci_default_knames, SCI_KNAMES_DEFAULT_ENTRIES_NR);
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h
index 9294b6a172..56fdf47c9e 100644
--- a/engines/sci/engine/kernel.h
+++ b/engines/sci/engine/kernel.h
@@ -242,7 +242,6 @@ extern Common::Rect get_nsrect(EngineState *s, reg_t object, byte clip);
*/
void process_sound_events(EngineState *s);
-
/******************** Constants ********************/
/* Maximum length of a savegame name (including terminator character) */
diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp
index 133e6dc3e5..e57cd55b0e 100644
--- a/engines/sci/engine/kevent.cpp
+++ b/engines/sci/engine/kevent.cpp
@@ -29,6 +29,7 @@
#include "sci/gfx/operations.h"
#include "sci/console.h"
#include "sci/debug.h" // for g_debug_simulated_key
+#include "sci/event.h"
#include "sci/gui/gui.h"
#include "sci/gui/gui_cursor.h"
@@ -39,7 +40,7 @@ namespace Sci {
reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
int mask = argv[0].toUint16();
reg_t obj = argv[1];
- sci_event_t e;
+ sciEvent curEvent;
int oldx, oldy;
int modifier_mask = getSciVersion() <= SCI_VERSION_01 ? SCI_EVM_ALL : SCI_EVM_NO_FOOLOCK;
SegManager *segMan = s->_segMan;
@@ -59,7 +60,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
oldx = mousePos.x;
oldy = mousePos.y;
- e = gfxop_get_event(s->gfx_state, mask);
+ curEvent = s->_event->get(mask);
s->parser_event = NULL_REG; // Invalidate parser event
@@ -68,17 +69,17 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
//s->_gui->moveCursor(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y);
- switch (e.type) {
+ switch (curEvent.type) {
case SCI_EVT_QUIT:
quit_vm();
break;
case SCI_EVT_KEYBOARD:
- if ((e.buckybits & SCI_EVM_LSHIFT) && (e.buckybits & SCI_EVM_RSHIFT) && (e.data == '-')) {
+ if ((curEvent.buckybits & SCI_EVM_LSHIFT) && (curEvent.buckybits & SCI_EVM_RSHIFT) && (curEvent.data == '-')) {
printf("Debug mode activated\n");
g_debugState.seeking = kDebugSeekNothing;
g_debugState.runningStep = 0;
- } else if ((e.buckybits & SCI_EVM_CTRL) && (e.data == '`')) {
+ } else if ((curEvent.buckybits & SCI_EVM_CTRL) && (curEvent.data == '`')) {
printf("Debug mode activated\n");
g_debugState.seeking = kDebugSeekNothing;
g_debugState.runningStep = 0;
@@ -86,50 +87,9 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
PUT_SEL32V(segMan, obj, type, SCI_EVT_KEYBOARD); // Keyboard event
s->r_acc = make_reg(0, 1);
- // TODO: Remove this as soon as ScummVM handles Ctrl-Alt-X to us
- if ((e.buckybits == SCI_EVM_CTRL) && (e.character = 'x'))
- e.buckybits |= SCI_EVM_ALT;
-
- if (e.buckybits & SCI_EVM_ALT) {
- // If Alt is pressed, we need to convert the actual key to a DOS scancode
- switch (e.character) {
- case 'a': e.character = 30 << 8; break;
- case 'b': e.character = 48 << 8; break;
- case 'c': e.character = 46 << 8; break;
- case 'd': e.character = 32 << 8; break;
- case 'e': e.character = 18 << 8; break;
- case 'f': e.character = 33 << 8; break;
- case 'g': e.character = 34 << 8; break;
- case 'h': e.character = 35 << 8; break;
- case 'i': e.character = 33 << 8; break;
- case 'j': e.character = 23 << 8; break;
- case 'k': e.character = 37 << 8; break;
- case 'l': e.character = 38 << 8; break;
- case 'm': e.character = 50 << 8; break;
- case 'n': e.character = 49 << 8; break;
- case 'o': e.character = 24 << 8; break;
- case 'p': e.character = 25 << 8; break;
- case 'q': e.character = 16 << 8; break;
- case 'r': e.character = 19 << 8; break;
- case 's': e.character = 31 << 8; break;
- case 't': e.character = 20 << 8; break;
- case 'u': e.character = 22 << 8; break;
- case 'v': e.character = 47 << 8; break;
- case 'w': e.character = 17 << 8; break;
- case 'x': e.character = 45 << 8; break;
- case 'y': e.character = 21 << 8; break;
- case 'z': e.character = 44 << 8; break;
- }
- } else if (e.buckybits & SCI_EVM_CTRL) {
- // Control is pressed...
- if ((e.character >= 97) && (e.character <= 121)) {
- e.character -= 96; // 'a' -> 0x01, etc.
- }
- }
-
- PUT_SEL32V(segMan, obj, message, e.character);
+ PUT_SEL32V(segMan, obj, message, curEvent.character);
// We only care about the translated character
- PUT_SEL32V(segMan, obj, modifiers, e.buckybits&modifier_mask);
+ PUT_SEL32V(segMan, obj, modifiers, curEvent.buckybits&modifier_mask);
}
break;
@@ -137,15 +97,15 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
case SCI_EVT_MOUSE_PRESS:
// track left buttton clicks, if requested
- if (e.type == SCI_EVT_MOUSE_PRESS && e.data == 1 && g_debug_track_mouse_clicks) {
+ if (curEvent.type == SCI_EVT_MOUSE_PRESS && curEvent.data == 1 && g_debug_track_mouse_clicks) {
((SciEngine *)g_engine)->getSciDebugger()->DebugPrintf("Mouse clicked at %d, %d\n",
mousePos.x, mousePos.y);
}
- if (mask & e.type) {
+ if (mask & curEvent.type) {
int extra_bits = 0;
- switch (e.data) {
+ switch (curEvent.data) {
case 2:
extra_bits = SCI_EVM_LSHIFT | SCI_EVM_RSHIFT;
break;
@@ -155,9 +115,9 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
break;
}
- PUT_SEL32V(segMan, obj, type, e.type);
+ PUT_SEL32V(segMan, obj, type, curEvent.type);
PUT_SEL32V(segMan, obj, message, 0);
- PUT_SEL32V(segMan, obj, modifiers, (e.buckybits | extra_bits)&modifier_mask);
+ PUT_SEL32V(segMan, obj, modifiers, (curEvent.buckybits | extra_bits)&modifier_mask);
s->r_acc = make_reg(0, 1);
}
break;
@@ -172,7 +132,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
// A SCI event occured, and we have been asked to stop, so open the debug console
Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
con->DebugPrintf("SCI event occured: ");
- switch (e.type) {
+ switch (curEvent.type) {
case SCI_EVT_QUIT:
con->DebugPrintf("quit event\n");
break;
@@ -184,7 +144,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
con->DebugPrintf("mouse click event\n");
break;
default:
- con->DebugPrintf("unknown or no event (event type %d)\n", e.type);
+ con->DebugPrintf("unknown or no event (event type %d)\n", curEvent.type);
}
con->attach();
diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp
index 41c36a8bc3..bbf4cf72d5 100644
--- a/engines/sci/engine/kmisc.cpp
+++ b/engines/sci/engine/kmisc.cpp
@@ -27,6 +27,7 @@
#include "sci/sci.h"
#include "sci/debug.h"
+#include "sci/event.h"
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
#include "sci/engine/gc.h"
@@ -44,8 +45,6 @@ reg_t kRestartGame(EngineState *s, int argc, reg_t *argv) {
return NULL_REG;
}
-void gfxop_sleep(GfxState *gfx, uint32 duration);
-
/* kGameIsRestarting():
** Returns the restarting_flag in acc
*/
@@ -69,7 +68,7 @@ reg_t kGameIsRestarting(EngineState *s, int argc, reg_t *argv) {
uint32 neededSleep = 30;
if (duration < neededSleep) {
- gfxop_sleep(s->gfx_state, neededSleep - duration);
+ kernel_sleep(s->_event, neededSleep - duration);
s->_lastAnimateTime = g_system->getMillis();
} else {
s->_lastAnimateTime = curTime;
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index 486f5cda87..7e78867cf3 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -48,6 +48,7 @@ namespace Common {
namespace Sci {
+class SciEvent;
class Menubar;
class SciGui;
class SciGuiCursor;
@@ -143,6 +144,8 @@ public:
SciGui *_gui; /* Currently active Gui */
+ SciEvent *_event; // Event handling
+
GfxState *gfx_state; /**< Graphics state and driver */
AudioPlayer *_audio;
diff --git a/engines/sci/event.cpp b/engines/sci/event.cpp
new file mode 100644
index 0000000000..c011a8c777
--- /dev/null
+++ b/engines/sci/event.cpp
@@ -0,0 +1,426 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/system.h"
+#include "common/events.h"
+
+#include "sci/sci.h"
+#include "sci/event.h"
+#include "sci/console.h"
+#include "sci/engine/state.h"
+#include "sci/engine/kernel.h"
+
+namespace Sci {
+
+#define SCANCODE_ROWS_NR 3
+
+SciEvent::SciEvent() {
+}
+
+SciEvent::~SciEvent() {
+}
+
+struct scancode_row {
+ int offset;
+ const char *keys;
+} scancode_rows[SCANCODE_ROWS_NR] = {
+ {0x10, "QWERTYUIOP[]"},
+ {0x1e, "ASDFGHJKL;'\\"},
+ {0x2c, "ZXCVBNM,./"}
+};
+
+int SciEvent::controlify(int ch) {
+ if ((ch >= 97) && (ch <= 121)) {
+ ch -= 96; // 'a' -> 0x01, etc.
+ }
+ return ch;
+}
+
+int SciEvent::altify (int ch) {
+ // Calculates a PC keyboard scancode from a character */
+ int row;
+ int c = toupper((char)ch);
+
+ for (row = 0; row < SCANCODE_ROWS_NR; row++) {
+ const char *keys = scancode_rows[row].keys;
+ int offset = scancode_rows[row].offset;
+
+ while (*keys) {
+ if (*keys == c)
+ return offset << 8;
+
+ offset++;
+ keys++;
+ }
+ }
+
+ return ch;
+}
+
+int SciEvent::shiftify (int c) {
+ char shifted_numbers[] = ")!@#$%^&*(";
+
+ if (c < 256) {
+ c = toupper((char)c);
+
+ if (c >= 'A' && c <= 'Z')
+ return c;
+
+ if (c >= '0' && c <= '9')
+ return shifted_numbers[c-'0'];
+
+ switch (c) {
+ case SCI_K_TAB:
+ return SCI_K_SHIFT_TAB;
+ case ']':
+ return '}';
+ case '[':
+ return '{';
+ case '`':
+ return '~';
+ case '-':
+ return '_';
+ case '=':
+ return '+';
+ case ';':
+ return ':';
+ case '\'':
+ return '"';
+ case '\\':
+ return '|';
+ case ',':
+ return '<';
+ case '.':
+ return '>';
+ case '/':
+ return '?';
+ default:
+ return c; // No match
+ }
+ }
+
+ if (c >= SCI_K_F1 && c <= SCI_K_F10)
+ return c + 25;
+
+ return c;
+}
+
+int SciEvent::numlockify (int c) {
+ switch (c) {
+ case SCI_K_DELETE:
+ return '.';
+ case SCI_K_INSERT:
+ return '0';
+ case SCI_K_END:
+ return '1';
+ case SCI_K_DOWN:
+ return '2';
+ case SCI_K_PGDOWN:
+ return '3';
+ case SCI_K_LEFT:
+ return '4';
+ case SCI_K_CENTER:
+ return '5';
+ case SCI_K_RIGHT:
+ return '6';
+ case SCI_K_HOME:
+ return '7';
+ case SCI_K_UP:
+ return '8';
+ case SCI_K_PGUP:
+ return '9';
+ default:
+ return c; // Unchanged
+ }
+}
+
+sciEvent SciEvent::getFromScummVM() {
+ static int _modifierStates = 0; // FIXME: Avoid non-const global vars
+ sciEvent input = { SCI_EVT_NONE, 0, 0, 0 };
+
+ Common::EventManager *em = g_system->getEventManager();
+ Common::Event ev;
+
+ bool found = em->pollEvent(ev);
+ Common::Point p = ev.mouse;
+
+ // Don't generate events for mouse movement
+ while (found && ev.type == Common::EVENT_MOUSEMOVE) {
+ found = em->pollEvent(ev);
+ }
+
+ if (found && !ev.synthetic && ev.type != Common::EVENT_MOUSEMOVE) {
+ int modifiers = em->getModifierState();
+
+ // We add the modifier key status to buckybits
+ // SDL sends a keydown event if a modifier key is turned on and a keyup event if it's off
+ //
+ // FIXME: This code is semi-bogus. It only records the modifier key being *pressed*.
+ // It does not track correctly whether capslock etc. is active. To do that, we
+ // would have to record the fact that the modifier was pressed in global var,
+ // and also watch for Common::EVENT_KEYUP events.
+ // But this is still not quite good enough, because not all events might
+ // pass through here (e.g. the GUI might be running with its own event loop).
+ //
+ // The best solution likely would be to add code to the EventManager class
+ // for tracking which keys are pressed and which are not...
+ if (ev.type == Common::EVENT_KEYDOWN || ev.type == Common::EVENT_KEYUP) {
+ switch (ev.kbd.keycode) {
+ case Common::KEYCODE_CAPSLOCK:
+ if (ev.type == Common::EVENT_KEYDOWN) {
+ _modifierStates |= SCI_EVM_CAPSLOCK;
+ } else {
+ _modifierStates &= ~SCI_EVM_CAPSLOCK;
+ }
+ break;
+ case Common::KEYCODE_NUMLOCK:
+ if (ev.type == Common::EVENT_KEYDOWN) {
+ _modifierStates |= SCI_EVM_NUMLOCK;
+ } else {
+ _modifierStates &= ~SCI_EVM_NUMLOCK;
+ }
+ break;
+ case Common::KEYCODE_SCROLLOCK:
+ if (ev.type == Common::EVENT_KEYDOWN) {
+ _modifierStates |= SCI_EVM_SCRLOCK;
+ } else {
+ _modifierStates &= ~SCI_EVM_SCRLOCK;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ //TODO: SCI_EVM_INSERT
+
+ input.buckybits =
+ ((modifiers & Common::KBD_ALT) ? SCI_EVM_ALT : 0) |
+ ((modifiers & Common::KBD_CTRL) ? SCI_EVM_CTRL : 0) |
+ ((modifiers & Common::KBD_SHIFT) ? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0) |
+ _modifierStates;
+
+ switch (ev.type) {
+ // Keyboard events
+ case Common::EVENT_KEYDOWN:
+ input.data = ev.kbd.keycode;
+ input.character = ev.kbd.ascii;
+
+ // Debug console
+ if (ev.kbd.flags == Common::KBD_CTRL && ev.kbd.keycode == Common::KEYCODE_d) {
+ // Open debug console
+ Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
+ con->attach();
+
+ // Clear keyboard event
+ input.type = SCI_EVT_NONE;
+ input.character = 0;
+ input.data = 0;
+ input.buckybits = 0;
+
+ return input;
+ }
+
+ if (!(input.data & 0xFF00)) {
+ // Directly accept most common keys without conversion
+ input.type = SCI_EVT_KEYBOARD;
+ if (input.data == Common::KEYCODE_TAB) {
+ // Tab
+ input.type = SCI_EVT_KEYBOARD;
+ input.data = SCI_K_TAB;
+ if (input.buckybits & (SCI_EVM_LSHIFT | SCI_EVM_RSHIFT))
+ input.character = SCI_K_SHIFT_TAB;
+ else
+ input.character = SCI_K_TAB;
+ }
+ } else if ((input.data >= Common::KEYCODE_F1) && input.data <= Common::KEYCODE_F10) {
+ // F1-F10
+ input.type = SCI_EVT_KEYBOARD;
+ // SCI_K_F1 == 59 << 8
+ // SCI_K_SHIFT_F1 == 84 << 8
+ input.data = SCI_K_F1 + ((input.data - Common::KEYCODE_F1)<<8);
+ if (input.buckybits & (SCI_EVM_LSHIFT | SCI_EVM_RSHIFT))
+ input.character = input.data + 25;
+ else
+ input.character = input.data;
+ } else {
+ // Special keys that need conversion
+ input.type = SCI_EVT_KEYBOARD;
+ switch (ev.kbd.keycode) {
+ case Common::KEYCODE_UP:
+ input.data = SCI_K_UP;
+ break;
+ case Common::KEYCODE_DOWN:
+ input.data = SCI_K_DOWN;
+ break;
+ case Common::KEYCODE_RIGHT:
+ input.data = SCI_K_RIGHT;
+ break;
+ case Common::KEYCODE_LEFT:
+ input.data = SCI_K_LEFT;
+ break;
+ case Common::KEYCODE_INSERT:
+ input.data = SCI_K_INSERT;
+ break;
+ case Common::KEYCODE_HOME:
+ input.data = SCI_K_HOME;
+ break;
+ case Common::KEYCODE_END:
+ input.data = SCI_K_END;
+ break;
+ case Common::KEYCODE_PAGEUP:
+ input.data = SCI_K_PGUP;
+ break;
+ case Common::KEYCODE_PAGEDOWN:
+ input.data = SCI_K_PGDOWN;
+ break;
+ case Common::KEYCODE_DELETE:
+ input.data = SCI_K_DELETE;
+ break;
+ // Keypad keys
+ case Common::KEYCODE_KP8: // up
+ if (!(_modifierStates & SCI_EVM_NUMLOCK))
+ input.data = SCI_K_UP;
+ break;
+ case Common::KEYCODE_KP2: // down
+ if (!(_modifierStates & SCI_EVM_NUMLOCK))
+ input.data = SCI_K_DOWN;
+ break;
+ case Common::KEYCODE_KP6: // right
+ if (!(_modifierStates & SCI_EVM_NUMLOCK))
+ input.data = SCI_K_RIGHT;
+ break;
+ case Common::KEYCODE_KP4: // left
+ if (!(_modifierStates & SCI_EVM_NUMLOCK))
+ input.data = SCI_K_LEFT;
+ break;
+ case Common::KEYCODE_KP5: // center
+ if (!(_modifierStates & SCI_EVM_NUMLOCK))
+ input.data = SCI_K_CENTER;
+ break;
+ default:
+ input.type = SCI_EVT_NONE;
+ break;
+ }
+ input.character = input.data;
+ }
+ break;
+
+ // Mouse events
+ case Common::EVENT_LBUTTONDOWN:
+ input.type = SCI_EVT_MOUSE_PRESS;
+ input.data = 1;
+ break;
+ case Common::EVENT_RBUTTONDOWN:
+ input.type = SCI_EVT_MOUSE_PRESS;
+ input.data = 2;
+ break;
+ case Common::EVENT_LBUTTONUP:
+ input.type = SCI_EVT_MOUSE_RELEASE;
+ input.data = 1;
+ break;
+ case Common::EVENT_RBUTTONUP:
+ input.type = SCI_EVT_MOUSE_RELEASE;
+ input.data = 2;
+ break;
+
+ // Misc events
+ case Common::EVENT_QUIT:
+ input.type = SCI_EVT_QUIT;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return input;
+}
+
+sciEvent SciEvent::get(unsigned int mask) {
+ //sci_event_t error_event = { SCI_EVT_ERROR, 0, 0, 0 };
+ sciEvent event = { 0, 0, 0, 0 };
+
+ // TODO: we need to call SciGuiCursor::refreshPosition() before each screen update to limit the mouse cursor position
+
+ // Update the screen here, since it's called very often
+ g_system->updateScreen();
+
+ // Get all queued events from graphics driver
+ do {
+ event = getFromScummVM();
+ if (event.type != SCI_EVT_NONE)
+ _events.push_back(event);
+ } while (event.type != SCI_EVT_NONE);
+
+ // Search for matching event in queue
+ Common::List<sciEvent>::iterator iter = _events.begin();
+ while (iter != _events.end() && !((*iter).type & mask))
+ ++iter;
+
+ if (iter != _events.end()) {
+ // Event found
+ event = *iter;
+
+ // If not peeking at the queue, remove the event
+ if (!(mask & SCI_EVT_PEEK)) {
+ _events.erase(iter);
+ }
+ } else {
+ // No event found: we must return a SCI_EVT_NONE event.
+
+ // Because event.type is SCI_EVT_NONE already here,
+ // there is no need to change it.
+ }
+
+ if (event.type == SCI_EVT_KEYBOARD) {
+ // Do we still have to translate the key?
+
+ event.character = event.data;
+
+ // TODO: Remove this as soon as ScummVM handles Ctrl-Alt-X to us
+ if ((event.buckybits == SCI_EVM_CTRL) && (event.character = 'x'))
+ event.buckybits |= SCI_EVM_ALT;
+
+ // Scancodify if appropriate
+ if (event.buckybits & SCI_EVM_ALT) {
+ event.character = altify(event.character);
+ } else if (event.buckybits & SCI_EVM_CTRL) {
+ event.character = controlify(event.character);
+ }
+
+ // Shift if appropriate
+ else if (((event.buckybits & (SCI_EVM_RSHIFT | SCI_EVM_LSHIFT)) && !(event.buckybits & SCI_EVM_CAPSLOCK))
+ || (!(event.buckybits & (SCI_EVM_RSHIFT | SCI_EVM_LSHIFT)) && (event.buckybits & SCI_EVM_CAPSLOCK)))
+ event.character = shiftify(event.character);
+
+ // Numlockify if appropriate
+ else if (event.buckybits & SCI_EVM_NUMLOCK)
+ event.data = numlockify(event.data);
+ }
+
+ return event;
+}
+
+} // End of namespace Sci
diff --git a/engines/sci/event.h b/engines/sci/event.h
new file mode 100644
index 0000000000..868ad29ead
--- /dev/null
+++ b/engines/sci/event.h
@@ -0,0 +1,135 @@
+/* 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$
+ *
+ */
+
+#ifndef SCI_ENGINE_EVENT_H
+#define SCI_ENGINE_EVENT_H
+
+#include "common/list.h"
+
+namespace Sci {
+
+#define SCI_INPUT_DEFAULT_CLOCKTIME 100000
+#define SCI_INPUT_DEFAULT_REDRAWTIME 30000
+
+
+struct sciEvent {
+ short type;
+ short data;
+ short buckybits;
+ short character; /* for keyboard events: 'data' after applying
+ ** the effects of 'buckybits', e.g. if
+ ** type == SCI_EVT_KEYBOARD
+ ** data == 'a'
+ ** buckybits == SCI_EVM_LSHIFT
+ ** then
+ ** character == 'A'
+ ** For 'Alt', characters are interpreted by their
+ ** PC keyboard scancodes.
+ */
+};
+
+/*Values for type*/
+#define SCI_EVT_NONE 0
+#define SCI_EVT_MOUSE_PRESS (1<<0)
+#define SCI_EVT_MOUSE_RELEASE (1<<1)
+#define SCI_EVT_KEYBOARD (1<<2)
+#define SCI_EVT_JOYSTICK (1<<6)
+#define SCI_EVT_SAID (1<<7)
+/*Fake values for other events*/
+#define SCI_EVT_ERROR (1<<10)
+#define SCI_EVT_QUIT (1<<11)
+#define SCI_EVT_PEEK (1<<15)
+/* The QUIT event may be used to signal an external 'quit' command being
+** issued to the gfx driver. */
+#define SCI_EVT_ANY 0x7fff
+
+/* Keycodes of special keys: */
+#define SCI_K_ESC 27
+#define SCI_K_BACKSPACE 8
+#define SCI_K_ENTER 13
+#define SCI_K_TAB '\t'
+#define SCI_K_SHIFT_TAB (0xf << 8)
+
+#define SCI_K_HOME (71 << 8) // 7
+#define SCI_K_UP (72 << 8) // 8
+#define SCI_K_PGUP (73 << 8) // 9
+//
+#define SCI_K_LEFT (75 << 8) // 4
+#define SCI_K_CENTER (76 << 8) // 5
+#define SCI_K_RIGHT (77 << 8) // 6
+//
+#define SCI_K_END (79 << 8) // 1
+#define SCI_K_DOWN (80 << 8) // 2
+#define SCI_K_PGDOWN (81 << 8) // 3
+//
+#define SCI_K_INSERT (82 << 8) // 0
+#define SCI_K_DELETE (83 << 8) // .
+
+#define SCI_K_F1 (59<<8)
+#define SCI_K_F2 (60<<8)
+#define SCI_K_F3 (61<<8)
+#define SCI_K_F4 (62<<8)
+#define SCI_K_F5 (63<<8)
+#define SCI_K_F6 (64<<8)
+#define SCI_K_F7 (65<<8)
+#define SCI_K_F8 (66<<8)
+#define SCI_K_F9 (67<<8)
+#define SCI_K_F10 (68<<8)
+
+/*Values for buckybits */
+#define SCI_EVM_RSHIFT (1<<0)
+#define SCI_EVM_LSHIFT (1<<1)
+#define SCI_EVM_CTRL (1<<2)
+#define SCI_EVM_ALT (1<<3)
+#define SCI_EVM_SCRLOCK (1<<4)
+#define SCI_EVM_NUMLOCK (1<<5)
+#define SCI_EVM_CAPSLOCK (1<<6)
+#define SCI_EVM_INSERT (1<<7)
+
+#define SCI_EVM_NO_FOOLOCK (~(SCI_EVM_SCRLOCK | SCI_EVM_NUMLOCK | SCI_EVM_CAPSLOCK | SCI_EVM_INSERT))
+#define SCI_EVM_ALL 0xFF
+
+class SciEvent {
+public:
+ SciEvent();
+ ~SciEvent();
+
+ sciEvent get(unsigned int mask);
+
+private:
+ int controlify (int ch);
+ int altify (int ch);
+ int shiftify (int c);
+ int numlockify (int c);
+ sciEvent getFromScummVM();
+
+ Common::List<sciEvent> _events;
+};
+
+void kernel_sleep(SciEvent *event, uint32 msecs); // is in kernel.cpp
+
+} // End of namespace Sci
+
+#endif
diff --git a/engines/sci/gfx/menubar.cpp b/engines/sci/gfx/menubar.cpp
index d86979137b..4474b9eefa 100644
--- a/engines/sci/gfx/menubar.cpp
+++ b/engines/sci/gfx/menubar.cpp
@@ -31,6 +31,7 @@
#include "sci/sci.h" // for INCLUDE_OLDGFX
#ifdef INCLUDE_OLDGFX
+#include "sci/event.h"
#include "sci/engine/state.h"
#include "sci/gfx/menubar.h"
#include "sci/gui/gui.h"
diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp
index d50341887d..a2791794fd 100644
--- a/engines/sci/gfx/operations.cpp
+++ b/engines/sci/gfx/operations.cpp
@@ -31,6 +31,7 @@
#include "sci/gui32/font.h"
#endif
#include "sci/console.h"
+#include "sci/event.h"
#include "common/system.h"
#include "common/events.h"
@@ -345,7 +346,6 @@ void gfxop_init(GfxState *state, ResourceManager *resMan,
SciGuiScreen *screen, SciGuiPalette *palette, int scaleFactor) {
state->visible_map = GFX_MASK_VISUAL;
state->disable_dirty = 0;
- state->_events.clear();
state->pic = state->pic_unscaled = NULL;
state->pic_nr = -1; // Set background pic number to an invalid value
state->tag_mode = 0;
@@ -1209,397 +1209,4 @@ void gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, Common::
#endif // INCLUDE_OLDGFX
-
-
-// Pointer and IO ops
-void gfxop_sleep(GfxState *state, uint32 msecs) {
- uint32 time;
- const uint32 wakeup_time = g_system->getMillis() + msecs;
-
- while (true) {
- // let backend process events and update the screen
- gfxop_get_event(state, SCI_EVT_PEEK);
- // TODO: we need to call SciGuiCursor::refreshPosition() before each screen update to limit the mouse cursor position
- g_system->updateScreen();
- time = g_system->getMillis();
- if (time + 10 < wakeup_time) {
- g_system->delayMillis(10);
- } else {
- if (time < wakeup_time)
- g_system->delayMillis(wakeup_time - time);
- break;
- }
-
- }
-}
-
-#define SCANCODE_ROWS_NR 3
-
-struct scancode_row {
- int offset;
- const char *keys;
-} scancode_rows[SCANCODE_ROWS_NR] = {
- {0x10, "QWERTYUIOP[]"},
- {0x1e, "ASDFGHJKL;'\\"},
- {0x2c, "ZXCVBNM,./"}
-};
-
-static int _gfxop_scancode(int ch) {
- // Calculates a PC keyboard scancode from a character */
- int row;
- int c = toupper((char)ch);
-
- for (row = 0; row < SCANCODE_ROWS_NR; row++) {
- const char *keys = scancode_rows[row].keys;
- int offset = scancode_rows[row].offset;
-
- while (*keys) {
- if (*keys == c)
- return offset << 8;
-
- offset++;
- keys++;
- }
- }
-
- return ch;
-}
-
-int _gfxop_shiftify(int c) {
- char shifted_numbers[] = ")!@#$%^&*(";
-
- if (c < 256) {
- c = toupper((char)c);
-
- if (c >= 'A' && c <= 'Z')
- return c;
-
- if (c >= '0' && c <= '9')
- return shifted_numbers[c-'0'];
-
- switch (c) {
- case SCI_K_TAB:
- return SCI_K_SHIFT_TAB;
- case ']':
- return '}';
- case '[':
- return '{';
- case '`':
- return '~';
- case '-':
- return '_';
- case '=':
- return '+';
- case ';':
- return ':';
- case '\'':
- return '"';
- case '\\':
- return '|';
- case ',':
- return '<';
- case '.':
- return '>';
- case '/':
- return '?';
- default:
- return c; // No match
- }
- }
-
- if (c >= SCI_K_F1 && c <= SCI_K_F10)
- return c + 25;
-
- return c;
-}
-
-static int _gfxop_numlockify(int c) {
- switch (c) {
- case SCI_K_DELETE:
- return '.';
- case SCI_K_INSERT:
- return '0';
- case SCI_K_END:
- return '1';
- case SCI_K_DOWN:
- return '2';
- case SCI_K_PGDOWN:
- return '3';
- case SCI_K_LEFT:
- return '4';
- case SCI_K_CENTER:
- return '5';
- case SCI_K_RIGHT:
- return '6';
- case SCI_K_HOME:
- return '7';
- case SCI_K_UP:
- return '8';
- case SCI_K_PGUP:
- return '9';
- default:
- return c; // Unchanged
- }
-}
-
-static sci_event_t scummvm_get_event() {
- static int _modifierStates = 0; // FIXME: Avoid non-const global vars
- sci_event_t input = { SCI_EVT_NONE, 0, 0, 0 };
-
- Common::EventManager *em = g_system->getEventManager();
- Common::Event ev;
-
- bool found = em->pollEvent(ev);
- Common::Point p = ev.mouse;
-
- // Don't generate events for mouse movement
- while (found && ev.type == Common::EVENT_MOUSEMOVE) {
- found = em->pollEvent(ev);
- }
-
- if (found && !ev.synthetic && ev.type != Common::EVENT_MOUSEMOVE) {
- int modifiers = em->getModifierState();
-
- // We add the modifier key status to buckybits
- // SDL sends a keydown event if a modifier key is turned on and a keyup event if it's off
- //
- // FIXME: This code is semi-bogus. It only records the modifier key being *pressed*.
- // It does not track correctly whether capslock etc. is active. To do that, we
- // would have to record the fact that the modifier was pressed in global var,
- // and also watch for Common::EVENT_KEYUP events.
- // But this is still not quite good enough, because not all events might
- // pass through here (e.g. the GUI might be running with its own event loop).
- //
- // The best solution likely would be to add code to the EventManager class
- // for tracking which keys are pressed and which are not...
- if (ev.type == Common::EVENT_KEYDOWN || ev.type == Common::EVENT_KEYUP) {
- switch (ev.kbd.keycode) {
- case Common::KEYCODE_CAPSLOCK:
- if (ev.type == Common::EVENT_KEYDOWN) {
- _modifierStates |= SCI_EVM_CAPSLOCK;
- } else {
- _modifierStates &= ~SCI_EVM_CAPSLOCK;
- }
- break;
- case Common::KEYCODE_NUMLOCK:
- if (ev.type == Common::EVENT_KEYDOWN) {
- _modifierStates |= SCI_EVM_NUMLOCK;
- } else {
- _modifierStates &= ~SCI_EVM_NUMLOCK;
- }
- break;
- case Common::KEYCODE_SCROLLOCK:
- if (ev.type == Common::EVENT_KEYDOWN) {
- _modifierStates |= SCI_EVM_SCRLOCK;
- } else {
- _modifierStates &= ~SCI_EVM_SCRLOCK;
- }
- break;
- default:
- break;
- }
- }
- //TODO: SCI_EVM_INSERT
-
- input.buckybits =
- ((modifiers & Common::KBD_ALT) ? SCI_EVM_ALT : 0) |
- ((modifiers & Common::KBD_CTRL) ? SCI_EVM_CTRL : 0) |
- ((modifiers & Common::KBD_SHIFT) ? SCI_EVM_LSHIFT | SCI_EVM_RSHIFT : 0) |
- _modifierStates;
-
- switch (ev.type) {
- // Keyboard events
- case Common::EVENT_KEYDOWN:
- input.data = ev.kbd.keycode;
- input.character = ev.kbd.ascii;
-
- // Debug console
- if (ev.kbd.flags == Common::KBD_CTRL && ev.kbd.keycode == Common::KEYCODE_d) {
- // Open debug console
- Console *con = ((Sci::SciEngine*)g_engine)->getSciDebugger();
- con->attach();
-
- // Clear keyboard event
- input.type = SCI_EVT_NONE;
- input.character = 0;
- input.data = 0;
- input.buckybits = 0;
-
- return input;
- }
-
- if (!(input.data & 0xFF00)) {
- // Directly accept most common keys without conversion
- input.type = SCI_EVT_KEYBOARD;
- if (input.data == Common::KEYCODE_TAB) {
- // Tab
- input.type = SCI_EVT_KEYBOARD;
- input.data = SCI_K_TAB;
- if (input.buckybits & (SCI_EVM_LSHIFT | SCI_EVM_RSHIFT))
- input.character = SCI_K_SHIFT_TAB;
- else
- input.character = SCI_K_TAB;
- }
- } else if ((input.data >= Common::KEYCODE_F1) && input.data <= Common::KEYCODE_F10) {
- // F1-F10
- input.type = SCI_EVT_KEYBOARD;
- // SCI_K_F1 == 59 << 8
- // SCI_K_SHIFT_F1 == 84 << 8
- input.data = SCI_K_F1 + ((input.data - Common::KEYCODE_F1)<<8);
- if (input.buckybits & (SCI_EVM_LSHIFT | SCI_EVM_RSHIFT))
- input.character = input.data + 25;
- else
- input.character = input.data;
- } else {
- // Special keys that need conversion
- input.type = SCI_EVT_KEYBOARD;
- switch (ev.kbd.keycode) {
- case Common::KEYCODE_UP:
- input.data = SCI_K_UP;
- break;
- case Common::KEYCODE_DOWN:
- input.data = SCI_K_DOWN;
- break;
- case Common::KEYCODE_RIGHT:
- input.data = SCI_K_RIGHT;
- break;
- case Common::KEYCODE_LEFT:
- input.data = SCI_K_LEFT;
- break;
- case Common::KEYCODE_INSERT:
- input.data = SCI_K_INSERT;
- break;
- case Common::KEYCODE_HOME:
- input.data = SCI_K_HOME;
- break;
- case Common::KEYCODE_END:
- input.data = SCI_K_END;
- break;
- case Common::KEYCODE_PAGEUP:
- input.data = SCI_K_PGUP;
- break;
- case Common::KEYCODE_PAGEDOWN:
- input.data = SCI_K_PGDOWN;
- break;
- case Common::KEYCODE_DELETE:
- input.data = SCI_K_DELETE;
- break;
- // Keypad keys
- case Common::KEYCODE_KP8: // up
- if (!(_modifierStates & SCI_EVM_NUMLOCK))
- input.data = SCI_K_UP;
- break;
- case Common::KEYCODE_KP2: // down
- if (!(_modifierStates & SCI_EVM_NUMLOCK))
- input.data = SCI_K_DOWN;
- break;
- case Common::KEYCODE_KP6: // right
- if (!(_modifierStates & SCI_EVM_NUMLOCK))
- input.data = SCI_K_RIGHT;
- break;
- case Common::KEYCODE_KP4: // left
- if (!(_modifierStates & SCI_EVM_NUMLOCK))
- input.data = SCI_K_LEFT;
- break;
- case Common::KEYCODE_KP5: // center
- if (!(_modifierStates & SCI_EVM_NUMLOCK))
- input.data = SCI_K_CENTER;
- break;
- default:
- input.type = SCI_EVT_NONE;
- break;
- }
- input.character = input.data;
- }
- break;
-
- // Mouse events
- case Common::EVENT_LBUTTONDOWN:
- input.type = SCI_EVT_MOUSE_PRESS;
- input.data = 1;
- break;
- case Common::EVENT_RBUTTONDOWN:
- input.type = SCI_EVT_MOUSE_PRESS;
- input.data = 2;
- break;
- case Common::EVENT_LBUTTONUP:
- input.type = SCI_EVT_MOUSE_RELEASE;
- input.data = 1;
- break;
- case Common::EVENT_RBUTTONUP:
- input.type = SCI_EVT_MOUSE_RELEASE;
- input.data = 2;
- break;
-
- // Misc events
- case Common::EVENT_QUIT:
- input.type = SCI_EVT_QUIT;
- break;
-
- default:
- break;
- }
- }
-
- return input;
-}
-
-sci_event_t gfxop_get_event(GfxState *state, unsigned int mask) {
- //sci_event_t error_event = { SCI_EVT_ERROR, 0, 0, 0 };
- sci_event_t event = { 0, 0, 0, 0 };
-
- // TODO: we need to call SciGuiCursor::refreshPosition() before each screen update to limit the mouse cursor position
-
- // Update the screen here, since it's called very often
- g_system->updateScreen();
-
- // Get all queued events from graphics driver
- do {
- event = scummvm_get_event();
- if (event.type != SCI_EVT_NONE)
- state->_events.push_back(event);
- } while (event.type != SCI_EVT_NONE);
-
- // Search for matching event in queue
- Common::List<sci_event_t>::iterator iter = state->_events.begin();
- while (iter != state->_events.end() && !((*iter).type & mask))
- ++iter;
-
- if (iter != state->_events.end()) {
- // Event found
- event = *iter;
-
- // If not peeking at the queue, remove the event
- if (!(mask & SCI_EVT_PEEK)) {
- state->_events.erase(iter);
- }
- } else {
- // No event found: we must return a SCI_EVT_NONE event.
-
- // Because event.type is SCI_EVT_NONE already here,
- // there is no need to change it.
- }
-
- if (event.type == SCI_EVT_KEYBOARD) {
- // Do we still have to translate the key?
-
- event.character = event.data;
-
- // Scancodify if appropriate
- if (event.buckybits & SCI_EVM_ALT)
- event.character = _gfxop_scancode(event.character);
-
- // Shift if appropriate
- else if (((event.buckybits & (SCI_EVM_RSHIFT | SCI_EVM_LSHIFT)) && !(event.buckybits & SCI_EVM_CAPSLOCK))
- || (!(event.buckybits & (SCI_EVM_RSHIFT | SCI_EVM_LSHIFT)) && (event.buckybits & SCI_EVM_CAPSLOCK)))
- event.character = _gfxop_shiftify(event.character);
-
- // Numlockify if appropriate
- else if (event.buckybits & SCI_EVM_NUMLOCK)
- event.data = _gfxop_numlockify(event.data);
- }
-
- return event;
-}
-
} // End of namespace Sci
diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h
index 2f98bfbd2e..b1329e6b15 100644
--- a/engines/sci/gfx/operations.h
+++ b/engines/sci/gfx/operations.h
@@ -121,8 +121,6 @@ struct GfxState {
DirtyRectList _dirtyRects; /**< Dirty rectangles */
#endif
-
- Common::List<sci_event_t> _events;
};
@@ -528,28 +526,6 @@ int _gfxop_clip(rect_t *rect, rect_t clipzone);
/** @name Pointer and IO ops */
/** @{ */
-/**
- * Suspends program execution for the specified amount of milliseconds.
- *
- * The mouse pointer will be redrawn continually, if applicable
- *
- * @param[in] state The state affected
- * @param[in] msecs The amount of milliseconds to wait
- */
-void gfxop_sleep(GfxState *state, uint32 msecs);
-
-/**
- * Retrieves the next input event from the driver.
- *
- * @param[in] state The affected state
- * @param[in] mask The event mask to poll from (see uinput.h)
- * @return The next event in the driver's event queue, or a NONE event
- * if no event matching the mask was found.
- */
-sci_event_t gfxop_get_event(GfxState *state, unsigned int mask);
-/** @} */
-
-
} // End of namespace Sci
#endif // SCI_GFX_GFX_OPERATIONS_H
diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp
index 28d6a35064..5316a51df1 100644
--- a/engines/sci/gui/gui.cpp
+++ b/engines/sci/gui/gui.cpp
@@ -28,6 +28,7 @@
#include "sci/sci.h"
#include "sci/debug.h" // for g_debug_sleeptime_factor
+#include "sci/event.h"
#include "sci/engine/state.h"
#include "sci/gui/gui.h"
#include "sci/gui/gui_screen.h"
@@ -62,7 +63,7 @@ SciGui::SciGui(EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette,
_text = new SciGuiText(_s->resMan, _gfx, _screen);
_windowMgr = new SciGuiWindowMgr(this, _screen, _gfx, _text);
_controls = new SciGuiControls(_s->_segMan, _gfx, _text);
- _menu = new SciGuiMenu(_s->_segMan, _gfx, _text, _screen, _cursor);
+ _menu = new SciGuiMenu(_s->_event, _s->_segMan, _gfx, _text, _screen, _cursor);
// _gui32 = new SciGui32(_s, _screen, _palette, _cursor); // for debug purposes
}
@@ -109,7 +110,7 @@ void SciGui::wait(int16 ticks) {
_s->last_wait_time = time;
ticks *= g_debug_sleeptime_factor;
- gfxop_sleep(_s->gfx_state, ticks * 1000 / 60);
+ kernel_sleep(_s->_event, ticks * 1000 / 60);
}
void SciGui::setPort(uint16 portPtr) {
@@ -319,7 +320,7 @@ void SciGui::drawMenuBar(bool clear) {
void SciGui::menuReset() {
delete _menu;
- _menu = new SciGuiMenu(_s->_segMan, _gfx, _text, _screen, _cursor);
+ _menu = new SciGuiMenu(_s->_event, _s->_segMan, _gfx, _text, _screen, _cursor);
_menu->init(_s->gfx_state);
}
@@ -768,7 +769,7 @@ void SciGui::moveCursor(Common::Point pos) {
// Trigger event reading to make sure the mouse coordinates will
// actually have changed the next time we read them.
- gfxop_get_event(_s->gfx_state, SCI_EVT_PEEK);
+ _s->_event->get(SCI_EVT_PEEK);
}
void SciGui::setCursorZone(Common::Rect zone) {
diff --git a/engines/sci/gui/gui_controls.cpp b/engines/sci/gui/gui_controls.cpp
index 40b61f3ef6..5b048bfb86 100644
--- a/engines/sci/gui/gui_controls.cpp
+++ b/engines/sci/gui/gui_controls.cpp
@@ -28,6 +28,7 @@
#include "graphics/primitives.h"
#include "sci/sci.h"
+#include "sci/event.h"
#include "sci/engine/state.h"
#include "sci/gui/gui_gfx.h"
#include "sci/gui/gui_font.h"
diff --git a/engines/sci/gui/gui_menu.cpp b/engines/sci/gui/gui_menu.cpp
index 106922603c..104a6cb2bb 100644
--- a/engines/sci/gui/gui_menu.cpp
+++ b/engines/sci/gui/gui_menu.cpp
@@ -28,6 +28,7 @@
#include "graphics/primitives.h"
#include "sci/sci.h"
+#include "sci/event.h"
#include "sci/engine/state.h"
#include "sci/gfx/operations.h"
#include "sci/gfx/gfx_state_internal.h"
@@ -41,8 +42,8 @@
namespace Sci {
-SciGuiMenu::SciGuiMenu(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor)
- : _segMan(segMan), _gfx(gfx), _text(text), _screen(screen), _cursor(cursor) {
+SciGuiMenu::SciGuiMenu(SciEvent *event, SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor)
+ : _event(event), _segMan(segMan), _gfx(gfx), _text(text), _screen(screen), _cursor(cursor) {
_listCount = 0;
// We actually set active item in here and remember last selection of the user
@@ -553,7 +554,7 @@ void SciGuiMenu::invertMenuSelection(uint16 itemId) {
}
GuiMenuItemEntry *SciGuiMenu::interactiveWithKeyboard() {
- sci_event_t curEvent;
+ sciEvent curEvent;
uint16 newMenuId = _curMenuId;
uint16 newItemId = _curItemId;
GuiMenuItemEntry *curItemEntry = findItem(_curMenuId, _curItemId);
@@ -575,7 +576,7 @@ GuiMenuItemEntry *SciGuiMenu::interactiveWithKeyboard() {
_gfx->BitsShow(_menuRect);
while (true) {
- curEvent = gfxop_get_event(_gfxstate, SCI_EVT_ANY);
+ curEvent = _event->get(SCI_EVT_ANY);
switch (curEvent.type) {
case SCI_EVT_KEYBOARD:
@@ -633,7 +634,7 @@ GuiMenuItemEntry *SciGuiMenu::interactiveWithKeyboard() {
break;
case SCI_EVT_NONE:
- gfxop_sleep(_gfxstate, 2500 / 1000);
+ kernel_sleep(_event, 2500 / 1000);
break;
}
}
diff --git a/engines/sci/gui/gui_menu.h b/engines/sci/gui/gui_menu.h
index 91176ab586..66cb19a71a 100644
--- a/engines/sci/gui/gui_menu.h
+++ b/engines/sci/gui/gui_menu.h
@@ -78,7 +78,7 @@ typedef Common::List<GuiMenuItemEntry *> GuiMenuItemList;
class SciGuiMenu {
public:
- SciGuiMenu(SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor);
+ SciGuiMenu(SciEvent *event, SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor);
~SciGuiMenu();
void init(GfxState *gfxstate);
@@ -99,6 +99,7 @@ private:
GuiMenuItemEntry *interactiveWithMouse();
GuiMenuItemEntry *interactiveGetItem(uint16 menuId, uint16 itemId, bool menuChanged);
+ SciEvent *_event;
GfxState *_gfxstate;
SegManager *_segMan;
SciGuiGfx *_gfx;
diff --git a/engines/sci/gui32/gui32.cpp b/engines/sci/gui32/gui32.cpp
index dd51ebed50..fc93307416 100644
--- a/engines/sci/gui32/gui32.cpp
+++ b/engines/sci/gui32/gui32.cpp
@@ -31,6 +31,7 @@
#include "sci/engine/state.h"
#include "sci/debug.h" // for g_debug_sleeptime_factor
+#include "sci/event.h"
#include "sci/resource.h"
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
@@ -394,7 +395,7 @@ void SciGui32::wait(int16 ticks) {
_s->last_wait_time = time;
ticks *= g_debug_sleeptime_factor;
- gfxop_sleep(_s->gfx_state, ticks * 1000 / 60);
+ kernel_sleep(_s->_event, ticks * 1000 / 60);
}
void SciGui32::setPort(uint16 portPtr) {
@@ -945,7 +946,7 @@ reg_t SciGui32::menuSelect(reg_t eventObject) {
old_menu = -1;
while (menu_mode) {
- sci_event_t ev = gfxop_get_event(_s->gfx_state, SCI_EVT_ANY);
+ sciEvent ev = _s->_event->get(SCI_EVT_ANY);
claimed = false;
@@ -1015,7 +1016,7 @@ reg_t SciGui32::menuSelect(reg_t eventObject) {
break;
case SCI_EVT_NONE:
- gfxop_sleep(_s->gfx_state, 2500 / 1000);
+ kernel_sleep(_s->_event, 2500 / 1000);
break;
}
@@ -1609,11 +1610,11 @@ void SciGui32::shakeScreen(uint16 shakeCount, uint16 directions) {
Common::Point(shake_right, shake_down));
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 50);
+ kernel_sleep(_s->_event, 50);
gfxop_draw_pixmap(_s->gfx_state, screen, gfx_rect(0, 0, 320, 200), Common::Point(0, 0));
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 50);
+ kernel_sleep(_s->_event, 50);
}
gfx_free_pixmap(screen);
@@ -2301,7 +2302,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_update(_s->gfx_state);
GRAPH_BLANK_BOX(_s, 319 - i, 10, granularity1, 190, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 1000);
+ kernel_sleep(_s->_event, animation_delay / 1000);
process_sound_events(_s);
}
GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0);
@@ -2313,7 +2314,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_update(_s->gfx_state);
GRAPH_UPDATE_BOX(_s, 319 - i, 10, granularity1, 190);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 1000);
+ kernel_sleep(_s->_event, animation_delay / 1000);
process_sound_events(_s);
}
break;
@@ -2326,7 +2327,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_update(_s->gfx_state);
GRAPH_BLANK_BOX(_s, 0, 199 - i, 320, granularity2, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 2 * animation_delay / 1000);
+ kernel_sleep(_s->_event, 2 * animation_delay / 1000);
process_sound_events(_s);
}
GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0);
@@ -2338,7 +2339,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_update(_s->gfx_state);
GRAPH_UPDATE_BOX(_s, 0, 199 - i, 320, granularity2);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 2 * animation_delay / 1000);
+ kernel_sleep(_s->_event, 2 * animation_delay / 1000);
process_sound_events(_s);
}
break;
@@ -2349,7 +2350,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 0; i < 319 + granularity0; i += granularity0) {
GRAPH_BLANK_BOX(_s, i, 10, granularity0, 190, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 2 / 1000);
+ kernel_sleep(_s->_event, animation_delay / 2 / 1000);
process_sound_events(_s);
}
GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0);
@@ -2358,7 +2359,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 319; i >= 1 - granularity0; i -= granularity0) {
GRAPH_UPDATE_BOX(_s, i, 10, granularity0, 190);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 2 / 1000);
+ kernel_sleep(_s->_event, animation_delay / 2 / 1000);
process_sound_events(_s);
}
break;
@@ -2369,7 +2370,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 319; i >= 1 - granularity0; i -= granularity0) {
GRAPH_BLANK_BOX(_s, i, 10, granularity0, 190, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 2 / 1000);
+ kernel_sleep(_s->_event, animation_delay / 2 / 1000);
process_sound_events(_s);
}
GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0);
@@ -2379,7 +2380,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 0; i < 319 + granularity0; i += granularity0) {
GRAPH_UPDATE_BOX(_s, i, 10, granularity0, 190);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 2 / 1000);
+ kernel_sleep(_s->_event, animation_delay / 2 / 1000);
process_sound_events(_s);
}
break;
@@ -2390,7 +2391,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 10; i < 199 + granularity1; i += granularity1) {
GRAPH_BLANK_BOX(_s, 0, i, 320, granularity1, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 1000);
+ kernel_sleep(_s->_event, animation_delay / 1000);
process_sound_events(_s);
}
GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0);
@@ -2400,7 +2401,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 199; i >= 11 - granularity1; i -= granularity1) {
GRAPH_UPDATE_BOX(_s, 0, i, 320, granularity1);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 1000);
+ kernel_sleep(_s->_event, animation_delay / 1000);
process_sound_events(_s);
}
break;
@@ -2411,7 +2412,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 199; i >= 11 - granularity1; i -= granularity1) {
GRAPH_BLANK_BOX(_s, 0, i, 320, granularity1, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 1000);
+ kernel_sleep(_s->_event, animation_delay / 1000);
process_sound_events(_s);
}
GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0);
@@ -2421,7 +2422,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
for (i = 10; i < 199 + granularity1; i += granularity1) {
GRAPH_UPDATE_BOX(_s, 0, i, 320, granularity1);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, animation_delay / 1000);
+ kernel_sleep(_s->_event, animation_delay / 1000);
process_sound_events(_s);
}
break;
@@ -2446,7 +2447,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
GRAPH_BLANK_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 4 * animation_delay / 1000);
+ kernel_sleep(_s->_event, 4 * animation_delay / 1000);
process_sound_events(_s);
}
@@ -2469,7 +2470,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
GRAPH_UPDATE_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 4 * animation_delay / 1000);
+ kernel_sleep(_s->_event, 4 * animation_delay / 1000);
process_sound_events(_s);
}
@@ -2494,7 +2495,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
GRAPH_BLANK_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 7 * animation_delay / 1000);
+ kernel_sleep(_s->_event, 7 * animation_delay / 1000);
process_sound_events(_s);
}
@@ -2517,7 +2518,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
GRAPH_UPDATE_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l);
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, 7 * animation_delay / 1000);
+ kernel_sleep(_s->_event, 7 * animation_delay / 1000);
process_sound_events(_s);
}
break;
@@ -2552,7 +2553,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
}
if (remaining_checkers & 1) {
- gfxop_sleep(_s->gfx_state, animation_delay / 4 / 1000);
+ kernel_sleep(_s->_event, animation_delay / 4 / 1000);
}
--remaining_checkers;
@@ -2584,7 +2585,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
}
if (remaining_checkers & 1) {
- gfxop_sleep(_s->gfx_state, animation_delay / 4 / 1000);
+ kernel_sleep(_s->_event, animation_delay / 4 / 1000);
}
--remaining_checkers;
@@ -2599,7 +2600,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(320 - i, 0, i, 190), Common::Point(0, 10));
gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(0, 0, 320 - i, 190), Common::Point(i, 10));
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, (animation_delay >> 3) / 1000);
+ kernel_sleep(_s->_event, (animation_delay >> 3) / 1000);
}
GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190);
break;
@@ -2610,7 +2611,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(0, 0, i, 190), Common::Point(319 - i, 10));
gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(i, 0, 320 - i, 190), Common::Point(0, 10));
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, (animation_delay >> 3) / 1000);
+ kernel_sleep(_s->_event, (animation_delay >> 3) / 1000);
}
GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190);
break;
@@ -2621,7 +2622,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(0, 190 - i, 320, i), Common::Point(0, 10));
gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(0, 0, 320, 190 - i), Common::Point(0, 10 + i));
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, (animation_delay >> 3) / 1000);
+ kernel_sleep(_s->_event, (animation_delay >> 3) / 1000);
}
GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190);
break;
@@ -2632,7 +2633,7 @@ void SciGui32::animate_do_animation(int argc, reg_t *argv) {
gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(0, 0, 320, i), Common::Point(0, 200 - i));
gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(0, i, 320, 190 - i), Common::Point(0, 10));
gfxop_update(_s->gfx_state);
- gfxop_sleep(_s->gfx_state, (animation_delay >> 3) / 1000);
+ kernel_sleep(_s->_event, (animation_delay >> 3) / 1000);
}
GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190);
break;
@@ -2965,7 +2966,7 @@ void SciGui32::moveCursor(Common::Point pos) {
// Trigger event reading to make sure the mouse coordinates will
// actually have changed the next time we read them.
- gfxop_get_event(_s->gfx_state, SCI_EVT_PEEK);
+ _s->_event->get(SCI_EVT_PEEK);
}
void SciGui32::graphAdjustPriority(int top, int bottom) {
diff --git a/engines/sci/module.mk b/engines/sci/module.mk
index 085fba6e03..6a273eacf6 100644
--- a/engines/sci/module.mk
+++ b/engines/sci/module.mk
@@ -4,6 +4,7 @@ MODULE_OBJS := \
console.o \
decompressor.o \
detection.o \
+ event.o \
resource.o \
sci.o \
seq_decoder.o \
diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp
index a675f5bff4..0bd1f0cf81 100644
--- a/engines/sci/sci.cpp
+++ b/engines/sci/sci.cpp
@@ -31,6 +31,7 @@
#include "sci/sci.h"
#include "sci/debug.h"
#include "sci/console.h"
+#include "sci/event.h"
#include "sci/engine/state.h"
#include "sci/engine/kernel.h"
@@ -138,6 +139,7 @@ Common::Error SciEngine::run() {
// We'll set the GUI below
_gamestate = new EngineState(_resMan, _kernel, _vocabulary, segMan, NULL, _audio);
+ _gamestate->_event = new SciEvent();
if (script_init_engine(_gamestate))
return Common::kUnknownError;
@@ -196,6 +198,7 @@ Common::Error SciEngine::run() {
delete _gamestate->_soundCmd;
delete _gamestate->_gui;
+ delete _gamestate->_event;
delete segMan;
delete cursor;
delete palette;
diff --git a/engines/sci/uinput.h b/engines/sci/uinput.h
index 062265186b..4d73d5c590 100644
--- a/engines/sci/uinput.h
+++ b/engines/sci/uinput.h
@@ -28,10 +28,10 @@
namespace Sci {
+#if 0
#define SCI_INPUT_DEFAULT_CLOCKTIME 100000
#define SCI_INPUT_DEFAULT_REDRAWTIME 30000
-
struct sci_event_t {
short type;
short data;
@@ -111,6 +111,8 @@ struct sci_event_t {
#define SCI_EVM_NO_FOOLOCK (~(SCI_EVM_SCRLOCK | SCI_EVM_NUMLOCK | SCI_EVM_CAPSLOCK | SCI_EVM_INSERT))
#define SCI_EVM_ALL 0xFF
+#endif
+
} // End of namespace Sci
#endif // SCI_UINPUT_H