SCI: implement kGetEvent modifiers DOS bug
Will fix darts minigame in the fan game "Betrayed Alliance" This bug in the original interpreter/keyboard driver seems to have been fixed in SCI32.
This commit is contained in:
parent
35e526d34b
commit
f9459656f5
1 changed files with 24 additions and 3 deletions
|
@ -42,6 +42,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
|
|||
reg_t obj = argv[1];
|
||||
SciEvent curEvent;
|
||||
int modifier_mask = getSciVersion() <= SCI_VERSION_01 ? SCI_KEYMOD_ALL : SCI_KEYMOD_NO_FOOLOCK;
|
||||
uint16 modifiers = 0;
|
||||
SegManager *segMan = s->_segMan;
|
||||
Common::Point mousePos;
|
||||
|
||||
|
@ -110,6 +111,25 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
|
|||
writeSelectorValue(segMan, obj, SELECTOR(x), mousePos.x);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(y), mousePos.y);
|
||||
|
||||
// Get current keyboard modifiers, only keep relevant bits
|
||||
modifiers = curEvent.modifiers & modifier_mask;
|
||||
if (g_sci->getPlatform() == Common::kPlatformDOS) {
|
||||
// We are supposed to emulate SCI running in DOS
|
||||
|
||||
// We set the higher byte of the modifiers to 02h
|
||||
// Original SCI also did that indirectly, because it asked BIOS for shift status
|
||||
// via AH=0x02 INT16, which then sets the shift flags in AL
|
||||
// AH is supposed to be destroyed in that case and it's not defined that 0x02
|
||||
// is still in it on return. The value of AX was then set into the modifiers selector.
|
||||
// At least one fan-made game (Betrayed Alliance) requires 0x02 to be in the upper byte,
|
||||
// otherwise the darts game (script 111) will not work properly.
|
||||
|
||||
// It seems Sierra fixed this behaviour (effectively bug) in SCI32
|
||||
if (getSciVersion() <= SCI_VERSION_1_1) {
|
||||
modifiers |= 0x0200;
|
||||
}
|
||||
}
|
||||
|
||||
//s->_gui->moveCursor(s->gfx_state->pointer_pos.x, s->gfx_state->pointer_pos.y);
|
||||
|
||||
switch (curEvent.type) {
|
||||
|
@ -125,7 +145,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
|
|||
|
||||
writeSelectorValue(segMan, obj, SELECTOR(message), curEvent.character);
|
||||
// We only care about the translated character
|
||||
writeSelectorValue(segMan, obj, SELECTOR(modifiers), curEvent.modifiers & modifier_mask);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(modifiers), modifiers);
|
||||
break;
|
||||
|
||||
case SCI_EVENT_MOUSE_RELEASE:
|
||||
|
@ -149,10 +169,11 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
modifiers |= extra_bits; // add these additional bits to the mix
|
||||
|
||||
writeSelectorValue(segMan, obj, SELECTOR(type), curEvent.type);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(message), 0);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(modifiers), (curEvent.modifiers | extra_bits) & modifier_mask);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(modifiers), modifiers);
|
||||
s->r_acc = make_reg(0, 1);
|
||||
}
|
||||
break;
|
||||
|
@ -161,7 +182,7 @@ reg_t kGetEvent(EngineState *s, int argc, reg_t *argv) {
|
|||
// Return a null event
|
||||
writeSelectorValue(segMan, obj, SELECTOR(type), SCI_EVENT_NONE);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(message), 0);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(modifiers), curEvent.modifiers & modifier_mask);
|
||||
writeSelectorValue(segMan, obj, SELECTOR(modifiers), modifiers);
|
||||
s->r_acc = NULL_REG;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue