aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Hesse2007-04-05 13:37:20 +0000
committerSven Hesse2007-04-05 13:37:20 +0000
commitec5a9eee3132c5e7ccc5338f426f0839bb9e0913 (patch)
tree0d12e8599143530241731872be276c45e8a8c7fd
parentc5e7eaf7dbcc18f4d26532f64e6cbf3e8614fc18 (diff)
downloadscummvm-rg350-ec5a9eee3132c5e7ccc5338f426f0839bb9e0913.tar.gz
scummvm-rg350-ec5a9eee3132c5e7ccc5338f426f0839bb9e0913.tar.bz2
scummvm-rg350-ec5a9eee3132c5e7ccc5338f426f0839bb9e0913.zip
- Minor cleanup
- Added Inter_v3 (for new opcode o3_getTotTextItemPart) - Some fixes to let Gob3 start with the first screen svn-id: r26383
-rw-r--r--engines/gob/cdrom.cpp2
-rw-r--r--engines/gob/dataio.cpp6
-rw-r--r--engines/gob/detection.cpp53
-rw-r--r--engines/gob/driver_vga.cpp2
-rw-r--r--engines/gob/game.cpp2
-rw-r--r--engines/gob/game_v1.cpp2
-rw-r--r--engines/gob/game_v2.cpp2
-rw-r--r--engines/gob/gob.cpp13
-rw-r--r--engines/gob/goblin_v2.cpp3
-rw-r--r--engines/gob/init.cpp23
-rw-r--r--engines/gob/inter.h49
-rw-r--r--engines/gob/inter_v1.cpp38
-rw-r--r--engines/gob/inter_v2.cpp14
-rw-r--r--engines/gob/inter_v3.cpp884
-rw-r--r--engines/gob/map.cpp2
-rw-r--r--engines/gob/module.mk1
-rw-r--r--engines/gob/palanim.cpp6
-rw-r--r--engines/gob/parse.cpp6
-rw-r--r--engines/gob/parse_v2.cpp48
-rw-r--r--engines/gob/scenery.cpp24
-rw-r--r--engines/gob/scenery.h2
-rw-r--r--engines/gob/sound.cpp6
-rw-r--r--engines/gob/sound.h2
-rw-r--r--engines/gob/util.cpp2
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 &params);
};
+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 &params);
+ virtual void executeGoblinOpcode(int i, OpGobParams &params);
+ virtual const char *getOpcodeDrawDesc(byte i);
+ virtual const char *getOpcodeFuncDesc(byte i, byte j);
+ virtual const char *getOpcodeGoblinDesc(int i);
+
+ bool o3_getTotTextItemPart(OpFuncParams &params);
+};
+
} // 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 &params) {
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 &params) {
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 &params) {
+ 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 &params) {
+ 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 &params) {
+ 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;