LOL: - implemented proper button processing (works exactly as in Kyra 2 and 3, so we do have some code duplication atm, I just fixed right mouse button support for LOL)

- keyboard control now works

svn-id: r38190
This commit is contained in:
Florian Kagerer 2009-02-15 03:36:30 +00:00
parent 36767120e1
commit 16a57f299c
14 changed files with 414 additions and 105 deletions

Binary file not shown.

View File

@ -114,8 +114,8 @@ void GUI::initMenu(Menu &menu) {
menuButtonData->width = menu.item[i].width - 1;
menuButtonData->height = menu.item[i].height - 1;
menuButtonData->buttonCallback = menu.item[i].callback;
menuButtonData->unk6 = menu.item[i].unk1F;
menuButtonData->unk8 = 0;
menuButtonData->keyCode = menu.item[i].unk1F;
menuButtonData->keyCode2 = 0;
_menuButtonList = addButtonToList(_menuButtonList, menuButtonData);
}

View File

@ -46,8 +46,8 @@ struct Button {
Button *nextButton;
uint16 index;
uint16 unk6;
uint16 unk8;
uint16 keyCode;
uint16 keyCode2;
byte data0Val1;
byte data1Val1;

View File

@ -34,7 +34,7 @@ namespace Kyra {
do { \
button.nextButton = 0; \
button.index = a; \
button.unk6 = button.unk8 = 0; \
button.keyCode = button.keyCode2 = 0; \
button.data0Val1 = b; \
button.data1Val1 = c; \
button.data2Val1 = d; \

View File

@ -613,8 +613,8 @@ void LoLEngine::gui_initButton(int index, int x) {
b->data2Val3 = 0x01;
b->index = cnt;
b->unk6 = _buttonData[index].clickedShapeId;
b->unk8 = _buttonData[index].unk2;
b->keyCode = _buttonData[index].keyCode;
b->keyCode2 = _buttonData[index].keyCode2;
b->dimTableIndex = _buttonData[index].screenDim;
b->flags = _buttonData[index].buttonflags;
@ -722,6 +722,18 @@ int LoLEngine::clickedAttackButton(Button *button) {
}
int LoLEngine::clickedMagicButton(Button *button) {
if (_characters[button->data2Val2].flags & 0x314C)
return 1;
if (notEnoughMagic(button->data2Val2, _availableSpells[_selectedSpell], 0))
return 1;
_characters[button->data2Val2].flags ^= 0x10;
gui_drawCharPortraitWithStats(button->data2Val2);
spellsub2(button->data2Val2);
_unkCharNum = button->data2Val2;
return 1;
}
@ -842,90 +854,334 @@ int LoLEngine::clickedUnk32(Button *button) {
GUI_LoL::GUI_LoL(LoLEngine *vm) : GUI(vm), _vm(vm), _screen(vm->_screen) {
_scrollUpFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollUp);
_scrollDownFunctor = BUTTON_FUNCTOR(GUI_LoL, this, &GUI_LoL::scrollDown);
_unknownButtonList = _backUpButtonList = 0;
_flagsModifier = 0;
_buttonListChanged = false;
}
int GUI_LoL::processButtonList(Button *list, uint16 inputFlag, int8 mouseWheel) {
inputFlag &= 0x7fff;
void GUI_LoL::processButton(Button *button) {
if (!button)
return;
if (button->flags & 8) {
if (button->flags & 0x10) {
// XXX
}
return;
}
int entry = button->flags2 & 5;
byte val1 = 0, val2 = 0, val3 = 0;
const uint8 *dataPtr = 0;
Button::Callback callback;
if (entry == 1) {
val1 = button->data1Val1;
dataPtr = button->data1ShapePtr;
callback = button->data1Callback;
val2 = button->data1Val2;
val3 = button->data1Val3;
} else if (entry == 4 || entry == 5) {
val1 = button->data2Val1;
dataPtr = button->data2ShapePtr;
callback = button->data2Callback;
val2 = button->data2Val2;
val3 = button->data2Val3;
} else {
val1 = button->data0Val1;
dataPtr = button->data0ShapePtr;
callback = button->data0Callback;
val2 = button->data0Val2;
val3 = button->data0Val3;
}
int x = 0, y = 0, x2 = 0, y2 = 0;
x = button->x;
if (x < 0)
x += _screen->getScreenDim(button->dimTableIndex)->w << 3;
x += _screen->getScreenDim(button->dimTableIndex)->sx << 3;
x2 = x + button->width - 1;
y = button->y;
if (y < 0)
y += _screen->getScreenDim(button->dimTableIndex)->h << 3;
y += _screen->getScreenDim(button->dimTableIndex)->sy << 3;
y2 = y + button->height - 1;
switch (val1 - 1) {
case 0:
_screen->hideMouse();
_screen->drawShape(_screen->_curPage, dataPtr, x, y, button->dimTableIndex, 0x10);
_screen->showMouse();
break;
case 1:
_screen->hideMouse();
_screen->printText((const char*)dataPtr, x, y, val2, val3);
_screen->showMouse();
break;
case 3:
if (callback)
(*callback)(button);
break;
case 4:
_screen->hideMouse();
_screen->drawBox(x, y, x2, y2, val2);
_screen->showMouse();
break;
case 5:
_screen->hideMouse();
_screen->fillRect(x, y, x2, y2, val2, -1, true);
_screen->showMouse();
break;
default:
break;
}
_screen->updateScreen();
}
int GUI_LoL::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseWheel) {
if (!buttonList)
return inputFlag & 0x7FFF;
if (_backUpButtonList != buttonList || _buttonListChanged) {
_unknownButtonList = 0;
//flagsModifier |= 0x2200;
_backUpButtonList = buttonList;
_buttonListChanged = false;
while (buttonList) {
processButton(buttonList);
buttonList = buttonList->nextButton;
}
}
int mouseX = _vm->_mouseX;
int mouseY = _vm->_mouseY;
uint16 flags = 0;
if (1/*!_screen_cursorDisable*/) {
uint16 inFlags = inputFlag & 0xFF;
uint16 temp = 0;
// HACK: inFlags == 200 is our left button (up)
if (inFlags == 199 || inFlags == 200)
temp = 0x100;
if (inFlags == 201 || inFlags == 202)
temp = 0x1000;
if (inputFlag & 0x800)
temp <<= 2;
flags |= temp;
_flagsModifier &= ~((temp & 0x4400) >> 1);
_flagsModifier |= (temp & 0x1100) * 2;
flags |= _flagsModifier;
flags |= (_flagsModifier << 2) ^ 0x8800;
}
buttonList = _backUpButtonList;
if (_unknownButtonList) {
buttonList = _unknownButtonList;
if (_unknownButtonList->flags & 8)
_unknownButtonList = 0;
}
int returnValue = 0;
while (list) {
bool processMouseClick = (inputFlag == 199 && list->flags & 0x100) || (inputFlag == 299 && list->flags & 0x1000);
bool target = _vm->posWithinRect(_vm->_mouseX, _vm->_mouseY, list->x, list->y, list->x + list->width, list->y + list->height);
/*if (list->flags & 8) {
list = list->nextButton;
while (buttonList) {
if (buttonList->flags & 8) {
buttonList = buttonList->nextButton;
continue;
}
buttonList->flags2 &= ~0x18;
buttonList->flags2 |= (buttonList->flags2 & 3) << 3;
if (mouseWheel && list->mouseWheel == mouseWheel && list->buttonCallback) {
if ((*list->buttonCallback.get())(list))
int x = buttonList->x;
if (x < 0)
x += _screen->getScreenDim(buttonList->dimTableIndex)->w << 3;
x += _screen->getScreenDim(buttonList->dimTableIndex)->sx << 3;
int y = buttonList->y;
if (y < 0)
y += _screen->getScreenDim(buttonList->dimTableIndex)->h;
y += _screen->getScreenDim(buttonList->dimTableIndex)->sy;
bool progress = false;
if (mouseX >= x && mouseY >= y && mouseX <= x+buttonList->width && mouseY <= y+buttonList->height)
progress = true;
buttonList->flags2 &= ~0x80;
uint16 inFlags = inputFlag & 0x7FFF;
if (inFlags) {
if (buttonList->keyCode == inFlags) {
progress = true;
flags = buttonList->flags & 0x0F00;
buttonList->flags2 |= 0x80;
inputFlag = 0;
_unknownButtonList = buttonList;
} else if (buttonList->keyCode2 == inFlags) {
flags = buttonList->flags & 0xF000;
if (!flags)
flags = buttonList->flags & 0x0F00;
progress = true;
buttonList->flags2 |= 0x80;
inputFlag = 0;
_unknownButtonList = buttonList;
}
}
bool unk1 = false;
if (mouseWheel && buttonList->mouseWheel == mouseWheel) {
progress = true;
unk1 = true;
}
if (!progress)
buttonList->flags2 &= ~6;
if ((flags & 0x3300) && (buttonList->flags & 4) && progress && (buttonList == _unknownButtonList || !_unknownButtonList)) {
buttonList->flags |= 6;
if (!_unknownButtonList)
_unknownButtonList = buttonList;
} else if ((flags & 0x8800) && !(buttonList->flags & 4) && progress) {
buttonList->flags2 |= 6;
} else {
buttonList->flags2 &= ~6;
}
bool progressSwitch = false;
if (!_unknownButtonList) {
progressSwitch = progress;
} else {
if (_unknownButtonList->flags & 0x40)
progressSwitch = (_unknownButtonList == buttonList);
else
progressSwitch = progress;
}
if (progressSwitch) {
if ((flags & 0x1100) && progress && !_unknownButtonList) {
inputFlag = 0;
_unknownButtonList = buttonList;
}
if ((buttonList->flags & flags) && (progress || !(buttonList->flags & 1))) {
uint16 combinedFlags = (buttonList->flags & flags);
combinedFlags = ((combinedFlags & 0xF000) >> 4) | (combinedFlags & 0x0F00);
combinedFlags >>= 8;
static const uint16 flagTable[] = {
0x000, 0x100, 0x200, 0x100, 0x400, 0x100, 0x400, 0x100, 0x800, 0x100,
0x200, 0x100, 0x400, 0x100, 0x400, 0x100
};
assert(combinedFlags < ARRAYSIZE(flagTable));
switch (flagTable[combinedFlags]) {
case 0x400:
if (!(buttonList->flags & 1) || ((buttonList->flags & 1) && _unknownButtonList == buttonList)) {
buttonList->flags2 ^= 1;
returnValue = buttonList->index | 0x8000;
unk1 = true;
}
if (!(buttonList->flags & 4)) {
buttonList->flags2 &= ~4;
buttonList->flags2 &= ~2;
}
break;
case 0x800:
if (!(buttonList->flags & 4)) {
buttonList->flags2 |= 4;
buttonList->flags2 |= 2;
}
if (!(buttonList->flags & 1))
unk1 = true;
break;
case 0x200:
if (buttonList->flags & 4) {
buttonList->flags2 |= 4;
buttonList->flags2 |= 2;
}
if (!(buttonList->flags & 1))
unk1 = true;
break;
case 0x100:
default:
buttonList->flags2 ^= 1;
returnValue = buttonList->index | 0x8000;
unk1 = true;
if (buttonList->flags & 4) {
buttonList->flags2 |= 4;
buttonList->flags2 |= 2;
}
_unknownButtonList = buttonList;
break;
}
}
}
bool unk2 = false;
if ((flags & 0x2200) && progress) {
buttonList->flags2 |= 6;
if (!(buttonList->flags & 4) && !(buttonList->flags2 & 1)) {
unk2 = true;
buttonList->flags2 |= 1;
}
}
if ((flags & 0x8800) == 0x8800) {
_unknownButtonList = 0;
if (!progress || (buttonList->flags & 4))
buttonList->flags2 &= ~6;
}
if (!progress && buttonList == _unknownButtonList && !(buttonList->flags & 0x40))
_unknownButtonList = 0;
if ((buttonList->flags2 & 0x18) != ((buttonList->flags2 & 3) << 3))
processButton(buttonList);
if (unk2)
buttonList->flags2 &= ~1;
if (unk1) {
buttonList->flags2 &= 0xFF;
buttonList->flags2 |= flags;
if (buttonList->buttonCallback) {
_vm->removeInputTop();
if ((*buttonList->buttonCallback.get())(buttonList))
break;
}
if (buttonList->flags & 0x20)
break;
}
int x = list->x;
int y = list->y;
assert(_screen->getScreenDim(list->dimTableIndex) != 0);
if (_unknownButtonList == buttonList && (buttonList->flags & 0x40))
break;
if (x < 0)
x += _screen->getScreenDim(list->dimTableIndex)->w << 3;
x += _screen->getScreenDim(list->dimTableIndex)->sx << 3;
if (y < 0)
y += _screen->getScreenDim(list->dimTableIndex)->h;
y += _screen->getScreenDim(list->dimTableIndex)->sy;
if (_vm->_mouseX >= x && _vm->_mouseY >= y && x + list->width >= _vm->_mouseX && y + list->height >= _vm->_mouseY) {
int processMouseClick = 0;
if (list->flags & 0x400) {
if ((inputFlag & 0xFF) == 199 || _pressFlag) {
if (!(list->flags2 & 1)) {
list->flags2 |= 1;
list->flags2 |= 4;
processButton(list);
_screen->updateScreen();
inputFlag = 0;
}
} else if ((inputFlag & 0xFF) == 200) {
if (list->flags2 & 1) {
list->flags2 &= 0xFFFE;
processButton(list);
processMouseClick = 1;
inputFlag = 0;
}
}
}
if (processMouseClick) {
if (list->buttonCallback) {
if ((*list->buttonCallback.get())(list))
break;
}
}
} else {
if (list->flags2 & 1) {
list->flags2 &= 0xFFFE;
processButton(list);
}
if (list->flags2 & 4) {
list->flags2 &= 0xFFFB;
processButton(list);
_screen->updateScreen();
}
}*/
if (processMouseClick && target) {
if (list->buttonCallback) {
if ((*list->buttonCallback.get())(list))
break;
}
}
list = list->nextButton;
buttonList = buttonList->nextButton;
}
if (!returnValue)
returnValue = inputFlag & 0xFF;
returnValue = inputFlag & 0x7FFF;
return returnValue;
}

View File

@ -41,7 +41,7 @@ public:
void initStaticData();
// button specific
void processButton(Button *button) {}
void processButton(Button *button);
int processButtonList(Button *buttonList, uint16 inputFlags, int8 mouseWheel);
// utilities for thumbnail creation
@ -53,6 +53,11 @@ private:
bool _pressFlag;
Button *_unknownButtonList;
Button *_backUpButtonList;
bool _buttonListChanged;
uint16 _flagsModifier;
int scrollUp(Button *button) { return 0; }
int scrollDown(Button *button) { return 0; }

View File

@ -218,13 +218,13 @@ int GUI_v2::processButtonList(Button *buttonList, uint16 inputFlag, int8 mouseWh
buttonList->flags2 &= ~0x80;
uint16 inFlags = inputFlag & 0x7FFF;
if (inFlags) {
if (buttonList->unk6 == inFlags) {
if (buttonList->keyCode == inFlags) {
progress = true;
flags = buttonList->flags & 0x0F00;
buttonList->flags2 |= 0x80;
inputFlag = 0;
_unknownButtonList = buttonList;
} else if (buttonList->unk8 == inFlags) {
} else if (buttonList->keyCode2 == inFlags) {
flags = buttonList->flags & 0xF000;
if (!flags)
flags = buttonList->flags & 0x0F00;

View File

@ -34,8 +34,8 @@ namespace Kyra {
do { \
button.nextButton = 0; \
button.index = a; \
button.unk6 = b; \
button.unk8 = c; \
button.keyCode = b; \
button.keyCode2 = c; \
button.data0Val1 = d; \
button.data1Val1 = e; \
button.data2Val1 = f; \

View File

@ -260,23 +260,53 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop) {
} else {
switch(event.kbd.keycode) {
case Common::KEYCODE_SPACE:
keys = 100;
keys = 120;
break;
case Common::KEYCODE_RETURN:
keys = 101;
keys = 121;
break;
case Common::KEYCODE_UP:
keys = 110;
case Common::KEYCODE_KP8:
keys = 96;
break;
case Common::KEYCODE_RIGHT:
keys = 111;
case Common::KEYCODE_KP6:
keys = 102;
break;
case Common::KEYCODE_DOWN:
keys = 112;
case Common::KEYCODE_KP2:
keys = 97;
break;
case Common::KEYCODE_LEFT:
case Common::KEYCODE_KP4:
keys = 92;
break;
case Common::KEYCODE_HOME:
case Common::KEYCODE_KP7:
keys = 91;
break;
case Common::KEYCODE_PAGEUP:
case Common::KEYCODE_KP9:
keys = 101;
break;
case Common::KEYCODE_F1:
keys = 112;
break;
case Common::KEYCODE_F2:
keys = 113;
break;
case Common::KEYCODE_F3:
keys = 114;
break;
case Common::KEYCODE_o:
keys = 25;
break;
case Common::KEYCODE_r:
keys = 20;
break;
case Common::KEYCODE_ESCAPE:
keys = 110;
break;
default:
break;
}
@ -303,7 +333,7 @@ int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop) {
Common::Point pos = getMousePos();
_mouseX = pos.x;
_mouseY = pos.y;
keys = (event.type == Common::EVENT_RBUTTONDOWN ? 299 : (300 | 0x800));
keys = (event.type == Common::EVENT_RBUTTONDOWN ? 201 : (202 | 0x800));
breakLoop = true;
} break;

View File

@ -1354,5 +1354,21 @@ void LoLEngine::calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs,
y = ((block & 0xffe0) << 3) | yOffs;
}
bool LoLEngine::notEnoughMagic(int charNum, int spellNum, int spellLevel) {
if (_spellProperties[spellNum].mpRequired[spellLevel] > _characters[charNum].magicPointsCur) {
return true;
} else {
}
return false;
}
void LoLEngine::spellsub2(int charNum) {
}
} // end of namespace Kyra

View File

@ -209,8 +209,8 @@ struct CompassDef {
struct ButtonDef {
uint16 buttonflags;
uint8 clickedShapeId;
uint16 unk2;
uint16 keyCode;
uint16 keyCode2;
int16 x;
int16 y;
uint16 w;
@ -848,6 +848,9 @@ private:
void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs);
// spells
bool notEnoughMagic(int charNum, int spellNum, int spellLevel);
void spellsub2(int charNum);
int8 _availableSpells[7];
int _selectedSpell;
const SpellProperty *_spellProperties;

View File

@ -916,30 +916,30 @@ uint16 TIMInterpreter_LoL::processDialogue() {
//}
}
} else {
int e = _vm->checkInput(0, false);
int e = _vm->checkInput(0, false) & 0xCF;
_vm->removeInputTop();
switch (e) {
case 100:
case 101:
case 120:
case 121:
_vm->snd_dialogueSpeechUpdate(1);
//_dlgTimer = 0;
res = _dialogueHighlightedButton + 1;
break;
case 110:
case 111:
case 92:
case 97:
if (_dialogueNumButtons > 1 && _dialogueHighlightedButton > 0)
_dialogueHighlightedButton--;
break;
case 112:
case 113:
case 96:
case 102:
if (_dialogueNumButtons > 1 && _dialogueHighlightedButton < (_dialogueNumButtons - 1))
_dialogueHighlightedButton++;
break;
case 200:
case 300:
case 202:
x = _dialogueButtonPosX;
for (int i = 0; i < _dialogueNumButtons; i++) {

View File

@ -44,7 +44,7 @@
namespace Kyra {
#define RESFILE_VERSION 36
#define RESFILE_VERSION 37
namespace {
bool checkKyraDat(Common::SeekableReadStream *file) {
@ -1078,9 +1078,8 @@ bool StaticResource::loadButtonDefs(const char *filename, void *&ptr, int &size)
for (int i = 0; i < size; i++) {
r[i].buttonflags = file->readUint16BE();
r[i].clickedShapeId = file->readByte();
file->readByte();
r[i].unk2 = file->readUint16BE();
r[i].keyCode = file->readUint16BE();
r[i].keyCode2 = file->readUint16BE();
r[i].x = file->readSint16BE();
r[i].y = file->readSint16BE();
r[i].w = file->readUint16BE();

View File

@ -31,7 +31,7 @@
#include "md5.h"
enum {
kKyraDatVersion = 36,
kKyraDatVersion = 37,
kIndexSize = 12
};
@ -1093,8 +1093,8 @@ bool extractLolButtonDefs(PAKFile &out, const Game *g, const byte *data, const u
for (int i = 0; i < num; i++) {
WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
src += 2; dst += 2;
*dst++ = *src++;
*dst++ = *src++;
WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
src += 2; dst += 2;
WRITE_BE_UINT16(dst, READ_LE_UINT16(src));
src += 6; dst += 2;
WRITE_BE_UINT16(dst, READ_LE_UINT16(src));