diff options
Diffstat (limited to 'engines/gob')
-rw-r--r-- | engines/gob/cdrom.cpp | 2 | ||||
-rw-r--r-- | engines/gob/dataio.cpp | 6 | ||||
-rw-r--r-- | engines/gob/detection.cpp | 53 | ||||
-rw-r--r-- | engines/gob/driver_vga.cpp | 2 | ||||
-rw-r--r-- | engines/gob/game.cpp | 2 | ||||
-rw-r--r-- | engines/gob/game_v1.cpp | 2 | ||||
-rw-r--r-- | engines/gob/game_v2.cpp | 2 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 13 | ||||
-rw-r--r-- | engines/gob/goblin_v2.cpp | 3 | ||||
-rw-r--r-- | engines/gob/init.cpp | 23 | ||||
-rw-r--r-- | engines/gob/inter.h | 49 | ||||
-rw-r--r-- | engines/gob/inter_v1.cpp | 38 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 14 | ||||
-rw-r--r-- | engines/gob/inter_v3.cpp | 884 | ||||
-rw-r--r-- | engines/gob/map.cpp | 2 | ||||
-rw-r--r-- | engines/gob/module.mk | 1 | ||||
-rw-r--r-- | engines/gob/palanim.cpp | 6 | ||||
-rw-r--r-- | engines/gob/parse.cpp | 6 | ||||
-rw-r--r-- | engines/gob/parse_v2.cpp | 48 | ||||
-rw-r--r-- | engines/gob/scenery.cpp | 24 | ||||
-rw-r--r-- | engines/gob/scenery.h | 2 | ||||
-rw-r--r-- | engines/gob/sound.cpp | 6 | ||||
-rw-r--r-- | engines/gob/sound.h | 2 | ||||
-rw-r--r-- | engines/gob/util.cpp | 2 |
24 files changed, 1095 insertions, 97 deletions
diff --git a/engines/gob/cdrom.cpp b/engines/gob/cdrom.cpp index a597737b8c..050c1f8318 100644 --- a/engines/gob/cdrom.cpp +++ b/engines/gob/cdrom.cpp @@ -167,7 +167,7 @@ void CDROM::startTrack(const char *trackname) { } if (!matchPtr) { - warning("Track %s not found", trackname); + warning("Track \"%s\" not found", trackname); return; } diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp index b16746ca4c..3d4610d961 100644 --- a/engines/gob/dataio.cpp +++ b/engines/gob/dataio.cpp @@ -285,12 +285,12 @@ void DataIO::openDataFile(const char *src, bool itk) { break; if (file == MAX_DATA_FILES) - error("openDataFile: Data file slots are full"); + error("DataIO::openDataFile(): Data file slots are full"); _dataFileHandles[file] = file_open(path); if (_dataFileHandles[file] == -1) - error("openDataFile: Can't open %s data file", path); + error("DataIO::openDataFile(): Can't open data file \"%s\"", path); _dataFileItk[file] = itk; _numDataChunks[file] = file_getHandle(_dataFileHandles[file])->readUint16LE(); @@ -447,7 +447,7 @@ int32 DataIO::getDataSize(const char *name) { return chunkSz; if (!file.open(buf)) - error("getDataSize: Can't find data(%s)", name); + error("DataIO::getDataSize(): Can't find data \"%s\"", name); chunkSz = file.size(); file.close(); diff --git a/engines/gob/detection.cpp b/engines/gob/detection.cpp index 6c7e930e03..db75f8d374 100644 --- a/engines/gob/detection.cpp +++ b/engines/gob/detection.cpp @@ -723,7 +723,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -731,11 +731,11 @@ static const GOBGameDescription gameDescriptions[] = { "gob3", "", AD_ENTRY1("intro.stk", "1e2f64ec8dfa89f42ee49936a27e66e7"), - UNK_LANG, + EN_USA, kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { // Supplied by paul66 in bug report #1652352 @@ -747,7 +747,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -759,7 +759,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -771,7 +771,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -783,7 +783,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -795,8 +795,8 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformAmiga, Common::ADGF_NO_FLAGS }, - GF_GOB2, - "intro" + GF_GOB3, + "menu" }, { { @@ -807,7 +807,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -819,7 +819,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -831,7 +831,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -843,7 +843,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -855,7 +855,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { // Supplied by paul66 and noizert in bug reports #1652352 and #1691230 @@ -867,7 +867,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -879,7 +879,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_DEMO }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -891,7 +891,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_DEMO }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -903,7 +903,7 @@ static const GOBGameDescription gameDescriptions[] = { kPlatformPC, Common::ADGF_DEMO }, - GF_GOB2, + GF_GOB3, "intro" }, { @@ -1008,6 +1008,18 @@ static const GOBGameDescription fallbackDescs[] = { }, { { + "gob3", + "unknown", + AD_ENTRY1(0, 0), + UNK_LANG, + kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GF_GOB3, + "intro" + }, + { + { "gob3cd", "unknown", AD_ENTRY1(0, 0), @@ -1015,7 +1027,7 @@ static const GOBGameDescription fallbackDescs[] = { kPlatformPC, Common::ADGF_NO_FLAGS }, - GF_GOB2 | GF_CD, + GF_GOB3 | GF_CD, "intro" }, }; @@ -1027,7 +1039,8 @@ static const ADFileBasedFallback fileBased[] = { { &fallbackDescs[2], { "intro.stk", "disk2.stk", "disk3.stk", 0 } }, { &fallbackDescs[3], { "intro.stk", "gobnew.lic", 0 } }, { &fallbackDescs[4], { "intro.stk", "scaa.imd", "scba.imd", "scbf.imd", 0 } }, - { &fallbackDescs[5], { "intro.stk", "mus_gob3.lic", 0 } }, + { &fallbackDescs[5], { "intro.stk", "imd.itk", 0 } }, + { &fallbackDescs[6], { "intro.stk", "mus_gob3.lic", 0 } }, { 0, { 0 } } }; diff --git a/engines/gob/driver_vga.cpp b/engines/gob/driver_vga.cpp index b5237430dc..759136180e 100644 --- a/engines/gob/driver_vga.cpp +++ b/engines/gob/driver_vga.cpp @@ -81,7 +81,7 @@ void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y, for (int i = 0; i < fontDesc->itemHeight; i++) { data = READ_BE_UINT16(src); src += 2; - if (fontDesc->itemSize <= 8) + if (fontDesc->itemWidth <= 8) src--; for (int j = 0; j < fontDesc->itemWidth; j++) { diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index a15ad2d9c3..dbd4dd1176 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -203,7 +203,7 @@ void Game::capturePush(int16 left, int16 top, int16 width, int16 height) { int16 right; if (_captureCount == 20) - error("capturePush: Capture stack overflow!"); + error("Game::capturePush(): Capture stack overflow!"); _captureStack[_captureCount].left = left; _captureStack[_captureCount].top = top; diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index 0f0547f4fa..ddc34f176c 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -290,7 +290,7 @@ int16 Game_v1::addNewCollision(int16 id, int16 left, int16 top, ptr->funcLeave = funcLeave; return i; } - error("addNewCollision: Collision array full!\n"); + error("Game_v1::addNewCollision(): Collision array full!\n"); return 0; } diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 041292f499..c978906910 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -327,7 +327,7 @@ int16 Game_v2::addNewCollision(int16 id, int16 left, int16 top, int16 right, int return i; } - error("addNewCollision: Collision array full!\n"); + error("Game_v2::addNewCollision(): Collision array full!\n"); return 0; } diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index 42c7f51b02..1502764f43 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -618,6 +618,17 @@ int GobEngine::init() { _map = new Map_v2(this); _goblin = new Goblin_v2(this); _scenery = new Scenery_v2(this); + } else if (_features & Gob::GF_GOB3) { + _init = new Init_v2(this); + _video = new Video_v2(this); + _inter = new Inter_v3(this); + _parse = new Parse_v2(this); + _mult = new Mult_v2(this); + _draw = new Draw_v2(this); + _game = new Game_v2(this); + _map = new Map_v2(this); + _goblin = new Goblin_v2(this); + _scenery = new Scenery_v2(this); } else error("GobEngine::init(): Unknown version of game engine"); @@ -625,7 +636,7 @@ int GobEngine::init() { if (!_noMusic && !(_platform == Common::kPlatformAmiga) && !(_platform == Common::kPlatformAtariST) && (((_platform == Common::kPlatformMacintosh) && (_features & Gob::GF_GOB1)) || - (_features & Gob::GF_GOB2))) + (_features & Gob::GF_GOB2) || (_features & Gob::GF_GOB3))) _adlib = new Adlib(this); _vm = this; diff --git a/engines/gob/goblin_v2.cpp b/engines/gob/goblin_v2.cpp index ada54fbb5b..de9da6afc0 100644 --- a/engines/gob/goblin_v2.cpp +++ b/engines/gob/goblin_v2.cpp @@ -463,6 +463,9 @@ void Goblin_v2::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc, } if (animData->frame >= framesCount) { + if (animData->nextState == -1) // TODO: This should never happen + return; + state = animData->nextState; animation = obj->goblinStates[state][0].animation; layer = obj->goblinStates[state][0].layer; diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 5a024b3dd8..ec82d05bda 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -32,6 +32,7 @@ #include "gob/cdrom.h" #include "gob/draw.h" #include "gob/game.h" +#include "gob/palanim.h" #include "gob/sound.h" #include "gob/video.h" #include "gob/imd.h" @@ -158,14 +159,34 @@ void Init::initGame(const char *totName) { _vm->_cdrom->testCD(1, "GOB"); _vm->_cdrom->readLIC("gob.lic"); - _vm->_draw->_cursorIndex = -1; + // Search for a Coktel logo animation or image to display imdHandle = _vm->_dataIO->openData("coktel.imd"); if (imdHandle >= 0) { _vm->_dataIO->closeData(imdHandle); _vm->_draw->initScreen(); + _vm->_draw->_cursorIndex = -1; _vm->_util->longDelay(200); // Letting everything settle _vm->_imdPlayer->play("coktel", -1, -1, true); _vm->_draw->closeScreen(); + } else if ((imdHandle = _vm->_dataIO->openData("coktel.clt")) >= 0) { + _vm->_draw->initScreen(); + _vm->_util->clearPalette(); + _vm->_dataIO->readData(imdHandle, (byte *) _vm->_draw->_vgaPalette, 768); + _vm->_dataIO->closeData(imdHandle); + imdHandle = _vm->_dataIO->openData("coktel.ims"); + if (imdHandle >= 0) { + byte *sprBuf; + + _vm->_dataIO->closeData(imdHandle); + sprBuf = _vm->_dataIO->getData("coktel.ims"); + _vm->_video->drawPackedSprite(sprBuf, 320, 200, 0, 0, 0, + _vm->_draw->_frontSurface); + _vm->_palAnim->fade(_palDesc, 0, 0); + _vm->_util->delay(500); + + delete[] sprBuf; + } + _vm->_draw->closeScreen(); } _vm->_game->start(); diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 2129a57b4b..be7ed9fe21 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -21,8 +21,8 @@ * */ -#ifndef GOB_INTERPRET_H -#define GOB_INTERPRET_H +#ifndef GOB_INTER_H +#define GOB_INTER_H #include "gob/goblin.h" @@ -401,15 +401,15 @@ protected: struct OpcodeDrawEntryBargon { OpcodeDrawProcBargon proc; const char *desc; - }; + }; struct OpcodeFuncEntryBargon { OpcodeFuncProcBargon proc; const char *desc; - }; + }; struct OpcodeGoblinEntryBargon { OpcodeGoblinProcBargon proc; const char *desc; - }; + }; const OpcodeDrawEntryBargon *_opcodesDrawBargon; const OpcodeFuncEntryBargon *_opcodesFuncBargon; const OpcodeGoblinEntryBargon *_opcodesGoblinBargon; @@ -435,6 +435,43 @@ protected: void oBargon_intro9(OpGobParams ¶ms); }; +class Inter_v3 : public Inter_v2 { +public: + Inter_v3(GobEngine *vm); + virtual ~Inter_v3() {}; + +protected: + typedef void (Inter_v3::*OpcodeDrawProcV3)(); + typedef bool (Inter_v3::*OpcodeFuncProcV3)(OpFuncParams &); + typedef void (Inter_v3::*OpcodeGoblinProcV3)(OpGobParams &); + struct OpcodeDrawEntryV3 { + OpcodeDrawProcV3 proc; + const char *desc; + }; + struct OpcodeFuncEntryV3 { + OpcodeFuncProcV3 proc; + const char *desc; + }; + struct OpcodeGoblinEntryV3 { + OpcodeGoblinProcV3 proc; + const char *desc; + }; + const OpcodeDrawEntryV3 *_opcodesDrawV3; + const OpcodeFuncEntryV3 *_opcodesFuncV3; + const OpcodeGoblinEntryV3 *_opcodesGoblinV3; + static const int _goblinFuncLookUp[][2]; + + virtual void setupOpcodes(); + virtual void executeDrawOpcode(byte i); + virtual bool executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms); + virtual void executeGoblinOpcode(int i, OpGobParams ¶ms); + virtual const char *getOpcodeDrawDesc(byte i); + virtual const char *getOpcodeFuncDesc(byte i, byte j); + virtual const char *getOpcodeGoblinDesc(int i); + + bool o3_getTotTextItemPart(OpFuncParams ¶ms); +}; + } // End of namespace Gob -#endif // GOB_INTERPRET_H +#endif // GOB_INTER_H diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 0eea277599..83d693c508 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1120,28 +1120,56 @@ void Inter_v1::o1_freeFontToSprite() { bool Inter_v1::o1_callSub(OpFuncParams ¶ms) { byte *storedIP; - uint32 offset; + uint16 offset; + offset = load16(); storedIP = _vm->_global->_inter_execPtr; - offset = READ_LE_UINT16(_vm->_global->_inter_execPtr); debugC(5, kDebugGameFlow, "tot = \"%s\", offset = %d", _vm->_game->_curTotFile, offset); + if (offset < 128) { + warning("Inter_v1::o1_callSub(): Offset %d points into the header. " + "Skipping call", offset); + return false; + } + // Skipping the copy protection screen in Gobliiins if (!_vm->_copyProtection && (_vm->_features & GF_GOB1) && (offset == 3905) && !scumm_stricmp(_vm->_game->_curTotFile, _vm->_startTot)) { debugC(2, kDebugGameFlow, "Skipping copy protection screen"); - _vm->_global->_inter_execPtr += 2; return false; } // Skipping the copy protection screen in Gobliins 2 if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (offset == 1746) && !scumm_stricmp(_vm->_game->_curTotFile, _vm->_startTot0)) { debugC(2, kDebugGameFlow, "Skipping copy protection screen"); - _vm->_global->_inter_execPtr += 2; return false; } + // TODO: DELETE ME! ---. +if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (_vm->_platform == Common::kPlatformAmiga) && (offset == 1722) && !scumm_stricmp(_vm->_game->_curTotFile, "intro0.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (offset == 361) && !scumm_stricmp(_vm->_game->_curTotFile, _vm->_startTot)) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (offset == 348) && !scumm_stricmp(_vm->_game->_curTotFile, _vm->_startTot)) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (offset == 1263) && !scumm_stricmp(_vm->_game->_curTotFile, "intro5.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (offset == 1202) && !scumm_stricmp(_vm->_game->_curTotFile, "intro5.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (offset == 2613) && !scumm_stricmp(_vm->_game->_curTotFile, "intro016.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB2) && (offset == 2688) && !scumm_stricmp(_vm->_game->_curTotFile, "intro016.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_BARGON) && (offset == 5462) && !scumm_stricmp(_vm->_game->_curTotFile, "ecran0.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_BARGON) && (offset == 5451) && !scumm_stricmp(_vm->_game->_curTotFile, "ecran0.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB3) && (offset == 1406) && !scumm_stricmp(_vm->_game->_curTotFile, "demo.tot")) + return false; +if (!_vm->_copyProtection && (_vm->_features & GF_GOB3) && (offset == 888) && !scumm_stricmp(_vm->_game->_curTotFile, "demo.tot")) + return false; + // TODO: DELETE ME! ---' _vm->_global->_inter_execPtr = _vm->_game->_totFileData + offset; @@ -1149,7 +1177,7 @@ bool Inter_v1::o1_callSub(OpFuncParams ¶ms) { return true; callSub(2); - _vm->_global->_inter_execPtr = storedIP + 2; + _vm->_global->_inter_execPtr = storedIP; return false; } diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 8ede483f45..58986d894c 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -747,7 +747,7 @@ void Inter_v2::checkSwitchTable(byte **ppExec) { break; default: - value = READ_VARO_UINT16(value); + value = (int16) READ_VARO_UINT16(value); break; } @@ -1377,6 +1377,10 @@ void Inter_v2::o2_initScreen() { if (height > 0) _vm->_video->_surfHeight = height; + if (offY != 0) + warning("Inter_v2::o2_initScreen(): Stub: Horizontal split (%d/%d)", + _vm->_video->_surfHeight - offY, offY); + _vm->_draw->closeScreen(); _vm->_util->clearPalette(); memset(_vm->_global->_redPalette, 0, 256); @@ -2033,7 +2037,6 @@ int16 Inter_v2::loadSound(int16 search) { } _vm->_game->freeSoundSlot(slot); - _vm->_game->_soundSamples[slot]._id = id; if (id == -1) { char sndfile[14]; @@ -2055,8 +2058,6 @@ int16 Inter_v2::loadSound(int16 search) { source = SOUND_EXT; dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); - if (_vm->_game->_totFileData[0x29] >= 51) - _vm->_snd->convToSigned(dataPtr, dataSize); } else { int16 totSize; @@ -2068,10 +2069,7 @@ int16 Inter_v2::loadSound(int16 search) { if (dataPtr) { _vm->_game->_soundSamples[slot].load(type, source, dataPtr, dataSize); - - if ((source == SOUND_EXT) && (type == SOUND_SND)) - if (_vm->_game->_totFileData[0x29] >= 51) - _vm->_game->_soundSamples[slot].flip(); + _vm->_game->_soundSamples[slot]._id = id; } return slot; diff --git a/engines/gob/inter_v3.cpp b/engines/gob/inter_v3.cpp new file mode 100644 index 0000000000..2d1dd46708 --- /dev/null +++ b/engines/gob/inter_v3.cpp @@ -0,0 +1,884 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2004 Ivan Dubrov + * Copyright (C) 2004-2006 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. + * + * $URL$ + * $Id$ + * + */ + +#include "common/stdafx.h" +#include "common/endian.h" + +#include "gob/gob.h" +#include "gob/inter.h" +#include "gob/global.h" +#include "gob/game.h" +#include "gob/parse.h" + +namespace Gob { + +#define OPCODE(x) _OPCODE(Inter_v3, x) + +const int Inter_v3::_goblinFuncLookUp[][2] = { + {0, 0}, + {2, 1}, + {3, 2}, + {4, 3}, + {5, 4}, + {6, 5}, + {7, 6}, + {8, 7}, + {9, 8}, + {10, 9}, + {12, 10}, + {13, 11}, + {14, 12}, + {15, 13}, + {16, 14}, + {21, 15}, + {22, 16}, + {23, 17}, + {24, 18}, + {25, 19}, + {26, 20}, + {27, 21}, + {28, 22}, + {29, 23}, + {30, 24}, + {32, 25}, + {33, 26}, + {34, 27}, + {35, 28}, + {36, 29}, + {37, 30}, + {40, 31}, + {41, 32}, + {42, 33}, + {43, 34}, + {44, 35}, + {50, 36}, + {52, 37}, + {53, 38}, + {100, 39}, + {152, 40}, + {200, 41}, + {201, 42}, + {202, 43}, + {203, 44}, + {204, 45}, + {250, 46}, + {251, 47}, + {252, 48}, + {500, 49}, + {502, 50}, + {503, 51}, + {600, 52}, + {601, 53}, + {602, 54}, + {603, 55}, + {604, 56}, + {605, 57}, + {1000, 58}, + {1001, 59}, + {1002, 60}, + {1003, 61}, + {1004, 62}, + {1005, 63}, + {1006, 64}, + {1008, 65}, + {1009, 66}, + {1010, 67}, + {1011, 68}, + {1015, 69}, + {2005, 70} +}; + +Inter_v3::Inter_v3(GobEngine *vm) : Inter_v2(vm) { + setupOpcodes(); +} + +void Inter_v3::setupOpcodes() { + static const OpcodeDrawEntryV3 opcodesDraw[256] = { + /* 00 */ + OPCODE(o1_loadMult), + OPCODE(o2_playMult), + OPCODE(o1_freeMultKeys), + {NULL, ""}, + /* 04 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + OPCODE(o1_initCursor), + /* 08 */ + OPCODE(o1_initCursorAnim), + OPCODE(o1_clearCursorAnim), + OPCODE(o2_setRenderFlags), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + OPCODE(o1_loadAnim), + OPCODE(o1_freeAnim), + OPCODE(o1_updateAnim), + OPCODE(o2_multSub), + /* 14 */ + OPCODE(o2_initMult), + OPCODE(o1_freeMult), + OPCODE(o1_animate), + OPCODE(o2_loadMultObject), + /* 18 */ + OPCODE(o1_getAnimLayerInfo), + OPCODE(o1_getObjAnimSize), + OPCODE(o1_loadStatic), + OPCODE(o1_freeStatic), + /* 1C */ + OPCODE(o2_renderStatic), + OPCODE(o2_loadCurLayer), + {NULL, ""}, + {NULL, ""}, + /* 20 */ + OPCODE(o2_playCDTrack), + OPCODE(o2_waitCDTrackEnd), + OPCODE(o2_stopCD), + OPCODE(o2_readLIC), + /* 24 */ + OPCODE(o2_freeLIC), + OPCODE(o2_getCDTrackPos), + {NULL, ""}, + {NULL, ""}, + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + OPCODE(o2_loadFontToSprite), + OPCODE(o1_freeFontToSprite), + {NULL, ""}, + {NULL, ""}, + /* 34 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 38 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 3C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 40 */ + OPCODE(o2_totSub), + OPCODE(o2_switchTotSub), + OPCODE(o2_copyVars), + OPCODE(o2_pasteVars), + /* 44 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 48 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 4C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 50 */ + OPCODE(o2_loadMapObjects), + OPCODE(o2_freeGoblins), + OPCODE(o2_moveGoblin), + OPCODE(o2_writeGoblinPos), + /* 54 */ + OPCODE(o2_stopGoblin), + OPCODE(o2_setGoblinState), + OPCODE(o2_placeGoblin), + {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_initScreen), + OPCODE(o2_scroll), + OPCODE(o2_setScrollOffset), + OPCODE(o2_playImd), + /* 84 */ + OPCODE(o2_getImdInfo), + OPCODE(o2_openItk), + OPCODE(o2_closeItk), + OPCODE(o2_setImdFrontSurf), + /* 88 */ + OPCODE(o2_resetImdFrontSurf), + {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 OpcodeFuncEntryV3 opcodesFunc[80] = { + /* 00 */ + OPCODE(o1_callSub), + OPCODE(o1_callSub), + OPCODE(o1_printTotText), + OPCODE(o1_loadCursor), + /* 04 */ + {NULL, ""}, + OPCODE(o1_switch), + OPCODE(o1_repeatUntil), + OPCODE(o1_whileDo), + /* 08 */ + OPCODE(o1_if), + OPCODE(o2_evaluateStore), + OPCODE(o1_loadSpriteToPos), + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + {NULL, ""}, + OPCODE(o2_printText), + OPCODE(o1_loadTot), + OPCODE(o1_palLoad), + /* 14 */ + OPCODE(o1_keyFunc), + OPCODE(o1_capturePush), + OPCODE(o1_capturePop), + OPCODE(o2_animPalInit), + /* 18 */ + {NULL, ""}, + {NULL, ""}, + OPCODE(o3_getTotTextItemPart), + {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(o2_goblinFunc), + OPCODE(o2_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(o2_stopSound), + OPCODE(o2_loadSound), + OPCODE(o1_freeSoundSlot), + /* 3C */ + OPCODE(o1_waitEndPlay), + OPCODE(o1_playComposition), + OPCODE(o2_getFreeMem), + OPCODE(o2_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(o2_readData), + OPCODE(o2_writeData), + OPCODE(o1_manageDataFile), + }; + + static const OpcodeGoblinEntryV3 opcodesGoblin[71] = { + /* 00 */ + OPCODE(o2_loadInfogramesIns), + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 04 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 08 */ + {NULL, ""}, + OPCODE(o2_playInfogrames), + {NULL, ""}, + {NULL, ""}, + /* 0C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 10 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 14 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 18 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 1C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 20 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 24 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + OPCODE(o2_handleGoblins), + /* 28 */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 2C */ + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + {NULL, ""}, + /* 30 */ + {NULL, ""}, + {NULL, ""}, + {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, ""}, + }; + + _opcodesDrawV3 = opcodesDraw; + _opcodesFuncV3 = opcodesFunc; + _opcodesGoblinV3 = opcodesGoblin; +} + +void Inter_v3::executeDrawOpcode(byte i) { + debugC(1, kDebugDrawOp, "opcodeDraw %d [0x%X] (%s)", + i, i, getOpcodeDrawDesc(i)); + + OpcodeDrawProcV3 op = _opcodesDrawV3[i].proc; + + if (op == NULL) + warning("unimplemented opcodeDraw: %d", i); + else + (this->*op) (); +} + +bool Inter_v3::executeFuncOpcode(byte i, byte j, OpFuncParams ¶ms) { + debugC(1, kDebugFuncOp, "opcodeFunc %d.%d [0x%X.0x%X] (%s)", + i, j, i, j, getOpcodeFuncDesc(i, j)); + + if ((i > 4) || (j > 15)) { + warning("unimplemented opcodeFunc: %d.%d", i, j); + return false; + } + + OpcodeFuncProcV3 op = _opcodesFuncV3[i*16 + j].proc; + + if (op == NULL) + warning("unimplemented opcodeFunc: %d.%d", i, j); + else + return (this->*op) (params); + + return false; +} + +void Inter_v3::executeGoblinOpcode(int i, OpGobParams ¶ms) { + debugC(1, kDebugGobOp, "opcodeGoblin %d [0x%X] (%s)", + i, i, getOpcodeGoblinDesc(i)); + + OpcodeGoblinProcV3 op = NULL; + + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) { + op = _opcodesGoblinV3[_goblinFuncLookUp[j][1]].proc; + break; + } + + if (op == NULL) { + int16 val; + + _vm->_global->_inter_execPtr -= 2; + val = load16(); + _vm->_global->_inter_execPtr += val << 1; + } + else + (this->*op) (params); +} + +const char *Inter_v3::getOpcodeDrawDesc(byte i) { + return _opcodesDrawV3[i].desc; +} + +const char *Inter_v3::getOpcodeFuncDesc(byte i, byte j) { + if ((i > 4) || (j > 15)) + return ""; + + return _opcodesFuncV3[i*16 + j].desc; +} + +const char *Inter_v3::getOpcodeGoblinDesc(int i) { + for (int j = 0; j < ARRAYSIZE(_goblinFuncLookUp); j++) + if (_goblinFuncLookUp[j][0] == i) + return _opcodesGoblinV3[_goblinFuncLookUp[j][1]].desc; + return ""; +} + +bool Inter_v3::o3_getTotTextItemPart(OpFuncParams ¶ms) { + byte *totData; + int16 totTextItem; + int16 part, curPart = 0; + int16 offX = 0, offY = 0; + int16 collId, collCmd; + uint32 stringStartVar, stringVar; + bool end; + + totTextItem = load16(); + stringStartVar = _vm->_parse->parseVarIndex(); + part = _vm->_parse->parseValExpr(); + + stringVar = stringStartVar; + WRITE_VARO_UINT8(stringVar, 0); + + if (!_vm->_game->_totTextData) + return false; + + totData = _vm->_game->_totTextData->dataPtr + + _vm->_game->_totTextData->items[totTextItem].offset; + + // Skip background rectangles + while(((int16) READ_LE_UINT16(totData)) != -1) + totData += 9; + totData += 2; + + while (*totData != 1) { + switch(*totData) { + case 2: + case 5: + totData++; + offX = READ_LE_UINT16(totData); + offY = READ_LE_UINT16(totData + 2); + totData += 4; + break; + + case 3: + case 4: + totData += 2; + break; + + case 6: + totData++; + + collCmd = *totData++; + if (collCmd & 0x80) { + collId = READ_LE_UINT16(totData); + totData += 2; + } + + // Skip collision coordinates + if (collCmd & 0x40) + totData += 8; + + if ((collCmd & 0x8F) && ((-collId - 1) == part)) { + int n = 0; + + while (1) { + if ((*totData < 1) || (*totData > 7)) { + if (*totData >= 32) { + WRITE_VARO_UINT8(stringVar++, *totData++); + n++; + } else + totData++; + continue; + } + + if ((n != 0) || (*totData == 1) || + (*totData == 6) || (*totData == 7)) { + WRITE_VARO_UINT8(stringVar, 0); + return false; + } + + switch(*totData) { + case 2: + case 5: + totData += 5; + break; + + case 3: + case 4: + totData += 2; + break; + } + } + + } + break; + + case 7: + case 8: + case 9: + totData++; + break; + + case 10: + if (curPart == part) { + WRITE_VARO_UINT8(stringVar++, 0xFF); + WRITE_VARO_UINT16(stringVar, offX); + WRITE_VARO_UINT16(stringVar + 2, offY); + WRITE_VARO_UINT16(stringVar + 4, + totData - _vm->_game->_totTextData->dataPtr); + WRITE_VARO_UINT8(stringVar + 6, 0); + return false; + } + + end = false; + while (!end) { + switch(*totData) { + case 2: + case 5: + if (ABS(offY - READ_LE_UINT16(totData + 3)) > 1) + end = true; + else + totData += 5; + break; + + case 3: + totData += 2; + break; + + case 10: + totData += totData[1] * 2 + 2; + break; + + default: + if (*totData < 32) + end = true; + while (*totData >= 32) + totData++; + break; + } + } + + if (part >= 0) + curPart++; + break; + + default: + while (1) { + + while (*totData >= 32) + WRITE_VARO_UINT8(stringVar++, *totData++); + WRITE_VARO_UINT8(stringVar, 0); + + if (((*totData != 2) && (*totData != 5)) || + (ABS(offY - READ_LE_UINT16(totData + 3)) > 1)) { + + if (curPart == part) + return false; + + stringVar = stringStartVar; + WRITE_VARO_UINT8(stringVar, 0); + + while (*totData >= 32) + totData++; + + if (part >= 0) + curPart++; + break; + + } else + totData += 5; + + } + break; + } + } + + return false; +} + +} // End of namespace Gob diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp index 3c137d72e9..e628163c53 100644 --- a/engines/gob/map.cpp +++ b/engines/gob/map.cpp @@ -463,7 +463,7 @@ void Map::loadMapsInitGobs(void) { int16 layer; if (!_loadFromAvo) - error("load: Loading .pas/.pos files is not supported!"); + error("Map::loadMapsInitGobs(): Loading .pas/.pos files is not supported!"); for (int i = 0; i < 3; i++) _vm->_goblin->nextLayer(_vm->_goblin->_goblins[i]); diff --git a/engines/gob/module.mk b/engines/gob/module.mk index 5673349a1f..7d3f1cc0e9 100644 --- a/engines/gob/module.mk +++ b/engines/gob/module.mk @@ -24,6 +24,7 @@ MODULE_OBJS := \ inter.o \ inter_v1.o \ inter_v2.o \ + inter_v3.o \ inter_bargon.o \ map.o \ map_v1.o \ diff --git a/engines/gob/palanim.cpp b/engines/gob/palanim.cpp index 98b6d0fa8d..50686beb6f 100644 --- a/engines/gob/palanim.cpp +++ b/engines/gob/palanim.cpp @@ -80,12 +80,12 @@ bool PalAnim::fadeStep(int16 oper) { byte newBlue; if (_vm->_global->_colorCount != 256) - error("fadeStep: Only 256 color mode is supported!"); + error("PalAnim::fadeStep(): Only 256 color mode is supported!"); if (oper == 0) { if (_vm->_global->_setAllPalette) { if (_vm->_global->_inVM != 0) - error("fade: _vm->_global->_inVM != 0 not supported."); + error("PalAnim::fadeStep(): _vm->_global->_inVM != 0 not supported."); for (int i = 0; i < 256; i++) { newRed = fadeColor(_vm->_global->_redPalette[i], _toFadeRed[i]); @@ -156,7 +156,7 @@ void PalAnim::fade(Video::PalDesc *palDesc, int16 fadeV, int16 allColors) { } } else { if (_vm->_global->_inVM != 0) - error("fade: _vm->_global->_inVM != 0 is not supported"); + error("PalAnim::fade(): _vm->_global->_inVM != 0 is not supported"); if (!palDesc) { for (i = 0; i < 256; i++) { diff --git a/engines/gob/parse.cpp b/engines/gob/parse.cpp index 90b10f2aa6..93af23c82b 100644 --- a/engines/gob/parse.cpp +++ b/engines/gob/parse.cpp @@ -49,7 +49,7 @@ int32 Parse::encodePtr(byte *ptr, int type) { offset = ptr - ((byte *) _vm->_global->_inter_resStr); break; default: - error("encodePtr: Unknown pointer type"); + error("Parse::encodePtr(): Unknown pointer type"); } assert((offset & 0xF0000000) == 0); return (type << 28) | offset; @@ -69,7 +69,7 @@ byte *Parse::decodePtr(int32 n) { ptr = (byte *) _vm->_global->_inter_resStr; break; default: - error("decodePtr: Unknown pointer type"); + error("Parse::decodePtr(): Unknown pointer type"); } return ptr + (n & 0x0FFFFFFF); } @@ -367,7 +367,7 @@ void Parse::printExpr_internal(char stopToken) { default: debugN(5, "<%d>", (int16) operation); - error("printExpr: invalid operator in expression"); + error("Parse::printExpr(): invalid operator in expression"); break; } diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp index d32ae0382f..cb72d1866e 100644 --- a/engines/gob/parse_v2.cpp +++ b/engines/gob/parse_v2.cpp @@ -116,6 +116,8 @@ int16 Parse_v2::parseValExpr(byte stopToken) { static int16 flag = 0; int16 oldflag; + memset(values, 0, 20 * sizeof(int16)); + oldflag = flag; if (flag == 0) { flag = 1; @@ -388,10 +390,7 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { case 26: case 27: case 28: - if ((operation == 27) || (operation == 16)) - *operPtr = 20; - else - *operPtr = operation - 6; + *operPtr = (operation == 28) ? 22 : 20; temp = _vm->_inter->load16(); dimCount = *_vm->_global->_inter_execPtr++; arrDescPtr = _vm->_global->_inter_execPtr; @@ -481,11 +480,6 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { parseExpr(10, 0); switch (operation) { - case 5: - _vm->_global->_inter_resVal = - _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; - break; - case 0: case 1: case 6: @@ -500,20 +494,27 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { _vm->_global->_inter_resVal = curVal; break; - case 10: + case 5: _vm->_global->_inter_resVal = - _vm->_util->getRandom(_vm->_global->_inter_resVal); + _vm->_global->_inter_resVal * _vm->_global->_inter_resVal; break; case 7: if (_vm->_global->_inter_resVal < 0) _vm->_global->_inter_resVal = -_vm->_global->_inter_resVal; break; + + case 10: + _vm->_global->_inter_resVal = + _vm->_util->getRandom(_vm->_global->_inter_resVal); + break; } + *operPtr = 20; *valPtr = _vm->_global->_inter_resVal; break; } + if ((stkPos > 0) && ((operPtr[-1] == 1) || (operPtr[-1] == 11))) { stkPos--; operPtr--; @@ -522,12 +523,8 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { if (*operPtr == 1) { *operPtr = 20; valPtr[0] = -valPtr[1]; - } else if (*operPtr == 11) { - if (operPtr[1] == 23) - *operPtr = 24; - else - *operPtr = 23; - } + } else + *operPtr = (operPtr[1] == 23) ? 24 : 23; } if (stkPos <= 0) @@ -600,11 +597,7 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { operPtr--; valPtr--; } else if (operPtr[-2] == 11) { - if (operPtr[-1] == 23) - operPtr[-2] = 24; - else - operPtr[-2] = 23; - + operPtr[-2] = (operPtr[-1] == 23) ? 24 : 23; stkPos--; operPtr--; valPtr--; @@ -619,6 +612,7 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { operPtr -= 2; valPtr -= 2; break; + case 6: valPtr[-3] /= valPtr[-1]; stkPos -= 2; @@ -897,6 +891,11 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { *arg_2 = operStack[0]; switch (operStack[0]) { + case 11: + if (arg_2 != 0) + *arg_2 ^= 1; + break; + case 20: _vm->_global->_inter_resVal = values[0]; break; @@ -906,11 +905,6 @@ int16 Parse_v2::parseExpr(byte stopToken, byte *arg_2) { strcpy(_vm->_global->_inter_resStr, (char *) decodePtr(values[0])); break; - case 11: - if (arg_2 != 0) - *arg_2 ^= 1; - break; - case 23: case 24: break; diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp index 2206f654ca..75a3ed9a4e 100644 --- a/engines/gob/scenery.cpp +++ b/engines/gob/scenery.cpp @@ -303,7 +303,7 @@ void Scenery::renderStatic(int16 scenery, int16 layer) { } } -void Scenery::updateStatic(int16 orderFrom) { +void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) { StaticLayer *layerPtr; PieceDesc **pictPtr; StaticPlane *planePtr; @@ -318,14 +318,11 @@ void Scenery::updateStatic(int16 orderFrom) { int16 top; int16 bottom; - if (_curStatic == -1) - return; - - if (_curStaticLayer >= _statics[_curStatic].layersCount) + if (layer >= _statics[index].layersCount) return; - layerPtr = &_statics[_curStatic].layers[_curStaticLayer]; - pictPtr = _statics[_curStatic].pieces; + layerPtr = &_statics[index].layers[layer]; + pictPtr = _statics[index].pieces; planeCount = layerPtr->planeCount; @@ -381,7 +378,7 @@ void Scenery::updateStatic(int16 orderFrom) { _toRedrawBottom - _vm->_draw->_destSpriteY + 1; _vm->_draw->_sourceSurface = - _staticPictToSprite[_curStatic * 7 + pictIndex]; + _staticPictToSprite[index * 7 + pictIndex]; _vm->_draw->_destSurface = 21; _vm->_draw->_transparency = planePtr->transp ? 3 : 0; _vm->_draw->spriteOperation(DRAW_BLITSURF); @@ -389,6 +386,17 @@ void Scenery::updateStatic(int16 orderFrom) { } } +void Scenery::updateStatic(int16 orderFrom) { + if (_curStatic == -1) + return; + + updateStatic(orderFrom, _curStatic & 0xFF, _curStaticLayer & 0xFF); + + if (_curStatic & 0xFF00) + updateStatic(orderFrom, (_curStatic >> 8) & 0xFF, + (_curStaticLayer >> 8) & 0xFF); +} + int16 Scenery::loadAnim(char search) { int16 picsCount; int16 resId; diff --git a/engines/gob/scenery.h b/engines/gob/scenery.h index 4b3b2f18b6..864b74f18d 100644 --- a/engines/gob/scenery.h +++ b/engines/gob/scenery.h @@ -147,6 +147,8 @@ protected: Animation _animations[10]; GobEngine *_vm; + + void updateStatic(int16 orderFrom, byte index, byte layer); }; class Scenery_v1 : public Scenery { diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp index d9c9b10627..8494e1da07 100644 --- a/engines/gob/sound.cpp +++ b/engines/gob/sound.cpp @@ -67,12 +67,10 @@ void SoundDesc::free() { _id = 0; } -void SoundDesc::flip() { - if ((_type == SOUND_SND) && _data && _dataPtr) { - _frequency = -_frequency; +void SoundDesc::convToSigned() { + if ((_type == SOUND_SND) && _data && _dataPtr) for (uint32 i = 0; i < _size; i++) _dataPtr[i] ^= 0x80; - } } void SoundDesc::loadSND(byte *data, uint32 dSize) { diff --git a/engines/gob/sound.h b/engines/gob/sound.h index 93cb8081ed..ffdaf2a3d6 100644 --- a/engines/gob/sound.h +++ b/engines/gob/sound.h @@ -57,7 +57,7 @@ public: void set(SoundType type, SoundSource src, byte *data, uint32 dSize); void load(SoundType type, SoundSource src, byte *data, uint32 dSize); void free(); - void flip(); + void convToSigned(); // Which fade out length to use when the fade starts half-way through? int16 calcFadeOutLength(int16 frequency) { diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp index 6fcba7ac12..31f7cb6a67 100644 --- a/engines/gob/util.cpp +++ b/engines/gob/util.cpp @@ -428,7 +428,7 @@ void Util::listInsertBack(List *list, void *data) { if (list->pHead != 0) { if (list->pTail == 0) { list->pTail = list->pHead; - warning("listInsertBack: Broken list"); + warning("Util::listInsertBack(): Broken list"); } node = new ListNode; |