scummvm/engines/cge/events.cpp
Johannes Schickel 61795739f8 COMMON: Rename Common::set_to to Common::fill.
This makes the name match with the name of the STL function with the same
behavior.
2011-11-16 18:06:30 +01:00

384 lines
12 KiB
C++

/* 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.
*
*/
/*
* This code is based on original Soltys source code
* Copyright (c) 1994-1995 Janus B. Wisniewski and L.K. Avalon
*/
#include "gui/saveload.h"
#include "gui/about.h"
#include "gui/message.h"
#include "common/config-manager.h"
#include "common/events.h"
#include "cge/events.h"
#include "cge/events.h"
#include "cge/text.h"
#include "cge/cge_main.h"
namespace CGE {
/*----------------- KEYBOARD interface -----------------*/
const uint16 Keyboard::_code[0x60] = {
0, Esc, '1', '2', '3',
'4', '5', '6', '7', '8',
'9', '0', '-', '+', BSp,
Tab, 'Q', 'W', 'E', 'R',
'T', 'Y', 'U', 'I', 'O',
'P', '[', ']', Enter, 0/*Ctrl*/,
'A', 'S', 'D', 'F', 'G',
'H', 'J', 'K', 'L', ';',
'\'', '`', 0/*LShift*/, '\\', 'Z',
'X', 'C', 'V', 'B', 'N',
'M', ',', '.', '/', 0/*RShift*/,
'*', 0/*Alt*/, ' ', 0/*Caps*/, F1,
F2, F3, F4, F5, F6,
F7, F8, F9, F10, 0/*NumLock*/,
0/*ScrollLock*/, Home, Up, PgUp, '-',
Left, Ctr, Right, '+', End,
Down, PgDn, Ins, Del, 0 * 0x54,
0 * 0x55, 0 * 0x56, F11, F12, 0 * 0x59,
0 * 0x5A, 0 * 0x5B, 0 * 0x5C, 0 * 0x5D, 0 * 0x5E,
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(CGEEngine *vm) : _client(NULL), _vm(vm) {
Common::fill(&_key[0], &_key[0x60], false);
_current = 0;
}
Keyboard::~Keyboard() {
}
Sprite *Keyboard::setClient(Sprite *spr) {
SWAP(_client, spr);
return spr;
}
bool Keyboard::getKey(Common::Event &event, int &cgeCode) {
Common::KeyCode keycode = event.kbd.keycode;
if ((keycode == Common::KEYCODE_LCTRL) || (keycode == Common::KEYCODE_RCTRL)) {
cgeCode = kKeyCtrl;
return true;
}
if ((keycode == Common::KEYCODE_LALT) || (keycode == Common::KEYCODE_RALT)) {
cgeCode = kKeyAlt;
return true;
}
if (keycode == Common::KEYCODE_KP_ENTER) {
cgeCode = 28;
return true;
}
if (keycode == Common::KEYCODE_F1) {
if (event.type == Common::EVENT_KEYUP)
return false;
// Display ScummVM version and translation strings
for (int i = 0; i < 5; i++)
_vm->_commandHandler->addCommand(kCmdInf, 1, kShowScummVMVersion + i, NULL);
return false;
} else if (keycode == Common::KEYCODE_F5) {
if (_vm->canSaveGameStateCurrently()) {
const EnginePlugin *plugin = NULL;
EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Save game:", "Save");
dialog->setSaveMode(true);
int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
Common::String savegameDescription = dialog->getResultString();
delete dialog;
if (savegameId != -1)
_vm->saveGameState(savegameId, savegameDescription);
}
return false;
} else if (keycode == Common::KEYCODE_F7) {
if (_vm->canLoadGameStateCurrently()) {
const EnginePlugin *plugin = NULL;
EngineMan.findGame(_vm->_gameDescription->gameid, &plugin);
GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser("Restore game:", "Restore");
dialog->setSaveMode(false);
int16 savegameId = dialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName());
delete dialog;
if (savegameId != -1)
_vm->loadGameState(savegameId);
}
return false;
}
// Scan through the ScummVM mapping list
for (int idx = 0; idx < 0x60; idx++) {
if (_scummVmCodes[idx] == event.kbd.ascii) {
cgeCode = idx;
return true;
}
}
return false;
}
void Keyboard::newKeyboard(Common::Event &event) {
int keycode;
if (!getKey(event, keycode))
return;
if (event.type == Common::EVENT_KEYUP) {
// Key release
_key[keycode] = false;
} else if (event.type == Common::EVENT_KEYDOWN) {
// Key press
_key[keycode] = true;
_current = Keyboard::_code[keycode];
if (_client) {
CGEEvent &evt = _vm->_eventManager->getNextEvent();
evt._x = _current; // Keycode
evt._mask = kEventKeyb; // Event mask
evt._spritePtr = _client; // Sprite pointer
}
}
}
uint16 Keyboard::lastKey() {
uint16 cur = _current;
_current = 0;
return cur;
}
/*----------------- MOUSE interface -----------------*/
Mouse::Mouse(CGEEngine *vm) : Sprite(vm, NULL), _busy(NULL), _hold(NULL), _hx(0), _vm(vm) {
_hold = NULL;
_hx = 0;
_hy = 0;
_exist = true;
_buttons = 0;
_busy = NULL;
_active = false;
_flags._kill = false;
const Seq ms[] = {
{ 0, 0, 0, 0, 1 },
{ 1, 1, 0, 0, 1 }
};
Seq *seq = (Seq *)malloc(2 * sizeof(Seq));
Common::copy(ms, ms + 2, seq);
setSeq(seq);
BitmapPtr *MC = new BitmapPtr[3];
MC[0] = new Bitmap(_vm, "MOUSE");
MC[1] = new Bitmap(_vm, "DUMMY");
MC[2] = NULL;
setShapeList(MC);
gotoxy(kScrWidth / 2, kScrHeight / 2);
_z = 127;
step(1);
}
Mouse::~Mouse() {
off();
}
void Mouse::on() {
if (_seqPtr && _exist) {
_active = true;
step(0);
if (_busy)
_busy->step(0);
}
}
void Mouse::off() {
if (_seqPtr == 0) {
if (_exist) {
_active = false;
}
step(1);
if (_busy)
_busy->step(1);
}
}
void Mouse::newMouse(Common::Event &event) {
if (!_active)
return;
CGEEvent &evt = _vm->_eventManager->getNextEvent();
evt._x = event.mouse.x;
evt._y = event.mouse.y;
evt._spritePtr = _vm->spriteAt(evt._x, evt._y);
switch (event.type) {
case Common::EVENT_MOUSEMOVE:
evt._mask = kMouseRoll;
break;
case Common::EVENT_LBUTTONDOWN:
evt._mask = kMouseLeftDown;
_buttons |= 1;
break;
case Common::EVENT_LBUTTONUP:
evt._mask = kMouseLeftUp;
_buttons &= ~1;
break;
case Common::EVENT_RBUTTONDOWN:
evt._mask = kMouseRightDown;
_buttons |= 2;
break;
case Common::EVENT_RBUTTONUP:
evt._mask = kMouseRightUp;
_buttons &= ~2;
break;
default:
break;
}
}
/*----------------- EventManager interface -----------------*/
EventManager::EventManager(CGEEngine *vm) : _vm(vm){
_eventQueueHead = 0;
_eventQueueTail = 0;
memset(&_eventQueue, 0, kEventMax * sizeof(CGEEvent));
memset(&_event, 0, sizeof(Common::Event));
}
void EventManager::poll() {
while (g_system->getEventManager()->pollEvent(_event)) {
switch (_event.type) {
case Common::EVENT_KEYDOWN:
case Common::EVENT_KEYUP:
// Handle keyboard events
_vm->_keyboard->newKeyboard(_event);
handleEvents();
break;
case Common::EVENT_MOUSEMOVE:
case Common::EVENT_LBUTTONDOWN:
case Common::EVENT_LBUTTONUP:
case Common::EVENT_RBUTTONDOWN:
case Common::EVENT_RBUTTONUP:
// Handle mouse events
_vm->_mouse->newMouse(_event);
handleEvents();
break;
default:
break;
}
}
}
void EventManager::handleEvents() {
while (_eventQueueTail != _eventQueueHead) {
CGEEvent e = _eventQueue[_eventQueueTail];
if (e._mask) {
if (_vm->_mouse->_hold && e._spritePtr != _vm->_mouse->_hold)
_vm->_mouse->_hold->touch(e._mask | kEventAttn, e._x - _vm->_mouse->_hold->_x, e._y - _vm->_mouse->_hold->_y);
// update mouse cursor position
if (e._mask & kMouseRoll)
_vm->_mouse->gotoxy(e._x, e._y);
// activate current touched SPRITE
if (e._spritePtr) {
if (e._mask & kEventKeyb)
e._spritePtr->touch(e._mask, e._x, e._y);
else
e._spritePtr->touch(e._mask, e._x - e._spritePtr->_x, e._y - e._spritePtr->_y);
} else if (_vm->_sys)
_vm->_sys->touch(e._mask, e._x, e._y);
if (e._mask & kMouseLeftDown) {
_vm->_mouse->_hold = e._spritePtr;
if (_vm->_mouse->_hold) {
_vm->_mouse->_hold->_flags._hold = true;
if (_vm->_mouse->_hold->_flags._drag) {
_vm->_mouse->_hx = e._x - _vm->_mouse->_hold->_x;
_vm->_mouse->_hy = e._y - _vm->_mouse->_hold->_y;
}
}
}
if (e._mask & kMouseLeftUp) {
if (_vm->_mouse->_hold) {
_vm->_mouse->_hold->_flags._hold = false;
_vm->_mouse->_hold = NULL;
}
}
///Touched = e.Ptr;
// discard Text if button released
if (e._mask & (kMouseLeftUp | kMouseRightUp))
_vm->killText();
}
_eventQueueTail = (_eventQueueTail + 1) % kEventMax;
}
if (_vm->_mouse->_hold) {
if (_vm->_mouse->_hold->_flags._drag)
_vm->_mouse->_hold->gotoxy(_vm->_mouse->_x - _vm->_mouse->_hx, _vm->_mouse->_y - _vm->_mouse->_hy);
}
}
void EventManager::clearEvent(Sprite *spr) {
if (spr) {
for (uint16 e = _eventQueueTail; e != _eventQueueHead; e = (e + 1) % kEventMax)
if (_eventQueue[e]._spritePtr == spr)
_eventQueue[e]._mask = 0;
} else
_eventQueueTail = _eventQueueHead;
}
CGEEvent &EventManager::getNextEvent() {
CGEEvent &evt = _eventQueue[_eventQueueHead];
_eventQueueHead = (_eventQueueHead + 1) % kEventMax;
return evt;
}
} // End of namespace CGE