Removed the buffering of mouse and keyboard events. I don't think any of

our other engines do this, so there is little reason for BS2 to. I did add
a filtering mechanism so that mouse button releases and scroll wheeling is
ignored during normal gameplay, but I don't know if that was necessary
either.

Since this left little more than an empty husk where the Input class used
to be, I've eliminated that class and buried its remains in Sword2Engine.

svn-id: r13812
This commit is contained in:
Torbjörn Andersson 2004-05-09 13:32:04 +00:00
parent 577600537c
commit fc970b3c75
14 changed files with 222 additions and 246 deletions

View file

@ -302,12 +302,17 @@ bool Debugger::Cmd_Var(int argc, const char **argv) {
}
bool Debugger::Cmd_Rect(int argc, const char **argv) {
uint32 filter = _vm->setEventFilter(0);
_definingRectangles = !_definingRectangles;
if (_definingRectangles)
if (_definingRectangles) {
_vm->setEventFilter(filter & ~(RD_LEFTBUTTONUP | RD_RIGHTBUTTONUP));
DebugPrintf("Mouse rectangles enabled\n");
else
} else {
_vm->setEventFilter(filter | RD_LEFTBUTTONUP | RD_RIGHTBUTTONUP);
DebugPrintf("Mouse rectangles disabled\n");
}
_draggingRectangle = 0;
return true;

View file

@ -304,6 +304,8 @@ void Dialog::setResult(int result) {
}
int Dialog::run() {
uint32 oldFilter = _gui->_vm->setEventFilter(0);
int i;
paint();
@ -316,17 +318,16 @@ int Dialog::run() {
_gui->_vm->_graphics->processMenu();
_gui->_vm->_graphics->updateDisplay(false);
int16 newMouseX = _gui->_vm->_input->_mouseX;
int16 newMouseY = _gui->_vm->_input->_mouseY + 40;
int16 newMouseX = _gui->_vm->_mouseX;
int16 newMouseY = _gui->_vm->_mouseY + 40;
MouseEvent *me = _gui->_vm->_input->mouseEvent();
KeyboardEvent ke;
int32 keyboardStatus = _gui->_vm->_input->readKey(&ke);
MouseEvent *me = _gui->_vm->mouseEvent();
KeyboardEvent *ke = _gui->_vm->keyboardEvent();
if (keyboardStatus == RD_OK) {
if (ke.keycode == 27)
if (ke) {
if (ke->keycode == 27)
setResult(0);
else if (ke.keycode == '\n' || ke.keycode == '\r')
else if (ke->keycode == '\n' || ke->keycode == '\r')
setResult(1);
}
@ -391,8 +392,8 @@ int Dialog::run() {
if (newMouseX != oldMouseX || newMouseY != oldMouseY)
_widgets[i]->onMouseMove(newMouseX, newMouseY);
if (keyboardStatus == RD_OK)
_widgets[i]->onKey(&ke);
if (ke)
_widgets[i]->onKey(ke);
_widgets[i]->onTick();
}
@ -406,6 +407,7 @@ int Dialog::run() {
setResult(0);
}
_gui->_vm->setEventFilter(oldFilter);
return _result;
}
@ -1480,19 +1482,13 @@ void SaveLoadDialog::saveLoadError(byte* text) {
// Wait for ESC or mouse click
while (1) {
MouseEvent *me;
_gui->_vm->_graphics->updateDisplay();
if (_gui->_vm->_input->keyWaiting()) {
KeyboardEvent ke;
_gui->_vm->_input->readKey(&ke);
if (ke.keycode == 27)
KeyboardEvent *ke = _gui->_vm->keyboardEvent();
if (ke && ke->keycode == 27)
break;
}
me = _gui->_vm->_input->mouseEvent();
MouseEvent *me = _gui->_vm->mouseEvent();
if (me && (me->buttons & RD_LEFTBUTTONDOWN))
break;

View file

@ -183,14 +183,14 @@ void Debugger::buildDebugText(void) {
if (_vm->_mouseTouching)
sprintf(buf, "mouse %d,%d (id %d: %s)",
_vm->_input->_mouseX + _vm->_thisScreen.scroll_offset_x,
_vm->_input->_mouseY + _vm->_thisScreen.scroll_offset_y,
_vm->_mouseX + _vm->_thisScreen.scroll_offset_x,
_vm->_mouseY + _vm->_thisScreen.scroll_offset_y,
_vm->_mouseTouching,
_vm->fetchObjectName(_vm->_mouseTouching, name));
else
sprintf(buf, "mouse %d,%d (not touching)",
_vm->_input->_mouseX + _vm->_thisScreen.scroll_offset_x,
_vm->_input->_mouseY + _vm->_thisScreen.scroll_offset_y);
_vm->_mouseX + _vm->_thisScreen.scroll_offset_x,
_vm->_mouseY + _vm->_thisScreen.scroll_offset_y);
makeDebugTextBlock(buf, 0, 30);
@ -311,7 +311,7 @@ void Debugger::drawDebugGraphics(void) {
// mouse marker & coords
if (_displayMouseMarker)
plotCrossHair(_vm->_input->_mouseX + _vm->_thisScreen.scroll_offset_x, _vm->_input->_mouseY + _vm->_thisScreen.scroll_offset_y, 215);
plotCrossHair(_vm->_mouseX + _vm->_thisScreen.scroll_offset_x, _vm->_mouseY + _vm->_thisScreen.scroll_offset_y, 215);
// mouse area rectangle / sprite box rectangle when testing anims

View file

@ -25,45 +25,6 @@ namespace Sword2 {
#define MOUSEFLASHFRAME 6
/**
* Logs the mouse button event passed in buttons. The button events were
* originaly defined as RD_LEFTBUTTONDOWN, RD_LEFTBUTTONUP, RD_RIGHTBUTTONDOWN
* and RD_RIGHTBUTTONUP. ScummVM adds RD_WHEELDOWN and RD_WHEELUP.
*/
void Input::logMouseEvent(uint16 buttons) {
// We need to leave the one, which is the current event, alone!
if (_mouseBacklog == MAX_MOUSE_EVENTS - 1)
return;
_mouseLog[(_mouseBacklog + _mouseLogPos) % MAX_MOUSE_EVENTS].buttons = buttons;
_mouseBacklog++;
}
bool Input::checkForMouseEvents(void) {
return _mouseBacklog != 0;
}
/**
* Get the next pending mouse event.
* @return a pointer to the mouse event, or NULL of there is none
*/
MouseEvent *Input::mouseEvent(void) {
MouseEvent *me;
if (_mouseBacklog) {
me = &_mouseLog[_mouseLogPos];
if (++_mouseLogPos == MAX_MOUSE_EVENTS)
_mouseLogPos = 0;
_mouseBacklog--;
return me;
}
return NULL;
}
void Graphics::decompressMouse(byte *decomp, byte *comp, int width, int height, int pitch, int xOff, int yOff) {
int32 size = width * height;
int32 i = 0;

View file

@ -424,9 +424,9 @@ int32 MoviePlayer::playDummy(const char *filename, MovieTextObject *text[], byte
_vm->_graphics->updateDisplay();
KeyboardEvent ke;
KeyboardEvent *ke = _vm->keyboardEvent();
if ((_vm->_input->readKey(&ke) == RD_OK && ke.keycode == 27) || _vm->_quit) {
if ((ke && ke->keycode == 27) || _vm->_quit) {
_snd->stopHandle(handle);
skipCutscene = true;
break;

View file

@ -43,10 +43,6 @@ enum {
RDERR_OPENVERSIONFILE,
// Keyboard error codes
RDERR_NOKEYWAITING,
// Sprite drawing error codes
RDERR_NOTIMPLEMENTED,
@ -77,17 +73,6 @@ enum {
RDERR_INVALIDID
};
// Mouse button defines
enum {
RD_LEFTBUTTONDOWN = 0x01,
RD_LEFTBUTTONUP = 0x02,
RD_RIGHTBUTTONDOWN = 0x04,
RD_RIGHTBUTTONUP = 0x08,
RD_WHEELUP = 0x10,
RD_WHEELDOWN = 0x20
};
// Sprite defines
enum {
@ -176,16 +161,6 @@ enum {
// Structure definitions
struct MouseEvent {
uint16 buttons;
};
struct KeyboardEvent {
uint16 ascii;
int keycode;
int modifiers;
};
#if !defined(__GNUC__)
#pragma START_PACK_STRUCTS
#endif
@ -230,52 +205,6 @@ struct MovieTextObject {
uint16 *speech;
};
// Input handling class
// Mouse buffer size
#define MAX_MOUSE_EVENTS 16
// Key buffer size
#define MAX_KEY_BUFFER 32
class Input {
private:
Sword2Engine *_vm;
uint8 _mouseBacklog;
uint8 _mouseLogPos;
MouseEvent _mouseLog[MAX_MOUSE_EVENTS];
void logMouseEvent(uint16 buttons);
// The number of key presses waiting to be processed.
uint8 _keyBacklog;
// Index of the next key to read from the buffer.
uint8 _keyLogPos;
// The keyboard buffer
KeyboardEvent _keyBuffer[MAX_KEY_BUFFER];
void writeKey(uint16 ascii, int keycode, int modifiers);
public:
int16 _mouseX;
int16 _mouseY;
Input(Sword2Engine *vm) :
_vm(vm), _mouseBacklog(0), _mouseLogPos(0), _keyBacklog(0),
_keyLogPos(0), _mouseX(0), _mouseY(0) {};
void parseEvents(void);
MouseEvent *mouseEvent(void);
bool checkForMouseEvents(void);
bool keyWaiting(void);
int32 readKey(KeyboardEvent *ev);
};
} // End of namespace Sword2
#endif

View file

@ -24,49 +24,6 @@
namespace Sword2 {
// ---------------------------------------------------------------------------
// OSystem Event Handler. Full of cross platform goodness and 99% fat free!
// ---------------------------------------------------------------------------
void Input::parseEvents(void) {
OSystem::Event event;
while (_vm->_system->poll_event(&event)) {
switch (event.event_code) {
case OSystem::EVENT_KEYDOWN:
writeKey(event.kbd.ascii, event.kbd.keycode, event.kbd.flags);
break;
case OSystem::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y - MENUDEEP;
break;
case OSystem::EVENT_LBUTTONDOWN:
logMouseEvent(RD_LEFTBUTTONDOWN);
break;
case OSystem::EVENT_RBUTTONDOWN:
logMouseEvent(RD_RIGHTBUTTONDOWN);
break;
case OSystem::EVENT_LBUTTONUP:
logMouseEvent(RD_LEFTBUTTONUP);
break;
case OSystem::EVENT_RBUTTONUP:
logMouseEvent(RD_RIGHTBUTTONUP);
break;
case OSystem::EVENT_WHEELUP:
logMouseEvent(RD_WHEELUP);
break;
case OSystem::EVENT_WHEELDOWN:
logMouseEvent(RD_WHEELDOWN);
break;
case OSystem::EVENT_QUIT:
_vm->closeGame();
break;
default:
break;
}
}
}
/**
* Tell updateDisplay() that the scene needs to be completely updated.
*/
@ -100,7 +57,7 @@ void Graphics::markAsDirty(int16 x0, int16 y0, int16 x1, int16 y1) {
*/
void Graphics::updateDisplay(bool redrawScene) {
_vm->_input->parseEvents();
_vm->parseEvents();
fadeServer();
if (redrawScene) {

View file

@ -662,9 +662,9 @@ int32 Logic::fnPlayCredits(int32 *params) {
_vm->_graphics->updateDisplay();
KeyboardEvent ke;
KeyboardEvent *ke = _vm->keyboardEvent();
if (_vm->_input->readKey(&ke) == RD_OK && ke.keycode == 27) {
if (ke && ke->keycode == 27) {
if (!abortCredits) {
abortCredits = true;
_vm->_graphics->fadeDown();

View file

@ -28,7 +28,6 @@ MODULE_OBJS := \
sword2/walker.o \
sword2/driver/d_draw.o \
sword2/driver/d_sound.o \
sword2/driver/keyboard.o \
sword2/driver/menu.o \
sword2/driver/_mouse.o \
sword2/driver/palette.o \

View file

@ -107,7 +107,7 @@ void Sword2Engine::mouseEngine(void) {
systemMenuMouse();
break;
case MOUSE_holding:
if (_input->_mouseY < 400) {
if (_mouseY < 400) {
_mouseMode = MOUSE_normal;
debug(5, " releasing");
}
@ -118,13 +118,13 @@ void Sword2Engine::mouseEngine(void) {
}
int Sword2Engine::menuClick(int menu_items) {
if (_input->_mouseX < RDMENU_ICONSTART)
if (_mouseX < RDMENU_ICONSTART)
return -1;
if (_input->_mouseX > RDMENU_ICONSTART + menu_items * (RDMENU_ICONWIDE + RDMENU_ICONSPACING) - RDMENU_ICONSPACING)
if (_mouseX > RDMENU_ICONSTART + menu_items * (RDMENU_ICONWIDE + RDMENU_ICONSPACING) - RDMENU_ICONSPACING)
return -1;
return (_input->_mouseX - RDMENU_ICONSTART) / (RDMENU_ICONWIDE + RDMENU_ICONSPACING);
return (_mouseX - RDMENU_ICONSTART) / (RDMENU_ICONWIDE + RDMENU_ICONSPACING);
}
void Sword2Engine::systemMenuMouse(void) {
@ -144,7 +144,7 @@ void Sword2Engine::systemMenuMouse(void) {
// If the mouse is moved off the menu, close it. Unless the player is
// dead, in which case the menu should always be visible.
if (_input->_mouseY > 0 && !Logic::_scriptVars[DEAD]) {
if (_mouseY > 0 && !Logic::_scriptVars[DEAD]) {
_mouseMode = MOUSE_normal;
_graphics->hideMenu(RDMENU_TOP);
return;
@ -152,12 +152,12 @@ void Sword2Engine::systemMenuMouse(void) {
// Check if the user left-clicks anywhere in the menu area.
me = _input->mouseEvent();
me = mouseEvent();
if (!me || !(me->buttons & RD_LEFTBUTTONDOWN))
return;
if (_input->_mouseY > 0)
if (_mouseY > 0)
return;
hit = menuClick(ARRAYSIZE(icon_list));
@ -266,7 +266,7 @@ void Sword2Engine::dragMouse(void) {
// objects in the scene, so if the mouse moves off the inventory menu,
// then close it.
if (_input->_mouseY < 400) {
if (_mouseY < 400) {
_mouseMode = MOUSE_normal;
_graphics->hideMenu(RDMENU_BOTTOM);
return;
@ -278,7 +278,7 @@ void Sword2Engine::dragMouse(void) {
// Now do the normal click stuff
me = _input->mouseEvent();
me = mouseEvent();
if (!me)
return;
@ -319,8 +319,8 @@ void Sword2Engine::dragMouse(void) {
// These might be required by the action script about to be run
Logic::_scriptVars[MOUSE_X] = _input->_mouseX + _thisScreen.scroll_offset_x;
Logic::_scriptVars[MOUSE_Y] = _input->_mouseY + _thisScreen.scroll_offset_y;
Logic::_scriptVars[MOUSE_X] = _mouseX + _thisScreen.scroll_offset_x;
Logic::_scriptVars[MOUSE_Y] = _mouseY + _thisScreen.scroll_offset_y;
// For scripts to know what's been clicked. First used for
// 'room_13_turning_script' in object 'biscuits_13'
@ -387,13 +387,13 @@ void Sword2Engine::menuMouse(void) {
// If the mouse is moved off the menu, close it.
if (_input->_mouseY < 400) {
if (_mouseY < 400) {
_mouseMode = MOUSE_normal;
_graphics->hideMenu(RDMENU_BOTTOM);
return;
}
me = _input->mouseEvent();
me = mouseEvent();
if (!me)
return;
@ -471,7 +471,7 @@ void Sword2Engine::normalMouse(void) {
// big-object menu lock situation, of if the player is dragging an
// object.
if (_input->_mouseY < 0 && !_mouseModeLocked && !Logic::_scriptVars[OBJECT_HELD]) {
if (_mouseY < 0 && !_mouseModeLocked && !Logic::_scriptVars[OBJECT_HELD]) {
_mouseMode = MOUSE_system_menu;
if (_mouseTouching) {
@ -490,7 +490,7 @@ void Sword2Engine::normalMouse(void) {
// Check if the cursor has moved onto the inventory menu area. No
// inventory in big-object menu lock situation,
if (_input->_mouseY > 399 && !_mouseModeLocked) {
if (_mouseY > 399 && !_mouseModeLocked) {
// If an object is being held, i.e. if the mouse cursor has a
// luggage, go to drag mode instead of menu mode, but the menu
// is still opened.
@ -523,7 +523,7 @@ void Sword2Engine::normalMouse(void) {
mouseOnOff();
me = _input->mouseEvent();
me = mouseEvent();
if (!me)
return;
@ -539,8 +539,8 @@ void Sword2Engine::normalMouse(void) {
if (button_down) {
// set both (x1,y1) and (x2,y2) to this point
_debugger->_rectX1 = _debugger->_rectX2 = (uint32) _input->_mouseX + _thisScreen.scroll_offset_x;
_debugger->_rectY1 = _debugger->_rectY2 = (uint32) _input->_mouseY + _thisScreen.scroll_offset_y;
_debugger->_rectX1 = _debugger->_rectX2 = (uint32) _mouseX + _thisScreen.scroll_offset_x;
_debugger->_rectY1 = _debugger->_rectY2 = (uint32) _mouseY + _thisScreen.scroll_offset_y;
_debugger->_draggingRectangle = 1;
}
} else if (_debugger->_draggingRectangle == 1) {
@ -552,8 +552,8 @@ void Sword2Engine::normalMouse(void) {
_debugger->_draggingRectangle = 2;
} else {
// drag rectangle
_debugger->_rectX2 = (uint32) _input->_mouseX + _thisScreen.scroll_offset_x;
_debugger->_rectY2 = (uint32) _input->_mouseY + _thisScreen.scroll_offset_y;
_debugger->_rectX2 = (uint32) _mouseX + _thisScreen.scroll_offset_x;
_debugger->_rectY2 = (uint32) _mouseY + _thisScreen.scroll_offset_y;
}
} else {
// currently locked to avoid knocking out of place
@ -582,8 +582,7 @@ void Sword2Engine::normalMouse(void) {
// Now do the normal click stuff
// We only care about down clicks when the mouse is over an object. We
// ignore mouse releases
// We only care about down clicks when the mouse is over an object.
if (!_mouseTouching || !button_down)
return;
@ -618,8 +617,8 @@ void Sword2Engine::normalMouse(void) {
// These might be required by the action script about to be run
Logic::_scriptVars[MOUSE_X] = _input->_mouseX + _thisScreen.scroll_offset_x;
Logic::_scriptVars[MOUSE_Y] = _input->_mouseY + _thisScreen.scroll_offset_y;
Logic::_scriptVars[MOUSE_X] = _mouseX + _thisScreen.scroll_offset_x;
Logic::_scriptVars[MOUSE_Y] = _mouseY + _thisScreen.scroll_offset_y;
if (_mouseTouching == Logic::_scriptVars[EXIT_CLICK_ID] && (me->buttons & RD_LEFTBUTTONDOWN)) {
// It's the exit double click situation. Let the existing
@ -693,7 +692,7 @@ void Sword2Engine::mouseOnOff(void) {
// don't detect objects that are hidden behind the menu bars (ie. in
// the scrolled-off areas of the screen)
if (_input->_mouseY < 0 || _input->_mouseY > 399) {
if (_mouseY < 0 || _mouseY > 399) {
pointer_type = 0;
_mouseTouching = 0;
} else {
@ -823,10 +822,10 @@ uint32 Sword2Engine::checkMouseList(void) {
// mouse-detection-box
if (_mouseList[i].priority == priority &&
_input->_mouseX + _thisScreen.scroll_offset_x >= _mouseList[i].x1 &&
_input->_mouseX + _thisScreen.scroll_offset_x <= _mouseList[i].x2 &&
_input->_mouseY + _thisScreen.scroll_offset_y >= _mouseList[i].y1 &&
_input->_mouseY + _thisScreen.scroll_offset_y <= _mouseList[i].y2) {
_mouseX + _thisScreen.scroll_offset_x >= _mouseList[i].x1 &&
_mouseX + _thisScreen.scroll_offset_x <= _mouseList[i].x2 &&
_mouseY + _thisScreen.scroll_offset_y >= _mouseList[i].y1 &&
_mouseY + _thisScreen.scroll_offset_y <= _mouseList[i].y2) {
// Record id
_mouseTouching = _mouseList[i].id;
@ -994,8 +993,8 @@ void Sword2Engine::createPointerText(uint32 text_id, uint32 pointer_res) {
// line reference number
_pointerTextBlocNo = _fontRenderer->buildNewBloc(
text + 2, _input->_mouseX + xOffset,
_input->_mouseY + yOffset,
text + 2, _mouseX + xOffset,
_mouseY + yOffset,
POINTER_TEXT_WIDTH, POINTER_TEXT_PEN,
RDSPR_TRANS | RDSPR_DISPLAYALIGN,
_speechFontId, justification);
@ -1066,7 +1065,7 @@ void Sword2Engine::registerMouse(ObjectMouse *ob_mouse) {
void Sword2Engine::monitorPlayerActivity(void) {
// if there is at least one mouse event outstanding
if (_input->checkForMouseEvents()) {
if (checkForMouseEvents()) {
// reset activity delay counter
_playerActivityDelay = 0;
} else {
@ -1133,7 +1132,7 @@ int32 Logic::fnAddHuman(int32 *params) {
}
// if mouse is over menu area
if (_vm->_input->_mouseY > 399) {
if (_vm->_mouseY > 399) {
if (_vm->_mouseMode != MOUSE_holding) {
// VITAL - reset things & rebuild the menu
_vm->_mouseMode = MOUSE_normal;

View file

@ -860,14 +860,11 @@ void ResourceManager::getCd(int cd) {
// CD2: "RBSII2"
while (1) {
KeyboardEvent ke;
MouseEvent *me;
me = _vm->_input->mouseEvent();
MouseEvent *me = _vm->mouseEvent();
if (me && (me->buttons & (RD_LEFTBUTTONDOWN | RD_RIGHTBUTTONDOWN)))
break;
if (_vm->_input->readKey(&ke) == RD_OK)
if (_vm->keyboardEvent())
break;
_vm->_graphics->updateDisplay();

View file

@ -135,11 +135,11 @@ int32 Logic::fnChoose(int32 *params) {
}
// The menu is there - we're just waiting for a click. We only care
// about left clicks and ignore mouse releases.
// about left clicks.
MouseEvent *me = _vm->_input->mouseEvent();
MouseEvent *me = _vm->mouseEvent();
if (!me || !(me->buttons & RD_LEFTBUTTONDOWN) || _vm->_input->_mouseY < 400)
if (!me || !(me->buttons & RD_LEFTBUTTONDOWN) || _vm->_mouseY < 400)
return IR_REPEAT;
// Check for click on a menu.
@ -200,7 +200,7 @@ int32 Logic::fnEndConversation(int32 *params) {
_vm->_graphics->hideMenu(RDMENU_BOTTOM);
if (_vm->_input->_mouseY > 399) {
if (_vm->_mouseY > 399) {
// Will wait for cursor to move off the bottom menu
_vm->_mouseMode = MOUSE_holding;
}
@ -995,8 +995,8 @@ int32 Logic::fnISpeak(int32 *params) {
// So that we can go to the options panel while text & speech is
// being tested
if (_scriptVars[SYSTEM_TESTING_TEXT] == 0 || _vm->_input->_mouseY > 0) {
MouseEvent *me = _vm->_input->mouseEvent();
if (_scriptVars[SYSTEM_TESTING_TEXT] == 0 || _vm->_mouseY > 0) {
MouseEvent *me = _vm->mouseEvent();
// Note that we now have TWO click-delays - one for LEFT
// button, one for RIGHT BUTTON
@ -1004,7 +1004,7 @@ int32 Logic::fnISpeak(int32 *params) {
if ((!_leftClickDelay && me && (me->buttons & RD_LEFTBUTTONDOWN)) ||
(!_rightClickDelay && me && (me->buttons & RD_RIGHTBUTTONDOWN))) {
// Mouse click, after click_delay has expired -> end
// the speech. We ignore mouse releases
// the speech.
// if testing text & speech
if (_scriptVars[SYSTEM_TESTING_TEXT]) {
@ -1018,10 +1018,6 @@ int32 Logic::fnISpeak(int32 *params) {
}
}
// Trash anything that's buffered
while (_vm->_input->mouseEvent())
;
speechFinished = true;
// if speech sample playing, halt it prematurely

View file

@ -120,6 +120,11 @@ Sword2Engine::Sword2Engine(GameDetector *detector, OSystem *syst)
_mixer->setVolume(256);
_mixer->setMusicVolume(256);
_keyboardEvent.pending = false;
_mouseEvent.pending = false;
_mouseX = _mouseY = 0;
// get some falling RAM and put it in your pocket, never let it slip
// away
@ -137,7 +142,6 @@ Sword2Engine::Sword2Engine(GameDetector *detector, OSystem *syst)
_logic = new Logic(this);
_fontRenderer = new FontRenderer(this);
_gui = new Gui(this);
_input = new Input(this);
_sound = new Sound(this);
_lastPaletteRes = 0;
@ -194,7 +198,6 @@ Sword2Engine::~Sword2Engine() {
delete _debugger;
delete _graphics;
delete _sound;
delete _input;
delete _gui;
delete _fontRenderer;
delete _logic;
@ -221,7 +224,9 @@ void Sword2Engine::errorString(const char *buf1, char *buf2) {
}
int32 Sword2Engine::initialiseGame(void) {
// init engine drivers
// During normal gameplay, we care neither about mouse button releases
// nor the scroll wheel.
setEventFilter(RD_LEFTBUTTONUP | RD_RIGHTBUTTONUP | RD_WHEELUP | RD_WHEELDOWN);
// initialise global script variables
// res 1 is the globals list
@ -258,6 +263,101 @@ void Sword2Engine::closeGame(void) {
_quit = true;
}
bool Sword2Engine::checkForMouseEvents(void) {
return _mouseEvent.pending;
}
MouseEvent *Sword2Engine::mouseEvent(void) {
if (!_mouseEvent.pending)
return NULL;
_mouseEvent.pending = false;
return &_mouseEvent;
}
KeyboardEvent *Sword2Engine::keyboardEvent(void) {
if (!_keyboardEvent.pending)
return NULL;
_keyboardEvent.pending = false;
return &_keyboardEvent;
}
uint32 Sword2Engine::setEventFilter(uint32 filter) {
uint32 oldFilter = _eventFilter;
_eventFilter = filter;
return oldFilter;
}
/**
* OSystem Event Handler. Full of cross platform goodness and 99% fat free!
*/
void Sword2Engine::parseEvents(void) {
OSystem::Event event;
while (_system->poll_event(&event)) {
switch (event.event_code) {
case OSystem::EVENT_KEYDOWN:
if (!(_eventFilter & RD_KEYDOWN)) {
_keyboardEvent.pending = true;
_keyboardEvent.ascii = event.kbd.ascii;
_keyboardEvent.keycode = event.kbd.keycode;
_keyboardEvent.modifiers = event.kbd.flags;
}
break;
case OSystem::EVENT_MOUSEMOVE:
if (!(_eventFilter & RD_KEYDOWN)) {
_mouseX = event.mouse.x;
_mouseY = event.mouse.y - RDMENU_MENUDEEP;
}
break;
case OSystem::EVENT_LBUTTONDOWN:
if (!(_eventFilter & RD_LEFTBUTTONDOWN)) {
_mouseEvent.pending = true;
_mouseEvent.buttons = RD_LEFTBUTTONDOWN;
}
break;
case OSystem::EVENT_RBUTTONDOWN:
if (!(_eventFilter & RD_RIGHTBUTTONDOWN)) {
_mouseEvent.pending = true;
_mouseEvent.buttons = RD_RIGHTBUTTONDOWN;
}
break;
case OSystem::EVENT_LBUTTONUP:
if (!(_eventFilter & RD_LEFTBUTTONUP)) {
_mouseEvent.pending = true;
_mouseEvent.buttons = RD_LEFTBUTTONUP;
}
break;
case OSystem::EVENT_RBUTTONUP:
if (!(_eventFilter & RD_RIGHTBUTTONUP)) {
_mouseEvent.pending = true;
_mouseEvent.buttons = RD_RIGHTBUTTONUP;
}
break;
case OSystem::EVENT_WHEELUP:
if (!(_eventFilter & RD_WHEELUP)) {
_mouseEvent.pending = true;
_mouseEvent.buttons = RD_WHEELUP;
}
break;
case OSystem::EVENT_WHEELDOWN:
if (!(_eventFilter & RD_WHEELDOWN)) {
_mouseEvent.pending = true;
_mouseEvent.buttons = RD_WHEELDOWN;
}
break;
case OSystem::EVENT_QUIT:
closeGame();
break;
default:
break;
}
}
}
void Sword2Engine::gameCycle(void) {
// do one game cycle
@ -290,8 +390,6 @@ void Sword2Engine::gameCycle(void) {
}
void Sword2Engine::go() {
KeyboardEvent ke;
_quit = false;
debug(5, "CALLING: readOptionSettings");
@ -354,13 +452,13 @@ void Sword2Engine::go() {
}
#endif
if (_input->keyWaiting()) {
_input->readKey(&ke);
KeyboardEvent *ke = keyboardEvent();
if ((ke.modifiers == OSystem::KBD_CTRL && ke.keycode == 'd') || ke.ascii == '#' || ke.ascii == '~') {
if (ke) {
if ((ke->modifiers == OSystem::KBD_CTRL && ke->keycode == 'd') || ke->ascii == '#' || ke->ascii == '~') {
_debugger->attach();
} else if (ke.modifiers == 0 || ke.modifiers == OSystem::KBD_SHIFT) {
switch (ke.keycode) {
} else if (ke->modifiers == 0 || ke->modifiers == OSystem::KBD_SHIFT) {
switch (ke->keycode) {
case 'p':
if (_gamePaused)
unpauseGame();

View file

@ -50,8 +50,37 @@ class FontRenderer;
class Gui;
class Debugger;
enum {
RD_LEFTBUTTONDOWN = 0x01,
RD_LEFTBUTTONUP = 0x02,
RD_RIGHTBUTTONDOWN = 0x04,
RD_RIGHTBUTTONUP = 0x08,
RD_WHEELUP = 0x10,
RD_WHEELDOWN = 0x20,
RD_KEYDOWN = 0x40,
RD_MOUSEMOVE = 0x80
};
struct MouseEvent {
bool pending;
uint16 buttons;
};
struct KeyboardEvent {
bool pending;
uint16 ascii;
int keycode;
int modifiers;
};
class Sword2Engine : public Engine {
private:
uint32 _eventFilter;
// The event "buffers"
MouseEvent _mouseEvent;
KeyboardEvent _keyboardEvent;
uint32 _bootParam;
int32 _saveSlot;
@ -146,7 +175,6 @@ public:
MemoryManager *_memory;
ResourceManager *_resman;
Input *_input;
Sound *_sound;
Graphics *_graphics;
Logic *_logic;
@ -161,6 +189,17 @@ public:
uint32 _controlsFontId;
uint32 _redFontId;
int16 _mouseX;
int16 _mouseY;
uint32 setEventFilter(uint32 filter);
void parseEvents(void);
bool checkForMouseEvents(void);
MouseEvent *mouseEvent(void);
KeyboardEvent *keyboardEvent(void);
void resetRenderLists(void);
void buildDisplay(void);
void displayMsg(byte *text, int time);