aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dists/engine-data/kyra.datbin255660 -> 255891 bytes
-rw-r--r--engines/kyra/gui_lol.cpp387
-rw-r--r--engines/kyra/items_lol.cpp32
-rw-r--r--engines/kyra/lol.cpp100
-rw-r--r--engines/kyra/lol.h100
-rw-r--r--engines/kyra/resource.h14
-rw-r--r--engines/kyra/script_lol.cpp56
-rw-r--r--engines/kyra/staticres.cpp111
-rw-r--r--engines/kyra/text_lol.cpp21
-rw-r--r--engines/kyra/text_lol.h3
-rw-r--r--tools/create_kyradat/create_kyradat.cpp27
-rw-r--r--tools/create_kyradat/create_kyradat.h11
-rw-r--r--tools/create_kyradat/lol_cd.h12
-rw-r--r--tools/create_kyradat/misc.h10
14 files changed, 740 insertions, 144 deletions
diff --git a/dists/engine-data/kyra.dat b/dists/engine-data/kyra.dat
index d31c53dd4d..0ad8f84071 100644
--- a/dists/engine-data/kyra.dat
+++ b/dists/engine-data/kyra.dat
Binary files differ
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,