aboutsummaryrefslogtreecommitdiff
path: root/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2005-12-28 21:34:40 +0000
committerJohannes Schickel2005-12-28 21:34:40 +0000
commitf7b49851264843b6e24c57dcbf9ca4751d6dae2f (patch)
tree2616d8ee99b8e8dd2dad90ae12042c8aea1200b8 /kyra
parentb7a2b9d31f4e56355a929c64aba1fc2fdbd0fe4d (diff)
downloadscummvm-rg350-f7b49851264843b6e24c57dcbf9ca4751d6dae2f.tar.gz
scummvm-rg350-f7b49851264843b6e24c57dcbf9ca4751d6dae2f.tar.bz2
scummvm-rg350-f7b49851264843b6e24c57dcbf9ca4751d6dae2f.zip
Implemented:
- cmd_magicInMouseItem - cmd_poisonDeathNow - cmd_poisonBrandonAndRemaps - cmd_playFluteAnimation Also implemented healing function for brandon. And implemented poison death sequence. svn-id: r19841
Diffstat (limited to 'kyra')
-rw-r--r--kyra/kyra.cpp258
-rw-r--r--kyra/kyra.h20
-rw-r--r--kyra/script_v1.cpp12
-rw-r--r--kyra/staticres.cpp17
4 files changed, 294 insertions, 13 deletions
diff --git a/kyra/kyra.cpp b/kyra/kyra.cpp
index f37e84f329..8a212950f4 100644
--- a/kyra/kyra.cpp
+++ b/kyra/kyra.cpp
@@ -355,6 +355,7 @@ int KyraEngine::init(GameDetector &detector) {
_brandonPosX = _brandonPosY = -1;
_brandonDrawFrame = 113;
_deathHandler = 0xFF;
+ _poisonDeathCounter = 0;
memset(_itemTable, 0, sizeof(_itemTable));
memset(_exitList, 0xFFFF, sizeof(_exitList));
@@ -1023,6 +1024,145 @@ void KyraEngine::seq_brandonHealing() {
_screen->showMouse();
}
+void KyraEngine::seq_brandonHealing2() {
+ debug(9, "seq_brandonHealing2()");
+ _screen->hideMouse();
+ checkAmuletAnimFlags();
+ assert(_healingShape2Table);
+ setupShapes123(_healingShape2Table, 30, 0);
+ resetBrandonPoisonFlags();
+ setBrandonAnimSeqSize(3, 48);
+ // snd_playSoundEffect(0x50);
+ for (int i = 123; i <= 152; ++i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(8);
+ }
+ resetBrandonAnimSeqSize();
+ _currentCharacter->currentAnimFrame = 7;
+ animRefreshNPC(0);
+ freeShapes123();
+ _screen->showMouse();
+ assert(_poisonGone);
+ characterSays(_poisonGone[0], 0, -2);
+ characterSays(_poisonGone[1], 0, -2);
+}
+
+void KyraEngine::seq_poisonDeathNow(int now) {
+ debug(9, "seq_poisonDeathNow(%d)", now);
+ if (!(_brandonStatusBit & 1))
+ return;
+ ++_poisonDeathCounter;
+ if (now)
+ _poisonDeathCounter = 2;
+ if (_poisonDeathCounter >= 2) {
+ // XXX
+ assert(_thePoison);
+ characterSays(_thePoison[0], 0, -2);
+ characterSays(_thePoison[1], 0, -2);
+ seq_poisonDeathNowAnim();
+ _deathHandler = 3;
+ } else {
+ assert(_thePoison);
+ characterSays(_thePoison[2], 0, -2);
+ characterSays(_thePoison[3], 0, -2);
+ }
+}
+
+void KyraEngine::seq_poisonDeathNowAnim() {
+ debug(9, "seq_poisonDeathNowAnim()");
+ _screen->hideMouse();
+ checkAmuletAnimFlags();
+ assert(_posionDeathShapeTable);
+ setupShapes123(_posionDeathShapeTable, 20, 0);
+ setBrandonAnimSeqSize(8, 48);
+
+ _currentCharacter->currentAnimFrame = 124;
+ animRefreshNPC(0);
+ delayWithTicks(30);
+
+ _currentCharacter->currentAnimFrame = 123;
+ animRefreshNPC(0);
+ delayWithTicks(30);
+
+ for (int i = 125; i <= 139; ++i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(8);
+ }
+
+ delayWithTicks(60);
+
+ for (int i = 140; i <= 142; ++i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(8);
+ }
+
+ delayWithTicks(60);
+
+ resetBrandonAnimSeqSize();
+ freeShapes123();
+ restoreAllObjectBackgrounds();
+ _currentCharacter->x1 = _currentCharacter->x2 = -1;
+ _currentCharacter->y1 = _currentCharacter->y2 = -1;
+ preserveAllBackgrounds();
+ _screen->showMouse();
+}
+
+void KyraEngine::seq_playFluteAnimation() {
+ debug(9, "seq_playFluteAnimation()");
+ _screen->hideMouse();
+ checkAmuletAnimFlags();
+ setupShapes123(_fluteAnimShapeTable, 36, 0);
+ setBrandonAnimSeqSize(3, 75);
+ for (int i = 123; i <= 130; ++i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(2);
+ }
+
+ int delayTime = 0, soundType = 0;
+ if (queryGameFlag(0x85)) {
+ // snd_playSoundEffect(0x63);
+ delayTime = 9;
+ soundType = 3;
+ } else if (queryGameFlag(0x86)) {
+ // snd_playSoundEffect(0x61);
+ delayTime = 2;
+ soundType = 1;
+ } else {
+ // snd_playSoundEffect(0x62);
+ delayTime = 2;
+ soundType = 2;
+ }
+
+ for (int i = 131; i <= 158; ++i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(delayTime);
+ }
+
+ for (int i = 126; i >= 123; --i) {
+ _currentCharacter->currentAnimFrame = i;
+ animRefreshNPC(0);
+ delayWithTicks(delayTime);
+ }
+ resetBrandonAnimSeqSize();
+ _currentCharacter->currentAnimFrame = 7;
+ animRefreshNPC(0);
+ freeShapes123();
+ _screen->showMouse();
+
+ if (soundType == 1) {
+ assert(_fluteString);
+ characterSays(_fluteString[0], 0, -2);
+ } else if (soundType == 2) {
+ assert(_fluteString);
+ characterSays(_fluteString[1], 0, -2);
+ }
+}
+
bool KyraEngine::seq_skipSequence() const {
debug(9, "KyraEngine::seq_skipSequence()");
return _quitFlag || _abortIntroFlag;
@@ -1486,7 +1626,7 @@ void KyraEngine::enterNewScene(int sceneId, int facing, int unk1, int unk2, int
_loopFlag2 = 0;
_screen->showMouse();
if (!brandonAlive) {
- // XXX seq_poisionDeathNow
+ seq_poisonDeathNow(0);
}
updateMousePointer(true);
_changedScene = true;
@@ -1991,7 +2131,7 @@ void KyraEngine::initSceneData(int facing, int unk1, int brandonAlive) {
void KyraEngine::resetBrandonPosionFlags() {
_brandonStatusBit = 0;
for (int i = 0; i < 256; ++i) {
- _unkBrandonPoisonFlags[i] = i;
+ _brandonPoisonFlagsGFX[i] = i;
}
}
@@ -3521,6 +3661,87 @@ void KyraEngine::magicOutMouseItem(int animIndex, int itemPos) {
_screen->_curPage = videoPageBackUp;
}
+void KyraEngine::magicInMouseItem(int animIndex, int item, int itemPos) {
+ debug(9, "magicInMouseItem(%d, %d, %d)", animIndex, item, itemPos);
+ int videoPageBackUp = _screen->_curPage;
+ _screen->_curPage = 0;
+ int x = 0, y = 0;
+ if (itemPos == -1) {
+ x = _mouseX - 12;
+ y = _mouseY - 18;
+ } else {
+ x = _itemPosX[itemPos] - 4;
+ y = _itemPosX[itemPos] - 3;
+ }
+ if (item < 0)
+ return;
+
+ int tableIndex = -1, loopStart = 0, maxLoops = 0;
+ if (animIndex == 0) {
+ tableIndex = _rnd.getRandomNumberRng(0, 5);
+ loopStart = 35;
+ maxLoops = 9;
+ } else if (animIndex == 1) {
+ tableIndex = _rnd.getRandomNumberRng(0, 11);
+ loopStart = 115;
+ maxLoops = 8;
+ } else if (animIndex == 2) {
+ tableIndex = 0;
+ loopStart = 124;
+ maxLoops = 4;
+ }
+
+ _screen->hideMouse();
+ backUpRect1(x, y);
+ if (animIndex == 2) {
+ // snd_playSoundEffect(0x5E);
+ } else {
+ // snd_playSoundEffect(0x37);
+ }
+
+ for (int shape = _magicMouseItemStartFrame[animIndex]; shape <= _magicMouseItemEndFrame[animIndex]; ++shape) {
+ restoreRect1(x, y);
+ uint32 nextTime = _system->getMillis() + 4 * _tickLength;
+ if (tableIndex == -1) {
+ _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
+ } else {
+ specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
+ }
+ _screen->updateScreen();
+ while (_system->getMillis() < nextTime) {
+ if (nextTime - _system->getMillis() >= 10)
+ delay(10);
+ }
+ }
+
+ for (int shape = _magicMouseItemStartFrame2[animIndex]; shape <= _magicMouseItemEndFrame2[animIndex]; ++shape) {
+ restoreRect1(x, y);
+ uint32 nextTime = _system->getMillis() + 4 * _tickLength;
+ if (tableIndex == -1) {
+ _screen->drawShape(0, _shapes[4+shape], x, y, 0, 0);
+ } else {
+ specialMouseItemFX(shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
+ }
+ _screen->updateScreen();
+ while (_system->getMillis() < nextTime) {
+ if (nextTime - _system->getMillis() >= 10)
+ delay(10);
+ }
+ }
+ restoreRect1(x, y);
+ if (itemPos == -1) {
+ _screen->setMouseCursor(8, 15, _shapes[220+item]);
+ _itemInHand = item;
+ } else {
+ _characterList[0].inventoryItems[itemPos] = item;
+ _screen->hideMouse();
+ _screen->drawShape(0, _shapes[220+item], _itemPosX[itemPos], _itemPosY[itemPos], 0, 0);
+ _screen->showMouse();
+ }
+ _screen->showMouse();
+ _screen->_curPage = videoPageBackUp;
+}
+
void KyraEngine::specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops) {
debug(9, "specialMouseItemFX(%d, %d, %d, %d, %d, %d, %d)", shape, x, y, animIndex, tableIndex, loopStart, maxLoops);
static const uint8 table1[] = {
@@ -3822,7 +4043,7 @@ void KyraEngine::prepDrawAllObjects() {
tempFlags = 1;
}
tempFlags |= 0x900 | flagUnk1 | 0x4000;
- _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, int(1), int(0)/*XXX*/, drawLayer, _brandonScaleX, _brandonScaleY);
+ _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _brandonPoisonFlagsGFX, int(1), int(0)/*XXX*/, drawLayer, _brandonScaleX, _brandonScaleY);
} else {
if (!(flagUnk2 & 0x4000)) {
tempFlags = 0;
@@ -3832,7 +4053,7 @@ void KyraEngine::prepDrawAllObjects() {
tempFlags |= 0x900 | flagUnk1;
}
- _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _unkBrandonPoisonFlags, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
+ _screen->drawShape(drawPage, _shapes[4+shapesIndex], xpos, ypos, 2, tempFlags | 4, _brandonPoisonFlagsGFX, int(1), drawLayer, _brandonScaleX, _brandonScaleY);
}
}
} else {
@@ -3864,7 +4085,7 @@ void KyraEngine::prepDrawAllObjects() {
if (!_scaleMode) {
if (flagUnk3 & 0x100) {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_unkBrandonPoisonFlags, 1, drawLayer);
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x100, (uint8*)_brandonPoisonFlagsGFX, 1, drawLayer);
} else if (flagUnk3 & 0x4000) {
// XXX
int hackVar = 0;
@@ -3874,7 +4095,7 @@ void KyraEngine::prepDrawAllObjects() {
}
} else {
if (flagUnk3 & 0x100) {
- _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_unkBrandonPoisonFlags, 1, drawLayer, _brandonScaleX, _brandonScaleY);
+ _screen->drawShape(drawPage, curObject->sceneAnimPtr, xpos, ypos, 2, curObject->flags | flagUnk1 | 0x104, (uint8*)_brandonPoisonFlagsGFX, 1, drawLayer, _brandonScaleX, _brandonScaleY);
} else if (flagUnk3 & 0x4000) {
// XXX
int hackVar = 0;
@@ -4421,6 +4642,29 @@ void KyraEngine::makeBrandonFaceMouse() {
updateAllObjectShapes();
}
+void KyraEngine::setBrandonPoisonFlags(int reset) {
+ debug(9, "setBrandonPoisonFlags(%d)", reset);
+ _brandonStatusBit |= 1;
+ if (reset)
+ _poisonDeathCounter = 0;
+ for (int i = 0; i < 0x100; ++i) {
+ _brandonPoisonFlagsGFX[i] = i;
+ }
+ _brandonPoisonFlagsGFX[0x99] = 0x34;
+ _brandonPoisonFlagsGFX[0x9A] = 0x35;
+ _brandonPoisonFlagsGFX[0x9B] = 0x37;
+ _brandonPoisonFlagsGFX[0x9C] = 0x38;
+ _brandonPoisonFlagsGFX[0x9D] = 0x2B;
+}
+
+void KyraEngine::resetBrandonPoisonFlags() {
+ debug(9, "resetBrandonPoisonFlags()");
+ _brandonStatusBit = 0;
+ for (int i = 0; i < 0x100; ++i) {
+ _brandonPoisonFlagsGFX[i] = i;
+ }
+}
+
#pragma mark -
#pragma mark - Pathfinder
#pragma mark -
@@ -5903,7 +6147,7 @@ int KyraEngine::buttonAmuletCallback(Button *caller) {
switch (jewel-1) {
case 0:
if (_brandonStatusBit & 1) {
- // seq_brandonHealing2
+ seq_brandonHealing2();
} else if (_brandonStatusBit == 0) {
seq_brandonHealing();
assert(_healingTip);
diff --git a/kyra/kyra.h b/kyra/kyra.h
index d39c0b1486..e415672d2c 100644
--- a/kyra/kyra.h
+++ b/kyra/kyra.h
@@ -505,6 +505,8 @@ protected:
void copyBackgroundBlock(int x, int page, int flag);
void copyBackgroundBlock2(int x);
void makeBrandonFaceMouse();
+ void setBrandonPoisonFlags(int reset);
+ void resetBrandonPoisonFlags();
void processInput(int xpos, int ypos);
int processInputHelper(int xpos, int ypos);
@@ -529,6 +531,7 @@ protected:
void itemSpecialFX1(int x, int y, int item);
void itemSpecialFX2(int x, int y, int item);
void magicOutMouseItem(int animIndex, int itemPos);
+ void magicInMouseItem(int animIndex, int item, int itemPos);
void specialMouseItemFX(int shape, int x, int y, int animIndex, int tableIndex, int loopStart, int maxLoops);
void processSpecialMouseItemFX(int shape, int x, int y, int tableValue, int loopStart, int maxLoops);
void updatePlayerItemsForScene();
@@ -559,6 +562,10 @@ protected:
void seq_introKallakMalcolm();
void seq_createAmuletJewel(int jewel, int page, int noSound, int drawOnly);
void seq_brandonHealing();
+ void seq_brandonHealing2();
+ void seq_poisonDeathNow(int now);
+ void seq_poisonDeathNowAnim();
+ void seq_playFluteAnimation();
void wsa_processFrame(WSAMovieV1 *wsa, int frameNum, uint8 *dst);
@@ -669,8 +676,9 @@ protected:
int16 _foyerItemTable[3];
uint16 _brandonStatusBit;
- uint8 _unkBrandonPoisonFlags[256]; // this seem not to be posion flags, it is used for drawing once
+ uint8 _brandonPoisonFlagsGFX[256]; // this seem not to be posion flags, it is used for drawing once
uint8 _deathHandler;
+ int8 _poisonDeathCounter;
int _brandonPosX;
int _brandonPosY;
int _brandonScaleX;
@@ -778,6 +786,8 @@ protected:
char **_blackJewel;
char **_poisonGone;
char **_healingTip;
+ char **_thePoison;
+ char **_fluteString;
int _itemList_Size;
int _takenList_Size;
@@ -789,6 +799,8 @@ protected:
int _blackJewel_Size;
int _poisonGone_Size;
int _healingTip_Size;
+ int _thePoison_Size;
+ int _fluteString_Size;
char **_characterImageTable;
int _characterImageTableSize;
@@ -801,6 +813,12 @@ protected:
Shape *_healingShape2Table;
int _healingShape2TableSize;
+ Shape *_posionDeathShapeTable;
+ int _posionDeathShapeTableSize;
+
+ Shape *_fluteAnimShapeTable;
+ int _fluteAnimShapeTableSize;
+
Room *_roomTable;
int _roomTableSize;
char **_roomFilenameTable;
diff --git a/kyra/script_v1.cpp b/kyra/script_v1.cpp
index 87a641b0a3..28beb26353 100644
--- a/kyra/script_v1.cpp
+++ b/kyra/script_v1.cpp
@@ -299,7 +299,8 @@ void ScriptHelper::c1_setRetAndJmp() {
#define stackPosString(x) (char*)&script->dataPtr->text[READ_BE_UINT16(&((uint16 *)script->dataPtr->text)[stackPos(x)])]
int KyraEngine::cmd_magicInMouseItem(ScriptState *script) {
- warning("STUB: cmd_magicInMouseItem");
+ debug(3, "cmd_magicInMouseItem(0x%X) (%d, %d)", script, stackPos(0), stackPos(1));
+ magicInMouseItem(stackPos(0), stackPos(1), -1);
return 0;
}
@@ -640,7 +641,8 @@ int KyraEngine::cmd_forceBrandonToNormal(ScriptState *script) {
}
int KyraEngine::cmd_poisonDeathNow(ScriptState *script) {
- warning("STUB: cmd_poisonDeathNow");
+ debug(3, "cmd_poisonDeathNow(0x%X) ()", script);
+ seq_poisonDeathNow(1);
return 0;
}
@@ -1579,7 +1581,8 @@ int KyraEngine::cmd_setSceneAnimCurrXY(ScriptState *script) {
}
int KyraEngine::cmd_poisonBrandonAndRemaps(ScriptState *script) {
- warning("STUB: cmd_poisonBrandonAndRemaps");
+ debug(3, "cmd_setSceneAnimCurrXY(0x%X) ()", script);
+ setBrandonPoisonFlags(1);
return 0;
}
@@ -1610,7 +1613,8 @@ int KyraEngine::cmd_queryBrandonStatusBit(ScriptState *script) {
}
int KyraEngine::cmd_playFluteAnimation(ScriptState *script) {
- warning("STUB: cmd_playFluteAnimation");
+ debug(3, "cmd_playFluteAnimation(0x%X) ()", script);
+ seq_playFluteAnimation();
return 0;
}
diff --git a/kyra/staticres.cpp b/kyra/staticres.cpp
index b691a54f2c..07ccb8773a 100644
--- a/kyra/staticres.cpp
+++ b/kyra/staticres.cpp
@@ -26,7 +26,7 @@
namespace Kyra {
-#define RESFILE_VERSION 7
+#define RESFILE_VERSION 8
#define GAME_FLAGS (GF_FLOPPY | GF_TALKIE | GF_DEMO | GF_AUDIOCD)
#define LANGUAGE_FLAGS (GF_ENGLISH | GF_FRENCH | GF_GERMAN | GF_SPANISH | GF_LNGUNK)
@@ -221,6 +221,12 @@ void KyraEngine::res_loadResources(int type) {
loadShapes(resFile, "HEALING.SHP", &_healingShapeTable, &_healingShapeTableSize);
loadShapes(resFile, "HEALING2.SHP", &_healingShape2Table, &_healingShape2TableSize);
+
+ res_loadLangTable("THEPOISON.", &resFile, (byte***)&_thePoison, &_thePoison_Size, loadNativeLanguage);
+ res_loadLangTable("FLUTE.", &resFile, (byte***)&_fluteString, &_fluteString_Size, loadNativeLanguage);
+
+ loadShapes(resFile, "POISONDEATH.SHP", &_posionDeathShapeTable, &_posionDeathShapeTableSize);
+ loadShapes(resFile, "FLUTE.SHP", &_fluteAnimShapeTable, &_fluteAnimShapeTableSize);
}
#undef loadRooms
@@ -285,6 +291,15 @@ void KyraEngine::res_unloadResources(int type) {
delete [] _healingShape2Table;
_healingShape2TableSize = 0;
+
+ res_freeLangTable(&_thePoison, &_thePoison_Size);
+ res_freeLangTable(&_fluteString, &_fluteString_Size);
+
+ delete [] _posionDeathShapeTable;
+ _posionDeathShapeTableSize = 0;
+
+ delete [] _fluteAnimShapeTable;
+ _fluteAnimShapeTableSize = 0;
}
}