diff options
-rw-r--r-- | engines/cge/cge.cpp | 4 | ||||
-rw-r--r-- | engines/cge/cge.h | 2 | ||||
-rw-r--r-- | engines/cge/cge_main.cpp | 42 | ||||
-rw-r--r-- | engines/cge/cge_main.h | 1 | ||||
-rw-r--r-- | engines/cge/events.cpp | 160 | ||||
-rw-r--r-- | engines/cge/events.h | 26 |
6 files changed, 142 insertions, 93 deletions
diff --git a/engines/cge/cge.cpp b/engines/cge/cge.cpp index 3feb8f64d2..f7e66183ce 100644 --- a/engines/cge/cge.cpp +++ b/engines/cge/cge.cpp @@ -51,6 +51,9 @@ CGEEngine::CGEEngine(OSystem *syst, const ADGameDescription *gameDescription) } void CGEEngine::setup() { + // Initialise fields + _lastFrame = 0; + // Create debugger console _console = new CGEConsole(this); @@ -98,6 +101,7 @@ void CGEEngine::setup() { _mouse = new MOUSE(this); _keyboard = new Keyboard(); + _eventManager = new EventManager(); OffUseCount = atoi(Text->getText(OFF_USE_COUNT)); } diff --git a/engines/cge/cge.h b/engines/cge/cge.h index 06c7fb2326..e4bb260bcc 100644 --- a/engines/cge/cge.h +++ b/engines/cge/cge.h @@ -43,6 +43,8 @@ enum { }; class CGEEngine : public Engine { +private: + uint32 _lastFrame; public: CGEEngine(OSystem *syst, const ADGameDescription *gameDescription); ~CGEEngine(); diff --git a/engines/cge/cge_main.cpp b/engines/cge/cge_main.cpp index 6e5c65b76f..0fa2b0cb0c 100644 --- a/engines/cge/cge_main.cpp +++ b/engines/cge/cge_main.cpp @@ -66,6 +66,7 @@ Heart *_heart; WALK *Hero; SYSTEM *Sys; Sprite *_pocLight; +EventManager *_eventManager; Keyboard *_keyboard; MOUSE *_mouse; Sprite *_pocket[POCKET_NX]; @@ -1537,6 +1538,7 @@ void CGEEngine::loadScript(const char *fname) { error("%s [%s]", NumStr("Bad INI line ######", lcnt), fname); } +#define GAME_FRAME_DELAY (1000 / 50) void CGEEngine::mainLoop() { SayDebug(); @@ -1558,8 +1560,17 @@ void CGEEngine::mainLoop() { Snail_->RunCom(); Snail->RunCom(); - // Delay to slow things down - g_system->delayMillis(10); + // Game frame delay + uint32 millis = g_system->getMillis(); + while (!_eventManager->_quitFlag && (millis < (_lastFrame + GAME_FRAME_DELAY))) { + // Handle any pending events + _eventManager->poll(); + + // Slight delay + g_system->delayMillis(10); + millis = g_system->getMillis(); + } + _lastFrame = millis; } @@ -1585,6 +1596,9 @@ void CGEEngine::loadUser() { void CGEEngine::runGame() { + if (_eventManager->_quitFlag) + return; + Text->Clear(); Text->Preload(100, 1000); LoadHeroXY(); @@ -1677,7 +1691,7 @@ void CGEEngine::runGame() { _keyboard->setClient(Sys); // main loop - while (! Finis) { + while (! Finis && !_eventManager->_quitFlag) { //TODO Change the SNPOST message send to a special way to send function pointer // if (FINIS) SNPOST(SNEXEC, -1, 0, (void *)&QGame); warning("RunGame: problematic use of SNPOST"); @@ -1697,6 +1711,9 @@ void CGEEngine::runGame() { void CGEEngine::movie(const char *ext) { + if (_eventManager->_quitFlag) + return; + const char *fn = progName(ext); if (INI_FILE::exist(fn)) { loadScript(fn); @@ -1708,7 +1725,7 @@ void CGEEngine::movie(const char *ext) { _heart->_enable = true; _keyboard->setClient(Sys); - while (!Snail->Idle()) + while (!Snail->Idle() && !_eventManager->_quitFlag) mainLoop(); _keyboard->setClient(NULL); @@ -1722,6 +1739,9 @@ void CGEEngine::movie(const char *ext) { bool CGEEngine::showTitle(const char *name) { + if (_eventManager->_quitFlag) + return false; + Bitmap::_pal = VGA::SysPal; BMP_PTR LB[] = { new Bitmap(name, true), NULL }; Bitmap::_pal = NULL; @@ -1750,8 +1770,12 @@ bool CGEEngine::showTitle(const char *name) { Vga->ShowQ->Append(_mouse); _heart->_enable = true; _mouse->On(); - for (selectSound(); !Snail->Idle() || VMENU::Addr;) + for (selectSound(); !Snail->Idle() || VMENU::Addr;) { mainLoop(); + if (_eventManager->_quitFlag) + return false; + } + _mouse->Off(); _heart->_enable = false; Vga->ShowQ->Clear(); @@ -1786,8 +1810,11 @@ bool CGEEngine::showTitle(const char *name) { Vga->ShowQ->Append(_mouse); //Mouse.On(); _heart->_enable = true; - for (takeName(); GetText::_ptr;) + for (takeName(); GetText::_ptr;) { mainLoop(); + if (_eventManager->_quitFlag) + return false; + } _heart->_enable = false; if (_keyboard->last() == Enter && *UsrFnam) usr_ok = true; @@ -1857,10 +1884,9 @@ void CGEEngine::cge_main(void) { if (Music && STARTUP::SoundOk) LoadMIDI(0); -/** *****DEBUG***** if (STARTUP::Mode < 2) movie(LGO_EXT); -*/ + if (showTitle("WELCOME")) { if ((!_isDemo) && (STARTUP::Mode == 1)) movie("X02"); // intro diff --git a/engines/cge/cge_main.h b/engines/cge/cge_main.h index 3eea114420..effded84cc 100644 --- a/engines/cge/cge_main.h +++ b/engines/cge/cge_main.h @@ -174,6 +174,7 @@ extern int OffUseCount; extern Sprite *_pocLight; extern Keyboard *_keyboard; extern MOUSE *_mouse; +extern EventManager *_eventManager; extern Sprite *_pocket[]; extern Sprite *_sprite; extern Sprite *_miniCave; diff --git a/engines/cge/events.cpp b/engines/cge/events.cpp index 49b08e407b..92c356fa5f 100644 --- a/engines/cge/events.cpp +++ b/engines/cge/events.cpp @@ -25,6 +25,7 @@ * Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon */ +#include "common/events.h" #include "cge/events.h" #include "cge/events.h" #include "cge/text.h" @@ -57,103 +58,85 @@ const uint16 Keyboard::_code[0x60] = { 0 * 0x5F }; +const uint16 Keyboard::_scummVmCodes[0x60] = { + 0, Common::KEYCODE_ESCAPE, Common::KEYCODE_1, Common::KEYCODE_2, Common::KEYCODE_3, + Common::KEYCODE_4, Common::KEYCODE_5, Common::KEYCODE_6, Common::KEYCODE_7, Common::KEYCODE_8, + Common::KEYCODE_9, Common::KEYCODE_0, Common::KEYCODE_MINUS, Common::KEYCODE_PLUS, Common::KEYCODE_BACKSPACE, + Common::KEYCODE_TAB, Common::KEYCODE_q, Common::KEYCODE_w, Common::KEYCODE_e, Common::KEYCODE_r, + Common::KEYCODE_t, Common::KEYCODE_y, Common::KEYCODE_u, Common::KEYCODE_i, Common::KEYCODE_o, + Common::KEYCODE_p, Common::KEYCODE_LEFTBRACKET, Common::KEYCODE_RIGHTBRACKET, Common::KEYCODE_RETURN, 0/*Ctrl*/, + Common::KEYCODE_a, Common::KEYCODE_s, Common::KEYCODE_d, Common::KEYCODE_f, Common::KEYCODE_g, + Common::KEYCODE_h, Common::KEYCODE_j, Common::KEYCODE_k, Common::KEYCODE_l, Common::KEYCODE_SEMICOLON, + Common::KEYCODE_BACKSLASH, Common::KEYCODE_TILDE, Common::KEYCODE_LSHIFT, Common::KEYCODE_BACKSLASH, Common::KEYCODE_z, + Common::KEYCODE_x, Common::KEYCODE_c, Common::KEYCODE_v, Common::KEYCODE_b, Common::KEYCODE_n, + Common::KEYCODE_m, Common::KEYCODE_COMMA, Common::KEYCODE_PERIOD, Common::KEYCODE_SLASH, Common::KEYCODE_RSHIFT, + Common::KEYCODE_KP_MULTIPLY, 0 /*Alt*/, Common::KEYCODE_SPACE, Common::KEYCODE_CAPSLOCK, Common::KEYCODE_F1, + Common::KEYCODE_F2, Common::KEYCODE_F3, Common::KEYCODE_F4, Common::KEYCODE_F5, Common::KEYCODE_F6, + Common::KEYCODE_F7, Common::KEYCODE_F8, Common::KEYCODE_F9, Common::KEYCODE_F10, Common::KEYCODE_NUMLOCK, + Common::KEYCODE_SCROLLOCK, Common::KEYCODE_KP7, Common::KEYCODE_KP8, Common::KEYCODE_KP9, Common::KEYCODE_KP_MINUS, + Common::KEYCODE_KP4, Common::KEYCODE_KP5, Common::KEYCODE_KP6, Common::KEYCODE_KP_PLUS, Common::KEYCODE_KP1, + Common::KEYCODE_KP2, Common::KEYCODE_KP3, Common::KEYCODE_KP0, Common::KEYCODE_KP_PERIOD, 0, + 0, 0, Common::KEYCODE_F11, Common::KEYCODE_F12, 0, + 0, 0, 0, 0, 0, + 0 +}; Keyboard::Keyboard() { _client = NULL; - Common::set_to(&_key[0], &_key[0x60], 0); + Common::set_to(&_key[0], &_key[0x60], false); _current = 0; - - // steal keyboard interrupt - /* TODO replace totally by scummvm handling - OldKeyboard = getvect(KEYBD_INT); - setvect(KEYBD_INT, NewKeyboard); - */ - warning("STUB: Keyboard::Keyboard"); } - Keyboard::~Keyboard() { - // bring back keyboard interrupt - /* TODO replace totally by scummvm handling - setvect(KEYBD_INT, OldKeyboard); - */ - // FIXME: STUB: KEYBOARD::~KEYBOARD } - Sprite *Keyboard::setClient(Sprite *spr) { Swap(_client, spr); return spr; } +bool Keyboard::getKey(uint16 keycode, int &cgeCode) { + if ((keycode == Common::KEYCODE_LCTRL) || (keycode == Common::KEYCODE_RCTRL)) { + cgeCode = 29; + return true; + } -void Keyboard::NewKeyboard(...) { - // table address - /* - _SI = (uint16) Key; - - // take keyboard code - asm in al,60h - asm mov bl,al - asm and bx,007Fh - asm cmp bl,60h - asm jae xit - asm cmp al,bl - asm je ok // key pressed - - // key released... - asm cmp [si+bx],bh // BH == 0 - asm jne ok - // ...but not pressed: call the original service - OldKeyboard(); - return; - - ok: - asm shl ax,1 - asm and ah,1 - asm xor ah,1 - asm mov [si+bx],ah - asm jz xit // released: exit - - // pressed: lock ASCII code - _SI = (uint16) Code; - asm add bx,bx // uint16 size - asm mov ax,[si+bx] - asm or ax,ax - asm jz xit // zero means NO KEY - Current = _AX; - - _SI = (uint16) Client; - asm or si,si - asm jz xit // if (Client) ... - //--- fill current event entry with mask, key code and sprite - asm mov bx,EvtHead // take queue head pointer - asm inc byte ptr EvtHead // update queue head pointer - asm shl bx,3 // * 8 - _AX = Current; - asm mov Evt[bx].(struct EVENT)X,ax // key code - asm mov ax,KEYB // event mask - asm mov Evt[bx].(struct EVENT)Msk,ax // event mask - //asm mov Evt[bx].(struct EVENT)Y,dx // row - asm mov Evt[bx].(struct EVENT)Ptr,si // SPRITE pointer - - xit: - - asm in al,61h // kbd control lines - asm push ax // save it - asm or al,80h // set the "enable kbd" bit - asm out 61h,al // and write it out - asm pop ax // original control port value - asm out 61h,al // write it back - asm mov al,20h // send End-Of-Interrupt - asm out 20h,al // to the 8259 IC - */ - warning("STUB: Keyboard::NewKeyboard"); + // Scan through the ScummVM mapping list + for (int idx = 0; idx < 0x60; ++idx) { + if (_scummVmCodes[idx] == keycode) { + cgeCode = idx; + return true; + } + } + + return false; +} + +void Keyboard::NewKeyboard(Common::Event &event) { + int keycode; + if (!getKey(event.kbd.keycode, keycode)) + return; + + if (event.type == Common::EVENT_KEYUP) { + // Key release + _key[event.kbd.keycode] = false; + } else if (event.type == Common::EVENT_KEYDOWN) { + // Key press + _key[event.kbd.keycode] = true; + _current = Keyboard::_code[event.kbd.keycode]; + + if (_client) { + CGEEvent &evt = Evt[EvtHead++]; + evt._x = _current; // Keycode + evt._msk = KEYB; // Event mask + evt._ptr = _client; // Sprite pointer + } + } } /*----------------- MOUSE interface -----------------*/ -Event Evt[EVT_MAX]; +CGEEvent Evt[EVT_MAX]; uint16 EvtHead = 0, EvtTail = 0; @@ -268,7 +251,7 @@ void MOUSE::ClrEvt(Sprite *spr) { void MOUSE::Tick(void) { step(); while (EvtTail != EvtHead) { - Event e = Evt[EvtTail]; + CGEEvent e = Evt[EvtTail]; if (e._msk) { if (Hold && e._ptr != Hold) Hold->touch(e._msk | ATTN, e._x - Hold->_x, e._y - Hold->_y); @@ -313,5 +296,24 @@ void MOUSE::Tick(void) { Hold->gotoxy(_x - hx, _y - hy); } +/*----------------- EventManager interface -----------------*/ + +EventManager::EventManager() { + _quitFlag = false; +} + +void EventManager::poll() { + while (g_system->getEventManager()->pollEvent(_event)) { + switch (_event.type) { + case Common::EVENT_QUIT: + _quitFlag = true; + return; + case Common::EVENT_KEYDOWN: + case Common::EVENT_KEYUP: + _keyboard->NewKeyboard(_event); + break; + } + } +} } // End of namespace CGE diff --git a/engines/cge/events.h b/engines/cge/events.h index 462571f5ad..be003ea0d8 100644 --- a/engines/cge/events.h +++ b/engines/cge/events.h @@ -28,6 +28,7 @@ #ifndef __CGE_CGE_EVENTS__ #define __CGE_CGE_EVENTS__ +#include "common/events.h" #include "cge/game.h" #include "cge/talk.h" #include "cge/jbw.h" @@ -45,13 +46,17 @@ namespace CGE { class Keyboard { +private: + bool getKey(uint16 keycode, int &cgeCode); public: static const uint16 _code[0x60]; + static const uint16 _scummVmCodes[0x60]; - void NewKeyboard(...); uint16 _current; Sprite *_client; - uint8 _key[0x60]; + bool _key[0x60]; + + void NewKeyboard(Common::Event &event); uint16 last() { uint16 cur = _current; _current = 0; @@ -77,14 +82,14 @@ public: extern TALK *Talk; -struct Event { +struct CGEEvent { uint16 _msk; uint16 _x; uint16 _y; Sprite *_ptr; }; -extern Event Evt[EVT_MAX]; +extern CGEEvent Evt[EVT_MAX]; extern uint16 EvtHead, EvtTail; typedef void (MOUSE_FUN)(void); @@ -112,8 +117,17 @@ private: CGEEngine *_vm; }; -/*----------------- Access variables -----------------*/ -// TODO: Move this into either the CGEEngine class or a suitable 'globals' +/*----------------- EventManager interface -----------------*/ + +class EventManager { +private: + Common::Event _event; +public: + bool _quitFlag; + + EventManager(); + void poll(); +}; } // End of namespace CGE |