- Implemented opcodes:
-> o2_removeHandItem 43 -> o2_makeBookOrCauldronAppear 42 - Implemented inventory WSA functionality svn-id: r29485
This commit is contained in:
parent
65c57841bd
commit
2e46b741a3
4 changed files with 263 additions and 5 deletions
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue