aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra
diff options
context:
space:
mode:
authorJohannes Schickel2007-11-12 17:56:49 +0000
committerJohannes Schickel2007-11-12 17:56:49 +0000
commit2e46b741a350716eb674a3ea18938ef23329f43f (patch)
tree442fbcfc32a96bea705da168ca7c212ae8a32194 /engines/kyra
parent65c57841bd0a42188e4add5d504f8475fb0e3e80 (diff)
downloadscummvm-rg350-2e46b741a350716eb674a3ea18938ef23329f43f.tar.gz
scummvm-rg350-2e46b741a350716eb674a3ea18938ef23329f43f.tar.bz2
scummvm-rg350-2e46b741a350716eb674a3ea18938ef23329f43f.zip
- Implemented opcodes:
-> o2_removeHandItem 43 -> o2_makeBookOrCauldronAppear 42 - Implemented inventory WSA functionality svn-id: r29485
Diffstat (limited to 'engines/kyra')
-rw-r--r--engines/kyra/kyra_v2.cpp123
-rw-r--r--engines/kyra/kyra_v2.h24
-rw-r--r--engines/kyra/script_v2.cpp12
-rw-r--r--engines/kyra/sequences_v2.cpp109
4 files changed, 263 insertions, 5 deletions
diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp
index 7e573d69f3..33c3ddc6c0 100644
--- a/engines/kyra/kyra_v2.cpp
+++ b/engines/kyra/kyra_v2.cpp
@@ -85,6 +85,8 @@ KyraEngine_v2::KyraEngine_v2(OSystem *system, const GameFlags &flags) : KyraEngi
_currentTalkSections.TLKTim = NULL;
_currentTalkSections.ENDTim = NULL;
+ _invWsa.wsa = 0;
+
memset(&_sceneScriptData, 0, sizeof(_sceneScriptData));
}
@@ -96,6 +98,7 @@ KyraEngine_v2::~KyraEngine_v2() {
delete _text;
_text = 0;
delete _debugger;
+ delete _invWsa.wsa;
}
Movie *KyraEngine_v2::createWSAMovie() {
@@ -492,7 +495,7 @@ void KyraEngine_v2::update() {
updateSpecialSceneScripts();
_timer->update();
//sub_274C0();
- //updateInvWsa();
+ updateInvWsa();
//sub_1574C();
_screen->updateScreen();
}
@@ -505,7 +508,7 @@ void KyraEngine_v2::updateWithText() {
updateSpecialSceneScripts();
_timer->update();
//sub_274C0();
- //updateInvWsa();
+ updateInvWsa();
restorePage3();
drawAnimObjects();
@@ -1542,6 +1545,118 @@ void KyraEngine_v2::playVoice(int high, int low) {
#pragma mark -
+void KyraEngine_v2::loadInvWsa(const char *filename, int run, int delayTime, int page, int sfx, int sFrame, int flags) {
+ int wsaFlags = 1;
+ if (flags)
+ wsaFlags |= 2;
+
+ if (!_invWsa.wsa)
+ _invWsa.wsa = new WSAMovieV2(this);
+
+ if (!_invWsa.wsa->open(filename, wsaFlags, 0))
+ error("Couldn't open inventory WSA file '%s'", filename);
+
+ _invWsa.curFrame = 0;
+ _invWsa.lastFrame = _invWsa.wsa->frames();
+
+ _invWsa.x = _invWsa.wsa->xAdd();
+ _invWsa.y = _invWsa.wsa->yAdd();
+ _invWsa.w = _invWsa.wsa->width();
+ _invWsa.h = _invWsa.wsa->height();
+ _invWsa.x2 = _invWsa.x + _invWsa.w - 1;
+ _invWsa.y2 = _invWsa.y + _invWsa.h - 1;
+
+ _invWsa.delay = delayTime;
+ _invWsa.page = page;
+ _invWsa.sfx = sfx;
+
+ _invWsa.specialFrame = sFrame;
+
+ if (_invWsa.page)
+ _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, 0, _invWsa.page, Screen::CR_NO_P_CHECK);
+
+ _invWsa.running = true;
+ _invWsa.timer = _system->getMillis();
+
+ if (run) {
+ while (_invWsa.running && !_skipFlag && !_quitFlag) {
+ update();
+ //XXX delay?
+ }
+ }
+}
+
+void KyraEngine_v2::closeInvWsa() {
+ _invWsa.wsa->close();
+ delete _invWsa.wsa;
+ _invWsa.wsa = 0;
+ _invWsa.running = false;
+}
+
+void KyraEngine_v2::updateInvWsa() {
+ if (!_invWsa.running || !_invWsa.wsa)
+ return;
+
+ if (_invWsa.timer > _system->getMillis())
+ return;
+
+ _invWsa.wsa->setX(0);
+ _invWsa.wsa->setY(0);
+ _invWsa.wsa->setDrawPage(_invWsa.page);
+ _invWsa.wsa->displayFrame(_invWsa.curFrame, 0, 0, 0);
+
+ if (_invWsa.page)
+ _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK);
+
+ _invWsa.timer = _system->getMillis() + _invWsa.delay * _tickLength;
+
+ ++_invWsa.curFrame;
+ if (_invWsa.curFrame >= _invWsa.lastFrame)
+ displayInvWsaLastFrame();
+
+ if (_invWsa.curFrame == _invWsa.specialFrame)
+ snd_playSoundEffect(_invWsa.sfx);
+
+ if (_invWsa.sfx == -2) {
+ switch (_invWsa.curFrame) {
+ case 9: case 27: case 40:
+ snd_playSoundEffect(0x39);
+ break;
+
+ case 18: case 34: case 44:
+ snd_playSoundEffect(0x33);
+ break;
+
+ case 48:
+ snd_playSoundEffect(0x38);
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+void KyraEngine_v2::displayInvWsaLastFrame() {
+ if (!_invWsa.wsa)
+ return;
+
+ _invWsa.wsa->setX(0);
+ _invWsa.wsa->setY(0);
+ _invWsa.wsa->setDrawPage(_invWsa.page);
+ _invWsa.wsa->displayFrame(_invWsa.lastFrame-1, 0, 0, 0);
+
+ if (_invWsa.page)
+ _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK);
+
+ closeInvWsa();
+
+ int32 countdown = _rnd.getRandomNumberRng(45, 80);
+ _timer->setCountdown(2, countdown * 60);
+}
+
+#pragma mark -
+
typedef Functor1Mem<ScriptState*, int, KyraEngine_v2> OpcodeV2;
#define Opcode(x) OpcodeV2(this, &KyraEngine_v2::x)
#define OpcodeUnImpl() OpcodeV2(this, 0)
@@ -1601,7 +1716,7 @@ void KyraEngine_v2::setupOpcodeTable() {
Opcode(o2_resetGameFlag),
Opcode(o2_setGameFlag),
Opcode(o2_setHandItem),
- OpcodeUnImpl(),
+ Opcode(o2_removeHandItem),
// 0x2c
Opcode(o2_handItemSet),
Opcode(o2_hideMouse),
@@ -1725,7 +1840,7 @@ void KyraEngine_v2::setupOpcodeTable() {
// 0x8c
Opcode(o2_deinitObject),
OpcodeUnImpl(),
- OpcodeUnImpl(),
+ Opcode(o2_makeBookOrCauldronAppear),
Opcode(o2_setSpecialSceneScriptState),
// 0x90
Opcode(o2_clearSpecialSceneScriptState),
diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h
index 008c508050..bdefcc6f1e 100644
--- a/engines/kyra/kyra_v2.h
+++ b/engines/kyra/kyra_v2.h
@@ -693,6 +693,28 @@ protected:
byte* loadTIMFile(const char *filename, byte *buffer, int32 bufferSize);
void freeTIM(byte *buffer);
+ // ingame static sequence handling
+ void seq_makeBookOrCauldronAppear(int type);
+ void seq_makeBookAppear();
+
+ struct InventoryWsa {
+ int x, y, x2, y2, w, h;
+ int page;
+ int curFrame, lastFrame, specialFrame;
+ int sfx;
+ int delay;
+ bool running;
+ uint32 timer;
+ WSAMovieV2 *wsa;
+ } _invWsa;
+
+ // TODO: move inside KyraEngine_v2::InventoryWsa?
+ void loadInvWsa(const char *filename, int run, int delay, int page, int sfx, int sFrame, int flags);
+ void closeInvWsa();
+
+ void updateInvWsa();
+ void displayInvWsaLastFrame();
+
// opcodes
int o2_setCharacterFacingRefresh(ScriptState *script);
int o2_setCharacterPos(ScriptState *script);
@@ -716,6 +738,7 @@ protected:
int o2_resetGameFlag(ScriptState *script);
int o2_setGameFlag(ScriptState *script);
int o2_setHandItem(ScriptState *script);
+ int o2_removeHandItem(ScriptState *script);
int o2_handItemSet(ScriptState *script);
int o2_hideMouse(ScriptState *script);
int o2_addSpecialExit(ScriptState *script);
@@ -750,6 +773,7 @@ protected:
int o2_countItemInstances(ScriptState *script);
int o2_initObject(ScriptState *script);
int o2_deinitObject(ScriptState *script);
+ int o2_makeBookOrCauldronAppear(ScriptState *script);
int o2_setSpecialSceneScriptState(ScriptState *script);
int o2_clearSpecialSceneScriptState(ScriptState *script);
int o2_querySpecialSceneScriptState(ScriptState *script);
diff --git a/engines/kyra/script_v2.cpp b/engines/kyra/script_v2.cpp
index f984dbb66b..e3bdfe198a 100644
--- a/engines/kyra/script_v2.cpp
+++ b/engines/kyra/script_v2.cpp
@@ -305,6 +305,12 @@ int KyraEngine_v2::o2_setHandItem(ScriptState *script) {
return 0;
}
+int KyraEngine_v2::o2_removeHandItem(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_removeHandItem(%p) ()", (const void *)script);
+ removeHandItem();
+ return 0;
+}
+
int KyraEngine_v2::o2_handItemSet(ScriptState *script) {
debugC(3, kDebugLevelScriptFuncs, "o2_handItemSet(%p) ()", (const void *)script);
return _handItemSet;
@@ -670,14 +676,18 @@ int KyraEngine_v2::o2_countItemInstances(ScriptState *script) {
int KyraEngine_v2::o2_initObject(ScriptState *script) {
debugC(3, kDebugLevelScriptFuncs, "o2_initObject(%p) (%d)", (const void *)script, stackPos(0));
initTalkObject(stackPos(0));
-
return 0;
}
int KyraEngine_v2::o2_deinitObject(ScriptState *script) {
debugC(3, kDebugLevelScriptFuncs, "o2_deinitObject(%p) (%d)", (const void *)script, stackPos(0));
deinitTalkObject(stackPos(0));
+ return 0;
+}
+int KyraEngine_v2::o2_makeBookOrCauldronAppear(ScriptState *script) {
+ debugC(3, kDebugLevelScriptFuncs, "o2_makeBookOrCauldronAppear(%p) (%d)", (const void *)script, stackPos(0));
+ seq_makeBookOrCauldronAppear(stackPos(0));
return 0;
}
diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp
index 206342e2e8..f6f92eb169 100644
--- a/engines/kyra/sequences_v2.cpp
+++ b/engines/kyra/sequences_v2.cpp
@@ -29,6 +29,7 @@
#include "kyra/wsamovie.h"
#include "kyra/sound.h"
#include "kyra/text_v2.h"
+#include "kyra/timer.h"
#include "common/system.h"
@@ -2173,6 +2174,114 @@ void KyraEngine_v2::seq_uninit() {
_seqWsa = NULL;
}
+#pragma mark -
+#pragma mark - Ingame sequences
+#pragma mark -
+
+void KyraEngine_v2::seq_makeBookOrCauldronAppear(int type) {
+ _screen->hideMouse();
+ showMessage(0, 0xCF);
+
+ if (type == 1) {
+ seq_makeBookAppear();
+ } else if (type == 2) {
+ loadInvWsa("CAULDRON.WSA", 1, 6, 0, -2, -2, 1);
+ }
+
+ _screen->copyRegionToBuffer(2, 0, 0, 320, 200, _screenBuffer);
+ _screen->loadBitmap("_PLAYALL.CPS", 3, 3, 0);
+
+ static int16 bookCauldronRects[] = {
+ 0x46, 0x90, 0x7F, 0x2B, // unknown rect (maybe unused?)
+ 0xCE, 0x90, 0x2C, 0x2C, // book rect
+ 0xFA, 0x90, 0x46, 0x2C // cauldron rect
+ };
+
+ int x = bookCauldronRects[type*4+0];
+ int y = bookCauldronRects[type*4+1];
+ int w = bookCauldronRects[type*4+2];
+ int h = bookCauldronRects[type*4+3];
+ _screen->copyRegion(x, y, x, y, w, h, 2, 0, Screen::CR_NO_P_CHECK);
+
+ _screen->copyBlockToPage(2, 0, 0, 320, 200, _screenBuffer);
+
+ if (type == 2) {
+ int32 countdown = _rnd.getRandomNumberRng(45, 80);
+ _timer->setCountdown(2, countdown * 60);
+ }
+
+ _screen->showMouse();
+}
+
+void KyraEngine_v2::seq_makeBookAppear() {
+ _screen->hideMouse();
+
+ displayInvWsaLastFrame();
+
+ showMessage(0, 0xCF);
+
+ loadInvWsa("BOOK2.WSA", 0, 4, 2, -1, -1, 0);
+
+ uint8 *rect = new uint8[_screen->getRectSize(_invWsa.w, _invWsa.h)];
+ assert(rect);
+
+ _screen->copyRegionToBuffer(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect);
+
+ _invWsa.running = false;
+ snd_playSoundEffect(0xAF);
+
+ _invWsa.wsa->setX(0);
+ _invWsa.wsa->setY(0);
+ _invWsa.wsa->setDrawPage(_invWsa.page);
+
+ while (true) {
+ _invWsa.timer = _system->getMillis() + _invWsa.delay * _tickLength;
+
+ _screen->copyBlockToPage(_invWsa.page, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, rect);
+
+ _invWsa.wsa->displayFrame(_invWsa.curFrame, 0x4000, 0, 0);
+
+ if (_invWsa.page)
+ _screen->copyRegion(_invWsa.x, _invWsa.y, _invWsa.x, _invWsa.y, _invWsa.w, _invWsa.h, _invWsa.page, 0, Screen::CR_NO_P_CHECK);
+
+ ++_invWsa.curFrame;
+
+ if (_invWsa.curFrame >= _invWsa.lastFrame && !_quitFlag)
+ break;
+
+ switch (_invWsa.curFrame) {
+ case 39:
+ snd_playSoundEffect(0xCA);
+ break;
+
+ case 50:
+ snd_playSoundEffect(0x6A);
+ break;
+
+ case 72:
+ snd_playSoundEffect(0xCB);
+ break;
+
+ case 85:
+ snd_playSoundEffect(0x38);
+ break;
+
+ default:
+ break;
+ }
+
+ do {
+ update();
+ } while (_invWsa.timer > _system->getMillis() && !_skipFlag);
+ }
+
+ closeInvWsa();
+ delete [] rect;
+ _invWsa.running = false;
+
+ _screen->showMouse();
+}
+
// static res
// TODO: move to staticres.cpp