diff options
author | Eugene Sandulenko | 2006-01-05 16:06:55 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2006-01-05 16:06:55 +0000 |
commit | 3adee6125dfab45cfb667eebe3ab631e8dd49401 (patch) | |
tree | 1c1a579aa1a0f738c57ee1f71918ac472f9018a4 | |
parent | 56f1e7d6afa03959c40244385700393208db5c1b (diff) | |
download | scummvm-rg350-3adee6125dfab45cfb667eebe3ab631e8dd49401.tar.gz scummvm-rg350-3adee6125dfab45cfb667eebe3ab631e8dd49401.tar.bz2 scummvm-rg350-3adee6125dfab45cfb667eebe3ab631e8dd49401.zip |
Slighty modified patch #1397672 "GobEngine script functions splitted"
svn-id: r19918
-rw-r--r-- | gob/gob.cpp | 93 | ||||
-rw-r--r-- | gob/gob.h | 18 | ||||
-rw-r--r-- | gob/inter.cpp | 1488 | ||||
-rw-r--r-- | gob/inter.h | 198 | ||||
-rw-r--r-- | gob/inter_v1.cpp | 1613 | ||||
-rw-r--r-- | gob/inter_v2.cpp | 514 | ||||
-rw-r--r-- | gob/module.mk | 2 |
7 files changed, 2398 insertions, 1528 deletions
diff --git a/gob/gob.cpp b/gob/gob.cpp index ed6a24bd3b..9dd2cd7e4e 100644 --- a/gob/gob.cpp +++ b/gob/gob.cpp @@ -20,7 +20,6 @@ */ #include "common/stdafx.h" -#include "base/gameDetector.h" #include "base/plugins.h" #include "backends/fs/fs.h" #include "common/md5.h" @@ -50,18 +49,7 @@ enum { kMD5FileSizeLimit = 1024 * 1024 }; -struct GobGameSettings { - const char *name; - const char *description; - uint32 features; - const char *md5sum; - GameSettings toGameSettings() const { - GameSettings dummy = { name, description, features }; - return dummy; - } -}; - -static const GobGameSettings gob_games[] = { +static const Gob::GobGameSettings gob_games[] = { // Supplied by Florian Zeitz on scummvm-devel {"gob1", "Gobliiins (DOS EGA)", Gob::GF_GOB1, "82aea70ef26f41fa963dfae270993e49"}, {"gob1", "Gobliiins (DOS EGA)", Gob::GF_GOB1, "1f499458837008058b8ba6ae07057214"}, @@ -144,7 +132,7 @@ GameList Engine_GOB_gameList() { DetectedGameList Engine_GOB_detectGames(const FSList &fslist) { DetectedGameList detectedGames; - const GobGameSettings *g; + const Gob::GobGameSettings *g; FSList::const_iterator file; // Iterate over all files in the given directory @@ -186,26 +174,6 @@ DetectedGameList Engine_GOB_detectGames(const FSList &fslist) { } Engine *Engine_GOB_create(GameDetector * detector, OSystem *syst) { - return new Gob::GobEngine(detector, syst); -} - -REGISTER_PLUGIN(GOB, "Gob Engine") - -namespace Gob { -#define MAX_TIME_DELTA 100 -GobEngine *_vm = NULL; - -GobEngine::GobEngine(GameDetector *detector, OSystem * syst) : Engine(syst) { - // Setup mixer - if (!_mixer->isReady()) { - warning("Sound initialization failed."); - } - - _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); - _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); - - _vm = this; - // Detect game features based on MD5 uint8 md5sum[16]; char md5str[32 + 1]; @@ -215,20 +183,20 @@ GobEngine::GobEngine(GameDetector *detector, OSystem * syst) : Engine(syst) { sprintf(md5str + j*2, "%02x", (int)md5sum[j]); } } else { - error("GobEngine::GobEngine(): Cannot find intro.stk"); + error("Engine_GOB_create(): Cannot find intro.stk"); } - const GobGameSettings *g; + const Gob::GobGameSettings *g; bool found = false; // TODO // Fallback. Maybe we will be able to determine game type from game // data contents - _features = GF_GOB1; + uint32 features = Gob::GF_GOB1; for (g = gob_games; g->name; g++) { if (strcmp(g->md5sum, (char *)md5str) == 0) { - _features = g->features; + features = g->features; if (g->description) g_system->setWindowCaption(g->description); @@ -241,6 +209,27 @@ GobEngine::GobEngine(GameDetector *detector, OSystem * syst) : Engine(syst) { if (!found) { printf("Unknown MD5 (%s)! Please report the details (language, platform, etc.) of this game to the ScummVM team\n", md5str); } + + return new Gob::GobEngine(detector, syst, features); +} + +REGISTER_PLUGIN(GOB, "Gob Engine") + +namespace Gob { +#define MAX_TIME_DELTA 100 +//GobEngine *_vm = NULL; + +GobEngine::GobEngine(GameDetector *detector, OSystem * syst, uint32 features) + : Engine(syst) { + // Setup mixer + if (!_mixer->isReady()) { + warning("Sound initialization failed."); + } + + _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume")); + _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume")); + + _features = features; } GobEngine::~GobEngine() { @@ -263,12 +252,23 @@ GobEngine::~GobEngine() { delete _scenery; delete _gtimer; delete _util; + delete _inter; } void GobEngine::errorString(const char *buf1, char *buf2) { strcpy(buf2, buf1); } +int GobEngine::go() { + _init->initGame(0); + + return 0; +} + +void GobEngine::shutdown() { + _system->quit(); +} + int GobEngine::init(GameDetector &detector) { _game = new Game(this); _snd = new Snd(this); @@ -280,7 +280,6 @@ int GobEngine::init(GameDetector &detector) { _dataio = new DataIO(this); _goblin = new Goblin(this); _init = new Init(this); - _inter = new Inter(this); _map = new Map(this); _mult = new Mult(this); _pack = new Pack(); @@ -289,6 +288,12 @@ int GobEngine::init(GameDetector &detector) { _scenery = new Scenery(this); _gtimer = new GTimer(); _util = new Util(this); + if (_features & Gob::GF_GOB1) + _inter = new Inter_v1(this); + else if (_features & Gob::GF_GOB2) + _inter = new Inter_v2(this); + else + error("GobEngine::init(): Unknown version of game engine"); _system->beginGFXTransaction(); initCommonGFX(detector); @@ -338,14 +343,4 @@ int GobEngine::init(GameDetector &detector) { return 0; } -int GobEngine::go() { - _init->initGame(0); - - return 0; -} - -void GobEngine::shutdown() { - _system->quit(); -} - } // End of namespace Gob @@ -28,6 +28,7 @@ #include "common/config-manager.h" #include "base/engine.h" +#include "base/gameDetector.h" #include "gob/dataio.h" #include "gob/video.h" @@ -70,6 +71,17 @@ enum { GF_CD = 1 << 4 }; +typedef struct GobGameSettings { + const char *name; + const char *description; + uint32 features; + const char *md5sum; + GameSettings toGameSettings() const { + GameSettings dummy = { name, description, features }; + return dummy; + } +} GobGameSettings; + class GobEngine : public Engine { void errorString(const char *buf_input, char *buf_output); @@ -78,7 +90,7 @@ protected: int init(GameDetector &detector); public: - GobEngine(GameDetector * detector, OSystem * syst); + GobEngine(GameDetector * detector, OSystem * syst, uint32 features); virtual ~GobEngine(); void shutdown(); @@ -96,7 +108,6 @@ public: DataIO *_dataio; Goblin *_goblin; Init *_init; - Inter *_inter; Map *_map; Mult *_mult; Pack *_pack; @@ -105,9 +116,8 @@ public: Scenery *_scenery; GTimer *_gtimer; Util *_util; + Inter *_inter; }; -extern GobEngine *_vm; - } // End of namespace Gob #endif diff --git a/gob/inter.cpp b/gob/inter.cpp index 82b829f5b7..f80f1c2dfd 100644 --- a/gob/inter.cpp +++ b/gob/inter.cpp @@ -51,13 +51,6 @@ int16 Inter::load16(void) { return tmp; } -void Inter::setMousePos(void) { - _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); - _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); - if (_vm->_global->_useMouse != 0) - _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); -} - char Inter::evalExpr(int16 *pRes) { byte token; @@ -97,102 +90,6 @@ char Inter::evalBoolResult() { return 0; } -void Inter::evaluateStore(void) { - char *savedPos; - int16 token; - int16 result; - int16 varOff; - - savedPos = _vm->_global->_inter_execPtr; - varOff = _vm->_parse->parseVarIndex(); - token = evalExpr(&result); - switch (savedPos[0]) { - case 23: - case 26: - WRITE_VAR_OFFSET(varOff, _vm->_global->_inter_resVal); - break; - - case 25: - case 28: - if (token == 20) - *(_vm->_global->_inter_variables + varOff) = result; - else - strcpy(_vm->_global->_inter_variables + varOff, _vm->_global->_inter_resStr); - break; - - } - return; -} - -void Inter::capturePush(void) { - int16 left; - int16 top; - int16 width; - int16 height; - - left = _vm->_parse->parseValExpr(); - top = _vm->_parse->parseValExpr(); - width = _vm->_parse->parseValExpr(); - height = _vm->_parse->parseValExpr(); - _vm->_game->capturePush(left, top, width, height); - (*_vm->_scenery->pCaptureCounter)++; -} - -void Inter::capturePop(void) { - if (*_vm->_scenery->pCaptureCounter != 0) { - (*_vm->_scenery->pCaptureCounter)--; - _vm->_game->capturePop(1); - } -} - -void Inter::printText(void) { - char buf[60]; - int16 i; - - debug(3, "printText"); - _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->backColor = _vm->_parse->parseValExpr(); - _vm->_draw->frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->fontIndex = _vm->_parse->parseValExpr(); - _vm->_draw->destSurface = 21; - _vm->_draw->textToPrint = buf; - _vm->_draw->transparency = 0; - - if (_vm->_draw->backColor >= 16) { - _vm->_draw->backColor = 0; - _vm->_draw->transparency = 1; - } - - do { - for (i = 0; *_vm->_global->_inter_execPtr != '.' && (byte)*_vm->_global->_inter_execPtr != 200; - i++, _vm->_global->_inter_execPtr++) { - buf[i] = *_vm->_global->_inter_execPtr; - } - - if ((byte)*_vm->_global->_inter_execPtr != 200) { - _vm->_global->_inter_execPtr++; - switch (*_vm->_global->_inter_execPtr) { - case 23: - case 26: - sprintf(buf + i, "%d", VAR_OFFSET(_vm->_parse->parseVarIndex())); - break; - - case 25: - case 28: - sprintf(buf + i, "%s", _vm->_global->_inter_variables + _vm->_parse->parseVarIndex()); - break; - } - _vm->_global->_inter_execPtr++; - } else { - buf[i] = 0; - } - _vm->_draw->spriteOperation(DRAW_PRINTTEXT); - } while ((byte)*_vm->_global->_inter_execPtr != 200); - _vm->_global->_inter_execPtr++; -} - void Inter::animPalette(void) { int16 i; Video::Color col; @@ -221,816 +118,60 @@ void Inter::animPalette(void) { _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); } -void Inter::animPalInit(void) { - _animPalDir = load16(); - _animPalLowIndex = _vm->_parse->parseValExpr(); - _animPalHighIndex = _vm->_parse->parseValExpr(); -} - -void Inter::loadMult(void) { - int16 resId; - - resId = load16(); - _vm->_mult->loadMult(resId); -} - -void Inter::playMult(void) { - int16 checkEscape; - - checkEscape = load16(); - _vm->_mult->playMult(VAR(57), -1, checkEscape, 0); -} - -void Inter::freeMult(void) { - load16(); // unused - _vm->_mult->freeMultKeys(); -} - -void Inter::initCursor(void) { - int16 width; - int16 height; - int16 count; - int16 i; - - _vm->_draw->cursorXDeltaVar = _vm->_parse->parseVarIndex(); - _vm->_draw->cursorYDeltaVar = _vm->_parse->parseVarIndex(); - - width = load16(); - if (width < 16) - width = 16; - - height = load16(); - if (height < 16) - height = 16; - - count = load16(); - if (count < 2) - count = 2; - - if (width != _vm->_draw->cursorWidth || height != _vm->_draw->cursorHeight || - _vm->_draw->cursorSprites->width != width * count) { - - _vm->_video->freeSurfDesc(_vm->_draw->cursorSprites); - _vm->_video->freeSurfDesc(_vm->_draw->cursorBack); - - _vm->_draw->cursorWidth = width; - _vm->_draw->cursorHeight = height; - - if (count < 0x80) - _vm->_draw->transparentCursor = 1; - else - _vm->_draw->transparentCursor = 0; - - if (count > 0x80) - count -= 0x80; - - _vm->_draw->cursorSprites = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->cursorWidth * count, - _vm->_draw->cursorHeight, 2); - _vm->_draw->spritesArray[23] = _vm->_draw->cursorSprites; - - _vm->_draw->cursorBack = - _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->cursorWidth, - _vm->_draw->cursorHeight, 0); - for (i = 0; i < 40; i++) { - _vm->_draw->cursorAnimLow[i] = -1; - _vm->_draw->cursorAnimDelays[i] = 0; - _vm->_draw->cursorAnimHigh[i] = 0; - } - _vm->_draw->cursorAnimLow[1] = 0; - } -} - -void Inter::initCursorAnim(void) { - int16 ind; - - ind = _vm->_parse->parseValExpr(); - _vm->_draw->cursorAnimLow[ind] = load16(); - _vm->_draw->cursorAnimHigh[ind] = load16(); - _vm->_draw->cursorAnimDelays[ind] = load16(); -} - -void Inter::clearCursorAnim(void) { - int16 ind; - - ind = _vm->_parse->parseValExpr(); - _vm->_draw->cursorAnimLow[ind] = -1; - _vm->_draw->cursorAnimHigh[ind] = 0; - _vm->_draw->cursorAnimDelays[ind] = 0; -} - -void Inter::drawOperations(void) { +void Inter::funcBlock(int16 retFlag) { + char cmdCount; + int16 counter; byte cmd; - int16 i; - - cmd = *_vm->_global->_inter_execPtr++; - - debug(4, "drawOperations(%d)", cmd); - - switch (cmd) { - case 0: - loadMult(); - break; - - case 1: - playMult(); - break; - - case 2: - freeMult(); - break; - - case 7: - initCursor(); - break; - - case 8: - initCursorAnim(); - break; - - case 9: - clearCursorAnim(); - break; - - case 10: - _vm->_draw->renderFlags = _vm->_parse->parseValExpr(); - break; - - case 11: - //word_23EC_DE = _vm->_parse->parseValExpr(); - break; - - case 16: - _vm->_scenery->loadAnim(0); - break; - - case 17: - _vm->_scenery->freeAnim(-1); - break; - - case 18: - _vm->_scenery->interUpdateAnim(); - break; - - case 19: - warning("Gob2 mult stub"); - break; - - case 20: - _vm->_mult->interInitMult(); - break; - - case 21: - _vm->_mult->freeMult(); - break; - - case 22: - _vm->_mult->animate(); - break; - - case 23: - _vm->_mult->interLoadMult(); - break; - - case 24: - _vm->_scenery->interStoreParams(); - break; - - case 25: - _vm->_mult->interGetObjAnimSize(); - break; - - case 26: - _vm->_scenery->loadStatic(0); - break; - - case 27: - _vm->_scenery->freeStatic(-1); - break; - - case 28: - _vm->_scenery->interRenderStatic(); - break; - - case 29: - _vm->_scenery->interLoadCurLayer(); - break; - - case 32: - if (_vm->_features & GF_GOB1) { - // Used in gob1 CD - evalExpr(0); - _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); - } else { - } - break; - - case 33: - if (_vm->_features & GF_GOB1) { - // Used in gob1 CD - - // Some scripts busy-wait while calling this opcode. - // This is a very nasty thing to do, so let's add a - // short delay here. It's probably a safe thing to do. - - _vm->_util->longDelay(1); - - int pos = _vm->_cdrom->getTrackPos(); - if (pos == -1) - pos = 32767; - WRITE_VAR(5, pos); - } else { - } - break; - - case 34: - if (_vm->_features & GF_GOB1) { - // Used in gob1 CD - _vm->_cdrom->stopPlaying(); - } else { - } - break; - - case 35: - if (_vm->_features & GF_GOB2) { - } - break; - - case 36: - if (_vm->_features & GF_GOB2) { - } - break; - - case 37: - if (_vm->_features & GF_GOB2) { - } - break; - - case 48: - i = load16(); - _vm->_draw->fontToSprite[i].sprite = load16(); - _vm->_draw->fontToSprite[i].base = load16(); - _vm->_draw->fontToSprite[i].width = load16(); - _vm->_draw->fontToSprite[i].height = load16(); - break; - - case 49: - i = load16(); - _vm->_draw->fontToSprite[i].sprite = -1; - _vm->_draw->fontToSprite[i].base = -1; - _vm->_draw->fontToSprite[i].width = -1; - _vm->_draw->fontToSprite[i].height = -1; - break; - - case 64: - if (_vm->_features & GF_GOB2) { - } - break; - - case 65: - if (_vm->_features & GF_GOB2) { - } - break; - - case 66: - if (_vm->_features & GF_GOB2) { - } - break; - - case 67: - if (_vm->_features & GF_GOB2) { - } - break; - - case 80: - if (_vm->_features & GF_GOB2) { - } - break; - - case 81: - if (_vm->_features & GF_GOB2) { - } - break; - - case 82: - if (_vm->_features & GF_GOB2) { - } - break; - - case 83: - if (_vm->_features & GF_GOB2) { - } - break; - - case 84: - if (_vm->_features & GF_GOB2) { - } - break; - - case 85: - if (_vm->_features & GF_GOB2) { - } - break; - - case 86: - if (_vm->_features & GF_GOB2) { - } - break; - - case 128: - if (_vm->_features & GF_GOB2) { - } - break; - - case 129: - if (_vm->_features & GF_GOB2) { - } - break; - - case 130: - if (_vm->_features & GF_GOB2) { - } - break; - - case 131: - if (_vm->_features & GF_GOB2) { - } - break; - - case 132: - if (_vm->_features & GF_GOB2) { - } - break; - - case 133: - if (_vm->_features & GF_GOB2) { - } - break; - - case 134: - if (_vm->_features & GF_GOB2) { - } - break; - - case 135: - if (_vm->_features & GF_GOB2) { - } - break; - - case 136: - if (_vm->_features & GF_GOB2) { - } - break; - - default: - warning("unimplemented drawOperation: %d", cmd); - } -} - -void Inter::getFreeMem(void) { - int16 freeVar; - int16 maxFreeVar; - - freeVar = _vm->_parse->parseVarIndex(); - maxFreeVar = _vm->_parse->parseVarIndex(); - - // HACK - WRITE_VAR_OFFSET(freeVar, 1000000); - WRITE_VAR_OFFSET(maxFreeVar, 1000000); -} - -void Inter::manageDataFile(void) { - evalExpr(0); - - if (_vm->_global->_inter_resStr[0] != 0) - _vm->_dataio->openDataFile(_vm->_global->_inter_resStr); - else - _vm->_dataio->closeDataFile(); -} - -void Inter::writeData(void) { - int16 offset; - int16 handle; - int16 size; - int16 dataVar; - int16 retSize; - - debug(4, "writeData"); - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); - - WRITE_VAR(1, 1); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr, Common::File::kFileWriteMode); + byte cmd2; - if (handle < 0) + if (_vm->_global->_inter_execPtr == 0) return; - if (offset < 0) { - _vm->_dataio->seekData(handle, -offset - 1, 2); - } else { - _vm->_dataio->seekData(handle, offset, 0); - } - - retSize = _vm->_dataio->file_getHandle(handle)->write(_vm->_global->_inter_variables + dataVar, size); - - if (retSize == size) - WRITE_VAR(1, 0); - - _vm->_dataio->closeData(handle); -} - -void Inter::checkData(void) { - int16 handle; - int16 varOff; - - debug(4, "_vm->_dataio->cheackData"); - evalExpr(0); - varOff = _vm->_parse->parseVarIndex(); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); - - WRITE_VAR_OFFSET(varOff, handle); - if (handle >= 0) - _vm->_dataio->closeData(handle); -} - -void Inter::readData(void) { - int16 retSize; - int16 size; - int16 dataVar; - int16 offset; - int16 handle; - - debug(4, "readData"); - evalExpr(0); - dataVar = _vm->_parse->parseVarIndex(); - size = _vm->_parse->parseValExpr(); - offset = _vm->_parse->parseValExpr(); - - if (_vm->_game->extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->extHandle); - - WRITE_VAR(1, 1); - handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); - if (handle >= 0) { - _vm->_draw->animateCursor(4); - if (offset < 0) - _vm->_dataio->seekData(handle, -offset - 1, 2); - else - _vm->_dataio->seekData(handle, offset, 0); - - retSize = _vm->_dataio->readData(handle, _vm->_global->_inter_variables + dataVar, size); - _vm->_dataio->closeData(handle); - - if (retSize == size) - WRITE_VAR(1, 0); - } - - if (_vm->_game->extHandle >= 0) - _vm->_game->extHandle = _vm->_dataio->openData(_vm->_game->curExtFile); -} - -void Inter::loadFont(void) { - int16 index; - - debug(4, "loadFont"); - evalExpr(0); - index = load16(); - - if (_vm->_draw->fonts[index] != 0) - _vm->_util->freeFont(_vm->_draw->fonts[index]); - - _vm->_draw->animateCursor(4); - if (_vm->_game->extHandle >= 0) - _vm->_dataio->closeData(_vm->_game->extHandle); - - _vm->_draw->fonts[index] = _vm->_util->loadFont(_vm->_global->_inter_resStr); - - if (_vm->_game->extHandle >= 0) - _vm->_game->extHandle = _vm->_dataio->openData(_vm->_game->curExtFile); -} - -void Inter::freeFont(void) { - int16 index; - - index = load16(); - if (_vm->_draw->fonts[index] != 0) - _vm->_util->freeFont(_vm->_draw->fonts[index]); - - _vm->_draw->fonts[index] = 0; -} - -void Inter::prepareStr(void) { - int16 var; - - var = _vm->_parse->parseVarIndex(); - _vm->_util->prepareStr(_vm->_global->_inter_variables + var); -} - -void Inter::insertStr(void) { - int16 pos; - int16 strVar; - - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - pos = _vm->_parse->parseValExpr(); - _vm->_util->insertStr(_vm->_global->_inter_resStr, _vm->_global->_inter_variables + strVar, pos); -} - -void Inter::cutStr(void) { - int16 var; - int16 pos; - int16 size; - - var = _vm->_parse->parseVarIndex(); - pos = _vm->_parse->parseValExpr(); - size = _vm->_parse->parseValExpr(); - _vm->_util->cutFromStr(_vm->_global->_inter_variables + var, pos, size); -} - -void Inter::strstr(void) { - int16 strVar; - int16 resVar; - int16 pos; - - strVar = _vm->_parse->parseVarIndex(); - evalExpr(0); - resVar = _vm->_parse->parseVarIndex(); - - pos = _vm->_util->strstr(_vm->_global->_inter_resStr, _vm->_global->_inter_variables + strVar); - WRITE_VAR_OFFSET(resVar, pos - 1); -} - -void Inter::setFrameRate(void) { - _vm->_util->setFrameRate(_vm->_parse->parseValExpr()); -} - -void Inter::istrlen(void) { - int16 len; - int16 var; - - var = _vm->_parse->parseVarIndex(); - len = strlen(_vm->_global->_inter_variables + var); - var = _vm->_parse->parseVarIndex(); - - WRITE_VAR_OFFSET(var, len); -} - -void Inter::strToLong(void) { - char str[20]; - int16 strVar; - int16 destVar; - int32 res; - - strVar = _vm->_parse->parseVarIndex(); - strcpy(str, _vm->_global->_inter_variables + strVar); - res = atol(str); - - destVar = _vm->_parse->parseVarIndex(); - WRITE_VAR_OFFSET(destVar, res); -} - -void Inter::invalidate(void) { - warning("invalidate: 'bugged' function!"); - _vm->_draw->destSurface = load16(); - _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_INVALIDATE); -} - -void Inter::loadSpriteContent(void) { - _vm->_draw->spriteLeft = load16(); - _vm->_draw->destSurface = load16(); - _vm->_draw->transparency = load16(); - _vm->_draw->destSpriteX = 0; - _vm->_draw->destSpriteY = 0; - _vm->_draw->spriteOperation(DRAW_LOADSPRITE); -} - -void Inter::copySprite(void) { - _vm->_draw->sourceSurface = load16(); - _vm->_draw->destSurface = load16(); - - _vm->_draw->spriteLeft = _vm->_parse->parseValExpr(); - _vm->_draw->spriteTop = _vm->_parse->parseValExpr(); - _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->transparency = load16(); - _vm->_draw->spriteOperation(DRAW_BLITSURF); -} - -void Inter::putPixel(void) { - _vm->_draw->destSurface = load16(); - - _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_PUTPIXEL); -} - -void Inter::fillRect(void) { - _vm->_draw->destSurface = load16(); - - _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->backColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_FILLRECT); -} - -void Inter::drawLine(void) { - _vm->_draw->destSurface = load16(); - - _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); - _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); - _vm->_draw->spriteBottom = _vm->_parse->parseValExpr(); - - _vm->_draw->frontColor = _vm->_parse->parseValExpr(); - _vm->_draw->spriteOperation(DRAW_DRAWLINE); -} - -void Inter::createSprite(void) { - int16 index; - int16 height; - int16 width; - int16 flag; - - index = load16(); - width = load16(); - height = load16(); - - flag = load16(); - if (flag == 1) - _vm->_draw->spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 2); - else - _vm->_draw->spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 0); - - _vm->_video->clearSurf(_vm->_draw->spritesArray[index]); -} - -void Inter::freeSprite(void) { - int16 index; + _breakFlag = false; + _vm->_global->_inter_execPtr++; + cmdCount = *_vm->_global->_inter_execPtr++; + _vm->_global->_inter_execPtr += 2; - index = load16(); - if (_vm->_draw->spritesArray[index] == 0) + if (cmdCount == 0) { + _vm->_global->_inter_execPtr = 0; return; + } - _vm->_video->freeSurfDesc(_vm->_draw->spritesArray[index]); - _vm->_draw->spritesArray[index] = 0; -} - -void Inter::renewTimeInVars(void) { - struct tm *t; - time_t now = time(NULL); - - t = localtime(&now); - - WRITE_VAR(5, 1900 + t->tm_year); - WRITE_VAR(6, t->tm_mon); - WRITE_VAR(7, 0); - WRITE_VAR(8, t->tm_mday); - WRITE_VAR(9, t->tm_hour); - WRITE_VAR(10, t->tm_min); - WRITE_VAR(11, t->tm_sec); -} - -void Inter::playComposition(void) { - static int16 composition[50]; - int16 i; - int16 dataVar; - int16 freqVal; - - dataVar = _vm->_parse->parseVarIndex(); - freqVal = _vm->_parse->parseValExpr(); - for (i = 0; i < 50; i++) - composition[i] = (int16)VAR_OFFSET(dataVar + i * 4); - - _vm->_snd->playComposition(_vm->_game->soundSamples, composition, freqVal); -} + counter = 0; + do { + if (_terminate) + break; -void Inter::stopSound(void) { - _vm->_snd->stopSound(_vm->_parse->parseValExpr()); - _soundEndTimeKey = 0; -} + cmd = (byte)*_vm->_global->_inter_execPtr; + if ((cmd >> 4) >= 12) { + cmd2 = 16 - (cmd >> 4); + cmd &= 0xf; + } else + cmd2 = 0; -void Inter::playSound(void) { - int16 frequency; - int16 freq2; - int16 repCount; - int16 index; + _vm->_global->_inter_execPtr++; + counter++; - index = _vm->_parse->parseValExpr(); - repCount = _vm->_parse->parseValExpr(); - frequency = _vm->_parse->parseValExpr(); +// debug(4, "funcBlock(%d, %d)", cmd2, cmd); - _vm->_snd->stopSound(0); - _soundEndTimeKey = 0; - if (_vm->_game->soundSamples[index] == 0) - return; + if(cmd2 == 0) + cmd >>= 4; - if (repCount < 0) { - if (_vm->_global->_soundFlags < 2) + if(executeFuncOpcode(cmd2, cmd, cmdCount, counter, retFlag)) return; - repCount = -repCount; - _soundEndTimeKey = _vm->_util->getTimeKey(); + if (_breakFlag) { + if (retFlag != 2) + break; - if (frequency == 0) { - freq2 = _vm->_game->soundSamples[index]->frequency; - } else { - freq2 = frequency; + if (*_breakFromLevel == -1) + _breakFlag = false; + break; } - _soundStopVal = - (10 * (_vm->_game->soundSamples[index]->size / 2)) / freq2; - _soundEndTimeKey += - ((_vm->_game->soundSamples[index]->size * repCount - - _vm->_game->soundSamples[index]->size / 2) * 1000) / freq2; - } - _vm->_snd->playSample(_vm->_game->soundSamples[index], repCount, frequency); -} - -void Inter::loadCursor(void) { - Game::TotResItem *itemPtr; - int16 width; - int16 height; - int32 offset; - char *dataBuf; - int16 id; - int8 index; - - id = load16(); - index = *_vm->_global->_inter_execPtr++; - itemPtr = &_vm->_game->totResourceTable->items[id]; - offset = itemPtr->offset; - - if (offset >= 0) { - dataBuf = - ((char *)_vm->_game->totResourceTable) + szGame_TotResTable + - szGame_TotResItem * _vm->_game->totResourceTable->itemsCount + offset; - } else { - dataBuf = _vm->_game->imFileData + (int32)READ_LE_UINT32(&((int32 *)_vm->_game->imFileData)[-offset - 1]); - } - - width = itemPtr->width; - height = itemPtr->height; - - _vm->_video->fillRect(_vm->_draw->cursorSprites, index * _vm->_draw->cursorWidth, 0, - index * _vm->_draw->cursorWidth + _vm->_draw->cursorWidth - 1, - _vm->_draw->cursorHeight - 1, 0); - - _vm->_video->drawPackedSprite((byte*)dataBuf, width, height, - index * _vm->_draw->cursorWidth, 0, 0, _vm->_draw->cursorSprites); - _vm->_draw->cursorAnimLow[index] = 0; -} - -void Inter::loadSpriteToPos(void) { - debug(4, "loadSpriteToPos"); - _vm->_draw->spriteLeft = load16(); - - _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); - _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); - - _vm->_draw->transparency = _vm->_global->_inter_execPtr[0]; - _vm->_draw->destSurface = (_vm->_global->_inter_execPtr[0] / 2) - 1; - - if (_vm->_draw->destSurface < 0) - _vm->_draw->destSurface = 101; - _vm->_draw->transparency &= 1; - _vm->_global->_inter_execPtr += 2; - _vm->_draw->spriteOperation(DRAW_LOADSPRITE); -} - -void Inter::loadTot(void) { - char buf[20]; - int8 size; - int16 i; - - debug(4, "loadTot"); - if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { - _vm->_global->_inter_execPtr++; - evalExpr(0); - strcpy(buf, _vm->_global->_inter_resStr); - } else { - size = *_vm->_global->_inter_execPtr++; - for (i = 0; i < size; i++) - buf[i] = *_vm->_global->_inter_execPtr++; - - buf[size] = 0; - } + } while (counter != cmdCount); - strcat(buf, ".tot"); - _terminate = true; - strcpy(_vm->_game->totToLoad, buf); + _vm->_global->_inter_execPtr = 0; + return; } void Inter::storeKey(int16 key) { @@ -1060,89 +201,6 @@ void Inter::storeKey(int16 key) { _vm->_util->waitKey(); } -void Inter::keyFunc(void) { - int16 flag; - int16 key; - - debug(4, "keyFunc"); - flag = load16(); - animPalette(); - _vm->_draw->blitInvalidated(); - - if (flag != 0) { - - if (flag != 1) { - if (flag != 2) { - _vm->_util->longDelay(flag); - return; - } - - key = 0; - - if (_vm->_global->_pressedKeys[0x48]) - key |= 1; - - if (_vm->_global->_pressedKeys[0x50]) - key |= 2; - - if (_vm->_global->_pressedKeys[0x4d]) - key |= 4; - - if (_vm->_global->_pressedKeys[0x4b]) - key |= 8; - - if (_vm->_global->_pressedKeys[0x1c]) - key |= 0x10; - - if (_vm->_global->_pressedKeys[0x39]) - key |= 0x20; - - if (_vm->_global->_pressedKeys[1]) - key |= 0x40; - - if (_vm->_global->_pressedKeys[0x1d]) - key |= 0x80; - - if (_vm->_global->_pressedKeys[0x2a]) - key |= 0x100; - - if (_vm->_global->_pressedKeys[0x36]) - key |= 0x200; - - if (_vm->_global->_pressedKeys[0x38]) - key |= 0x400; - - if (_vm->_global->_pressedKeys[0x3b]) - key |= 0x800; - - if (_vm->_global->_pressedKeys[0x3c]) - key |= 0x1000; - - if (_vm->_global->_pressedKeys[0x3d]) - key |= 0x2000; - - if (_vm->_global->_pressedKeys[0x3e]) - key |= 0x4000; - - WRITE_VAR(0, key); - _vm->_util->waitKey(); - return; - } - key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->mouseButtons, 0); - - storeKey(key); - return; - } else { - key = _vm->_game->checkCollisions(0, 0, 0, 0); - storeKey(key); - - if (flag == 1) - return; - - _vm->_util->waitKey(); - } -} - void Inter::checkSwitchTable(char **ppExec) { int16 i; int16 len; @@ -1197,447 +255,19 @@ void Inter::checkSwitchTable(char **ppExec) { _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; } -void Inter::repeatUntil(void) { - char *blockPtr; - int16 size; - char flag; - - debug(4, "repeatUntil"); - _nestLevel[0]++; - blockPtr = _vm->_global->_inter_execPtr; - - do { - _vm->_global->_inter_execPtr = blockPtr; - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - funcBlock(1); - _vm->_global->_inter_execPtr = blockPtr + size + 1; - flag = evalBoolResult(); - } while (flag == 0 && !_breakFlag && !_terminate); - - _nestLevel[0]--; - - if (*_breakFromLevel > -1) { - _breakFlag = false; - *_breakFromLevel = -1; - } -} - -void Inter::whileDo(void) { - char *blockPtr; - char *savedIP; - char flag; - int16 size; - - debug(4, "whileDo"); - _nestLevel[0]++; - do { - savedIP = _vm->_global->_inter_execPtr; - flag = evalBoolResult(); - - if (_terminate) - return; - - blockPtr = _vm->_global->_inter_execPtr; - - size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - if (flag != 0) { - funcBlock(1); - _vm->_global->_inter_execPtr = savedIP; - } else { - _vm->_global->_inter_execPtr += size; - } - - if (_breakFlag || _terminate) { - _vm->_global->_inter_execPtr = blockPtr; - _vm->_global->_inter_execPtr += size; - break; +void Inter::callSub(int16 retFlag) { + int16 block; + while (_vm->_global->_inter_execPtr != 0 && (char *)_vm->_global->_inter_execPtr != _vm->_game->totFileData) { + block = *_vm->_global->_inter_execPtr; + if (block == 1) { + funcBlock(retFlag); + } else if (block == 2) { + _vm->_game->collisionsBlock(); } - } while (flag != 0); - - _nestLevel[0]--; - if (*_breakFromLevel > -1) { - _breakFlag = false; - *_breakFromLevel = -1; - } -} - -void Inter::funcBlock(int16 retFlag) { - char cmdCount; - int16 counter; - byte cmd; - byte cmd2; - char *storedIP; - char *callAddr; - char boolRes; - - if (_vm->_global->_inter_execPtr == 0) - return; - - _breakFlag = false; - _vm->_global->_inter_execPtr++; - cmdCount = *_vm->_global->_inter_execPtr++; - _vm->_global->_inter_execPtr += 2; - - if (cmdCount == 0) { - _vm->_global->_inter_execPtr = 0; - return; } - counter = 0; - do { - if (_terminate) - break; - - cmd = (byte)*_vm->_global->_inter_execPtr; - if ((cmd >> 4) >= 12) { - cmd2 = 16 - (cmd >> 4); - cmd &= 0xf; - } else - cmd2 = 0; - - _vm->_global->_inter_execPtr++; - counter++; - - debug(4, "funcBlock(%d, %d)", cmd2, cmd); - - switch (cmd2) { - case 0: - switch (cmd >> 4) { - case 0: - case 1: - storedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = (char *)_vm->_game->totFileData + READ_LE_UINT16(_vm->_global->_inter_execPtr); - - if (counter == cmdCount && retFlag == 2) - return; - - callSub(2); - _vm->_global->_inter_execPtr = storedIP + 2; - break; - - case 2: - _vm->_draw->printText(); - break; - - case 3: - loadCursor(); - break; - - case 5: - checkSwitchTable(&callAddr); - storedIP = _vm->_global->_inter_execPtr; - _vm->_global->_inter_execPtr = callAddr; - - if (counter == cmdCount && retFlag == 2) - return; - - funcBlock(0); - _vm->_global->_inter_execPtr = storedIP; - break; - - case 6: - repeatUntil(); - break; - - case 7: - whileDo(); - break; - - case 8: - boolRes = evalBoolResult(); - if (boolRes != 0) { - if (counter == cmdCount - && retFlag == 2) - return; - - storedIP = _vm->_global->_inter_execPtr; - funcBlock(0); - _vm->_global->_inter_execPtr = storedIP; - - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - debug(5, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); - cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; - _vm->_global->_inter_execPtr++; - if (cmd != 12) - break; - - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - } else { - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - - debug(5, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); - cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; - _vm->_global->_inter_execPtr++; - if (cmd != 12) - break; - - if (counter == cmdCount && retFlag == 2) - return; - - storedIP = _vm->_global->_inter_execPtr; - funcBlock(0); - _vm->_global->_inter_execPtr = storedIP; - _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; - } - break; - - case 9: - evaluateStore(); - break; - - case 10: - loadSpriteToPos(); - break; - } - break; - - case 1: - switch (cmd) { - case 1: - printText(); - break; - - case 2: - loadTot(); - break; - - case 3: - _vm->_draw->interPalLoad(); - break; - - case 4: - keyFunc(); - break; - - case 5: - capturePush(); - break; - - case 6: - capturePop(); - break; - - case 7: - animPalInit(); - break; - - case 14: - drawOperations(); - break; - - case 15: - cmdCount = *_vm->_global->_inter_execPtr++; - counter = 0; - break; - } - break; - - case 2: - - switch (cmd) { - case 0: - if (retFlag != 2) - _breakFlag = true; - - _vm->_global->_inter_execPtr = 0; - return; - - case 1: - renewTimeInVars(); - break; - - case 2: - _vm->_snd->speakerOn(_vm->_parse->parseValExpr(), -1); - break; - - case 3: - _vm->_snd->speakerOff(); - break; - - case 4: - putPixel(); - break; - - case 5: - _vm->_goblin->interFunc(); - break; - - case 6: - createSprite(); - break; - - case 7: - freeSprite(); - break; - } - break; - - case 3: - switch (cmd) { - case 0: - if (retFlag == 1) { - _breakFlag = true; - _vm->_global->_inter_execPtr = 0; - return; - } - - if (*_nestLevel == 0) - break; - - *_breakFromLevel = *_nestLevel; - _breakFlag = true; - _vm->_global->_inter_execPtr = 0; - return; - - case 1: - loadSpriteContent(); - break; - - case 2: - copySprite(); - break; - - case 3: - fillRect(); - break; - - case 4: - drawLine(); - break; - - case 5: - strToLong(); - break; - - case 6: - invalidate(); - break; - - case 7: - _vm->_draw->backDeltaX = _vm->_parse->parseValExpr(); - _vm->_draw->backDeltaY = _vm->_parse->parseValExpr(); - break; - - case 8: - playSound(); - break; - - case 9: - stopSound(); - break; - - case 10: - _vm->_game->interLoadSound(-1); - break; - - case 11: - _vm->_game->freeSoundSlot(-1); - break; - - case 12: - _vm->_snd->waitEndPlay(); - break; - - case 13: - playComposition(); - break; - - case 14: - getFreeMem(); - break; - - case 15: - checkData(); - break; - } - break; - - case 4: - - switch (cmd) { - case 1: - prepareStr(); - break; - - case 2: - insertStr(); - break; - - case 3: - cutStr(); - break; - - case 4: - strstr(); - break; - - case 5: - istrlen(); - break; - - case 6: - setMousePos(); - break; - - case 7: - setFrameRate(); - break; - - case 8: - _vm->_draw->blitInvalidated(); - _vm->_util->waitEndFrame(); - animPalette(); - storeKey(_vm->_game->checkKeys(&_vm->_global->_inter_mouseX, - &_vm->_global->_inter_mouseY, &_vm->_game->mouseButtons, 0)); - break; - - case 9: - _vm->_draw->animateCursor(1); - break; - - case 10: - _vm->_draw->blitCursor(); - break; - - case 11: - loadFont(); - break; - - case 12: - freeFont(); - break; - - case 13: - readData(); - break; - - case 14: - writeData(); - break; - - case 15: - manageDataFile(); - break; - } - break; - - } - - if (_breakFlag) { - if (retFlag != 2) - break; - - if (*_breakFromLevel == -1) - _breakFlag = false; - break; - } - } while (counter != cmdCount); - - _vm->_global->_inter_execPtr = 0; - return; + if ((char *)_vm->_global->_inter_execPtr == _vm->_game->totFileData) + _terminate = true; } void Inter::initControlVars(void) { @@ -1652,19 +282,19 @@ void Inter::initControlVars(void) { _soundEndTimeKey = 0; } -void Inter::callSub(int16 retFlag) { - int16 block; - while (_vm->_global->_inter_execPtr != 0 && (char *)_vm->_global->_inter_execPtr != _vm->_game->totFileData) { - block = *_vm->_global->_inter_execPtr; - if (block == 1) { - funcBlock(retFlag); - } else if (block == 2) { - _vm->_game->collisionsBlock(); - } - } +void Inter::renewTimeInVars(void) { + struct tm *t; + time_t now = time(NULL); - if ((char *)_vm->_global->_inter_execPtr == _vm->_game->totFileData) - _terminate = true; + t = localtime(&now); + + WRITE_VAR(5, 1900 + t->tm_year); + WRITE_VAR(6, t->tm_mon); + WRITE_VAR(7, 0); + WRITE_VAR(8, t->tm_mday); + WRITE_VAR(9, t->tm_hour); + WRITE_VAR(10, t->tm_min); + WRITE_VAR(11, t->tm_sec); } } // End of namespace Gob diff --git a/gob/inter.h b/gob/inter.h index fc725a7109..085f578bdc 100644 --- a/gob/inter.h +++ b/gob/inter.h @@ -24,6 +24,14 @@ namespace Gob { +// This is to help devices with small memory (PDA, smartphones, ...) +// to save abit of memory used by opcode names in the Scumm engine. +#ifndef REDUCE_MEMORY_USAGE +# define _OPCODE(ver, x) { &ver::x, #x } +#else +# define _OPCODE(ver, x) { &ver::x, "" } +#endif + class Inter { public: int16 _animPalLowIndex; @@ -40,66 +48,164 @@ public: int16 peek16(char *ptr); int32 peek32(char *ptr); - void setMousePos(void); char evalExpr(int16 *pRes); char evalBoolResult(void); - void storeResult(void); - void printText(void); void animPalette(void); - void animPalInit(void); - void loadMult(void); - void playMult(void); - void freeMult(void); - void initCursor(void); - void initCursorAnim(void); - void clearCursorAnim(void); - void drawOperations(void); - void getFreeMem(void); - void manageDataFile(void); - void writeData(void); - void checkData(void); - void readData(void); - void loadFont(void); - void freeFont(void); - void prepareStr(void); - void insertStr(void); - void cutStr(void); - void strstr(void); - void setFrameRate(void); - void istrlen(void); - void strToLong(void); - void invalidate(void); - void loadSpriteContent(void); - void copySprite(void); - void putPixel(void); - void fillRect(void); - void drawLine(void); - void createSprite(void); - void freeSprite(void); - void renewTimeInVars(void); - void playComposition(void); - void stopSound(void); - void playSound(void); - void loadCursor(void); - void loadSpriteToPos(void); void funcBlock(int16 retFlag); - void loadTot(void); void storeKey(int16 key); - void keyFunc(void); void checkSwitchTable(char **ppExec); - void repeatUntil(void); - void whileDo(void); void callSub(int16 retFlag); void initControlVars(void); + void renewTimeInVars(void); Inter(GobEngine *vm); + virtual ~Inter() {}; protected: GobEngine *_vm; - void evaluateStore(void); - void capturePush(void); - void capturePop(void); + virtual void setupOpcodes(void) = 0; + virtual void executeDrawOpcode(byte i) = 0; + virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) = 0; + virtual const char *getOpcodeDrawDesc(byte i) = 0; + virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0; +}; + +class Inter_v1 : public Inter { +public: + Inter_v1(GobEngine *vm); + virtual ~Inter_v1() {}; + +protected: + typedef void (Inter_v1::*OpcodeDrawProcV1)(void); + typedef bool (Inter_v1::*OpcodeFuncProcV1)(char &, int16 &, int16 &); + struct OpcodeDrawEntryV1 { + OpcodeDrawProcV1 proc; + const char *desc; + }; + struct OpcodeFuncEntryV1 { + OpcodeFuncProcV1 proc; + const char *desc; + }; + const OpcodeDrawEntryV1 *_opcodesDrawV1; + const OpcodeFuncEntryV1 *_opcodesFuncV1; + + virtual void setupOpcodes(void); + virtual void executeDrawOpcode(byte i); + virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); + virtual const char *getOpcodeDrawDesc(byte i); + virtual const char *getOpcodeFuncDesc(byte i, byte j); + + void o1_loadMult(void); + void o1_playMult(void); + void o1_freeMult(void); + void o1_initCursor(void); + void o1_initCursorAnim(void); + void o1_clearCursorAnim(void); + void o1_setRenderFlags(void); + void o1_loadAnim(void); + void o1_freeAnim(void); + void o1_updateAnim(void); + void o1_initMult(void); + void o1_multFreeMult(void); + void o1_animate(void); + void o1_multLoadMult(void); + void o1_storeParams(void); + void o1_getObjAnimSize(void); + void o1_loadStatic(void); + void o1_freeStatic(void); + void o1_renderStatic(void); + void o1_loadCurLayer(void); + void o1_playCDTrack(void); + void o1_getCDTrackPos(void); + void o1_stopCD(void); + void o1_loadFontToSprite(void); + void o1_freeFontToSprite(void); + bool o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_drawPrintText(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_call(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_callBool(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_loadCursor(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_repeatUntil(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_whileDo(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_loadSpriteToPos(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_printText(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_loadTot(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_palLoad(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_keyFunc(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_capturePush(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_capturePop(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_drawOperations(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_renewTimeInVars(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_putPixel(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_createSprite(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_loadSpriteContent(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_copySprite(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_fillRect(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_drawLine(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_strToLong(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_invalidate(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_playSound(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_stopSound(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_playComposition(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_checkData(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_prepareStr(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_insertStr(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_cutStr(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_strstr(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_istrlen(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_setFrameRate(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_loadFont(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_freeFont(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_readData(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_writeData(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_manageDataFile(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_setcmdCount(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_return(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_speakerOn(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_speakerOff(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_func(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_freeSoundSlot(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_waitEndPlay(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_animateCursor(char &cmdCount, int16 &counter, int16 &retFlag); + bool o1_blitCursor(char &cmdCount, int16 &counter, int16 &retFlag); +}; + +class Inter_v2 : public Inter_v1 { +public: + Inter_v2(GobEngine *vm); + virtual ~Inter_v2() {}; + +protected: + typedef void (Inter_v2::*OpcodeDrawProcV2)(void); + typedef bool (Inter_v2::*OpcodeFuncProcV2)(char &, int16 &, int16 &); + struct OpcodeDrawEntryV2 { + OpcodeDrawProcV2 proc; + const char *desc; + }; + struct OpcodeFuncEntryV2 { + OpcodeFuncProcV2 proc; + const char *desc; + }; + const OpcodeDrawEntryV2 *_opcodesDrawV2; + const OpcodeFuncEntryV2 *_opcodesFuncV2; + + virtual void setupOpcodes(void); + virtual void executeDrawOpcode(byte i); + virtual bool executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag); + virtual const char *getOpcodeDrawDesc(byte i); + virtual const char *getOpcodeFuncDesc(byte i, byte j); + + void o2_drawStub(void) { warning("Gob2 stub"); } }; } // End of namespace Gob diff --git a/gob/inter_v1.cpp b/gob/inter_v1.cpp new file mode 100644 index 0000000000..7a3a1d5d32 --- /dev/null +++ b/gob/inter_v1.cpp @@ -0,0 +1,1613 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2005 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $Header$ + * + */ +#include "gob/gob.h" +#include "gob/global.h" +#include "gob/inter.h" +#include "gob/util.h" +#include "gob/scenery.h" +#include "gob/parse.h" +#include "gob/game.h" +#include "gob/draw.h" +#include "gob/mult.h" +#include "gob/goblin.h" +#include "gob/cdrom.h" + +namespace Gob { + +#define OPCODE(x) _OPCODE(Inter_v1, x) + +Inter_v1::Inter_v1(GobEngine *vm) : Inter(vm) { + setupOpcodes(); +} + +void Inter_v1::setupOpcodes(void) { + static const OpcodeDrawEntryV1 opcodesDraw[256] = { + /* 00 */ + OPCODE(o1_loadMult), + OPCODE(o1_playMult), + OPCODE(o1_freeMult), + {NULL, ""}, + /* 04 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_initCursor), + /* 08 */ + OPCODE(o1_initCursorAnim), + OPCODE(o1_clearCursorAnim), + OPCODE(o1_setRenderFlags), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + OPCODE(o1_loadAnim), + OPCODE(o1_freeAnim), + OPCODE(o1_updateAnim), + {NULL, ""}, + /* 14 */ + OPCODE(o1_initMult), + OPCODE(o1_multFreeMult), + OPCODE(o1_animate), + OPCODE(o1_multLoadMult), + /* 18 */ + OPCODE(o1_storeParams), + OPCODE(o1_getObjAnimSize), + OPCODE(o1_loadStatic), + OPCODE(o1_freeStatic), + /* 1C */ + OPCODE(o1_renderStatic), + OPCODE(o1_loadCurLayer), + {NULL, ""}, + {NULL, ""}, + /* 20 */ + OPCODE(o1_playCDTrack), + OPCODE(o1_getCDTrackPos), + OPCODE(o1_stopCD), + {NULL, ""}, + /* 24 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o1_loadFontToSprite), + OPCODE(o1_freeFontToSprite), + {NULL, ""}, + {NULL, ""}, + /* 34 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 38 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 3C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 40 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 44 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 48 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 4C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 50 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 54 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 58 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 5C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 60 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 64 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 68 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 6C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 70 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 74 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 78 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 7C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 80 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 84 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 88 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 8C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 90 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 94 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 98 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 9C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* AC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* BC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* CC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* DC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* EC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* FC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""} + }; + + static const OpcodeFuncEntryV1 opcodesFunc[80] = { + /* 00 */ + OPCODE(o1_callSub), + OPCODE(o1_callSub), + OPCODE(o1_drawPrintText), + OPCODE(o1_loadCursor), + /* 04 */ + {NULL, ""}, + OPCODE(o1_call), + OPCODE(o1_repeatUntil), + OPCODE(o1_whileDo), + /* 08 */ + OPCODE(o1_callBool), + OPCODE(o1_evaluateStore), + OPCODE(o1_loadSpriteToPos), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + {NULL, ""}, + OPCODE(o1_printText), + OPCODE(o1_loadTot), + OPCODE(o1_palLoad), + /* 14 */ + OPCODE(o1_keyFunc), + OPCODE(o1_capturePush), + OPCODE(o1_capturePop), + OPCODE(o1_animPalInit), + /* 18 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 1C */ + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_drawOperations), + OPCODE(o1_setcmdCount), + /* 20 */ + OPCODE(o1_return), + OPCODE(o1_renewTimeInVars), + OPCODE(o1_speakerOn), + OPCODE(o1_speakerOff), + /* 24 */ + OPCODE(o1_putPixel), + OPCODE(o1_func), + OPCODE(o1_createSprite), + OPCODE(o1_freeSprite), + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o1_returnTo), + OPCODE(o1_loadSpriteContent), + OPCODE(o1_copySprite), + OPCODE(o1_fillRect), + /* 34 */ + OPCODE(o1_drawLine), + OPCODE(o1_strToLong), + OPCODE(o1_invalidate), + OPCODE(o1_setBackDelta), + /* 38 */ + OPCODE(o1_playSound), + OPCODE(o1_stopSound), + OPCODE(o1_loadSound), + OPCODE(o1_freeSoundSlot), + /* 3C */ + OPCODE(o1_waitEndPlay), + OPCODE(o1_playComposition), + OPCODE(o1_getFreeMem), + OPCODE(o1_checkData), + /* 40 */ + {NULL, ""}, + OPCODE(o1_prepareStr), + OPCODE(o1_insertStr), + OPCODE(o1_cutStr), + /* 44 */ + OPCODE(o1_strstr), + OPCODE(o1_istrlen), + OPCODE(o1_setMousePos), + OPCODE(o1_setFrameRate), + /* 48 */ + OPCODE(o1_animatePalette), + OPCODE(o1_animateCursor), + OPCODE(o1_blitCursor), + OPCODE(o1_loadFont), + /* 4C */ + OPCODE(o1_freeFont), + OPCODE(o1_readData), + OPCODE(o1_writeData), + OPCODE(o1_manageDataFile), + }; + + _opcodesDrawV1 = opcodesDraw; + _opcodesFuncV1 = opcodesFunc; +} + +bool Inter_v1::o1_setMousePos(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_global->_inter_mouseX = _vm->_parse->parseValExpr(); + _vm->_global->_inter_mouseY = _vm->_parse->parseValExpr(); + if (_vm->_global->_useMouse != 0) + _vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY); + return false; +} + +bool Inter_v1::o1_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag) { + char *savedPos; + int16 token; + int16 result; + int16 varOff; + + savedPos = _vm->_global->_inter_execPtr; + varOff = _vm->_parse->parseVarIndex(); + token = evalExpr(&result); + switch (savedPos[0]) { + case 23: + case 26: + WRITE_VAR_OFFSET(varOff, _vm->_global->_inter_resVal); + break; + + case 25: + case 28: + if (token == 20) + *(_vm->_global->_inter_variables + varOff) = result; + else + strcpy(_vm->_global->_inter_variables + varOff, _vm->_global->_inter_resStr); + break; + + } + return false; +} + +bool Inter_v1::o1_capturePush(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 left; + int16 top; + int16 width; + int16 height; + + left = _vm->_parse->parseValExpr(); + top = _vm->_parse->parseValExpr(); + width = _vm->_parse->parseValExpr(); + height = _vm->_parse->parseValExpr(); + _vm->_game->capturePush(left, top, width, height); + (*_vm->_scenery->pCaptureCounter)++; + return false; +} + +bool Inter_v1::o1_capturePop(char &cmdCount, int16 &counter, int16 &retFlag) { + if (*_vm->_scenery->pCaptureCounter != 0) { + (*_vm->_scenery->pCaptureCounter)--; + _vm->_game->capturePop(1); + } + return false; +} + +bool Inter_v1::o1_printText(char &cmdCount, int16 &counter, int16 &retFlag) { + char buf[60]; + int16 i; + + debug(3, "printText"); + _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->backColor = _vm->_parse->parseValExpr(); + _vm->_draw->frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->fontIndex = _vm->_parse->parseValExpr(); + _vm->_draw->destSurface = 21; + _vm->_draw->textToPrint = buf; + _vm->_draw->transparency = 0; + + if (_vm->_draw->backColor >= 16) { + _vm->_draw->backColor = 0; + _vm->_draw->transparency = 1; + } + + do { + for (i = 0; *_vm->_global->_inter_execPtr != '.' && (byte)*_vm->_global->_inter_execPtr != 200; + i++, _vm->_global->_inter_execPtr++) { + buf[i] = *_vm->_global->_inter_execPtr; + } + + if ((byte)*_vm->_global->_inter_execPtr != 200) { + _vm->_global->_inter_execPtr++; + switch (*_vm->_global->_inter_execPtr) { + case 23: + case 26: + sprintf(buf + i, "%d", VAR_OFFSET(_vm->_parse->parseVarIndex())); + break; + + case 25: + case 28: + sprintf(buf + i, "%s", _vm->_global->_inter_variables + _vm->_parse->parseVarIndex()); + break; + } + _vm->_global->_inter_execPtr++; + } else { + buf[i] = 0; + } + _vm->_draw->spriteOperation(DRAW_PRINTTEXT); + } while ((byte)*_vm->_global->_inter_execPtr != 200); + _vm->_global->_inter_execPtr++; + + return false; +} + +bool Inter_v1::o1_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag) { + _animPalDir = load16(); + _animPalLowIndex = _vm->_parse->parseValExpr(); + _animPalHighIndex = _vm->_parse->parseValExpr(); + return false; +} + +void Inter_v1::o1_loadMult(void) { + int16 resId; + + resId = load16(); + _vm->_mult->loadMult(resId); +} + +void Inter_v1::o1_playMult(void) { + int16 checkEscape; + + checkEscape = load16(); + _vm->_mult->playMult(VAR(57), -1, checkEscape, 0); +} + +void Inter_v1::o1_freeMult(void) { + load16(); // unused + _vm->_mult->freeMultKeys(); +} + +void Inter_v1::o1_initCursor(void) { + int16 width; + int16 height; + int16 count; + int16 i; + + _vm->_draw->cursorXDeltaVar = _vm->_parse->parseVarIndex(); + _vm->_draw->cursorYDeltaVar = _vm->_parse->parseVarIndex(); + + width = load16(); + if (width < 16) + width = 16; + + height = load16(); + if (height < 16) + height = 16; + + count = load16(); + if (count < 2) + count = 2; + + if (width != _vm->_draw->cursorWidth || height != _vm->_draw->cursorHeight || + _vm->_draw->cursorSprites->width != width * count) { + + _vm->_video->freeSurfDesc(_vm->_draw->cursorSprites); + _vm->_video->freeSurfDesc(_vm->_draw->cursorBack); + + _vm->_draw->cursorWidth = width; + _vm->_draw->cursorHeight = height; + + if (count < 0x80) + _vm->_draw->transparentCursor = 1; + else + _vm->_draw->transparentCursor = 0; + + if (count > 0x80) + count -= 0x80; + + _vm->_draw->cursorSprites = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->cursorWidth * count, + _vm->_draw->cursorHeight, 2); + _vm->_draw->spritesArray[23] = _vm->_draw->cursorSprites; + + _vm->_draw->cursorBack = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, _vm->_draw->cursorWidth, + _vm->_draw->cursorHeight, 0); + for (i = 0; i < 40; i++) { + _vm->_draw->cursorAnimLow[i] = -1; + _vm->_draw->cursorAnimDelays[i] = 0; + _vm->_draw->cursorAnimHigh[i] = 0; + } + _vm->_draw->cursorAnimLow[1] = 0; + } +} + +void Inter_v1::o1_initCursorAnim(void) { + int16 ind; + + ind = _vm->_parse->parseValExpr(); + _vm->_draw->cursorAnimLow[ind] = load16(); + _vm->_draw->cursorAnimHigh[ind] = load16(); + _vm->_draw->cursorAnimDelays[ind] = load16(); +} + +void Inter_v1::o1_clearCursorAnim(void) { + int16 ind; + + ind = _vm->_parse->parseValExpr(); + _vm->_draw->cursorAnimLow[ind] = -1; + _vm->_draw->cursorAnimHigh[ind] = 0; + _vm->_draw->cursorAnimDelays[ind] = 0; +} + +bool Inter_v1::o1_drawOperations(char &cmdCount, int16 &counter, int16 &retFlag) { + byte cmd; + + cmd = *_vm->_global->_inter_execPtr++; + + executeDrawOpcode(cmd); + + return false; +} + +bool Inter_v1::o1_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 freeVar; + int16 maxFreeVar; + + freeVar = _vm->_parse->parseVarIndex(); + maxFreeVar = _vm->_parse->parseVarIndex(); + + // HACK + WRITE_VAR_OFFSET(freeVar, 1000000); + WRITE_VAR_OFFSET(maxFreeVar, 1000000); + return false; +} + +bool Inter_v1::o1_manageDataFile(char &cmdCount, int16 &counter, int16 &retFlag) { + evalExpr(0); + + if (_vm->_global->_inter_resStr[0] != 0) + _vm->_dataio->openDataFile(_vm->_global->_inter_resStr); + else + _vm->_dataio->closeDataFile(); + return false; +} + +bool Inter_v1::o1_writeData(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 offset; + int16 handle; + int16 size; + int16 dataVar; + int16 retSize; + + debug(4, "writeData"); + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + offset = _vm->_parse->parseValExpr(); + + WRITE_VAR(1, 1); + handle = _vm->_dataio->openData(_vm->_global->_inter_resStr, Common::File::kFileWriteMode); + + if (handle < 0) + return false; + + if (offset < 0) { + _vm->_dataio->seekData(handle, -offset - 1, 2); + } else { + _vm->_dataio->seekData(handle, offset, 0); + } + + retSize = _vm->_dataio->file_getHandle(handle)->write(_vm->_global->_inter_variables + dataVar, size); + + if (retSize == size) + WRITE_VAR(1, 0); + + _vm->_dataio->closeData(handle); + return false; +} + +bool Inter_v1::o1_checkData(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 handle; + int16 varOff; + + debug(4, "_vm->_dataio->cheackData"); + evalExpr(0); + varOff = _vm->_parse->parseVarIndex(); + handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); + + WRITE_VAR_OFFSET(varOff, handle); + if (handle >= 0) + _vm->_dataio->closeData(handle); + return false; +} + +bool Inter_v1::o1_readData(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 retSize; + int16 size; + int16 dataVar; + int16 offset; + int16 handle; + + debug(4, "readData"); + evalExpr(0); + dataVar = _vm->_parse->parseVarIndex(); + size = _vm->_parse->parseValExpr(); + offset = _vm->_parse->parseValExpr(); + + if (_vm->_game->extHandle >= 0) + _vm->_dataio->closeData(_vm->_game->extHandle); + + WRITE_VAR(1, 1); + handle = _vm->_dataio->openData(_vm->_global->_inter_resStr); + if (handle >= 0) { + _vm->_draw->animateCursor(4); + if (offset < 0) + _vm->_dataio->seekData(handle, -offset - 1, 2); + else + _vm->_dataio->seekData(handle, offset, 0); + + retSize = _vm->_dataio->readData(handle, _vm->_global->_inter_variables + dataVar, size); + _vm->_dataio->closeData(handle); + + if (retSize == size) + WRITE_VAR(1, 0); + } + + if (_vm->_game->extHandle >= 0) + _vm->_game->extHandle = _vm->_dataio->openData(_vm->_game->curExtFile); + return false; +} + +bool Inter_v1::o1_loadFont(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 index; + + debug(4, "loadFont"); + evalExpr(0); + index = load16(); + + if (_vm->_draw->fonts[index] != 0) + _vm->_util->freeFont(_vm->_draw->fonts[index]); + + _vm->_draw->animateCursor(4); + if (_vm->_game->extHandle >= 0) + _vm->_dataio->closeData(_vm->_game->extHandle); + + _vm->_draw->fonts[index] = _vm->_util->loadFont(_vm->_global->_inter_resStr); + + if (_vm->_game->extHandle >= 0) + _vm->_game->extHandle = _vm->_dataio->openData(_vm->_game->curExtFile); + return false; +} + +bool Inter_v1::o1_freeFont(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 index; + + index = load16(); + if (_vm->_draw->fonts[index] != 0) + _vm->_util->freeFont(_vm->_draw->fonts[index]); + + _vm->_draw->fonts[index] = 0; + return false; +} + +bool Inter_v1::o1_prepareStr(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 var; + + var = _vm->_parse->parseVarIndex(); + _vm->_util->prepareStr(_vm->_global->_inter_variables + var); + return false; +} + +bool Inter_v1::o1_insertStr(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 pos; + int16 strVar; + + strVar = _vm->_parse->parseVarIndex(); + evalExpr(0); + pos = _vm->_parse->parseValExpr(); + _vm->_util->insertStr(_vm->_global->_inter_resStr, _vm->_global->_inter_variables + strVar, pos); + return false; +} + +bool Inter_v1::o1_cutStr(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 var; + int16 pos; + int16 size; + + var = _vm->_parse->parseVarIndex(); + pos = _vm->_parse->parseValExpr(); + size = _vm->_parse->parseValExpr(); + _vm->_util->cutFromStr(_vm->_global->_inter_variables + var, pos, size); + return false; +} + +bool Inter_v1::o1_strstr(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 strVar; + int16 resVar; + int16 pos; + + strVar = _vm->_parse->parseVarIndex(); + evalExpr(0); + resVar = _vm->_parse->parseVarIndex(); + + pos = _vm->_util->strstr(_vm->_global->_inter_resStr, _vm->_global->_inter_variables + strVar); + WRITE_VAR_OFFSET(resVar, pos - 1); + return false; +} + +bool Inter_v1::o1_setFrameRate(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_util->setFrameRate(_vm->_parse->parseValExpr()); + return false; +} + +bool Inter_v1::o1_istrlen(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 len; + int16 var; + + var = _vm->_parse->parseVarIndex(); + len = strlen(_vm->_global->_inter_variables + var); + var = _vm->_parse->parseVarIndex(); + + WRITE_VAR_OFFSET(var, len); + return false; +} + +bool Inter_v1::o1_strToLong(char &cmdCount, int16 &counter, int16 &retFlag) { + char str[20]; + int16 strVar; + int16 destVar; + int32 res; + + strVar = _vm->_parse->parseVarIndex(); + strcpy(str, _vm->_global->_inter_variables + strVar); + res = atol(str); + + destVar = _vm->_parse->parseVarIndex(); + WRITE_VAR_OFFSET(destVar, res); + return false; +} + +bool Inter_v1::o1_invalidate(char &cmdCount, int16 &counter, int16 &retFlag) { + warning("invalidate: 'bugged' function!"); + _vm->_draw->destSurface = load16(); + _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_INVALIDATE); + return false; +} + +bool Inter_v1::o1_loadSpriteContent(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->spriteLeft = load16(); + _vm->_draw->destSurface = load16(); + _vm->_draw->transparency = load16(); + _vm->_draw->destSpriteX = 0; + _vm->_draw->destSpriteY = 0; + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); + return false; +} + +bool Inter_v1::o1_copySprite(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->sourceSurface = load16(); + _vm->_draw->destSurface = load16(); + + _vm->_draw->spriteLeft = _vm->_parse->parseValExpr(); + _vm->_draw->spriteTop = _vm->_parse->parseValExpr(); + _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->transparency = load16(); + _vm->_draw->spriteOperation(DRAW_BLITSURF); + return false; +} + +bool Inter_v1::o1_putPixel(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->destSurface = load16(); + + _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_PUTPIXEL); + return false; +} + +bool Inter_v1::o1_fillRect(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->destSurface = load16(); + + _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->backColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_FILLRECT); + return false; +} + +bool Inter_v1::o1_drawLine(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->destSurface = load16(); + + _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); + _vm->_draw->spriteRight = _vm->_parse->parseValExpr(); + _vm->_draw->spriteBottom = _vm->_parse->parseValExpr(); + + _vm->_draw->frontColor = _vm->_parse->parseValExpr(); + _vm->_draw->spriteOperation(DRAW_DRAWLINE); + return false; +} + +bool Inter_v1::o1_createSprite(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 index; + int16 height; + int16 width; + int16 flag; + + index = load16(); + width = load16(); + height = load16(); + + flag = load16(); + if (flag == 1) + _vm->_draw->spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 2); + else + _vm->_draw->spritesArray[index] = _vm->_video->initSurfDesc(_vm->_global->_videoMode, width, height, 0); + + _vm->_video->clearSurf(_vm->_draw->spritesArray[index]); + return false; +} + +bool Inter_v1::o1_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 index; + + index = load16(); + if (_vm->_draw->spritesArray[index] == 0) + return false; + + _vm->_video->freeSurfDesc(_vm->_draw->spritesArray[index]); + _vm->_draw->spritesArray[index] = 0; + return false; +} + +bool Inter_v1::o1_playComposition(char &cmdCount, int16 &counter, int16 &retFlag) { + static int16 composition[50]; + int16 i; + int16 dataVar; + int16 freqVal; + + dataVar = _vm->_parse->parseVarIndex(); + freqVal = _vm->_parse->parseValExpr(); + for (i = 0; i < 50; i++) + composition[i] = (int16)VAR_OFFSET(dataVar + i * 4); + + _vm->_snd->playComposition(_vm->_game->soundSamples, composition, freqVal); + return false; +} + +bool Inter_v1::o1_stopSound(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_snd->stopSound(_vm->_parse->parseValExpr()); + _soundEndTimeKey = 0; + return false; +} + +bool Inter_v1::o1_playSound(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 frequency; + int16 freq2; + int16 repCount; + int16 index; + + index = _vm->_parse->parseValExpr(); + repCount = _vm->_parse->parseValExpr(); + frequency = _vm->_parse->parseValExpr(); + + _vm->_snd->stopSound(0); + _soundEndTimeKey = 0; + if (_vm->_game->soundSamples[index] == 0) + return false; + + if (repCount < 0) { + if (_vm->_global->_soundFlags < 2) + return false; + + repCount = -repCount; + _soundEndTimeKey = _vm->_util->getTimeKey(); + + if (frequency == 0) { + freq2 = _vm->_game->soundSamples[index]->frequency; + } else { + freq2 = frequency; + } + _soundStopVal = + (10 * (_vm->_game->soundSamples[index]->size / 2)) / freq2; + _soundEndTimeKey += + ((_vm->_game->soundSamples[index]->size * repCount - + _vm->_game->soundSamples[index]->size / 2) * 1000) / freq2; + } + _vm->_snd->playSample(_vm->_game->soundSamples[index], repCount, frequency); + return false; +} + +bool Inter_v1::o1_loadCursor(char &cmdCount, int16 &counter, int16 &retFlag) { + Game::TotResItem *itemPtr; + int16 width; + int16 height; + int32 offset; + char *dataBuf; + int16 id; + int8 index; + + id = load16(); + index = *_vm->_global->_inter_execPtr++; + itemPtr = &_vm->_game->totResourceTable->items[id]; + offset = itemPtr->offset; + + if (offset >= 0) { + dataBuf = + ((char *)_vm->_game->totResourceTable) + szGame_TotResTable + + szGame_TotResItem * _vm->_game->totResourceTable->itemsCount + offset; + } else { + dataBuf = _vm->_game->imFileData + (int32)READ_LE_UINT32(&((int32 *)_vm->_game->imFileData)[-offset - 1]); + } + + width = itemPtr->width; + height = itemPtr->height; + + _vm->_video->fillRect(_vm->_draw->cursorSprites, index * _vm->_draw->cursorWidth, 0, + index * _vm->_draw->cursorWidth + _vm->_draw->cursorWidth - 1, + _vm->_draw->cursorHeight - 1, 0); + + _vm->_video->drawPackedSprite((byte*)dataBuf, width, height, + index * _vm->_draw->cursorWidth, 0, 0, _vm->_draw->cursorSprites); + _vm->_draw->cursorAnimLow[index] = 0; + + return false; +} + +bool Inter_v1::o1_loadSpriteToPos(char &cmdCount, int16 &counter, int16 &retFlag) { + debug(4, "loadSpriteToPos"); + _vm->_draw->spriteLeft = load16(); + + _vm->_draw->destSpriteX = _vm->_parse->parseValExpr(); + _vm->_draw->destSpriteY = _vm->_parse->parseValExpr(); + + _vm->_draw->transparency = _vm->_global->_inter_execPtr[0]; + _vm->_draw->destSurface = (_vm->_global->_inter_execPtr[0] / 2) - 1; + + if (_vm->_draw->destSurface < 0) + _vm->_draw->destSurface = 101; + _vm->_draw->transparency &= 1; + _vm->_global->_inter_execPtr += 2; + _vm->_draw->spriteOperation(DRAW_LOADSPRITE); + + return false; +} + +bool Inter_v1::o1_loadTot(char &cmdCount, int16 &counter, int16 &retFlag) { + char buf[20]; + int8 size; + int16 i; + + debug(4, "loadTot"); + if ((*_vm->_global->_inter_execPtr & 0x80) != 0) { + _vm->_global->_inter_execPtr++; + evalExpr(0); + strcpy(buf, _vm->_global->_inter_resStr); + } else { + size = *_vm->_global->_inter_execPtr++; + for (i = 0; i < size; i++) + buf[i] = *_vm->_global->_inter_execPtr++; + + buf[size] = 0; + } + + strcat(buf, ".tot"); + _terminate = true; + strcpy(_vm->_game->totToLoad, buf); + + return false; +} + +bool Inter_v1::o1_keyFunc(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 flag; + int16 key; + + debug(4, "keyFunc"); + flag = load16(); + animPalette(); + _vm->_draw->blitInvalidated(); + + if (flag != 0) { + + if (flag != 1) { + if (flag != 2) { + _vm->_util->longDelay(flag); + return false; + } + + key = 0; + + if (_vm->_global->_pressedKeys[0x48]) + key |= 1; + + if (_vm->_global->_pressedKeys[0x50]) + key |= 2; + + if (_vm->_global->_pressedKeys[0x4d]) + key |= 4; + + if (_vm->_global->_pressedKeys[0x4b]) + key |= 8; + + if (_vm->_global->_pressedKeys[0x1c]) + key |= 0x10; + + if (_vm->_global->_pressedKeys[0x39]) + key |= 0x20; + + if (_vm->_global->_pressedKeys[1]) + key |= 0x40; + + if (_vm->_global->_pressedKeys[0x1d]) + key |= 0x80; + + if (_vm->_global->_pressedKeys[0x2a]) + key |= 0x100; + + if (_vm->_global->_pressedKeys[0x36]) + key |= 0x200; + + if (_vm->_global->_pressedKeys[0x38]) + key |= 0x400; + + if (_vm->_global->_pressedKeys[0x3b]) + key |= 0x800; + + if (_vm->_global->_pressedKeys[0x3c]) + key |= 0x1000; + + if (_vm->_global->_pressedKeys[0x3d]) + key |= 0x2000; + + if (_vm->_global->_pressedKeys[0x3e]) + key |= 0x4000; + + WRITE_VAR(0, key); + _vm->_util->waitKey(); + return false; + } + key = _vm->_game->checkKeys(&_vm->_global->_inter_mouseX, &_vm->_global->_inter_mouseY, &_vm->_game->mouseButtons, 0); + + storeKey(key); + return false; + } else { + key = _vm->_game->checkCollisions(0, 0, 0, 0); + storeKey(key); + + if (flag == 1) + return false; + + _vm->_util->waitKey(); + } + return false; +} + +bool Inter_v1::o1_repeatUntil(char &cmdCount, int16 &counter, int16 &retFlag) { + char *blockPtr; + int16 size; + char flag; + + debug(4, "repeatUntil"); + _nestLevel[0]++; + blockPtr = _vm->_global->_inter_execPtr; + + do { + _vm->_global->_inter_execPtr = blockPtr; + size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + funcBlock(1); + _vm->_global->_inter_execPtr = blockPtr + size + 1; + flag = evalBoolResult(); + } while (flag == 0 && !_breakFlag && !_terminate); + + _nestLevel[0]--; + + if (*_breakFromLevel > -1) { + _breakFlag = false; + *_breakFromLevel = -1; + } + return false; +} + +bool Inter_v1::o1_whileDo(char &cmdCount, int16 &counter, int16 &retFlag) { + char *blockPtr; + char *savedIP; + char flag; + int16 size; + + debug(4, "whileDo"); + _nestLevel[0]++; + do { + savedIP = _vm->_global->_inter_execPtr; + flag = evalBoolResult(); + + if (_terminate) + return false; + + blockPtr = _vm->_global->_inter_execPtr; + + size = READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + if (flag != 0) { + funcBlock(1); + _vm->_global->_inter_execPtr = savedIP; + } else { + _vm->_global->_inter_execPtr += size; + } + + if (_breakFlag || _terminate) { + _vm->_global->_inter_execPtr = blockPtr; + _vm->_global->_inter_execPtr += size; + break; + } + } while (flag != 0); + + _nestLevel[0]--; + if (*_breakFromLevel > -1) { + _breakFlag = false; + *_breakFromLevel = -1; + } + return false; +} + +void Inter_v1::o1_setRenderFlags(void) { + _vm->_draw->renderFlags = _vm->_parse->parseValExpr(); +} + +void Inter_v1::o1_loadAnim(void) { + _vm->_scenery->loadAnim(0); +} + +void Inter_v1::o1_freeAnim(void) { + _vm->_scenery->freeAnim(-1); +} + +void Inter_v1::o1_updateAnim(void) { + _vm->_scenery->interUpdateAnim(); +} + +void Inter_v1::o1_initMult(void) { + _vm->_mult->interInitMult(); +} + +void Inter_v1::o1_multFreeMult(void) { + _vm->_mult->freeMult(); +} + +void Inter_v1::o1_animate(void) { + _vm->_mult->animate(); +} + +void Inter_v1::o1_multLoadMult(void) { + _vm->_mult->interLoadMult(); +} + +void Inter_v1::o1_storeParams(void) { + _vm->_scenery->interStoreParams(); +} + +void Inter_v1::o1_getObjAnimSize(void) { + _vm->_mult->interGetObjAnimSize(); +} + +void Inter_v1::o1_loadStatic(void) { + _vm->_scenery->loadStatic(0); +} + +void Inter_v1::o1_freeStatic(void) { + _vm->_scenery->freeStatic(-1); +} + +void Inter_v1::o1_renderStatic(void) { + _vm->_scenery->interRenderStatic(); +} + +void Inter_v1::o1_loadCurLayer(void) { + _vm->_scenery->interLoadCurLayer(); +} + +void Inter_v1::o1_playCDTrack(void) { + // Used in gob1 CD + evalExpr(0); + _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); +} + +void Inter_v1::o1_getCDTrackPos(void) { + // Used in gob1 CD + + // Some scripts busy-wait while calling this opcode. + // This is a very nasty thing to do, so let's add a + // short delay here. It's probably a safe thing to do. + + _vm->_util->longDelay(1); + + int pos = _vm->_cdrom->getTrackPos(); + if (pos == -1) + pos = 32767; + WRITE_VAR(5, pos); +} + +void Inter_v1::o1_stopCD(void) { + // Used in gob1 CD + _vm->_cdrom->stopPlaying(); +} + +void Inter_v1::o1_loadFontToSprite(void) { + int16 i = load16(); + _vm->_draw->fontToSprite[i].sprite = load16(); + _vm->_draw->fontToSprite[i].base = load16(); + _vm->_draw->fontToSprite[i].width = load16(); + _vm->_draw->fontToSprite[i].height = load16(); +} + +void Inter_v1::o1_freeFontToSprite(void) { + int16 i = load16(); + _vm->_draw->fontToSprite[i].sprite = -1; + _vm->_draw->fontToSprite[i].base = -1; + _vm->_draw->fontToSprite[i].width = -1; + _vm->_draw->fontToSprite[i].height = -1; +} + +void Inter_v1::executeDrawOpcode(byte i) { + debug(4, "opcodeDraw %d (%s)", i, getOpcodeDrawDesc(i)); + + OpcodeDrawProcV1 op = _opcodesDrawV1[i].proc; + + if (op == NULL) + warning("unimplemented opcodeDraw: %d", i); + else + (this->*op) (); +} + +bool Inter_v1::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { + debug(4, "opcodeFunc %d (%s)", i, getOpcodeFuncDesc(i, j)); + + if ((i > 4) || (j > 15)) { + warning("unimplemented opcodeFunc: %d.%d", i, j); + return false; + } + + OpcodeFuncProcV1 op = _opcodesFuncV1[i*16 + j].proc; + + if (op == NULL) + warning("unimplemented opcodeFunc: %d.%d", i, j); + else + return (this->*op) (cmdCount, counter, retFlag); + return false; +} + +const char *Inter_v1::getOpcodeDrawDesc(byte i) { + return _opcodesDrawV1[i].desc; +} + +const char *Inter_v1::getOpcodeFuncDesc(byte i, byte j) +{ + if ((i > 4) || (j > 15)) + return ""; + + return _opcodesFuncV1[i*16 + j].desc; +} + +bool Inter_v1::o1_callSub(char &cmdCount, int16 &counter, int16 &retFlag) { + char *storedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = (char *)_vm->_game->totFileData + READ_LE_UINT16(_vm->_global->_inter_execPtr); + + if (counter == cmdCount && retFlag == 2) + return true; + + callSub(2); + _vm->_global->_inter_execPtr = storedIP + 2; + + return false; +} + +bool Inter_v1::o1_drawPrintText(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->printText(); + return false; +} + +bool Inter_v1::o1_call(char &cmdCount, int16 &counter, int16 &retFlag) { + char *callAddr; + + checkSwitchTable(&callAddr); + char *storedIP = _vm->_global->_inter_execPtr; + _vm->_global->_inter_execPtr = callAddr; + + if (counter == cmdCount && retFlag == 2) + return true; + + funcBlock(0); + _vm->_global->_inter_execPtr = storedIP; + + return false; +} + +bool Inter_v1::o1_callBool(char &cmdCount, int16 &counter, int16 &retFlag) { + byte cmd; + bool boolRes = evalBoolResult(); + if (boolRes != 0) { + if (counter == cmdCount + && retFlag == 2) + return true; + + char *storedIP = _vm->_global->_inter_execPtr; + funcBlock(0); + _vm->_global->_inter_execPtr = storedIP; + + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + debug(5, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); + cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; + _vm->_global->_inter_execPtr++; + if (cmd != 12) + return false; + + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + } else { + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + + debug(5, "cmd = %d", (int16)*_vm->_global->_inter_execPtr); + cmd = (byte)(*_vm->_global->_inter_execPtr) >> 4; + _vm->_global->_inter_execPtr++; + if (cmd != 12) + return false; + + if (counter == cmdCount && retFlag == 2) + return true; + + char *storedIP = _vm->_global->_inter_execPtr; + funcBlock(0); + _vm->_global->_inter_execPtr = storedIP; + _vm->_global->_inter_execPtr += READ_LE_UINT16(_vm->_global->_inter_execPtr + 2) + 2; + } + return false; +} + +bool Inter_v1::o1_palLoad(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->interPalLoad(); + return false; +} + +bool Inter_v1::o1_setcmdCount(char &cmdCount, int16 &counter, int16 &retFlag) { + cmdCount = *_vm->_global->_inter_execPtr++; + counter = 0; + return false; +} + +bool Inter_v1::o1_return(char &cmdCount, int16 &counter, int16 &retFlag) { + if (retFlag != 2) + _breakFlag = true; + + _vm->_global->_inter_execPtr = 0; + return false; +} + +bool Inter_v1::o1_renewTimeInVars(char &cmdCount, int16 &counter, int16 &retFlag) { + renewTimeInVars(); + return false; +} + +bool Inter_v1::o1_speakerOn(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_snd->speakerOn(_vm->_parse->parseValExpr(), -1); + return false; +} + +bool Inter_v1::o1_speakerOff(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_snd->speakerOff(); + return false; +} + +bool Inter_v1::o1_func(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_goblin->interFunc(); + return false; +} + +bool Inter_v1::o1_returnTo(char &cmdCount, int16 &counter, int16 &retFlag) { + if (retFlag == 1) { + _breakFlag = true; + _vm->_global->_inter_execPtr = 0; + return true; + } + + if (*_nestLevel == 0) + return false; + + *_breakFromLevel = *_nestLevel; + _breakFlag = true; + _vm->_global->_inter_execPtr = 0; + return true; +} + +bool Inter_v1::o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->backDeltaX = _vm->_parse->parseValExpr(); + _vm->_draw->backDeltaY = _vm->_parse->parseValExpr(); + return false; +} + +bool Inter_v1::o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_game->interLoadSound(-1); + return false; +} + +bool Inter_v1::o1_freeSoundSlot(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_game->freeSoundSlot(-1); + return false; +} + +bool Inter_v1::o1_waitEndPlay(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_snd->waitEndPlay(); + return false; +} + +bool Inter_v1::o1_animatePalette(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->blitInvalidated(); + _vm->_util->waitEndFrame(); + animPalette(); + storeKey(_vm->_game->checkKeys(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_vm->_game->mouseButtons, 0)); + return false; +} + +bool Inter_v1::o1_animateCursor(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->animateCursor(1); + return false; +} + +bool Inter_v1::o1_blitCursor(char &cmdCount, int16 &counter, int16 &retFlag) { + _vm->_draw->blitCursor(); + return false; +} + + +} // End of namespace Gob diff --git a/gob/inter_v2.cpp b/gob/inter_v2.cpp new file mode 100644 index 0000000000..774af4db74 --- /dev/null +++ b/gob/inter_v2.cpp @@ -0,0 +1,514 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2005 The ScummVM project + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $Header$ + * + */ +#include "gob/gob.h" +#include "gob/global.h" +#include "gob/inter.h" +#include "gob/util.h" +#include "gob/scenery.h" +#include "gob/parse.h" +#include "gob/game.h" +#include "gob/draw.h" +#include "gob/mult.h" +#include "gob/goblin.h" +#include "gob/cdrom.h" + +namespace Gob { + +#define OPCODE(x) _OPCODE(Inter_v2, x) + +Inter_v2::Inter_v2(GobEngine *vm) : Inter_v1(vm) { + setupOpcodes(); +} + +void Inter_v2::setupOpcodes(void) { + static const OpcodeDrawEntryV2 opcodesDraw[256] = { + /* 00 */ + OPCODE(o1_loadMult), + OPCODE(o1_playMult), + OPCODE(o1_freeMult), + {NULL, ""}, + /* 04 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_initCursor), + /* 08 */ + OPCODE(o1_initCursorAnim), + OPCODE(o1_clearCursorAnim), + OPCODE(o1_setRenderFlags), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + OPCODE(o1_loadAnim), + OPCODE(o1_freeAnim), + OPCODE(o1_updateAnim), + OPCODE(o2_drawStub), + /* 14 */ + OPCODE(o1_initMult), + OPCODE(o1_multFreeMult), + OPCODE(o1_animate), + OPCODE(o1_multLoadMult), + /* 18 */ + OPCODE(o1_storeParams), + OPCODE(o1_getObjAnimSize), + OPCODE(o1_loadStatic), + OPCODE(o1_freeStatic), + /* 1C */ + OPCODE(o1_renderStatic), + OPCODE(o1_loadCurLayer), + {NULL, ""}, + {NULL, ""}, + /* 20 */ + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + /* 24 */ + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + {NULL, ""}, + {NULL, ""}, + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o1_loadFontToSprite), + OPCODE(o1_freeFontToSprite), + {NULL, ""}, + {NULL, ""}, + /* 34 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 38 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 3C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 40 */ + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + /* 44 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 48 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 4C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 50 */ + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + /* 54 */ + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + {NULL, ""}, + /* 58 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 5C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 60 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 64 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 68 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 6C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 70 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 74 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 78 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 7C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 80 */ + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + /* 84 */ + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + OPCODE(o2_drawStub), + /* 88 */ + OPCODE(o2_drawStub), + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 8C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 90 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 94 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 98 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 9C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* A8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* AC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* B8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* BC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* C8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* CC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* D8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* DC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* E8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* EC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F0 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F4 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* F8 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* FC */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""} + }; + + static const OpcodeFuncEntryV2 opcodesFunc[80] = { + /* 00 */ + OPCODE(o1_callSub), + OPCODE(o1_callSub), + OPCODE(o1_drawPrintText), + OPCODE(o1_loadCursor), + /* 04 */ + {NULL, ""}, + OPCODE(o1_call), + OPCODE(o1_repeatUntil), + OPCODE(o1_whileDo), + /* 08 */ + OPCODE(o1_callBool), + OPCODE(o1_evaluateStore), + OPCODE(o1_loadSpriteToPos), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + {NULL, ""}, + OPCODE(o1_printText), + OPCODE(o1_loadTot), + OPCODE(o1_palLoad), + /* 14 */ + OPCODE(o1_keyFunc), + OPCODE(o1_capturePush), + OPCODE(o1_capturePop), + OPCODE(o1_animPalInit), + /* 18 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 1C */ + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_drawOperations), + OPCODE(o1_setcmdCount), + /* 20 */ + OPCODE(o1_return), + OPCODE(o1_renewTimeInVars), + OPCODE(o1_speakerOn), + OPCODE(o1_speakerOff), + /* 24 */ + OPCODE(o1_putPixel), + OPCODE(o1_func), + OPCODE(o1_createSprite), + OPCODE(o1_freeSprite), + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o1_returnTo), + OPCODE(o1_loadSpriteContent), + OPCODE(o1_copySprite), + OPCODE(o1_fillRect), + /* 34 */ + OPCODE(o1_drawLine), + OPCODE(o1_strToLong), + OPCODE(o1_invalidate), + OPCODE(o1_setBackDelta), + /* 38 */ + OPCODE(o1_playSound), + OPCODE(o1_stopSound), + OPCODE(o1_loadSound), + OPCODE(o1_freeSoundSlot), + /* 3C */ + OPCODE(o1_waitEndPlay), + OPCODE(o1_playComposition), + OPCODE(o1_getFreeMem), + OPCODE(o1_checkData), + /* 40 */ + {NULL, ""}, + OPCODE(o1_prepareStr), + OPCODE(o1_insertStr), + OPCODE(o1_cutStr), + /* 44 */ + OPCODE(o1_strstr), + OPCODE(o1_istrlen), + OPCODE(o1_setMousePos), + OPCODE(o1_setFrameRate), + /* 48 */ + OPCODE(o1_animatePalette), + OPCODE(o1_animateCursor), + OPCODE(o1_blitCursor), + OPCODE(o1_loadFont), + /* 4C */ + OPCODE(o1_freeFont), + OPCODE(o1_readData), + OPCODE(o1_writeData), + OPCODE(o1_manageDataFile), + }; + + _opcodesDrawV2 = opcodesDraw; + _opcodesFuncV2 = opcodesFunc; +} + +void Inter_v2::executeDrawOpcode(byte i) { + debug(4, "opcodeDraw %d (%s)", i, getOpcodeDrawDesc(i)); + + OpcodeDrawProcV2 op = _opcodesDrawV2[i].proc; + + if (op == NULL) + warning("unimplemented opcodeDraw: %d", i); + else + (this->*op) (); +} + +bool Inter_v2::executeFuncOpcode(byte i, byte j, char &cmdCount, int16 &counter, int16 &retFlag) { + debug(4, "opcodeFunc %d (%s)", i, getOpcodeFuncDesc(i, j)); + + if ((i > 4) || (j > 15)) { + warning("unimplemented opcodeFunc: %d.%d", i, j); + return false; + } + + OpcodeFuncProcV2 op = _opcodesFuncV2[i*16 + j].proc; + + if (op == NULL) + warning("unimplemented opcodeFunc: %d.%d", i, j); + else + return (this->*op) (cmdCount, counter, retFlag); + return false; +} + +const char *Inter_v2::getOpcodeDrawDesc(byte i) { + return _opcodesDrawV2[i].desc; +} + +const char *Inter_v2::getOpcodeFuncDesc(byte i, byte j) +{ + if ((i > 4) || (j > 15)) + return ""; + + return _opcodesFuncV2[i*16 + j].desc; +} + + +} // End of namespace Gob diff --git a/gob/module.mk b/gob/module.mk index 6d2acac63c..5a9dccf71a 100644 --- a/gob/module.mk +++ b/gob/module.mk @@ -12,6 +12,8 @@ MODULE_OBJS := \ gob/goblin.o \ gob/init.o \ gob/inter.o \ + gob/inter_v1.o \ + gob/inter_v2.o \ gob/map.o \ gob/mult.o \ gob/pack.o \ |