- Implemented opcodes:

-> o2_removeHandItem 43
  -> o2_makeBookOrCauldronAppear 42
- Implemented inventory WSA functionality

svn-id: r29485
This commit is contained in:
Johannes Schickel 2007-11-12 17:56:49 +00:00
parent 65c57841bd
commit 2e46b741a3
4 changed files with 263 additions and 5 deletions

View file

@ -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),

View file

@ -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);

View file

@ -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;
}

View file

@ -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