aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/cge/cge.cpp4
-rw-r--r--engines/cge/cge.h2
-rw-r--r--engines/cge/cge_main.cpp42
-rw-r--r--engines/cge/cge_main.h1
-rw-r--r--engines/cge/events.cpp160
-rw-r--r--engines/cge/events.h26
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