From a5f1808c83844c21a5e22543157fa341536b5406 Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Fri, 4 Dec 2009 17:38:24 +0000 Subject: SCI: SciEvent created, kernel_sleep() created svn-id: r46252 --- engines/sci/console.cpp | 7 +- engines/sci/engine/kernel.cpp | 22 ++ engines/sci/engine/kernel.h | 1 - engines/sci/engine/kevent.cpp | 70 ++----- engines/sci/engine/kmisc.cpp | 5 +- engines/sci/engine/state.h | 3 + engines/sci/event.cpp | 426 +++++++++++++++++++++++++++++++++++++++ engines/sci/event.h | 135 +++++++++++++ engines/sci/gfx/menubar.cpp | 1 + engines/sci/gfx/operations.cpp | 395 +----------------------------------- engines/sci/gfx/operations.h | 24 --- engines/sci/gui/gui.cpp | 9 +- engines/sci/gui/gui_controls.cpp | 1 + engines/sci/gui/gui_menu.cpp | 11 +- engines/sci/gui/gui_menu.h | 3 +- engines/sci/gui32/gui32.cpp | 57 +++--- engines/sci/module.mk | 1 + engines/sci/sci.cpp | 3 + engines/sci/uinput.h | 4 +- 19 files changed, 659 insertions(+), 519 deletions(-) create mode 100644 engines/sci/event.cpp create mode 100644 engines/sci/event.h (limited to 'engines') 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::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 _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::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 _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 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 -- cgit v1.2.3