ILLUSIONS: Refactor the input system

This commit is contained in:
johndoe123 2014-12-11 14:14:52 +01:00 committed by Eugene Sandulenko
parent a078073e88
commit 36ec0fafdb
21 changed files with 253 additions and 138 deletions

View File

@ -258,7 +258,7 @@ void Control::appearActor() {
_actor->_flags |= 0x2000;
_actor->_flags |= 0x4000;
}
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
}
} else {
if (_objectId == 0x40004) {
@ -500,7 +500,6 @@ void Control::getCollisionRectAccurate(Common::Rect &collisionRect) {
if (_actor) {
if (_actor->_scale != 100) {
// scaledValue = value * scale div 100
collisionRect.left = collisionRect.left * _actor->_scale / 100;
collisionRect.top = collisionRect.top * _actor->_scale / 100;
collisionRect.right = collisionRect.right * _actor->_scale / 100;
@ -520,7 +519,6 @@ void Control::getCollisionRect(Common::Rect &collisionRect) {
collisionRect = Common::Rect(_unkPt.x, _unkPt.y, _pt.x, _pt.y);
if (_actor) {
if (_actor->_scale != 100) {
// scaledValue = value * scale div 100
collisionRect.left = collisionRect.left * _actor->_scale / 100;
collisionRect.top = collisionRect.top * _actor->_scale / 100;
collisionRect.right = collisionRect.right * _actor->_scale / 100;
@ -762,19 +760,12 @@ void Control::startMoveActor(uint32 sequenceId, Common::Point destPt, uint32 cal
_vm->notifyThreadId(_actor->_notifyId3C);
_actor->_notifyId3C = callerThreadId2;
_actor->_pathPointIndex = 0;
if (_vm->getGameId() == kGameIdBBDOU) {
_vm->_input->discardButtons(0x10);
} else if (_vm->getGameId() == kGameIdDuckman) {
_vm->_input->discardButtons(0x20);
}
_vm->_input->discardEvent(kEventSkip);
}
}
PointArray *Control::createPath(Common::Point destPt) {
// TODO Implement actual pathfinding
PointArray *walkPoints = (_actor->_flags & 2) ? _actor->_pathWalkPoints->_points : 0;
PathLines *walkRects = (_actor->_flags & 0x10) ? _actor->_pathWalkRects->_rects : 0;
PathFinder pathFinder;
@ -791,12 +782,12 @@ void Control::updateActorMovement(uint32 deltaTime) {
// TODO Move while loop to caller
static const int16 kAngleTbl[] = {60, 0, 120, 0, 60, 0, 120, 0};
bool again = false;
bool fastWalked = false;
while (1) {
if (!again && _vm->testMainActorFastWalk(this)) {
again = true;
if (!fastWalked && _vm->testMainActorFastWalk(this)) {
fastWalked = true;
disappearActor();
_actor->_flags |= 0x8000;
_actor->_seqCodeIp = 0;
@ -921,12 +912,12 @@ void Control::updateActorMovement(uint32 deltaTime) {
_vm->notifyThreadId(_actor->_notifyId3C);
_actor->_walkCallerThreadId1 = 0;
}
again = false;
fastWalked = false;
}
_actor->_pathFlag50 = false;
}
if (!again)
if (!fastWalked)
break;
}

View File

@ -89,7 +89,7 @@ void BbdouCursor::enable(uint32 objectId) {
_vm->_camera->panEdgeFollow(objectId, 360);
_data._idleCtr = 0;
}
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
}
void BbdouCursor::disable(uint32 objectId) {
@ -354,7 +354,7 @@ void BbdouCursor::hide(uint32 objectId) {
_bbdou->resetItem10(objectId, &_data._item10);
_vm->_camera->popCameraMode();
}
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
}
} // End of namespace Illusions

View File

@ -331,7 +331,7 @@ void BbdouSpecialCode::resetItem10(uint32 objectId, Item10 *item10) {
item10->_objectIds[0] = 0;
item10->_objectIds[1] = 0;
}
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
}
bool BbdouSpecialCode::testValueRange(int value) {
@ -407,7 +407,7 @@ void BbdouSpecialCode::showBubble(uint32 objectId, uint32 overlappedObjectId, ui
control3->deactivateObject();
item10->_playSound48 = 1;
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
}
@ -540,14 +540,14 @@ void BbdouSpecialCode::cursorInteractControlRoutine(Control *cursorControl, uint
}
cursorData._currOverlappedObjectId = 0;
} else if (cursorData._currOverlappedObjectId) {
if (_vm->_input->pollButton(1)) {
if (_vm->_input->pollEvent(kEventLeftClick)) {
cursorData._idleCtr = 0;
if (runCause(cursorControl, cursorData, cursorData._item10._verbId, cursorData._holdingObjectId, cursorData._currOverlappedObjectId, 1)) {
resetItem10(cursorControl->_objectId, &cursorData._item10);
cursorData._currOverlappedObjectId = 0;
cursorControl->setActorIndexTo1();
}
} else if (_vm->_input->pollButton(2)) {
} else if (_vm->_input->pollEvent(kEventRightClick)) {
uint32 verbId;
cursorData._idleCtr = 0;
if (cursorData._holdingObjectId) {
@ -561,10 +561,10 @@ void BbdouSpecialCode::cursorInteractControlRoutine(Control *cursorControl, uint
}
}
} else {
if (_vm->_input->pollButton(1)) {
if (_vm->_input->pollEvent(kEventLeftClick)) {
cursorData._idleCtr = 0;
runCause(cursorControl, cursorData, 0x1B0002, 0, 0x40003, 0);
} else if (_vm->_input->pollButton(4)) {
} else if (_vm->_input->pollEvent(kEventInventory)) {
cursorData._idleCtr = 0;
if (cursorData._item10._field58 <= 1)
runCause(cursorControl, cursorData, cursorData._holdingObjectId != 0 ? 0x1B000B : 0x1B0004, 0, 0x40003, 0);

View File

@ -216,6 +216,8 @@ Common::Error IllusionsEngine_BBDOU::run() {
_updateFunctions = new UpdateFunctions();
_soundMan = new SoundMan(this);
initInput();
initUpdateFunctions();
_fader = 0;
@ -283,6 +285,28 @@ bool IllusionsEngine_BBDOU::hasFeature(EngineFeature f) const {
*/
}
void IllusionsEngine_BBDOU::initInput() {
_input->setInputEvent(kEventLeftClick, 0x01)
.addMouseButton(MOUSE_LEFT_BUTTON)
.addKey(Common::KEYCODE_RETURN);
_input->setInputEvent(kEventRightClick, 0x02)
.addMouseButton(MOUSE_RIGHT_BUTTON);
_input->setInputEvent(kEventInventory, 0x04)
.addMouseButton(MOUSE_RIGHT_BUTTON)
.addKey(Common::KEYCODE_TAB);
_input->setInputEvent(kEventAbort, 0x08)
.addKey(Common::KEYCODE_ESCAPE);
_input->setInputEvent(kEventSkip, 0x10)
.addKey(Common::KEYCODE_SPACE);
_input->setInputEvent(kEventF1, 0x20)
.addKey(Common::KEYCODE_F1);
_input->setInputEvent(kEventUp, 0x40)
.addKey(Common::KEYCODE_UP);
_input->setInputEvent(kEventDown, 0x80)
.addMouseButton(MOUSE_RIGHT_BUTTON)
.addKey(Common::KEYCODE_DOWN);
}
#define UPDATEFUNCTION(priority, tag, callback) \
_updateFunctions->add(priority, tag, new Common::Functor1Mem<uint, int, IllusionsEngine_BBDOU> \
(this, &IllusionsEngine_BBDOU::callback));

View File

@ -98,6 +98,8 @@ public:
uint32 _theThreadId;
uint32 _globalSceneId;
void initInput();
void initUpdateFunctions();
int updateScript(uint flags);

View File

@ -263,7 +263,7 @@ void ScriptOpcodes_BBDOU::opChangeScene(ScriptThread *scriptThread, OpCall &opCa
}
// NOTE Skipped checking for stalled resources
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->_prevSceneId = _vm->getCurrentScene();
_vm->exitScene(opCall._callerThreadId);
_vm->enterScene(sceneId, opCall._callerThreadId);
@ -277,7 +277,7 @@ void ScriptOpcodes_BBDOU::opStartModalScene(ScriptThread *scriptThread, OpCall &
ARG_UINT32(sceneId);
ARG_UINT32(threadId);
// NOTE Skipped checking for stalled resources
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->enterPause(opCall._callerThreadId);
_vm->_talkItems->pauseByTag(_vm->getCurrentScene());
_vm->enterScene(sceneId, opCall._callerThreadId);
@ -288,7 +288,7 @@ void ScriptOpcodes_BBDOU::opStartModalScene(ScriptThread *scriptThread, OpCall &
void ScriptOpcodes_BBDOU::opExitModalScene(ScriptThread *scriptThread, OpCall &opCall) {
// NOTE Skipped checking for stalled resources
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->exitScene(opCall._callerThreadId);
_vm->leavePause(opCall._callerThreadId);
_vm->_talkItems->unpauseByTag(_vm->getCurrentScene());
@ -298,7 +298,7 @@ void ScriptOpcodes_BBDOU::opEnterCloseUpScene(ScriptThread *scriptThread, OpCall
ARG_SKIP(2);
ARG_UINT32(sceneId);
// NOTE Skipped checking for stalled resources
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->enterPause(opCall._callerThreadId);
_vm->enterScene(sceneId, opCall._callerThreadId);
}
@ -768,7 +768,7 @@ void ScriptOpcodes_BBDOU::opChangeSceneAll(ScriptThread *scriptThread, OpCall &o
ARG_UINT32(sceneId);
ARG_UINT32(threadId);
// NOTE Skipped checking for stalled resources
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->_prevSceneId = _vm->getCurrentScene();
_vm->dumpActiveScenes(_vm->_globalSceneId, opCall._callerThreadId);
_vm->enterScene(sceneId, opCall._callerThreadId);

View File

@ -67,7 +67,7 @@ void Cursor::show() {
_control->_actor->_flags |= 0x2000;
_control->_actor->_flags |= 0x4000;
}
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
}
}

View File

@ -156,7 +156,7 @@ void DuckmanDialogSystem::updateDialogState() {
_vm->setCursorActorIndex(6, 1, 0);
}
if (_vm->_input->pollButton(1)) {
if (_vm->_input->pollEvent(kEventLeftClick)) {
if (_vm->_cursor._currOverlappedControl) {
_vm->playSoundEffect(9);
*_vm->_cursor._op113_choiceOfsPtr = _vm->_cursor._currOverlappedControl->_actor->_choiceJumpOffs;

View File

@ -113,6 +113,8 @@ Common::Error IllusionsEngine_Duckman::run() {
_dialogSys = new DuckmanDialogSystem(this);
initInput();
initUpdateFunctions();
_scriptOpcodes = new ScriptOpcodes_Duckman(this);
@ -203,6 +205,29 @@ bool IllusionsEngine_Duckman::hasFeature(EngineFeature f) const {
*/
}
void IllusionsEngine_Duckman::initInput() {
// TODO Check if these are correct...
_input->setInputEvent(kEventLeftClick, 0x01)
.addMouseButton(MOUSE_LEFT_BUTTON)
.addKey(Common::KEYCODE_RETURN);
_input->setInputEvent(kEventRightClick, 0x02)
.addMouseButton(MOUSE_RIGHT_BUTTON)
.addKey(Common::KEYCODE_BACKSPACE);
// 0x04 is unused
_input->setInputEvent(kEventInventory, 0x08)
.addKey(Common::KEYCODE_TAB);
_input->setInputEvent(kEventAbort, 0x10)
.addKey(Common::KEYCODE_ESCAPE);
_input->setInputEvent(kEventSkip, 0x20)
.addMouseButton(MOUSE_LEFT_BUTTON)
.addKey(Common::KEYCODE_SPACE);
_input->setInputEvent(kEventUp, 0x40)
.addKey(Common::KEYCODE_UP);
_input->setInputEvent(kEventDown, 0x80)
.addMouseButton(MOUSE_RIGHT_BUTTON)
.addKey(Common::KEYCODE_DOWN);
}
#define UPDATEFUNCTION(priority, tag, callback) \
_updateFunctions->add(priority, tag, new Common::Functor1Mem<uint, int, IllusionsEngine_Duckman> \
(this, &IllusionsEngine_Duckman::callback));
@ -301,7 +326,7 @@ void IllusionsEngine_Duckman::loadSpecialCode(uint32 resId) {
}
void IllusionsEngine_Duckman::unloadSpecialCode(uint32 resId) {
//TODO?
delete _specialCode;
}
void IllusionsEngine_Duckman::notifyThreadId(uint32 &threadId) {
@ -315,7 +340,7 @@ void IllusionsEngine_Duckman::notifyThreadId(uint32 &threadId) {
bool IllusionsEngine_Duckman::testMainActorFastWalk(Control *control) {
return
control->_objectId == _scriptResource->getMainActorObjectId() &&
_input->pollButton(0x20);
_input->pollEvent(kEventSkip);
}
bool IllusionsEngine_Duckman::testMainActorCollision(Control *control) {
@ -742,7 +767,7 @@ void IllusionsEngine_Duckman::leavePause(uint32 sceneId, uint32 threadId) {
}
void IllusionsEngine_Duckman::dumpActiveScenes(uint32 sceneId, uint32 threadId) {
// TODO
// TODO?
}
void IllusionsEngine_Duckman::dumpCurrSceneFiles(uint32 sceneId, uint32 threadId) {
@ -866,7 +891,7 @@ void IllusionsEngine_Duckman::updateGameState2() {
_cursor._currOverlappedControl = 0;
}
if (_input->pollButton(1)) {
if (_input->pollEvent(kEventLeftClick)) {
if (_cursor._currOverlappedControl) {
runTriggerCause(_cursor._actorIndex, _cursor._objectId, _cursor._currOverlappedControl->_objectId);
} else {
@ -877,7 +902,7 @@ void IllusionsEngine_Duckman::updateGameState2() {
else
runTriggerCause(_cursor._actorIndex, _cursor._objectId, 0x40003);
}
} else if (_input->pollButton(2)) {
} else if (_input->pollEvent(kEventRightClick)) {
if (_cursor._actorIndex != 3 && _cursor._actorIndex != 10 && _cursor._actorIndex != 11 && _cursor._actorIndex != 12 && _cursor._actorIndex != 13) {
int newActorIndex = getCursorActorIndex();
if (newActorIndex != _cursor._actorIndex) {
@ -889,7 +914,7 @@ void IllusionsEngine_Duckman::updateGameState2() {
startCursorSequence();
}
}
} else if (_input->pollButton(8)) {
} else if (_input->pollEvent(kEventInventory)) {
if (_cursor._field14[0] == 1) {
runTriggerCause(1, 0, _scriptResource->getMainActorObjectId());
} else if (_cursor._field14[1] == 1) {

View File

@ -100,6 +100,8 @@ public:
ScreenShaker *_screenShaker;
void initInput();
void initUpdateFunctions();
int updateScript(uint flags);

View File

@ -250,7 +250,7 @@ void ScriptOpcodes_Duckman::opEnterScene18(ScriptThread *scriptThread, OpCall &o
//static uint dsceneId = 0, dthreadId = 0;
//static uint dsceneId = 0x00010008, dthreadId = 0x00020029;//Beginning in Jac
//static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front
static uint dsceneId = 0x0001000A, dthreadId = 0x00020043;//Home front
//static uint dsceneId = 0x0001000E, dthreadId = 0x0002007C;
//static uint dsceneId = 0x00010012, dthreadId = 0x0002009D;//Paramount
//static uint dsceneId = 0x00010020, dthreadId = 0x00020112;//Xmas
@ -261,15 +261,16 @@ void ScriptOpcodes_Duckman::opEnterScene18(ScriptThread *scriptThread, OpCall &o
//static uint dsceneId = 0x00010036, dthreadId = 0x000201B5;
//static uint dsceneId = 0x00010039, dthreadId = 0x00020089;//Map
//static uint dsceneId = 0x0001003D, dthreadId = 0x000201E0;
static uint dsceneId = 0x0001004B, dthreadId = 0x0002029B;
//static uint dsceneId = 0x0001004B, dthreadId = 0x0002029B;
//static uint dsceneId = 0x0001005B, dthreadId = 0x00020341;
//static uint dsceneId = 0x00010010, dthreadId = 0x0002008A;
//static uint dsceneId = 0x10002, dthreadId = 0x20001;//Debug menu, not supported
void ScriptOpcodes_Duckman::opChangeScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(sceneId);
ARG_UINT32(threadId);
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
debug("changeScene(%08X, %08X)", sceneId, threadId);
@ -291,7 +292,7 @@ void ScriptOpcodes_Duckman::opStartModalScene(ScriptThread *scriptThread, OpCall
ARG_SKIP(2);
ARG_UINT32(sceneId);
ARG_UINT32(threadId);
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->enterPause(_vm->getCurrentScene(), opCall._callerThreadId);
_vm->_talkItems->pauseByTag(_vm->getCurrentScene());
_vm->enterScene(sceneId, threadId);
@ -299,7 +300,7 @@ void ScriptOpcodes_Duckman::opStartModalScene(ScriptThread *scriptThread, OpCall
}
void ScriptOpcodes_Duckman::opExitModalScene(ScriptThread *scriptThread, OpCall &opCall) {
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
if (_vm->_scriptResource->_properties.get(0x000E0027)) {
// TODO _vm->startScriptThread2(0x10002, 0x20001, 0);
opCall._result = kTSTerminate;
@ -314,13 +315,13 @@ void ScriptOpcodes_Duckman::opExitModalScene(ScriptThread *scriptThread, OpCall
void ScriptOpcodes_Duckman::opEnterScene24(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(sceneId);
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->enterPause(_vm->getCurrentScene(), opCall._callerThreadId);
_vm->enterScene(sceneId, 0);
}
void ScriptOpcodes_Duckman::opLeaveScene24(ScriptThread *scriptThread, OpCall &opCall) {
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->dumpCurrSceneFiles(_vm->getCurrentScene(), opCall._callerThreadId);
_vm->exitScene();
_vm->leavePause(_vm->getCurrentScene(), opCall._callerThreadId);
@ -797,7 +798,7 @@ void ScriptOpcodes_Duckman::opEnterScene(ScriptThread *scriptThread, OpCall &opC
void ScriptOpcodes_Duckman::opEnterCloseUpScene(ScriptThread *scriptThread, OpCall &opCall) {
ARG_SKIP(2);
ARG_UINT32(sceneId);
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->enterPause(opCall._callerThreadId);
_vm->enterScene(sceneId, opCall._callerThreadId);
}
@ -945,7 +946,7 @@ void ScriptOpcodes_Duckman::opChangeSceneAll(ScriptThread *scriptThread, OpCall
ARG_SKIP(2);
ARG_UINT32(sceneId);
ARG_UINT32(threadId);
_vm->_input->discardButtons(0xFFFF);
_vm->_input->discardAllEvents();
_vm->_prevSceneId = _vm->getCurrentScene();
_vm->dumpActiveScenes(_vm->_globalSceneId, opCall._callerThreadId);
_vm->enterScene(sceneId, opCall._callerThreadId);

View File

@ -24,6 +24,59 @@
namespace Illusions {
// KeyMap
void KeyMap::addKey(Common::KeyCode key) {
add(key, MOUSE_NONE);
}
void KeyMap::addMouseButton(int mouseButton) {
add(Common::KEYCODE_INVALID, mouseButton);
}
void KeyMap::add(Common::KeyCode key, int mouseButton) {
KeyMapping keyMapping;
keyMapping._key = key;
keyMapping._mouseButton = mouseButton;
keyMapping._down = false;
push_back(keyMapping);
}
// InputEvent
InputEvent& InputEvent::setBitMask(uint bitMask) {
_bitMask = bitMask;
return *this;
}
InputEvent& InputEvent::addKey(Common::KeyCode key) {
_keyMap.addKey(key);
return *this;
}
InputEvent& InputEvent::addMouseButton(int mouseButton) {
_keyMap.addMouseButton(mouseButton);
return *this;
}
byte InputEvent::handle(Common::KeyCode key, int mouseButton, bool down) {
byte newKeys = 0;
for (KeyMap::iterator it = _keyMap.begin(); it != _keyMap.end(); ++it) {
KeyMapping &keyMapping = *it;
if ((keyMapping._key != Common::KEYCODE_INVALID && keyMapping._key == key) ||
(keyMapping._mouseButton != MOUSE_NONE && keyMapping._mouseButton == mouseButton)) {
if (down && !keyMapping._down) {
newKeys |= _bitMask;
keyMapping._down = true;
} else if (!down)
keyMapping._down = false;
}
}
return newKeys;
}
// Input
Input::Input() {
_buttonStates = 0;
_newButtons = 0;
@ -34,7 +87,6 @@ Input::Input() {
_cursorPos.y = 0;
_prevCursorPos.x = 0;
_prevCursorPos.y = 0;
initKeys();
}
void Input::processEvent(Common::Event event) {
@ -51,53 +103,41 @@ void Input::processEvent(Common::Event event) {
_cursorPos.y = event.mouse.y;
break;
case Common::EVENT_LBUTTONDOWN:
handleMouseButton(MOUSE_BUTTON0, true);
handleMouseButton(MOUSE_LEFT_BUTTON, true);
break;
case Common::EVENT_LBUTTONUP:
handleMouseButton(MOUSE_BUTTON0, false);
handleMouseButton(MOUSE_LEFT_BUTTON, false);
break;
case Common::EVENT_RBUTTONDOWN:
handleMouseButton(MOUSE_BUTTON1, true);
handleMouseButton(MOUSE_RIGHT_BUTTON, true);
break;
case Common::EVENT_RBUTTONUP:
handleMouseButton(MOUSE_BUTTON1, false);
handleMouseButton(MOUSE_RIGHT_BUTTON, false);
break;
default:
break;
}
}
bool Input::pollButton(uint buttons) {
if (lookButtonStates(buttons)) {
_buttonStates &= ~buttons;
return true;
}
return false;
bool Input::pollEvent(uint evt) {
return pollButton(_inputEvents[evt].getBitMask());
}
bool Input::lookButtonStates(uint buttons) {
return (buttons & (_buttonStates & _enabledButtons)) != 0;
void Input::discardEvent(uint evt) {
discardButtons(_inputEvents[evt].getBitMask());
}
bool Input::lookNewButtons(uint buttons) {
return (buttons & (_newButtons & _enabledButtons)) != 0;
void Input::discardAllEvents() {
discardButtons(0xFFFF);
}
void Input::setButtonState(uint buttons) {
_buttonStates |= _enabledButtons & buttons;
void Input::activateButton(uint bitMask) {
_enabledButtons |= bitMask;
_buttonStates &= ~bitMask;
}
void Input::discardButtons(uint buttons) {
_buttonStates &= ~buttons;
}
void Input::activateButton(uint buttons) {
_enabledButtons |= buttons;
_buttonStates &= ~buttons;
}
void Input::deactivateButton(uint buttons) {
_enabledButtons &= ~buttons;
void Input::deactivateButton(uint bitMask) {
_enabledButtons &= ~bitMask;
}
Common::Point Input::getCursorPosition() {
@ -116,43 +156,14 @@ Common::Point Input::getCursorDelta() {
return deltaPos;
}
void Input::initKeys() {
// NOTE Skipped debugging keys of the original engine, not sure if used
// TODO Move this to the engine class and tidy up methods (one for mouse buttons, one for keys)
addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON0, 0x01);
addKeyMapping(Common::KEYCODE_RETURN, MOUSE_NONE, 0x01);
addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x02);
addKeyMapping(Common::KEYCODE_TAB, MOUSE_NONE, 0x04);
addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x04);
addKeyMapping(Common::KEYCODE_ESCAPE, MOUSE_NONE, 0x08);
addKeyMapping(Common::KEYCODE_SPACE, MOUSE_NONE, 0x10);
addKeyMapping(Common::KEYCODE_F1, MOUSE_NONE, 0x20);
addKeyMapping(Common::KEYCODE_UP, MOUSE_NONE, 0x40);
addKeyMapping(Common::KEYCODE_DOWN, MOUSE_NONE, 0x80);
addKeyMapping(Common::KEYCODE_INVALID, MOUSE_BUTTON1, 0x80);
}
void Input::addKeyMapping(Common::KeyCode key, int mouseButton, uint bitMask) {
KeyMapping keyMapping;
keyMapping._key = key;
keyMapping._mouseButton = mouseButton;
keyMapping._bitMask = bitMask;
keyMapping._down = false;
_keyMap.push_back(keyMapping);
InputEvent& Input::setInputEvent(uint evt, uint bitMask) {
InputEvent& inputEvent = _inputEvents[evt];
return inputEvent.setBitMask(bitMask);
}
void Input::handleKey(Common::KeyCode key, int mouseButton, bool down) {
for (KeyMap::iterator it = _keyMap.begin(); it != _keyMap.end(); ++it) {
KeyMapping &keyMapping = *it;
if ((keyMapping._key != Common::KEYCODE_INVALID && keyMapping._key == key) ||
(keyMapping._mouseButton != MOUSE_NONE && keyMapping._mouseButton == mouseButton)) {
if (down && !keyMapping._down) {
_newKeys |= keyMapping._bitMask;
keyMapping._down = true;
} else if (!down)
keyMapping._down = false;
}
}
for (uint i = 0; i < kEventMax; ++i)
_newKeys |= _inputEvents[i].handle(key, mouseButton, down);
uint prevButtonStates = _buttonStates;
_buttonStates |= _newKeys;
_newKeys = 0;
@ -167,4 +178,28 @@ void Input::handleMouseButton(int mouseButton, bool down) {
handleKey(Common::KEYCODE_INVALID, mouseButton, down);
}
bool Input::pollButton(uint bitMask) {
if (lookButtonStates(bitMask)) {
_buttonStates &= ~bitMask;
return true;
}
return false;
}
bool Input::lookButtonStates(uint bitMask) {
return (bitMask & (_buttonStates & _enabledButtons)) != 0;
}
bool Input::lookNewButtons(uint bitMask) {
return (bitMask & (_newButtons & _enabledButtons)) != 0;
}
void Input::setButtonState(uint bitMask) {
_buttonStates |= _enabledButtons & bitMask;
}
void Input::discardButtons(uint bitMask) {
_buttonStates &= ~bitMask;
}
} // End of namespace Illusions

View File

@ -31,43 +31,75 @@
namespace Illusions {
enum {
MOUSE_NONE = 0,
MOUSE_BUTTON0 = 1,
MOUSE_BUTTON1 = 2
MOUSE_NONE = 0,
MOUSE_LEFT_BUTTON = 1,
MOUSE_RIGHT_BUTTON = 2
};
enum {
kEventLeftClick = 0,
kEventRightClick = 1,
kEventInventory = 2,
kEventAbort = 3,
kEventSkip = 4,
kEventF1 = 5,
kEventUp = 6,
kEventDown = 7,
kEventMax
};
struct KeyMapping {
Common::KeyCode _key;
int _mouseButton;
uint _bitMask;
bool _down;
};
class KeyMap : public Common::Array<KeyMapping> {
public:
void addKey(Common::KeyCode key);
void addMouseButton(int mouseButton);
protected:
void add(Common::KeyCode key, int mouseButton);
};
class InputEvent {
public:
InputEvent& setBitMask(uint bitMask);
InputEvent& addKey(Common::KeyCode key);
InputEvent& addMouseButton(int mouseButton);
byte handle(Common::KeyCode key, int mouseButton, bool down);
uint getBitMask() const { return _bitMask; }
protected:
uint _bitMask;
KeyMap _keyMap;
};
class Input {
public:
Input();
void processEvent(Common::Event event);
bool pollButton(uint buttons);
bool lookButtonStates(uint buttons);
bool lookNewButtons(uint buttons);
void setButtonState(uint buttons);
void discardButtons(uint buttons);
void activateButton(uint buttons);
void deactivateButton(uint buttons);
bool pollEvent(uint evt);
void discardEvent(uint evt);
void discardAllEvents();
void activateButton(uint bitMask);
void deactivateButton(uint bitMask);
Common::Point getCursorPosition();
void setCursorPosition(Common::Point mousePos);
Common::Point getCursorDelta();
InputEvent& setInputEvent(uint evt, uint bitMask);
protected:
typedef Common::Array<KeyMapping> KeyMap;
uint _buttonStates, _newButtons, _buttonsDown;
uint _enabledButtons;
uint _newKeys;
Common::Point _cursorPos, _prevCursorPos;
KeyMap _keyMap;
void initKeys();
void addKeyMapping(Common::KeyCode key, int mouseButton, uint bitMask);
InputEvent _inputEvents[kEventMax];
void handleKey(Common::KeyCode key, int mouseButton, bool down);
void handleMouseButton(int mouseButton, bool down);
bool pollButton(uint bitMask);
void discardButtons(uint bitMask);
bool lookButtonStates(uint bitMask);
bool lookNewButtons(uint bitMask);
void setButtonState(uint bitMask);
};
} // End of namespace Illusions

View File

@ -85,7 +85,7 @@ void SoundGroupResource::load(byte *data, uint32 dataSize) {
// SoundGroupInstance
SoundGroupInstance::SoundGroupInstance(IllusionsEngine *vm)
: _vm(vm) {
: _vm(vm), _soundGroupResource(0) {
}
void SoundGroupInstance::load(Resource *resource) {
@ -100,6 +100,7 @@ void SoundGroupInstance::load(Resource *resource) {
void SoundGroupInstance::unload() {
_vm->_soundMan->unloadSounds(_resId);
delete _soundGroupResource;
}
} // End of namespace Illusions

View File

@ -782,7 +782,8 @@ static uint16 average(const uint16 a, const uint16 b) {
byte r1, g1, b1, r2, g2, b2;
g_system->getScreenFormat().colorToRGB(a, r1, g1, b1);
g_system->getScreenFormat().colorToRGB(b, r2, g2, b2);
return g_system->getScreenFormat().RGBToColor((r1 + r1 + r2) / 3, (g1 + g1 + g2) / 3, (b1 + b1 + b2) / 3);
// return g_system->getScreenFormat().RGBToColor((r1 + r1 + r2) / 3, (g1 + g1 + g2) / 3, (b1 + b1 + b2) / 3);
return g_system->getScreenFormat().RGBToColor((r1 + r2) / 2, (g1 + g2) / 2, (b1 + b2) / 2);
}
void Screen::drawSurface21(Common::Rect &dstRect, Graphics::Surface *surface, Common::Rect &srcRect) {

View File

@ -147,6 +147,7 @@ void Sound::load() {
}
void Sound::unload() {
debug("Sound::unload() %08X", _soundEffectId);
stop();
delete _stream;
_stream = 0;

View File

@ -35,13 +35,13 @@ AbortableThread::AbortableThread(IllusionsEngine *vm, uint32 threadId, uint32 ca
_scriptCodeIp(scriptCodeIp), _status(1) {
_type = kTTAbortableThread;
_tag = _vm->getCurrentScene();
_vm->_input->discardButtons(8);
_vm->_input->discardEvent(kEventAbort);
}
int AbortableThread::onUpdate() {
if (_status != 1 || _pauseCtr < 0)
return kTSTerminate;
if (_vm->_input->pollButton(8)) {
if (_vm->_input->pollEvent(kEventAbort)) {
_vm->_threads->killThread(_scriptThreadId);
++_pauseCtr;
_vm->startTempScriptThread(_scriptCodeIp, _threadId, 0, 0, 0);

View File

@ -41,14 +41,14 @@ int CauseThread_Duckman::onUpdate() {
if (_vm->getCurrentScene() == _tag) {
Control *cursorCursor = _vm->getObjectControl(0x40004);
cursorCursor->appearActor();
_vm->_input->discardButtons(1);
_vm->_input->discardEvent(kEventLeftClick);
}
return kTSTerminate;
} else {
_tag = _vm->getCurrentScene();
Control *cursorCursor = _vm->getObjectControl(0x40004);
cursorCursor->disappearActor();
_vm->_input->discardButtons(1);
_vm->_input->discardEvent(kEventLeftClick);
_vm->startScriptThread(_triggerThreadId, _threadId);
_flag = true;
return kTSSuspend;

View File

@ -151,7 +151,7 @@ int TalkThread::onUpdate() {
}
_vm->_soundMan->startVoice(255, panX);
}
_vm->_input->discardButtons(0x10);
_vm->_input->discardEvent(kEventSkip);
_status = 6;
return kTSYield;
@ -162,7 +162,7 @@ int TalkThread::onUpdate() {
// TODO _vm->removeText();
if (_entryText && *_entryText) {
refreshText();
_vm->_input->discardButtons(0x10);
_vm->_input->discardEvent(kEventSkip);
} else {
_flags |= 8;
}
@ -178,7 +178,7 @@ int TalkThread::onUpdate() {
}
_flags |= 2;
}
if (_objectId && _vm->_input->pollButton(0x10)) {
if (_objectId && _vm->_input->pollEvent(kEventSkip)) {
if (!(_flags & 8)) {
// TODO _vm->removeText();
if (_entryText && *_entryText)
@ -205,7 +205,7 @@ int TalkThread::onUpdate() {
}
}
if ((_flags & 8) && (_flags & 2) && (_flags & 4)) {
_vm->_input->discardButtons(0x10);
_vm->_input->discardEvent(kEventSkip);
_status = 7;
return kTSTerminate;
}

View File

@ -133,7 +133,7 @@ int TalkThread_Duckman::onUpdate() {
}
_vm->_soundMan->startVoice(255, panX);
}
_vm->_input->discardButtons(0x20);
_vm->_input->discardEvent(kEventSkip);
_status = 5;
return kTSYield;
@ -144,7 +144,7 @@ int TalkThread_Duckman::onUpdate() {
_vm->_screenText->removeText();
if (_entryText && *_entryText) {
refreshText();
_vm->_input->discardButtons(0x20);
_vm->_input->discardEvent(kEventSkip);
} else {
_flags |= 8;
}
@ -157,7 +157,7 @@ int TalkThread_Duckman::onUpdate() {
_flags |= 2;
}
}
if (_objectId && _vm->_input->pollButton(0x20)) {
if (_objectId && _vm->_input->pollEvent(kEventSkip)) {
if (!(_flags & 8)) {
_vm->_screenText->removeText();
if (_entryText && *_entryText)
@ -179,7 +179,7 @@ int TalkThread_Duckman::onUpdate() {
}
}
if ((_flags & 8) && (_flags & 2) && (_flags & 4)) {
_vm->_input->discardButtons(0x20);
_vm->_input->discardEvent(kEventSkip);
return kTSTerminate;
}
return kTSYield;

View File

@ -46,7 +46,7 @@ TimerThread::TimerThread(IllusionsEngine *vm, uint32 threadId, uint32 callingThr
int TimerThread::onUpdate() {
if (isTimerExpired(_startTime, _endTime) ||
(_isAbortable && _vm->_input->pollButton(8)))
(_isAbortable && _vm->_input->pollEvent(kEventAbort)))
return kTSTerminate;
return kTSYield;
}