Correct implementation for set.key opcode. Fixes #2605104: "AGI: Manhunter, F3 hotkey dosent work", removed number of hacks

svn-id: r41259
This commit is contained in:
Eugene Sandulenko 2009-06-06 17:48:09 +00:00
parent d6a4dbeb1d
commit ea3373708c
8 changed files with 29 additions and 30 deletions

View File

@ -489,6 +489,11 @@ int AgiEngine::agiInit() {
_game.mouseFence.setWidth(0); // Reset
_game.lastController = 0;
for (i = 0; i < MAX_DIRS; i++)
_game.controllerOccured[i] = false;
return ec;
}

View File

@ -63,6 +63,7 @@ typedef signed int Err;
#define MAX_WORDS 20
#define MAX_STRINGS 24 // MAX_STRINGS + 1 used for get.num
#define MAX_STRINGLEN 40
#define MAX_CONTROLLERS 39
#define _EMPTY 0xfffff
#define EGO_OWNED 0xff
@ -334,9 +335,9 @@ enum AgiSlowliness {
kPausePicture = 500
};
struct AgiEvent {
uint16 data;
uint8 occured;
struct AgiController {
uint16 keycode;
uint8 controller;
};
struct AgiObject {
@ -573,7 +574,10 @@ struct AgiGame {
unsigned int numObjects;
AgiEvent evKeyp[MAX_DIRS]; /**< keyboard keypress events */
bool controllerOccured[MAX_DIRS]; /**< keyboard keypress events */
AgiController controllers[MAX_CONTROLLERS];
int lastController;
char strings[MAX_STRINGS + 1][MAX_STRINGLEN]; /**< strings */
// directory entries for resources

View File

@ -100,7 +100,7 @@ void AgiEngine::resetControllers() {
int i;
for (i = 0; i < MAX_DIRS; i++) {
_game.evKeyp[i].occured = false;
_game.controllerOccured[i] = false;
}
}
@ -371,9 +371,6 @@ int AgiEngine::playGame() {
int AgiEngine::runGame() {
int i, ec = errOK;
for (i = 0; i < MAX_DIRS; i++)
memset(&_game.evKeyp[i], 0, sizeof(struct AgiEvent));
// Execute the game
do {
debugC(2, kDebugLevelMain, "game loop");

View File

@ -120,11 +120,11 @@ int AgiEngine::handleController(int key) {
debugC(3, kDebugLevelInput, "key = %04x", key);
for (i = 0; i < MAX_DIRS; i++) {
if (_game.evKeyp[i].data == key) {
debugC(3, kDebugLevelInput, "event %d: key press", i);
_game.evKeyp[i].occured = true;
report("event AC:%i occured\n", i);
for (i = 0; i < _game.lastController; i++) {
if (_game.controllers[i].keycode == key) {
debugC(3, kDebugLevelInput, "event %d: key press", _game.controllers[i].controller);
_game.controllerOccured[_game.controllers[i].controller] = true;
report("event AC:%i occured\n", _game.controllers[i].controller);
return true;
}
}

View File

@ -375,15 +375,7 @@ bool Menu::keyhandler(int key) {
// activate that option
if (d->enabled) {
debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event);
_vm->_game.evKeyp[d->event].occured = true;
_vm->_game.evKeyp[d->event].data = d->event;
// In LSL1, event 0x20 is set when changing the game speed to normal via the menu
// Do not set the event data to 0x20, as this event is then incorrectly triggered
// when the spacebar is pressed, which has a keycode equal to 0x20 as well
// Fixes bug #1751390 - "LSL: after changing game speed, space key turn unfunctional"
if (d->event == 0x20)
_vm->_game.evKeyp[d->event].data = d->event + 1;
_vm->_game.controllerOccured[d->event] = true;
_vm->_menuSelected = true;
goto exit_menu;
@ -415,7 +407,7 @@ bool Menu::keyhandler(int key) {
if (d->enabled) {
debugC(6, kDebugLevelMenu | kDebugLevelInput, "event %d registered", d->event);
_vm->_game.evKeyp[d->event].occured = true;
_vm->_game.controllerOccured[d->event] = true;
goto exit_menu;
}
break;

View File

@ -1408,12 +1408,13 @@ cmd(set_key) {
debugC(4, kDebugLevelScripts, "%d %d %d", p0, p1, p2);
if (game.evKeyp[p2].data != 0) // TBC sets c23 (ESC) twice!
return;
key = 256 * p1 + p0;
game.evKeyp[p2].data = key;
game.evKeyp[p2].occured = false;
game.controllers[game.lastController].keycode = key;
game.controllers[game.lastController].controller = p2;
game.lastController++;
game.controllerOccured[p2] = false;
}
cmd(set_string) {

View File

@ -126,7 +126,7 @@ static uint8 testKeypressed() {
}
static uint8 testController(uint8 cont) {
return game.evKeyp[cont].occured;
return (game.controllerOccured[cont] ? 1 : 0);
}
static uint8 testPosn(uint8 n, uint8 x1, uint8 y1, uint8 x2, uint8 y2) {

View File

@ -382,7 +382,7 @@ int AgiEngine::loadGame(const char *fileName, bool checkId) {
// Those are not serialized
for (i = 0; i < MAX_DIRS; i++) {
_game.evKeyp[i].occured = false;
_game.controllerOccured[i] = false;
}
for (i = 0; i < MAX_STRINGS; i++)