diff options
-rw-r--r-- | dists/engine-data/kyra.dat | bin | 255660 -> 255891 bytes | |||
-rw-r--r-- | engines/kyra/gui_lol.cpp | 387 | ||||
-rw-r--r-- | engines/kyra/items_lol.cpp | 32 | ||||
-rw-r--r-- | engines/kyra/lol.cpp | 100 | ||||
-rw-r--r-- | engines/kyra/lol.h | 100 | ||||
-rw-r--r-- | engines/kyra/resource.h | 14 | ||||
-rw-r--r-- | engines/kyra/script_lol.cpp | 56 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 111 | ||||
-rw-r--r-- | engines/kyra/text_lol.cpp | 21 | ||||
-rw-r--r-- | engines/kyra/text_lol.h | 3 | ||||
-rw-r--r-- | tools/create_kyradat/create_kyradat.cpp | 27 | ||||
-rw-r--r-- | tools/create_kyradat/create_kyradat.h | 11 | ||||
-rw-r--r-- | tools/create_kyradat/lol_cd.h | 12 | ||||
-rw-r--r-- | tools/create_kyradat/misc.h | 10 |
14 files changed, 740 insertions, 144 deletions
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat Binary files differindex d31c53dd4d..0ad8f84071 100644 --- a/dists/engine-data/kyra.dat +++ b/dists/engine-data/kyra.dat diff --git a/engines/kyra/gui_lol.cpp b/engines/kyra/gui_lol.cpp index cdef2bcd30..8581b47d86 100644 --- a/engines/kyra/gui_lol.cpp +++ b/engines/kyra/gui_lol.cpp @@ -82,16 +82,14 @@ 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 > 48) + if (item > 47) item -= 48; int flag = item & 1 ? 0 : 1; - _screen->hideMouse(); _screen->drawShape(_screen->_curPage, _gameShapes[4], x, 179, 0, flag); - if (_inventory[index]) - _screen->drawShape(_screen->_curPage, getItemIconShapePtr(_inventory[index]), x + 1, 180, 0, 0); - _screen->showMouse(); + if (_inventory[item]) + _screen->drawShape(_screen->_curPage, getItemIconShapePtr(_inventory[item]), x + 1, 180, 0, 0); } void LoLEngine::gui_drawScroll() { @@ -128,6 +126,198 @@ 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) @@ -171,11 +361,11 @@ void LoLEngine::gui_drawCharPortraitWithStats(int charNum) { // magic submenu closed int handIndex = 0; if (_characters[charNum].items[0]) { - if (_itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].unk8 != -1) + if (_itemProperties[_itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex].might != -1) handIndex = _itemsInPlay[_characters[charNum].items[0]].itemPropertyIndex; } - handIndex = _gameShapeMap[_itemProperties[handIndex].shpIndex << 1]; + handIndex = _gameShapeMap[(_itemProperties[handIndex].shpIndex << 1) + 1]; if (handIndex == 0x5a) { // draw raceClassSex specific hand shape handIndex = _characters[charNum].raceClassSex - 1; if (handIndex < 0) @@ -637,6 +827,13 @@ void LoLEngine::gui_enableSequenceButtons(int x, int y, int w, int h, int enable 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; @@ -659,6 +856,16 @@ void LoLEngine::gui_initCharacterControlButtons(int index, int xOffs) { 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() { } @@ -669,7 +876,7 @@ void LoLEngine::gui_initMagicSubmenu(int charNum) { gui_initButtonsFromList(_buttonList7); } -void LoLEngine::gui_initButton(int index, int x) { +void LoLEngine::gui_initButton(int index, int x, int y, int val) { Button *b = new Button; memset (b, 0, sizeof(Button)); @@ -703,7 +910,7 @@ void LoLEngine::gui_initButton(int index, int x) { b->dimTableIndex = _buttonData[index].screenDim; b->flags = _buttonData[index].buttonflags; - b->data2Val2 = _buttonData[index].index; + b->data2Val2 = (val != -1) ? (uint8)(val & 0xff) : _buttonData[index].index; if (index == 15) { // magic sub menu @@ -720,7 +927,7 @@ void LoLEngine::gui_initButton(int index, int x) { b->height = _sceneWindowButton.h - 1; } else { b->x = x != -1 ? x : _buttonData[index].x; - b->y = _buttonData[index].y; + b->y = y != -1 ? y : _buttonData[index].y; b->width = _buttonData[index].w - 1; b->height = _buttonData[index].h - 1; } @@ -877,6 +1084,21 @@ int LoLEngine::clickedScreen(Button *button) { } int LoLEngine::clickedPortraitLeft(Button *button) { + removeUnkFlags(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); + return 1; } @@ -891,11 +1113,79 @@ int LoLEngine::clickedPortraitEtcRight(Button *button) { return 1; } -int LoLEngine::clickedUnk14(Button *button) { +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; + + pickupItem(_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); + return 1; } -int LoLEngine::clickedUnk15(Button *button) { +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(); + setUnkFlags(2); + return 1; } @@ -903,21 +1193,88 @@ int LoLEngine::clickedUnk16(Button *button) { return 1; } -int LoLEngine::clickedUnk17(Button *button) { +int LoLEngine::clickedScene1(Button *button) { + if (_updateFlags & 1) + return 0; + int cp = _screen->setCurPage(_sceneDrawPage1); + + _screen->setCurPage(cp); + 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); + + pickupItem(0); + _inventory[slot] = makeItem(280, 0, 0); + } else { + pickupItem(slotItem); + _inventory[slot] = hItem; + } + + gui_drawInventoryItem(button->data2Val2); + return 1; } int LoLEngine::clickedInventoryScroll(Button *button) { - int8 dir = (int8) button->data2Val2; - int shp = (dir == 1) ? 75 : 74; + 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); + return 1; } diff --git a/engines/kyra/items_lol.cpp b/engines/kyra/items_lol.cpp index 122d20f93d..7c5267f164 100644 --- a/engines/kyra/items_lol.cpp +++ b/engines/kyra/items_lol.cpp @@ -25,6 +25,7 @@ #include "kyra/lol.h" +#include "kyra/screen_lol.h" namespace Kyra { @@ -63,7 +64,7 @@ void LoLEngine::giveCredits(int credits, int redraw) { if (redraw) { gui_drawMoneyBox(6); if (credits) - update(); + delay(_tickLength, 1); } credits -= t; } @@ -110,14 +111,14 @@ int LoLEngine::makeItem(int itemIndex, int curFrame, int flags) { if (testUnkItemFlags(r)) { if (_itemsInPlay[r].itemIndexUnk) _itemsInPlay[_itemsInPlay[r].itemIndexUnk].level = _itemsInPlay[r].level; - clearItemTableEntry(r); + deleteItem(r); slot = r; } else { int ii = _itemsInPlay[slot].itemIndexUnk; while (ii) { if (testUnkItemFlags(ii)) { _itemsInPlay[slot].itemIndexUnk = _itemsInPlay[ii].itemIndexUnk; - clearItemTableEntry(ii); + deleteItem(ii); slot = ii; break; } else { @@ -148,7 +149,7 @@ bool LoLEngine::testUnkItemFlags(int itemIndex) { } -void LoLEngine::clearItemTableEntry(int itemIndex) { +void LoLEngine::deleteItem(int itemIndex) { memset(&_itemsInPlay[itemIndex], 0, sizeof(ItemInPlay)); _itemsInPlay[itemIndex].shpCurFrame_flg |= 0x8000; } @@ -160,7 +161,7 @@ CLevelItem *LoLEngine::findItem(uint16 index) { return (CLevelItem *)&_itemsInPlay[index]; } -void LoLEngine::runItemScript(int reg1, int item, int reg0, int reg3, int reg4) { +void LoLEngine::runItemScript(int charNum, int item, int reg0, int reg3, int reg4) { EMCState scriptState; memset(&scriptState, 0, sizeof(EMCState)); @@ -172,7 +173,7 @@ void LoLEngine::runItemScript(int reg1, int item, int reg0, int reg3, int reg4) _emc->start(&scriptState, func); scriptState.regs[0] = reg0; - scriptState.regs[1] = reg1; + scriptState.regs[1] = charNum; scriptState.regs[2] = item; scriptState.regs[3] = reg3; scriptState.regs[4] = reg4; @@ -181,6 +182,25 @@ void LoLEngine::runItemScript(int reg1, int item, int reg0, int reg3, int reg4) _emc->run(&scriptState); } +void LoLEngine::pickupItem(int itemIndex) { + if (itemIndex && _itemProperties[_itemsInPlay[itemIndex].itemPropertyIndex].flags & 0x80) { + runItemScript(-1, itemIndex, 0x400, 0, 0); + if (_itemsInPlay[itemIndex].shpCurFrame_flg & 0x8000) + itemIndex = 0; + } + + int mouseOffs = 0; + + if (itemIndex && !(_screen->_drawGuiFlag & 0x200)) { + mouseOffs = 10; + if (!_hideControls || textEnabled()) + _txt->printMessage(0, getLangString(0x403E), getLangString(_itemProperties[_itemsInPlay[itemIndex].itemPropertyIndex].nameStringId)); + } + + _itemInHand = itemIndex; + _screen->setMouseCursor(mouseOffs, mouseOffs, getItemIconShapePtr(itemIndex)); +} + } // end of namespace Kyra diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index 3bb1565ddc..45283e9430 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -80,9 +80,10 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _itemsInPlay = 0; _itemProperties = 0; _itemInHand = 0; - memset(_inventory, 0, 48); + memset(_inventory, 0, 48 * sizeof(uint16)); _inventoryCurItem = 0; _hideControls = 0; + _lastCharInventory = -1; _itemIconShapes = _itemShapes = _gameShapes = _thrownShapes = _iceShapes = _fireballShapes = 0; _levelShpList = _levelDatList = 0; @@ -104,6 +105,7 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy _lampStatusTimer = 0xffffffff; _weaponsDisabled = false; + _charInventoryUnk = 0; _lastButtonShape = 0; _buttonPressTimer = 0; _selectedCharacter = 0; @@ -182,6 +184,10 @@ LoLEngine::LoLEngine(OSystem *system, const GameFlags &flags) : KyraEngine_v1(sy memset(_activeTim, 0, 10 * sizeof(TIM*)); memset(_activeVoiceFile, 0, sizeof(_activeVoiceFile)); + _pageBuffer1 = _pageBuffer2 = 0; + + memset(_charStatsTemp, 0, 5 * sizeof(int)); + _buttonData = 0; _activeButtons = 0; _preserveEvents = false; @@ -208,6 +214,9 @@ LoLEngine::~LoLEngine() { delete[] _itemProperties; delete[] _characters; + delete[] _pageBuffer1; + delete[] _pageBuffer2; + if (_itemIconShapes) { for (int i = 0; i < _numItemIconShapes; i++) delete[] _itemIconShapes[i]; @@ -333,6 +342,11 @@ Common::Error LoLEngine::init() { _screen->setAnimBlockPtr(10000); _screen->setScreenDim(0); + _pageBuffer1 = new uint8[0xfa00]; + memset(_pageBuffer1, 0, 0xfa00); + _pageBuffer2 = new uint8[0xfa00]; + memset(_pageBuffer2, 0, 0xfa00); + _itemsInPlay = new ItemInPlay[401]; memset(_itemsInPlay, 0, sizeof(ItemInPlay) * 400); @@ -711,9 +725,9 @@ void LoLEngine::startupNew() { _currentLevel = 1; giveCredits(41, 0); - _inventory[0] = makeItem(0xd8, 0, 0); - _inventory[1] = makeItem(0xd9, 0, 0); - _inventory[2] = makeItem(0xda, 0, 0); + _inventory[0] = makeItem(216, 0, 0); + _inventory[1] = makeItem(217, 0, 0); + _inventory[2] = makeItem(218, 0, 0); memset(_availableSpells, -1, 7); _availableSpells[0] = 0; @@ -763,7 +777,8 @@ void LoLEngine::runLoop() { _nextScriptFunc = 0; } - //processUnkAnimStructs(); + //updateTimers(); + //checkFloatingPointerRegions(); gui_updateInput(); @@ -778,8 +793,8 @@ void LoLEngine::runLoop() { checkForPartyDeath(_partyDeathFlag); _partyDeathFlag = -1; }*/ - - _system->delayMillis(_tickLength); + + delay(_tickLength); } } @@ -841,6 +856,9 @@ uint8 *LoLEngine::getTableEntry(uint8 *buffer, uint16 id) { } bool LoLEngine::addCharacter(int id) { + const uint16 *cdf[] = { _charDefsMan, _charDefsMan, _charDefsMan, _charDefsWoman, + _charDefsMan, _charDefsMan, _charDefsWoman, _charDefsKieran, _charDefsAkshel }; + int numChars = countActiveCharacters(); if (numChars == 4) return false; @@ -849,6 +867,7 @@ bool LoLEngine::addCharacter(int id) { for (; i < _charDefaultsSize; i++) { if (_charDefaults[i].id == id) { memcpy(&_characters[numChars], &_charDefaults[i], sizeof(LoLCharacter)); + _characters[numChars].defaultModifiers = cdf[i]; break; } } @@ -859,8 +878,7 @@ bool LoLEngine::addCharacter(int id) { _characters[numChars].rand = _rnd.getRandomNumberRng(1, 12); - i = 0; - for (; i < 11; i++) { + for (i = 0; i < 11; i++) { if (_characters[numChars].items[i]) { _characters[numChars].items[i] = makeItem(_characters[numChars].items[i], 0, 0); runItemScript(numChars, _characters[numChars].items[i], 0x80, 0, 0); @@ -1043,6 +1061,61 @@ void LoLEngine::faceFrameRefresh(int charNum) { _characters[charNum].curFaceFrame = 0; } +void LoLEngine::recalcCharacterStats(int charNum) { + for (int i = 0; i < 5; i++) + _charStatsTemp[i] = calculateCharacterStats(charNum, i); +} + +int LoLEngine::calculateCharacterStats(int charNum, int index) { + if (index == 0) { + // Might + int c = 0; + for (int i = 0; i < 8; i++) + c += _characters[charNum].itemsMight[i]; + if (c) + c += _characters[charNum].might2; + else + c = _characters[charNum].defaultModifiers[8]; + + c = (c * _characters[charNum].defaultModifiers[1]) >> 8; + c = (c * _characters[charNum].might3) >> 8; + + return c; + + } else if (index == 1) { + // Protection + return calculateProtection(charNum); + + } else if (index > 4) { + return -1; + + } else { + // Fighter + // Rogue + // Mage + index -= 2; + return _characters[charNum].skillLevels[index] + _characters[charNum].skillModifiers[index]; + } + + return 1; +} + +int LoLEngine::calculateProtection(int index) { + int c = 0; + if (index & 0x8000) { + // Monster + index &= 0x7fff; + c = (_cLevelItems[index].monsters->itemProtection * _cLevelItems[index].monsters->protection) >> 8; + } else { + // Character + c = _characters[index].itemsProtection + _characters[index].protection2; + c = (c * _characters[index].defaultModifiers[2]) >> 8; + c = (c * _characters[index].protection3) >> 8; + } + + return c; +} + void LoLEngine::setupScreenDims() { if (textEnabled()) { _screen->modifyScreenDim(4, 11, 124, 28, 45); @@ -1345,6 +1418,15 @@ int LoLEngine::snd_stopMusic() { return snd_playTrack(-1); } +void LoLEngine::delay(uint32 millis, bool cUpdate, bool isMainLoop) { + uint32 endTime = _system->getMillis() + millis; + while (endTime > _system->getMillis()) { + if (cUpdate) + update(); + _system->delayMillis(4); + } +} + void LoLEngine::runLoopSub4(int a) { cmzS7(a, _currentBlock); } diff --git a/engines/kyra/lol.h b/engines/kyra/lol.h index 9a8ed444ef..537a1af9bd 100644 --- a/engines/kyra/lol.h +++ b/engines/kyra/lol.h @@ -48,13 +48,9 @@ struct LoLCharacter { int16 id; uint8 curFaceFrame; uint8 nextFaceFrame; - uint16 field_12; - uint16 field_14; - uint8 field_16; - uint16 field_17[5]; - uint16 field_21; - uint16 field_23; - uint16 field_25; + uint8 field_12; + const uint16 *defaultModifiers; + uint16 itemsMight[8]; uint16 field_27[2]; uint8 field_2B; uint16 field_2C; @@ -63,7 +59,7 @@ struct LoLCharacter { uint16 field_32; uint16 field_34; uint8 field_36; - uint16 field_37; + uint16 itemsProtection; uint16 hitPointsCur; uint16 hitPointsMax; uint16 magicPointsCur; @@ -71,21 +67,15 @@ struct LoLCharacter { uint8 field_41; uint16 damageSuffered; uint16 weaponHit; - uint16 field_46; - uint16 field_48; - uint16 field_4A; - uint16 field_4C; + uint16 might3; + uint16 protection3; + uint16 might2; + uint16 protection2; uint16 rand; uint16 items[11]; - uint8 field_66[3]; - uint8 field_69[3]; - uint8 field_6C; - uint8 field_6D; - uint16 field_6E; - uint16 field_70; - uint16 field_72; - uint16 field_74; - uint16 field_76; + uint8 skillLevels[3]; + uint8 skillModifiers[3]; + int32 experiencePts[3]; uint8 arrayUnk2[5]; uint8 arrayUnk1[5]; }; @@ -113,11 +103,14 @@ struct LevelBlockProperty { struct MonsterProperty { uint8 id; uint8 maxWidth; - uint16 unk[9]; + uint16 field2[2]; + uint16 protection; + uint16 unk[6]; uint16 *pos; uint16 unk2[8]; uint16 unk3[8]; - uint16 unk4[2]; + uint16 itemProtection; + uint16 might; uint8 b; uint16 unk5[2]; uint16 unk6[5]; @@ -182,11 +175,11 @@ struct ItemProperty { uint16 nameStringId; uint8 shpIndex; uint16 flags; - uint16 unk5; + uint16 type; uint8 itemScriptFunc; - int8 unk8; - uint8 unk9; - uint8 unkA; + int8 might; + uint8 skill; + uint8 protection; uint16 unkB; uint8 unkD; }; @@ -368,6 +361,12 @@ private: void gui_drawCompass(); void gui_drawScroll(); void gui_highlightSelectedSpell(int unk); + void gui_displayCharInventory(int charNum); + void gui_printCharInventoryStats(int charNum); + void gui_printCharacterStats(int index, int redraw, int value); + void gui_changeCharacterStats(int charNum); + void gui_drawCharInventoryItem(int itemIndex); + void gui_drawBarGraph(int x, int y, int w, int h, int32 curVal, int32 maxVal, int col1, int col2); int gui_enableControls(); int gui_disableControls(int controlMode); @@ -382,6 +381,7 @@ private: int _compassDirection; int _compassUnk; int _compassDirectionIndex; + int _charInventoryUnk; const CompassDef *_compassDefs; int _compassDefsSize; @@ -390,13 +390,15 @@ private: void gui_triggerEvent(int eventType); void gui_enableDefaultPlayfieldButtons(); void gui_enableSequenceButtons(int x, int y, int w, int h, int enableFlags); + void gui_enableCharInventoryButtons(int charNum); void gui_resetButtonList(); void gui_initButtonsFromList(const int16 *list); void gui_initCharacterControlButtons(int index, int xOffs); + void gui_initCharInventorySpecialButtons(int charNum); void gui_initMagicScrollButtons(); void gui_initMagicSubmenu(int charNum); - void gui_initButton(int index, int x = -1); + void gui_initButton(int index, int x = -1, int y = -1, int val = -1); void gui_notifyButtonListChanged() { if (_gui) _gui->_buttonListChanged = true; } void assignButtonCallback(Button *button, int index); @@ -417,10 +419,10 @@ private: int clickedPortraitLeft(Button *button); int clickedLiveMagicBarsLeft(Button *button); int clickedPortraitEtcRight(Button *button); - int clickedUnk14(Button *button); - int clickedUnk15(Button *button); + int clickedCharInventorySlot(Button *button); + int clickedExitCharInventory(Button *button); int clickedUnk16(Button *button); - int clickedUnk17(Button *button); + int clickedScene1(Button *button); int clickedInventorySlot(Button *button); int clickedInventoryScroll(Button *button); int clickedUnk20(Button *button); @@ -584,6 +586,10 @@ private: void setCharFaceFrame(int charNum, int frameNum); void faceFrameRefresh(int charNum); + void recalcCharacterStats(int charNum); + int calculateCharacterStats(int charNum, int index); + int calculateProtection(int index); + LoLCharacter *_characters; uint16 _activeCharsXpos[3]; int _updateFlags; @@ -601,6 +607,8 @@ private: int _levelFlagUnk; int _unkCharNum; + int _charStatsTemp[5]; + uint8 **_monsterShapes; uint8 **_monsterPalettes; uint8 **_buf4; @@ -609,6 +617,17 @@ private: const LoLCharacter *_charDefaults; int _charDefaultsSize; + const uint16 *_charDefsMan; + int _charDefsManSize; + const uint16 *_charDefsWoman; + int _charDefsWomanSize; + const uint16 *_charDefsKieran; + int _charDefsKieranSize; + const uint16 *_charDefsAkshel; + int _charDefsAkshelSize; + const int32 *_expRequirements; + int _expRequirementsSize; + // lamp void resetLampStatus(); void setLampMode(bool lampOn); @@ -830,9 +849,11 @@ private: void giveCredits(int credits, int redraw); int makeItem(int itemIndex, int curFrame, int flags); bool testUnkItemFlags(int itemIndex); - void clearItemTableEntry(int itemIndex); + void deleteItem(int itemIndex); CLevelItem *findItem(uint16 index); - void runItemScript(int reg1, int item, int reg0, int reg3, int reg4); + void runItemScript(int charNum, int item, int reg0, int reg3, int reg4); + + void pickupItem(int itemIndex); uint8 _moneyColumnHeight[5]; uint16 _credits; @@ -844,14 +865,27 @@ private: uint16 _inventory[48]; int _inventoryCurItem; int _hideControls; + int _lastCharInventory; + + const uint8 *_charInvIndex; + int _charInvIndexSize; + const int8 *_charInvDefs; + int _charInvDefsSize; EMCData _itemScript; + const uint16 *_inventorySlotDesc; + int _inventorySlotDescSize; + // misc + void delay(uint32 millis, bool cUpdate = false, bool isMainLoop = false); void runLoopSub4(int a); void calcCoordinates(uint16 & x, uint16 & y, int block, uint16 xOffs, uint16 yOffs); bool characterSays(int track, int charId, bool redraw); + uint8 *_pageBuffer1; + uint8 *_pageBuffer2; + // spells bool notEnoughMagic(int charNum, int spellNum, int spellLevel); diff --git a/engines/kyra/resource.h b/engines/kyra/resource.h index 85be020ebc..d28001d893 100644 --- a/engines/kyra/resource.h +++ b/engines/kyra/resource.h @@ -220,6 +220,16 @@ enum kKyraResources { //lolIngameADLSfxIndex, lolSpellProperties, lolGameShapeMap, + lolCharInvIndex, + lolCharInvDefs, + lolCharDefsMan, + lolCharDefsWoman, + lolCharDefsKieran, + //lolCharDefsUnk, + lolCharDefsAkshel, + lolExpRequirements, + lolInventoryDesc, + lolLevelShpList, lolLevelDatList, lolCompassDefs, @@ -291,6 +301,7 @@ public: const SpellProperty *loadSpellData(int id, int &entries); const CompassDef *loadCompassData(int id, int &entries); const uint16 *loadRawDataBe16(int id, int &entries); + const uint32 *loadRawDataBe32(int id, int &entries); const ButtonDef *loadButtonDefs(int id, int &entries); // use '-1' to prefetch/unload all ids @@ -327,6 +338,7 @@ private: bool loadSpellData(const char *filename, void *&ptr, int &size); bool loadCompassData(const char *filename, void *&ptr, int &size); bool loadRawDataBe16(const char *filename, void *&ptr, int &size); + bool loadRawDataBe32(const char *filename, void *&ptr, int &size); bool loadButtonDefs(const char *filename, void *&ptr, int &size); void freeRawData(void *&ptr, int &size); @@ -341,6 +353,7 @@ private: void freeSpellData(void *&ptr, int &size); void freeCompassData(void *&ptr, int &size); void freeRawDataBe16(void *&ptr, int &size); + void freeRawDataBe32(void *&ptr, int &size); void freeButtonDefs(void *&ptr, int &size); const char *getFilename(const char *name); @@ -362,6 +375,7 @@ private: lolSpellData, lolCompassData, lolRawDataBe16, + lolRawDataBe32, lolButtonData }; diff --git a/engines/kyra/script_lol.cpp b/engines/kyra/script_lol.cpp index bd7696c1e4..2c4e5cc06a 100644 --- a/engines/kyra/script_lol.cpp +++ b/engines/kyra/script_lol.cpp @@ -155,11 +155,11 @@ int LoLEngine::olol_setItemProperty(EMCState *script) { tmp->nameStringId = stackPos(1); tmp->shpIndex = stackPos(2); - tmp->unk5 = stackPos(3); + tmp->type = stackPos(3); tmp->itemScriptFunc = stackPos(4); - tmp->unk8 = stackPos(5); - tmp->unk9 = stackPos(6); - tmp->unkA = stackPos(7); + tmp->might = stackPos(5); + tmp->skill = stackPos(6); + tmp->protection = stackPos(7); tmp->flags = stackPos(8); tmp->unkB = stackPos(9); return 1; @@ -198,13 +198,15 @@ int LoLEngine::olol_getItemPara(EMCState *script) { case 8: return p->shpIndex; case 9: - return p->unk5; + return p->type; case 10: return p->itemScriptFunc; case 11: + return p->might; case 12: + return p->skill; case 13: - return p[stackPos(1)].unkB & 0x0f; + return p->protection; case 14: return p->unkB; case 15: @@ -212,7 +214,7 @@ int LoLEngine::olol_getItemPara(EMCState *script) { case 16: return p->flags; case 17: - return (p->unk9 << 8) | p->unk8; + return (p->skill << 8) | p->might; default: break; } @@ -245,22 +247,22 @@ int LoLEngine::olol_getCharacterStat(EMCState *script) { return c->magicPointsMax; case 9: - return c->field_37; + return c->itemsProtection; case 10: return c->items[d]; case 11: - return c->field_66[d] + c->field_69[d]; + return c->skillLevels[d] + c->skillModifiers[d]; case 12: return c->field_27[d]; case 13: - return (d & 0x80) ? c->field_25 : c->field_17[d]; + return (d & 0x80) ? c->itemsMight[7] : c->itemsMight[d]; case 14: - return c->field_69[d]; + return c->skillModifiers[d]; case 15: return c->id; @@ -304,7 +306,7 @@ int LoLEngine::olol_setCharacterStat(EMCState *script) { break; case 9: - c->field_37 = e; + c->itemsProtection = e; break; case 10: @@ -312,7 +314,7 @@ int LoLEngine::olol_setCharacterStat(EMCState *script) { break; case 11: - c->field_66[d] = e; + c->skillLevels[d] = e; break; case 12: @@ -321,13 +323,13 @@ int LoLEngine::olol_setCharacterStat(EMCState *script) { case 13: if (d & 0x80) - c->field_25 = e; + c->itemsMight[7] = e; else - c->field_17[d] = e; + c->itemsMight[d] = e; break; case 14: - c->field_69[d] = e; + c->skillModifiers[d] = e; break; default: @@ -520,15 +522,15 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) { l->maxWidth = shpWidthMax; - l->unk[0] = (stackPos(2) << 8) / 100; - l->unk[1] = 256; - l->unk[2] = (stackPos(3) << 8) / 100; - l->unk[3] = stackPos(4); - l->unk[4] = (stackPos(5) << 8) / 100; - l->unk[5] = (stackPos(6) << 8) / 100; - l->unk[6] = (stackPos(7) << 8) / 100; - l->unk[7] = (stackPos(8) << 8) / 100; - l->unk[8] = 0; + l->field2[0] = (stackPos(2) << 8) / 100; + l->field2[1] = 256; + l->protection = (stackPos(3) << 8) / 100; + l->unk[0] = stackPos(4); + l->unk[1] = (stackPos(5) << 8) / 100; + l->unk[2] = (stackPos(6) << 8) / 100; + l->unk[3] = (stackPos(7) << 8) / 100; + l->unk[4] = (stackPos(8) << 8) / 100; + l->unk[5] = 0; for (int i = 0; i < 8; i++) { l->unk2[i] = stackPos(9 + i); @@ -536,8 +538,8 @@ int LoLEngine::olol_loadMonsterProperties(EMCState *script) { } l->pos = &l->unk[0]; - l->unk4[0] = stackPos(25); - l->unk4[1] = stackPos(26); + l->itemProtection = stackPos(25); + l->might = stackPos(26); l->b = 1; l->unk5[0] = stackPos(27); l->unk5[1] = stackPos(28); diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index e5b67c572a..df5d4ee08b 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -44,7 +44,7 @@ namespace Kyra { -#define RESFILE_VERSION 38 +#define RESFILE_VERSION 39 namespace { bool checkKyraDat(Common::SeekableReadStream *file) { @@ -226,6 +226,7 @@ bool StaticResource::init() { { lolSpellData, proc(loadSpellData), proc(freeSpellData) }, { lolCompassData, proc(loadCompassData), proc(freeCompassData) }, { lolRawDataBe16, proc(loadRawDataBe16), proc(freeRawDataBe16) }, + { lolRawDataBe32, proc(loadRawDataBe32), proc(freeRawDataBe32) }, { lolButtonData, proc(loadButtonDefs), proc(freeButtonDefs) }, { 0, 0, 0 } @@ -378,6 +379,16 @@ bool StaticResource::init() { { lolIngameMT32SfxIndex, kRawData, "SFX_MT32.MAP" }, { lolSpellProperties, lolSpellData, "SPELLS.DEF" }, { lolGameShapeMap, kRawData, "GAMESHP.MAP" }, + { lolCharInvIndex, kRawData, "CHARINV.MAP" }, + { lolCharInvDefs, kRawData, "CHARINV.DEF" }, + { lolCharDefsMan, lolRawDataBe16, "CHMAN.DEF" }, + { lolCharDefsWoman, lolRawDataBe16, "CHWOMAN.DEF" }, + { lolCharDefsKieran, lolRawDataBe16, "CHKIERAN.DEF" }, + //{ lolCharDefsUnk, lolRawDataBe16, "CHUNK.DEF" }, + { lolCharDefsAkshel, lolRawDataBe16, "CHAKSHEL.DEF" }, + { lolExpRequirements, lolRawDataBe32, "EXPERIENCE.DEF" }, + { lolInventoryDesc, lolRawDataBe16, "INVDESC.DEF" }, + { lolLevelShpList, kStringList, "SHPFILES.TXT" }, { lolLevelDatList, kStringList, "DATFILES.TXT" }, { lolCompassDefs, lolCompassData, "COMPASS.DEF" }, @@ -498,6 +509,10 @@ const uint16 *StaticResource::loadRawDataBe16(int id, int &entries) { return (const uint16*)getData(id, lolRawDataBe16, entries); } +const uint32 *StaticResource::loadRawDataBe32(int id, int &entries) { + return (const uint32*)getData(id, lolRawDataBe32, entries); +} + const ButtonDef *StaticResource::loadButtonDefs(int id, int &entries) { return (const ButtonDef*)getData(id, lolButtonData, entries); } @@ -948,14 +963,10 @@ bool StaticResource::loadCharData(const char *filename, void *&ptr, int &size) { t->id = file->readSint16LE(); t->curFaceFrame = file->readByte(); t->nextFaceFrame = file->readByte(); - t->field_12 = file->readUint16LE(); - t->field_14 = file->readUint16LE(); - t->field_16 = file->readByte(); - for (int ii = 0; ii < 5; ii++) - t->field_17[ii] = file->readUint16LE(); - t->field_21 = file->readUint16LE(); - t->field_23 = file->readUint16LE(); - t->field_25 = file->readUint16LE(); + t->field_12 = file->readByte(); + file->readUint32LE(); + for (int ii = 0; ii < 8; ii++) + t->itemsMight[ii] = file->readUint16LE(); for (int ii = 0; ii < 2; ii++) t->field_27[ii] = file->readUint16LE(); t->field_2B = file->readByte(); @@ -965,7 +976,7 @@ bool StaticResource::loadCharData(const char *filename, void *&ptr, int &size) { t->field_32 = file->readUint16LE(); t->field_34 = file->readUint16LE(); t->field_36 = file->readByte(); - t->field_37 = file->readUint16LE(); + t->itemsProtection = file->readUint16LE(); t->hitPointsCur = file->readUint16LE();; t->hitPointsMax = file->readUint16LE();; t->magicPointsCur = file->readUint16LE();; @@ -973,24 +984,19 @@ bool StaticResource::loadCharData(const char *filename, void *&ptr, int &size) { t->field_41 = file->readByte(); t->damageSuffered = file->readUint16LE(); t->weaponHit = file->readUint16LE(); - t->field_46 = file->readUint16LE(); - t->field_48 = file->readUint16LE(); - t->field_4A = file->readUint16LE(); - t->field_4C = file->readUint16LE(); + t->might3 = file->readUint16LE(); + t->protection3 = file->readUint16LE(); + t->might2 = file->readUint16LE(); + t->protection2 = file->readUint16LE(); t->rand = file->readUint16LE(); for (int ii = 0; ii < 11; ii++) t->items[ii] = file->readUint16LE(); for (int ii = 0; ii < 3; ii++) - t->field_66[ii] = file->readByte(); + t->skillLevels[ii] = file->readByte(); + for (int ii = 0; ii < 3; ii++) + t->skillModifiers[ii] = file->readByte(); for (int ii = 0; ii < 3; ii++) - t->field_69[ii] = file->readByte(); - t->field_6C = file->readByte(); - t->field_6D = file->readByte(); - t->field_6E = file->readUint16LE(); - t->field_70 = file->readUint16LE(); - t->field_72 = file->readUint16LE(); - t->field_74 = file->readUint16LE(); - t->field_76 = file->readUint16LE(); + t->experiencePts[ii] = file->readUint32LE(); for (int ii = 0; ii < 5; ii++) t->arrayUnk2[ii] = file->readByte(); for (int ii = 0; ii < 5; ii++) @@ -1071,6 +1077,24 @@ bool StaticResource::loadRawDataBe16(const char *filename, void *&ptr, int &size return true; } +bool StaticResource::loadRawDataBe32(const char *filename, void *&ptr, int &size) { + Common::SeekableReadStream *file = getFile(filename); + + if (!file) + return false; + + size = file->size() >> 2; + + uint32 *r = new uint32[size]; + + for (int i = 0; i < size; i++) + r[i] = file->readUint32BE(); + + ptr = r; + + return true; +} + bool StaticResource::loadButtonDefs(const char *filename, void *&ptr, int &size) { Common::SeekableReadStream *file = getFile(filename); @@ -1194,6 +1218,13 @@ void StaticResource::freeRawDataBe16(void *&ptr, int &size) { size = 0; } +void StaticResource::freeRawDataBe32(void *&ptr, int &size) { + uint32 *data = (uint32*)ptr; + delete[] data; + ptr = 0; + size = 0; +} + void StaticResource::freeButtonDefs(void *&ptr, int &size) { ButtonDef *d = (ButtonDef*)ptr; delete[] d; @@ -1693,6 +1724,14 @@ void LoLEngine::initStaticResource() { //_ingameADLSoundIndex = _staticres->loadRawData(lolIngameADLSfxIndex, _ingameADLSoundIndexSize); _spellProperties = _staticres->loadSpellData(lolSpellProperties, _spellPropertiesSize); _gameShapeMap = (const int8*)_staticres->loadRawData(lolGameShapeMap, _gameShapeMapSize); + _charInvIndex = _staticres->loadRawData(lolCharInvIndex, _charInvIndexSize); + _charInvDefs = (const int8*)_staticres->loadRawData(lolCharInvDefs, _charInvDefsSize); + _charDefsMan = _staticres->loadRawDataBe16(lolCharDefsMan, _charDefsManSize); + _charDefsWoman = _staticres->loadRawDataBe16(lolCharDefsWoman, _charDefsWomanSize); + _charDefsKieran = _staticres->loadRawDataBe16(lolCharDefsKieran, _charDefsKieranSize); + _charDefsAkshel = _staticres->loadRawDataBe16(lolCharDefsAkshel, _charDefsAkshelSize); + _expRequirements = (const int32*)_staticres->loadRawDataBe32(lolExpRequirements, _expRequirementsSize); + _inventorySlotDesc = _staticres->loadRawDataBe16(lolInventoryDesc, _inventorySlotDescSize); _levelShpList = _staticres->loadStrings(lolLevelShpList, _levelShpListSize); _levelDatList = _staticres->loadStrings(lolLevelDatList, _levelDatListSize); _compassDefs = _staticres->loadCompassData(lolCompassDefs, _compassDefsSize); @@ -1779,23 +1818,23 @@ void LoLEngine::assignButtonCallback(Button *button, int index) { cb(clickedPortraitEtcRight), cb(clickedPortraitEtcRight), cb(clickedPortraitEtcRight), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk14), - cb(clickedUnk15), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedCharInventorySlot), + cb(clickedExitCharInventory), cb(clickedUnk16), cb(clickedUnk16), cb(clickedUnk16), cb(clickedUnk16), - cb(clickedUnk17), + cb(clickedScene1), cb(clickedInventorySlot), cb(clickedInventorySlot), cb(clickedInventorySlot), diff --git a/engines/kyra/text_lol.cpp b/engines/kyra/text_lol.cpp index 48d67b7dda..9f724b9486 100644 --- a/engines/kyra/text_lol.cpp +++ b/engines/kyra/text_lol.cpp @@ -45,9 +45,6 @@ TextDisplayer_LoL::TextDisplayer_LoL(LoLEngine *vm, Screen_LoL *screen) : _vm(vm _currentLine = new char[85]; memset(_currentLine, 0, 85); - - _pageBuffer1 = new uint8[0xfa00]; - _pageBuffer2 = new uint8[0xfa00]; } TextDisplayer_LoL::~TextDisplayer_LoL() { @@ -55,22 +52,20 @@ TextDisplayer_LoL::~TextDisplayer_LoL() { delete[] _out; delete[] _backupBuffer; delete[] _currentLine; - delete[] _pageBuffer1; - delete[] _pageBuffer2; } void TextDisplayer_LoL::setupField(bool mode) { if (_vm->textEnabled()) { if (mode) { - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer1); + _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer1); _screen->copyRegion(80, 142, 0, 0, 240, 37, 0, 3, Screen::CR_NO_P_CHECK); - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer2); - _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer1); + _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer2); + _screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer1); } else { _screen->clearDim(4); int cp = _screen->setCurPage(2); - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer1); - _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer2); + _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer1); + _screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer2); _screen->copyRegion(80, 142, 0, 0, 240, 37, 3, 2, Screen::CR_NO_P_CHECK); for (int i = 177; i > 141; i--) { @@ -83,7 +78,7 @@ void TextDisplayer_LoL::setupField(bool mode) { _vm->delayUntil(endTime); } - _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer1); + _screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer1); _screen->setCurPage(cp); _vm->_updateFlags &= 0xfffd; @@ -101,7 +96,7 @@ void TextDisplayer_LoL::expandField() { _vm->_textColourFlag = 0; //_vm->toggleGuiUnk(11, 0); _screen->clearDim(3); - _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _pageBuffer1); + _screen->copyRegionToBuffer(3, 0, 0, 320, 200, _vm->_pageBuffer1); _screen->copyRegion(83, 140, 0, 0, 235, 3, 0, 2, Screen::CR_NO_P_CHECK); for (int i = 140; i < 177; i++) { @@ -113,7 +108,7 @@ void TextDisplayer_LoL::expandField() { _vm->delayUntil(endTime); } - _screen->copyBlockToPage(3, 0, 0, 320, 200, _pageBuffer1); + _screen->copyBlockToPage(3, 0, 0, 320, 200, _vm->_pageBuffer1); _vm->_updateFlags |= 2; } else { diff --git a/engines/kyra/text_lol.h b/engines/kyra/text_lol.h index 730ff6df9c..a6232805b9 100644 --- a/engines/kyra/text_lol.h +++ b/engines/kyra/text_lol.h @@ -93,9 +93,6 @@ private: uint8 _colour2; bool _colour1prot; - uint8 *_pageBuffer1; - uint8 *_pageBuffer2; - LoLEngine *_vm; Screen_LoL *_screen; }; diff --git a/tools/create_kyradat/create_kyradat.cpp b/tools/create_kyradat/create_kyradat.cpp index 3b1b43a2b1..4ec75d653c 100644 --- a/tools/create_kyradat/create_kyradat.cpp +++ b/tools/create_kyradat/create_kyradat.cpp @@ -31,7 +31,7 @@ #include "md5.h" enum { - kKyraDatVersion = 38, + kKyraDatVersion = 39, kIndexSize = 12 }; @@ -74,6 +74,7 @@ bool extractPaddedStrings(PAKFile &out, const Game *g, const byte *data, const u bool extractRaw16to8(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0); bool extractMrShapeAnimData(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0); bool extractRaw16(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0); +bool extractRaw32(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0); bool extractLolButtonDefs(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch = 0); int extractHofSeqData_checkString(const void *ptr, uint8 checkSize); @@ -100,6 +101,7 @@ const ExtractType extractTypeTable[] = { { k3TypeShpData, extractMrShapeAnimData, createFilename }, { lolTypeRaw16, extractRaw16, createFilename }, + { lolTypeRaw32, extractRaw32, createFilename }, { lolTypeButtonDef, extractLolButtonDefs, createFilename }, { -1, 0, 0} @@ -274,6 +276,15 @@ const ExtractFilename extractFilenames[] = { //{ lolADLSfxIndex, kTypeRawData, "SFX_ADL.MAP" }, { lolSpellProperties, kTypeRawData, "SPELLS.DEF" }, { lolGameShapeMap, kTypeRawData, "GAMESHP.MAP" }, + { lolCharInvIndex, k3TypeRaw16to8, "CHARINV.MAP" }, + { lolCharInvDefs, kTypeRawData, "CHARINV.DEF" }, + { lolCharDefsMan, lolTypeRaw16, "CHMAN.DEF" }, + { lolCharDefsWoman, lolTypeRaw16, "CHWOMAN.DEF" }, + { lolCharDefsKieran, lolTypeRaw16, "CHKIERAN.DEF" }, + //{ lolCharDefsUnk, lolTypeRaw16, "CHUNK.DEF" }, + { lolCharDefsAkshel, lolTypeRaw16, "CHAKSHEL.DEF" }, + { lolExpRequirements, lolTypeRaw32, "EXPERIENCE.DEF" }, + { lolInventoryDesc, lolTypeRaw16, "INVDESC.DEF" }, { lolLevelShpList, kTypeStringList, "SHPFILES.TXT" }, { lolLevelDatList, kTypeStringList, "DATFILES.TXT" }, { lolCompassDefs, k3TypeRaw16to8, "COMPASS.DEF" }, @@ -1083,6 +1094,20 @@ bool extractRaw16(PAKFile &out, const Game *g, const byte *data, const uint32 si return out.addFile(filename, buffer, size); } +bool extractRaw32(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { + uint8 *buffer = new uint8[size]; + const uint8 *src = data; + uint8 *dst = buffer; + + for (uint32 i = 0; i < (size >> 2); i++) { + WRITE_BE_UINT32(dst, READ_LE_UINT32(src)); + src += 4; + dst += 4; + } + + return out.addFile(filename, buffer, size); +} + bool extractLolButtonDefs(PAKFile &out, const Game *g, const byte *data, const uint32 size, const char *filename, int fmtPatch) { int num = size / 22; uint8 *buffer = new uint8[size]; diff --git a/tools/create_kyradat/create_kyradat.h b/tools/create_kyradat/create_kyradat.h index 5be72e363f..ecd7bdd81e 100644 --- a/tools/create_kyradat/create_kyradat.h +++ b/tools/create_kyradat/create_kyradat.h @@ -185,6 +185,16 @@ enum kExtractID { //lolADLSfxIndex, lolSpellProperties, lolGameShapeMap, + lolCharInvIndex, + lolCharInvDefs, + lolCharDefsMan, + lolCharDefsWoman, + lolCharDefsKieran, + //lolCharDefsUnk, + lolCharDefsAkshel, + lolExpRequirements, + lolInventoryDesc, + lolLevelShpList, lolLevelDatList, lolCompassDefs, @@ -322,6 +332,7 @@ enum kExtractType { k3TypeShpData, lolTypeRaw16, + lolTypeRaw32, lolTypeButtonDef }; diff --git a/tools/create_kyradat/lol_cd.h b/tools/create_kyradat/lol_cd.h index 3bab171b9f..66f49d887d 100644 --- a/tools/create_kyradat/lol_cd.h +++ b/tools/create_kyradat/lol_cd.h @@ -7,7 +7,17 @@ const ExtractEntry lolCDFile2[] = { { lolMT32SfxIndex, 0x0002B110, 0x0002B20A }, //{ lolADLSfxIndex, 0x0002B210, 0x0002B30A }, { lolSpellProperties, 0x0002B5D0, 0x0002B6E8 }, - { lolGameShapeMap, 0x0002B35D, 0x0002B52C }, + { lolGameShapeMap, 0x0002B35C, 0x0002B470 }, + { lolCharInvIndex, 0x0002B470, 0x0002B47A }, + { lolCharInvDefs, 0x0002B47A, 0x0002B4D2 }, + { lolCharDefsMan, 0x0002B4D2, 0x0002B4E4 }, + { lolCharDefsWoman, 0x0002B4E4, 0x0002B4F6 }, + { lolCharDefsKieran, 0x0002B4F6, 0x0002B508 }, + //{ lolCharDefsUnk, 0x0002B508, 0x0002B51A }, + { lolCharDefsAkshel, 0x0002B51A, 0x0002B52C }, + { lolExpRequirements, 0x0002B830, 0x0002B85C }, + { lolInventoryDesc, 0x00032706, 0x0003271C }, + { lolLevelShpList, 0x00032826, 0x000328A5 }, { lolLevelDatList, 0x000328A5, 0x000329A4 }, { lolCompassDefs, 0x000286C4, 0x000287C4 }, diff --git a/tools/create_kyradat/misc.h b/tools/create_kyradat/misc.h index d565c7504a..2b865b34a4 100644 --- a/tools/create_kyradat/misc.h +++ b/tools/create_kyradat/misc.h @@ -491,6 +491,16 @@ const int lolCDFile2Need[] = { //lolADLSfxIndex, lolSpellProperties, lolGameShapeMap, + lolCharInvIndex, + lolCharInvDefs, + lolCharDefsMan, + lolCharDefsWoman, + lolCharDefsKieran, + //lolCharDefsUnk, + lolCharDefsAkshel, + lolExpRequirements, + lolInventoryDesc, + lolLevelShpList, lolLevelDatList, lolCompassDefs, |