aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/gui_v2.cpp442
-rw-r--r--engines/kyra/items_v2.cpp12
-rw-r--r--engines/kyra/kyra_v2.cpp53
-rw-r--r--engines/kyra/kyra_v2.h57
-rw-r--r--engines/kyra/screen.cpp18
-rw-r--r--engines/kyra/screen.h2
-rw-r--r--engines/kyra/screen_v2.cpp3
-rw-r--r--engines/kyra/staticres.cpp79
8 files changed, 641 insertions, 25 deletions
diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp
index 4c5fb8d840..bbb51adda5 100644
--- a/engines/kyra/gui_v2.cpp
+++ b/engines/kyra/gui_v2.cpp
@@ -220,5 +220,447 @@ void KyraEngine_v2::gui_printString(const char *format, int x, int y, int col1,
_screen->printText(string, x, y, col1, col2);
}
+#pragma mark -
+
+void KyraEngine_v2::loadButtonShapes() {
+ const uint8 *src = _screen->getCPagePtr(3);
+ _screen->loadBitmap("_BUTTONS.CSH", 3, 3, 0);
+ _buttonShapes[0] = _screen->makeShapeCopy(src, 0);
+ _buttonShapes[1] = _screen->makeShapeCopy(src, 1);
+ _buttonShapes[2] = _screen->makeShapeCopy(src, 2);
+ _buttonShapes[3] = _screen->makeShapeCopy(src, 3);
+ _buttonShapes[4] = _screen->makeShapeCopy(src, 4);
+ _buttonShapes[5] = _screen->makeShapeCopy(src, 5);
+ _buttonShapes[6] = _screen->makeShapeCopy(src, 6);
+ _buttonShapes[7] = _screen->makeShapeCopy(src, 7);
+ _buttonShapes[8] = _screen->makeShapeCopy(src, 6);
+ _buttonShapes[9] = _screen->makeShapeCopy(src, 7);
+ _buttonShapes[10] = _screen->makeShapeCopy(src, 10);
+ _buttonShapes[11] = _screen->makeShapeCopy(src, 11);
+ _buttonShapes[16] = _screen->makeShapeCopy(src, 16);
+ _buttonShapes[17] = _screen->makeShapeCopy(src, 17);
+ _buttonShapes[18] = _screen->makeShapeCopy(src, 18);
+}
+
+KyraEngine_v2::Button *KyraEngine_v2::addButtonToList(Button *list, Button *newButton) {
+ if (!newButton)
+ return list;
+
+ newButton->nextButton = 0;
+
+ if (list) {
+ Button *cur = list;
+ while (cur->nextButton)
+ cur = cur->nextButton;
+ cur->nextButton = newButton;
+ } else {
+ list = newButton;
+ }
+
+ _buttonListChanged = true;
+ return list;
+}
+
+void KyraEngine_v2::processButton(Button *button) {
+ if (!button)
+ return;
+
+ if (button->flags & 8) {
+ if (button->flags & 0x10) {
+ // XXX
+ }
+ return;
+ }
+
+ int entry = button->flags2 & 5;
+
+ byte val1 = 0, val2 = 0, val3 = 0;
+ uint8 *dataPtr = 0;
+ if (entry == 1) {
+ val1 = button->data1Val1;
+ dataPtr = button->shapePtr1;
+ val2 = button->data1Val2;
+ val3 = button->data1Val3;
+ } else if (entry == 4 || entry == 5) {
+ val1 = button->data2Val1;
+ dataPtr = button->shapePtr2;
+ val2 = button->data2Val2;
+ val3 = button->data2Val3;
+ } else {
+ val1 = button->data0Val1;
+ dataPtr = button->shapePtr0;
+ val2 = button->data0Val2;
+ val3 = button->data0Val3;
+ }
+
+ int x = 0, y = 0, x2 = 0, y2 = 0;
+
+ x = button->x;
+ if (x < 0)
+ x += _screen->getScreenDim(button->dimTableIndex)->w << 3;
+ x += _screen->getScreenDim(button->dimTableIndex)->sx << 3;
+ x2 = x + button->width - 1;
+
+ y = button->y;
+ if (y < 0)
+ y += _screen->getScreenDim(button->dimTableIndex)->h << 3;
+ y += _screen->getScreenDim(button->dimTableIndex)->sy << 3;
+ y2 = y + button->height - 1;
+
+ switch (val1 - 1) {
+ case 0:
+ _screen->hideMouse();
+ _screen->drawShape(_screen->_curPage, dataPtr, x, y, button->dimTableIndex, 0x10);
+ _screen->showMouse();
+ break;
+
+ case 1:
+ _screen->hideMouse();
+ _screen->printText((const char*)dataPtr, x, y, val2, val3);
+ _screen->showMouse();
+ break;
+
+ case 3:
+ warning("STUB processButton with func 3");
+ //XXX
+ break;
+
+ case 4:
+ warning("STUB processButton with func 4");
+ _screen->hideMouse();
+ //XXX
+ _screen->showMouse();
+ break;
+
+ case 5:
+ _screen->hideMouse();
+ _screen->fillRect(x, y, x2, y2, val2, -1, true);
+ _screen->showMouse();
+ break;
+
+ default:
+ break;
+ }
+
+ _screen->updateScreen();
+}
+
+int KyraEngine_v2::processButtonList(Button *buttonList, uint16 inputFlag) {
+ if (!buttonList)
+ return inputFlag & 0x7FFF;
+
+ if (_backUpButtonList != buttonList || _buttonListChanged) {
+ _unknownButtonList = 0;
+ //XXX_gui_unk2 (very strange code, maybe keyboard related? or some non interactive input...)
+ _backUpButtonList = buttonList;
+ _buttonListChanged = false;
+
+ while (buttonList) {
+ processButton(buttonList);
+ buttonList = buttonList->nextButton;
+ }
+ }
+
+ int mouseX = _mouseX;
+ int mouseY = _mouseY;
+
+ uint16 flags = 0;
+
+ if (1/*!_screen_cursorDisable*/) {
+ uint16 inFlags = inputFlag & 0xFF;
+ uint16 temp = 0;
+
+ if (inFlags == 199)
+ temp = 0x1000;
+ else if (inFlags == 198)
+ temp = 0x0100;
+
+ if (inputFlag & 0x800)
+ temp <<= 2;
+
+ // the original did some flag hackery here, this works fine too
+ flags |= temp;
+ }
+
+ buttonList = _backUpButtonList;
+ if (_unknownButtonList) {
+ buttonList = _unknownButtonList;
+ if (_unknownButtonList->flags & 8)
+ _unknownButtonList = 0;
+ }
+
+ int returnValue = 0;
+ while (buttonList) {
+ if (buttonList->flags & 8)
+ continue;
+ buttonList->flags2 &= 0xFFE7;
+ buttonList->flags2 |= (buttonList->flags2 & 3) << 3;
+
+ int x = buttonList->x;
+ if (x < 0)
+ x += _screen->getScreenDim(buttonList->dimTableIndex)->w << 3;
+ x += _screen->getScreenDim(buttonList->dimTableIndex)->sx << 3;
+
+ int y = buttonList->y;
+ if (y < 0)
+ y += _screen->getScreenDim(buttonList->dimTableIndex)->h;
+ y += _screen->getScreenDim(buttonList->dimTableIndex)->sy;
+
+ bool progress = false;
+
+ if (mouseX >= x && mouseY >= y && mouseX <= x+buttonList->width && mouseY <= y+buttonList->height)
+ progress = true;
+
+ uint16 inFlags = inputFlag & 0x7FFF;
+ if (inFlags) {
+ if (buttonList->unk6 == inFlags) {
+ progress = true;
+ flags = buttonList->flags & 0x0F00;
+ buttonList->flags2 |= 0x80;
+ inputFlag = 0;
+ _unknownButtonList = buttonList;
+ } else if (buttonList->unk8 == inFlags) {
+ flags = buttonList->flags & 0xF000;
+ if (!flags)
+ flags = buttonList->flags & 0x0F00;
+ progress = true;
+ buttonList->flags2 |= 0x80;
+ inputFlag = 0;
+ _unknownButtonList = buttonList;
+ }
+ }
+
+ bool unk1 = false;
+ if (!progress)
+ buttonList->flags2 &= 0xFFF9;
+
+ if ((flags & 0x3300) && (buttonList->flags & 4) && progress && (buttonList == _unknownButtonList || !_unknownButtonList)) {
+ buttonList->flags |= 6;
+ if (!_unknownButtonList)
+ _unknownButtonList = buttonList;
+ } else if ((flags & 0x8800) && !(buttonList->flags & 4) && progress) {
+ buttonList->flags2 |= 6;
+ } else {
+ buttonList->flags2 &= 0xFFF9;
+ }
+
+ bool progressSwitch = false;
+ if (!_unknownButtonList) {
+ progressSwitch = progress;
+ } else {
+ if (_unknownButtonList->flags & 0x40)
+ progressSwitch = (_unknownButtonList == buttonList);
+ else
+ progressSwitch = progress;
+ }
+
+ if (progressSwitch) {
+ if ((flags & 0x1100) && progress && !_unknownButtonList) {
+ inputFlag = 0;
+ _unknownButtonList = buttonList;
+ }
+
+ if ((buttonList->flags & flags) && (progress || !(buttonList->flags & 1))) {
+ uint16 combinedFlags = (buttonList->flags & flags);
+ combinedFlags = ((combinedFlags & 0xF000) >> 4) | (combinedFlags & 0x0F00);
+ combinedFlags >>= 8;
+
+ static const uint16 flagTable[] = {
+ 0x000, 0x100, 0x200, 0x100, 0x400, 0x100, 0x400, 0x100, 0x800, 0x100,
+ 0x200, 0x100, 0x400, 0x100, 0x400, 0x100
+ };
+
+ assert(combinedFlags < ARRAYSIZE(flagTable));
+
+ switch (flagTable[combinedFlags]) {
+ case 0x400:
+ if ((buttonList->flags & 1) && _unknownButtonList == buttonList) {
+ buttonList->flags2 ^= 1;
+ returnValue = buttonList->index | 0x8000;
+ unk1 = true;
+ }
+
+ if (!(buttonList->flags & 4)) {
+ buttonList->flags2 &= 0xFFFB;
+ buttonList->flags2 &= 0xFFFD;
+ }
+ break;
+
+ case 0x800:
+ if (!(buttonList->flags & 4)) {
+ buttonList->flags2 |= 4;
+ buttonList->flags2 |= 2;
+ }
+
+ if (!(buttonList->flags & 1))
+ unk1 = true;
+ break;
+
+ case 0x200:
+ if (buttonList->flags & 4) {
+ buttonList->flags2 |= 4;
+ buttonList->flags2 |= 2;
+ }
+
+ if (!(buttonList->flags & 1))
+ unk1 = true;
+ break;
+
+ case 0x100:
+ default:
+ buttonList->flags2 ^= 1;
+ returnValue = buttonList->index | 0x8000;
+ unk1 = true;
+ if (buttonList->flags & 4) {
+ buttonList->flags2 |= 4;
+ buttonList->flags2 |= 2;
+ _unknownButtonList = buttonList;
+ }
+ break;
+ }
+ }
+ }
+
+ bool unk2 = false;
+ if ((flags & 0x2200) && progress) {
+ buttonList->flags2 |= 6;
+ if (!(buttonList->flags & 4) && !(buttonList->flags2 & 1)) {
+ unk2 = true;
+ buttonList->flags2 |= 1;
+ }
+ }
+
+ if ((flags & 0x8800) == 0x8800) {
+ _unknownButtonList = 0;
+ if (!progress || (buttonList->flags & 4))
+ buttonList->flags2 &= 0xFFF9;
+ }
+
+ if (!progress && buttonList == _unknownButtonList && !(buttonList->flags & 0x40))
+ _unknownButtonList = 0;
+
+ if ((buttonList->flags2 & 0x18) == ((buttonList->flags2 & 3) << 3))
+ processButton(buttonList);
+
+ if (unk2)
+ buttonList->flags2 &= 0xFFFE;
+
+ if (unk1) {
+ buttonList->flags2 &= 0xFF;
+ buttonList->flags2 |= flags;
+
+ if (buttonList->buttonCallback)
+ if ((this->*buttonList->buttonCallback)(buttonList))
+ break;
+ if (buttonList->flags & 0x20)
+ break;
+ }
+
+ if (_unknownButtonList == buttonList && (buttonList->flags & 0x40))
+ break;
+
+ buttonList = buttonList->nextButton;
+ }
+
+ if (!returnValue)
+ returnValue = inputFlag & 0x7FFF;
+ return returnValue;
+}
+
+int KyraEngine_v2::buttonInventory(Button *button) {
+ //XXX test if cursor is shown
+ int inventorySlot = button->index - 6;
+
+ uint16 item = _mainCharacter.inventory[inventorySlot];
+ if (_itemInHand == -1) {
+ if (item == -1)
+ return 0;
+ _screen->hideMouse();
+ clearInventorySlot(inventorySlot, 0);
+ snd_playSoundEffect(0x0B);
+ setMouseCursor(item);
+ int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7;
+ updateCommandLineEx(item+54, string, 0xD6);
+ _itemInHand = (int16)item;
+ _screen->showMouse();
+ _mainCharacter.inventory[inventorySlot] = 0xFFFF;
+ } else {
+ if (_mainCharacter.inventory[inventorySlot] != 0xFFFF) {
+ if (checkInventoryItemExchange(_itemInHand, inventorySlot))
+ return 0;
+
+ item = _mainCharacter.inventory[inventorySlot];
+ snd_playSoundEffect(0x0B);
+ _screen->hideMouse();
+ clearInventorySlot(inventorySlot, 0);
+ drawInventoryShape(0, _itemInHand, inventorySlot);
+ setMouseCursor(item);
+ int string = (_lang == 1) ? getItemCommandStringPickUp(item) : 7;
+ updateCommandLineEx(item+54, string, 0xD6);
+ _screen->showMouse();
+ _mainCharacter.inventory[inventorySlot] = _itemInHand;
+ setHandItem(item);
+ } else {
+ snd_playSoundEffect(0x0C);
+ _screen->hideMouse();
+ drawInventoryShape(0, _itemInHand, inventorySlot);
+ _screen->setMouseCursor(0, 0, getShapePtr(0));
+ int string = (_lang == 1) ? getItemCommandStringInv(_itemInHand) : 8;
+ updateCommandLineEx(_itemInHand+54, string, 0xD6);
+ _screen->showMouse();
+ _mainCharacter.inventory[inventorySlot] = _itemInHand;
+ _itemInHand = -1;
+ }
+ }
+
+ return 0;
+}
+
+bool KyraEngine_v2::checkInventoryItemExchange(uint16 handItem, int slot) {
+ bool removeItem = false;
+ uint16 newItem = 0xFFFF;
+
+ uint16 invItem = _mainCharacter.inventory[slot];
+
+ for (const uint16 *table = _itemMagicTable; *table != 0xFFFF; table += 4) {
+ if (table[0] != handItem || table[1] != invItem)
+ continue;
+
+ if (table[3] == 0xFFFF)
+ continue;
+
+ removeItem = (table[3] == 1);
+ newItem = table[2];
+
+ snd_playSoundEffect(0x68);
+ _mainCharacter.inventory[slot] = newItem;
+ _screen->hideMouse();
+ clearInventorySlot(slot, 0);
+ drawInventoryShape(0, newItem, slot);
+
+ if (removeItem)
+ removeHandItem();
+
+ _screen->showMouse();
+
+ if (_lang != 1)
+ updateCommandLineEx(newItem+53, 0x2E, 0xD6);
+
+ return true;
+ }
+
+ return false;
+}
+
+void KyraEngine_v2::drawInventoryShape(int page, uint16 item, int slot) {
+ _screen->drawShape(page, getShapePtr(item+64), _inventoryX[slot], _inventoryY[slot], 0, 0);
+ _screen->updateScreen();
+}
+
+void KyraEngine_v2::clearInventorySlot(int slot, int page) {
+ _screen->drawShape(page, _defaultShapeTable[240+slot], _inventoryX[slot], _inventoryY[slot], 0, 0);
+ _screen->updateScreen();
+}
+
} // end of namespace Kyra
diff --git a/engines/kyra/items_v2.cpp b/engines/kyra/items_v2.cpp
index 02aeb7912c..78f6f58f31 100644
--- a/engines/kyra/items_v2.cpp
+++ b/engines/kyra/items_v2.cpp
@@ -408,6 +408,18 @@ int KyraEngine_v2::getItemCommandStringPickUp(uint16 item) {
return pickUpStringIds[stringId];
}
+int KyraEngine_v2::getItemCommandStringInv(uint16 item) {
+ assert(item < _itemStringMapSize);
+ int stringId = _itemStringMap[item];
+
+ static const int pickUpStringIds[] = {
+ 0x02C, 0x104, 0x008, 0x107
+ };
+ assert(stringId < ARRAYSIZE(pickUpStringIds));
+
+ return pickUpStringIds[stringId];
+}
+
void KyraEngine_v2::setMouseCursor(uint16 item) {
int shape = 0;
int hotX = 1;
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index 45de6a3672..5a693f1c08 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -102,6 +102,9 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngi
memset(&_sceneScriptData, 0, sizeof(_sceneScriptData));
+ _backUpButtonList = _unknownButtonList = _buttonList = 0;
+ memset(&_buttonShapes, 0, sizeof(_buttonShapes));
+
_dlgBuffer = 0;
_conversationState = new int8*[19];
for (int i = 0; i < 19; i++)
@@ -112,6 +115,7 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngi
}
KyraEngine_v2::~KyraEngine_v2() {
+ cleanup();
seq_uninit();
if (_sequences)
@@ -313,9 +317,10 @@ void KyraEngine_v2::startup() {
_itemList = new Item[30];
memset(_itemList, 0, sizeof(Item)*30);
resetItemList();
- //loadButtonShapes();
+ loadButtonShapes();
_loadedZTable = 1;
loadZShapes(_loadedZTable);
+ initMainButtonList();
loadInventoryShapes();
_res->loadFileToBuf("PALETTE.COL", _screen->_currentPalette, 0x300);
@@ -390,7 +395,7 @@ void KyraEngine_v2::runLoop() {
// }
//}
- int inputFlag = checkInput(0/*dword_324C5*/);
+ int inputFlag = checkInput(_buttonList);
removeInputTop();
update();
@@ -694,7 +699,7 @@ void KyraEngine_v2::updateInput() {
_eventList.push_back(event);
}
-int KyraEngine_v2::checkInput(void *p) {
+int KyraEngine_v2::checkInput(Button *buttonList) {
updateInput();
int keys = 0;
@@ -747,7 +752,7 @@ int KyraEngine_v2::checkInput(void *p) {
}
_system->delayMillis(10);
- return keys;
+ return processButtonList(buttonList, keys | 0x8000);
}
void KyraEngine_v2::removeInputTop() {
@@ -774,32 +779,44 @@ void KyraEngine_v2::delay(uint32 amount, bool updateGame, bool isMainLoop) {
}
void KyraEngine_v2::cleanup() {
- delete [] _gamePlayBuffer;
- delete [] _unkBuf500Bytes;
- delete [] _screenBuffer;
- delete [] _unkBuf200kByte;
+ delete [] _gamePlayBuffer; _gamePlayBuffer = 0;
+ delete [] _unkBuf500Bytes; _unkBuf500Bytes = 0;
+ delete [] _screenBuffer; _screenBuffer = 0;
+ delete [] _unkBuf200kByte; _unkBuf200kByte = 0;
resetNewShapes(_newShapeCount, _newShapeFiledata);
+ _newShapeFiledata = 0;
+ _newShapeCount = 0;
- for (int i = 0; i < ARRAYSIZE(_defaultShapeTable); ++i)
+ for (int i = 0; i < ARRAYSIZE(_defaultShapeTable); ++i) {
delete [] _defaultShapeTable[i];
+ _defaultShapeTable[i] = 0;
+ }
freeSceneShapePtrs();
- delete [] _cCodeBuffer;
- delete [] _optionsBuffer;
- delete [] _chapterBuffer;
+ delete [] _cCodeBuffer; _cCodeBuffer = 0;
+ delete [] _optionsBuffer; _optionsBuffer = 0;
+ delete [] _chapterBuffer; _chapterBuffer = 0;
- delete [] _talkObjectList;
- delete [] _shapeDescTable;
+ delete [] _talkObjectList; _talkObjectList = 0;
+ delete [] _shapeDescTable; _shapeDescTable = 0;
- delete [] _gfxBackUpRect;
+ delete [] _gfxBackUpRect; _gfxBackUpRect = 0;
- delete [] _sceneList;
+ delete [] _sceneList; _sceneList = 0;
- for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i)
+ for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) {
delete _sceneAnimMovie[i];
- for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i)
+ _sceneAnimMovie[i] = 0;
+ }
+ for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) {
delete _wsaSlots[i];
+ _wsaSlots[i] = 0;
+ }
+ for (int i = 0; i < ARRAYSIZE(_buttonShapes); ++i) {
+ delete [] _buttonShapes[i];
+ _buttonShapes[i] = 0;
+ }
}
#pragma mark - Localization
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index 24765be863..3fec195d60 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -307,7 +307,8 @@ protected:
void updateMouse();
- int checkInput(void *p);
+ struct Button;
+ int checkInput(Button *buttonList);
void removeInputTop();
void handleInput(int x, int y);
bool handleInputUnkSub(int x, int y);
@@ -557,6 +558,59 @@ protected:
// inventory
static const int _inventoryX[];
static const int _inventoryY[];
+ static const uint16 _itemMagicTable[];
+
+ bool checkInventoryItemExchange(uint16 item, int slot);
+ void drawInventoryShape(int page, uint16 item, int slot);
+ void clearInventorySlot(int slot, int page);
+
+ // gui
+ void loadButtonShapes();
+ uint8 *_buttonShapes[19];
+
+ struct Button {
+ Button *nextButton;
+ uint16 index;
+ uint16 unk6;
+ uint16 unk8;
+ byte data0Val1;
+ byte data1Val1;
+ byte data2Val1;
+ // XXX
+ uint16 flags;
+ uint8 *shapePtr0;
+ uint8 *shapePtr1;
+ uint8 *shapePtr2;
+ uint16 dimTableIndex;
+ int16 x;
+ int16 y;
+ int16 width;
+ int16 height;
+ uint8 data0Val2;
+ uint8 data0Val3;
+ uint8 data1Val2;
+ uint8 data1Val3;
+ uint8 data2Val2;
+ uint8 data2Val3;
+ // XXX
+ uint16 flags2;
+ typedef int (KyraEngine_v2::*ButtonCallback)(KyraEngine_v2::Button*);
+ ButtonCallback buttonCallback;
+ // XXX
+ };
+
+ bool _buttonListChanged;
+ Button *_buttonList;
+ Button *_backUpButtonList;
+ Button *_unknownButtonList;
+
+ void initMainButtonList();
+
+ void processButton(Button *button);
+ Button *addButtonToList(Button *list, Button *newButton);
+ int processButtonList(Button *button, uint16 inputFlag);
+
+ int buttonInventory(Button *button);
// localization
void loadCCodeBuffer(const char *file);
@@ -580,6 +634,7 @@ protected:
// - Just used in French version
int getItemCommandStringDrop(uint16 item);
int getItemCommandStringPickUp(uint16 item);
+ int getItemCommandStringInv(uint16 item);
// -
char _internStringBuf[200];
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 186f215668..762b6a20ce 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -761,8 +761,8 @@ void Screen::shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPag
}
}
-void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum) {
- debugC(9, kDebugLevelScreen, "Screen::fillRect(%d, %d, %d, %d, %d, %d)", x1, y1, x2, y2, color, pageNum);
+void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum, bool xor) {
+ debugC(9, kDebugLevelScreen, "Screen::fillRect(%d, %d, %d, %d, %d, %d, %d)", x1, y1, x2, y2, color, pageNum, xor);
assert(x2 < SCREEN_W && y2 < SCREEN_H);
if (pageNum == -1)
pageNum = _curPage;
@@ -774,9 +774,17 @@ void Screen::fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum)
clearOverlayRect(pageNum, x1, y1, x2-x1+1, y2-y1+1);
- for (; y1 <= y2; ++y1) {
- memset(dst, color, x2 - x1 + 1);
- dst += SCREEN_W;
+ if (xor) {
+ for (; y1 <= y2; ++y1) {
+ for (int x = x1; x <= x2; ++x)
+ dst[x] ^= color;
+ dst += SCREEN_W;
+ }
+ } else {
+ for (; y1 <= y2; ++y1) {
+ memset(dst, color, x2 - x1 + 1);
+ dst += SCREEN_W;
+ }
}
}
diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h
index 0c9bc98b1c..4a45c7184c 100644
--- a/engines/kyra/screen.h
+++ b/engines/kyra/screen.h
@@ -127,7 +127,7 @@ public:
void copyBlockToPage(int pageNum, int x, int y, int w, int h, const uint8 *src);
void shuffleScreen(int sx, int sy, int w, int h, int srcPage, int dstPage, int ticks, bool transparent);
- void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1);
+ void fillRect(int x1, int y1, int x2, int y2, uint8 color, int pageNum = -1, bool xor = false);
void clearPage(int pageNum);
diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp
index cb3967b73a..2bec373266 100644
--- a/engines/kyra/screen_v2.cpp
+++ b/engines/kyra/screen_v2.cpp
@@ -687,6 +687,9 @@ void Screen_v2::drawShape(uint8 page, const uint8 *shape, int x, int y, int sd,
uint8 *dst = getPagePtr(page) + y * 320 + x;
uint8 *dstStart = getPagePtr(page);
+ if (page == 0 || page == 1)
+ addDirtyRect(x, y, x2-x1, y2-y1);
+ clearOverlayRect(page, x, y, x2-x1, y2-y1);
int scaleYTable[200];
for (y = y1; y < y2; ++y) {
diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp
index 817e14fda6..cded12e8a9 100644
--- a/engines/kyra/staticres.cpp
+++ b/engines/kyra/staticres.cpp
@@ -1445,6 +1445,85 @@ const int8 KyraEngine_v2::_dosTrackMap[] = {
const int KyraEngine_v2::_dosTrackMapSize = ARRAYSIZE(KyraEngine_v2::_dosTrackMap);
+void KyraEngine_v2::initMainButtonList() {
+ // note: _buttonDataListPtr
+ static Button mainButtons[] = {
+ { 0, 0x1, 0x4F, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0x00A, 0x95, 0x39, 0x1D, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, /*&KyraEngine_v2::sub_C9A1*/0 },
+ { 0, 0x2, 0x00, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0x104, 0x90, 0x3C, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, /*&KyraEngine_v2::sub_27037*/0 },
+ { 0, 0x5, 0x00, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0x0FA, 0x90, 0x0A, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, /*&KyraEngine_v2::sub_27032*/0 },
+ { 0, 0x3, 0x00, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0x0CE, 0x90, 0x2C, 0x2C, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, /*&KyraEngine_v2::gui_showBook*/0 },
+ { 0, 0x4, 0x00, 0, 1, 1, 1, 0x4487, 0, 0, 0, 0, 0x0B6, 0x9D, 0x18, 0x1E, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, /*&KyraEngine_v2::sub_2735E*/0 },
+ { 0, 0x6, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x04D, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0x7, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x061, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0x8, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x075, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0x9, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x089, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0xA, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x09D, 0x92, 0x13, 0x15, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0xB, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x04D, 0xA8, 0x13, 0x14, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0xC, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x061, 0xA8, 0x13, 0x14, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0xD, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x075, 0xA8, 0x13, 0x14, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0xE, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x089, 0xA8, 0x13, 0x14, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory },
+ { 0, 0xF, 0x00, 0, 0, 0, 0, 0x1100, 0, 0, 0, 0, 0x09D, 0xA8, 0x13, 0x14, 0xC7, 0xCF, 0xC7, 0xCF, 0xC7, 0xCF, 0, &KyraEngine_v2::buttonInventory }
+ };
+
+ switch (_lang) {
+ case 0:
+ mainButtons[0].shapePtr0 = _buttonShapes[6];
+ mainButtons[0].shapePtr1 = mainButtons[0].shapePtr2 = _buttonShapes[7];
+ break;
+
+ case 1:
+ mainButtons[0].shapePtr0 = _buttonShapes[8];
+ mainButtons[0].shapePtr1 = mainButtons[0].shapePtr2 = _buttonShapes[9];
+ break;
+
+ case 2:
+ mainButtons[0].shapePtr0 = _buttonShapes[10];
+ mainButtons[0].shapePtr1 = mainButtons[0].shapePtr2 = _buttonShapes[11];
+ break;
+
+ default:
+ mainButtons[0].shapePtr0 = _buttonShapes[6];
+ mainButtons[0].shapePtr1 = mainButtons[0].shapePtr2 = _buttonShapes[7];
+ break;
+ }
+
+ _buttonList = &mainButtons[0];
+ for (size_t i = 1; i < ARRAYSIZE(mainButtons); ++i)
+ _buttonList = addButtonToList(_buttonList, &mainButtons[i]);
+}
+
+const uint16 KyraEngine_v2::_itemMagicTable[] = {
+ 0x0D, 0x0A, 0x0B, 0,
+ 0x0D, 0x0B, 0x0A, 0,
+ 0x0D, 0x38, 0x37, 0,
+ 0x0D, 0x37, 0x38, 0,
+ 0x0D, 0x35, 0x36, 0,
+ 0x0D, 0x36, 0x35, 0,
+ 0x34, 0x27, 0x33, 0,
+ 0x41, 0x29, 0x49, 0,
+ 0x45, 0x29, 0x4A, 1,
+ 0x46, 0x29, 0x4A, 1,
+ 0x3C, 0x29, 0x4B, 1,
+ 0x34, 0x29, 0x4C, 0,
+ 0x3C, 0x49, 0x3B, 1,
+ 0x41, 0x4B, 0x3B, 0,
+ 0x3C, 0x4A, 0x3B, 1,
+ 0x34, 0x49, 0x3B, 0,
+ 0x41, 0x4C, 0x3B, 0,
+ 0x45, 0x4C, 0x3B, 1,
+ 0x46, 0x4C, 0x3B, 1,
+ 0x34, 0x4A, 0x3B, 0,
+ 0x0D, 0x67, 0x68, 0,
+ 0x0D, 0x68, 0x67, 0,
+ 0x0D, 0x69, 0x6A, 0,
+ 0x0D, 0x6A, 0x69, 0,
+ 0x0D, 0x6B, 0x6C, 0,
+ 0x0D, 0x6C, 0x6B, 0,
+ 0x0D, 0x88, 0x87, 0,
+ 0x0D, 0x87, 0x88, 0,
+ 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF
+};
+
// kyra 3 static res
const char *KyraEngine_v3::_soundList[] = {