scummvm/engines/kyra/gui_lol.cpp

1738 lines
42 KiB
C++
Raw Normal View History

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $URL$
* $Id$
*
*/
#include "kyra/lol.h"
#include "kyra/screen_lol.h"
2009-02-01 19:27:01 +00:00
#include "kyra/gui_lol.h"
namespace Kyra {
void LoLEngine::gui_drawPlayField() {
_screen->loadBitmap("PLAYFLD.CPS", 3, 3, 0);
if (_screen->_drawGuiFlag & 0x4000) {
// copy compass shape
static const int cx[] = { 112, 152, 224 };
_screen->copyRegion(cx[_lang], 32, 288, 0, 32, 32, 2, 2, Screen::CR_NO_P_CHECK);
2009-02-01 19:27:01 +00:00
_compassDirection = -1;
}
if (_screen->_drawGuiFlag & 0x1000)
// draw automap book
_screen->drawShape(2, _gameShapes[78], 289, 32, 0, 0);
int cp = _screen->setCurPage(2);
if (_screen->_drawGuiFlag & 0x2000) {
gui_drawScroll();
} else {
_selectedSpell = 0;
}
if (_screen->_drawGuiFlag & 0x800)
2009-02-01 19:27:01 +00:00
resetLampStatus();
gui_drawScene(2);
gui_drawAllCharPortraitsWithStats();
gui_drawInventory();
gui_drawMoneyBox(_screen->_curPage);
2009-02-01 19:27:01 +00:00
_screen->setCurPage(cp);
_screen->hideMouse();
_screen->copyPage(2, 0);
_screen->showMouse();
}
void LoLEngine::gui_drawScene(int pageNum) {
2009-02-01 19:27:01 +00:00
if (!(_updateFlags & 1) && _weaponsDisabled == false && _unkDrawLevelBool && _vcnBlocks)
drawScene(pageNum);
}
void LoLEngine::gui_drawInventory() {
2009-02-01 19:27:01 +00:00
if (!_hideControls || !_hideInventory) {
for (int i = 0; i < 9; i++)
gui_drawInventoryItem(i);
}
}
void LoLEngine::gui_drawInventoryItem(int index) {
static const uint16 inventoryXpos[] = { 0x6A, 0x7F, 0x94, 0xA9, 0xBE, 0xD3, 0xE8, 0xFD, 0x112 };
int x = inventoryXpos[index];
int item = _inventoryCurItem + index;
if (item > 47)
item -= 48;
int flag = item & 1 ? 0 : 1;
_screen->drawShape(_screen->_curPage, _gameShapes[4], x, 179, 0, flag);
if (_inventory[item])
_screen->drawShape(_screen->_curPage, getItemIconShapePtr(_inventory[item]), x + 1, 180, 0, 0);
}
void LoLEngine::gui_drawScroll() {
_screen->copyRegion(112, 0, 12, 0, 87, 15, 2, 2, Screen::CR_NO_P_CHECK);
int h = 0;
for (int i = 0; i < 7; i++) {
if (_availableSpells[i] != -1)
h += 9;
}
if (h == 18)
h = 27;
if (h) {
_screen->copyRegion(201, 1, 17, 15, 6, h, 2, 2, Screen::CR_NO_P_CHECK);
_screen->copyRegion(208, 1, 89, 15, 6, h, 2, 2, Screen::CR_NO_P_CHECK);
_screen->fillRect(21, 15, 89, h + 15, 206);
}
_screen->copyRegion(112, 16, 12, h + 15, 87, 14, 2, 2, Screen::CR_NO_P_CHECK);
int y = 15;
for (int i = 0; i < 7; i++) {
if (_availableSpells[i] == -1)
continue;
uint8 col = (i == _selectedSpell) ? 132 : 1;
_screen->fprintString(getLangString(_spellProperties[_availableSpells[i]].spellNameCode), 24, y, col, 0, 0);
y += 9;
}
}
void LoLEngine::gui_highlightSelectedSpell(int unk) {
}
void LoLEngine::gui_displayCharInventory(int charNum) {
static const uint8 inventoryTypes[] = { 0, 1, 2, 6, 3, 1, 1, 3, 5, 4 };
int cp = _screen->setCurPage(2);
LoLCharacter *l = &_characters[charNum];
int id = l->id;
if (id < 0)
id = -id;
if (id != _lastCharInventory) {
char file[13];
sprintf(file, "invent%d.cps", inventoryTypes[id]);
_screen->loadBitmap(file, 3, 3, 0);
_screen->copyRegion(0, 0, 112, 0, 208, 120, 2, 6);
} else {
_screen->copyRegion(112, 0, 0, 0, 208, 120, 6, 2);
}
_screen->copyRegion(80, 143, 80, 143, 232, 35, 0, 2);
gui_drawAllCharPortraitsWithStats();
_screen->fprintString(l->name, 157, 9, 254, 0, 5);
gui_printCharInventoryStats(charNum);
for (int i = 0; i < 11; i++)
gui_drawCharInventoryItem(i);
_screen->fprintString(getLangString(0x4033), 182, 103, 172, 0, 5);
static const uint16 skillFlags[] = { 0x0080, 0x0000, 0x1000, 0x0002, 0x100, 0x0001, 0x0000, 0x0000 };
uint16 tmp[6];
memset(tmp, -1, 6);
int x = 0;
int32 c = 0;
for (int i = 0; i < 3; i++) {
if (!(l->flags & skillFlags[i << 1]))
continue;
uint8 *shp = _gameShapes[skillFlags[(i << 1) + 1]];
_screen->drawShape(_screen->_curPage, shp, 108 + x, 98, 0, 0);
x += (shp[3] + 2);
tmp[c] = skillFlags[(i << 1) + 1];
c++;
}
for (int i = 0; i < 3; i++) {
int32 b = l->experiencePts[i] - _expRequirements[l->skillLevels[i] - 1];
int32 e = _expRequirements[l->skillLevels[i]] - _expRequirements[l->skillLevels[i] - 1];
while (e & 0xffff8000) {
e >>= 1;
c = b;
b >>= 1;
if (c && !b)
b = 1;
}
gui_drawBarGraph(154, 64 + i * 10, 34, 5, b, e, 132, 0);
}
_screen->drawClippedLine(14, 120, 194, 120, 1);
_screen->copyRegion(0, 0, 112, 0, 208, 121, 2, 0);
_screen->copyRegion(80, 143, 80, 143, 232, 35, 2, 0);
_screen->setCurPage(cp);
}
void LoLEngine::gui_printCharInventoryStats(int charNum) {
for (int i = 0; i < 5; i++)
gui_printCharacterStats(i, 1, calculateCharacterStats(charNum, i));
_charInventoryUnk |= (1 << charNum);
}
void LoLEngine::gui_printCharacterStats(int index, int redraw, int value) {
uint32 offs = _screen->_curPage ? 0 : 112;
int y = 0;
int col = 0;
if (index < 2) {
// might
// protection
y = index * 10 + 22;
col = 158;
if (redraw)
_screen->fprintString(getLangString(0x4014 + index), offs + 108, y, col, 0, 4);
} else {
//skills
int s = index - 2;
y = s * 10 + 62;
col = _characters[_selectedCharacter].flags & (0x200 << s) ? 254 : 180;
if (redraw)
_screen->fprintString(getLangString(0x4014 + index), offs + 108, y, col, 0, 4);
}
if (offs)
_screen->copyRegion(294, y, 182 + offs, y, 18, 8, 6, _screen->_curPage, Screen::CR_NO_P_CHECK);
_screen->fprintString("%d", 200 + offs, y, col, 0, 6, value);
}
void LoLEngine::gui_changeCharacterStats(int charNum) {
int tmp[5];
int inc[5];
bool prc = false;
for (int i = 0; i < 5; i++) {
tmp[i] = calculateCharacterStats(charNum, i);
int diff = tmp[i] - _charStatsTemp[i];
inc[i] = diff / 15;
if (diff) {
prc = true;
if (!inc[i])
inc[i] = (diff < 0) ? -1 : 1;
}
}
if (!prc)
return;
do {
prc = false;
for (int i = 0; i < 5; i++) {
if (tmp[i] == _charStatsTemp[i])
continue;
_charStatsTemp[i] += inc[i];
if ((inc[i] > 0 && tmp[i] < _charStatsTemp[i]) || (inc[i] < 0 && tmp[i] > _charStatsTemp[i]))
_charStatsTemp[i] = tmp[i];
gui_printCharacterStats(i, 0, _charStatsTemp[i]);
prc = true;
}
delay(_tickLength, true);
} while (prc);
}
void LoLEngine::gui_drawCharInventoryItem(int itemIndex) {
static const uint8 slotShapes[] = { 0x30, 0x34, 0x30, 0x34, 0x2E, 0x2F, 0x32, 0x33, 0x31, 0x35, 0x35 };
const int8 *coords = &_charInvDefs[_charInvIndex[_characters[_selectedCharacter].raceClassSex] * 22 + itemIndex * 2];
int8 x = *coords++;
int8 y = *coords;
if (y == -1)
return;
if (!_screen->_curPage)
x += 112;
int i = _characters[_selectedCharacter].items[itemIndex];
int shapeNum = i ? ((itemIndex < 9) ? 4 : 5) : slotShapes[itemIndex];
_screen->drawShape(_screen->_curPage, _gameShapes[shapeNum], x, y, 0, 0);
if (i)
_screen->drawShape(_screen->_curPage, getItemIconShapePtr(i), x + 1, y + 1, 0, 0);
}
void LoLEngine::gui_drawBarGraph(int x, int y, int w, int h, int32 cur, int32 max, int col1, int col2) {
if (max < 1)
return;
if (cur < 0)
cur = 0;
int32 e = MIN(cur, max);
if (!--w)
return;
if (!--h)
return;
int32 t = (e * w) / max;
if (!t && e)
t++;
if (t)
_screen->fillRect(x, y, x + t - 1, y + h, col1);
if (t < w && col2)
_screen->fillRect(x + t, y, x + w, y + h, col2);
}
void LoLEngine::gui_drawAllCharPortraitsWithStats() {
int numChars = countActiveCharacters();
if (!numChars)
return;
for (int i = 0; i < numChars; i++)
gui_drawCharPortraitWithStats(i);
}
void LoLEngine::gui_drawCharPortraitWithStats(int charNum) {
2009-02-01 19:27:01 +00:00
if (!(_characters[charNum].flags & 1) || _updateFlags & 2)
return;
Screen::FontId tmpFid = _screen->setFont(Screen::FID_6_FNT);
int cp = _screen->setCurPage(6);
2009-02-01 19:27:01 +00:00
gui_drawBox(0, 0, 66, 34, 1, 1, -1);
gui_drawCharFaceShape(0, 0, 1, _screen->_curPage);
gui_drawLiveMagicBar(33, 32, _characters[charNum].magicPointsCur, 0, _characters[charNum].magicPointsMax, 5, 32, 162, 1, 0);
gui_drawLiveMagicBar(39, 32, _characters[charNum].hitPointsCur, 0, _characters[charNum].hitPointsMax, 5, 32, 154, 1, 1);
_screen->printText(getLangString(0x4253), 33, 1, 160, 0);
_screen->printText(getLangString(0x4254), 39, 1, 152, 0);
int spellLevels = 0;
if (_availableSpells[_selectedSpell] != -1) {
for (int i = 0; i < 4; i++) {
if (_spellProperties[_availableSpells[_selectedSpell]].mpRequired[i] <= _characters[charNum].magicPointsCur &&
_spellProperties[_availableSpells[_selectedSpell] + 1].unkArr[i] <= _characters[charNum].hitPointsCur)
spellLevels++;
}
}
if (_characters[charNum].flags & 0x10) {
// magic submenu open
_screen->drawShape(_screen->_curPage, _gameShapes[73], 44, 0, 0, 0);
if (spellLevels < 4)
_screen->drawGridBox(44, (spellLevels << 3) + 1, 22, 32 - (spellLevels << 3), 1);
} else {
// magic submenu closed
int handIndex = 0;
2009-02-01 19:27:01 +00:00
if (_characters[charNum].items[0]) {
if (_itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].might != -1)
2009-02-01 19:27:01 +00:00
handIndex = _itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex;
}
handIndex = _gameShapeMap[(_itemProperties[handIndex].shpIndex << 1) + 1];
2009-02-01 19:27:01 +00:00
if (handIndex == 0x5a) { // draw raceClassSex specific hand shape
handIndex = _characters[charNum].raceClassSex - 1;
if (handIndex < 0)
handIndex = 0;
handIndex += 68;
}
2009-02-01 19:27:01 +00:00
// draw hand/weapon
2009-02-01 19:27:01 +00:00
_screen->drawShape(_screen->_curPage, _gameShapes[handIndex], 44, 0, 0, 0);
// draw magic symbol
_screen->drawShape(_screen->_curPage, _gameShapes[72 + _characters[charNum].field_41], 44, 17, 0, 0);
if (spellLevels == 0)
_screen->drawGridBox(44, 17, 22, 15, 1);
}
uint16 f = _characters[charNum].flags & 0x314C;
2009-02-01 19:27:01 +00:00
if ((f == 0 && _weaponsDisabled) || (f && (f != 4 || _characters[charNum].weaponHit == 0 || _weaponsDisabled)))
_screen->drawGridBox(44, 0, 22, 34, 1);
if (_characters[charNum].weaponHit) {
_screen->drawShape(_screen->_curPage, _gameShapes[34], 44, 0, 0, 0);
_screen->fprintString("%d", 57, 7, 254, 0, 1, _characters[charNum].weaponHit);
}
if (_characters[charNum].damageSuffered)
_screen->fprintString("%d", 17, 28, 254, 0, 1, _characters[charNum].damageSuffered);
if (!cp)
_screen->hideMouse();
2009-02-01 19:27:01 +00:00
uint8 col = (charNum != _selectedCharacter || countActiveCharacters() == 1) ? 1 : 212;
_screen->drawBox(0, 0, 65, 33, col);
_screen->copyRegion(0, 0, _activeCharsXpos[charNum], 143, 66, 34, _screen->_curPage, cp, Screen::CR_NO_P_CHECK);
if (!cp)
_screen->showMouse();
_screen->setCurPage(cp);
_screen->setFont(tmpFid);
}
2009-02-01 19:27:01 +00:00
void LoLEngine::gui_drawBox(int x, int y, int w, int h, int frameColor1, int frameColor2, int fillColor) {
w--; h--;
if (fillColor != -1)
_screen->fillRect(x + 1, y + 1, x + w - 1, y + h - 1, fillColor);
_screen->drawClippedLine(x + 1, y, x + w, y, frameColor2);
_screen->drawClippedLine(x + w, y, x + w, y + h - 1, frameColor2);
_screen->drawClippedLine(x, y, x, y + h, frameColor1);
_screen->drawClippedLine(x, y + h, x + w, y + h, frameColor1);
}
void LoLEngine::gui_drawCharFaceShape(int charNum, int x, int y, int pageNum) {
if (_characters[charNum].curFaceFrame < 7 && _characters[charNum].nextFaceFrame)
_characters[charNum].curFaceFrame = _characters[charNum].nextFaceFrame;
if (_characters[charNum].nextFaceFrame == 0 && _characters[charNum].curFaceFrame > 1 && _characters[charNum].curFaceFrame < 7)
_characters[charNum].curFaceFrame = _characters[charNum].nextFaceFrame;
int frm = (_characters[charNum].flags & 0x1108 && _characters[charNum].curFaceFrame < 7) ? 1 : _characters[charNum].curFaceFrame;
if (_characters[charNum].hitPointsCur <= (_characters[charNum].hitPointsMax >> 1))
frm += 14;
if (!pageNum)
_screen->hideMouse();
_screen->drawShape(pageNum, _characterFaceShapes[frm][charNum], x, y, 0, 0x100, _screen->_paletteOverlay2, (_characters[charNum].flags & 0x80 ? 1 : 0));
if (_characters[charNum].flags & 0x40)
// draw spider web
_screen->drawShape(pageNum, _gameShapes[21], x, y, 0, 0);
if (!pageNum)
_screen->showMouse();
}
void LoLEngine::gui_highlightPortraitFrame(int charNum) {
if (charNum != _selectedCharacter) {
int o = _selectedCharacter;
_selectedCharacter = charNum;
gui_drawCharPortraitWithStats(o);
}
gui_drawCharPortraitWithStats(charNum);
}
void LoLEngine::gui_drawLiveMagicBar(int x, int y, int curPoints, int unk, int maxPoints, int w, int h, int col1, int col2, int flag) {
w--;
h--;
if (maxPoints < 1)
return;
int t = (curPoints < 1) ? 0 : curPoints;
curPoints = (maxPoints < t) ? maxPoints : t;
int barHeight = (curPoints * h) / maxPoints;
if (barHeight < 1 && curPoints < 1)
barHeight = 1;
_screen->drawClippedLine(x - 1, y - h, x - 1, y, 1);
if (flag) {
t = maxPoints >> 1;
if (t > curPoints)
col1 = 144;
t = maxPoints >> 2;
if (t > curPoints)
col1 = 132;
}
if (barHeight > 0)
_screen->fillRect(x, y - barHeight, x + w, y, col1);
if (barHeight < h)
_screen->fillRect(x, y - h, x + w, y - barHeight, col2);
if (unk > 0 && unk < maxPoints)
_screen->drawBox(x, y - barHeight, x + w, y, col1 - 2);
}
void LoLEngine::calcCharPortraitXpos() {
int nc = countActiveCharacters();
// TODO
int t = (235 - (nc * 66)) / (nc + 1);
for (int i = 0; i < nc; i++)
_activeCharsXpos[i] = i * 66 + t * (i + 1) + 83;
}
void LoLEngine::gui_drawMoneyBox(int pageNum) {
static const uint16 moneyX[] = { 0x128, 0x134, 0x12b, 0x131, 0x12e};
static const uint16 moneyY[] = { 0x73, 0x73, 0x74, 0x74, 0x75};
int backupPage = _screen->_curPage;
_screen->_curPage = pageNum;
_screen->fillRect(292, 97, 316, 118, 252, pageNum);
for (int i = 0; i < 5; i++) {
if (!_moneyColumnHeight[i])
continue;
uint8 h = _moneyColumnHeight[i] - 1;
_screen->drawClippedLine(moneyX[i], moneyY[i], moneyX[i], moneyY[i] - h, 0xd2);
_screen->drawClippedLine(moneyX[i] + 1, moneyY[i], moneyX[i] + 1, moneyY[i] - h, 0xd1);
_screen->drawClippedLine(moneyX[i] + 2, moneyY[i], moneyX[i] + 2, moneyY[i] - h, 0xd0);
_screen->drawClippedLine(moneyX[i] + 3, moneyY[i], moneyX[i] + 3, moneyY[i] - h, 0xd1);
_screen->drawClippedLine(moneyX[i] + 4, moneyY[i], moneyX[i] + 4, moneyY[i] - h, 0xd2);
}
Screen::FontId backupFont = _screen->setFont(Screen::FID_6_FNT);
_screen->fprintString("%d", 305, 98, 254, 0, 1, _credits);
_screen->setFont(backupFont);
_screen->_curPage = backupPage;
if (pageNum == 6) {
_screen->hideMouse();
_screen->copyRegion(292, 97, 292, 97, 25, 22, 6, 0);
_screen->showMouse();
}
}
void LoLEngine::gui_drawCompass() {
if (!(_screen->_drawGuiFlag & 0x4000))
return;
2009-02-01 19:27:01 +00:00
if (_compassDirection == -1) {
_compassDirectionIndex = -1;
2009-02-01 19:27:01 +00:00
_compassDirection = _currentDirection << 6;
}
2009-02-01 19:27:01 +00:00
int t = ((_compassDirection + 4) >> 3) & 0x1f;
if (t == _compassDirectionIndex)
return;
_compassDirectionIndex = t;
if (!_screen->_curPage)
_screen->hideMouse();
const CompassDef *c = &_compassDefs[t];
_screen->drawShape(_screen->_curPage, _gameShapes[22 + _lang], 294, 3, 0, 0);
2009-02-01 19:27:01 +00:00
_screen->drawShape(_screen->_curPage, _gameShapes[25 + c->shapeIndex], 298 + c->x, c->y + 9, 0, c->flags | 0x300, _screen->_paletteOverlay1, 1);
_screen->drawShape(_screen->_curPage, _gameShapes[25 + c->shapeIndex], 299 + c->x, c->y + 8, 0, c->flags);
if (!_screen->_curPage)
_screen->showMouse();
}
2009-02-01 19:27:01 +00:00
int LoLEngine::gui_enableControls() {
_floatingMouseArrowControl = 0;
if (!_hideControls) {
for (int i = 76; i < 85; i++)
gui_toggleButtonDisplayMode(i, 2);
2009-02-01 19:27:01 +00:00
}
gui_toggleFightButtons(false);
return 1;
}
int LoLEngine::gui_disableControls(int controlMode) {
if (_hideControls)
return 0;
_floatingMouseArrowControl = (controlMode & 2) ? 2 : 1;
gui_toggleFightButtons(true);
for (int i = 76; i < 85; i++)
gui_toggleButtonDisplayMode(i, ((controlMode & 2) && (i > 78)) ? 2 : 3);
2009-02-01 19:27:01 +00:00
return 1;
}
void LoLEngine::gui_toggleButtonDisplayMode(int shapeIndex, int mode) {
static const int16 buttonX[] = { 0x0056, 0x0128, 0x000C, 0x0021, 0x0122, 0x000C, 0x0021, 0x0036, 0x000C, 0x0021, 0x0036 };
static const int16 buttonY[] = { 0x00B4, 0x00B4, 0x00B4, 0x00B4, 0x0020, 0x0084, 0x0084, 0x0084, 0x0096, 0x0096, 0x0096 };
2009-02-01 19:27:01 +00:00
if (shapeIndex == 78 && !(_screen->_drawGuiFlag & 0x1000))
return;
if (_hideControls && _hideInventory)
return;
if (mode == 0)
shapeIndex = _lastButtonShape;
2009-02-01 19:27:01 +00:00
int pageNum = 0;
int16 x1 = buttonX[shapeIndex - 74];
int16 y1 = buttonY[shapeIndex - 74];
2009-02-01 19:27:01 +00:00
int16 x2 = 0;
int16 y2 = 0;
uint32 t = 0;
switch (mode) {
case 1:
mode = 0x100;
_lastButtonShape = shapeIndex;
2009-02-01 19:27:01 +00:00
break;
case 0:
if (!_lastButtonShape)
2009-02-01 19:27:01 +00:00
return;
t = _system->getMillis();
if (_buttonPressTimer > t)
delay(_buttonPressTimer - t);
2009-02-01 19:27:01 +00:00
case 2:
mode = 0;
_lastButtonShape = 0;
2009-02-01 19:27:01 +00:00
break;
case 3:
mode = 0;
_lastButtonShape = 0;
2009-02-01 19:27:01 +00:00
pageNum = 6;
x2 = x1;
y2 = y1;
x1 = 0;
y1 = 0;
break;
default:
break;
}
_screen->drawShape(pageNum, _gameShapes[shapeIndex], x1, y1, 0, mode, _screen->_paletteOverlay1, 1);
if (!pageNum)
_screen->updateScreen();
if (pageNum == 6) {
int cp = _screen->setCurPage(6);
2009-02-01 19:27:01 +00:00
_screen->drawGridBox(x1, y1, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], 1);
_screen->copyRegion(x1, y1, x2, y2, _gameShapes[shapeIndex][3], _gameShapes[shapeIndex][2], pageNum, 0, Screen::CR_NO_P_CHECK);
_screen->updateScreen();
2009-02-01 19:27:01 +00:00
_screen->setCurPage(cp);
}
2009-02-01 19:27:01 +00:00
_buttonPressTimer = _system->getMillis() + 6 * _tickLength;
2009-02-01 19:27:01 +00:00
}
void LoLEngine::gui_toggleFightButtons(bool disable) {
for (int i = 0; i < 3; i++) {
if (!(_characters[i].flags & 1))
continue;
if (disable)
_characters[i].flags |= 0x2000;
else
_characters[i].flags &= 0xdfff;
if (disable && !textEnabled()) {
int u = _selectedCharacter;
_selectedCharacter = 99;
int f = _updateFlags;
_updateFlags &= 0xfffd;
gui_drawCharPortraitWithStats(i);
_updateFlags = f;
_selectedCharacter = u;
} else {
gui_drawCharPortraitWithStats(i);
}
}
2009-02-01 19:27:01 +00:00
}
void LoLEngine::gui_updateInput() {
int inputFlag = checkInput(_activeButtons, true);
if (_preserveEvents)
_preserveEvents = false;
else
removeInputTop();
if (inputFlag && _unkCharNum != -1 && !(inputFlag & 0x8800)) {
gui_enableDefaultPlayfieldButtons();
_characters[_unkCharNum].flags &= 0xffef;
gui_drawCharPortraitWithStats(_unkCharNum);
gui_triggerEvent(inputFlag);
_unkCharNum = -1;
inputFlag = 0;
}
switch (inputFlag) {
case 43:
case 61:
// space or enter
snd_stopSpeech(true);
break;
case 55:
if (_weaponsDisabled || _availableSpells[1] == -1)
return;
gui_highlightSelectedSpell(0);
if (_availableSpells[++_selectedSpell] == -1)
_selectedSpell = 0;
gui_highlightSelectedSpell(1);
gui_drawAllCharPortraitsWithStats();
break;
case 0x71a:
break;
default:
break;
}
}
void LoLEngine::gui_triggerEvent(int eventType) {
Common::Event evt;
memset(&evt, 0, sizeof(Common::Event));
evt.mouse.x = _mouseX;
evt.mouse.y = _mouseY;
if (eventType == 65) {
evt.type = Common::EVENT_LBUTTONDOWN;
} else if (eventType == 66) {
evt.type = Common::EVENT_RBUTTONDOWN;
} else {
evt.type = Common::EVENT_KEYDOWN;
switch (eventType) {
case 96:
evt.kbd.keycode = Common::KEYCODE_UP;
break;
case 102:
evt.kbd.keycode = Common::KEYCODE_RIGHT;
break;
case 97:
evt.kbd.keycode = Common::KEYCODE_DOWN;
break;
case 92:
evt.kbd.keycode = Common::KEYCODE_LEFT;
break;
case 91:
evt.kbd.keycode = Common::KEYCODE_HOME;
break;
case 101:
evt.kbd.keycode = Common::KEYCODE_PAGEUP;
break;
case 112:
evt.kbd.keycode = Common::KEYCODE_F1;
break;
case 113:
evt.kbd.keycode = Common::KEYCODE_F2;
break;
case 114:
evt.kbd.keycode = Common::KEYCODE_F3;
break;
case 25:
evt.kbd.keycode = Common::KEYCODE_o;
break;
case 20:
evt.kbd.keycode = Common::KEYCODE_r;
break;
case 110:
evt.kbd.keycode = Common::KEYCODE_ESCAPE;
break;
case 43:
evt.kbd.keycode = Common::KEYCODE_SPACE;
break;
case 61:
evt.kbd.keycode = Common::KEYCODE_RETURN;
break;
case 55:
evt.kbd.keycode = Common::KEYCODE_SLASH;
break;
default:
break;
}
}
removeInputTop();
_eventList.push_back(Event(evt, true));
_preserveEvents = true;
}
void LoLEngine::gui_enableDefaultPlayfieldButtons() {
gui_resetButtonList();
gui_initButtonsFromList(_buttonList1);
gui_initCharacterControlButtons(7, 44);
gui_initCharacterControlButtons(11, 44);
gui_initCharacterControlButtons(17, 0);
gui_initCharacterControlButtons(29, 0);
gui_initCharacterControlButtons(25, 33);
if (_screen->_drawGuiFlag & 0x2000)
gui_initMagicScrollButtons();
}
void LoLEngine::gui_enableSequenceButtons(int x, int y, int w, int h, int enableFlags) {
gui_resetButtonList();
_sceneWindowButton.x = x;
_sceneWindowButton.y = y;
_sceneWindowButton.w = w;
_sceneWindowButton.h = h;
gui_initButtonsFromList(_buttonList3);
if (enableFlags & 1)
gui_initButtonsFromList(_buttonList4);
if (enableFlags & 2)
gui_initButtonsFromList(_buttonList5);
}
void LoLEngine::gui_enableCharInventoryButtons(int charNum) {
gui_resetButtonList();
gui_initButtonsFromList(_buttonList2);
gui_initCharInventorySpecialButtons(charNum);
gui_initCharacterControlButtons(21, 0);
}
void LoLEngine::gui_resetButtonList() {
while (_activeButtons) {
Button *n = _activeButtons->nextButton;
delete _activeButtons;
_activeButtons = n;
}
gui_notifyButtonListChanged();
_activeButtons = 0;
}
void LoLEngine::gui_initButtonsFromList(const int16 *list) {
while (*list != -1)
gui_initButton(*list++);
}
void LoLEngine::gui_initCharacterControlButtons(int index, int xOffs) {
int c = countActiveCharacters();
for (int i = 0; i < c; i++)
gui_initButton(index + i, _activeCharsXpos[i] + xOffs);
}
void LoLEngine::gui_initCharInventorySpecialButtons(int charNum) {
const int8 *s = &_charInvDefs[_charInvIndex[_characters[charNum].raceClassSex] * 22];
for (int i = 0; i < 11; i++) {
if (*s != -1)
gui_initButton(33 + i, s[0], s[1], i);
s += 2;
}
}
void LoLEngine::gui_initMagicScrollButtons() {
}
void LoLEngine::gui_initMagicSubmenu(int charNum) {
gui_resetButtonList();
_subMenuIndex = charNum;
gui_initButtonsFromList(_buttonList7);
}
void LoLEngine::gui_initButton(int index, int x, int y, int val) {
Button *b = new Button;
memset (b, 0, sizeof(Button));
int cnt = 1;
if (_activeButtons) {
cnt++;
Button *n = _activeButtons;
while (n->nextButton) {
n = n->nextButton;
cnt++;
}
n->nextButton = b;
} else {
_activeButtons = b;
}
b->data0Val2 = 0xfe;
b->data0Val3 = 0x01;
b->data1Val2 = 0xfe;
b->data1Val3 = 0x01;
b->data2Val2 = 0xfe;
b->data2Val3 = 0x01;
b->index = cnt;
b->keyCode = _buttonData[index].keyCode;
b->keyCode2 = _buttonData[index].keyCode2;
b->dimTableIndex = _buttonData[index].screenDim;
b->flags = _buttonData[index].buttonflags;
b->data2Val2 = (val != -1) ? (uint8)(val & 0xff) : _buttonData[index].index;
if (index == 15) {
// magic sub menu
b->x = _activeCharsXpos[_subMenuIndex] + 44;
b->data2Val2 = _subMenuIndex;
b->y = _buttonData[index].y;
b->width = _buttonData[index].w - 1;
b->height = _buttonData[index].h - 1;
} else if (index == 64) {
// scene window button
b->x = _sceneWindowButton.x;
b->y = _sceneWindowButton.y;
b->width = _sceneWindowButton.w - 1;
b->height = _sceneWindowButton.h - 1;
} else {
b->x = x != -1 ? x : _buttonData[index].x;
b->y = y != -1 ? y : _buttonData[index].y;
b->width = _buttonData[index].w - 1;
b->height = _buttonData[index].h - 1;
}
assignButtonCallback(b, index);
}
2009-02-01 19:27:01 +00:00
int LoLEngine::clickedUpArrow(Button *button) {
if (button->data2Val2 && !(_unkGameFlag & 4))
return 0;
moveParty(_currentDirection, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 0, 80);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedDownArrow(Button *button) {
if (button->data2Val2 && !(_unkGameFlag & 4))
return 0;
moveParty(_currentDirection ^ 2, 0, 1, 83);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedLeftArrow(Button *button) {
if (button->data2Val2 && !(_unkGameFlag & 4))
return 0;
moveParty((_currentDirection - 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 2, 82);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedRightArrow(Button *button) {
if (button->data2Val2 && !(_unkGameFlag & 4))
return 0;
moveParty((_currentDirection + 1) & 3, ((button->flags2 & 0x1080) == 0x1080) ? 1 : 0, 3, 84);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedTurnLeftArrow(Button *button) {
if (button->data2Val2 && !(_unkGameFlag & 4))
return 0;
gui_toggleButtonDisplayMode(79, 1);
_currentDirection = (--_currentDirection) & 3;
_sceneDefaultUpdate = 1;
runLevelScript(_currentBlock, 0x4000);
initTextFading(2, 0);
if (!_sceneDefaultUpdate)
gui_drawScene(0);
else
movePartySmoothScrollTurnLeft(1);
gui_toggleButtonDisplayMode(79, 0);
runLevelScript(_currentBlock, 0x10);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedTurnRightArrow(Button *button) {
if (button->data2Val2 && !(_unkGameFlag & 4))
return 0;
gui_toggleButtonDisplayMode(81, 1);
_currentDirection = (++_currentDirection) & 3;
_sceneDefaultUpdate = 1;
runLevelScript(_currentBlock, 0x4000);
initTextFading(2, 0);
if (!_sceneDefaultUpdate)
gui_drawScene(0);
else
movePartySmoothScrollTurnRight(1);
gui_toggleButtonDisplayMode(81, 0);
runLevelScript(_currentBlock, 0x10);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedAttackButton(Button *button) {
return 1;
}
int LoLEngine::clickedMagicButton(Button *button) {
int c = button->data2Val2;
if (_characters[c].flags & 0x314C)
return 1;
if (notEnoughMagic(c, _availableSpells[_selectedSpell], 0))
return 1;
_characters[c].flags ^= 0x10;
gui_drawCharPortraitWithStats(c);
gui_initMagicSubmenu(c);
_unkCharNum = c;
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedMagicSubmenu(Button *button) {
int spellLevel = (_mouseY - 144) >> 3;
int c = button->data2Val2;
gui_enableDefaultPlayfieldButtons();
if (notEnoughMagic(c, _availableSpells[_selectedSpell], spellLevel)) {
_characters[c].flags &= 0xffef;
gui_drawCharPortraitWithStats(c);
} else {
_characters[c].flags |= 4;
_characters[c].flags &= 0xffef;
///
// TODO
///
/*if (processSpellcast(c, _availableSpells[_selectedSpell], spellLevel)) {
initCharacterUnkSub(c, 1, 8, 1);
sub_718F(c, 2, spellLevel * spellLevel);
} else {*/
_characters[c].flags &= 0xfffb;
gui_drawCharPortraitWithStats(c);
//}
}
_unkCharNum = -1;
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedScreen(Button *button) {
_characters[_unkCharNum].flags &= 0xffef;
gui_drawCharPortraitWithStats(_unkCharNum);
_unkCharNum = -1;
if (!(button->flags2 & 0x80)) {
if (button->flags2 & 0x100)
gui_triggerEvent(65);
else
gui_triggerEvent(66);
}
gui_enableDefaultPlayfieldButtons();
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedPortraitLeft(Button *button) {
disableSysTimer(2);
if (!_weaponsDisabled) {
_screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer2);
_screen->copyPage(0, 2);
_screen->copyRegionToBuffer(2, 0, 0, 320, 200, _pageBuffer1);
_updateFlags |= 0x0C;
gui_disableControls(1);
}
_selectedCharacter = button->data2Val2;
_weaponsDisabled = true;
gui_displayCharInventory(_selectedCharacter);
gui_enableCharInventoryButtons(_selectedCharacter);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedLiveMagicBarsLeft(Button *button) {
gui_highlightPortraitFrame(button->data2Val2);
_txt->printMessage(0, getLangString(0x4047), _characters[button->data2Val2].name, _characters[button->data2Val2].hitPointsCur,
_characters[button->data2Val2].hitPointsMax, _characters[button->data2Val2].magicPointsCur, _characters[button->data2Val2].magicPointsMax);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedPortraitEtcRight(Button *button) {
return 1;
}
int LoLEngine::clickedCharInventorySlot(Button *button) {
if (_itemInHand) {
uint16 sl = 1 << button->data2Val2;
int type = _itemProperties[_itemsInPlay[_itemInHand].itemPropertyIndex].type;
if (!(sl & type)) {
bool f = false;
for (int i = 0; i < 11; i++) {
if (!(type & (1 << i)))
continue;
_txt->printMessage(0, getLangString(i > 3 ? 0x418A : 0x418B), getLangString(_itemProperties[_itemsInPlay[_itemInHand].itemPropertyIndex].nameStringId), getLangString(_inventorySlotDesc[i]));
f = true;
}
if (!f)
_txt->printMessage(_itemsInPlay[_itemInHand].itemPropertyIndex == 231 ? 2 : 0, getLangString(0x418C));
return 1;
}
} else {
if (!_characters[_selectedCharacter].items[button->data2Val2]) {
_txt->printMessage(0, getLangString(_inventorySlotDesc[button->data2Val2] + 8));
return 1;
}
}
int ih = _itemInHand;
setHandItem(_characters[_selectedCharacter].items[button->data2Val2]);
_characters[_selectedCharacter].items[button->data2Val2] = ih;
gui_drawCharInventoryItem(button->data2Val2);
recalcCharacterStats(_selectedCharacter);
if (_itemInHand)
runItemScript(_selectedCharacter, _itemInHand, 0x100, 0, 0);
if (ih)
runItemScript(_selectedCharacter, ih, 0x80, 0, 0);
gui_drawCharInventoryItem(button->data2Val2);
gui_drawCharPortraitWithStats(_selectedCharacter);
gui_changeCharacterStats(_selectedCharacter);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedExitCharInventory(Button *button) {
_updateFlags &= 0xfff3;
gui_enableDefaultPlayfieldButtons();
_weaponsDisabled = false;
for (int i = 0; i < 4; i++) {
if (_charInventoryUnk & (1 << i))
_characters[i].flags &= 0xf1ff;
}
_screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer1);
int cp = _screen->setCurPage(2);
gui_drawAllCharPortraitsWithStats();
gui_drawInventory();
_screen->setCurPage(cp);
_screen->copyPage(2, 0);
_screen->updateScreen();
gui_enableControls();
_screen->copyBlockToPage(2, 0, 0, 320, 200, _pageBuffer2);
_lastCharInventory = -1;
updateSceneWindow();
enableSysTimer(2);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedUnk16(Button *button) {
return 1;
}
int LoLEngine::clickedScenePickupItem(Button *button) {
static const int8 checkX[] = { 0, 0, 1, 0, -1, -1, 1, 1, -1, 0, 2, 0, -2, -1, 1, 2, 2, 1, -1, -2, -2 };
static const int8 checkY[] = { 0, -1, 0, 1, 0, -1, -1, 1, 1, -2, 0, 2, 0, -2, -2, -1, 1, 2, 2, 1, -1 };
if (_updateFlags & 1)
return 0;
int cp = _screen->setCurPage(_sceneDrawPage1);
clickSceneSub1();
int p = 0;
for (int i = 0; i < 21; i++) {
p = _screen->getPagePixel(_screen->_curPage, _mouseX + checkX[i], _mouseY + checkY[i]);
if (p)
break;
}
_screen->setCurPage(cp);
if (!p)
return 0;
uint16 block = (p <= 128) ? calcNewBlockPosition(_currentBlock, _currentDirection) : _currentBlock;
int found = checkSceneForItems(&_levelBlockProperties[block], p &0x7f);
if (found != -1) {
foundItemSub(found, block);
setHandItem(found);
}
_sceneUpdateRequired = true;
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedInventorySlot(Button *button) {
int slot = _inventoryCurItem + button->data2Val2;
if (slot > 47)
slot -= 48;
uint16 slotItem = _inventory[slot];
int hItem = _itemInHand;
if ((_itemsInPlay[hItem].itemPropertyIndex == 281 || _itemsInPlay[slotItem].itemPropertyIndex == 281) &&
(_itemsInPlay[hItem].itemPropertyIndex == 220 || _itemsInPlay[slotItem].itemPropertyIndex == 220)) {
// merge ruby of truth
WSAMovie_v2 *wsa = new WSAMovie_v2(this, _screen);
wsa->open("truth.wsa", 0, 0);
wsa->setDrawPage(2);
wsa->setX(0);
wsa->setY(0);
_screen->hideMouse();
_inventory[slot] = 0;
gui_drawInventoryItem(button->data2Val2);
_screen->copyRegion(button->x, button->y - 3, button->x, button->y - 3, 25, 27, 0, 2);
KyraEngine_v1::snd_playSoundEffect(99);
for (int i = 0; i < 25; i++) {
_smoothScrollTimer = _system->getMillis() + 7 * _tickLength;
_screen->copyRegion(button->x, button->y - 3, 0, 0, 25, 27, 2, 2);
wsa->displayFrame(i, 0x4000);
_screen->copyRegion(0, 0, button->x, button->y - 3, 25, 27, 2, 0);
_screen->updateScreen();
delayUntil(_smoothScrollTimer);
}
_screen->showMouse();
wsa->close();
delete wsa;
deleteItem(slotItem);
deleteItem(hItem);
setHandItem(0);
_inventory[slot] = makeItem(280, 0, 0);
} else {
setHandItem(slotItem);
_inventory[slot] = hItem;
}
gui_drawInventoryItem(button->data2Val2);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedInventoryScroll(Button *button) {
int8 inc = (int8)button->data2Val2;
int shp = (inc == 1) ? 75 : 74;
if (button->flags2 & 0x1000)
inc *= 9;
_inventoryCurItem += inc;
gui_toggleButtonDisplayMode(shp, 1);
if (_inventoryCurItem < 0)
_inventoryCurItem += 48;
if (_inventoryCurItem > 47)
_inventoryCurItem -= 48;
gui_drawInventory();
gui_toggleButtonDisplayMode(shp, 0);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedWall(Button *button) {
int block = calcNewBlockPosition(_currentBlock, _currentDirection);
int dir = _currentDirection ^ 2;
uint8 type = _wllBuffer3[_levelBlockProperties[block].walls[dir]];
int res = 0;
switch (type) {
case 1:
res = clickedWallShape(block, dir);
break;
case 2:
res = clicked2(block, dir);
break;
case 3:
res = clicked3(block, dir);
break;
case 4:
res = clickedWallOnlyScript(block);
break;
case 5:
res = clickedDoorSwitch(block, dir);
break;
case 6:
res = clicked6(block, dir);
break;
default:
break;
}
return res;
2009-02-01 19:27:01 +00:00
}
int LoLEngine::clickedSequenceWindow(Button *button) {
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedScroll(Button *button) {
return 1;
}
int LoLEngine::clickedUnk23(Button *button) {
return 1;
}
int LoLEngine::clickedUnk24(Button *button) {
return 1;
}
int LoLEngine::clickedSceneDropItem(Button *button) {
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedOptions(Button *button) {
gui_toggleButtonDisplayMode(76, 1);
gui_toggleButtonDisplayMode(76, 0);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedRestParty(Button *button) {
gui_toggleButtonDisplayMode(77, 1);
gui_toggleButtonDisplayMode(77, 0);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedMoneyBox(Button *button) {
_txt->printMessage(0, getLangString(_credits == 1 ? 0x402D : 0x402E), _credits);
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedCompass(Button *button) {
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedAutomap(Button *button) {
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedLamp(Button *button) {
2009-02-01 19:27:01 +00:00
return 1;
}
int LoLEngine::clickedUnk32(Button *button) {
return 1;
}
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;
2009-02-01 19:27:01 +00:00
}
void GUI_LoL::processButton(Button *button) {
if (!button)
return;
if (button->flags & 8) {
if (button->flags & 0x10) {
// XXX
2009-02-01 19:27:01 +00:00
}
return;
}
2009-02-01 19:27:01 +00:00
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;
2009-02-01 19:27:01 +00:00
}
}
2009-02-01 19:27:01 +00:00
int mouseX = _vm->_mouseX;
int mouseY = _vm->_mouseY;
2009-02-01 19:27:01 +00:00
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 (buttonList) {
if (buttonList->flags & 8) {
buttonList = buttonList->nextButton;
continue;
}
buttonList->flags2 &= ~0x18;
buttonList->flags2 |= (buttonList->flags2 & 3) << 3;
int x = buttonList->x;
2009-02-01 19:27:01 +00:00
if (x < 0)
x += _screen->getScreenDim(buttonList->dimTableIndex)->w << 3;
x += _screen->getScreenDim(buttonList->dimTableIndex)->sx << 3;
2009-02-01 19:27:01 +00:00
int y = buttonList->y;
2009-02-01 19:27:01 +00:00
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;
2009-02-01 19:27:01 +00:00
}
if (!(buttonList->flags & 4)) {
buttonList->flags2 &= ~4;
buttonList->flags2 &= ~2;
}
break;
case 0x800:
if (!(buttonList->flags & 4)) {
buttonList->flags2 |= 4;
buttonList->flags2 |= 2;
2009-02-01 19:27:01 +00:00
}
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;
2009-02-01 19:27:01 +00:00
}
}
}
2009-02-01 19:27:01 +00:00
bool unk2 = false;
if ((flags & 0x2200) && progress) {
buttonList->flags2 |= 6;
if (!(buttonList->flags & 4) && !(buttonList->flags2 & 1)) {
unk2 = true;
buttonList->flags2 |= 1;
2009-02-01 19:27:01 +00:00
}
}
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;
2009-02-01 19:27:01 +00:00
}
if (_unknownButtonList == buttonList && (buttonList->flags & 0x40))
break;
buttonList = buttonList->nextButton;
2009-02-01 19:27:01 +00:00
}
if (!returnValue)
returnValue = inputFlag & 0x7FFF;
2009-02-01 19:27:01 +00:00
return returnValue;
}
} // end of namespace Kyra