aboutsummaryrefslogtreecommitdiff
path: root/kyra/kyra.cpp
diff options
context:
space:
mode:
authorJohannes Schickel2005-12-26 14:53:51 +0000
committerJohannes Schickel2005-12-26 14:53:51 +0000
commit55f737c4a2b6f8dc51241dad02d2e2692e734213 (patch)
treec6afa69f71f6cedecf408b3508c7d5b9e9ba7d36 /kyra/kyra.cpp
parentfcf1af2ffc739d3efa430edc5280f83d3ab270fb (diff)
downloadscummvm-rg350-55f737c4a2b6f8dc51241dad02d2e2692e734213.tar.gz
scummvm-rg350-55f737c4a2b6f8dc51241dad02d2e2692e734213.tar.bz2
scummvm-rg350-55f737c4a2b6f8dc51241dad02d2e2692e734213.zip
Started to implement the amulet button callback.
Also implemented some of the first jewel functionallity. And cleaned up the resource unloading a bit. svn-id: r19833
Diffstat (limited to 'kyra/kyra.cpp')
-rw-r--r--kyra/kyra.cpp286
1 files changed, 278 insertions, 8 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp
index fe7cc76eb3..7f91f7cdc9 100644
--- a/kyra/kyra.cpp
+++ b/kyra/kyra.cpp
@@ -182,6 +182,16 @@ KyraEngine::KyraEngine(GameDetector *detector, OSystem *system)
_seq_WSATable = _seq_CPSTable = _seq_COLTable = _seq_textsTable = 0;
_seq_WSATable_Size = _seq_CPSTable_Size = _seq_COLTable_Size = _seq_textsTable_Size = 0;
+
+ _roomFilenameTable = _characterImageTable = 0;
+ _roomFilenameTableSize = _characterImageTableSize = 0;
+ _itemList = _takenList = _placedList = _droppedList = _noDropList = 0;
+ _itemList_Size = _takenList_Size = _placedList_Size = _droppedList_Size = _noDropList_Size = 0;
+ _putDownFirst = _waitForAmulet = _blackJewel = _poisonGone = _healingTip = 0;
+ _putDownFirst_Size = _waitForAmulet_Size = _blackJewel_Size = _poisonGone_Size = _healingTip_Size = 0;
+
+ _defaultShapeTable = _healingShapeTable = _healingShape2Table = 0;
+ _defaultShapeTableSize = _healingShapeTableSize = _healingShape2TableSize = 0;
// Setup mixer
if (!_mixer->isReady()) {
@@ -344,6 +354,7 @@ int KyraEngine::init(GameDetector &detector) {
_brandonPosX = _brandonPosY = -1;
_brandonDrawFrame = 113;
+ _deathHandler = 0xFF;
memset(_itemTable, 0, sizeof(_itemTable));
memset(_exitList, 0xFFFF, sizeof(_exitList));
@@ -981,6 +992,37 @@ void KyraEngine::seq_createAmuletJewel(int jewel, int page, int noSound, int dra
setGameFlag(0x55+jewel);
}
+void KyraEngine::seq_brandonHealing() {
+ debug(9, "seq_brandonHealing()");
+ if (!(_deathHandler & 8))
+ return;
+ if (_currentCharacter->sceneId == 210) {
+ //if (_unkSceneVar == 4 || _unkSceneVar == 6)
+ // return;
+ }
+ _screen->hideMouse();
+ checkAmuletAnimFlags();
+ assert(_healingShapeTable);
+ setupShapes123(_healingShapeTable, 22, 0);
+ setBrandonAnimSeqSize(3, 48);
+ // snd_playSoundEffect(0x53);
+ for (int i = 123; i <= 144; ++i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(8);
+ }
+ for (int i = 125; i >= 123; --i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(8);
+ }
+ resetBrandonAnimSeqSize();
+ _currentCharacter->currentAnimFrame = 7;
+ animRefreshNPC(0);
+ freeShapes123();
+ _screen->showMouse();
+}
+
bool KyraEngine::seq_skipSequence() const {
debug(9, "KyraEngine::seq_skipSequence()");
return _quitFlag || _abortIntroFlag;
@@ -2600,14 +2642,14 @@ void KyraEngine::printCharacterText(char *text, int8 charNum) {
}
void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
- debug(9, "KyraEngine:::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration);
+ debug(9, "KyraEngine::characterSays('%s', %i, %d)", chatStr, charNum, chatDuration);
uint8 startAnimFrames[] = { 0x10, 0x32, 0x56, 0x0, 0x0, 0x0 };
uint16 chatTicks;
int16 convoInitialized;
int8 chatPartnerNum;
- if (_currentCharacter->sceneId == 0xD2)
+ if (_currentCharacter->sceneId == 210)
return;
convoInitialized = initCharacterChat(charNum);
@@ -2634,7 +2676,7 @@ void KyraEngine::characterSays(char *chatStr, int8 charNum, int8 chatDuration) {
if (yPos < 11)
yPos = 11;
- if (yPos > 100 )
+ if (yPos > 100)
yPos = 100;
_talkMessageY = yPos;
@@ -3582,7 +3624,7 @@ void KyraEngine::redrawInventory(int page) {
}
#pragma mark -
-#pragma mark - Animation specific code
+#pragma mark - Animation/shape specific code
#pragma mark -
void KyraEngine::preserveAllBackgrounds() {
@@ -3780,7 +3822,7 @@ void KyraEngine::prepDrawAllObjects() {
tempFlags = 1;
}
tempFlags |= 0x900 | flagUnk1 | 0x4000;
- _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, 1, 0/*XXX*/, drawLayer, _brandonScaleX, _brandonScaleY);
+ _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, int(1), int(0)/*XXX*/, drawLayer, _brandonScaleX, _brandonScaleY);
} else {
if (!(flagUnk2 & 0x4000)) {
tempFlags = 0;
@@ -3790,7 +3832,7 @@ void KyraEngine::prepDrawAllObjects() {
tempFlags |= 0x900 | flagUnk1;
}
- _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, 1, drawLayer, _brandonScaleX, _brandonScaleY);
+ _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
}
}
} else {
@@ -4021,6 +4063,146 @@ void KyraEngine::animAddNPC(int character) {
animObj->bkgdChangeFlag = 1;
}
+void KyraEngine::drawJewelPress(int jewel, int drawSpecial) {
+ debug(9, "drawJewelPress(%d, %d)", jewel, drawSpecial);
+ _screen->hideMouse();
+ int shape = 0;
+ if (drawSpecial) {
+ shape = 0x14E;
+ } else {
+ shape = jewel + 0x149;
+ }
+ // snd_playSoundEffect(0x45);
+ _screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+ _screen->updateScreen();
+ delayWithTicks(2);
+ if (drawSpecial) {
+ shape = 0x148;
+ } else {
+ shape = jewel + 0x143;
+ }
+ _screen->drawShape(0, _shapes[4+shape], _amuletX2[jewel], _amuletY2[jewel], 0, 0);
+ _screen->updateScreen();
+ _screen->showMouse();
+}
+
+void KyraEngine::drawJewelsFadeOutStart() {
+ debug(9, "drawJewelsFadeOutStart()");
+ static const uint16 jewelTable1[] = { 0x164, 0x15F, 0x15A, 0x155, 0x150, 0xFFFF };
+ static const uint16 jewelTable2[] = { 0x163, 0x15E, 0x159, 0x154, 0x14F, 0xFFFF };
+ static const uint16 jewelTable3[] = { 0x166, 0x160, 0x15C, 0x157, 0x152, 0xFFFF };
+ static const uint16 jewelTable4[] = { 0x165, 0x161, 0x15B, 0x156, 0x151, 0xFFFF };
+ for (int i = 0; jewelTable1[i] != 0xFFFF; ++i) {
+ if (queryGameFlag(0x57)) {
+ _screen->drawShape(0, _shapes[4+jewelTable1[i]], _amuletX2[2], _amuletY2[2], 0, 0);
+ }
+ if (queryGameFlag(0x59)) {
+ _screen->drawShape(0, _shapes[4+jewelTable3[i]], _amuletX2[4], _amuletY2[4], 0, 0);
+ }
+ if (queryGameFlag(0x56)) {
+ _screen->drawShape(0, _shapes[4+jewelTable2[i]], _amuletX2[1], _amuletY2[1], 0, 0);
+ }
+ if (queryGameFlag(0x58)) {
+ _screen->drawShape(0, _shapes[4+jewelTable4[i]], _amuletX2[3], _amuletY2[3], 0, 0);
+ }
+ _screen->updateScreen();
+ delayWithTicks(3);
+ }
+}
+
+void KyraEngine::drawJewelsFadeOutEnd(int jewel) {
+ debug(9, "drawJewelsFadeOutEnd(%d)", jewel);
+ static const uint16 jewelTable[] = { 0x153, 0x158, 0x15D, 0x162, 0x148, 0xFFFF };
+ int newDelay = 0;
+ switch (jewel-1) {
+ case 2:
+ if (_currentCharacter->sceneId >= 109 && _currentCharacter->sceneId <= 198) {
+ newDelay = 18900;
+ } else {
+ newDelay = 8100;
+ }
+ break;
+
+ default:
+ newDelay = 3600;
+ break;
+ }
+ setGameFlag(0xF1);
+ setTimerCountdown(19, newDelay);
+ _screen->hideMouse();
+ for (int i = 0; jewelTable[i] != 0xFFFF; ++i) {
+ uint16 shape = jewelTable[i];
+ if (queryGameFlag(0x57)) {
+ _screen->drawShape(0, _shapes[4+shape], _amuletX2[2], _amuletY2[2], 0, 0);
+ }
+ if (queryGameFlag(0x59)) {
+ _screen->drawShape(0, _shapes[4+shape], _amuletX2[4], _amuletY2[4], 0, 0);
+ }
+ if (queryGameFlag(0x56)) {
+ _screen->drawShape(0, _shapes[4+shape], _amuletX2[1], _amuletY2[1], 0, 0);
+ }
+ if (queryGameFlag(0x58)) {
+ _screen->drawShape(0, _shapes[4+shape], _amuletX2[3], _amuletY2[3], 0, 0);
+ }
+ _screen->updateScreen();
+ delayWithTicks(3);
+ }
+ _screen->showMouse();
+}
+
+void KyraEngine::setupShapes123(const Shape *shapeTable, int endShape, int flags) {
+ debug(9, "setupShapes123(0x%X, startShape, flags)", shapeTable, endShape, flags);
+ for (int i = 123; i <= 172; ++i) {
+ _shapes[4+i] = NULL;
+ }
+ uint8 curImage = 0xFF;
+ int curPageBackUp = _screen->_curPage;
+ _screen->_curPage = 8; // we are using page 8 here in the original page 2 was backuped and then used for this stuff
+ int shapeFlags = 2;
+ if (flags)
+ shapeFlags = 3;
+ for (int i = 123; i < 123+endShape; ++i) {
+ uint8 newImage = shapeTable[i-123].imageIndex;
+ if (newImage != curImage) {
+ assert(_characterImageTable);
+ loadBitmap(_characterImageTable[newImage], 8, 8, 0);
+ curImage = newImage;
+ }
+ _shapes[4+i] = _screen->encodeShape(shapeTable[i-123].x<<3, shapeTable[i-123].y, shapeTable[i-123].w<<3, shapeTable[i-123].h, flags);
+ assert(i-7 < _defaultShapeTableSize);
+ _defaultShapeTable[i-7].xOffset = shapeTable[i-123].xOffset;
+ _defaultShapeTable[i-7].yOffset = shapeTable[i-123].yOffset;
+ _defaultShapeTable[i-7].w = shapeTable[i-123].w;
+ _defaultShapeTable[i-7].h = shapeTable[i-123].h;
+ }
+ _screen->_curPage = curPageBackUp;
+}
+
+void KyraEngine::freeShapes123() {
+ debug(9, "freeShapes123()");
+ for (int i = 123; i <= 172; ++i) {
+ free(_shapes[4+i]);
+ _shapes[4+i] = NULL;
+ }
+}
+
+void KyraEngine::setBrandonAnimSeqSize(int width, int height) {
+ debug(9, "setBrandonAnimSeqSize(%d, %d)", width, height);
+ restoreAllObjectBackgrounds();
+ _brandonAnimSeqSizeWidth = _charactersAnimState[0].width;
+ _brandonAnimSeqSizeHeight = _charactersAnimState[0].height;
+ _charactersAnimState[0].width = width + 1;
+ _charactersAnimState[0].height = height;
+ preserveAllBackgrounds();
+}
+
+void KyraEngine::resetBrandonAnimSeqSize() {
+ restoreAllObjectBackgrounds();
+ _charactersAnimState[0].width = _brandonAnimSeqSizeWidth;
+ _charactersAnimState[0].height = _brandonAnimSeqSizeHeight;
+ preserveAllBackgrounds();
+}
+
#pragma mark -
#pragma mark - Queue handling
#pragma mark -
@@ -4228,6 +4410,17 @@ void KyraEngine::copyBackgroundBlock2(int x) {
copyBackgroundBlock(x, 4, 1);
}
+void KyraEngine::makeBrandonFaceMouse() {
+ debug(9, "makeBrandonFaceMouse()");
+ if (_mouseX >= _currentCharacter->x1) {
+ _currentCharacter->facing = 3;
+ } else {
+ _currentCharacter->facing = 5;
+ }
+ animRefreshNPC(0);
+ updateAllObjectShapes();
+}
+
#pragma mark -
#pragma mark - Pathfinder
#pragma mark -
@@ -5097,7 +5290,7 @@ void KyraEngine::checkAmuletAnimFlags() {
void KyraEngine::timerRedrawAmulet(int timerNum) {
debug(9, "timerRedrawAmulet(%i)", timerNum);
- if (queryGameFlag(241)) {
+ if (queryGameFlag(0xF1)) {
drawAmulet();
setTimerCountdown(19, -1);
}
@@ -5110,6 +5303,7 @@ void KyraEngine::drawAmulet() {
static const int16 amuletTable2[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x152, 0x157, 0x15C, 0x161, 0x166, 0x147, -1};
static const int16 amuletTable4[] = {0x167, 0x162, 0x15D, 0x158, 0x153, 0x151, 0x156, 0x15B, 0x160, 0x165, 0x146, -1};
+ resetGameFlag(0xF1);
_screen->hideMouse();
int i = 0;
@@ -5126,7 +5320,8 @@ void KyraEngine::drawAmulet() {
if (queryGameFlag(88))
_screen->drawShape(0, _shapes[4+amuletTable4[i]], _amuletX[3], _amuletY[3], 0, 0);
- delay(3 * _tickLength);
+ _screen->updateScreen();
+ delayWithTicks(3);
i++;
}
_screen->showMouse();
@@ -5661,6 +5856,81 @@ int KyraEngine::buttonInventoryCallback(Button *caller) {
return 0;
}
+int KyraEngine::buttonAmuletCallback(Button *caller) {
+ if (!(_deathHandler & 8))
+ return 1;
+ int jewel = caller->specialValue - 0x14;
+ if (_currentCharacter->sceneId == 210) {
+ //if (_unkSceneVar == 4 || _unkSceneVar == 6)
+ // return 1;
+ }
+ if (!queryGameFlag(0x2D))
+ return 1;
+ if (_itemInHand != -1) {
+ assert(_putDownFirst);
+ characterSays(_putDownFirst[0], 0, -2);
+ return 1;
+ }
+ if (queryGameFlag(0xF1)) {
+ assert(_waitForAmulet);
+ characterSays(_waitForAmulet[0], 0, -2);
+ return 1;
+ }
+ if (!queryGameFlag(0x55+jewel)) {
+ assert(_blackJewel);
+ makeBrandonFaceMouse();
+ drawJewelPress(jewel, 1);
+ characterSays(_blackJewel[0], 0, -2);
+ return 1;
+ }
+ drawJewelPress(jewel, 0);
+ drawJewelsFadeOutStart();
+ drawJewelsFadeOutEnd(jewel);
+
+ _scriptInterpreter->initScript(_scriptClick, _scriptClickData);
+ _scriptClick->variables[3] = 0;
+ _scriptClick->variables[6] = jewel;
+ _scriptInterpreter->startScript(_scriptClick, 4);
+
+ while (_scriptInterpreter->validScript(_scriptClick)) {
+ _scriptInterpreter->runScript(_scriptClick);
+ }
+
+ if (_scriptClick->variables[3])
+ return 1;
+
+ _unkAmuletVar = 1;
+ switch (jewel-1) {
+ case 0:
+ if (_brandonStatusBit & 1) {
+ // seq_brandonHealing2
+ } else if (_brandonStatusBit == 0) {
+ seq_brandonHealing();
+ assert(_healingTip);
+ characterSays(_healingTip[0], 0, -2);
+ }
+ break;
+
+ case 1:
+ warning("jewel 1 STUB");
+ break;
+
+ case 2:
+ warning("jewel 2 STUB");
+ break;
+
+ case 3:
+ warning("jewel 3 STUB");
+ break;
+
+ default:
+ break;
+ }
+ _unkAmuletVar = 0;
+ // XXX clearKyrandiaButtonIO (!used before every return in this function!)
+ return 1;
+}
+
void KyraEngine::processButtonList(Button *list) {
while (list) {
if (list->flags & 8) {