Skip to content

Commit

Permalink
GOB: Implement Util::getKeyState() for Little Red
Browse files Browse the repository at this point in the history
This makes the bees level playable, removing the "lock-up".
Collision detection between Little Red and the bees and butterflies
doesn't work yet though, so they're just flying through her.

Nevertheless, the game seems to be completable now.
  • Loading branch information
DrMcCoy committed Jun 15, 2012
1 parent c668431 commit 7632246
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 15 deletions.
12 changes: 12 additions & 0 deletions engines/gob/inter.cpp
Expand Up @@ -52,6 +52,7 @@ Inter::Inter(GobEngine *vm) : _vm(vm), _varStack(600) {
_soundEndTimeKey = 0;
_soundStopVal = 0;

_lastBusyWait = 0;
_noBusyWait = false;

_variables = 0;
Expand Down Expand Up @@ -452,4 +453,15 @@ uint32 Inter::readValue(uint16 index, uint16 type) {
return 0;
}

void Inter::handleBusyWait() {
uint32 now = _vm->_util->getTimeKey();

if (!_noBusyWait)
if ((now - _lastBusyWait) <= 20)
_vm->_util->longDelay(1);

_lastBusyWait = now;
_noBusyWait = false;
}

} // End of namespace Gob
9 changes: 7 additions & 2 deletions engines/gob/inter.h
Expand Up @@ -142,8 +142,9 @@ class Inter {

VariableStack _varStack;

// The busy-wait detection in o1_keyFunc breaks fast scrolling in Ween
bool _noBusyWait;
// Busy-wait detection
bool _noBusyWait;
uint32 _lastBusyWait;

GobEngine *_vm;

Expand Down Expand Up @@ -172,6 +173,8 @@ class Inter {
void storeString(const char *value);

uint32 readValue(uint16 index, uint16 type);

void handleBusyWait();
};

class Inter_v1 : public Inter {
Expand Down Expand Up @@ -522,6 +525,8 @@ class Inter_LittleRed : public Inter_v2 {
virtual void setupOpcodesDraw();
virtual void setupOpcodesFunc();
virtual void setupOpcodesGob();

void oLittleRed_keyFunc(OpFuncParams &params);
};

class Inter_v3 : public Inter_v2 {
Expand Down
58 changes: 58 additions & 0 deletions engines/gob/inter_littlered.cpp
Expand Up @@ -22,6 +22,13 @@

#include "gob/gob.h"
#include "gob/inter.h"
#include "gob/global.h"
#include "gob/util.h"
#include "gob/draw.h"
#include "gob/game.h"
#include "gob/script.h"
#include "gob/hotspots.h"
#include "gob/sound/sound.h"

namespace Gob {

Expand All @@ -39,11 +46,62 @@ void Inter_LittleRed::setupOpcodesDraw() {

void Inter_LittleRed::setupOpcodesFunc() {
Inter_v2::setupOpcodesFunc();

OPCODEFUNC(0x14, oLittleRed_keyFunc);
}

void Inter_LittleRed::setupOpcodesGob() {
OPCODEGOB(500, o2_playProtracker);
OPCODEGOB(501, o2_stopProtracker);
}

void Inter_LittleRed::oLittleRed_keyFunc(OpFuncParams &params) {
animPalette();
_vm->_draw->blitInvalidated();

handleBusyWait();

int16 cmd = _vm->_game->_script->readInt16();
int16 key;
uint32 keyState;

switch (cmd) {
case -1:
break;

case 0:
_vm->_draw->_showCursor &= ~2;
_vm->_util->longDelay(1);
key = _vm->_game->_hotspots->check(0, 0);
storeKey(key);

_vm->_util->clearKeyBuf();
break;

case 1:
_vm->_util->forceMouseUp(true);
key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX,
&_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons, 0);
storeKey(key);
break;

case 2:
_vm->_util->processInput(true);
keyState = _vm->_util->getKeyState();

WRITE_VAR(0, keyState);
_vm->_util->clearKeyBuf();
break;

default:
_vm->_sound->speakerOnUpdate(cmd);
if (cmd < 20) {
_vm->_util->delay(cmd);
_noBusyWait = true;
} else
_vm->_util->longDelay(cmd);
break;
}
}

} // End of namespace Gob
16 changes: 4 additions & 12 deletions engines/gob/inter_v1.cpp
Expand Up @@ -1189,26 +1189,15 @@ void Inter_v1::o1_palLoad(OpFuncParams &params) {
}

void Inter_v1::o1_keyFunc(OpFuncParams &params) {
static uint32 lastCalled = 0;
int16 cmd;
int16 key;
uint32 now;

if (!_vm->_vidPlayer->isPlayingLive()) {
_vm->_draw->forceBlit();
_vm->_video->retrace();
}

cmd = _vm->_game->_script->readInt16();
animPalette();
_vm->_draw->blitInvalidated();

now = _vm->_util->getTimeKey();
if (!_noBusyWait)
if ((now - lastCalled) <= 20)
_vm->_util->longDelay(1);
lastCalled = now;
_noBusyWait = false;
handleBusyWait();

// WORKAROUND for bug #1726130: Ween busy-waits in the intro for a counter
// to become 5000. We deliberately slow down busy-waiting, so we shorten
Expand All @@ -1217,6 +1206,9 @@ void Inter_v1::o1_keyFunc(OpFuncParams &params) {
(_vm->_game->_script->pos() == 729) && _vm->isCurrentTot("intro5.tot"))
WRITE_VAR(59, 4000);

int16 cmd = _vm->_game->_script->readInt16();
int16 key;

switch (cmd) {
case -1:
break;
Expand Down
40 changes: 39 additions & 1 deletion engines/gob/util.cpp
Expand Up @@ -21,7 +21,6 @@
*/

#include "common/stream.h"
#include "common/events.h"

#include "graphics/palette.h"

Expand All @@ -45,6 +44,8 @@ Util::Util(GobEngine *vm) : _vm(vm) {
_frameRate = 12;
_frameWaitTime = 0;
_startFrameTime = 0;

_keyState = 0;
}

uint32 Util::getTimeKey() {
Expand Down Expand Up @@ -116,6 +117,8 @@ void Util::processInput(bool scroll) {
_mouseButtons = (MouseButtons) (((uint32) _mouseButtons) & ~((uint32) kMouseButtonsRight));
break;
case Common::EVENT_KEYDOWN:
keyDown(event);

if (event.kbd.hasFlags(Common::KBD_CTRL)) {
if (event.kbd.keycode == Common::KEYCODE_f)
_fastMode ^= 1;
Expand All @@ -132,6 +135,7 @@ void Util::processInput(bool scroll) {
addKeyToBuffer(event.kbd);
break;
case Common::EVENT_KEYUP:
keyUp(event);
break;
default:
break;
Expand Down Expand Up @@ -576,4 +580,38 @@ void Util::checkJoystick() {
_vm->_global->_useJoystick = 0;
}

uint32 Util::getKeyState() const {
return _keyState;
}

void Util::keyDown(const Common::Event &event) {
if (event.kbd.keycode == Common::KEYCODE_UP)
_keyState |= 0x0001;
else if (event.kbd.keycode == Common::KEYCODE_DOWN)
_keyState |= 0x0002;
else if (event.kbd.keycode == Common::KEYCODE_RIGHT)
_keyState |= 0x0004;
else if (event.kbd.keycode == Common::KEYCODE_LEFT)
_keyState |= 0x0008;
else if (event.kbd.keycode == Common::KEYCODE_SPACE)
_keyState |= 0x0020;
else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
_keyState |= 0x0040;
}

void Util::keyUp(const Common::Event &event) {
if (event.kbd.keycode == Common::KEYCODE_UP)
_keyState &= ~0x0001;
else if (event.kbd.keycode == Common::KEYCODE_DOWN)
_keyState &= ~0x0002;
else if (event.kbd.keycode == Common::KEYCODE_RIGHT)
_keyState &= ~0x0004;
else if (event.kbd.keycode == Common::KEYCODE_LEFT)
_keyState &= ~0x0008;
else if (event.kbd.keycode == Common::KEYCODE_SPACE)
_keyState &= ~0x0020;
else if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
_keyState &= ~0x0040;
}

} // End of namespace Gob
8 changes: 8 additions & 0 deletions engines/gob/util.h
Expand Up @@ -25,6 +25,7 @@

#include "common/str.h"
#include "common/keyboard.h"
#include "common/events.h"

namespace Common {
class SeekableReadStream;
Expand Down Expand Up @@ -110,6 +111,8 @@ class Util {
bool checkKey(int16 &key);
bool keyPressed();

uint32 getKeyState() const;

void getMouseState(int16 *pX, int16 *pY, MouseButtons *pButtons);
void setMousePos(int16 x, int16 y);
void waitMouseUp();
Expand Down Expand Up @@ -155,13 +158,18 @@ class Util {
int16 _frameWaitTime;
uint32 _startFrameTime;

uint32 _keyState;

GobEngine *_vm;

bool keyBufferEmpty();
void addKeyToBuffer(const Common::KeyState &key);
bool getKeyFromBuffer(Common::KeyState &key);
int16 translateKey(const Common::KeyState &key);
void checkJoystick();

void keyDown(const Common::Event &event);
void keyUp(const Common::Event &event);
};

} // End of namespace Gob
Expand Down

0 comments on commit 7632246

Please sign in to comment.