Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,455 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "kyra/script/script.h"
#include "kyra/kyra_v1.h"
#include "kyra/resource/resource.h"
#include "common/endian.h"
namespace Kyra {
EMCInterpreter::EMCInterpreter(KyraEngine_v1 *vm) : _vm(vm), _scriptData(nullptr), _filename(nullptr), _parameter(0) {
#define OPCODE(x) { &EMCInterpreter::x, #x }
static const OpcodeEntry opcodes[] = {
// 0x00
OPCODE(op_jmp),
OPCODE(op_setRetValue),
OPCODE(op_pushRetOrPos),
OPCODE(op_push),
// 0x04
OPCODE(op_push),
OPCODE(op_pushReg),
OPCODE(op_pushBPNeg),
OPCODE(op_pushBPAdd),
// 0x08
OPCODE(op_popRetOrPos),
OPCODE(op_popReg),
OPCODE(op_popBPNeg),
OPCODE(op_popBPAdd),
// 0x0C
OPCODE(op_addSP),
OPCODE(op_subSP),
OPCODE(op_sysCall),
OPCODE(op_ifNotJmp),
// 0x10
OPCODE(op_negate),
OPCODE(op_eval),
OPCODE(op_setRetAndJmp)
};
_opcodes = opcodes;
#undef OPCODE
}
bool EMCInterpreter::callback(Common::IFFChunk &chunk) {
switch (chunk._type) {
case MKTAG('T','E','X','T'):
_scriptData->text = new byte[chunk._size];
assert(_scriptData->text);
if (chunk._stream->read(_scriptData->text, chunk._size) != chunk._size)
error("Couldn't read TEXT chunk from file '%s'", _filename);
break;
case MKTAG('O','R','D','R'):
_scriptData->ordr = new uint16[chunk._size >> 1];
_scriptData->ordrSize = chunk._size;
assert(_scriptData->ordr);
if (chunk._stream->read(_scriptData->ordr, chunk._size) != chunk._size)
error("Couldn't read ORDR chunk from file '%s'", _filename);
for (int i = (chunk._size >> 1) - 1; i >= 0; --i)
_scriptData->ordr[i] = READ_BE_UINT16(&_scriptData->ordr[i]);
break;
case MKTAG('D','A','T','A'):
_scriptData->data = new uint16[chunk._size >> 1];
_scriptData->dataSize = chunk._size;
assert(_scriptData->data);
if (chunk._stream->read(_scriptData->data, chunk._size) != chunk._size)
error("Couldn't read DATA chunk from file '%s'", _filename);
for (int i = (chunk._size >> 1) - 1; i >= 0; --i)
_scriptData->data[i] = READ_BE_UINT16(&_scriptData->data[i]);
break;
default:
warning("Unexpected chunk '%s' of size %d found in file '%s'", tag2str(chunk._type), chunk._size, _filename);
}
return false;
}
bool EMCInterpreter::load(const char *filename, EMCData *scriptData, const Common::Array<const Opcode *> *opcodes) {
Common::SeekableReadStream *stream = _vm->resource()->createReadStream(filename);
if (!stream) {
error("Couldn't open script file '%s'", filename);
return false; // for compilers that don't support NORETURN
}
memset(scriptData, 0, sizeof(EMCData));
_scriptData = scriptData;
_filename = filename;
IFFParser iff(*stream);
Common::Functor1Mem< Common::IFFChunk &, bool, EMCInterpreter > c(this, &EMCInterpreter::callback);
iff.parse(c);
if (!_scriptData->ordr)
error("No ORDR chunk found in file: '%s'", filename);
if (!_scriptData->data)
error("No DATA chunk found in file: '%s'", filename);
if (stream->err())
error("Read error while parsing file '%s'", filename);
delete stream;
_scriptData->sysFuncs = opcodes;
Common::strlcpy(_scriptData->filename, filename, 13);
_scriptData = nullptr;
_filename = nullptr;
return true;
}
void EMCInterpreter::unload(EMCData *data) {
if (!data)
return;
delete[] data->text;
delete[] data->ordr;
delete[] data->data;
data->text = nullptr;
data->ordr = data->data = nullptr;
}
void EMCInterpreter::init(EMCState *scriptStat, const EMCData *data) {
scriptStat->dataPtr = data;
scriptStat->ip = nullptr;
scriptStat->stack[EMCState::kStackLastEntry] = 0;
scriptStat->bp = EMCState::kStackSize+1;
scriptStat->sp = EMCState::kStackLastEntry;
}
bool EMCInterpreter::start(EMCState *script, int function) {
if (!script->dataPtr)
return false;
if (function >= (int) script->dataPtr->ordrSize / 2 || function < 0)
return false;
uint16 functionOffset = script->dataPtr->ordr[function];
if (functionOffset == 0xFFFF)
return false;
if (_vm->game() == GI_KYRA1) {
if (_vm->gameFlags().platform == Common::kPlatformFMTowns || _vm->gameFlags().platform == Common::kPlatformPC98 || _vm->gameFlags().lang == Common::KO_KOR)
script->ip = &script->dataPtr->data[functionOffset+1];
else
script->ip = &script->dataPtr->data[functionOffset];
} else {
if (functionOffset+1 >= (int) script->dataPtr->dataSize / 2)
return false;
script->ip = &script->dataPtr->data[functionOffset+1];
}
return true;
}
bool EMCInterpreter::isValid(EMCState *script) {
if (!script->ip || !script->dataPtr || _vm->shouldQuit())
return false;
return true;
}
bool EMCInterpreter::run(EMCState *script) {
_parameter = 0;
if (!script->ip)
return false;
// Should be no Problem at all to cast to uint32 here, since that's the biggest ptrdiff the original
// would allow, of course that's not realistic to happen to be somewhere near the limit of uint32 anyway.
const uint32 instOffset = (uint32)((const byte *)script->ip - (const byte *)script->dataPtr->data);
if ((int32)instOffset < 0 || instOffset >= script->dataPtr->dataSize) {
error("Attempt to execute out of bounds: 0x%.08X out of 0x%.08X",
instOffset, script->dataPtr->dataSize);
}
int16 code = *script->ip++;
int16 opcode = (code >> 8) & 0x1F;
if (code & 0x8000) {
opcode = 0;
_parameter = code & 0x7FFF;
} else if (code & 0x4000) {
_parameter = (int8)(code);
} else if (code & 0x2000) {
_parameter = *script->ip++;
} else {
_parameter = 0;
}
if (opcode > 18) {
error("Unknown script opcode: %d in file '%s' at offset 0x%.08X", opcode, script->dataPtr->filename, instOffset);
} else {
debugC(5, kDebugLevelScript, "[0x%.08X] EMCInterpreter::%s([%d/%u])", instOffset, _opcodes[opcode].desc, _parameter, (uint)_parameter);
(this->*(_opcodes[opcode].proc))(script);
}
return (script->ip != nullptr);
}
#pragma mark -
#pragma mark - Command implementations
#pragma mark -
void EMCInterpreter::op_jmp(EMCState *script) {
script->ip = script->dataPtr->data + _parameter;
}
void EMCInterpreter::op_setRetValue(EMCState *script) {
script->retValue = _parameter;
}
void EMCInterpreter::op_pushRetOrPos(EMCState *script) {
switch (_parameter) {
case 0:
script->stack[--script->sp] = script->retValue;
break;
case 1:
script->stack[--script->sp] = script->ip - script->dataPtr->data + 1;
script->stack[--script->sp] = script->bp;
script->bp = script->sp + 2;
break;
default:
script->ip = nullptr;
}
}
void EMCInterpreter::op_push(EMCState *script) {
script->stack[--script->sp] = _parameter;
}
void EMCInterpreter::op_pushReg(EMCState *script) {
script->stack[--script->sp] = script->regs[_parameter];
}
void EMCInterpreter::op_pushBPNeg(EMCState *script) {
script->stack[--script->sp] = script->stack[(-(int32)(_parameter + 2)) + script->bp];
}
void EMCInterpreter::op_pushBPAdd(EMCState *script) {
script->stack[--script->sp] = script->stack[(_parameter - 1) + script->bp];
}
void EMCInterpreter::op_popRetOrPos(EMCState *script) {
switch (_parameter) {
case 0:
script->retValue = script->stack[script->sp++];
break;
case 1:
if (script->sp >= EMCState::kStackLastEntry) {
script->ip = nullptr;
} else {
script->bp = script->stack[script->sp++];
script->ip = script->dataPtr->data + script->stack[script->sp++];
}
break;
default:
script->ip = nullptr;
}
}
void EMCInterpreter::op_popReg(EMCState *script) {
script->regs[_parameter] = script->stack[script->sp++];
}
void EMCInterpreter::op_popBPNeg(EMCState *script) {
script->stack[(-(int32)(_parameter + 2)) + script->bp] = script->stack[script->sp++];
}
void EMCInterpreter::op_popBPAdd(EMCState *script) {
script->stack[(_parameter - 1) + script->bp] = script->stack[script->sp++];
}
void EMCInterpreter::op_addSP(EMCState *script) {
script->sp += _parameter;
}
void EMCInterpreter::op_subSP(EMCState *script) {
script->sp -= _parameter;
}
void EMCInterpreter::op_sysCall(EMCState *script) {
const uint8 id = _parameter;
assert(script->dataPtr->sysFuncs);
assert(id < script->dataPtr->sysFuncs->size());
if ((*script->dataPtr->sysFuncs)[id] && ((*script->dataPtr->sysFuncs)[id])->isValid()) {
script->retValue = (*(*script->dataPtr->sysFuncs)[id])(script);
} else {
script->retValue = 0;
warning("Unimplemented system call 0x%.02X/%d used in file '%s'", id, id, script->dataPtr->filename);
}
}
void EMCInterpreter::op_ifNotJmp(EMCState *script) {
if (!script->stack[script->sp++]) {
_parameter &= 0x7FFF;
script->ip = script->dataPtr->data + _parameter;
}
}
void EMCInterpreter::op_negate(EMCState *script) {
int16 value = script->stack[script->sp];
switch (_parameter) {
case 0:
if (!value)
script->stack[script->sp] = 1;
else
script->stack[script->sp] = 0;
break;
case 1:
script->stack[script->sp] = -value;
break;
case 2:
script->stack[script->sp] = ~value;
break;
default:
warning("Unknown negation func: %d", _parameter);
script->ip = nullptr;
}
}
void EMCInterpreter::op_eval(EMCState *script) {
int16 ret = 0;
bool error = false;
int16 val1 = script->stack[script->sp++];
int16 val2 = script->stack[script->sp++];
switch (_parameter) {
case 0:
ret = (val2 && val1) ? 1 : 0;
break;
case 1:
ret = (val2 || val1) ? 1 : 0;
break;
case 2:
ret = (val1 == val2) ? 1 : 0;
break;
case 3:
ret = (val1 != val2) ? 1 : 0;
break;
case 4:
ret = (val1 > val2) ? 1 : 0;
break;
case 5:
ret = (val1 >= val2) ? 1 : 0;
break;
case 6:
ret = (val1 < val2) ? 1 : 0;
break;
case 7:
ret = (val1 <= val2) ? 1 : 0;
break;
case 8:
ret = val1 + val2;
break;
case 9:
ret = val2 - val1;
break;
case 10:
ret = val1 * val2;
break;
case 11:
ret = val2 / val1;
break;
case 12:
ret = val2 >> val1;
break;
case 13:
ret = val2 << val1;
break;
case 14:
ret = val1 & val2;
break;
case 15:
ret = val1 | val2;
break;
case 16:
ret = val2 % val1;
break;
case 17:
ret = val1 ^ val2;
break;
default:
warning("Unknown evaluate func: %d", _parameter);
error = true;
}
if (error)
script->ip = nullptr;
else
script->stack[--script->sp] = ret;
}
void EMCInterpreter::op_setRetAndJmp(EMCState *script) {
if (script->sp >= EMCState::kStackLastEntry) {
script->ip = nullptr;
} else {
script->retValue = script->stack[script->sp++];
uint16 temp = script->stack[script->sp++];
script->stack[EMCState::kStackLastEntry] = 0;
script->ip = &script->dataPtr->data[temp];
}
}
} // End of namespace Kyra

View File

@@ -0,0 +1,164 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef KYRA_SCRIPT_H
#define KYRA_SCRIPT_H
#include "common/stream.h"
#include "common/array.h"
#include "common/func.h"
#include "common/formats/iff_container.h"
namespace Kyra {
struct EMCState;
typedef Common::Functor1<EMCState *, int> Opcode;
struct EMCData {
char filename[13];
byte *text;
uint16 *data;
uint32 ordrSize;
uint16 *ordr;
uint32 dataSize;
const Common::Array<const Opcode *> *sysFuncs;
};
struct EMCState {
enum {
kStackSize = 100,
kStackLastEntry = kStackSize - 1
};
const uint16 *ip;
const EMCData *dataPtr;
int16 retValue;
uint16 bp;
uint16 sp;
int16 regs[30]; // VM registers
int16 stack[kStackSize]; // VM stack
};
#ifdef RELEASE_BUILD
#define stackPos(x) (script->stack[script->sp+x])
#else
#define stackPos(x) emcSafeReadStack(script, x, __LINE__, __FILE__)
#endif
#define safeStackPos(x) (script->sp+x < EMCState::kStackSize ? stackPos(x) : 0)
#define stackPosString(x) ((const char *)&script->dataPtr->text[READ_BE_UINT16(&script->dataPtr->text[stackPos(x)<<1])])
class Resource;
class KyraEngine_v1;
class IFFParser : public Common::IFFParser {
public:
IFFParser(Common::ReadStream &input) : Common::IFFParser(&input) {
// It seems Westwood missunderstood the 'size' field of the FORM chunk.
//
// For EMC scripts (type EMC2) it's filesize instead of filesize - 8,
// means accidentally including the 8 bytes used by the chunk header for the FORM
// chunk.
//
// For TIM scripts (type AVFS) it's filesize - 12 instead of filesize - 8,
// means it will not include the size of the 'type' field in the FORM chunk,
// instead of only not including the chunk header size.
//
// Both lead to some problems in our IFF parser, either reading after the end
// of file or producing a "Chunk overread" error message. To work around this
// we need to adjust the size field properly.
// Fix for certain Russian fan translations:
// Westwood's original code completely ignores the FORM chunk and its size
// setting. After opening a TIM or EMC file they just check whether the FORM
// chunk exists (as a kind of file type verification) and then immediately seek
// behind the FORM chunk.
// This means that their parser is immune to weird fan translation scripts
// where the file size doesn't match the form chunk size. In our implemetation
// this would produce "Chunk overread" errors.
// Westwood also always pads all chunk sizes to 2 byte alignment after reading
// them from the file (not with FORM though, since they completely ignore it).
// This seems to do the trick for our FORM chunk size issue with the Russian
// fan translations. Another method which I have tried and which seems to work
// well would be simply setting _formChunk.size to the file size (-12 for TIM).
_formChunk.size = (_formChunk.size + 1) & ~1;
if (_formType == MKTAG('E','M','C','2'))
_formChunk.size -= 8;
else if (_formType == MKTAG('A','V','F','S'))
_formChunk.size += 4;
}
};
class EMCInterpreter {
public:
EMCInterpreter(KyraEngine_v1 *vm);
bool load(const char *filename, EMCData *data, const Common::Array<const Opcode *> *opcodes);
void unload(EMCData *data);
void init(EMCState *scriptState, const EMCData *data);
bool start(EMCState *script, int function);
bool isValid(EMCState *script);
bool run(EMCState *script);
protected:
KyraEngine_v1 *_vm;
int16 _parameter;
const char *_filename;
EMCData *_scriptData;
bool callback(Common::IFFChunk &chunk);
typedef void (EMCInterpreter::*OpcodeProc)(EMCState *);
struct OpcodeEntry {
OpcodeProc proc;
const char *desc;
};
const OpcodeEntry *_opcodes;
private:
void op_jmp(EMCState *);
void op_setRetValue(EMCState *);
void op_pushRetOrPos(EMCState *);
void op_push(EMCState *);
void op_pushReg(EMCState *);
void op_pushBPNeg(EMCState *);
void op_pushBPAdd(EMCState *);
void op_popRetOrPos(EMCState *);
void op_popReg(EMCState *);
void op_popBPNeg(EMCState *);
void op_popBPAdd(EMCState *);
void op_addSP(EMCState *);
void op_subSP(EMCState *);
void op_sysCall(EMCState *);
void op_ifNotJmp(EMCState *);
void op_negate(EMCState *);
void op_eval(EMCState *);
void op_setRetAndJmp(EMCState *);
};
} // End of namespace Kyra
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,132 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef ENABLE_EOB
#ifndef KYRA_SCRIPT_EOB_H
#define KYRA_SCRIPT_EOB_H
#include "common/func.h"
#include "common/substream.h"
#include "common/savefile.h"
namespace Kyra {
class KyraRpgEngine;
class EoBInfProcessor {
public:
EoBInfProcessor(EoBCoreEngine *engine, Screen_EoB *_screen);
~EoBInfProcessor();
void loadData(const uint8 *data, uint32 dataSize);
void run(int func, int flags);
void setFlags(uint32 flags);
void clearFlags(uint32 flags);
bool checkFlags(uint32 flags) const;
bool preventRest() const;
void loadState(Common::SeekableReadStreamEndian &in, bool origFile = false);
void saveState(Common::OutSaveFile *out, bool origFile = false);
void reset();
private:
const char *getString(uint16 index);
int oeob_setWallType(int8 *data);
int oeob_toggleWallState(int8 *data);
int oeob_openDoor(int8 *data);
int oeob_closeDoor(int8 *data);
int oeob_replaceMonster(int8 *data);
int oeob_movePartyOrObject(int8 *data);
int oeob_moveInventoryItemToBlock(int8 *data);
int oeob_printMessage_v1(int8 *data);
int oeob_printMessage_v2(int8 *data);
int oeob_setFlags(int8 *data);
int oeob_playSoundEffect(int8 *data);
int oeob_removeFlags(int8 *data);
int oeob_modifyCharacterHitPoints(int8 *data);
int oeob_calcAndInflictCharacterDamage(int8 *data);
int oeob_jump(int8 *data);
int oeob_end(int8 *data);
int oeob_returnFromSubroutine(int8 *data);
int oeob_callSubroutine(int8 *data);
int oeob_eval_v1(int8 *data);
int oeob_eval_v2(int8 *data);
int oeob_deleteItem(int8 *data);
int oeob_loadNewLevelOrMonsters(int8 *data);
int oeob_increasePartyExperience(int8 *data);
int oeob_createItem_v1(int8 *data);
int oeob_createItem_v2(int8 *data);
int oeob_launchObject(int8 *data);
int oeob_changeDirection(int8 *data);
int oeob_identifyItems(int8 *data);
int oeob_sequence(int8 *data);
int oeob_delay(int8 *data);
int oeob_drawScene(int8 *data);
int oeob_dialogue(int8 *data);
int oeob_specialEvent(int8 *data);
EoBCoreEngine *_vm;
Screen_EoB *_screen;
typedef Common::Functor1Mem<int8 *, int, EoBInfProcessor> InfProc;
struct InfOpcode : private Common::NonCopyable {
InfOpcode(InfProc *p, const char *d) : proc(p), desc(d) {}
~InfOpcode() { delete proc; }
InfProc *proc;
Common::String desc;
};
Common::Array<const InfOpcode *> _opcodes;
int8 *_scriptData;
uint16 _scriptSize;
uint8 _abortScript;
uint16 _abortAfterSubroutine;
int _dlgResult;
uint8 _preventRest;
uint16 _lastScriptFunc;
uint16 _lastScriptFlags;
int8 **_subroutineStack;
int _subroutineStackPos;
uint32 *_flagTable;
int16 *_stack;
int _stackIndex;
int8 _activeCharacter;
static const uint8 _segaCDColorMap[16];
const int _commandMin;
};
} // End of namespace Kyra
#endif
#endif // ENABLE_EOB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,305 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef KYRA_SCRIPT_TIM_H
#define KYRA_SCRIPT_TIM_H
#include "kyra/kyra_v1.h"
#include "common/array.h"
#include "common/func.h"
#include "common/str.h"
namespace Kyra {
class WSAMovie_v2;
class Screen_v2;
class Movie;
class LoLEngine;
class TimAnimator {
public:
struct AnimPart {
uint16 firstFrame;
uint16 lastFrame;
uint16 cycles;
int16 nextPart;
int16 partDelay;
uint16 field_A;
int16 sfxIndex;
uint16 sfxFrame;
};
struct Animation {
Movie *wsa;
int16 x, y;
uint32 nextFrame;
uint8 enable;
uint8 field_D;
uint8 frameDelay;
int8 curPart;
uint8 curFrame;
uint8 cyclesCompleted;
uint16 wsaCopyParams;
int8 lastPart;
AnimPart *parts;
};
#ifdef ENABLE_LOL
TimAnimator(LoLEngine *engine, Screen_v2 *screen_v2, OSystem *system, bool useParts);
#else
TimAnimator(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSystem *system, bool useParts);
#endif
~TimAnimator();
void init(int animIndex, Movie *wsa, int x, int y, int wsaCopyParams, int frameDelay);
void reset(int animIndex, bool clearStruct);
void displayFrame(int animIndex, int page, int frame, int flags = -1);
const Movie *getWsaCPtr(int animIndex) { return (animIndex >= 0 && animIndex < 6) ? _animations[animIndex].wsa : 0; }
int getAnimX(int animIndex) { return (animIndex >= 0 && animIndex < 6) ? _animations[animIndex].x : 0; }
int getAnimY(int animIndex) { return (animIndex >= 0 && animIndex < 6) ? _animations[animIndex].y : 0; }
#ifdef ENABLE_LOL
void setupPart(int animIndex, int part, int firstFrame, int lastFrame, int cycles, int nextPart, int partDelay, int f, int sfxIndex, int sfxFrame);
void start(int animIndex, int part);
void stop(int animIndex);
void update(int animIndex);
void playPart(int animIndex, int firstFrame, int lastFrame, int delay);
int resetLastPart(int animIndex);
#endif
private:
#ifdef ENABLE_LOL
LoLEngine *_vm;
#else
KyraEngine_v1 *_vm;
#endif
Screen_v2 *_screen;
OSystem *_system;
Animation *_animations;
const bool _useParts;
};
struct TIM;
typedef Common::Functor2<const TIM *, const uint16 *, int> TIMOpcode;
struct TIM {
char filename[13];
uint16 clickedButton;
int16 dlgFunc;
int16 procFunc;
uint16 procParam;
enum {
kCountFuncs = 10
};
struct Function {
uint16 *ip;
uint32 lastTime;
uint32 nextTime;
uint16 *loopIp;
uint16 *avtl;
} func[kCountFuncs];
enum {
kWSASlots = 6,
kAnimParts = 10
};
struct WSASlot {
int anim;
int16 x, y;
uint16 wsaFlags;
uint16 offscreen;
} wsa[kWSASlots];
uint16 *avtl;
uint8 *text;
const Common::Array<const TIMOpcode *> *opcodes;
// TODO: Get rid of this ugly HACK to allow the
// Lands of Lore outro to be working properly.
bool isLoLOutro;
uint8 lolCharacter;
};
class TIMInterpreter {
public:
TIMInterpreter(KyraEngine_v1 *engine, Screen_v2 *screen_v2, OSystem *system);
virtual ~TIMInterpreter();
TIM *load(const char *filename, const Common::Array<const TIMOpcode *> *opcodes);
void unload(TIM *&tim) const;
bool callback(Common::IFFChunk &chunk);
virtual int initAnimStruct(int index, const char *filename, int x, int y, int, int offscreenBuffer, uint16 wsaFlags);
virtual int freeAnimStruct(int index);
TimAnimator *animator() { return _animator; }
void setLangData(const char *filename);
void clearLangData() { delete[] _langData; _langData = 0; }
const char *getCTableEntry(uint idx) const;
void resetFinishedFlag() { _finished = false; }
bool finished() const { return _finished; }
int exec(TIM *tim, bool loop);
void stopCurFunc() { if (_currentTim) cmd_stopCurFunc(0); }
void stopAllFuncs(TIM *tim);
void refreshTimersAfterPause(uint32 elapsedTime);
void displayText(uint16 textId, int16 flags);
void displayText(uint16 textId, int16 flags, uint8 color);
void setupTextPalette(uint index, int fadePalette);
virtual void resetDialogueState(TIM *tim) {}
int _drawPage2;
int _palDelayInc, _palDiff, _palDelayAcc;
int _abortFlag;
protected:
KyraEngine_v1 *_vm;
Screen_v2 *_screen;
OSystem *_system;
TIM *_currentTim;
int _currentFunc;
TimAnimator *_animator;
bool _finished;
// used when loading
int _avtlChunkSize;
const char *_filename;
TIM *_tim;
Common::String _vocFiles[120];
virtual void update() {}
virtual void checkSpeechProgress() {}
char _audioFilename[32];
uint8 *_langData;
char *getTableEntry(uint idx);
bool _textDisplayed;
uint8 *_textAreaBuffer;
virtual int execCommand(int cmd, const uint16 *param);
typedef int (TIMInterpreter::*CommandProc)(const uint16 *);
struct CommandEntry {
CommandProc proc;
const char *desc;
};
const CommandEntry *_commands;
int _commandsSize;
int cmd_initFunc0(const uint16 *param);
int cmd_stopCurFunc(const uint16 *param);
int cmd_initWSA(const uint16 *param);
int cmd_uninitWSA(const uint16 *param);
int cmd_initFunc(const uint16 *param);
int cmd_stopFunc(const uint16 *param);
int cmd_wsaDisplayFrame(const uint16 *param);
int cmd_displayText(const uint16 *param);
int cmd_loadVocFile(const uint16 *param);
int cmd_unloadVocFile(const uint16 *param);
int cmd_playVocFile(const uint16 *param);
int cmd_loadSoundFile(const uint16 *param);
int cmd_playMusicTrack(const uint16 *param);
virtual int cmd_setLoopIp(const uint16 *param);
virtual int cmd_continueLoop(const uint16 *param);
int cmd_resetLoopIp(const uint16 *param);
int cmd_resetAllRuntimes(const uint16 *param);
int cmd_execOpcode(const uint16 *param);
int cmd_initFuncNow(const uint16 *param);
int cmd_stopFuncNow(const uint16 *param);
#define cmd_return(n, v) \
int cmd_return_##n(const uint16 *){ return v; }
cmd_return( 1, 1)
cmd_return(n1, -1)
#undef cmd_return
};
#ifdef ENABLE_LOL
class LoLEngine;
class Screen_LoL;
class TIMInterpreter_LoL : public TIMInterpreter {
public:
TIMInterpreter_LoL(LoLEngine *engine, Screen_v2 *screen_v2, OSystem *system);
int initAnimStruct(int index, const char *filename, int x, int y, int frameDelay, int, uint16 wsaCopyParams) override;
int freeAnimStruct(int index) override;
void resetDialogueState(TIM *tim) override;
private:
void update() override;
void checkSpeechProgress() override;
const char *getTableString(int id);
void advanceToOpcode(int opcode);
LoLEngine *_vm;
Screen_LoL *_screen;
int execCommand(int cmd, const uint16 *param) override;
typedef int (TIMInterpreter_LoL::*CommandProc)(const uint16 *);
struct CommandEntry {
CommandProc proc;
const char *desc;
};
const CommandEntry *_commands;
int _commandsSize;
int cmd_stopAllFuncs(const uint16 *param);
int cmd_setLoopIp(const uint16 *param) override;
int cmd_continueLoop(const uint16 *param) override;
int cmd_processDialogue(const uint16 *param);
int cmd_dialogueBox(const uint16 *param);
};
#endif // ENABLE_LOL
} // End of namespace Kyra
#endif

View File

@@ -0,0 +1,125 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "kyra/kyra_v1.h"
#include "kyra/graphics/screen.h"
#include "common/system.h"
namespace Kyra {
int KyraEngine_v1::o1_queryGameFlag(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_queryGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
return queryGameFlag(stackPos(0));
}
int KyraEngine_v1::o1_setGameFlag(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
return setGameFlag(stackPos(0));
}
int KyraEngine_v1::o1_resetGameFlag(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_resetGameFlag(%p) (0x%X)", (const void *)script, stackPos(0));
return resetGameFlag(stackPos(0));
}
int KyraEngine_v1::o1_getRand(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getRand(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
int min = stackPos(0);
int max = stackPos(1);
if (max < min)
SWAP(min, max);
return _rnd.getRandomNumberRng(min, max);
}
int KyraEngine_v1::o1_hideMouse(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_hideMouse(%p) ()", (const void *)script);
screen()->hideMouse();
return 0;
}
int KyraEngine_v1::o1_showMouse(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_showMouse(%p) ()", (const void *)script);
screen()->showMouse();
return 0;
}
int KyraEngine_v1::o1_setMousePos(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setMousePos(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
setMousePos(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_setHandItem(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setHandItem(%p) (%d)", (const void *)script, stackPos(0));
setHandItem(stackPos(0));
return 0;
}
int KyraEngine_v1::o1_removeHandItem(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_removeHandItem(%p) ()", (const void *)script);
removeHandItem();
return 0;
}
int KyraEngine_v1::o1_getMouseState(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_getMouseState(%p) ()", (const void *)script);
return _mouseState;
}
int KyraEngine_v1::o1_setDeathHandler(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_setDeathHandler(%p) (%d)", (const void *)script, stackPos(0));
_deathHandler = stackPos(0);
return 0;
}
int KyraEngine_v1::o1_playWanderScoreViaMap(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playWanderScoreViaMap(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
snd_playWanderScoreViaMap(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v1::o1_fillRect(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_fillRect(%p) (%d, %d, %d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
screen()->fillRect(stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(0));
return 0;
}
int KyraEngine_v1::o1_blockInWalkableRegion(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockInWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
screen()->blockInRegion(stackPos(0), stackPos(1), stackPos(2) - stackPos(0) + 1, stackPos(3) - stackPos(1) + 1);
return 0;
}
int KyraEngine_v1::o1_blockOutWalkableRegion(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_blockOutWalkableRegion(%p) (%d, %d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2), stackPos(3));
screen()->blockOutRegion(stackPos(0), stackPos(1), stackPos(2) - stackPos(0) + 1, stackPos(3) - stackPos(1) + 1);
return 0;
}
int KyraEngine_v1::o1_playSoundEffect(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v1::o1_playSoundEffect(%p) (%d)", (const void *)script, stackPos(0));
if (!_preventScriptSfx)
snd_playSoundEffect(stackPos(0));
return 0;
}
} // End of namespace Kyra

View File

@@ -0,0 +1,341 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "kyra/engine/kyra_v2.h"
#include "kyra/graphics/screen_v2.h"
#include "kyra/engine/timer.h"
#include "common/system.h"
namespace Kyra {
int KyraEngine_v2::o2_getCharacterX(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterX(%p) ()", (const void *)script);
return _mainCharacter.x1;
}
int KyraEngine_v2::o2_getCharacterY(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterY(%p) ()", (const void *)script);
return _mainCharacter.y1;
}
int KyraEngine_v2::o2_getCharacterFacing(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterFacing(%p) ()", (const void *)script);
return _mainCharacter.facing;
}
int KyraEngine_v2::o2_getCharacterScene(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getCharacterScene(%p) ()", (const void *)script);
return _mainCharacter.sceneId;
}
int KyraEngine_v2::o2_setCharacterFacingOverwrite(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setCharacterFacingOverwrite(%p) (%d)", (const void *)script, stackPos(0));
_mainCharacter.facing = stackPos(0);
_overwriteSceneFacing = true;
return 0;
}
int KyraEngine_v2::o2_trySceneChange(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_trySceneChange(%p) (%d, %d, %d, %d)", (const void *)script,
stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_unkHandleSceneChangeFlag = 1;
int success = inputSceneChange(stackPos(0), stackPos(1), stackPos(2), stackPos(3));
_unkHandleSceneChangeFlag = 0;
if (success) {
_emc->init(script, script->dataPtr);
_unk4 = 0;
_savedMouseState = -1;
_unk5 = 1;
return 0;
} else {
return (_unk4 != 0) ? 1 : 0;
}
}
int KyraEngine_v2::o2_moveCharacter(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_moveCharacter(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
moveCharacter(stackPos(0), stackPos(1), stackPos(2));
return 0;
}
int KyraEngine_v2::o2_checkForItem(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_checkForItem(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
return findItem(stackPos(0), stackPos(1)) == -1 ? 0 : 1;
}
int KyraEngine_v2::o2_defineItem(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineItem(%p) (%d, %d, %d, %d)", (const void *)script,
stackPos(0), stackPos(1), stackPos(2), stackPos(3));
int freeItem = findFreeItem();
if (freeItem >= 0) {
_itemList[freeItem].id = stackPos(0);
_itemList[freeItem].x = stackPos(1);
_itemList[freeItem].y = stackPos(2);
_itemList[freeItem].sceneId = stackPos(3);
}
return freeItem;
}
int KyraEngine_v2::o2_addSpecialExit(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_addSpecialExit(%p) (%d, %d, %d, %d, %d)", (const void *)script,
stackPos(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4));
if (_specialExitCount < 5) {
_specialExitTable[_specialExitCount + 0] = stackPos(0);
_specialExitTable[_specialExitCount + 5] = stackPos(1);
_specialExitTable[_specialExitCount + 10] = stackPos(2) + stackPos(0) - 1;
_specialExitTable[_specialExitCount + 15] = stackPos(3) + stackPos(1) - 1;
_specialExitTable[_specialExitCount + 20] = stackPos(4);
++_specialExitCount;
}
return 0;
}
int KyraEngine_v2::o2_delay(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_delay(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
if (stackPos(1)) {
uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength;
while (_system->getMillis() < maxWaitTime) {
int inputFlag = checkInput(nullptr);
removeInputTop();
if (inputFlag == 198 || inputFlag == 199)
return 1;
if (!_chatText.empty())
updateWithText();
else
update();
_system->delayMillis(10);
}
} else {
delay(stackPos(0) * _tickLength, true);
}
return 0;
}
int KyraEngine_v2::o2_update(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_update(%p) (%d)", (const void *)script, stackPos(0));
for (int times = stackPos(0); times != 0; --times) {
if (!_chatText.empty())
updateWithText();
else
update();
}
return 0;
}
int KyraEngine_v2::o2_getShapeFlag1(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getShapeFlag1(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
return screen()->getShapeFlag1(stackPos(0), stackPos(1));
}
int KyraEngine_v2::o2_waitForConfirmationClick(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_waitForConfirmationClick(%p) (%d)", (const void *)script, stackPos(0));
resetSkipFlag();
uint32 maxWaitTime = _system->getMillis() + stackPos(0) * _tickLength;
while (_system->getMillis() < maxWaitTime) {
int inputFlag = checkInput(nullptr);
removeInputTop();
if (inputFlag == 198 || inputFlag == 199) {
_sceneScriptState.regs[1] = _mouseX;
_sceneScriptState.regs[2] = _mouseY;
return 0;
}
update();
_system->delayMillis(10);
}
_sceneScriptState.regs[1] = _mouseX;
_sceneScriptState.regs[2] = _mouseY;
return 1;
}
int KyraEngine_v2::o2_randomSceneChat(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_randomSceneChat(%p)", (const void *)script);
randomSceneChat();
return 0;
}
int KyraEngine_v2::o2_setDlgIndex(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setDlgIndex(%p) (%d)", (const void *)script, stackPos(0));
setDlgIndex(stackPos(0));
return 0;
}
int KyraEngine_v2::o2_getDlgIndex(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getDlgIndex(%p) ()", (const void *)script);
return _mainCharacter.dlgIndex;
}
int KyraEngine_v2::o2_defineRoomEntrance(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineRoomEntrance(%p) (%d, %d, %d)", (const void *)script, stackPos(0), stackPos(1), stackPos(2));
switch (stackPos(0)) {
case 0:
_sceneEnterX1 = stackPos(1);
_sceneEnterY1 = stackPos(2);
break;
case 1:
_sceneEnterX2 = stackPos(1);
_sceneEnterY2 = stackPos(2);
break;
case 2:
_sceneEnterX3 = stackPos(1);
_sceneEnterY3 = stackPos(2);
break;
case 3:
_sceneEnterX4 = stackPos(1);
_sceneEnterY4 = stackPos(2);
break;
default:
break;
}
return 0;
}
int KyraEngine_v2::o2_runAnimationScript(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_runAnimationScript(%p) ('%s', %d, %d, %d)", (const void *)script, stackPosString(0), stackPos(1),
stackPos(2), stackPos(3));
runAnimationScript(stackPosString(0), stackPos(3), stackPos(2) ? 1 : 0, stackPos(1), stackPos(2));
return 0;
}
int KyraEngine_v2::o2_setSpecialSceneScriptRunTime(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setSpecialSceneScriptRunTime(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
assert(stackPos(0) >= 0 && stackPos(0) < 10);
_sceneSpecialScriptsTimer[stackPos(0)] = _system->getMillis() + stackPos(1) * _tickLength;
return 0;
}
int KyraEngine_v2::o2_defineScene(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_defineScene(%p) (%d, '%s', %d, %d, %d, %d, %d, %d)",
(const void *)script, stackPos(0), stackPosString(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5), stackPos(6), stackPos(7));
const int scene = stackPos(0);
Common::strlcpy(_sceneList[scene].filename1, stackPosString(1), sizeof(_sceneList[scene].filename1));
Common::strlcpy(_sceneList[scene].filename2, stackPosString(1), sizeof(_sceneList[scene].filename2));
_sceneList[scene].exit1 = stackPos(2);
_sceneList[scene].exit2 = stackPos(3);
_sceneList[scene].exit3 = stackPos(4);
_sceneList[scene].exit4 = stackPos(5);
_sceneList[scene].flags = stackPos(6);
_sceneList[scene].sound = stackPos(7);
if (_mainCharacter.sceneId == scene) {
_sceneExit1 = _sceneList[scene].exit1;
_sceneExit2 = _sceneList[scene].exit2;
_sceneExit3 = _sceneList[scene].exit3;
_sceneExit4 = _sceneList[scene].exit4;
}
return 0;
}
int KyraEngine_v2::o2_setSpecialSceneScriptState(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0));
_specialSceneScriptState[stackPos(0)] = 1;
return 1;
}
int KyraEngine_v2::o2_clearSpecialSceneScriptState(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_clearSpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0));
_specialSceneScriptState[stackPos(0)] = 0;
return 0;
}
int KyraEngine_v2::o2_querySpecialSceneScriptState(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_querySpecialSceneScriptState(%p) (%d)", (const void *)script, stackPos(0));
return _specialSceneScriptState[stackPos(0)];
}
int KyraEngine_v2::o2_setHiddenItemsEntry(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setHiddenItemsEntry(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
return (_hiddenItems[stackPos(0)] = stackPos(1));
}
int KyraEngine_v2::o2_getHiddenItemsEntry(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getHiddenItemsEntry(%p) (%d)", (const void *)script, stackPos(0));
return (int16)_hiddenItems[stackPos(0)];
}
int KyraEngine_v2::o2_disableTimer(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_disableTimer(%p) (%d)", (const void *)script, stackPos(0));
_timer->disable(stackPos(0));
return 0;
}
int KyraEngine_v2::o2_enableTimer(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_enableTimer(%p) (%d)", (const void *)script, stackPos(0));
_timer->enable(stackPos(0));
return 0;
}
int KyraEngine_v2::o2_setTimerCountdown(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setTimerCountdown(%p) (%d, %d)", (const void *)script, stackPos(0), stackPos(1));
_timer->setCountdown(stackPos(0), stackPos(1));
return 0;
}
int KyraEngine_v2::o2_setVocHigh(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_setVocHigh(%p) (%d)", (const void *)script, stackPos(0));
_vocHigh = stackPos(0);
return _vocHigh;
}
int KyraEngine_v2::o2_getVocHigh(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2_getVocHigh(%p) ()", (const void *)script);
return _vocHigh;
}
#pragma mark -
int KyraEngine_v2::o2a_setAnimationShapes(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_v2::o2a_setAnimationShapes(%p) ('%s', %d, %d, %d, %d, %d)", (const void *)script,
stackPosString(0), stackPos(1), stackPos(2), stackPos(3), stackPos(4), stackPos(5));
Common::strlcpy(_animShapeFilename, stackPosString(0), sizeof(_animShapeFilename));
_animShapeLastEntry = stackPos(1);
_animShapeWidth = stackPos(2);
_animShapeHeight = stackPos(3);
_animShapeXAdd = stackPos(4);
_animShapeYAdd = stackPos(5);
return 0;
}
int KyraEngine_v2::o2a_setResetFrame(EMCState *script) {
debugC(3, kDebugLevelScriptFuncs, "KyraEngine_MR::o3t_setResetFrame(%p) (%d)", (const void *)script, stackPos(0));
_animResetFrame = stackPos(0);
return 0;
}
} // End of namespace Kyra