aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorSven Hesse2006-05-11 19:43:30 +0000
committerSven Hesse2006-05-11 19:43:30 +0000
commit42e03bd70720643c0866abd7d6da50529d2c1f03 (patch)
tree80aff92316136cac1222ccf01782b5c58d4d7490 /engines
parentd6af07989df23219293cf6117e6cd0ae6a63e2e9 (diff)
downloadscummvm-rg350-42e03bd70720643c0866abd7d6da50529d2c1f03.tar.gz
scummvm-rg350-42e03bd70720643c0866abd7d6da50529d2c1f03.tar.bz2
scummvm-rg350-42e03bd70720643c0866abd7d6da50529d2c1f03.zip
- Sound! Still a bit glitchy, though:
- Negative frequences?!? Maybe "SFX"? - No sound for a small part of the intro (there aren't any sndKeys covering that part either) - A rythm-instrument (hi-hat?) in the titlemusic isn't played as one - More differences in the drawing functions fleshed out - Some of the goblin handling functions written - More unnamed functions and variables, wheeee... svn-id: r22410
Diffstat (limited to 'engines')
-rw-r--r--engines/gob/game.cpp120
-rw-r--r--engines/gob/game.h6
-rw-r--r--engines/gob/game_v2.cpp5
-rw-r--r--engines/gob/gob.cpp8
-rw-r--r--engines/gob/goblin.cpp289
-rw-r--r--engines/gob/goblin.h46
-rw-r--r--engines/gob/goblin_v1.cpp140
-rw-r--r--engines/gob/goblin_v2.cpp105
-rw-r--r--engines/gob/init.cpp4
-rw-r--r--engines/gob/inter.cpp43
-rw-r--r--engines/gob/inter.h24
-rw-r--r--engines/gob/inter_v1.cpp35
-rw-r--r--engines/gob/inter_v2.cpp487
-rw-r--r--engines/gob/map.cpp308
-rw-r--r--engines/gob/map.h20
-rw-r--r--engines/gob/map_v1.cpp346
-rw-r--r--engines/gob/map_v2.cpp192
-rw-r--r--engines/gob/module.mk4
-rw-r--r--engines/gob/mult.cpp8
-rw-r--r--engines/gob/mult.h38
-rw-r--r--engines/gob/mult_v1.cpp6
-rw-r--r--engines/gob/mult_v2.cpp96
-rw-r--r--engines/gob/music.cpp34
-rw-r--r--engines/gob/music.h13
-rw-r--r--engines/gob/sound.cpp11
-rw-r--r--engines/gob/sound.h2
-rw-r--r--engines/gob/util.h18
-rw-r--r--engines/gob/video.cpp131
-rw-r--r--engines/gob/video.h8
-rw-r--r--engines/gob/video_v1.cpp129
-rw-r--r--engines/gob/video_v2.cpp149
31 files changed, 2027 insertions, 798 deletions
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index a737502060..adfaec9c4c 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -64,8 +64,11 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_collStackElemSizes[i] = 0;
}
- for (i = 0; i < 20; i++)
+ for (i = 0; i < 60; i++) {
_soundSamples[i] = 0;
+ _soundIds[i] = 0;
+ _soundTypes[i] = 0;
+ }
_curTotFile[0] = 0;
_curExtFile[0] = 0;
@@ -1372,8 +1375,6 @@ void Game::start(void) {
void Game::totSub(int8 flags, char *newTotFile) {
int8 curBackupPos;
- warning("totSub(%d, \"%s\");", flags, newTotFile);
-
if (_backupedCount >= 5)
return;
@@ -1437,6 +1438,74 @@ void Game::totSub(int8 flags, char *newTotFile) {
strcat(_curExtFile, ".EXT");
}
+void Game::switchTotSub(int16 index, int16 skipPlay) {
+ int16 backupedCount;
+ int16 curBackupPos;
+
+ if ((_backupedCount - index) < 1)
+ return;
+
+ curBackupPos = _curBackupPos;
+ backupedCount = _backupedCount;
+ if (_curBackupPos == _backupedCount) {
+ _cursorXDeltaArray[_backupedCount] = _vm->_draw->_cursorXDeltaVar;
+ _cursorYDeltaArray[_backupedCount] = _vm->_draw->_cursorYDeltaVar;
+ _totTextDataArray[_backupedCount] = _totTextData;
+ _totFileDataArray[_backupedCount] = _totFileData;
+ _totResourceTableArray[_backupedCount] = _totResourceTable;
+ _extTableArray[_backupedCount] = _extTable;
+ _extHandleArray[_backupedCount] = _extHandle;
+ _imFileDataArray[_backupedCount] = _imFileData;
+ _variablesArray[_backupedCount] = _vm->_global->_inter_variables;
+ strcpy(_curTotFileArray[_backupedCount], _curTotFile);
+ _backupedCount++;
+ }
+ _curBackupPos -= index;
+ if (index >= 0)
+ _curBackupPos--;
+
+ _vm->_draw->_cursorXDeltaVar = _cursorXDeltaArray[_curBackupPos];
+ _vm->_draw->_cursorYDeltaVar = _cursorYDeltaArray[_curBackupPos];
+ _totTextData = _totTextDataArray[_curBackupPos];
+ _totFileData = _totFileDataArray[_curBackupPos];
+ _totResourceTable = _totResourceTableArray[_curBackupPos];
+ _extTable = _extTableArray[_curBackupPos];
+ _extHandle = _extHandleArray[_curBackupPos];
+ _imFileData = _imFileDataArray[_curBackupPos];
+ _vm->_global->_inter_variables = _variablesArray[_curBackupPos];
+ strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
+ strcpy(_curExtFile, _curTotFile);
+ _curExtFile[strlen(_curExtFile)-4] = '\0';
+ strcat(_curExtFile, ".EXT");
+
+ if (_vm->_inter->_terminate != 0)
+ return;
+
+ _vm->_game->pushCollisions(0);
+ _vm->_game->playTot(skipPlay);
+
+ if (_vm->_inter->_terminate != 2)
+ _vm->_inter->_terminate = 0;
+
+ _vm->_game->popCollisions();
+
+ _curBackupPos = curBackupPos;
+ _backupedCount = backupedCount;
+ _vm->_draw->_cursorXDeltaVar = _cursorXDeltaArray[_curBackupPos];
+ _vm->_draw->_cursorYDeltaVar = _cursorYDeltaArray[_curBackupPos];
+ _totTextData = _totTextDataArray[_curBackupPos];
+ _totFileData = _totFileDataArray[_curBackupPos];
+ _totResourceTable = _totResourceTableArray[_curBackupPos];
+ _extTable = _extTableArray[_curBackupPos];
+ _extHandle = _extHandleArray[_curBackupPos];
+ _imFileData = _imFileDataArray[_curBackupPos];
+ _vm->_global->_inter_variables = _variablesArray[_curBackupPos];
+ strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
+ strcpy(_curExtFile, _curTotFile);
+ _curExtFile[strlen(_curExtFile)-4] = '\0';
+ strcat(_curExtFile, ".EXT");
+}
+
int16 Game::openLocTextFile(char *locTextFile, int language) {
int n;
@@ -1634,4 +1703,49 @@ void Game::sub_BB28(void) {
_vm->_draw->freeSprite(21);
}
+Snd::SoundDesc *Game::loadSND(const char *path, int8 arg_4) {
+ Snd::SoundDesc *soundDesc;
+ int32 dsize;
+ char *data;
+ char *dataPtr;
+
+ soundDesc = new Snd::SoundDesc;
+
+ data = _vm->_dataio->getData(path);
+ if (data == 0) {
+ delete soundDesc;
+ return 0;
+ }
+ soundDesc->data = data;
+ soundDesc->flag = *data & 0x7F;
+ if (*data == 0)
+ soundDesc->flag = 8;
+ dataPtr = data + 4;
+
+ WRITE_LE_UINT16(dataPtr, READ_BE_UINT16(dataPtr));
+
+ WRITE_LE_UINT32(data, (READ_LE_UINT32(data) >> 24) + ((READ_LE_UINT16(data) & 0xFF00) << 8) + ((READ_LE_UINT16(data + 2) & 0xFF) >> 8));
+
+ soundDesc->size = READ_LE_UINT32(data);
+ dsize = _vm->_dataio->getDataSize(path) - 6;
+ if (dsize > soundDesc->size)
+ soundDesc->size = dsize;
+
+ soundDesc->frequency = READ_LE_UINT16(dataPtr);
+ soundDesc->data += 6;
+ soundDesc->timerTicks = 1193180 / READ_LE_UINT16(dataPtr);
+
+ if (arg_4 & 2)
+ arg_4 |= 1;
+ if ((soundDesc->frequency < 4700) && (arg_4 & 1))
+ arg_4 &= 0xFE;
+
+ if (arg_4 & 1) {
+ if ((_vm->_global->_soundFlags & BLASTER_FLAG) || (_vm->_global->_soundFlags & PROAUDIO_FLAG)) {
+ }
+ }
+
+ return soundDesc;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/game.h b/engines/gob/game.h
index d0c70e5fba..7e14a54091 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -110,7 +110,9 @@ public:
int16 _extHandle;
- Snd::SoundDesc *_soundSamples[20];
+ Snd::SoundDesc *_soundSamples[60];
+ int16 _soundIds[60];
+ int8 _soundTypes[60];
char _totToLoad[20];
@@ -157,7 +159,9 @@ public:
void loadImFile(void);
void start(void);
void totSub(int8 flags, char *newTotFile);
+ void switchTotSub(int16 index, int16 skipPlay);
char *loadLocTexts(void);
+ Snd::SoundDesc *loadSND(const char *path, int8 arg_4);
virtual void playTot(int16 skipPlay) = 0;
virtual void clearCollisions(void) = 0;
diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp
index 8da4a92e03..337b629b33 100644
--- a/engines/gob/game_v2.cpp
+++ b/engines/gob/game_v2.cpp
@@ -238,8 +238,9 @@ void Game_v2::playTot(int16 skipPlay) {
}
_vm->_snd->stopSound(0);
- for (i = 0; i < 20; i++)
- freeSoundSlot(i);
+ for (i = 0; i < 60; i++)
+ if ((_soundTypes[i] & 8) == 0)
+ freeSoundSlot(i);
if (_totToLoad[0] == 0)
break;
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 7fa54445f6..b883de37c0 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -196,8 +196,6 @@ int GobEngine::init() {
_anim = new Anim();
_cdrom = new CDROM(this);
_dataio = new DataIO(this);
- _goblin = new Goblin(this);
- _map = new Map(this);
_pack = new Pack();
_palanim = new PalAnim(this);
_scenery = new Scenery(this);
@@ -211,6 +209,8 @@ int GobEngine::init() {
_game = new Game_v1(this);
_video = new Video_v1(this);
_init = new Init_v1(this);
+ _map = new Map_v1(this);
+ _goblin = new Goblin_v1(this);
}
else if (_features & Gob::GF_GOB2) {
_inter = new Inter_v2(this);
@@ -220,10 +220,12 @@ int GobEngine::init() {
_game = new Game_v2(this);
_video = new Video_v2(this);
_init = new Init_v2(this);
+ _map = new Map_v2(this);
+ _goblin = new Goblin_v2(this);
}
else
error("GobEngine::init(): Unknown version of game engine");
- if ((_features & Gob::GF_MAC) || (_features & Gob::GF_GOB1))
+ if ((_features & Gob::GF_MAC) || (_features & Gob::GF_GOB1) || (_features & Gob::GF_GOB2))
_music = new Music(this);
_system->beginGFXTransaction();
diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp
index 629a31bd05..05bfe6fc5a 100644
--- a/engines/gob/goblin.cpp
+++ b/engines/gob/goblin.cpp
@@ -34,10 +34,13 @@
#include "gob/dataio.h"
#include "gob/cdrom.h"
#include "gob/music.h"
+#include "gob/mult.h"
namespace Gob {
Goblin::Goblin(GobEngine *vm) : _vm(vm) {
+ int i;
+
_goesAtTarget = 0;
_readyToAct = 0;
_gobAction = 0;
@@ -68,7 +71,7 @@ Goblin::Goblin(GobEngine *vm) : _vm(vm) {
_noPick = 0;
_objList = 0;
- int i;
+
for (i = 0; i < 4; i++)
_goblins[i] = 0;
_currentGoblin = 0;
@@ -144,6 +147,19 @@ Goblin::Goblin(GobEngine *vm) : _vm(vm) {
}
_objCount = 0;
_gobsCount = 0;
+
+ _soundSlotsCount = 0;
+ for (i = 0; i < 60; i++)
+ _soundSlots[i] = -1;
+
+ warning("GOB2 Stub! _word_2F9C0, _word_2F9BE, _word_2F9BC, _word_2F9BA, _dword_2F9B6, _dword_2F9B2");
+ _word_2F9C0 = 0;
+ _word_2F9BE = 0;
+ _word_2F9BC = 0;
+ _word_2F9BA = 0;
+ _dword_2F9B6 = 0;
+ _dword_2F9B2 = 0;
+ _dword_2F2A4 = 0;
}
char Goblin::rotateState(int16 from, int16 to) {
@@ -494,52 +510,6 @@ void Goblin::animateObjects(void) {
}
}
-void Goblin::placeObject(Gob_Object *objDesc, char animated) {
- int16 layer;
-
- if (objDesc->stateMach[objDesc->state][0] != 0) {
- objDesc->animation =
- objDesc->stateMach[objDesc->state][0]->animation;
-
- objDesc->noTick = 0;
- objDesc->toRedraw = 1;
- objDesc->doAnim = animated;
-
- objDesc->maxTick = 1;
- objDesc->tick = 1;
- objDesc->curFrame = 0;
- objDesc->type = 0;
- objDesc->actionStartState = 0;
- objDesc->nextState = -1;
- objDesc->multState = -1;
- objDesc->stateColumn = 0;
- objDesc->curLookDir = 0;
- objDesc->visible = 1;
- objDesc->pickable = 0;
- objDesc->unk14 = 0;
-
- objDesc->relaxTime = _vm->_util->getRandom(30);
-
- layer = objDesc->stateMach[objDesc->state][0]->layer;
- _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0,
- objDesc->xPos, objDesc->yPos, 0);
-
- objDesc->order = _vm->_scenery->_toRedrawBottom / 24 + 3;
-
- objDesc->left = objDesc->xPos;
- objDesc->right = objDesc->xPos;
- objDesc->dirtyLeft = objDesc->xPos;
- objDesc->dirtyRight = objDesc->xPos;
-
- objDesc->top = objDesc->yPos;
- objDesc->bottom = objDesc->yPos;
- objDesc->dirtyTop = objDesc->yPos;
- objDesc->dirtyBottom = objDesc->yPos;
-
- _vm->_util->listInsertBack(_objList, objDesc);
- }
-}
-
int16 Goblin::getObjMaxFrame(Gob_Object * objDesc) {
int16 layer;
@@ -1816,63 +1786,6 @@ int16 Goblin::doMove(Gob_Object *gobDesc, int16 cont, int16 action) {
return gobIndex;
}
-void Goblin::freeObjects(void) {
- int16 i;
- int16 state;
- int16 col;
-
- for (i = 0; i < 16; i++) {
- if (_soundData[i] == 0)
- continue;
-
- _vm->_snd->freeSoundDesc(_soundData[i]);
- _soundData[i] = 0;
- }
-
- for (i = 0; i < 4; i++) {
- if (_goblins[i] == 0)
- continue;
-
- _goblins[i]->stateMach = _goblins[i]->realStateMach;
-
- for (state = 0; state < 40; state++) {
- for (col = 0; col < 6; col++) {
- delete _goblins[i]->stateMach[state][col];
- _goblins[i]->stateMach[state][col] = 0;
- }
- }
-
- if (i == 3) {
- for (state = 40; state < 70; state++) {
- delete _goblins[3]->stateMach[state][0];
- _goblins[3]->stateMach[state][0] = 0;
- }
- }
-
- delete[] _goblins[i]->stateMach;
- delete _goblins[i];
- _goblins[i] = 0;
- }
-
- for (i = 0; i < 20; i++) {
- if (_objects[i] == 0)
- continue;
-
- _objects[i]->stateMach = _objects[i]->realStateMach;
-
- for (state = 0; state < 40; state++) {
- for (col = 0; col < 6; col++) {
- delete _objects[i]->stateMach[state][col];
- _objects[i]->stateMach[state][col] = 0;
- }
- }
-
- delete[] _objects[i]->stateMach;
- delete _objects[i];
- _objects[i] = 0;
- }
-}
-
void Goblin::zeroObjects(void) {
int16 i;
@@ -1906,10 +1819,10 @@ void Goblin::loadObjects(char *source) {
_vm->_map->loadMapObjects(source);
for (i = 0; i < _gobsCount; i++)
- placeObject(_goblins[i], 0);
+ placeObject(_goblins[i], 0, 0, 0, 0, 0);
for (i = 0; i < _objCount; i++) {
- placeObject(_objects[i], 1);
+ placeObject(_objects[i], 1, 0, 0, 0, 0);
}
initVarPointers();
@@ -2378,4 +2291,168 @@ int16 Goblin::treatItem(int16 action) {
}
}
+void Goblin::sub_19BD3(void) {
+ Mult::Mult_Object *obj0;
+ Mult::Mult_Object *obj1;
+ Mult::Mult_AnimData *anim0;
+ Mult::Mult_AnimData *anim1;
+ int16 varVal;
+ int16 var_2;
+ int16 var_4;
+ int16 var_6;
+ int16 var_8;
+ int16 var_A;
+ int16 var_C;
+ int16 di;
+ int16 si;
+
+ obj0 = &(_vm->_mult->_objects[0]);
+ obj1 = &(_vm->_mult->_objects[1]);
+ anim0 = obj0->pAnimData;
+ anim1 = obj1->pAnimData;
+
+ si = anim0->state;
+ di = anim1->state;
+
+ if (anim0->someFlag == 0) {
+ if ((_word_2F9BC == 0) && (anim0->isStatic == 0)) {
+ if ((VAR(_dword_2F9B6) == 0) && (si == 28)) {
+ si = _vm->_util->getRandom(3) + 24;
+ warning("GOB2 Stub! sub_195C7(0, si);");
+ WRITE_VAR(_dword_2F9B6, 100);
+ } else
+ WRITE_VAR(_dword_2F9B6, VAR(_dword_2F9B6) - 1);
+ }
+ if ((si == 8) || (si == 9) || (si == 29))
+ anim0->field_10 = 6;
+ }
+ if (anim1->someFlag == 0) {
+ if((_word_2F9BA == 0) && (anim1->isStatic == 0)) {
+ if ((VAR(_dword_2F9B2) == 0) && (di == 28)) {
+ di = _vm->_util->getRandom(3) + 24;
+ warning("GOB2 Stub! sub_195C7(1, di);");
+ WRITE_VAR(_dword_2F9B2, 100);
+ } else
+ WRITE_VAR(_dword_2F9B2, VAR(_dword_2F9B2) - 1);
+ }
+ if ((di == 8) || (di == 9) || (di == 29))
+ anim1->field_10 = 6;
+ }
+
+ if ((anim0->someFlag == 1) && (anim0->isStatic == 0) &&
+ ((anim0->state == 28) || (anim0->state == 29)))
+ anim0->field_10 = 0;
+ if ((anim1->someFlag == 1) && (anim1->isStatic == 0) &&
+ ((anim1->state == 28) || (anim1->state == 29)))
+ anim1->field_10 = 0;
+
+ if (VAR(18) != ((uint32) -1)) {
+ if (anim0->layer == 44)
+ anim0->field_10 = 4;
+ else if(anim0->layer == 45)
+ anim0->field_10 = 0;
+ if (anim0->someFlag == 0)
+ anim0->field_10 = 6;
+ }
+ if (VAR(19) != ((uint32) -1)) {
+ if (anim1->layer == 48)
+ anim1->field_10 = 4;
+ else if(anim1->layer == 49)
+ anim1->field_10 = 0;
+ if (anim1->someFlag == 0)
+ anim1->field_10 = 6;
+ }
+
+ if ((anim0->layer == 45) && (anim0->field_10 == 4) && (anim0->field_12 == 5) &&
+ (VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
+ warning("GOB2 Stub! sub_195C7(0, 19);");
+ }
+ if ((anim0->layer == 44) && (anim0->field_10 == 0) && (anim0->field_12 == 5) &&
+ (VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
+ warning("GOB2 Stub! sub_195C7(0, 16);");
+ }
+ if ((anim1->layer == 49) && (anim1->field_10 == 4) && (anim1->field_12 == 5) &&
+ (VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
+ warning("GOB2 Stub! sub_195C7(1, 19);");
+ }
+ if ((anim1->layer == 48) && (anim1->field_10 == 0) && (anim1->field_12 == 5) &&
+ (VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
+ warning("GOB2 Stub! sub_195C7(1, 16);");
+ }
+
+ var_2 = obj0->goblinX;
+ var_4 = obj1->goblinX;
+ var_6 = obj0->goblinY;
+ var_8 = obj1->goblinY;
+ di = anim0->field_13;
+ si = anim0->field_14;
+ var_A = anim1->field_13;
+ var_C = anim1->field_14;
+
+ varVal = _vm->_util->readVariableByte(_dword_2F2A4 + var_6 * 40 + var_2);
+ if ((varVal > 17) && (varVal < 21))
+ warning("GOB2 Stub! sub_195C7(anim0);");
+ varVal = _vm->_util->readVariableByte(_dword_2F2A4 + var_8 * 40 + var_4);
+ if ((varVal > 17) && (varVal < 21))
+ warning("GOB2 Stub! sub_19B45(anim1);");
+
+ if ((di < 0) || (di > 39) || (si < 0) || (si > 39))
+ return;
+
+ if (var_6 > si) {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17) {
+ do {
+ si--;
+ } while (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17);
+ si++;
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di - 1) == 0) {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di + 1) != 0)
+ di++;
+ } else
+ di--;
+ warning("GOB2 Stub! sub_197A6(di (=%d), si (=%d), 0);", si, di);
+ }
+ } else {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17) {
+ do {
+ si++;
+ } while (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17);
+ si--;
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di - 1) == 0) {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di + 1) != 0)
+ di++;
+ } else
+ di--;
+ warning("GOB2 Stub! sub_197A6(di (=%d), si (=%d), 0);", si, di);
+ }
+ }
+ if (var_8 > var_C) {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17) {
+ do {
+ var_C--;
+ } while (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17);
+ var_C++;
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) == 0) {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) != 0)
+ var_A++;
+ } else
+ var_A--;
+ warning("GOB2 Stub! sub_197A6(var_A (=%d), var_C (=%d), 1);", var_A, var_C);
+ }
+ } else {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17) {
+ do {
+ var_C++;
+ } while (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17);
+ var_C--;
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) == 0) {
+ if (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) != 0)
+ var_A++;
+ } else
+ var_A--;
+ warning("GOB2 Stub! sub_197A6(var_A (=%d), var_C (=%d), 1);", var_A, var_C);
+ }
+ }
+}
+
} // End of namespace Gob
diff --git a/engines/gob/goblin.h b/engines/gob/goblin.h
index 858bf247ae..2a43add91a 100644
--- a/engines/gob/goblin.h
+++ b/engines/gob/goblin.h
@@ -46,6 +46,12 @@ public:
int16 sndFrame; // +Eh
} GCC_PACK;
+ struct Gob2_State {
+ int16 animation;
+ int16 layer;
+ int16 field_4;
+ };
+
typedef Gob_State *Gob_PState;
typedef Gob_PState Gob_StateLine[6];
@@ -177,19 +183,28 @@ public:
int16 _positionedGob;
char _noPick;
+ // GOB2:
+ int16 _soundSlotsCount;
+ int16 _soundSlots[60];
+ int16 _word_2F9C0;
+ int16 _word_2F9BE;
+ int16 _word_2F9BC;
+ int16 _word_2F9BA;
+ int16 _dword_2F9B6; // index into the variables array
+ int16 _dword_2F9B2; // index into the variables array
+ char *_dword_2F2A4; // index into the variables array
+
// Functions
char rotateState(int16 from, int16 to);
void playSound(Snd::SoundDesc * snd, int16 repCount, int16 freq);
void drawObjects(void);
void animateObjects(void);
- void placeObject(Gob_Object * objDesc, char animated);
int16 getObjMaxFrame(Gob_Object * obj);
int16 objIntersected(Gob_Object * obj1, Gob_Object * obj2);
void setMultStates(Gob_Object * gobDesc);
int16 nextLayer(Gob_Object * gobDesc);
void showBoredom(int16 gobIndex);
void switchGoblin(int16 index);
- void freeObjects(void);
void zeroObjects(void);
void freeAllObjects(void);
void loadObjects(char *source);
@@ -203,7 +218,14 @@ public:
int16 treatItem(int16 action);
int16 doMove(Gob_Object *gobDesc, int16 cont, int16 action);
+ void sub_19BD3(void);
+
+ virtual void placeObject(Gob_Object * objDesc, char animated,
+ int16 index, int16 x, int16 y, int16 state) = 0;
+ virtual void freeObjects(void) = 0;
+
Goblin(GobEngine *vm);
+ virtual ~Goblin() {};
protected:
int16 _rotStates[4][4];
@@ -226,6 +248,26 @@ protected:
void moveAdvance(Gob_Object *gobDesc, int16 nextAct, int16 framesCount);
};
+class Goblin_v1 : public Goblin {
+public:
+ virtual void placeObject(Gob_Object * objDesc, char animated,
+ int16 index, int16 x, int16 y, int16 state);
+ virtual void freeObjects(void);
+
+ Goblin_v1(GobEngine *vm);
+ virtual ~Goblin_v1() {};
+};
+
+class Goblin_v2 : public Goblin_v1 {
+public:
+ virtual void placeObject(Gob_Object * objDesc, char animated,
+ int16 index, int16 x, int16 y, int16 state);
+ virtual void freeObjects(void);
+
+ Goblin_v2(GobEngine *vm);
+ virtual ~Goblin_v2() {};
+};
+
} // End of namespace Gob
#endif /* __GOBLIN_H */
diff --git a/engines/gob/goblin_v1.cpp b/engines/gob/goblin_v1.cpp
new file mode 100644
index 0000000000..234cc778d9
--- /dev/null
+++ b/engines/gob/goblin_v1.cpp
@@ -0,0 +1,140 @@
+/* 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/goblin.h"
+#include "gob/scenery.h"
+
+namespace Gob {
+
+Goblin_v1::Goblin_v1(GobEngine *vm) : Goblin(vm) {
+}
+
+void Goblin_v1::freeObjects(void) {
+ int16 i;
+ int16 state;
+ int16 col;
+
+ for (i = 0; i < 16; i++) {
+ if (_soundData[i] == 0)
+ continue;
+
+ _vm->_snd->freeSoundDesc(_soundData[i]);
+ _soundData[i] = 0;
+ }
+
+ for (i = 0; i < 4; i++) {
+ if (_goblins[i] == 0)
+ continue;
+
+ _goblins[i]->stateMach = _goblins[i]->realStateMach;
+
+ for (state = 0; state < 40; state++) {
+ for (col = 0; col < 6; col++) {
+ delete _goblins[i]->stateMach[state][col];
+ _goblins[i]->stateMach[state][col] = 0;
+ }
+ }
+
+ if (i == 3) {
+ for (state = 40; state < 70; state++) {
+ delete _goblins[3]->stateMach[state][0];
+ _goblins[3]->stateMach[state][0] = 0;
+ }
+ }
+
+ delete[] _goblins[i]->stateMach;
+ delete _goblins[i];
+ _goblins[i] = 0;
+ }
+
+ for (i = 0; i < 20; i++) {
+ if (_objects[i] == 0)
+ continue;
+
+ _objects[i]->stateMach = _objects[i]->realStateMach;
+
+ for (state = 0; state < 40; state++) {
+ for (col = 0; col < 6; col++) {
+ delete _objects[i]->stateMach[state][col];
+ _objects[i]->stateMach[state][col] = 0;
+ }
+ }
+
+ delete[] _objects[i]->stateMach;
+ delete _objects[i];
+ _objects[i] = 0;
+ }
+}
+
+void Goblin_v1::placeObject(Gob_Object *objDesc, char animated,
+ int16 index, int16 x, int16 y, int16 state) {
+ int16 layer;
+
+ if (objDesc->stateMach[objDesc->state][0] != 0) {
+ objDesc->animation =
+ objDesc->stateMach[objDesc->state][0]->animation;
+
+ objDesc->noTick = 0;
+ objDesc->toRedraw = 1;
+ objDesc->doAnim = animated;
+
+ objDesc->maxTick = 1;
+ objDesc->tick = 1;
+ objDesc->curFrame = 0;
+ objDesc->type = 0;
+ objDesc->actionStartState = 0;
+ objDesc->nextState = -1;
+ objDesc->multState = -1;
+ objDesc->stateColumn = 0;
+ objDesc->curLookDir = 0;
+ objDesc->visible = 1;
+ objDesc->pickable = 0;
+ objDesc->unk14 = 0;
+
+ objDesc->relaxTime = _vm->_util->getRandom(30);
+
+ layer = objDesc->stateMach[objDesc->state][0]->layer;
+ _vm->_scenery->updateAnim(layer, 0, objDesc->animation, 0,
+ objDesc->xPos, objDesc->yPos, 0);
+
+ objDesc->order = _vm->_scenery->_toRedrawBottom / 24 + 3;
+
+ objDesc->left = objDesc->xPos;
+ objDesc->right = objDesc->xPos;
+ objDesc->dirtyLeft = objDesc->xPos;
+ objDesc->dirtyRight = objDesc->xPos;
+
+ objDesc->top = objDesc->yPos;
+ objDesc->bottom = objDesc->yPos;
+ objDesc->dirtyTop = objDesc->yPos;
+ objDesc->dirtyBottom = objDesc->yPos;
+
+ _vm->_util->listInsertBack(_objList, objDesc);
+ }
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/goblin_v2.cpp b/engines/gob/goblin_v2.cpp
new file mode 100644
index 0000000000..724361ff4a
--- /dev/null
+++ b/engines/gob/goblin_v2.cpp
@@ -0,0 +1,105 @@
+/* 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/goblin.h"
+#include "gob/mult.h"
+#include "gob/game.h"
+#include "gob/scenery.h"
+
+namespace Gob {
+
+Goblin_v2::Goblin_v2(GobEngine *vm) : Goblin_v1(vm) {
+ _gobsCount = -1;
+}
+
+void Goblin_v2::freeObjects(void) {
+ int i;
+
+ if (_gobsCount < 0)
+ return;
+
+ for (i = 0; i < _gobsCount; i++) {
+ delete[] _vm->_mult->_objects[i].goblinStates[0];
+ delete[] _vm->_mult->_objects[i].goblinStates;
+ }
+ for (i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
+ if ((_vm->_goblin->_soundSlots[i] & 0x8000) == 0)
+ _vm->_game->freeSoundSlot(_vm->_goblin->_soundSlots[i]);
+// delete[] off_2F2AB;
+ _gobsCount = -1;
+}
+
+void Goblin_v2::placeObject(Gob_Object *objDesc, char animated,
+ int16 index, int16 x, int16 y, int16 state) {
+ Mult::Mult_Object *obj;
+ Mult::Mult_AnimData *objAnim;
+ int16 layer;
+ int16 animation;
+
+ obj = &_vm->_mult->_objects[index];
+ objAnim = obj->pAnimData;
+
+ obj->goblinX = x;
+ obj->goblinY = y;
+ objAnim->order = y;
+
+ if (state == -1) {
+ objAnim->frame = 0;
+ objAnim->isPaused = 0;
+ objAnim->isStatic = 0;
+ objAnim->newCycle = 0;
+ _vm->_scenery->updateAnim(objAnim->layer, 0, objAnim->animation, 0,
+ *obj->pPosX, *obj->pPosY, 0);
+ if (_vm->_mult->_word_2CC86 == 0)
+ *obj->pPosY = (y + 1) * _vm->_mult->_word_2F2AF; // - (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
+ else
+ *obj->pPosY = ((y + 1) / 2) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
+ *obj->pPosX = x * _vm->_mult->_word_2F2B1;
+ } else {
+ if (obj->goblinStates[state] != 0) {
+ layer = obj->goblinStates[state][0].layer;
+ animation = obj->goblinStates[state][0].animation;
+ objAnim->state = state;
+ objAnim->layer = layer;
+ objAnim->animation = animation;
+ objAnim->frame = 0;
+ objAnim->isPaused = 0;
+ objAnim->isStatic = 0;
+ objAnim->newCycle = _vm->_scenery->_animations[animation].layers[layer]->framesCount;
+ _vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
+ if (_vm->_mult->_word_2CC86 == 0)
+ *obj->pPosY = (y + 1) * _vm->_mult->_word_2F2AF; // - (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
+ else
+ *obj->pPosY = ((y + 1) / 2) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->scenery->_animTop);
+ *obj->pPosX = x * _vm->_mult->_word_2F2B1;
+ warning("GOB2 Stub! sub_FE1D(obj");
+ } else
+ warning("GOB2 Stub! sub_FE1D(obj");
+ }
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp
index 1bfd0aadb5..c411a2430f 100644
--- a/engines/gob/init.cpp
+++ b/engines/gob/init.cpp
@@ -144,7 +144,7 @@ memBlocks = word ptr -2*/
_palDesc->unused2 = _vm->_draw->_unusedPalette2;
_vm->_video->setFullPalette(_palDesc);
- for (i = 0; i < 4; i++)
+ for (i = 0; i < 8; i++)
_vm->_draw->_fonts[i] = 0;
handle = _vm->_dataio->openData("intro.inf");
@@ -167,7 +167,7 @@ memBlocks = word ptr -2*/
infEnd = infBuf + _vm->_dataio->getDataSize("intro.inf");
for (i = 0; i < 4; i++, infPtr++) {
- for (j = 0; *infPtr >= ' ' && infPtr != infEnd;
+ for (j = 0; infPtr < infEnd && *infPtr >= ' ';
j++, infPtr++)
buffer[j] = *infPtr;
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index ed51ab7893..69787ae601 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -40,11 +40,18 @@
namespace Gob {
Inter::Inter(GobEngine *vm) : _vm(vm) {
+ int i;
+
_terminate = false;
_breakFlag = false;
- _animPalLowIndex = 0;
- _animPalHighIndex = 0;
- _animPalDir = 0;
+
+ for (i = 0; i < 8; i++)
+ {
+ _animPalLowIndex[i] = 0;
+ _animPalHighIndex[i] = 0;
+ _animPalDir[i] = 0;
+ }
+
_soundEndTimeKey = 0;
_soundStopVal = 0;
_breakFromLevel = 0;
@@ -96,34 +103,6 @@ char Inter::evalBoolResult() {
return 0;
}
-void Inter::animPalette(void) {
- int16 i;
- Video::Color col;
-
- if (_animPalDir == 0)
- return;
-
- _vm->_video->waitRetrace(_vm->_global->_videoMode);
-
- if (_animPalDir == -1) {
- col = _vm->_draw->_vgaSmallPalette[_animPalLowIndex];
-
- for (i = _animPalLowIndex; i < _animPalHighIndex; i++)
- _vm->_draw->_vgaSmallPalette[i] = _vm->_draw->_vgaSmallPalette[i + 1];
-
- _vm->_draw->_vgaSmallPalette[_animPalHighIndex] = col;
- } else {
- col = _vm->_draw->_vgaSmallPalette[_animPalHighIndex];
- for (i = _animPalHighIndex; i > _animPalLowIndex; i--)
- _vm->_draw->_vgaSmallPalette[i] = _vm->_draw->_vgaSmallPalette[i - 1];
-
- _vm->_draw->_vgaSmallPalette[_animPalLowIndex] = col;
- }
-
- _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaSmallPalette;
- _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
-}
-
void Inter::funcBlock(int16 retFlag) {
char cmdCount;
int16 counter;
@@ -305,7 +284,7 @@ void Inter::initControlVars(void) {
_breakFlag = false;
_terminate = false;
- _animPalDir = 0;
+ _animPalDir[0] = 0;
_soundEndTimeKey = 0;
}
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index 5f99cc154a..2ae07da874 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -37,9 +37,9 @@ namespace Gob {
class Inter {
public:
- int16 _animPalLowIndex;
- int16 _animPalHighIndex;
- int16 _animPalDir;
+ int16 _animPalLowIndex[8];
+ int16 _animPalHighIndex[8];
+ int16 _animPalDir[8];
uint32 _soundEndTimeKey;
int16 _soundStopVal;
char _terminate;
@@ -53,7 +53,6 @@ public:
char evalExpr(int16 *pRes);
char evalBoolResult(void);
- void animPalette(void);
void funcBlock(int16 retFlag);
void storeKey(int16 key);
void checkSwitchTable(char **ppExec);
@@ -78,6 +77,7 @@ protected:
virtual const char *getOpcodeFuncDesc(byte i, byte j) = 0;
virtual const char *getOpcodeGoblinDesc(int i) = 0;
virtual void loadMult(void) = 0;
+ virtual void animPalette(void) = 0;
};
class Inter_v1 : public Inter {
@@ -116,6 +116,7 @@ protected:
virtual const char *getOpcodeFuncDesc(byte i, byte j);
virtual const char *getOpcodeGoblinDesc(int i);
virtual void loadMult(void);
+ virtual void animPalette(void);
void o1_loadMult(void);
void o1_playMult(void);
@@ -307,21 +308,30 @@ protected:
virtual const char *getOpcodeFuncDesc(byte i, byte j);
virtual const char *getOpcodeGoblinDesc(int i);
virtual void loadMult(void);
+ virtual void animPalette(void);
- void o2_drawStub(void) { warning("Gob2 stub"); }
+ void o2_drawStub(void) { error("Gob2 stub"); }
void o2_totSub(void);
+ void o2_switchTotSub(void);
void o2_stub0x52(void);
- void o2_stub0x53(void);
void o2_stub0x54(void);
- void o2_stub0x56(void);
void o2_stub0x80(void);
+ void o2_stub0x82(void);
+ void o2_stub0x83(void);
+ void o2_stub0x85(void);
void o2_renderStatic(void);
+ bool o2_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag);
+ bool o2_playSound(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_palLoad(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_loadTot(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag);
bool o2_loadSound(char &cmdCount, int16 &counter, int16 &retFlag);
+ void o2_loadMapObjects(void);
+ void o2_freeGoblins(void);
+ void o2_writeGoblinPos(void);
+ void o2_placeGoblin(void);
void o2_multSub(void);
void o2_setRenderFlags(void);
void o2_initMult(void);
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 59785fc46e..9e6b574f67 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -754,9 +754,9 @@ bool Inter_v1::o1_printText(char &cmdCount, int16 &counter, int16 &retFlag) {
}
bool Inter_v1::o1_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag) {
- _animPalDir = load16();
- _animPalLowIndex = _vm->_parse->parseValExpr();
- _animPalHighIndex = _vm->_parse->parseValExpr();
+ _animPalDir[0] = load16();
+ _animPalLowIndex[0] = _vm->_parse->parseValExpr();
+ _animPalHighIndex[0] = _vm->_parse->parseValExpr();
return false;
}
@@ -1199,6 +1199,7 @@ bool Inter_v1::o1_playComposition(char &cmdCount, int16 &counter, int16 &retFlag
}
bool Inter_v1::o1_stopSound(char &cmdCount, int16 &counter, int16 &retFlag) {
+ _vm->_music->stopPlay();
_vm->_snd->stopSound(_vm->_parse->parseValExpr());
_soundEndTimeKey = 0;
return false;
@@ -2764,4 +2765,32 @@ void Inter_v1::storeMouse(void) {
WRITE_VAR(4, _vm->_game->_mouseButtons);
}
+void Inter_v1::animPalette(void) {
+ int16 i;
+ Video::Color col;
+
+ if (_animPalDir[0] == 0)
+ return;
+
+ _vm->_video->waitRetrace(_vm->_global->_videoMode);
+
+ if (_animPalDir[0] == -1) {
+ col = _vm->_draw->_vgaSmallPalette[_animPalLowIndex[0]];
+
+ for (i = _animPalLowIndex[0]; i < _animPalHighIndex[0]; i++)
+ _vm->_draw->_vgaSmallPalette[i] = _vm->_draw->_vgaSmallPalette[i + 1];
+
+ _vm->_draw->_vgaSmallPalette[_animPalHighIndex[0]] = col;
+ } else {
+ col = _vm->_draw->_vgaSmallPalette[_animPalHighIndex[0]];
+ for (i = _animPalHighIndex[0]; i > _animPalLowIndex[0]; i--)
+ _vm->_draw->_vgaSmallPalette[i] = _vm->_draw->_vgaSmallPalette[i - 1];
+
+ _vm->_draw->_vgaSmallPalette[_animPalLowIndex[0]] = col;
+ }
+
+ _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaSmallPalette;
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+}
+
} // End of namespace Gob
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 27448e80a9..b09dbf61fc 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -37,6 +37,8 @@
#include "gob/cdrom.h"
#include "gob/palanim.h"
#include "gob/anim.h"
+#include "gob/music.h"
+#include "gob/map.h"
namespace Gob {
@@ -204,7 +206,7 @@ void Inter_v2::setupOpcodes(void) {
{NULL, ""},
/* 40 */
OPCODE(o2_totSub),
- OPCODE(o2_drawStub),
+ OPCODE(o2_switchTotSub),
OPCODE(o2_drawStub),
OPCODE(o2_drawStub),
/* 44 */
@@ -223,14 +225,14 @@ void Inter_v2::setupOpcodes(void) {
{NULL, ""},
{NULL, ""},
/* 50 */
- OPCODE(o2_drawStub),
- OPCODE(o2_drawStub),
+ OPCODE(o2_loadMapObjects),
+ OPCODE(o2_freeGoblins),
OPCODE(o2_stub0x52),
- OPCODE(o2_stub0x53),
+ OPCODE(o2_writeGoblinPos),
/* 54 */
OPCODE(o2_stub0x54),
OPCODE(o2_drawStub),
- OPCODE(o2_stub0x56),
+ OPCODE(o2_placeGoblin),
{NULL, ""},
/* 58 */
{NULL, ""},
@@ -285,11 +287,11 @@ void Inter_v2::setupOpcodes(void) {
/* 80 */
OPCODE(o2_stub0x80),
OPCODE(o2_drawStub),
- OPCODE(o2_drawStub),
- OPCODE(o2_drawStub),
+ OPCODE(o2_stub0x82),
+ OPCODE(o2_stub0x83),
/* 84 */
OPCODE(o2_drawStub),
- OPCODE(o2_drawStub),
+ OPCODE(o2_stub0x85),
OPCODE(o2_drawStub),
OPCODE(o2_drawStub),
/* 88 */
@@ -474,7 +476,7 @@ void Inter_v2::setupOpcodes(void) {
OPCODE(o1_keyFunc),
OPCODE(o1_capturePush),
OPCODE(o1_capturePop),
- OPCODE(o1_animPalInit),
+ OPCODE(o2_animPalInit),
/* 18 */
{NULL, ""},
{NULL, ""},
@@ -516,7 +518,7 @@ void Inter_v2::setupOpcodes(void) {
OPCODE(o1_invalidate),
OPCODE(o1_setBackDelta),
/* 38 */
- OPCODE(o1_playSound),
+ OPCODE(o2_playSound),
OPCODE(o1_stopSound),
OPCODE(o2_loadSound),
OPCODE(o1_freeSoundSlot),
@@ -718,17 +720,6 @@ void Inter_v2::o2_stub0x52(void) {
warning("STUB: Gob2 drawOperation 0x52 (%d %d %d)", expr1, expr2, expr3);
}
-void Inter_v2::o2_stub0x53(void) {
- int16 var1 = _vm->_parse->parseVarIndex() >> 2;
- int16 var2 = _vm->_parse->parseVarIndex() >> 2;
- int16 index = _vm->_parse->parseValExpr();
-
- warning("STUB: Gob2 drawOperation 0x53 (%d %d %d)", var1, var2, index);
-
-// WRITE_VAR(var1, _vm->_mult->_objects[index].field_1A);
-// WRITE_VAR(var2, _vm->_mult->_objects[index].field_1B);
-}
-
void Inter_v2::o2_stub0x54(void) {
int16 index = _vm->_parse->parseValExpr();
@@ -737,15 +728,6 @@ void Inter_v2::o2_stub0x54(void) {
// _vm->_mult->_objects[index].pAnimData->field_12 = 4;
}
-void Inter_v2::o2_stub0x56(void) {
- int16 expr1 = _vm->_parse->parseValExpr();
- int16 expr2 = _vm->_parse->parseValExpr();
- int16 expr3 = _vm->_parse->parseValExpr();
- int16 expr4 = _vm->_parse->parseValExpr();
-
- warning("STUB: Gob2 drawOperation 0x56 (%d %d %d %d)", expr1, expr2, expr3, expr4);
-}
-
void Inter_v2::o2_stub0x80(void) {
int16 start;
int16 videoMode;
@@ -817,156 +799,194 @@ void Inter_v2::o2_stub0x80(void) {
}
}
-int16 Inter_v2::loadSound(int16 search) {
- int16 id;
- int16 slot;
-/* int i;
- int8 var_7;
- char *pointer;
- char sndfile[14];
+void Inter_v2::o2_stub0x82(void) {
+ int16 expr;
- char *dword_2EBF0[60];
- int16 word_2EAFE[60];
- int8 byte_2EB8A[60];
+ expr = _vm->_parse->parseValExpr();
- for (i = 0; i < 60; i++)
- dword_2EBF0[i] = 0;*/
+ if (expr == -1) {
+ if (_vm->_game->_byte_2FC9B != 0)
+ _vm->_game->_byte_2FC9B = 1;
+ _vm->_parse->parseValExpr();
+ WRITE_VAR(2, _vm->_game->_word_2FC9E);
+ WRITE_VAR(3, _vm->_game->_word_2FC9C);
+ } else {
+ _vm->_game->_word_2FC9E = expr;
+ _vm->_game->_word_2FC9C = _vm->_parse->parseValExpr();
+ }
+/* if (_vm->_game->_off_2E51B != 0)
+ warning("GOB2 Stub! _vid_setPixelShift(_vm->_game->_word_2FC9E, _vm->_game->_word_2FC9C + 200 - _vm->_game->_word_2E51F)");
+ else
+ warning("GOB2 Stub! _vid_setPixelShift(_vm->_game->_word_2FC9E, _vm->_game->_word_2FC9C);");*/
+}
- warning("STUB: loadSound()");
+// some sub
+void Inter_v2::o2_stub0x83(void) {
+ char dest[128];
+ int16 expr1;
+ int16 expr2;
+ int16 expr3;
+ int16 expr4;
+ int16 expr5;
+ int16 expr6;
+ int16 expr7;
+ int16 expr8;
+
+ evalExpr(0);
+ strcpy(dest, _vm->_global->_inter_resStr);
+ expr1 = _vm->_parse->parseValExpr();
+ expr2 = _vm->_parse->parseValExpr();
+ expr3 = _vm->_parse->parseValExpr();
+ expr4 = _vm->_parse->parseValExpr();
+ expr5 = _vm->_parse->parseValExpr();
+ expr6 = _vm->_parse->parseValExpr();
+ expr7 = _vm->_parse->parseValExpr();
+ expr8 = _vm->_parse->parseValExpr();
+
+ warning("STUB: Gob2 drawOperation 0x83 (\"%s\" %d %d %d %d %d %d %d %d)", dest, expr1, expr2, expr3, expr4, expr5, expr6, expr7, expr8);
+}
- slot = 0;
- if (search == 0) {
- slot = _vm->_parse->parseValExpr();
- }
- id = load16();
+void Inter_v2::o2_stub0x85(void) {
+ char dest[32];
-// warning("==> %d %d", slot, id);
+ evalExpr(0);
+ strcpy(dest, _vm->_global->_inter_resStr);
+ strcat(dest, ".ITK");
- if (id == -1)
- _vm->_global->_inter_execPtr += 9;
+ warning("STUB: Gob2 drawOperation 0x85 (\"%s\")", dest);
+ _vm->_dataio->openDataFile(dest);
+}
- return slot;
+int16 Inter_v2::loadSound(int16 search) {
+ int16 id; // si
+ int16 slot; // di
+ int32 i;
+ bool isADL;
+ char sndfile[14];
+ char *extData;
+ char *dataPtr;
+ Snd::SoundDesc *soundDesc;
+
+ memset(sndfile, 0, 14 * sizeof(char));
-/* var_7 = 0;
+ isADL = false;
if (search == 0) {
slot = _vm->_parse->parseValExpr();
if (slot < 0) {
- var_7 = 1;
+ isADL = true;
slot = -slot;
}
id = load16();
- }
- else {
- // loc_961D
+ } else {
id = load16();
for (slot = 0; slot < 60; slot++)
- if ((dword_2EBF0[slot] != 0) && (word_2EAFE[slot] = id))
+ if ((_vm->_game->_soundSamples[slot] != 0) && (_vm->_game->_soundIds[slot] == id))
return slot | 0x8000;
for (slot = 59; slot >= 0; slot--)
- if (dword_2EBF0[slot] == 0) break;
-
+ if (_vm->_game->_soundSamples[slot] == 0) break;
}
-
- if (dword_2EBF0[slot] != 0)
+
+ if (_vm->_game->_soundSamples[slot] != 0)
_vm->_game->freeSoundSlot(slot);
- word_2EAFE[slot] = id;
+ _vm->_game->_soundIds[slot] = id;
- if (id == -1) {
+ if (id == -1) { // loc_969D
strcpy(sndfile, _vm->_global->_inter_execPtr);
_vm->_global->_inter_execPtr += 9;
- if (var_7 == 0) {
- // loc_96EB
+ if (!isADL) {
strcat(sndfile, ".SND");
-// dword_2EBF0[slot] = sub_1F5D0(sndfile);
- }
- else {
+ _vm->_game->_soundSamples[slot] = _vm->_game->loadSND(sndfile, 3);
+ } else {
strcat(sndfile, ".ADL");
- dword_2EBF0[slot] = _vm->_dataio->getData(sndfile);
+ // TODO: This is very ugly
+ _vm->_game->_soundSamples[slot] = (Snd::SoundDesc *) _vm->_dataio->getData(sndfile);
}
- byte_2EB8A[slot] = 2;
- // loc_969D
- }
- else {
- // loc_9735
- if (id >= 30000) {
- // loc_973E
- if ((var_7 == 0) &&
- (_vm->_global->_soundFlags & 0x14) &&
- (_vm->_game->_totFileData[0x29] >= 51)) {
- // loc_9763
- if (_vm->_global->_soundFlags & 0x14) {
- // loc_976E
-// var_E = new char[16];
- if (_vm->_inter->_terminate)
- return slot;
- pointer = _vm->_game->loadExtData(id, NULL, NULL);
- if (pointer == NULL) {
-// delete[] var_E;
- return slot;
- }
- // loc_97C5
-// var_E->pointer = pointer+6;
-// var_E->0x0C = pointer[4] << 8 + pointer[5];
- // ...
-// dword_2EBF0[slot] = var_E;
- delete[] pointer;
+ _vm->_game->_soundTypes[slot] = 2;
+ } else { // loc_9735
+ if (id >= 30000) { // loc_973E
+ if (!isADL && (_vm->_game->_totFileData[0x29] >= 51)) { // loc_9763
+ if (_vm->_inter->_terminate != 0)
return slot;
- }
- else {
- // loc_9A59
+ soundDesc = new Snd::SoundDesc;
+ extData = _vm->_game->loadExtData(id, 0, 0);
+ if (extData == 0) {
+ delete soundDesc;
return slot;
}
+ soundDesc->data = extData + 6;
+ soundDesc->frequency = (extData[4] << 8) + extData[5];
+ soundDesc->size = (extData[1] << 16) + (extData[2] << 8) + extData[3];
+ soundDesc->flag = 0;
+ if (soundDesc->frequency < 4700)
+ soundDesc->frequency = 4700;
+ soundDesc->frequency = -soundDesc->frequency;
+ for (i = 0, dataPtr = soundDesc->data; i < soundDesc->size; i++, dataPtr++)
+ *dataPtr ^= 0x80;
+ _vm->_game->_soundTypes[slot] = 4;
+ _vm->_game->_soundSamples[slot] = soundDesc;
+ } else { // loc_99BC
+ extData = _vm->_game->loadExtData(id, 0, 0);
+ if (extData == 0)
+ return slot;
+ _vm->_game->_soundTypes[slot] = 1;
+ if (!isADL)
+ _vm->_game->loadSound(slot, extData);
+ else
+ // TODO: This is very ugly
+ _vm->_game->_soundSamples[slot] = (Snd::SoundDesc *) extData;
}
- else {
- // loc_99BC
- pointer = _vm->_game->loadExtData(id, NULL, NULL);
- // ...
- delete[] pointer;
- return slot;
- }
- }
- else {
- // loc_9A13
-// pointer = _vm->_game->loadTotResource(id);
- return slot;
+ } else { // loc_9A13
+ extData = _vm->_game->loadTotResource(id);
+ if (!isADL)
+ _vm->_game->loadSound(slot, extData);
+ else
+ // TODO: This is very ugly
+ _vm->_game->_soundSamples[slot] = (Snd::SoundDesc *) extData;
}
}
+ // loc_9A4E
- if (var_7 != 0)
- byte_2EB8A[slot] |= 8;
+ if (isADL)
+ _vm->_game->_soundTypes[slot] |= 8;
- if (dword_2EBF0[slot])
- delete[] dword_2EBF0[slot];
+ return slot;
+}
- return slot;*/
-
-/* char *dataPtr;
- int16 id;
+void Inter_v2::o2_loadMapObjects(void) {
+ _vm->_map->loadMapObjects(0);
+}
- if (slot == -1)
- slot = _vm->_parse->parseValExpr();
+void Inter_v2::o2_freeGoblins(void) {
+ _vm->_goblin->freeObjects();
+}
- id = load16();
- if (id == -1) {
- _vm->_global->_inter_execPtr += 9;
- return;
- }
+void Inter_v2::o2_placeGoblin(void) {
+ int16 index;
+ int16 x;
+ int16 y;
+ int16 state;
- if (id >= 30000) {
- dataPtr = _vm->_game->loadExtData(id, 0, 0);
- _vm->_game->_soundFromExt[slot] = 1;
- } else {
- dataPtr = _vm->_game->loadTotResource(id);
- _vm->_game->_soundFromExt[slot] = 0;
- }
+ index = _vm->_parse->parseValExpr();
+ x = _vm->_parse->parseValExpr();
+ y = _vm->_parse->parseValExpr();
+ state = _vm->_parse->parseValExpr();
- warning("STUB: loadSound()");
- return;
+ _vm->_goblin->placeObject(0, 0, index, x, y, state);
+}
- _vm->_game->loadSound(slot, dataPtr);*/
+void Inter_v2::o2_writeGoblinPos(void) {
+ int16 var1;
+ int16 var2;
+ int16 index;
+
+ var1 = _vm->_parse->parseVarIndex() >> 2;
+ var2 = _vm->_parse->parseVarIndex() >> 2;
+ index = _vm->_parse->parseValExpr();
+ WRITE_VAR(var1, _vm->_mult->_objects[index].goblinX);
+ WRITE_VAR(var2, _vm->_mult->_objects[index].goblinY);
}
void Inter_v2::o2_multSub(void) {
@@ -984,9 +1004,12 @@ void Inter_v2::o2_renderStatic(void) {
void Inter_v2::loadMult(void) {
int16 val;
- int16 objIndex;
+ int16 objIndex; // si
int16 i;
+ int16 animation;
char *lmultData;
+ Mult::Mult_Object *obj;
+ Mult::Mult_AnimData *objAnim;
debugC(4, DEBUG_GAMEFLOW, "Inter_v2::loadMult(): Loading...");
@@ -998,36 +1021,142 @@ void Inter_v2::loadMult(void) {
lmultData = (char *)_vm->_mult->_objects[objIndex].pAnimData;
for (i = 0; i < 11; i++) {
- if (*_vm->_global->_inter_execPtr != 99) {
- val = _vm->_parse->parseValExpr();
- lmultData[i] = val;
- } else
+ if (*_vm->_global->_inter_execPtr != 99)
+ lmultData[i] = _vm->_parse->parseValExpr();
+ else
_vm->_global->_inter_execPtr++;
}
- warning("GOB2 Stub! Inter_v2::loadMult()");
+ if (_vm->_mult->_objects[objIndex].pAnimData->animType == 100) {
+ if (_vm->_goblin->_gobsCount >= 0) {
+ obj = &_vm->_mult->_objects[objIndex];
+ objAnim = obj->pAnimData;
+
+ val = *obj->pPosX % 256;
+ obj->field_1C = val;
+ obj->field_1E = val;
+ obj->goblinX = val;
+ val = *obj->pPosY % 256;
+ obj->field_1D = val;
+ obj->field_1F = val;
+ obj->goblinY = val;
+ *obj->pPosX *= _vm->_mult->_word_2F2B1;
+ objAnim->field_15 = objAnim->unknown;
+ objAnim->field_E = -1;
+ objAnim->field_F = -1;
+ objAnim->field_12 = 0;
+ objAnim->state = objAnim->layer;
+ objAnim->layer = obj->goblinStates[objAnim->state][0].layer;
+ objAnim->animation = obj->goblinStates[objAnim->state][0].animation;
+ animation = objAnim->animation;
+ _vm->_scenery->updateAnim(objAnim->state, 0, 0, 0, *obj->pPosX, *obj->pPosY, 0);
+ if (_vm->_mult->_word_2CC86 == 0) {
+ *obj->pPosY = (obj->goblinY + 1) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop)
+ } else {
+ *obj->pPosY = (obj->goblinY + 1) * _vm->_mult->_word_2F2AF; //- (_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (obj->goblinY + 1) / 2;
+ }
+ *obj->pPosX = obj->goblinX * _vm->_mult->_word_2F2B1;
+ }
+ }
+ if (_vm->_mult->_objects[objIndex].pAnimData->animType == 101) {
+ if (_vm->_goblin->_gobsCount >= 0) {
+ obj = &_vm->_mult->_objects[objIndex];
+ objAnim = obj->pAnimData;
+
+ objAnim->field_E = -1;
+ objAnim->field_F = -1;
+ objAnim->state = objAnim->layer;
+ objAnim->layer = obj->goblinStates[objAnim->state][0].layer;
+ objAnim->animation = obj->goblinStates[objAnim->state][0].animation;
+ if ((*obj->pPosX == 1000) && (*obj->pPosY == 1000)) {
+ *obj->pPosX = _vm->_scenery->_animations[objAnim->animation].layers[objAnim->state]->posX;
+ *obj->pPosY = _vm->_scenery->_animations[objAnim->animation].layers[objAnim->state]->posY;
+ }
+ _vm->_scenery->updateAnim(objAnim->state, 0, objAnim->animation, 0, *obj->pPosX, *obj->pPosY, 0);
+ }
+ }
+}
+
+bool Inter_v2::o2_animPalInit(char &cmdCount, int16 &counter, int16 &retFlag) {
+ int16 index;
+
+ index = load16();
+ if (index > 0) {
+ index--;
+ _animPalLowIndex[index] = _vm->_parse->parseValExpr();
+ _animPalHighIndex[index] = _vm->_parse->parseValExpr();
+ _animPalDir[index] = 1;
+ } else if (index == 0) {
+ memset(_animPalDir, 0, 8 * sizeof(int16));
+ _vm->_parse->parseValExpr();
+ _vm->_parse->parseValExpr();
+ } else {
+ index = -index - 1;
+ _animPalLowIndex[index] = _vm->_parse->parseValExpr();
+ _animPalHighIndex[index] = _vm->_parse->parseValExpr();
+ _animPalDir[index] = -1;
+ }
+ return false;
+}
+
+bool Inter_v2::o2_playSound(char &cmdCount, int16 &counter, int16 &retFlag) {
+ int16 frequency;
+ int16 freq2;
+ int16 repCount; // di
+ int16 index; // si
+
+ index = _vm->_parse->parseValExpr();
+ repCount = _vm->_parse->parseValExpr();
+ frequency = _vm->_parse->parseValExpr();
+
+ _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;
+ }
+ // loc_E2F3
+ if (_vm->_game->_soundTypes[index] & 8) {
+ _vm->_music->loadFromMemory((byte *) _vm->_game->_soundSamples[index]);
+ _vm->_music->setRepeating(repCount - 1);
+ _vm->_music->startPlay();
+ } else {
+ _vm->_snd->stopSound(0);
+ _vm->_snd->playSample(_vm->_game->_soundSamples[index], repCount, frequency);
+ }
+
+ return false;
}
bool Inter_v2::o2_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag) {
int16 cmd;
- int16 word_2F9C0;
- int16 word_2F9BE;
- int16 word_2F9BC;
- int16 word_2F9BA;
- char *dword_2F9B6;
- char *dword_2F9B2;
cmd = load16();
_vm->_global->_inter_execPtr += 2;
if (cmd == 100) {
- word_2F9C0 = VAR(load16());
- word_2F9BE = VAR(load16());
- dword_2F9B6 = _vm->_global->_inter_variables + (load16() >> 2);
- dword_2F9B2 = _vm->_global->_inter_variables + (load16() >> 2);
- word_2F9BC = VAR(load16());
- word_2F9BA = VAR(load16());
- warning("GOB2 Stub! sub_19BD3()");
+ _vm->_goblin->_word_2F9C0 = VAR(load16());
+ _vm->_goblin->_word_2F9BE = VAR(load16());
+ _vm->_goblin->_dword_2F9B6 = load16();
+ _vm->_goblin->_dword_2F9B2 = load16();
+ _vm->_goblin->_word_2F9BC = VAR(load16());
+ _vm->_goblin->_word_2F9BA = VAR(load16());
+ _vm->_goblin->sub_19BD3();
} else if (cmd != 101) {
_vm->_global->_inter_execPtr -= 2;
cmd = load16();
@@ -1569,6 +1698,16 @@ void Inter_v2::o2_totSub(void) {
_vm->_game->totSub(flags, totFile);
}
+void Inter_v2::o2_switchTotSub(void) {
+ int16 index;
+ int16 skipPlay;
+
+ index = load16();
+ skipPlay = load16();
+
+ _vm->_game->switchTotSub(index, skipPlay);
+}
+
void Inter_v2::storeMouse(void) {
int16 x;
int16 y;
@@ -1586,4 +1725,40 @@ void Inter_v2::o2_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Ob
warning("GOB2 Stub! o2_setPickable");
}
+void Inter_v2::animPalette(void) {
+ int16 i;
+ int16 j;
+ Video::Color col;
+ bool first;
+
+ first = true;
+ for (j = 0; j < 8; j ++) {
+ if (_animPalDir[j] == 0)
+ continue;
+
+ if (first) {
+ _vm->_video->waitRetrace(_vm->_global->_videoMode);
+ first = false;
+ }
+
+ if (_animPalDir[j] == -1) {
+ col = _vm->_global->_pPaletteDesc->vgaPal[_animPalLowIndex[j]];
+
+ for (i = _animPalLowIndex[j]; i < _animPalHighIndex[j]; i++)
+ _vm->_draw->_vgaPalette[i] = _vm->_global->_pPaletteDesc->vgaPal[i];
+
+ _vm->_global->_pPaletteDesc->vgaPal[_animPalHighIndex[j]] = col;
+ } else {
+ col = _vm->_global->_pPaletteDesc->vgaPal[_animPalHighIndex[j]];
+ for (i = _animPalHighIndex[j]; i > _animPalLowIndex[j]; i--)
+ _vm->_draw->_vgaPalette[i] = _vm->_global->_pPaletteDesc->vgaPal[i];
+
+ _vm->_global->_pPaletteDesc->vgaPal[_animPalLowIndex[j]] = col;
+ }
+ _vm->_global->_pPaletteDesc->vgaPal = _vm->_draw->_vgaPalette;
+ }
+ if (!first)
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+}
+
} // End of namespace Gob
diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp
index 4e90e5f232..5333ee5219 100644
--- a/engines/gob/map.cpp
+++ b/engines/gob/map.cpp
@@ -440,314 +440,6 @@ void Map::loadItemToObject(void) {
}
}
-void Map::loadMapObjects(char *avjFile) {
- int16 i;
- char avoName[128];
- int16 handle;
- char item;
- int16 soundCount;
- int16 tmp;
- char *savedPtr;
- char *savedPtr2;
- char *savedPtr3;
- int16 state;
- int16 col;
- int32 flag;
- Goblin::Gob_State *pState;
- char buf[128];
- char sndNames[20][14];
- char *dataBuf;
- int16 x;
- int16 y;
- int16 count2;
- int16 count3;
-
- strcpy(avoName, _sourceFile);
- strcat(avoName, ".avo");
-
- handle = _vm->_dataio->openData(avoName);
- if (handle >= 0) {
- _loadFromAvo = 1;
- _vm->_dataio->closeData(handle);
- _avoDataPtr = _vm->_dataio->getData(avoName);
- dataBuf = _avoDataPtr;
- loadDataFromAvo((char *)_passMap, kMapHeight * kMapWidth);
-
- for (y = 0; y < kMapHeight; y++) {
- for (x = 0; x < kMapWidth; x++) {
- loadDataFromAvo(&item, 1);
- _itemsMap[y][x] = item;
- }
- }
-
- for (i = 0; i < 40; i++) {
- _wayPoints[i].x = loadFromAvo_LE_UINT16();
- _wayPoints[i].y = loadFromAvo_LE_UINT16();
- }
- loadDataFromAvo((char *)_itemPoses, szMap_ItemPos * 20);
- } else {
- _loadFromAvo = 0;
- _avoDataPtr = _vm->_dataio->getData(avjFile);
- dataBuf = _avoDataPtr;
- }
-
- _avoDataPtr += 32;
- _avoDataPtr += 76;
- _avoDataPtr += 4;
- _avoDataPtr += 20;
-
- for (i = 0; i < 3; i++) {
- tmp = loadFromAvo_LE_UINT16();
- _avoDataPtr += tmp * 14;
- }
-
- soundCount = loadFromAvo_LE_UINT16();
- savedPtr = _avoDataPtr;
-
- _avoDataPtr += 14 * soundCount;
- _avoDataPtr += 4;
- _avoDataPtr += 24;
-
- count2 = loadFromAvo_LE_UINT16();
- count3 = loadFromAvo_LE_UINT16();
-
- savedPtr2 = _avoDataPtr;
- _avoDataPtr += count2 * 8;
-
- savedPtr3 = _avoDataPtr;
- _avoDataPtr += count3 * 8;
-
- _vm->_goblin->_gobsCount = loadFromAvo_LE_UINT16();
- for (i = 0; i < _vm->_goblin->_gobsCount; i++) {
- _vm->_goblin->_goblins[i] = new Goblin::Gob_Object;
-
- _vm->_goblin->_goblins[i]->xPos = READ_LE_UINT16(savedPtr2);
- savedPtr2 += 2;
-
- _vm->_goblin->_goblins[i]->yPos = READ_LE_UINT16(savedPtr2);
- savedPtr2 += 2;
-
- _vm->_goblin->_goblins[i]->order = READ_LE_UINT16(savedPtr2);
- savedPtr2 += 2;
-
- _vm->_goblin->_goblins[i]->state = READ_LE_UINT16(savedPtr2);
- savedPtr2 += 2;
-
- if (i == 3)
- _vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[70];
- else
- _vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[40];
-
- uint32* tempstatedata = new uint32[40*6];
- for (state = 0; state < 40; ++state) {
- for (col = 0; col < 6; ++col) {
- tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr);
- _avoDataPtr += 4;
- }
- }
- _avoDataPtr += 160;
- _vm->_goblin->_goblins[i]->multObjIndex = *_avoDataPtr;
- _avoDataPtr += 2;
-
- _vm->_goblin->_goblins[i]->realStateMach = _vm->_goblin->_goblins[i]->stateMach;
- for (state = 0; state < 40; state++) {
- for (col = 0; col < 6; col++) {
- if (tempstatedata[state*6+col] == 0) {
- _vm->_goblin->_goblins[i]->stateMach[state][col] = 0;
- continue;
- }
-
- Goblin::Gob_State *tmpState = new Goblin::Gob_State;
- _vm->_goblin->_goblins[i]->stateMach[state][col] = tmpState;
-
- tmpState->animation = loadFromAvo_LE_UINT16();
- tmpState->layer = loadFromAvo_LE_UINT16();
- _avoDataPtr += 8;
- tmpState->unk0 = loadFromAvo_LE_UINT16();
- tmpState->unk1 = loadFromAvo_LE_UINT16();
-
- _avoDataPtr += 2;
- if (READ_LE_UINT32(_avoDataPtr) != 0) {
- _avoDataPtr += 4;
- tmpState->sndItem = loadFromAvo_LE_UINT16();
- } else {
- _avoDataPtr += 6;
- tmpState->sndItem = -1;
- }
- tmpState->freq = loadFromAvo_LE_UINT16();
- tmpState->repCount = loadFromAvo_LE_UINT16();
- tmpState->sndFrame = loadFromAvo_LE_UINT16();
- }
- }
- delete[] tempstatedata;
- }
-
- pState = new Goblin::Gob_State;
- _vm->_goblin->_goblins[0]->stateMach[39][0] = pState;
- pState->animation = 0;
- pState->layer = 98;
- pState->unk0 = 0;
- pState->unk1 = 0;
- pState->sndItem = -1;
-
- pState = new Goblin::Gob_State;
- _vm->_goblin->_goblins[1]->stateMach[39][0] = pState;
- pState->animation = 0;
- pState->layer = 99;
- pState->unk0 = 0;
- pState->unk1 = 0;
- pState->sndItem = -1;
-
- pState = new Goblin::Gob_State;
- _vm->_goblin->_goblins[2]->stateMach[39][0] = pState;
- pState->animation = 0;
- pState->layer = 100;
- pState->unk0 = 0;
- pState->unk1 = 0;
- pState->sndItem = -1;
-
- _vm->_goblin->_goblins[2]->stateMach[10][0]->sndFrame = 13;
- _vm->_goblin->_goblins[2]->stateMach[11][0]->sndFrame = 13;
- _vm->_goblin->_goblins[2]->stateMach[28][0]->sndFrame = 13;
- _vm->_goblin->_goblins[2]->stateMach[29][0]->sndFrame = 13;
-
- _vm->_goblin->_goblins[1]->stateMach[10][0]->sndFrame = 13;
- _vm->_goblin->_goblins[1]->stateMach[11][0]->sndFrame = 13;
-
- for (state = 40; state < 70; state++) {
- pState = new Goblin::Gob_State;
- _vm->_goblin->_goblins[3]->stateMach[state][0] = pState;
- _vm->_goblin->_goblins[3]->stateMach[state][1] = 0;
-
- pState->animation = 9;
- pState->layer = state - 40;
- pState->sndItem = -1;
- pState->sndFrame = 0;
- }
-
- _vm->_goblin->_objCount = loadFromAvo_LE_UINT16();
- for (i = 0; i < _vm->_goblin->_objCount; i++) {
- _vm->_goblin->_objects[i] = new Goblin::Gob_Object;
-
- _vm->_goblin->_objects[i]->xPos = READ_LE_UINT16(savedPtr3);
- savedPtr3 += 2;
-
- _vm->_goblin->_objects[i]->yPos = READ_LE_UINT16(savedPtr3);
- savedPtr3 += 2;
-
- _vm->_goblin->_objects[i]->order = READ_LE_UINT16(savedPtr3);
- savedPtr3 += 2;
-
- _vm->_goblin->_objects[i]->state = READ_LE_UINT16(savedPtr3);
- savedPtr3 += 2;
-
- _vm->_goblin->_objects[i]->stateMach = new Goblin::Gob_StateLine[40];
-
- uint32* tempstatedata = new uint32[40*6];
- for (state = 0; state < 40; ++state) {
- for (col = 0; col < 6; ++col) {
- tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr);
- _avoDataPtr += 4;
- }
- }
- _avoDataPtr += 160;
- _vm->_goblin->_objects[i]->multObjIndex = *_avoDataPtr;
- _avoDataPtr += 2;
-
- _vm->_goblin->_objects[i]->realStateMach = _vm->_goblin->_objects[i]->stateMach;
- for (state = 0; state < 40; state++) {
- for (col = 0; col < 6; col++) {
- if (tempstatedata[state*6+col] == 0) {
- _vm->_goblin->_objects[i]->stateMach[state][col] = 0;
- continue;
- }
-
- Goblin::Gob_State *tmpState = new Goblin::Gob_State;
- _vm->_goblin->_objects[i]->stateMach[state][col] = tmpState;
-
- tmpState->animation = loadFromAvo_LE_UINT16();
- tmpState->layer = loadFromAvo_LE_UINT16();
- _avoDataPtr += 8;
- tmpState->unk0 = loadFromAvo_LE_UINT16();
- tmpState->unk1 = loadFromAvo_LE_UINT16();
-
- _avoDataPtr += 2;
- if (READ_LE_UINT32(_avoDataPtr) != 0) {
- _avoDataPtr += 4;
- tmpState->sndItem = loadFromAvo_LE_UINT16();
- } else {
- _avoDataPtr += 6;
- tmpState->sndItem = -1;
- }
- tmpState->freq = loadFromAvo_LE_UINT16();
- tmpState->repCount = loadFromAvo_LE_UINT16();
- tmpState->sndFrame = loadFromAvo_LE_UINT16();
- }
- }
- delete[] tempstatedata;
- }
-
- _vm->_goblin->_objects[10] = new Goblin::Gob_Object;
- memset(_vm->_goblin->_objects[10], 0, sizeof(Goblin::Gob_Object));
-
- _vm->_goblin->_objects[10]->stateMach = new Goblin::Gob_StateLine[40];
- for (state = 0; state < 40; ++state)
- for (col = 0; col < 6; ++col)
- _vm->_goblin->_objects[10]->stateMach[state][col] = 0;
-
- pState = new Goblin::Gob_State;
- _vm->_goblin->_objects[10]->stateMach[0][0] = pState;
-
- memset(pState, 0, sizeof(Goblin::Gob_State));
- pState->animation = 9;
- pState->layer = 27;
- pState->unk0 = 0;
- pState->unk1 = 0;
- pState->sndItem = -1;
- pState->sndFrame = 0;
-
- _vm->_goblin->placeObject(_vm->_goblin->_objects[10], 1);
-
- _vm->_goblin->_objects[10]->realStateMach = _vm->_goblin->_objects[10]->stateMach;
- _vm->_goblin->_objects[10]->type = 1;
- _vm->_goblin->_objects[10]->unk14 = 1;
-
- state = loadFromAvo_LE_UINT16();
- for (i = 0; i < state; i++) {
- _avoDataPtr += 30;
-
- loadDataFromAvo((char *)&flag, 4);
- _avoDataPtr += 56;
-
- if (flag != 0)
- _avoDataPtr += 30;
- }
-
- loadDataFromAvo((char *)&tmp, 2);
- _avoDataPtr += 48;
- loadItemToObject();
- _avoDataPtr = savedPtr;
-
- for (i = 0; i < soundCount; i++) {
- loadDataFromAvo(buf, 14);
- strcat(buf, ".SND");
- strcpy(sndNames[i], buf);
- }
-
- delete[] dataBuf;
-
- _vm->_goblin->_soundData[14] = _vm->_snd->loadSoundData("diamant1.snd");
-
- for (i = 0; i < soundCount; i++) {
- handle = _vm->_dataio->openData(sndNames[i]);
- if (handle < 0)
- continue;
-
- _vm->_dataio->closeData(handle);
- _vm->_goblin->_soundData[i] = _vm->_snd->loadSoundData(sndNames[i]);
- }
-}
-
void Map::loadMapsInitGobs(void) {
int16 layer;
int16 i;
diff --git a/engines/gob/map.h b/engines/gob/map.h
index 59e9a3bdf9..1b12f9280f 100644
--- a/engines/gob/map.h
+++ b/engines/gob/map.h
@@ -85,11 +85,13 @@ public:
int16 checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1);
void optimizePoints(void);
void loadItemToObject(void);
- void loadMapObjects(char *avjFile);
void loadDataFromAvo(char *dest, int16 size);
void loadMapsInitGobs(void);
+ virtual void loadMapObjects(char *avjFile) = 0;
+
Map(GobEngine *vm);
+ virtual ~Map() {};
protected:
char *_avoDataPtr;
@@ -99,6 +101,22 @@ protected:
uint16 loadFromAvo_LE_UINT16();
};
+class Map_v1 : public Map {
+public:
+ virtual void loadMapObjects(char *avjFile);
+
+ Map_v1(GobEngine *vm);
+ virtual ~Map_v1() {};
+};
+
+class Map_v2 : public Map_v1 {
+public:
+ virtual void loadMapObjects(char *avjFile);
+
+ Map_v2(GobEngine *vm);
+ virtual ~Map_v2() {};
+};
+
} // End of namespace Gob
#endif /* __MAP_H */
diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp
new file mode 100644
index 0000000000..4e9859b89f
--- /dev/null
+++ b/engines/gob/map_v1.cpp
@@ -0,0 +1,346 @@
+/* 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/map.h"
+#include "gob/dataio.h"
+#include "gob/goblin.h"
+#include "gob/sound.h"
+
+namespace Gob {
+
+Map_v1::Map_v1(GobEngine *vm) : Map(vm) {
+}
+
+void Map_v1::loadMapObjects(char *avjFile) {
+ int16 i;
+ char avoName[128];
+ int16 handle;
+ char item;
+ int16 soundCount;
+ int16 tmp;
+ char *savedPtr;
+ char *savedPtr2;
+ char *savedPtr3;
+ int16 state;
+ int16 col;
+ int32 flag;
+ Goblin::Gob_State *pState;
+ char buf[128];
+ char sndNames[20][14];
+ char *dataBuf;
+ int16 x;
+ int16 y;
+ int16 count2;
+ int16 count3;
+
+ strcpy(avoName, _sourceFile);
+ strcat(avoName, ".avo");
+
+ handle = _vm->_dataio->openData(avoName);
+ if (handle >= 0) {
+ _loadFromAvo = 1;
+ _vm->_dataio->closeData(handle);
+ _avoDataPtr = _vm->_dataio->getData(avoName);
+ dataBuf = _avoDataPtr;
+ loadDataFromAvo((char *)_passMap, kMapHeight * kMapWidth);
+
+ for (y = 0; y < kMapHeight; y++) {
+ for (x = 0; x < kMapWidth; x++) {
+ loadDataFromAvo(&item, 1);
+ _itemsMap[y][x] = item;
+ }
+ }
+
+ for (i = 0; i < 40; i++) {
+ _wayPoints[i].x = loadFromAvo_LE_UINT16();
+ _wayPoints[i].y = loadFromAvo_LE_UINT16();
+ }
+ loadDataFromAvo((char *)_itemPoses, szMap_ItemPos * 20);
+ } else {
+ _loadFromAvo = 0;
+ _avoDataPtr = _vm->_dataio->getData(avjFile);
+ dataBuf = _avoDataPtr;
+ }
+
+ _avoDataPtr += 32;
+ _avoDataPtr += 76;
+ _avoDataPtr += 4;
+ _avoDataPtr += 20;
+
+ for (i = 0; i < 3; i++) {
+ tmp = loadFromAvo_LE_UINT16();
+ _avoDataPtr += tmp * 14;
+ }
+
+ soundCount = loadFromAvo_LE_UINT16();
+ savedPtr = _avoDataPtr;
+
+ _avoDataPtr += 14 * soundCount;
+ _avoDataPtr += 4;
+ _avoDataPtr += 24;
+
+ count2 = loadFromAvo_LE_UINT16();
+ count3 = loadFromAvo_LE_UINT16();
+
+ savedPtr2 = _avoDataPtr;
+ _avoDataPtr += count2 * 8;
+
+ savedPtr3 = _avoDataPtr;
+ _avoDataPtr += count3 * 8;
+
+ _vm->_goblin->_gobsCount = loadFromAvo_LE_UINT16();
+ for (i = 0; i < _vm->_goblin->_gobsCount; i++) {
+ _vm->_goblin->_goblins[i] = new Goblin::Gob_Object;
+
+ _vm->_goblin->_goblins[i]->xPos = READ_LE_UINT16(savedPtr2);
+ savedPtr2 += 2;
+
+ _vm->_goblin->_goblins[i]->yPos = READ_LE_UINT16(savedPtr2);
+ savedPtr2 += 2;
+
+ _vm->_goblin->_goblins[i]->order = READ_LE_UINT16(savedPtr2);
+ savedPtr2 += 2;
+
+ _vm->_goblin->_goblins[i]->state = READ_LE_UINT16(savedPtr2);
+ savedPtr2 += 2;
+
+ if (i == 3)
+ _vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[70];
+ else
+ _vm->_goblin->_goblins[i]->stateMach = new Goblin::Gob_StateLine[40];
+
+ uint32* tempstatedata = new uint32[40*6];
+ for (state = 0; state < 40; ++state) {
+ for (col = 0; col < 6; ++col) {
+ tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr);
+ _avoDataPtr += 4;
+ }
+ }
+ _avoDataPtr += 160;
+ _vm->_goblin->_goblins[i]->multObjIndex = *_avoDataPtr;
+ _avoDataPtr += 2;
+
+ _vm->_goblin->_goblins[i]->realStateMach = _vm->_goblin->_goblins[i]->stateMach;
+ for (state = 0; state < 40; state++) {
+ for (col = 0; col < 6; col++) {
+ if (tempstatedata[state*6+col] == 0) {
+ _vm->_goblin->_goblins[i]->stateMach[state][col] = 0;
+ continue;
+ }
+
+ Goblin::Gob_State *tmpState = new Goblin::Gob_State;
+ _vm->_goblin->_goblins[i]->stateMach[state][col] = tmpState;
+
+ tmpState->animation = loadFromAvo_LE_UINT16();
+ tmpState->layer = loadFromAvo_LE_UINT16();
+ _avoDataPtr += 8;
+ tmpState->unk0 = loadFromAvo_LE_UINT16();
+ tmpState->unk1 = loadFromAvo_LE_UINT16();
+
+ _avoDataPtr += 2;
+ if (READ_LE_UINT32(_avoDataPtr) != 0) {
+ _avoDataPtr += 4;
+ tmpState->sndItem = loadFromAvo_LE_UINT16();
+ } else {
+ _avoDataPtr += 6;
+ tmpState->sndItem = -1;
+ }
+ tmpState->freq = loadFromAvo_LE_UINT16();
+ tmpState->repCount = loadFromAvo_LE_UINT16();
+ tmpState->sndFrame = loadFromAvo_LE_UINT16();
+ }
+ }
+ delete[] tempstatedata;
+ }
+
+ pState = new Goblin::Gob_State;
+ _vm->_goblin->_goblins[0]->stateMach[39][0] = pState;
+ pState->animation = 0;
+ pState->layer = 98;
+ pState->unk0 = 0;
+ pState->unk1 = 0;
+ pState->sndItem = -1;
+
+ pState = new Goblin::Gob_State;
+ _vm->_goblin->_goblins[1]->stateMach[39][0] = pState;
+ pState->animation = 0;
+ pState->layer = 99;
+ pState->unk0 = 0;
+ pState->unk1 = 0;
+ pState->sndItem = -1;
+
+ pState = new Goblin::Gob_State;
+ _vm->_goblin->_goblins[2]->stateMach[39][0] = pState;
+ pState->animation = 0;
+ pState->layer = 100;
+ pState->unk0 = 0;
+ pState->unk1 = 0;
+ pState->sndItem = -1;
+
+ _vm->_goblin->_goblins[2]->stateMach[10][0]->sndFrame = 13;
+ _vm->_goblin->_goblins[2]->stateMach[11][0]->sndFrame = 13;
+ _vm->_goblin->_goblins[2]->stateMach[28][0]->sndFrame = 13;
+ _vm->_goblin->_goblins[2]->stateMach[29][0]->sndFrame = 13;
+
+ _vm->_goblin->_goblins[1]->stateMach[10][0]->sndFrame = 13;
+ _vm->_goblin->_goblins[1]->stateMach[11][0]->sndFrame = 13;
+
+ for (state = 40; state < 70; state++) {
+ pState = new Goblin::Gob_State;
+ _vm->_goblin->_goblins[3]->stateMach[state][0] = pState;
+ _vm->_goblin->_goblins[3]->stateMach[state][1] = 0;
+
+ pState->animation = 9;
+ pState->layer = state - 40;
+ pState->sndItem = -1;
+ pState->sndFrame = 0;
+ }
+
+ _vm->_goblin->_objCount = loadFromAvo_LE_UINT16();
+ for (i = 0; i < _vm->_goblin->_objCount; i++) {
+ _vm->_goblin->_objects[i] = new Goblin::Gob_Object;
+
+ _vm->_goblin->_objects[i]->xPos = READ_LE_UINT16(savedPtr3);
+ savedPtr3 += 2;
+
+ _vm->_goblin->_objects[i]->yPos = READ_LE_UINT16(savedPtr3);
+ savedPtr3 += 2;
+
+ _vm->_goblin->_objects[i]->order = READ_LE_UINT16(savedPtr3);
+ savedPtr3 += 2;
+
+ _vm->_goblin->_objects[i]->state = READ_LE_UINT16(savedPtr3);
+ savedPtr3 += 2;
+
+ _vm->_goblin->_objects[i]->stateMach = new Goblin::Gob_StateLine[40];
+
+ uint32* tempstatedata = new uint32[40*6];
+ for (state = 0; state < 40; ++state) {
+ for (col = 0; col < 6; ++col) {
+ tempstatedata[state*6+col] = READ_LE_UINT32(_avoDataPtr);
+ _avoDataPtr += 4;
+ }
+ }
+ _avoDataPtr += 160;
+ _vm->_goblin->_objects[i]->multObjIndex = *_avoDataPtr;
+ _avoDataPtr += 2;
+
+ _vm->_goblin->_objects[i]->realStateMach = _vm->_goblin->_objects[i]->stateMach;
+ for (state = 0; state < 40; state++) {
+ for (col = 0; col < 6; col++) {
+ if (tempstatedata[state*6+col] == 0) {
+ _vm->_goblin->_objects[i]->stateMach[state][col] = 0;
+ continue;
+ }
+
+ Goblin::Gob_State *tmpState = new Goblin::Gob_State;
+ _vm->_goblin->_objects[i]->stateMach[state][col] = tmpState;
+
+ tmpState->animation = loadFromAvo_LE_UINT16();
+ tmpState->layer = loadFromAvo_LE_UINT16();
+ _avoDataPtr += 8;
+ tmpState->unk0 = loadFromAvo_LE_UINT16();
+ tmpState->unk1 = loadFromAvo_LE_UINT16();
+
+ _avoDataPtr += 2;
+ if (READ_LE_UINT32(_avoDataPtr) != 0) {
+ _avoDataPtr += 4;
+ tmpState->sndItem = loadFromAvo_LE_UINT16();
+ } else {
+ _avoDataPtr += 6;
+ tmpState->sndItem = -1;
+ }
+ tmpState->freq = loadFromAvo_LE_UINT16();
+ tmpState->repCount = loadFromAvo_LE_UINT16();
+ tmpState->sndFrame = loadFromAvo_LE_UINT16();
+ }
+ }
+ delete[] tempstatedata;
+ }
+
+ _vm->_goblin->_objects[10] = new Goblin::Gob_Object;
+ memset(_vm->_goblin->_objects[10], 0, sizeof(Goblin::Gob_Object));
+
+ _vm->_goblin->_objects[10]->stateMach = new Goblin::Gob_StateLine[40];
+ for (state = 0; state < 40; ++state)
+ for (col = 0; col < 6; ++col)
+ _vm->_goblin->_objects[10]->stateMach[state][col] = 0;
+
+ pState = new Goblin::Gob_State;
+ _vm->_goblin->_objects[10]->stateMach[0][0] = pState;
+
+ memset(pState, 0, sizeof(Goblin::Gob_State));
+ pState->animation = 9;
+ pState->layer = 27;
+ pState->unk0 = 0;
+ pState->unk1 = 0;
+ pState->sndItem = -1;
+ pState->sndFrame = 0;
+
+ _vm->_goblin->placeObject(_vm->_goblin->_objects[10], 1, 0, 0, 0, 0);
+
+ _vm->_goblin->_objects[10]->realStateMach = _vm->_goblin->_objects[10]->stateMach;
+ _vm->_goblin->_objects[10]->type = 1;
+ _vm->_goblin->_objects[10]->unk14 = 1;
+
+ state = loadFromAvo_LE_UINT16();
+ for (i = 0; i < state; i++) {
+ _avoDataPtr += 30;
+
+ loadDataFromAvo((char *)&flag, 4);
+ _avoDataPtr += 56;
+
+ if (flag != 0)
+ _avoDataPtr += 30;
+ }
+
+ loadDataFromAvo((char *)&tmp, 2);
+ _avoDataPtr += 48;
+ loadItemToObject();
+ _avoDataPtr = savedPtr;
+
+ for (i = 0; i < soundCount; i++) {
+ loadDataFromAvo(buf, 14);
+ strcat(buf, ".SND");
+ strcpy(sndNames[i], buf);
+ }
+
+ delete[] dataBuf;
+
+ _vm->_goblin->_soundData[14] = _vm->_snd->loadSoundData("diamant1.snd");
+
+ for (i = 0; i < soundCount; i++) {
+ handle = _vm->_dataio->openData(sndNames[i]);
+ if (handle < 0)
+ continue;
+
+ _vm->_dataio->closeData(handle);
+ _vm->_goblin->_soundData[i] = _vm->_snd->loadSoundData(sndNames[i]);
+ }
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp
new file mode 100644
index 0000000000..d8ef031cc9
--- /dev/null
+++ b/engines/gob/map_v2.cpp
@@ -0,0 +1,192 @@
+/* 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/map.h"
+#include "gob/dataio.h"
+#include "gob/goblin.h"
+#include "gob/sound.h"
+#include "gob/inter.h"
+#include "gob/game.h"
+#include "gob/parse.h"
+#include "gob/mult.h"
+
+namespace Gob {
+
+Map_v2::Map_v2(GobEngine *vm) : Map_v1(vm) {
+}
+
+void Map_v2::loadMapObjects(char *avjFile) {
+ int i;
+ int j;
+ int k;
+ int16 var;
+ int16 id;
+ int16 numChunks;
+ int16 chunkLength;
+ int16 offVar;
+ int16 offData;
+ int16 tmp;
+ int16 numData;
+ int16 statesCount;
+ int16 state;
+ char *variables;
+ char *extData;
+ char *dataPtr;
+ char *dataPtrBak;
+ char *dataPtrBak2;
+ char statesMask[102];
+ Goblin::Gob2_State *statesPtr;
+
+ uint8 var_9;
+ uint8 byte_2F2AA;
+ byte *off_2F2AB;
+
+ var = _vm->_parse->parseVarIndex();
+ variables = _vm->_global->_inter_variables + var;
+
+ id = _vm->_inter->load16();
+
+ if (id == -1) {
+ _vm->_goblin->_dword_2F2A4 = _vm->_global->_inter_variables + var;
+ return;
+ }
+
+ extData = _vm->_game->loadExtData(id, 0, 0);
+ dataPtr = extData;
+
+ if (*dataPtr++ == 3) {
+ _vm->_mult->_word_2F22A = 640;
+ _vm->_mult->_word_2CC84 = 65;
+ } else {
+ _vm->_mult->_word_2F22A = 320;
+ _vm->_mult->_word_2CC84 = 40;
+ }
+ byte_2F2AA = *dataPtr++;
+ _vm->_mult->_word_2F2B1 = READ_LE_UINT16(dataPtr);
+ dataPtr += 2;
+ _vm->_mult->_word_2F2AF = READ_LE_UINT16(dataPtr);
+ dataPtr += 2;
+
+ _vm->_mult->_word_2CC86 = _vm->_mult->_word_2F2AF & 0xFF00 ? 0 : 1;
+ _vm->_mult->_word_2F2AF &= 0xFF;
+
+ dataPtrBak = dataPtr;
+ dataPtr += (_vm->_mult->_word_2F22A / _vm->_mult->_word_2F2B1) * (200 / _vm->_mult->_word_2F2AF);
+
+ if (*extData == 1) {
+ byte_2F2AA = 40;
+ var_9 = 40;
+ } else {
+ if (byte_2F2AA == 0) {
+ var_9 = 1;
+ } else {
+ var_9 = byte_2F2AA;
+ }
+ }
+
+ off_2F2AB = new byte[3 * var_9];
+ memset(off_2F2AB, -1, 3 * var_9);
+ memcpy(off_2F2AB, dataPtr, 3 * byte_2F2AA);
+ dataPtr += 3 * byte_2F2AA;
+
+ // In the original asm, this writes byte-wise into the variables-array
+ if (variables != _vm->_global->_inter_variables) {
+ _vm->_goblin->_dword_2F2A4 = variables;
+ numChunks = 200 / _vm->_mult->_word_2F2AF;
+ chunkLength = _vm->_mult->_word_2F22A / _vm->_mult->_word_2F2B1;
+ for (i = 0; i < numChunks; i++) {
+ offVar = _vm->_mult->_word_2CC84 * i;
+ offData = (chunkLength * i);
+ for (j = 0; j < chunkLength; j++) {
+ _vm->_util->writeVariableByte(_vm->_goblin->_dword_2F2A4 + offVar + j,
+ *(dataPtrBak + offData + j));
+ }
+ }
+ }
+
+ tmp = READ_LE_UINT16(dataPtr);
+ dataPtr += tmp * 14 + 2;
+ tmp = READ_LE_UINT16(dataPtr);
+ dataPtr += tmp * 14 + 2;
+ dataPtr += 28;
+ tmp = READ_LE_UINT16(dataPtr);
+ dataPtr += tmp * 14 + 2;
+
+ _vm->_goblin->_gobsCount = tmp;
+ for (i = 0; i < _vm->_goblin->_gobsCount; i++) {
+ memset(statesMask, -1, 101);
+ _vm->_mult->_objects[i].goblinStates = new Goblin::Gob2_State*[101];
+ memset(_vm->_mult->_objects[i].goblinStates, 0, 101 * sizeof(Goblin::Gob2_State *));
+ memcpy(statesMask, dataPtr, 100);
+ dataPtr += 100;
+ dataPtrBak2 = dataPtr;
+ statesCount = 0;
+ for (j = 0; j < 100; j++) {
+ if (statesMask[j] != -1) {
+ statesCount++;
+ dataPtr += 4;
+ numData = *dataPtr++;
+ statesCount += numData;
+ dataPtr += numData * 9;
+ }
+ }
+ statesPtr = new Goblin::Gob2_State[statesCount];
+ _vm->_mult->_objects[i].goblinStates[0] = statesPtr;
+ dataPtr = dataPtrBak2;
+ for (j = 0; j < 100; j++) {
+ state = statesMask[j];
+ if (state != -1) {
+ _vm->_mult->_objects[i].goblinStates[state] = statesPtr++;
+ _vm->_mult->_objects[i].goblinStates[state][0].animation = READ_LE_UINT16(dataPtr);
+ dataPtr += 2;
+ _vm->_mult->_objects[i].goblinStates[state][0].layer = READ_LE_UINT16(dataPtr);
+ dataPtr += 2;
+ numData = *dataPtr++;
+ _vm->_mult->_objects[i].goblinStates[state][0].field_4 = numData;
+ for (k = 0; k < numData; k++) {
+ dataPtr++;
+ _vm->_mult->_objects[i].goblinStates[state][k].animation = *dataPtr << 8;
+ dataPtr += 2;
+ _vm->_mult->_objects[i].goblinStates[state][k].animation += *dataPtr;
+ dataPtr += 2;
+ _vm->_mult->_objects[i].goblinStates[state][k].layer = *dataPtr << 8;
+ dataPtr += 2;
+ _vm->_mult->_objects[i].goblinStates[state][k].layer += *dataPtr;
+ _vm->_mult->_objects[i].goblinStates[state][k].field_4 = READ_LE_UINT16(dataPtr);
+ dataPtr += 2;
+ statesPtr++;
+ }
+ }
+ }
+ }
+
+ _vm->_goblin->_soundSlotsCount = _vm->_inter->load16();
+ for (i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
+ _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 5a19baa6f8..9a8ba2c0ea 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -14,6 +14,8 @@ MODULE_OBJS := \
global.o \
gob.o \
goblin.o \
+ goblin_v1.o \
+ goblin_v2.o \
init.o \
init_v1.o \
init_v2.o \
@@ -21,6 +23,8 @@ MODULE_OBJS := \
inter_v1.o \
inter_v2.o \
map.o \
+ map_v1.o \
+ map_v2.o \
mult.o \
mult_v1.o \
mult_v2.o \
diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp
index 0ad2fb5b50..3960cb2b6a 100644
--- a/engines/gob/mult.cpp
+++ b/engines/gob/mult.cpp
@@ -120,8 +120,12 @@ Mult::Mult(GobEngine *vm) : _vm(vm) {
}
_orderArray = 0;
- warning("GOB2 Stub! _word_2CC88");
- _word_2CC88 = -1;
+ warning("GOB2 Stub! _word_2F2B1, _word_2F2AF, _word_2CC86, _word_2F22A, _word_2CC84");
+ _word_2F2B1 = 0;
+ _word_2F2AF = 0;
+ _word_2CC86 = 0;
+ _word_2F22A = 0;
+ _word_2CC84 = 0;
}
void Mult::interGetObjAnimSize(void) {
diff --git a/engines/gob/mult.h b/engines/gob/mult.h
index 65b3a02238..d09260fa25 100644
--- a/engines/gob/mult.h
+++ b/engines/gob/mult.h
@@ -25,6 +25,7 @@
#include "gob/sound.h"
#include "gob/video.h"
+#include "gob/goblin.h"
namespace Gob {
@@ -49,7 +50,15 @@ public:
int8 somethingLayer; // New in GOB2
int8 somethingFrame; // New in GOB2
int8 someFlag; // New in GOB2
+ int8 state; // New in GOB2
+ int8 field_E; // New in GOB2
int8 field_F; // New in GOB2
+ int8 field_10; // New in GOB2
+ int8 field_12; // New in GOB2
+ int8 field_13; // New in GOB2
+ int8 field_14; // New in GOB2
+ int8 field_15; // New in GOB2
+ int8 field_17; // New in GOB2
} GCC_PACK;
struct Mult_Object {
@@ -61,11 +70,18 @@ public:
int16 lastRight;
int16 lastTop;
int16 lastBottom;
- int8 someFlag; // New in GOB2
- int16 somethingLeft; // New in GOB2
- int16 somethingTop; // New in GOB2
- int16 somethingRight; // New in GOB2
- int16 somethingBottom; // New in GOB2
+ int8 someFlag; // New in GOB2
+ int16 somethingLeft; // New in GOB2
+ int16 somethingTop; // New in GOB2
+ int16 somethingRight; // New in GOB2
+ int16 somethingBottom; // New in GOB2
+ int8 goblinX; // New in GOB2
+ int8 goblinY; // New in GOB2
+ int8 field_1C; // New in GOB2
+ int8 field_1D; // New in GOB2
+ int8 field_1E; // New in GOB2
+ int8 field_1F; // New in GOB2
+ Goblin::Gob2_State **goblinStates; // New in GOB2
};
struct Mult_StaticKey {
@@ -186,7 +202,11 @@ public:
int8 *_orderArray;
- int16 _word_2CC88;
+ uint16 _word_2F2B1;
+ uint16 _word_2F2AF;
+ uint16 _word_2CC86;
+ uint16 _word_2F22A;
+ uint16 _word_2CC84;
void zeroMultData(void);
void checkFreeMult(void);
@@ -218,7 +238,7 @@ protected:
virtual char prepPalAnim(char stop) = 0;
virtual void doPalAnim(void) = 0;
virtual char doFadeAnim(char stop) = 0;
- virtual char doSoundAnim(char stop) = 0;
+ virtual char doSoundAnim(char stop, int16 frame) = 0;
};
class Mult_v1 : public Mult {
@@ -243,7 +263,7 @@ protected:
virtual char prepPalAnim(char stop);
virtual void doPalAnim(void);
virtual char doFadeAnim(char stop);
- virtual char doSoundAnim(char stop);
+ virtual char doSoundAnim(char stop, int16 frame);
};
class Mult_v2 : public Mult_v1 {
@@ -325,7 +345,7 @@ protected:
virtual char prepPalAnim(char stop);
virtual void doPalAnim(void);
virtual char doFadeAnim(char stop);
- virtual char doSoundAnim(char stop);
+ virtual char doSoundAnim(char stop, int16 frame);
void sub_62DD(int16 index);
void sub_6A35(void);
diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp
index 37ede23366..f0dc7410ef 100644
--- a/engines/gob/mult_v1.cpp
+++ b/engines/gob/mult_v1.cpp
@@ -305,7 +305,7 @@ void Mult_v1::playMult(int16 startFrame, int16 endFrame, char checkEscape,
doPalAnim();
stop = doFadeAnim(stop);
- stop = doSoundAnim(stop);
+ stop = doSoundAnim(stop, _frame);
if (_frame >= endFrame)
stopNoClear = 1;
@@ -597,11 +597,11 @@ char Mult_v1::doFadeAnim(char stop) {
return stop;
}
-char Mult_v1::doSoundAnim(char stop) {
+char Mult_v1::doSoundAnim(char stop, int16 frame) {
Mult_SndKey *sndKey;
for (_index = 0; _index < _sndKeysCount; _index++) {
sndKey = &_sndKeys[_index];
- if (sndKey->frame != _frame)
+ if (sndKey->frame != frame)
continue;
if (sndKey->cmd != -1) {
diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp
index 09ddef4b43..032f1702eb 100644
--- a/engines/gob/mult_v2.cpp
+++ b/engines/gob/mult_v2.cpp
@@ -34,6 +34,7 @@
#include "gob/draw.h"
#include "gob/palanim.h"
#include "gob/parse.h"
+#include "gob/music.h"
namespace Gob {
@@ -56,6 +57,17 @@ void Mult_v2::loadMult(int16 resId) {
index = (resId & 0x8000) ? *_vm->_global->_inter_execPtr++ : 0;
_multData2 = new Mult_Data;
+
+ // ---.
+ for (i = 0; i < 4; i++) {
+ _multData2->field_157[i] = 0;
+ for (j = 0; j < 4; j++) {
+ _multData2->field_15F[i][j] = 0;
+ _multData2->field_17F[i][j] = 0;
+ }
+ }
+ // ---'
+
_multDatas[index] = _multData2;
for (i = 0; i < 10; i++) {
@@ -361,6 +373,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_objCount = 4;
_objects = new Mult_Object[_objCount];
+
_orderArray = new int8[_objCount];
_renderData = new int16[9 * _objCount];
_renderData2 = new Mult_Object*[_objCount];
@@ -369,6 +382,14 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_animArrayY = new int32[_objCount];
_animArrayData = new Mult_AnimData[_objCount];
+ // TODO: Delete that after the code that initializes these fields exists!
+ int i;
+ for (i = 0; i < _objCount; i++) {
+ _animArrayData[i].field_13 = 0;
+ _animArrayData[i].field_14 = 0;
+ _animArrayData[i].field_17 = 0;
+ }
+ // ---'
for (_counter = 0; _counter < _objCount; _counter++) {
multObj = &_objects[_counter];
@@ -427,6 +448,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
}
do {
+ _vm->_snd->loopSounds();
stop = 1;
if (VAR(58) == 0) {
@@ -449,7 +471,7 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
doPalAnim();
stop = doFadeAnim(stop);
- stop = doSoundAnim(stop);
+ stop = doSoundAnim(stop, _frame);
if (_frame >= endFrame)
stopNoClear = 1;
@@ -771,23 +793,18 @@ char Mult_v2::doFadeAnim(char stop) {
return stop;
}
-char Mult_v2::doSoundAnim(char stop) {
+char Mult_v2::doSoundAnim(char stop, int16 frame) {
Mult_SndKey *sndKey;
for (_index = 0; _index < _multData2->sndKeysCount; _index++) {
sndKey = &_multData2->sndKeys[_index];
- if (sndKey->frame != _frame)
+ if (sndKey->frame != frame)
continue;
if (sndKey->cmd != -1) {
- if (sndKey->cmd == 1) {
- _vm->_snd->stopSound(0);
- stop = 0;
- playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount,
- sndKey->freq, sndKey->channel);
-
- } else if (sndKey->cmd == 4) {
+ if ((sndKey->cmd == 1) || (sndKey->cmd == 4)) {
_vm->_snd->stopSound(0);
- stop = 0;
+ if (_vm->_game->_soundSamples[sndKey->soundIndex] == 0)
+ continue;
playSound(_vm->_game->_soundSamples[sndKey->soundIndex], sndKey->repCount,
sndKey->freq, sndKey->channel);
}
@@ -817,6 +834,8 @@ void Mult_v2::sub_62DD(int16 index) {
for (i = 0; i < 4; i++) {
if (_multData2->field_124[index][i] != -1) {
for (j = _multData2->field_15F[index][i]; j < _multData2->animKeysCount[i]; j++) {
+ if ((i >= 4) || (j >= _multData2->animKeysCount[i]))
+ continue;
animKey = &_multData2->animKeys[i][j];
if (animKey->frame > frame)
break;
@@ -894,6 +913,43 @@ void Mult_v2::sub_62DD(int16 index) {
warning("GOB2 Stub! sub_1CBF8(arg0, arg1, arg2, arg3);");
}
}
+
+ doSoundAnim(0, frame);
+
+ if (_multData2->field_156 == 1) { // loc_6809
+ frame++;
+ if (_multData2->field_157[index] == (frame-1)) {
+ _multData2->somepointer05indices[0] = -1;
+ _multData2->somepointer05indices[1] = -1;
+ _multData2->somepointer05indices[2] = -1;
+ _multData2->somepointer05indices[3] = -1;
+ frame = -1;
+ for (i = 0; i < 4; i++) {
+ if ((_multData2->field_124[index][i] == -1) || (_multData2->field_124[index][i] == 1024))
+ continue;
+ _objects[_multData2->field_124[index][i]].pAnimData->animType =
+ _objects[_multData2->field_124[index][i]].pAnimData->field_17;
+ }
+ }
+ } else { // loc_68F3
+ frame--;
+ if (_multData2->field_157[index] == (frame+1)) {
+ _multData2->somepointer05indices[0] = -1;
+ _multData2->somepointer05indices[1] = -1;
+ _multData2->somepointer05indices[2] = -1;
+ _multData2->somepointer05indices[3] = -1;
+ frame = -1;
+ for (i = 0; i < 4; i++) {
+ if ((_multData2->field_124[index][i] == -1) || (_multData2->field_124[index][i] == 1024))
+ continue;
+ _objects[_multData2->field_124[index][i]].pAnimData->animType =
+ _objects[_multData2->field_124[index][i]].pAnimData->field_17;
+ }
+ }
+ }
+ // loc_6A06
+ _multData2->animKeysIndices1[index] = frame;
+ WRITE_VAR(18 + index, frame);
}
void Mult_v2::sub_6A35(void) {
@@ -1043,7 +1099,7 @@ void Mult_v2::animate(void) {
}
}
- if (_word_2CC88 >= 0) {
+ if (_vm->_goblin->_gobsCount >= 0) {
for (i = 0; i < orderArrayPos; i++) {
animObj1 = _renderData2[orderArray[i]];
for (j = i+1; j < orderArrayPos; j++) {
@@ -1135,7 +1191,7 @@ void Mult_v2::animate(void) {
if (animData1->maxTick == animObj1->tick) {
animObj1->tick = 0;
- if ((animData1->animType < 100) || (_word_2CC88 < 0)) {
+ if ((animData1->animType < 100) || (_vm->_goblin->_gobsCount < 0)) {
if (animData1->animType == 4) {
animData1->frame = 0;
animData1->isPaused = 1;
@@ -1217,8 +1273,18 @@ void Mult_v2::animate(void) {
void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq,
int16 channel) {
- warning("GOB2 Stub! Mult_v2::playSound()");
-// _vm->_snd->playSample(soundDesc, repCount, freq);
+ warning("PlaySound(%p, %d, %d, %d), %d", (void *) soundDesc, repCount, freq, channel, soundDesc->frequency);
+ if (soundDesc->frequency >= 0) {
+ if (soundDesc->frequency == freq)
+ _vm->_snd->playSample(soundDesc, repCount, -channel);
+ else
+ _vm->_snd->playSample(soundDesc, repCount, freq);
+ } else {
+ if (soundDesc->frequency == -freq)
+ _vm->_snd->playSample(soundDesc, repCount, -channel);
+ else
+ _vm->_snd->playSample(soundDesc, repCount, freq);
+ }
}
void Mult_v2::freeMultKeys(void) {
diff --git a/engines/gob/music.cpp b/engines/gob/music.cpp
index a70a6cfe0b..52b37e7206 100644
--- a/engines/gob/music.cpp
+++ b/engines/gob/music.cpp
@@ -81,7 +81,7 @@ Music::Music(GobEngine *vm) : _vm(vm) {
_first = true;
_ended = false;
_playing = false;
- _looping = true;
+ _repCount = -1;
_samplesTillPoll = 0;
setFreqs();
@@ -94,21 +94,24 @@ Music::~Music(void) {
}
void Music::premixerCall(int16 *buf, uint len) {
+ _mutex.lock();
if (!_playing) {
memset(buf, 0, 2 * len * sizeof(int16));
+ _mutex.unlock();
return;
}
else {
if (_first) {
memset(buf, 0, 2 * len * sizeof(int16));
pollMusic();
+ _mutex.unlock();
return;
}
else {
uint32 render;
int16 *data = buf;
uint datalen = len;
- while (datalen) {
+ while (datalen && _playing) {
if (_samplesTillPoll) {
render = (datalen > _samplesTillPoll) ? (_samplesTillPoll) : (datalen);
datalen -= render;
@@ -129,7 +132,11 @@ void Music::premixerCall(int16 *buf, uint len) {
_ended = false;
_playPos = _data + 3 + (_data[1] + 1) * 0x38;
_samplesTillPoll = 0;
- if (_looping) {
+ if (_repCount == -1) {
+ reset();
+ setVoices();
+ } else if (_repCount > 0) {
+ _repCount--;
reset();
setVoices();
}
@@ -141,6 +148,7 @@ void Music::premixerCall(int16 *buf, uint len) {
buf[2 * i] = buf[2 * i + 1] = buf[i];
}
}
+ _mutex.unlock();
}
void Music::writeOPL(byte reg, byte val) {
@@ -175,6 +183,10 @@ void Music::setFreqs(void) {
}
void Music::reset() {
+ OPLResetChip(_opl);
+ _samplesTillPoll = 0;
+
+ setFreqs();
// Set frequencies and octave to 0; notes off
for (int i = 0; i < 9; i++) {
writeOPL(0xA0 | i, 0);
@@ -299,7 +311,7 @@ void Music::pollMusic(void) {
byte volume;
uint16 tempo;
- if (_playPos > (_data + _dataSize)) {
+ if ((_playPos > (_data + _dataSize)) && (_dataSize != (uint32) -1)) {
_ended = true;
return;
}
@@ -355,7 +367,7 @@ void Music::pollMusic(void) {
break;
default:
warning("Unknown command in ADL, stopping playback");
- _looping = false;
+ _repCount = 0;
_ended = true;
break;
}
@@ -427,6 +439,18 @@ bool Music::loadMusic(const char *filename) {
return true;
}
+void Music::loadFromMemory(byte *data) {
+ _playing = false;
+ _repCount = 0;
+
+ _dataSize = (uint32) -1;
+ _data = data;
+
+ reset();
+ setVoices();
+ _playPos = _data + 3 + (_data[1] + 1) * 0x38;
+}
+
void Music::unloadMusic(void) {
_playing = false;
diff --git a/engines/gob/music.h b/engines/gob/music.h
index 16aa839cdc..19c7b2d28f 100644
--- a/engines/gob/music.h
+++ b/engines/gob/music.h
@@ -26,6 +26,7 @@
#include "sound/audiostream.h"
#include "sound/fmopl.h"
+#include "common/mutex.h"
#include "gob/gob.h"
@@ -38,14 +39,17 @@ public:
Music(GobEngine *vm);
~Music();
+ void lock() { _mutex.lock(); }
+ void unlock() { _mutex.unlock(); }
bool playing() { return _playing; }
- bool getLooping() { return _looping; }
- void setLooping(bool looping) { _looping = looping; }
+ bool getRepeating(void) { return _repCount; }
+ void setRepeating (int32 repCount) { _repCount = repCount; }
void startPlay(void);
- void stopPlay(void) { _playing = false; }
+ void stopPlay(void) { _mutex.lock(); _playing = false; _mutex.unlock(); }
void playTrack(const char *trackname);
void playBgMusic(void);
bool loadMusic(const char *filename);
+ void loadFromMemory(byte *data);
void unloadMusic(void);
// AudioStream API
@@ -74,10 +78,11 @@ protected:
bool _notOn[11];
byte _pollNotes[16];
uint32 _samplesTillPoll;
+ int32 _repCount;
bool _playing;
bool _first;
bool _ended;
- bool _looping;
+ Common::Mutex _mutex;
GobEngine *_vm;
void premixerCall(int16 *buf, uint len);
diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp
index 9bb0fc2de0..6a7446d63d 100644
--- a/engines/gob/sound.cpp
+++ b/engines/gob/sound.cpp
@@ -24,6 +24,8 @@
#include "gob/gob.h"
#include "gob/global.h"
#include "gob/sound.h"
+#include "gob/game.h"
+#include "gob/util.h"
namespace Gob {
@@ -93,7 +95,14 @@ void Snd::speakerOff(void) {
}
void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) {
- assert(frequency > 0);
+ if (frequency == 0)
+ frequency = sndDesc->frequency;
+
+ if (frequency <= 0) {
+ warning("Attempted to play a sample with a frequency of %d", frequency);
+ return;
+ }
+// assert(frequency > 0);
if (!_vm->_mixer->isSoundHandleActive(sndDesc->handle)) {
_vm->_mixer->playRaw(&sndDesc->handle, sndDesc->data, sndDesc->size, frequency, 0);
diff --git a/engines/gob/sound.h b/engines/gob/sound.h
index d755e9898c..5c989a7a38 100644
--- a/engines/gob/sound.h
+++ b/engines/gob/sound.h
@@ -45,7 +45,7 @@ public:
typedef void (*CleanupFuncPtr) (int16);
- SoundDesc *_loopingSounds[5]; // Should be enough
+ SoundDesc *_loopingSounds[10]; // Should be enough
char _playingSound;
CleanupFuncPtr _cleanupFunc;
diff --git a/engines/gob/util.h b/engines/gob/util.h
index 1e707b42c1..17c3c09155 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -24,6 +24,7 @@
#define GOB_UTIL_H
#include "gob/video.h"
+#include "gob/global.h"
namespace Gob {
@@ -86,6 +87,23 @@ public:
static const char trStr1[];
static const char trStr2[];
static const char trStr3[];
+
+ inline uint8 readVariableByte(char *address) {
+ int16 whichVar = address - _vm->_global->_inter_variables;
+ int16 whichVarByte = whichVar % 4;
+
+ whichVar >>= 2;
+ return ((VAR(whichVar) >> 8 * (3-whichVarByte)) & 0xFF);
+ }
+ inline void writeVariableByte(char *address, uint8 value) {
+ int16 whichVar = address - _vm->_global->_inter_variables;
+ int16 whichVarByte = whichVar % 4;
+
+ whichVar >>= 2;
+ VAR(whichVar) &= ~(0xFF << 8 * (3-whichVarByte));
+ VAR(whichVar) |= ((uint32) value) << 8 * (3-whichVarByte);
+ }
+
Util(GobEngine *vm);
protected:
diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp
index 41680b343b..0dc7055471 100644
--- a/engines/gob/video.cpp
+++ b/engines/gob/video.cpp
@@ -285,7 +285,7 @@ void Video::drawCircle(Video::SurfaceDesc *dest, int16 x, int16 y, int16 radius,
void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y,
int16 transp, SurfaceDesc *dest) {
- if (Video::spriteUncompressor(sprBuf, width, height, x, y, transp, dest))
+ if (spriteUncompressor(sprBuf, width, height, x, y, transp, dest))
return;
if ((dest->vidMode & 0x7f) != 0x13)
@@ -391,135 +391,6 @@ void Video::initPrimary(int16 mode) {
}
}
-char Video::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
- int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) {
- SurfaceDesc sourceDesc;
- byte *memBuffer;
- byte *srcPtr;
- byte *destPtr;
- byte *linePtr;
- byte temp;
- uint16 sourceLeft;
- int16 curWidth;
- int16 curHeight;
- int16 offset;
- int16 counter2;
- uint16 cmdVar;
- int16 bufPos;
- int16 strLen;
-
- if (!destDesc)
- return 1;
-
- if ((destDesc->vidMode & 0x7f) != 0x13)
- error("Video::spriteUncompressor: Video mode 0x%x is not supported!",
- destDesc->vidMode & 0x7f);
-
- if (sprBuf[0] != 1)
- return 0;
-
- if (sprBuf[1] != 2)
- return 0;
-
- if (sprBuf[2] == 2) {
- sourceDesc.width = srcWidth;
- sourceDesc.height = srcHeight;
- sourceDesc.vidMode = 0x93;
- sourceDesc.vidPtr = sprBuf + 3;
- Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1,
- srcHeight - 1, x, y, transp);
- return 1;
- } else {
- memBuffer = new byte[4114];
- if (memBuffer == 0)
- return 0;
-
- srcPtr = sprBuf + 3;
- sourceLeft = READ_LE_UINT16(srcPtr);
-
- destPtr = destDesc->vidPtr + destDesc->width * y + x;
-
- curWidth = 0;
- curHeight = 0;
-
- linePtr = destPtr;
- srcPtr += 4;
-
- for (offset = 0; offset < 4078; offset++)
- memBuffer[offset] = 0x20;
-
- cmdVar = 0;
- bufPos = 4078;
- while (1) {
- cmdVar >>= 1;
- if ((cmdVar & 0x100) == 0) {
- cmdVar = *srcPtr | 0xff00;
- srcPtr++;
- }
- if ((cmdVar & 1) != 0) {
- temp = *srcPtr++;
- if (temp != 0 || transp == 0)
- *destPtr = temp;
- destPtr++;
- curWidth++;
- if (curWidth >= srcWidth) {
- curWidth = 0;
- linePtr += destDesc->width;
- destPtr = linePtr;
- curHeight++;
- if (curHeight >= srcHeight)
- break;
- }
- sourceLeft--;
- if (sourceLeft == 0)
- break;
-
- memBuffer[bufPos] = temp;
- bufPos++;
- bufPos %= 4096;
- } else {
- offset = *srcPtr;
- srcPtr++;
- offset |= (*srcPtr & 0xf0) << 4;
- strLen = (*srcPtr & 0x0f) + 3;
- srcPtr++;
-
- for (counter2 = 0; counter2 < strLen;
- counter2++) {
- temp =
- memBuffer[(offset +
- counter2) % 4096];
- if (temp != 0 || transp == 0)
- *destPtr = temp;
- destPtr++;
-
- curWidth++;
- if (curWidth >= srcWidth) {
- curWidth = 0;
- linePtr += destDesc->width;
- destPtr = linePtr;
- curHeight++;
- if (curHeight >= srcHeight) {
- delete[] memBuffer;
- return 1;
- }
- }
- sourceLeft--;
- if (sourceLeft == 0) {
- delete[] memBuffer;
- return 1;
- }
- memBuffer[bufPos] = temp;
- bufPos++;
- bufPos %= 4096;
- }
- }
- }
- }
- delete[] memBuffer;
- return 1;
-}
-
void Video::setHandlers() { _vm->_global->_setAllPalette = 1; }
} // End of namespace Gob
diff --git a/engines/gob/video.h b/engines/gob/video.h
index 293643ed55..24c331d875 100644
--- a/engines/gob/video.h
+++ b/engines/gob/video.h
@@ -112,8 +112,6 @@ public:
void setPalette(PalDesc * palDesc);
void setFullPalette(PalDesc * palDesc);
void initPrimary(int16 mode);
- char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight, int16 x,
- int16 y, int16 transp, SurfaceDesc * destDesc);
void freeDriver(void);
void setHandlers();
@@ -121,6 +119,8 @@ public:
int16 color1, int16 color2, int16 transp, SurfaceDesc * dest) = 0;
virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags) = 0;
virtual void waitRetrace(int16) = 0;
+ virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
+ int16 x, int16 y, int16 transp, SurfaceDesc * destDesc) = 0;
protected:
class VideoDriver *_videoDriver;
@@ -135,6 +135,8 @@ public:
int16 color1, int16 color2, int16 transp, SurfaceDesc * dest);
virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags);
virtual void waitRetrace(int16);
+ virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
+ int16 x, int16 y, int16 transp, SurfaceDesc * destDesc);
Video_v1(GobEngine *vm);
virtual ~Video_v1() {};
@@ -146,6 +148,8 @@ public:
int16 color1, int16 color2, int16 transp, SurfaceDesc * dest);
virtual SurfaceDesc *initSurfDesc(int16 vidMode, int16 width, int16 height, int16 flags);
virtual void waitRetrace(int16);
+ virtual char spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
+ int16 x, int16 y, int16 transp, SurfaceDesc * destDesc);
Video_v2(GobEngine *vm);
virtual ~Video_v2() {};
diff --git a/engines/gob/video_v1.cpp b/engines/gob/video_v1.cpp
index cafea57d1e..61b565bcc4 100644
--- a/engines/gob/video_v1.cpp
+++ b/engines/gob/video_v1.cpp
@@ -113,4 +113,133 @@ Video::SurfaceDesc *Video_v1::initSurfDesc(int16 vidMode, int16 width, int16 hei
return descPtr;
}
+char Video_v1::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
+ int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) {
+ SurfaceDesc sourceDesc;
+ byte *memBuffer;
+ byte *srcPtr;
+ byte *destPtr;
+ byte *linePtr;
+ byte temp;
+ uint16 sourceLeft;
+ int16 curWidth;
+ int16 curHeight;
+ int16 offset;
+ int16 counter2;
+ uint16 cmdVar;
+ int16 bufPos;
+ int16 strLen;
+
+ if (!destDesc)
+ return 1;
+
+ if ((destDesc->vidMode & 0x7f) != 0x13)
+ error("Video::spriteUncompressor: Video mode 0x%x is not supported!",
+ destDesc->vidMode & 0x7f);
+
+ if (sprBuf[0] != 1)
+ return 0;
+
+ if (sprBuf[1] != 2)
+ return 0;
+
+ if (sprBuf[2] == 2) {
+ sourceDesc.width = srcWidth;
+ sourceDesc.height = srcHeight;
+ sourceDesc.vidMode = 0x93;
+ sourceDesc.vidPtr = sprBuf + 3;
+ Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1,
+ srcHeight - 1, x, y, transp);
+ return 1;
+ } else {
+ memBuffer = new byte[4114];
+ if (memBuffer == 0)
+ return 0;
+
+ srcPtr = sprBuf + 3;
+ sourceLeft = READ_LE_UINT16(srcPtr);
+
+ destPtr = destDesc->vidPtr + destDesc->width * y + x;
+
+ curWidth = 0;
+ curHeight = 0;
+
+ linePtr = destPtr;
+ srcPtr += 4;
+
+ for (offset = 0; offset < 4078; offset++)
+ memBuffer[offset] = 0x20;
+
+ cmdVar = 0;
+ bufPos = 4078;
+ while (1) {
+ cmdVar >>= 1;
+ if ((cmdVar & 0x100) == 0) {
+ cmdVar = *srcPtr | 0xff00;
+ srcPtr++;
+ }
+ if ((cmdVar & 1) != 0) {
+ temp = *srcPtr++;
+ if (temp != 0 || transp == 0)
+ *destPtr = temp;
+ destPtr++;
+ curWidth++;
+ if (curWidth >= srcWidth) {
+ curWidth = 0;
+ linePtr += destDesc->width;
+ destPtr = linePtr;
+ curHeight++;
+ if (curHeight >= srcHeight)
+ break;
+ }
+ sourceLeft--;
+ if (sourceLeft == 0)
+ break;
+
+ memBuffer[bufPos] = temp;
+ bufPos++;
+ bufPos %= 4096;
+ } else {
+ offset = *srcPtr;
+ srcPtr++;
+ offset |= (*srcPtr & 0xf0) << 4;
+ strLen = (*srcPtr & 0x0f) + 3;
+ srcPtr++;
+
+ for (counter2 = 0; counter2 < strLen;
+ counter2++) {
+ temp =
+ memBuffer[(offset +
+ counter2) % 4096];
+ if (temp != 0 || transp == 0)
+ *destPtr = temp;
+ destPtr++;
+
+ curWidth++;
+ if (curWidth >= srcWidth) {
+ curWidth = 0;
+ linePtr += destDesc->width;
+ destPtr = linePtr;
+ curHeight++;
+ if (curHeight >= srcHeight) {
+ delete[] memBuffer;
+ return 1;
+ }
+ }
+ sourceLeft--;
+ if (sourceLeft == 0) {
+ delete[] memBuffer;
+ return 1;
+ }
+ memBuffer[bufPos] = temp;
+ bufPos++;
+ bufPos %= 4096;
+ }
+ }
+ }
+ }
+ delete[] memBuffer;
+ return 1;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/video_v2.cpp b/engines/gob/video_v2.cpp
index 8e55154dde..cad6937c0b 100644
--- a/engines/gob/video_v2.cpp
+++ b/engines/gob/video_v2.cpp
@@ -154,4 +154,153 @@ Video::SurfaceDesc *Video_v2::initSurfDesc(int16 vidMode, int16 width, int16 hei
return descPtr;
}
+char Video_v2::spriteUncompressor(byte *sprBuf, int16 srcWidth, int16 srcHeight,
+ int16 x, int16 y, int16 transp, SurfaceDesc *destDesc) {
+ SurfaceDesc sourceDesc;
+ byte *memBuffer;
+ byte *srcPtr;
+ byte *destPtr;
+ byte *linePtr;
+ byte temp;
+ uint32 sourceLeft;
+ int16 curWidth;
+ int16 curHeight;
+ int16 offset;
+ int16 counter2;
+ uint16 cmdVar;
+ int16 bufPos;
+ int16 strLen;
+
+ if (!destDesc)
+ return 1;
+
+ if ((destDesc->vidMode & 0x7f) != 0x13)
+ error("Video::spriteUncompressor: Video mode 0x%x is not supported!",
+ destDesc->vidMode & 0x7f);
+
+ if (sprBuf[0] != 1)
+ return 0;
+
+ if (sprBuf[1] != 2)
+ return 0;
+
+ if (sprBuf[2] == 2) {
+ sourceDesc.width = srcWidth;
+ sourceDesc.height = srcHeight;
+ sourceDesc.vidMode = 0x93;
+ sourceDesc.vidPtr = sprBuf + 3;
+ Video::drawSprite(&sourceDesc, destDesc, 0, 0, srcWidth - 1,
+ srcHeight - 1, x, y, transp);
+ return 1;
+ } else if (sprBuf[2] == 1) {
+ memBuffer = new byte[4370];
+ if (memBuffer == 0)
+ return 0;
+
+ srcPtr = sprBuf + 3;
+ sourceLeft = READ_LE_UINT32(srcPtr);
+
+ // TODO: Needed until wide/scrolling surfaces are supported...
+ if ((x + srcWidth) >= destDesc->width)
+ x = 0;
+ if ((y + srcHeight) >= destDesc->height)
+ y = 0;
+
+ destPtr = destDesc->vidPtr + destDesc->width * y + x;
+
+ curWidth = 0;
+ curHeight = 0;
+
+ linePtr = destPtr;
+ srcPtr += 4;
+
+ int16 var_2E = 0;
+ int16 var_2F;
+ if ((READ_LE_UINT16(srcPtr + 2) == 0x5678) && (READ_LE_UINT16(srcPtr) != 0x1234)) {
+ srcPtr += 4;
+ bufPos = 273;
+ var_2F = 18;
+ } else {
+ var_2F = 100;
+ bufPos = 4078;
+ }
+ if (transp == 0)
+ var_2E = 300;
+ else
+ var_2E = 0;
+
+ cmdVar = 0;
+ while (1) {
+ cmdVar >>= 1;
+ if ((cmdVar & 0x100) == 0) {
+ cmdVar = *srcPtr | 0xff00;
+ srcPtr++;
+ }
+ if ((cmdVar & 1) != 0) {
+ temp = *srcPtr++;
+ if (temp != var_2E)
+ *destPtr = temp;
+ destPtr++;
+ curWidth++;
+ if (curWidth >= srcWidth) {
+ curWidth = 0;
+ linePtr += destDesc->width;
+ destPtr = linePtr;
+ curHeight++;
+ if (curHeight >= srcHeight)
+ break;
+ }
+ sourceLeft--;
+ memBuffer[bufPos] = temp;
+ bufPos++;
+ bufPos %= 4096;
+ if (sourceLeft == 0)
+ break;
+ } else {
+ offset = *srcPtr++;
+ offset |= (*srcPtr & 0xf0) << 4;
+ strLen = (*srcPtr & 0x0f) + 3;
+ *srcPtr++;
+ if (strLen == var_2F)
+ strLen = *srcPtr++ + 18;
+
+ for (counter2 = 0; counter2 < strLen;
+ counter2++) {
+ temp = memBuffer[(offset + counter2) % 4096];
+ if (temp != var_2E)
+ *destPtr = temp;
+ destPtr++;
+
+ curWidth++;
+ if (curWidth >= srcWidth) {
+ curWidth = 0;
+ linePtr += destDesc->width;
+ destPtr = linePtr;
+ curHeight++;
+ if (curHeight >= srcHeight) {
+ delete[] memBuffer;
+ return 1;
+ }
+ }
+ memBuffer[bufPos] = temp;
+ bufPos++;
+ bufPos %= 4096;
+ }
+ // loc_1D4E4
+
+ if (strLen < (int32) sourceLeft)
+ sourceLeft--;
+ else {
+ delete[] memBuffer;
+ return 1;
+ }
+ }
+ }
+ } else
+ return 0;
+
+ delete[] memBuffer;
+ return 1;
+}
+
} // End of namespace Gob