aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorSven Hesse2006-05-29 18:24:52 +0000
committerSven Hesse2006-05-29 18:24:52 +0000
commitd6f1ba1540d60d374121244565a08a9c77670e5b (patch)
tree26ca285e2690fcdd78f4870d8ff1a07fa8dd9367 /engines/gob
parente1844e485f19d5abb260b5eb821f9ce38658b2ad (diff)
downloadscummvm-rg350-d6f1ba1540d60d374121244565a08a9c77670e5b.tar.gz
scummvm-rg350-d6f1ba1540d60d374121244565a08a9c77670e5b.tar.bz2
scummvm-rg350-d6f1ba1540d60d374121244565a08a9c77670e5b.zip
- More GOB2 map conversions
- Added Music_Dummy (for --music-driver=null) - Implemented IMDs. That took longer than I expected... On the bright side, Ween's intro now plays more correctly svn-id: r22754
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/anim.h2
-rw-r--r--engines/gob/dataio.cpp4
-rw-r--r--engines/gob/dataio.h1
-rw-r--r--engines/gob/game.cpp848
-rw-r--r--engines/gob/game.h57
-rw-r--r--engines/gob/gob.cpp11
-rw-r--r--engines/gob/goblin.cpp189
-rw-r--r--engines/gob/goblin.h6
-rw-r--r--engines/gob/goblin_v1.cpp21
-rw-r--r--engines/gob/goblin_v2.cpp41
-rw-r--r--engines/gob/inter.cpp14
-rw-r--r--engines/gob/inter.h10
-rw-r--r--engines/gob/inter_v1.cpp17
-rw-r--r--engines/gob/inter_v2.cpp133
-rw-r--r--engines/gob/map.cpp149
-rw-r--r--engines/gob/map.h63
-rw-r--r--engines/gob/map_v1.cpp67
-rw-r--r--engines/gob/map_v2.cpp121
-rw-r--r--engines/gob/module.mk2
-rw-r--r--engines/gob/mult.cpp6
-rw-r--r--engines/gob/mult.h17
-rw-r--r--engines/gob/mult_v2.cpp7
-rw-r--r--engines/gob/music.cpp24
-rw-r--r--engines/gob/music.h37
-rw-r--r--engines/gob/scenery.cpp224
-rw-r--r--engines/gob/scenery.h27
-rw-r--r--engines/gob/scenery_v1.cpp244
-rw-r--r--engines/gob/scenery_v2.cpp251
-rw-r--r--engines/gob/sound.cpp2
-rw-r--r--engines/gob/util.cpp6
30 files changed, 2012 insertions, 589 deletions
diff --git a/engines/gob/anim.h b/engines/gob/anim.h
index f5252364b9..f4d255e590 100644
--- a/engines/gob/anim.h
+++ b/engines/gob/anim.h
@@ -23,6 +23,8 @@
#ifndef GOB_ANIM_H
#define GOB_ANIM_H
+#include "gob/video.h"
+
namespace Gob {
class Anim {
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp
index b862302492..da61f7b187 100644
--- a/engines/gob/dataio.cpp
+++ b/engines/gob/dataio.cpp
@@ -317,6 +317,10 @@ void DataIO::seekData(int16 handle, int32 pos, int16 from) {
file_getHandle(handle)->seek(pos, from);
}
+int32 DataIO::getPos(int16 handle) {
+ return file_getHandle(handle)->pos();
+}
+
int32 DataIO::getDataSize(const char *name) {
char buf[128];
int32 chunkSz;
diff --git a/engines/gob/dataio.h b/engines/gob/dataio.h
index 9b28adfd10..a2b27e98c4 100644
--- a/engines/gob/dataio.h
+++ b/engines/gob/dataio.h
@@ -55,6 +55,7 @@ public:
int16 openData(const char *path, Common::File::AccessMode mode = Common::File::kFileReadMode);
int32 readData(int16 handle, char *buf, int16 size);
void seekData(int16 handle, int32 pos, int16 from);
+ int32 getPos(int16 handle);
int32 getDataSize(const char *name);
char *getData(const char *path);
char *getSmallData(const char *path);
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index adfaec9c4c..5bf3c289e4 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -39,6 +39,7 @@
#include "gob/goblin.h"
#include "gob/cdrom.h"
#include "gob/music.h"
+#include "gob/palanim.h"
namespace Gob {
@@ -107,13 +108,28 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_curTotFileArray[i][0] = 0;
}
- warning("GOB2 Stub! _byte_2FC9B, _word_2FC9C, _word_2FC9E, _word_2E51F, _off_2E51B, _off_2E517");
+ _imdFile = 0;
+ _curImdFile[0] = 0;
+ _imdX = 0;
+ _imdY = 0;
+ _imdFrameDataSize = 0;
+ _imdVidBufferSize = 0;
+ _imdFrameData = 0;
+ _imdVidBuffer = 0;
+
+ warning("GOB2 Stub! _byte_2FC82, _byte_2FC83, _word_2FC80");
+ _byte_2FC82 = 0;
+ _byte_2FC83 = 0;
+ _word_2FC80 = 0;
+
+ warning("GOB2 Stub! _byte_2FC9B, _word_2FC9C, _word_2FC9E, _word_2E51F, _off_2E51B, _off_2E517, _dword_2F2B6");
_byte_2FC9B = 0;
_word_2FC9C = 0;
_word_2FC9E = 0;
_word_2E51F = 0;
_off_2E51B = 0;
_off_2E517 = 0;
+ _dword_2F2B6 = 0;
}
char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight) {
@@ -1650,6 +1666,7 @@ void Game::collAreaSub(int16 index, int8 enter) {
}
}
+// "DEVinitscreen"
void Game::sub_ADD2(void) {
_word_2FC9C = 0;
_word_2FC9E = 0;
@@ -1687,6 +1704,7 @@ void Game::sub_ADD2(void) {
}*/
}
+// "DEVclosescreen"
void Game::sub_BB28(void) {
_vm->_draw->freeSprite(23);
_vm->_video->freeSurfDesc(_vm->_draw->_cursorBack);
@@ -1748,4 +1766,832 @@ Snd::SoundDesc *Game::loadSND(const char *path, int8 arg_4) {
return soundDesc;
}
+int8 Game::openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags) {
+ int i;
+ int j;
+ const char *src;
+ byte *vidMem;
+ Video::SurfaceDesc *surfDesc;
+
+ if (path[0] != 0) {
+ if (_imdFile == 0)
+ _curImdFile[0] = 0;
+
+ src = strrchr(path, '\\');
+ src = src == 0 ? path : src+1;
+
+ if (strcmp(_curImdFile, src) != 0) {
+ closeImd();
+ _imdFile = loadImdFile(path, 0, 2);
+ if (_imdFile == 0)
+ return 0;
+
+ _imdX = _imdFile->x;
+ _imdY = _imdFile->y;
+ strcpy(_curImdFile, src);
+ _imdFrameData = new byte[_imdFrameDataSize + 1000];
+ _imdVidBuffer = new byte[_imdVidBufferSize + 1000];
+ memset(_imdFrameData, 0, _imdFrameDataSize + 1000);
+ memset(_imdVidBuffer, 0, _imdVidBufferSize + 1000);
+
+ if (_vm->_video->_extraMode) {
+ _byte_2FC83 = (flags & 0x80) ? 1 : 0;
+ if (!(_imdFile->field_E & 0x100) || (_imdFile->field_E & 0x2000)) {
+ setImdXY(_imdFile, 0, 0);
+ _imdFile->surfDesc =
+ _vm->_video->initSurfDesc(0x13, _imdFile->width, _imdFile->height, 0);
+ } else {
+ if (_byte_2FC82 == 0)
+ _imdFile->surfDesc = _vm->_draw->_spritesArray[21];
+ else
+ _imdFile->surfDesc = _vm->_draw->_spritesArray[20];
+ if ((x != -1) || (y != -1)) {
+ _imdX = x != -1 ? x : _imdX;
+ _imdY = y != -1 ? y : _imdY;
+ setImdXY(_imdFile, _imdX, _imdY);
+ }
+ }
+ if (flags & 0x40) {
+ _imdX = x != -1 ? x : _imdX;
+ _imdY = y != -1 ? y : _imdY;
+ if (_vm->_video->_extraMode && ((_imdFile->surfDesc->vidMode & 0x7F) == 0x13)) {
+ surfDesc = _vm->_video->initSurfDesc(0x13, _imdFile->width, _imdFile->height, 0);
+ _vm->_video->drawSprite(_vm->_draw->_spritesArray[21], surfDesc, _imdX, _imdY,
+ _imdX + _imdFile->width - 1, _imdY + _imdFile->height - 1, 0, 0, 0);
+ vidMem = _imdFile->surfDesc->vidPtr;
+ for (i = 0; i < _imdFile->height; i++)
+ for (j = 0; j < _imdFile->width; j++, vidMem++) {
+ *(vidMem) = *(surfDesc->vidPtr
+ + (j / 4)
+ + (surfDesc->width / 4 * i)
+ + (surfDesc->reserved2 * (j & 3)));
+ }
+ _vm->_video->freeSurfDesc(surfDesc);
+ }
+ }
+ } else {
+ if ((x != -1) || (y != -1)) {
+ _imdX = x != -1 ? x : _imdX;
+ _imdY = y != -1 ? y : _imdY;
+ setImdXY(_imdFile, _imdX, _imdY);
+ }
+ _byte_2FC83 = (flags & 0x80) ? 1 : 0;
+ if (_byte_2FC83 == 0)
+ _imdFile->surfDesc = _vm->_draw->_spritesArray[21];
+ else
+ _imdFile->surfDesc = _vm->_draw->_spritesArray[20];
+ }
+ }
+ }
+
+ if (_imdFile == 0)
+ return 0;
+
+ if (repeat == -1) {
+ closeImd();
+ return 0;
+ }
+
+ _imdX = x != -1 ? x : _imdX;
+ _imdY = y != -1 ? y : _imdY;
+
+ WRITE_VAR(7, _imdFile->framesCount);
+
+ return 1;
+}
+
+void Game::closeImd(void) {
+ if (_imdFile == 0)
+ return;
+
+ if ((_imdFile->surfDesc != _vm->_draw->_spritesArray[20]) &&
+ (_imdFile->surfDesc != _vm->_draw->_spritesArray[21]))
+ _vm->_video->freeSurfDesc(_imdFile->surfDesc);
+
+ finishImd(_imdFile);
+
+ delete[] _imdFrameData;
+ delete[] _imdVidBuffer;
+ _imdFrameData = 0;
+ _imdVidBuffer = 0;
+
+ _imdFile = 0;
+}
+
+void Game::finishImd(Game::Imd *imdPtr) {
+ if (imdPtr == 0)
+ return;
+
+/*
+ if (dword_31345 != 0) {
+ _vm->_sound->stopSound(0);
+ dword_31345 = 0;
+ delete off_31461;
+ byte_31344 = 0;
+ }
+*/
+
+ _vm->_dataio->closeData(imdPtr->fileHandle);
+
+ if (imdPtr->frameCoords != 0)
+ delete[] imdPtr->frameCoords;
+ if (imdPtr->palette != 0)
+ delete[] imdPtr->palette;
+ if (imdPtr->framesPos != 0)
+ delete[] imdPtr->framesPos;
+
+ delete imdPtr;
+ imdPtr = 0;
+}
+
+// flagsBit: 0 = read and set palette
+// 1 = read palette
+Game::Imd *Game::loadImdFile(const char *path, Video::SurfaceDesc *surfDesc, int8 flags) {
+ int i;
+ Imd *imdPtr;
+ int16 handle;
+ int16 setAllPalBak;
+ char buf[18];
+ Video::Color *palBak;
+
+ int32 byte_31449 = 0;
+ int32 byte_3144D = 0;
+
+ buf[0] = 0;
+ strcpy(buf, path);
+ strcat(buf, ".IMD");
+
+ handle = _vm->_dataio->openData(buf);
+
+ if (handle < 0) {
+ warning("Can't open IMD \"%s\"", buf);
+ return 0;
+ }
+
+ imdPtr = new Imd;
+ memset(imdPtr, 0, sizeof(Imd));
+
+ imdPtr->palette = 0;
+
+ _vm->_dataio->readData(handle, buf, 18);
+
+ // "fileHandle" holds the major version while loading
+ imdPtr->fileHandle = READ_LE_UINT16(buf);
+ imdPtr->verMin = READ_LE_UINT16(buf + 2);
+ imdPtr->framesCount = READ_LE_UINT16(buf + 4);
+ imdPtr->x = READ_LE_UINT16(buf + 6);
+ imdPtr->y = READ_LE_UINT16(buf + 8);
+ imdPtr->width = READ_LE_UINT16(buf + 10);
+ imdPtr->height = READ_LE_UINT16(buf + 12);
+ imdPtr->field_E = READ_LE_UINT16(buf + 14);
+ imdPtr->curFrame = READ_LE_UINT16(buf + 16);
+
+ if (imdPtr->fileHandle != 0)
+ imdPtr->verMin = 0;
+
+ if ((imdPtr->verMin & 0xFF) < 2) {
+ warning("IMD version incorrect (%d,%d)", imdPtr->fileHandle, imdPtr->verMin);
+ _vm->_dataio->closeData(handle);
+ delete imdPtr;
+ return 0;
+ }
+
+ imdPtr->surfDesc = surfDesc;
+ imdPtr->framesPos = 0;
+ imdPtr->firstFramePos = imdPtr->curFrame;
+
+ if (flags & 3) {
+ imdPtr->palette = new Video::Color[256];
+ _vm->_dataio->readData(handle, (char *) imdPtr->palette, 768);
+ } else {
+ _vm->_dataio->seekData(handle, 768, 1);
+ imdPtr->palette = 0;
+ }
+ if ((flags & 3) == 1) {
+ palBak = _vm->_global->_pPaletteDesc->vgaPal;
+ setAllPalBak = _vm->_global->_setAllPalette;
+ _vm->_global->_pPaletteDesc->vgaPal = imdPtr->palette;
+ _vm->_global->_setAllPalette = 1;
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+ _vm->_global->_setAllPalette = setAllPalBak;
+ _vm->_global->_pPaletteDesc->vgaPal = palBak;
+ }
+
+ if ((imdPtr->verMin & 0xFF) >= 3) {
+ _vm->_dataio->readData(handle, buf, 2);
+ imdPtr->stdX = READ_LE_UINT16(buf);
+ if (imdPtr->stdX > 1) {
+ warning("IMD ListI incorrect (%d)", imdPtr->stdX);
+ _vm->_dataio->closeData(handle);
+ delete imdPtr;
+ return 0;
+ }
+ if(imdPtr->stdX != 0) {
+ _vm->_dataio->readData(handle, buf, 8);
+ imdPtr->stdX = READ_LE_UINT16(buf);
+ imdPtr->stdY = READ_LE_UINT16(buf + 2);
+ imdPtr->stdWidth = READ_LE_UINT16(buf + 4);
+ imdPtr->stdHeight = READ_LE_UINT16(buf + 6);
+ } else
+ imdPtr->stdX = -1;
+ } else
+ imdPtr->stdX = -1;
+
+ if ((imdPtr->verMin & 0xFF) >= 4) {
+ _vm->_dataio->readData(handle, buf, 4);
+ byte_31449 = READ_LE_UINT32(buf);
+ imdPtr->framesPos = byte_31449 == 0 ? 0 : new int32[imdPtr->framesCount];
+ } else
+ imdPtr->framesPos = 0;
+
+ if (imdPtr->verMin & 0x8000) {
+ _vm->_dataio->readData(handle, buf, 4);
+ byte_3144D = READ_LE_UINT32(buf);
+ }
+
+ if (imdPtr->verMin & 0x4000) {
+ // loc_29C4F
+ error("GOB2 Stub! loadImdFile, imdPtr->verMin & 0x4000");
+ // Sound stuff, I presume...
+ }
+
+ if (imdPtr->verMin & 0x2000) {
+ _vm->_dataio->readData(handle, buf, 4);
+ imdPtr->frameDataSize = READ_LE_UINT16(buf);
+ imdPtr->vidBufferSize = READ_LE_UINT16(buf + 2);
+ } else {
+ imdPtr->frameDataSize = imdPtr->width * imdPtr->height + 1000;
+ imdPtr->vidBufferSize = imdPtr->width * imdPtr->height + 1000;
+ }
+
+ if (imdPtr->framesPos != 0) {
+ _vm->_dataio->seekData(handle, byte_31449, 0);
+ for (i = 0; i < imdPtr->framesCount; i++) {
+ _vm->_dataio->readData(handle, buf, 4);
+ imdPtr->framesPos[i] = READ_LE_UINT32(buf);
+ }
+ }
+
+ if (imdPtr->verMin & 0x8000) {
+ _vm->_dataio->seekData(handle, byte_3144D, 0);
+ imdPtr->frameCoords = new ImdCoord[imdPtr->framesCount];
+ for (i = 0; i < imdPtr->framesCount; i++) {
+ _vm->_dataio->readData(handle, buf, 8);
+ imdPtr->frameCoords[i].left = READ_LE_UINT16(buf);
+ imdPtr->frameCoords[i].top = READ_LE_UINT16(buf + 2);
+ imdPtr->frameCoords[i].right = READ_LE_UINT16(buf + 4);
+ imdPtr->frameCoords[i].bottom = READ_LE_UINT16(buf + 6);
+ }
+ } else
+ imdPtr->frameCoords = 0;
+
+ _vm->_dataio->seekData(handle, imdPtr->firstFramePos, 0);
+ imdPtr->curFrame = 0;
+ imdPtr->fileHandle = handle;
+ imdPtr->filePos = imdPtr->firstFramePos;
+ _imdFrameDataSize = imdPtr->frameDataSize;
+ _imdVidBufferSize = imdPtr->vidBufferSize;
+ if (flags & 0x80) {
+ imdPtr->verMin |= 0x1000;
+ warning("GOB2 Stub! loadImdFile(), flags & 0x80");
+ }
+
+ return imdPtr;
+}
+
+void Game::setImdXY(Game::Imd *imdPtr, int16 x, int16 y) {
+ int i;
+
+ if (imdPtr->stdX != -1) {
+ imdPtr->stdX = imdPtr->stdX - imdPtr->x + x;
+ imdPtr->stdY = imdPtr->stdY - imdPtr->y + y;
+ }
+
+ if (imdPtr->frameCoords != 0) {
+ for (i = 0; i < imdPtr->framesCount; i++) {
+ imdPtr->frameCoords[i].left -= imdPtr->frameCoords[i].left - imdPtr->x + x;
+ imdPtr->frameCoords[i].top -= imdPtr->frameCoords[i].top - imdPtr->y + y;
+ imdPtr->frameCoords[i].right -= imdPtr->frameCoords[i].right - imdPtr->x + x;
+ imdPtr->frameCoords[i].bottom -= imdPtr->frameCoords[i].bottom - imdPtr->y + y;
+ }
+ }
+
+ imdPtr->x = x;
+ imdPtr->y = y;
+}
+
+void Game::playImd(int16 frame, int16 arg_2, int16 arg_4, int16 arg_6, int16 arg_8, int16 lastFrame) {
+ int16 var_1;
+ int16 var_4 = 0;
+ byte *vidMemBak;
+ Video::SurfaceDesc *surfDescBak;
+ Video::SurfaceDesc frontSurfBak;
+
+ int8 byte_31344 = 0;
+
+ if ((frame < 0) || (frame > lastFrame))
+ return;
+
+ if ((frame == arg_8) || ((frame == lastFrame) && (arg_2 == 8))) { // loc_1C3F0
+ var_1 = 1;
+ _vm->_draw->_applyPal = 0;
+ if (arg_2 >= 4) {
+ if (arg_4 != -1)
+ memcpy( ((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + arg_4 * 3,
+ ((char *) (_imdFile->palette)) + arg_4 * 3, (arg_6 - arg_4 + 1) * 3);
+ else
+ memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, (char *) _imdFile->palette, 768);
+ }
+ } else
+ var_1 = 0;
+
+ if ((var_1 == 1) && (arg_2 == 8) && (_byte_2FC83 != 0))
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+ if (_vm->_video->_extraMode && (_imdFile->surfDesc->vidMode == 0x13)) {
+ if ((_byte_2FC82 != 0) && (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr)) {
+ vidMemBak = _vm->_draw->_spritesArray[20]->vidPtr;
+ _vm->_draw->_spritesArray[20]->vidPtr = _vm->_draw->_spritesArray[21]->vidPtr;
+ var_4 = viewImd(_imdFile, frame);
+ _vm->_draw->_spritesArray[20]->vidPtr = vidMemBak;
+ } else
+ var_4 = viewImd(_imdFile, frame);
+ if (_byte_2FC82 == 0) {
+ if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1))
+ _vm->_draw->invalidateRect(_imdX, _imdY,
+ _imdX + _imdFile->width - 1, _imdY + _imdFile->height - 1);
+ else
+ _vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left,
+ _imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right,
+ _imdFile->frameCoords[frame].bottom);
+ }
+ } else {
+ if ((_imdFile->field_E & 0x100) && (_vm->_video->_extraMode) &&
+ (_byte_2FC82 != 0) && (sub_2C825(_imdFile) & 0x8000) && (_byte_2FC83 == 0)) {
+ surfDescBak = _imdFile->surfDesc;
+ if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr)
+ _imdFile->surfDesc = _vm->_draw->_spritesArray[21];
+ else
+ _imdFile->surfDesc = _vm->_draw->_spritesArray[20];
+ setImdXY(_imdFile, _imdX, _imdY);
+ var_4 = viewImd(_imdFile, frame);
+ _imdFile->surfDesc = surfDescBak;
+ setImdXY(_imdFile, 0, 0);
+ } else {
+ var_4 = viewImd(_imdFile, frame);
+ if (!(var_4 & 0x800)) {
+ if (_byte_2FC83 == 0) {
+ if (_vm->_video->_extraMode) {
+ if (_byte_2FC82 == 0) {
+ memcpy((char *) &frontSurfBak, (char *) &_vm->_draw->_frontSurface,
+ sizeof(Video::SurfaceDesc));
+ memcpy((char *) &_vm->_draw->_frontSurface, (char *) &_vm->_draw->_spritesArray[21],
+ sizeof(Video::SurfaceDesc));
+ imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+ memcpy((char *) &_vm->_draw->_frontSurface, (char *) &frontSurfBak,
+ sizeof(Video::SurfaceDesc));
+ if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1))
+ _vm->_draw->invalidateRect(_imdX, _imdY, _imdX + _imdFile->width - 1,
+ _imdY + _imdFile->height - 1);
+ else
+ _vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left,
+ _imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right,
+ _imdFile->frameCoords[frame].bottom);
+ } else {
+ if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr) { // loc_1C68D
+ memcpy((char *) &frontSurfBak, (char *) &_vm->_draw->_frontSurface,
+ sizeof(Video::SurfaceDesc));
+ memcpy((char *) &_vm->_draw->_frontSurface, (char *) &_vm->_draw->_spritesArray[21],
+ sizeof(Video::SurfaceDesc));
+ imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+ memcpy((char *) &_vm->_draw->_frontSurface, (char *) &frontSurfBak,
+ sizeof(Video::SurfaceDesc));
+ } else
+ imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+ }
+ } else {
+ if ((_imdFile->frameCoords == 0) || (_imdFile->frameCoords[frame].left == -1))
+ _vm->_draw->invalidateRect(_imdX, _imdY, _imdX + _imdFile->width - 1,
+ _imdY + _imdFile->height - 1);
+ else
+ _vm->_draw->invalidateRect(_imdFile->frameCoords[frame].left,
+ _imdFile->frameCoords[frame].top, _imdFile->frameCoords[frame].right,
+ _imdFile->frameCoords[frame].bottom);
+ }
+ } else
+ if (_vm->_video->_extraMode)
+ imdDrawFrame(_imdFile, frame, _imdX, _imdY);
+ }
+ }
+ }
+
+ if ((var_1 != 0) && (arg_2 == 16)) {
+ if ((_vm->_draw->_spritesArray[20] != _vm->_draw->_spritesArray[21]) && (_byte_2FC83 == 0))
+ _vm->_video->drawSprite(_vm->_draw->_spritesArray[21],
+ _vm->_draw->_spritesArray[20], 0, 0,
+ _vm->_draw->_spritesArray[21]->width - 1,
+ _vm->_draw->_spritesArray[21]->height - 1, 0, 0, 0);
+ _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0);
+ _vm->_draw->_noInvalidated = 1;
+ }
+ if ((var_1 != 0) && (arg_2 == 8) && (_byte_2FC83 == 0))
+ _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
+
+ if (!(var_4 & 0x800)) {
+ if (_vm->_draw->_cursorIndex == -1) {
+ if (_byte_2FC82 != 0) {
+ if (_word_2FC80 == _vm->_draw->_spritesArray[20]->vidPtr)
+ _word_2FC80 = _vm->_draw->_spritesArray[21]->vidPtr;
+ else
+ _word_2FC80 = _vm->_draw->_spritesArray[20]->vidPtr;
+ warning("GOB2 Stub! sub_1BC3A(_word_2FC80);");
+ } else
+ _vm->_draw->blitInvalidated();
+ } else
+ _vm->_draw->animateCursor(-1);
+ }
+
+ if ((var_1 != 0) && ((arg_2 == 2) || (arg_2 == 4)))
+ _vm->_palanim->fade(_vm->_global->_pPaletteDesc, -2, 0);
+
+ // To allow quitting, etc. during IMDs
+ _vm->_util->processInput();
+
+ if (byte_31344 != 2) {
+ if (var_4 & 0x800) {
+ if (_dword_2F2B6 == 0)
+ _vm->_util->delay(30);
+ else {
+ _dword_2F2B6 -= 30;
+ if (_dword_2F2B6 < 0)
+ _dword_2F2B6 = 0;
+ }
+ } else
+ _vm->_util->waitEndFrame();
+ }
+ _vm->_inter->animPalette();
+}
+
+int16 Game::viewImd(Game::Imd *imdPtr, int16 frame) {
+ int16 x;
+ int16 y;
+ int16 width;
+ int16 height;
+ int16 retVal;
+ uint32 tmp;
+ char buf[4];
+
+ int8 var_4;
+ int32 var_12 = 0;
+
+ // .---
+ int16 word_31451 = 0;
+ int8 byte_31344 = 0;
+ int8 byte_2DA60 = 0;
+ int16 word_2DA61 = -1;
+ // '---
+
+ word_31451 = 0;
+
+ if (imdPtr == 0)
+ return 0x8000;
+
+ retVal = 0;
+ var_4 = 0;
+
+ if (frame != imdPtr->curFrame) {
+ retVal |= 0x2000;
+ if (frame == 0)
+ imdPtr->filePos = imdPtr->firstFramePos;
+ else if (frame == 1) {
+ imdPtr->filePos = imdPtr->firstFramePos;
+ _vm->_dataio->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
+ _vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+ tmp = READ_LE_UINT16(buf);
+ imdPtr->filePos += tmp + 4;
+ } else if (imdPtr->framesPos != 0)
+ imdPtr->filePos = imdPtr->framesPos[frame];
+ else
+ error("Image %d innaccessible in IMD", frame);
+ imdPtr->curFrame = frame;
+ _vm->_dataio->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
+ }
+
+ x = imdPtr->x;
+ y = imdPtr->y;
+ width = imdPtr->width;
+ height = imdPtr->height;
+
+ do {
+ if (frame != 0) {
+ if (imdPtr->stdX != -1) {
+ imdPtr->x = imdPtr->stdX;
+ imdPtr->y = imdPtr->stdY;
+ imdPtr->width = imdPtr->stdWidth;
+ imdPtr->height = imdPtr->stdHeight;
+ retVal |= 0x1000;
+ }
+ if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1)) {
+ var_4 |= 0x400;
+ imdPtr->x = imdPtr->frameCoords[frame].left;
+ imdPtr->y = imdPtr->frameCoords[frame].top;
+ imdPtr->width = imdPtr->frameCoords[frame].right - imdPtr->x + 1;
+ imdPtr->height = imdPtr->frameCoords[frame].bottom - imdPtr->y + 1;
+ }
+ }
+
+ _vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+ tmp = READ_LE_UINT16(buf);
+
+ imdPtr->filePos += 2;
+
+ if ((tmp & 0xFFF8) == 0xFFF0) {
+ if (tmp == 0xFFF0) {
+ _vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+ tmp = READ_LE_UINT16(buf);
+ if (var_4 == 0)
+ word_31451 = tmp;
+ _vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+ tmp = READ_LE_UINT16(buf);
+ imdPtr->filePos += 4;
+ } else if (tmp == 0xFFF1) {
+ retVal = 0x8000;
+ continue;
+ } else if (tmp == 0xFFF2) {
+ _vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+ tmp = READ_LE_UINT16(buf);
+ imdPtr->filePos += 2;
+ _vm->_dataio->seekData(imdPtr->fileHandle, tmp, 1);
+ imdPtr->filePos += tmp;
+ retVal = 0x8000;
+ continue;
+ } else if (tmp == 0xFFF3) {
+ _vm->_dataio->readData(imdPtr->fileHandle, buf, 4);
+ tmp = READ_LE_UINT32(buf);
+ imdPtr->filePos += 4;
+ _vm->_dataio->seekData(imdPtr->fileHandle, tmp, 1);
+ imdPtr->filePos += tmp;
+ retVal = 0x8000;
+ continue;
+ }
+ }
+ if (byte_31344 != 0) {
+ if ((var_4 == 0) && (_vm->_global->_soundFlags & 0x14) && (byte_31344 == 2)) { // loc_2A503
+ var_12 = _vm->_util->getTimeKey();
+ warning("GOB2 Stub! viewImd, IMD sound stuff");
+ }
+ }
+ var_4 = 0;
+ if (tmp == 0xFFFD) {
+ _vm->_dataio->readData(imdPtr->fileHandle, buf, 2);
+ frame = READ_LE_UINT16(buf);
+ if ((imdPtr->framesPos != 0) && (byte_2DA60 == 0)) {
+ word_2DA61 = frame;
+ imdPtr->filePos = imdPtr->framesPos[frame];
+ _vm->_dataio->seekData(imdPtr->fileHandle, imdPtr->filePos, 0);
+ var_4 = 1;
+ retVal |= 0x200;
+ imdPtr->curFrame = frame;
+ } else
+ imdPtr->filePos += 2;
+ continue;
+ }
+ if (tmp != 0) {
+ imdPtr->filePos += tmp + 2;
+ if (byte_2DA60 != 0) {
+ _vm->_dataio->seekData(imdPtr->fileHandle, tmp + 2, 1);
+ } else {
+ _vm->_dataio->readData(imdPtr->fileHandle, (char *) _imdFrameData, tmp + 2);
+ retVal |= *_imdFrameData;
+ if (imdPtr->surfDesc == 0)
+ continue;
+ if (!(_vm->_video->_extraMode && (imdPtr->surfDesc->vidMode == 0x13))) // MODIFIED... NOT!
+ imdRenderFrame(imdPtr);
+ else
+ warning("GOB2 Stub! viedImd, sub_2C69A(imdPtr);");
+ }
+ } else
+ retVal |= 0x800;
+ } while(var_4 != 0);
+
+ if (byte_2DA60 != 0) {
+ byte_2DA60 = 0;
+ retVal |= 0x100;
+ }
+
+ imdPtr->x = x;
+ imdPtr->y = y;
+ imdPtr->width = width;
+ imdPtr->height = height;
+ imdPtr->curFrame++;
+
+ return retVal;
+}
+
+void Game::imdDrawFrame(Imd *imdPtr, int16 frame, int16 x, int16 y) {
+ // In the original asm, "sub_2C348" is called instead of Video::drawSprite();
+ // it basically just blits.
+
+ if (frame == 0)
+ _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, 0, 0,
+ imdPtr->width - 1, imdPtr->height - 1, x, y, 1);
+ else if ((imdPtr->frameCoords != 0) && (imdPtr->frameCoords[frame].left != -1))
+ _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface,
+ imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top,
+ imdPtr->frameCoords[frame].right, imdPtr->frameCoords[frame].bottom,
+ imdPtr->frameCoords[frame].left, imdPtr->frameCoords[frame].top, 1);
+ else if (imdPtr->stdX != -1)
+ _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface,
+ imdPtr->stdX, imdPtr->stdY, imdPtr->stdX + imdPtr->stdWidth - 1,
+ imdPtr->stdY + imdPtr->stdHeight - 1, x + imdPtr->stdX,
+ y + imdPtr->stdY, 1);
+ else
+ _vm->_video->drawSprite(imdPtr->surfDesc, _vm->_draw->_frontSurface, 0, 0,
+ imdPtr->width - 1, imdPtr->height - 1, x, y, 1);
+}
+
+void Game::imdRenderFrame(Imd *imdPtr) {
+ int i;
+ int16 imdX;
+ int16 imdY;
+ int16 imdW;
+ int16 imdH;
+ int16 sW;
+ uint16 pixCount, pixWritten;
+ uint8 type;
+ byte *imdVidMem;
+ byte *imdVidMemBak;
+ byte *dataPtr = 0;
+ byte *srcPtr = 0;
+ byte *srcPtrBak = 0;
+
+ dataPtr = (byte *) _imdFrameData;
+ imdX = imdPtr->x;
+ imdY = imdPtr->y;
+ imdW = imdPtr->width;
+ imdH = imdPtr->height;
+ sW = imdPtr->surfDesc->width;
+ imdVidMem = imdPtr->surfDesc->vidPtr + sW * imdY + imdX;
+
+ type = *dataPtr++;
+ srcPtr = dataPtr;
+
+ if (type & 0x10) {
+ type ^= 0x10;
+ dataPtr++; // => 0x3C8 |_ palette
+ dataPtr += 48; // => 0x3C9 | stuff
+ }
+
+ srcPtr = dataPtr;
+ if (type & 0x80) {
+ srcPtr = (byte *) _imdVidBuffer;
+ type &= 0x7F;
+ if ((type == 2) && (imdW == sW)) {
+ imdFrameUncompressor(imdVidMem, dataPtr);
+ return;
+ } else
+ imdFrameUncompressor(srcPtr, dataPtr);
+ }
+
+ if (type == 2) {
+ for (i = 0; i < imdH; i++) {
+ memcpy(imdVidMem, srcPtr, imdW);
+ srcPtr += imdW;
+ imdVidMem += sW;
+ }
+ } else if (type == 1) {
+ imdVidMemBak = imdVidMem;
+ for (i = 0; i < imdH; i++) {
+ pixWritten = 0;
+ while (pixWritten < imdW) {
+ pixCount = *srcPtr++;
+ if (pixCount & 0x80) {
+ pixCount = (pixCount & 0x7F) + 1;
+ // Just to be safe
+ pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
+ pixWritten += pixCount;
+ memcpy(imdVidMem, srcPtr, pixCount);
+ imdVidMem += pixCount;
+ srcPtr += pixCount;
+ } else {
+ pixCount = (pixCount + 1) % 256;
+ pixWritten += pixCount;
+ imdVidMem += pixCount;
+ }
+ }
+ imdVidMemBak += sW;
+ imdVidMem = imdVidMemBak;
+ }
+ } else if (type == 0x42) { // loc_2AFC4
+ warning("=> type == 0x42");
+ } else if ((type & 0xF) == 2) { // loc_2AFEC
+ warning("=> (type & 0xF) == 2");
+ } else { // loc_2B021
+ srcPtrBak = srcPtr;
+ for (i = 0; i < imdH; i += 2) {
+ pixWritten = 0;
+ while (pixWritten < imdW) {
+ pixCount = *srcPtr++;
+ if (pixCount & 0x80) {
+ pixCount = (pixCount & 0x7F) + 1;
+ // Just to be safe
+ pixCount = (pixWritten + pixCount) > imdW ? imdW - pixWritten : pixCount;
+ pixWritten += pixCount;
+ memcpy(imdVidMem, srcPtr, pixCount);
+ memcpy(imdVidMem + sW, srcPtr, pixCount);
+ imdVidMem += pixCount;
+ srcPtr += pixCount;
+ } else {
+ pixCount = (pixCount + 1) % 256;
+ pixWritten += pixCount;
+ imdVidMem += pixCount;
+ }
+ }
+ srcPtrBak += sW + sW;
+ srcPtr = srcPtrBak;
+ }
+ }
+}
+
+void Game::imdFrameUncompressor(byte *dest, byte *src) {
+ int i;
+ byte buf[4370];
+ int16 chunkLength;
+ int16 frameLength;
+ uint16 bufPos1;
+ uint16 bufPos2;
+ uint16 tmp;
+ uint8 chunkBitField;
+ uint8 chunkCount;
+ bool mode;
+
+ memset(buf, 0, sizeof(buf));
+
+ frameLength = READ_LE_UINT16(src);
+ src += 4;
+ bufPos1 = 4078;
+ mode = 0; // 275h (jnz +2)
+ if ((READ_LE_UINT16(src) == 0x1234) && (READ_LE_UINT16(src + 2) == 0x5678)) {
+ src += 4;
+ bufPos1 = 273;
+ mode = 1; // 123Ch (cmp al, 12h)
+ }
+ chunkCount = 1;
+ chunkBitField = 0;
+
+ while(frameLength > 0) {
+ chunkCount--;
+ if (chunkCount == 0) {
+ tmp = *src++;
+ chunkCount = 8;
+ chunkBitField = tmp;
+ }
+ if (chunkBitField % 2) {
+ chunkBitField >>= 1;
+ buf[bufPos1] = *src;
+ *dest++ = *src++;
+ bufPos1 = (bufPos1 + 1) % 4096;
+ frameLength--;
+ continue;
+ }
+ chunkBitField >>= 1;
+
+ tmp = READ_LE_UINT16(src);
+ src += 2;
+ chunkLength = ((tmp & 0xF00) >> 8) + 3;
+
+ if ((mode && ((chunkLength & 0xFF) == 0x12)) || (!mode && (chunkLength == 0)))
+ chunkLength = *src++ + 0x12;
+
+ bufPos2 = (tmp & 0xFF) + ((tmp >> 4) & 0x0F00);
+ if (((tmp + chunkLength) >= 4096) || ((chunkLength + bufPos1) >= 4096)) {
+ for (i = 0; i < chunkLength; i++, dest++) {
+ *dest = buf[bufPos2];
+ buf[bufPos1] = buf[bufPos2];
+ bufPos1 = (bufPos1 + 1) % 4096;
+ bufPos2 = (bufPos2 + 1) % 4096;
+ }
+ frameLength -= chunkLength;
+ } else if (((tmp + chunkLength) < bufPos1) || ((chunkLength + bufPos1) < bufPos2)) {
+ memcpy(dest, buf + bufPos2, chunkLength);
+ dest += chunkLength;
+ memmove(buf + bufPos1, buf + bufPos2, chunkLength);
+ bufPos1 += chunkLength;
+ bufPos2 += chunkLength;
+ frameLength -= chunkLength;
+ } else {
+ for (i = 0; i < chunkLength; i++, dest++, bufPos1++, bufPos2++) {
+ *dest = buf[bufPos2];
+ buf[bufPos1] = buf[bufPos2];
+ }
+ frameLength -= chunkLength;
+ }
+ }
+}
+
+int16 Game::sub_2C825(Imd *imdPtr) {
+ warning("GOB2 Stub! sub_2C825()");
+ return 0;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/game.h b/engines/gob/game.h
index 7e14a54091..f272ece7d3 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -94,6 +94,37 @@ public:
int16 frontColor;
char *ptr;
} GCC_PACK;
+
+ struct ImdCoord {
+ int16 left;
+ int16 top;
+ int16 right;
+ int16 bottom;
+ } GCC_PACK;
+
+ struct Imd {
+ int16 fileHandle;
+ int16 verMin;
+ int16 framesCount;
+ int16 x;
+ int16 y;
+ int16 width;
+ int16 height;
+ int16 field_E;
+ int16 curFrame;
+ Video::Color *palette;
+ Video::SurfaceDesc *surfDesc;
+ int32 *framesPos;
+ int32 firstFramePos;
+ int16 stdX;
+ int16 stdY;
+ int16 stdWidth;
+ int16 stdHeight;
+ int32 filePos;
+ ImdCoord *frameCoords;
+ int32 frameDataSize;
+ int32 vidBufferSize;
+ } GCC_PACK;
#pragma END_PACK_STRUCTS
TotResTable *_totResourceTable;
@@ -135,6 +166,18 @@ public:
char *_variablesArray[5];
char _curTotFileArray[5][14];
+ Imd *_imdFile;
+ char _curImdFile[15];
+ int16 _imdX;
+ int16 _imdY;
+ int16 _imdFrameDataSize;
+ int16 _imdVidBufferSize;
+ byte *_imdFrameData;
+ byte *_imdVidBuffer;
+ int8 _byte_2FC82;
+ int8 _byte_2FC83;
+ byte *_word_2FC80;
+
Game(GobEngine *vm);
virtual ~Game() {};
@@ -163,6 +206,18 @@ public:
char *loadLocTexts(void);
Snd::SoundDesc *loadSND(const char *path, int8 arg_4);
+ Imd *loadImdFile(const char *path, Video::SurfaceDesc *surfDesc, int8 flags);
+ int8 openImd(const char *path, int16 x, int16 y, int16 repeat, int16 flags);
+ void closeImd(void);
+ void finishImd(Imd *imdPtr);
+ void setImdXY(Imd *imdPtr, int16 x, int16 y);
+ void playImd(int16 arg_0, int16 arg_2, int16 arg_4, int16 arg_6, int16 arg_8, int16 arg_A);
+ int16 viewImd(Game::Imd *imdPtr, int16 arg_4);
+ void imdDrawFrame(Imd *imdPtr, int16 arg_4, int16 arg_6, int16 arg_8);
+ void imdRenderFrame(Imd *imdPtr);
+ void imdFrameUncompressor(byte *dest, byte *src);
+ int16 sub_2C825(Imd *imdPtr);
+
virtual void playTot(int16 skipPlay) = 0;
virtual void clearCollisions(void) = 0;
virtual void addNewCollision(int16 id, int16 left, int16 top, int16 right,
@@ -177,10 +232,12 @@ public:
int16 _word_2FC9C;
int16 _word_2FC9E;
int16 _word_2E51F;
+ int32 _dword_2F2B6;
Video::SurfaceDesc *_off_2E51B;
Video::SurfaceDesc *_off_2E517;
void sub_ADD2(void);
void sub_BB28(void);
+
protected:
int16 _lastCollKey;
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index fd6f67c601..61d64d6442 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -199,7 +199,6 @@ int GobEngine::init() {
_dataio = new DataIO(this);
_pack = new Pack();
_palanim = new PalAnim(this);
- _scenery = new Scenery(this);
_gtimer = new GTimer();
_util = new Util(this);
if (_features & Gob::GF_GOB1) {
@@ -212,6 +211,7 @@ int GobEngine::init() {
_init = new Init_v1(this);
_map = new Map_v1(this);
_goblin = new Goblin_v1(this);
+ _scenery = new Scenery_v1(this);
}
else if (_features & Gob::GF_GOB2) {
_inter = new Inter_v2(this);
@@ -223,11 +223,16 @@ int GobEngine::init() {
_init = new Init_v2(this);
_map = new Map_v2(this);
_goblin = new Goblin_v2(this);
+ _scenery = new Scenery_v2(this);
}
else
error("GobEngine::init(): Unknown version of game engine");
- if ((_features & Gob::GF_MAC) || (_features & Gob::GF_GOB1) || (_features & Gob::GF_GOB2))
- _music = new Music(this);
+ if ((_features & Gob::GF_MAC) || (_features & Gob::GF_GOB1) || (_features & Gob::GF_GOB2)) {
+ if (ConfMan.get("music_driver") == "null")
+ _music = new Music_Dummy(this);
+ else
+ _music = new Music(this);
+ }
_system->beginGFXTransaction();
initCommonGFX(false);
diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp
index 05bfe6fc5a..1e1c700f81 100644
--- a/engines/gob/goblin.cpp
+++ b/engines/gob/goblin.cpp
@@ -159,7 +159,6 @@ Goblin::Goblin(GobEngine *vm) : _vm(vm) {
_word_2F9BA = 0;
_dword_2F9B6 = 0;
_dword_2F9B2 = 0;
- _dword_2F2A4 = 0;
}
char Goblin::rotateState(int16 from, int16 to) {
@@ -633,8 +632,8 @@ void Goblin::switchGoblin(int16 index) {
else
next = index - 1;
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3 ||
- _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6)
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
+ _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6)
return;
if (_goblins[(_currentGoblin + 1) % 3]->type != 0 &&
@@ -686,7 +685,7 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
int16 deltaPix;
int16 i;
- if (_vm->_map->_passMap[_pressedMapY][_pressedMapX] == 0 &&
+ if (_vm->_map->getPass(_pressedMapX, _pressedMapY) == 0 &&
(_gobAction == 0
|| _vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0)) {
@@ -696,7 +695,7 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
for (i = 1;
i <= _pressedMapX
- && _vm->_map->_passMap[_pressedMapY][_pressedMapX - i] == 0;
+ && _vm->_map->getPass(_pressedMapX - i, _pressedMapY) == 0;
i++);
if (i <= _pressedMapX) {
@@ -705,11 +704,11 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
}
for (i = 1;
- (i + _pressedMapX) < Map::kMapWidth
- && _vm->_map->_passMap[_pressedMapY][_pressedMapX + i] == 0;
+ (i + _pressedMapX) < _vm->_map->_mapWidth
+ && _vm->_map->getPass(_pressedMapX + i, _pressedMapY) == 0;
i++);
- if (_pressedMapX + i < Map::kMapWidth) {
+ if (_pressedMapX + i < _vm->_map->_mapWidth) {
deltaPix = (i * 12) - (posX % 12);
if (resDelta == -1 || deltaPix < resDeltaPix) {
resDeltaPix = deltaPix;
@@ -719,11 +718,11 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
}
for (i = 1;
- (i + _pressedMapY) < Map::kMapHeight
- && _vm->_map->_passMap[_pressedMapY + i][_pressedMapX] == 0;
+ (i + _pressedMapY) < _vm->_map->_mapHeight
+ && _vm->_map->getPass(_pressedMapX, _pressedMapY + i) == 0;
i++);
- if (_pressedMapY + i < Map::kMapHeight) {
+ if (_pressedMapY + i < _vm->_map->_mapHeight) {
deltaPix = (i * 6) - (posY % 6);
if (resDelta == -1 || deltaPix < resDeltaPix) {
resDeltaPix = deltaPix;
@@ -734,7 +733,7 @@ void Goblin::adjustDest(int16 posX, int16 posY) {
for (i = 1;
i <= _pressedMapY
- && _vm->_map->_passMap[_pressedMapY - i][_pressedMapX] == 0;
+ && _vm->_map->getPass(_pressedMapX, _pressedMapY - i) == 0;
i++);
if (i <= _pressedMapY) {
@@ -775,11 +774,11 @@ void Goblin::adjustTarget(void) {
&& _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX] !=
0) {
_pressedMapY--;
- } else if (_pressedMapX < Map::kMapWidth - 1
+ } else if (_pressedMapX < _vm->_map->_mapWidth - 1
&& _vm->_map->_itemsMap[_pressedMapY][_pressedMapX + 1] !=
0) {
_pressedMapX++;
- } else if (_pressedMapX < Map::kMapWidth - 1 && _pressedMapY > 0
+ } else if (_pressedMapX < _vm->_map->_mapWidth - 1 && _pressedMapY > 0
&& _vm->_map->_itemsMap[_pressedMapY - 1][_pressedMapX +
1] != 0) {
_pressedMapY--;
@@ -790,7 +789,7 @@ void Goblin::adjustTarget(void) {
void Goblin::targetDummyItem(Gob_Object *gobDesc) {
if (_vm->_map->_itemsMap[_pressedMapY][_pressedMapX] == 0 &&
- _vm->_map->_passMap[_pressedMapY][_pressedMapX] == 1) {
+ _vm->_map->getPass(_pressedMapX, _pressedMapY) == 1) {
if (gobDesc->curLookDir == 0) {
_vm->_map->_itemPoses[0].x = _pressedMapX;
_vm->_map->_itemPoses[0].y = _pressedMapY;
@@ -938,7 +937,7 @@ void Goblin::targetItem(void) {
tmpPosX++;
}
- if (_vm->_map->_passMap[tmpPosY][tmpPosX] == 1) {
+ if (_vm->_map->getPass(tmpPosX, tmpPosY) == 1) {
_pressedMapX = tmpPosX;
_vm->_map->_destX = tmpPosX;
_gobDestX = tmpPosX;
@@ -951,26 +950,6 @@ void Goblin::targetItem(void) {
}
}
-void Goblin::initiateMove(void) {
- _vm->_map->findNearestToDest();
- _vm->_map->findNearestToGob();
- _vm->_map->optimizePoints();
-
- _pathExistence = _vm->_map->checkDirectPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
- _pressedMapX, _pressedMapY);
-
- if (_pathExistence == 3) {
- if (_vm->_map->checkLongPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
- _pressedMapX, _pressedMapY,
- _vm->_map->_nearestWayPoint, _vm->_map->_nearestDest) == 0) {
- _pathExistence = 0;
- } else {
- _vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
- _vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
- }
- }
-}
-
void Goblin::moveFindItem(int16 posX, int16 posY) {
int16 i;
if (_gobAction == 3 || _gobAction == 4) {
@@ -1121,7 +1100,7 @@ void Goblin::moveInitStep(int16 framesCount, int16 action, int16 cont,
targetDummyItem(gobDesc);
targetItem();
- initiateMove();
+ initiateMove(0);
moveCheckSelect(framesCount, gobDesc, pGobIndex, pNextAct);
} else {
@@ -1142,57 +1121,57 @@ void Goblin::moveTreatRopeStairs(Gob_Object *gobDesc) {
return;
if (gobDesc->nextState == 28
- && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) {
_forceNextState[0] = 28;
_forceNextState[1] = -1;
}
if (gobDesc->nextState == 29
- && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) {
_forceNextState[0] = 29;
_forceNextState[1] = -1;
}
if ((gobDesc->nextState == 28 || gobDesc->nextState == 29
|| gobDesc->nextState == 20)
- && _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6) {
if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 2)
- && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6) {
_forceNextState[0] = 28;
_forceNextState[1] = -1;
} else if ((gobDesc->curLookDir == 0
|| gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 6)
- && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6) {
_forceNextState[0] = 29;
_forceNextState[1] = -1;
}
}
if (gobDesc->nextState == 8
- && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 3) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) {
_forceNextState[0] = 8;
_forceNextState[1] = -1;
}
if (gobDesc->nextState == 9
- && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 3) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) {
_forceNextState[0] = 9;
_forceNextState[1] = -1;
}
if (gobDesc->nextState == 20
- && _vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
if ((gobDesc->curLookDir == 0 || gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 2)
- && _vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 3) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 3) {
_forceNextState[0] = 8;
_forceNextState[1] = -1;
} else if ((gobDesc->curLookDir == 0
|| gobDesc->curLookDir == 4
|| gobDesc->curLookDir == 6)
- && _vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 3) {
+ && _vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 3) {
_forceNextState[0] = 9;
_forceNextState[1] = -1;
}
@@ -1226,14 +1205,14 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
_vm->_map->_destY = _pressedMapY;
} else {
- if (_vm->_map->checkDirectPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+ if (_vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
_gobDestX, _gobDestY) == 1) {
_vm->_map->_destX = _gobDestX;
_vm->_map->_destY = _gobDestY;
} else if (_vm->_map->_curGoblinX == _vm->_map->_destX && _vm->_map->_curGoblinY == _vm->_map->_destY) {
if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest) {
- _vm->_map->optimizePoints();
+ _vm->_map->optimizePoints(0, 0, 0);
_vm->_map->_destX =
_vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
@@ -1245,7 +1224,7 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
if (_vm->_map->_nearestWayPoint > _vm->_map->_nearestDest)
_vm->_map->_nearestWayPoint--;
} else if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest) {
- _vm->_map->optimizePoints();
+ _vm->_map->optimizePoints(0, 0, 0);
_vm->_map->_destX =
_vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].
@@ -1257,9 +1236,9 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
if (_vm->_map->_nearestWayPoint < _vm->_map->_nearestDest)
_vm->_map->_nearestWayPoint++;
} else {
- if (_vm->_map->checkDirectPath(_vm->_map->_curGoblinX,
+ if (_vm->_map->checkDirectPath(-1, _vm->_map->_curGoblinX,
_vm->_map->_curGoblinY, _gobDestX,
- _gobDestY) == 3 && _vm->_map->_passMap[_pressedMapY][_pressedMapX] != 0) {
+ _gobDestY) == 3 && _vm->_map->getPass(_pressedMapX, _pressedMapY) != 0) {
_vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
_vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
} else {
@@ -1296,18 +1275,18 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
break;
case Map::kDirN:
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY - 1) == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
gobDesc->nextState = 8;
break;
}
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
_currentGoblin == 1) {
gobDesc->nextState = 28;
break;
@@ -1317,18 +1296,18 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
break;
case Map::kDirS:
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY + 1) == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
}
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3) {
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3) {
gobDesc->nextState = 9;
break;
}
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6 &&
_currentGoblin == 1) {
gobDesc->nextState = 29;
break;
@@ -1338,7 +1317,7 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
break;
case Map::kDirSE:
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX + 1] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY + 1) == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
@@ -1352,7 +1331,7 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
break;
case Map::kDirSW:
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY + 1][_vm->_map->_curGoblinX - 1] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY + 1) == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
@@ -1366,7 +1345,7 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
break;
case Map::kDirNW:
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX - 1] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX - 1, _vm->_map->_curGoblinY - 1) == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
@@ -1380,7 +1359,7 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
break;
case Map::kDirNE:
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY - 1][_vm->_map->_curGoblinX + 1] == 6 &&
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX + 1, _vm->_map->_curGoblinY - 1) == 6 &&
_currentGoblin != 1) {
_pathExistence = 0;
break;
@@ -1439,8 +1418,8 @@ void Goblin::movePathFind(Gob_Object *gobDesc, int16 nextAct) {
break;
default:
- if (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 3 ||
- (_vm->_map->_passMap[_vm->_map->_curGoblinY][_vm->_map->_curGoblinX] == 6
+ if (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 3 ||
+ (_vm->_map->getPass(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY) == 6
&& _currentGoblin == 1)) {
gobDesc->nextState = 20;
break;
@@ -2017,8 +1996,8 @@ void Goblin::pickItem(int16 indexToPocket, int16 idToPocket) {
_itemIndInPocket = indexToPocket;
_itemIdInPocket = idToPocket;
- for (y = 0; y < Map::kMapHeight; y++) {
- for (x = 0; x < Map::kMapWidth; x++) {
+ for (y = 0; y < _vm->_map->_mapHeight; y++) {
+ for (x = 0; x < _vm->_map->_mapWidth; x++) {
if (_itemByteFlag == 1) {
if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
idToPocket)
@@ -2084,7 +2063,7 @@ void Goblin::placeItem(int16 indexInPocket, int16 idInPocket) {
}
if (lookDir == 4) {
- if (xPos < Map::kMapWidth - 1) {
+ if (xPos < _vm->_map->_mapWidth - 1) {
_vm->_map->placeItem(xPos + 1, yPos, idInPocket);
if (yPos > 0) {
@@ -2107,10 +2086,10 @@ void Goblin::placeItem(int16 indexInPocket, int16 idInPocket) {
_vm->_map->_itemPoses[idInPocket].orient = lookDir;
if (_vm->_map->_itemPoses[idInPocket].orient == 0) {
// _vm->_map->_itemPoses[idInPocket].x++;
- if (_vm->_map->_passMap[(int)_vm->_map->_itemPoses[idInPocket].y][_vm->_map->_itemPoses[idInPocket].x + 1] == 1)
+ if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x + 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1)
_vm->_map->_itemPoses[idInPocket].x++;
} else {
- if (_vm->_map->_passMap[(int)_vm->_map->_itemPoses[idInPocket].y][_vm->_map->_itemPoses[idInPocket].x - 1] == 1)
+ if (_vm->_map->getPass(_vm->_map->_itemPoses[idInPocket].x - 1, (int)_vm->_map->_itemPoses[idInPocket].y) == 1)
_vm->_map->_itemPoses[idInPocket].x--;
}
}
@@ -2133,8 +2112,8 @@ void Goblin::swapItems(int16 indexToPick, int16 idToPick) {
_itemIdInPocket = idToPick;
if (_itemByteFlag == 0) {
- for (y = 0; y < Map::kMapHeight; y++) {
- for (x = 0; x < Map::kMapWidth; x++) {
+ for (y = 0; y < _vm->_map->_mapHeight; y++) {
+ for (x = 0; x < _vm->_map->_mapWidth; x++) {
if ((_vm->_map->_itemsMap[y][x] & 0xff) == idToPick)
_vm->_map->_itemsMap[y][x] =
(_vm->_map->_itemsMap[y][x] & 0xff00) +
@@ -2143,8 +2122,8 @@ void Goblin::swapItems(int16 indexToPick, int16 idToPick) {
}
} else {
- for (y = 0; y < Map::kMapHeight; y++) {
- for (x = 0; x < Map::kMapWidth; x++) {
+ for (y = 0; y < _vm->_map->_mapHeight; y++) {
+ for (x = 0; x < _vm->_map->_mapWidth; x++) {
if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8) ==
idToPick)
_vm->_map->_itemsMap[y][x] =
@@ -2296,11 +2275,11 @@ void Goblin::sub_19BD3(void) {
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 pass;
+ int16 gob1X;
+ int16 gob2X;
+ int16 gob1Y;
+ int16 gob2Y;
int16 var_A;
int16 var_C;
int16 di;
@@ -2380,73 +2359,73 @@ void Goblin::sub_19BD3(void) {
warning("GOB2 Stub! sub_195C7(1, 16);");
}
- var_2 = obj0->goblinX;
- var_4 = obj1->goblinX;
- var_6 = obj0->goblinY;
- var_8 = obj1->goblinY;
+ gob1X = obj0->goblinX;
+ gob2X = obj1->goblinX;
+ gob1Y = obj0->goblinY;
+ gob2Y = 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))
+ pass = _vm->_map->getPass(gob1X, gob1Y, 40);
+ if ((pass > 17) && (pass < 21))
+ warning("GOB2 Stub! sub_19AB7(anim0);");
+ pass = _vm->_map->getPass(gob2X, gob2Y, 40);
+ if ((pass > 17) && (pass < 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) {
+ if (gob1Y > si) {
+ if (_vm->_map->getPass(di, si, 40) > 17) {
do {
si--;
- } while (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17);
+ } while (_vm->_map->getPass(di, si, 40) > 17);
si++;
- if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di - 1) == 0) {
- if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di + 1) != 0)
+ if (_vm->_map->getPass(di - 1, si, 40) == 0) {
+ if (_vm->_map->getPass(di + 1, si, 40) != 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) {
+ if (_vm->_map->getPass(di, si, 40) > 17) {
do {
si++;
- } while (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di) > 17);
+ } while (_vm->_map->getPass(di, si, 40) > 17);
si--;
- if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di - 1) == 0) {
- if (_vm->_util->readVariableByte(_dword_2F2A4 + si * 40 + di + 1) != 0)
+ if (_vm->_map->getPass(di - 1, si, 40) == 0) {
+ if (_vm->_map->getPass(di + 1, si, 40) != 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) {
+ if (gob2Y > var_C) {
+ if (_vm->_map->getPass(var_A, var_C, 40) > 17) {
do {
var_C--;
- } while (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17);
+ } while (_vm->_map->getPass(var_A, var_C, 40) > 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)
+ if (_vm->_map->getPass(var_A - 1, var_C, 40) == 0) {
+ if (_vm->_map->getPass(var_A + 1, var_C, 40) != 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) {
+ if (_vm->_map->getPass(var_A, var_C, 40) > 17) {
do {
var_C++;
- } while (_vm->_util->readVariableByte(_dword_2F2A4 + var_C * 40 + var_A) > 17);
+ } while (_vm->_map->getPass(var_A, var_C, 40) > 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)
+ if (_vm->_map->getPass(var_A - 1, var_C, 40) == 0) {
+ if (_vm->_map->getPass(var_A + 1, var_C, 40) != 0)
var_A++;
} else
var_A--;
diff --git a/engines/gob/goblin.h b/engines/gob/goblin.h
index 2a43add91a..7e506e4214 100644
--- a/engines/gob/goblin.h
+++ b/engines/gob/goblin.h
@@ -23,6 +23,7 @@
#ifndef GOB_GOBLIN_H
#define GOB_GOBLIN_H
+#include "gob/gob.h"
#include "gob/util.h"
#include "gob/sound.h"
@@ -192,7 +193,6 @@ public:
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);
@@ -223,6 +223,7 @@ public:
virtual void placeObject(Gob_Object * objDesc, char animated,
int16 index, int16 x, int16 y, int16 state) = 0;
virtual void freeObjects(void) = 0;
+ virtual void initiateMove(int16 index) = 0;
Goblin(GobEngine *vm);
virtual ~Goblin() {};
@@ -238,7 +239,6 @@ protected:
void adjustTarget(void);
void targetDummyItem(Gob_Object *gobDesc);
void targetItem(void);
- void initiateMove(void);
void moveFindItem(int16 posX, int16 posY);
void moveCheckSelect(int16 framesCount, Gob_Object * gobDesc, int16 *pGobIndex, int16 *nextAct);
void moveInitStep(int16 framesCount, int16 action, int16 cont,
@@ -253,6 +253,7 @@ public:
virtual void placeObject(Gob_Object * objDesc, char animated,
int16 index, int16 x, int16 y, int16 state);
virtual void freeObjects(void);
+ virtual void initiateMove(int16 index);
Goblin_v1(GobEngine *vm);
virtual ~Goblin_v1() {};
@@ -263,6 +264,7 @@ public:
virtual void placeObject(Gob_Object * objDesc, char animated,
int16 index, int16 x, int16 y, int16 state);
virtual void freeObjects(void);
+ virtual void initiateMove(int16 index);
Goblin_v2(GobEngine *vm);
virtual ~Goblin_v2() {};
diff --git a/engines/gob/goblin_v1.cpp b/engines/gob/goblin_v1.cpp
index 234cc778d9..d7623604e9 100644
--- a/engines/gob/goblin_v1.cpp
+++ b/engines/gob/goblin_v1.cpp
@@ -27,6 +27,7 @@
#include "gob/gob.h"
#include "gob/goblin.h"
#include "gob/scenery.h"
+#include "gob/map.h"
namespace Gob {
@@ -137,4 +138,24 @@ void Goblin_v1::placeObject(Gob_Object *objDesc, char animated,
}
}
+void Goblin_v1::initiateMove(int16 index) {
+ _vm->_map->findNearestToDest(0);
+ _vm->_map->findNearestToGob(0);
+ _vm->_map->optimizePoints(0, 0, 0);
+
+ _pathExistence = _vm->_map->checkDirectPath(0, _vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+ _pressedMapX, _pressedMapY);
+
+ if (_pathExistence == 3) {
+ if (_vm->_map->checkLongPath(_vm->_map->_curGoblinX, _vm->_map->_curGoblinY,
+ _pressedMapX, _pressedMapY,
+ _vm->_map->_nearestWayPoint, _vm->_map->_nearestDest) == 0) {
+ _pathExistence = 0;
+ } else {
+ _vm->_map->_destX = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].x;
+ _vm->_map->_destY = _vm->_map->_wayPoints[_vm->_map->_nearestWayPoint].y;
+ }
+ }
+}
+
} // End of namespace Gob
diff --git a/engines/gob/goblin_v2.cpp b/engines/gob/goblin_v2.cpp
index 724361ff4a..9c4befc5cc 100644
--- a/engines/gob/goblin_v2.cpp
+++ b/engines/gob/goblin_v2.cpp
@@ -29,6 +29,7 @@
#include "gob/mult.h"
#include "gob/game.h"
#include "gob/scenery.h"
+#include "gob/map.h"
namespace Gob {
@@ -74,11 +75,13 @@ void Goblin_v2::placeObject(Gob_Object *objDesc, char animated,
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);
+ if (!_vm->_map->_bigTiles)
+ *obj->pPosY = (y + 1) * _vm->_map->_tilesHeight
+ - (_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;
+ *obj->pPosY = ((y + 1) / 2) * _vm->_map->_tilesHeight
+ - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+ *obj->pPosX = x * _vm->_map->_tilesWidth;
} else {
if (obj->goblinStates[state] != 0) {
layer = obj->goblinStates[state][0].layer;
@@ -91,14 +94,32 @@ void Goblin_v2::placeObject(Gob_Object *objDesc, char animated,
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);
+ if (!_vm->_map->_bigTiles)
+ *obj->pPosY = (y + 1) * _vm->_map->_tilesHeight
+ - (_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");
+ *obj->pPosY = ((y + 1) / 2) * _vm->_map->_tilesHeight
+ - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
+ *obj->pPosX = x * _vm->_map->_tilesWidth;
+ initiateMove(index);
} else
- warning("GOB2 Stub! sub_FE1D(obj");
+ initiateMove(index);
+ }
+}
+
+void Goblin_v2::initiateMove(int16 index) {
+ Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+
+ obj->destX = obj->gobDestX;
+ obj->destY = obj->gobDestY;
+ _vm->_map->findNearestToDest(index);
+ _vm->_map->findNearestToGob(index);
+ _vm->_map->optimizePoints(index, obj->goblinX, obj->goblinY);
+ obj->pAnimData->field_12 = _vm->_map->checkDirectPath(index,
+ obj->goblinX, obj->goblinY, obj->gobDestX, obj->gobDestY);
+ if (obj->pAnimData->field_12 == 3) {
+ obj->destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
+ obj->destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
}
}
diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp
index 69787ae601..9ef90718eb 100644
--- a/engines/gob/inter.cpp
+++ b/engines/gob/inter.cpp
@@ -304,8 +304,8 @@ void Inter::renewTimeInVars(void) {
}
void Inter::manipulateMap(int16 xPos, int16 yPos, int16 item) {
- for (int16 y = 0; y < Map::kMapHeight; y++) {
- for (int16 x = 0; x < Map::kMapWidth; x++) {
+ for (int16 y = 0; y < _vm->_map->_mapHeight; y++) {
+ for (int16 x = 0; x < _vm->_map->_mapWidth; x++) {
if ((_vm->_map->_itemsMap[y][x] & 0xff) == item) {
_vm->_map->_itemsMap[y][x] &= 0xff00;
} else if (((_vm->_map->_itemsMap[y][x] & 0xff00) >> 8)
@@ -315,7 +315,7 @@ void Inter::manipulateMap(int16 xPos, int16 yPos, int16 item) {
}
}
- if (xPos < Map::kMapWidth - 1) {
+ if (xPos < _vm->_map->_mapWidth - 1) {
if (yPos > 0) {
if ((_vm->_map->_itemsMap[yPos][xPos] & 0xff00) != 0 ||
(_vm->_map->_itemsMap[yPos - 1][xPos] & 0xff00) !=
@@ -415,28 +415,28 @@ void Inter::manipulateMap(int16 xPos, int16 yPos, int16 item) {
if (item < 0 || item >= 20)
return;
- if (xPos > 1 && _vm->_map->_passMap[yPos][xPos - 2] == 1) {
+ if (xPos > 1 && _vm->_map->getPass(xPos - 2, yPos) == 1) {
_vm->_map->_itemPoses[item].x = xPos - 2;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 4;
return;
}
- if (xPos < Map::kMapWidth - 2 && _vm->_map->_passMap[yPos][xPos + 2] == 1) {
+ if (xPos < _vm->_map->_mapWidth - 2 && _vm->_map->getPass(xPos + 2, yPos) == 1) {
_vm->_map->_itemPoses[item].x = xPos + 2;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 0;
return;
}
- if (xPos < Map::kMapWidth - 1 && _vm->_map->_passMap[yPos][xPos + 1] == 1) {
+ if (xPos < _vm->_map->_mapWidth - 1 && _vm->_map->getPass(xPos + 1, yPos) == 1) {
_vm->_map->_itemPoses[item].x = xPos + 1;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 0;
return;
}
- if (xPos > 0 && _vm->_map->_passMap[yPos][xPos - 1] == 1) {
+ if (xPos > 0 && _vm->_map->getPass(xPos - 1, yPos) == 1) {
_vm->_map->_itemPoses[item].x = xPos - 1;
_vm->_map->_itemPoses[item].y = yPos;
_vm->_map->_itemPoses[item].orient = 4;
diff --git a/engines/gob/inter.h b/engines/gob/inter.h
index 2ae07da874..3377287001 100644
--- a/engines/gob/inter.h
+++ b/engines/gob/inter.h
@@ -62,6 +62,7 @@ public:
void manipulateMap(int16 xPos, int16 yPos, int16 item);
virtual int16 loadSound(int16 slot) = 0;
virtual void storeMouse(void) = 0;
+ virtual void animPalette(void) = 0;
Inter(GobEngine *vm);
virtual ~Inter() {};
@@ -77,7 +78,6 @@ 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 {
@@ -86,6 +86,7 @@ public:
virtual ~Inter_v1() {};
virtual int16 loadSound(int16 slot);
virtual void storeMouse(void);
+ virtual void animPalette(void);
protected:
typedef void (Inter_v1::*OpcodeDrawProcV1)(void);
@@ -116,7 +117,6 @@ 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);
@@ -278,6 +278,7 @@ public:
virtual ~Inter_v2() {};
virtual int16 loadSound(int16 search);
virtual void storeMouse(void);
+ virtual void animPalette(void);
protected:
typedef void (Inter_v2::*OpcodeDrawProcV2)(void);
@@ -308,16 +309,13 @@ 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) { error("Gob2 stub"); }
void o2_totSub(void);
void o2_switchTotSub(void);
- void o2_stub0x52(void);
void o2_stub0x54(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);
@@ -332,6 +330,7 @@ protected:
void o2_freeGoblins(void);
void o2_writeGoblinPos(void);
void o2_placeGoblin(void);
+ void o2_moveGoblin(void);
void o2_multSub(void);
void o2_setRenderFlags(void);
void o2_initMult(void);
@@ -343,6 +342,7 @@ protected:
void o2_getCDTrackPos(void);
void o2_playMult(void);
void o2_initCursor(void);
+ void o2_playImd(void);
void o2_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
};
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 9e6b574f67..96e91b6559 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -1485,7 +1485,20 @@ void Inter_v1::o1_freeAnim(void) {
}
void Inter_v1::o1_updateAnim(void) {
- _vm->_scenery->interUpdateAnim();
+ int16 deltaX;
+ int16 deltaY;
+ int16 flags;
+ int16 frame;
+ int16 layer;
+ int16 animation;
+
+ evalExpr(&deltaX);
+ evalExpr(&deltaY);
+ evalExpr(&animation);
+ evalExpr(&layer);
+ evalExpr(&frame);
+ flags = load16();
+ _vm->_scenery->updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1);
}
void Inter_v1::o1_initMult(void) {
@@ -2230,7 +2243,7 @@ void Inter_v1::o1_setPassMap(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj
int16 xPos = load16();
int16 yPos = load16();
int16 val = load16();
- _vm->_map->_passMap[yPos][xPos] = val;
+ _vm->_map->setPass(xPos, yPos, val);
}
void Inter_v1::o1_setGoblinPosH(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index b09dbf61fc..3757d59c70 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -227,7 +227,7 @@ void Inter_v2::setupOpcodes(void) {
/* 50 */
OPCODE(o2_loadMapObjects),
OPCODE(o2_freeGoblins),
- OPCODE(o2_stub0x52),
+ OPCODE(o2_moveGoblin),
OPCODE(o2_writeGoblinPos),
/* 54 */
OPCODE(o2_stub0x54),
@@ -288,7 +288,7 @@ void Inter_v2::setupOpcodes(void) {
OPCODE(o2_stub0x80),
OPCODE(o2_drawStub),
OPCODE(o2_stub0x82),
- OPCODE(o2_stub0x83),
+ OPCODE(o2_playImd),
/* 84 */
OPCODE(o2_drawStub),
OPCODE(o2_stub0x85),
@@ -712,20 +712,10 @@ const char *Inter_v2::getOpcodeGoblinDesc(int i) {
return "";
}
-void Inter_v2::o2_stub0x52(void) {
- int16 expr1 = _vm->_parse->parseValExpr();
- int16 expr2 = _vm->_parse->parseValExpr();
- int16 expr3 = _vm->_parse->parseValExpr();
-
- warning("STUB: Gob2 drawOperation 0x52 (%d %d %d)", expr1, expr2, expr3);
-}
-
void Inter_v2::o2_stub0x54(void) {
int16 index = _vm->_parse->parseValExpr();
- warning("STUB: Gob2 drawOperation 0x54 (%d)", index);
-
-// _vm->_mult->_objects[index].pAnimData->field_12 = 4;
+ _vm->_mult->_objects[index].pAnimData->field_12 = 4;
}
void Inter_v2::o2_stub0x80(void) {
@@ -757,7 +747,7 @@ void Inter_v2::o2_stub0x80(void) {
memset(_vm->_global->_redPalette, 0, 256);
memset(_vm->_global->_greenPalette, 0, 256);
memset(_vm->_global->_bluePalette, 0, 256);
- warning("GOB2 Stub! _vid_setStubDriver");
+// warning("GOB2 Stub! _vid_setStubDriver");
if (videoMode == 0x10) {
_vm->_global->_videoMode = 0x12;
@@ -820,32 +810,6 @@ void Inter_v2::o2_stub0x82(void) {
warning("GOB2 Stub! _vid_setPixelShift(_vm->_game->_word_2FC9E, _vm->_game->_word_2FC9C);");*/
}
-// 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);
-}
-
void Inter_v2::o2_stub0x85(void) {
char dest[32];
@@ -977,6 +941,28 @@ void Inter_v2::o2_placeGoblin(void) {
_vm->_goblin->placeObject(0, 0, index, x, y, state);
}
+void Inter_v2::o2_moveGoblin(void) {
+ Mult::Mult_Object *obj;
+ Mult::Mult_AnimData *objAnim;
+ int16 destX = _vm->_parse->parseValExpr();
+ int16 destY = _vm->_parse->parseValExpr();
+ int16 index = _vm->_parse->parseValExpr();
+
+ obj = &_vm->_mult->_objects[index];
+ objAnim = obj->pAnimData;
+
+ obj->gobDestX = destX;
+ obj->gobDestY = destY;
+ objAnim->field_13 = destX;
+ objAnim->field_14 = destY;
+ if (objAnim->someFlag != 0) {
+ if ((destX == -1) && (destY == -1)) {
+ warning("STUB: Gob2 drawOperation moveGoblin (%d %d %d), someFlag: %d", destX, destY, index, objAnim->someFlag);
+ }
+ }
+ _vm->_goblin->initiateMove(index);
+}
+
void Inter_v2::o2_writeGoblinPos(void) {
int16 var1;
int16 var2;
@@ -1033,14 +1019,14 @@ void Inter_v2::loadMult(void) {
objAnim = obj->pAnimData;
val = *obj->pPosX % 256;
- obj->field_1C = val;
- obj->field_1E = val;
+ obj->destX = val;
+ obj->gobDestX = val;
obj->goblinX = val;
val = *obj->pPosY % 256;
- obj->field_1D = val;
- obj->field_1F = val;
+ obj->destY = val;
+ obj->gobDestY = val;
obj->goblinY = val;
- *obj->pPosX *= _vm->_mult->_word_2F2B1;
+ *obj->pPosX *= _vm->_map->_tilesWidth;
objAnim->field_15 = objAnim->unknown;
objAnim->field_E = -1;
objAnim->field_F = -1;
@@ -1050,12 +1036,14 @@ void Inter_v2::loadMult(void) {
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)
+ if (!_vm->_map->_bigTiles) {
+ *obj->pPosY = (obj->goblinY + 1) * _vm->_map->_tilesHeight
+ - (_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->pPosY = ((obj->goblinY + 1) / 2) * _vm->_map->_tilesHeight
+ - (_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
}
- *obj->pPosX = obj->goblinX * _vm->_mult->_word_2F2B1;
+ *obj->pPosX = obj->goblinX * _vm->_map->_tilesWidth;
}
}
if (_vm->_mult->_objects[objIndex].pAnimData->animType == 101) {
@@ -1675,6 +1663,53 @@ void Inter_v2::o2_initCursor(void) {
}
}
+void Inter_v2::o2_playImd(void) {
+ char imd[128];
+ int i;
+ int16 x;
+ int16 y;
+ int16 startFrame; // di
+ int16 lastFrame; // si
+ int16 breakKey;
+ int16 flags;
+ int16 expr7;
+ int16 expr8;
+
+ evalExpr(0);
+ _vm->_global->_inter_resStr[8] = 0;
+ strcpy(imd, _vm->_global->_inter_resStr);
+ x = _vm->_parse->parseValExpr();
+ y = _vm->_parse->parseValExpr();
+ startFrame = _vm->_parse->parseValExpr();
+ lastFrame = _vm->_parse->parseValExpr();
+ breakKey = _vm->_parse->parseValExpr();
+ flags = _vm->_parse->parseValExpr();
+ expr7 = _vm->_parse->parseValExpr();
+ expr8 = _vm->_parse->parseValExpr();
+
+ if (_vm->_game->openImd(imd, x, y, startFrame, flags) == 0)
+ return;
+
+ int16 var_C;
+
+ var_C = lastFrame;
+ if (lastFrame < 0)
+ lastFrame = _vm->_game->_imdFile->framesCount - 1;
+ for (i = startFrame; i <= lastFrame; i++) {
+ _vm->_game->playImd(i, 1 << (flags & 0x3F), expr7, expr8, 0, lastFrame);
+ WRITE_VAR(11, i);
+ if (breakKey != 0) {
+ _vm->_util->getMouseState(&_vm->_global->_inter_mouseX,
+ &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons);
+ storeKey(_vm->_util->checkKey());
+ if (VAR(0) == (unsigned) breakKey)
+ return;
+ }
+ }
+ if (var_C == -1)
+ _vm->_game->closeImd();
+}
+
void Inter_v2::o2_totSub(void) {
char totFile[14];
int flags;
diff --git a/engines/gob/map.cpp b/engines/gob/map.cpp
index 5333ee5219..c69706b5e4 100644
--- a/engines/gob/map.cpp
+++ b/engines/gob/map.cpp
@@ -33,21 +33,26 @@
#include "gob/goblin.h"
#include "gob/sound.h"
#include "gob/scenery.h"
+#include "gob/mult.h"
namespace Gob {
Map::Map(GobEngine *vm) : _vm(vm) {
int i;
- for (i = 0; i < kMapHeight; i++)
- for (int j = 0; j < kMapWidth; j++) {
- _passMap[i][j] = 0;
- _itemsMap[i][j] = 0;
- }
- for (i = 0; i < 40; i++) {
- _wayPoints[i].x = 0;
- _wayPoints[i].y = 0;
- }
+ _mapWidth = -1;
+ _mapHeight = -1;
+ _screenWidth = 0;
+ _tilesWidth = 0;
+ _tilesHeight = 0;
+ _passWidth = 0;
+
+ _passMap = 0;
+ _itemsMap = 0;
+ _wayPointsCount = 0;
+ _wayPoints = 0;
+ _bigTiles = false;
+
for (i = 0; i < 40; i++) {
_itemPoses[i].x = 0;
_itemPoses[i].y = 0;
@@ -85,7 +90,7 @@ int16 Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) {
if (x0 == x1 && y0 == y1)
return 0;
- if (!(x1 >= 0 && x1 < kMapWidth && y1 >= 0 && y1 < kMapHeight))
+ if (!(x1 >= 0 && x1 < _mapWidth && y1 >= 0 && y1 < _mapHeight))
return 0;
if (y1 > y0)
@@ -98,91 +103,91 @@ int16 Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) {
else if (x1 < x0)
dir |= kLeft;
- if (_passMap[y0][x0] == 3 && (dir & kUp)) {
- if (_passMap[y0 - 1][x0] != 0)
+ if (getPass(x0, y0) == 3 && (dir & kUp)) {
+ if (getPass(x0, y0 - 1) != 0)
return kDirN;
}
- if (_passMap[y0][x0] == 3 && (dir & kDown)) {
- if (_passMap[y0 + 1][x0] != 0)
+ if (getPass(x0, y0) == 3 && (dir & kDown)) {
+ if (getPass(x0, y0 + 1) != 0)
return kDirS;
}
- if (_passMap[y0][x0] == 6 && (dir & kUp)) {
- if (_passMap[y0 - 1][x0] != 0)
+ if (getPass(x0, y0) == 6 && (dir & kUp)) {
+ if (getPass(x0, y0 - 1) != 0)
return kDirN;
}
- if (_passMap[y0][x0] == 6 && (dir & kDown)) {
- if (_passMap[y0 + 1][x0] != 0)
+ if (getPass(x0, y0) == 6 && (dir & kDown)) {
+ if (getPass(x0, y0 + 1) != 0)
return kDirS;
}
if (dir == kLeft) {
- if (x0 - 1 >= 0 && _passMap[y0][x0 - 1] != 0)
+ if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0)
return kDirW;
return 0;
}
if (dir == kRight) {
- if (x0 + 1 < kMapWidth && _passMap[y0][x0 + 1] != 0)
+ if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0)
return kDirE;
return 0;
}
if (dir == kUp) {
- if (y0 - 1 >= 0 && _passMap[y0 - 1][x0] != 0)
+ if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0)
return kDirN;
if (y0 - 1 >= 0 && x0 - 1 >= 0
- && _passMap[y0 - 1][x0 - 1] != 0)
+ && getPass(x0 - 1, y0 - 1) != 0)
return kDirNW;
- if (y0 - 1 >= 0 && x0 + 1 < kMapWidth
- && _passMap[y0 - 1][x0 + 1] != 0)
+ if (y0 - 1 >= 0 && x0 + 1 < _mapWidth
+ && getPass(x0 + 1, y0 - 1) != 0)
return kDirNE;
return 0;
}
if (dir == kDown) {
- if (y0 + 1 < kMapHeight && _passMap[y0 + 1][x0] != 0)
+ if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0)
return kDirS;
- if (y0 + 1 < kMapHeight && x0 - 1 >= 0
- && _passMap[y0 + 1][x0 - 1] != 0)
+ if (y0 + 1 < _mapHeight && x0 - 1 >= 0
+ && getPass(x0 - 1, y0 + 1) != 0)
return kDirSW;
- if (y0 + 1 < kMapHeight && x0 + 1 < kMapWidth
- && _passMap[y0 + 1][x0 + 1] != 0)
+ if (y0 + 1 < _mapHeight && x0 + 1 < _mapWidth
+ && getPass(x0 + 1, y0 + 1) != 0)
return kDirSE;
return 0;
}
if (dir == (kRight | kUp)) {
- if (y0 - 1 >= 0 && x0 + 1 < kMapWidth
- && _passMap[y0 - 1][x0 + 1] != 0)
+ if (y0 - 1 >= 0 && x0 + 1 < _mapWidth
+ && getPass(x0 + 1, y0 - 1) != 0)
return kDirNE;
- if (y0 - 1 >= 0 && _passMap[y0 - 1][x0] != 0)
+ if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0)
return kDirN;
- if (x0 + 1 < kMapWidth && _passMap[y0][x0 + 1] != 0)
+ if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0)
return kDirE;
return 0;
}
if (dir == (kRight | kDown)) {
- if (x0 + 1 < kMapWidth && y0 + 1 < kMapHeight
- && _passMap[y0 + 1][x0 + 1] != 0)
+ if (x0 + 1 < _mapWidth && y0 + 1 < _mapHeight
+ && getPass(x0 + 1, y0 + 1) != 0)
return kDirSE;
- if (y0 + 1 < kMapHeight && _passMap[y0 + 1][x0] != 0)
+ if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0)
return kDirS;
- if (x0 + 1 < kMapWidth && _passMap[y0][x0 + 1] != 0)
+ if (x0 + 1 < _mapWidth && getPass(x0 + 1, y0) != 0)
return kDirE;
return 0;
@@ -190,27 +195,27 @@ int16 Map::getDirection(int16 x0, int16 y0, int16 x1, int16 y1) {
if (dir == (kLeft | kUp)) {
if (x0 - 1 >= 0 && y0 - 1 >= 0
- && _passMap[y0 - 1][x0 - 1] != 0)
+ && getPass(x0 - 1, y0 - 1) != 0)
return kDirNW;
- if (y0 - 1 >= 0 && _passMap[y0 - 1][x0] != 0)
+ if (y0 - 1 >= 0 && getPass(x0, y0 - 1) != 0)
return kDirN;
- if (x0 - 1 >= 0 && _passMap[y0][x0 - 1] != 0)
+ if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0)
return kDirW;
return 0;
}
if (dir == (kLeft | kDown)) {
- if (x0 - 1 >= 0 && y0 + 1 < kMapHeight
- && _passMap[y0 + 1][x0 - 1] != 0)
+ if (x0 - 1 >= 0 && y0 + 1 < _mapHeight
+ && getPass(x0 - 1, y0 + 1) != 0)
return kDirSW;
- if (y0 + 1 < kMapHeight && _passMap[y0 + 1][x0] != 0)
+ if (y0 + 1 < _mapHeight && getPass(x0, y0 + 1) != 0)
return kDirS;
- if (x0 - 1 >= 0 && _passMap[y0][x0 - 1] != 0)
+ if (x0 - 1 >= 0 && getPass(x0 - 1, y0) != 0)
return kDirW;
return 0;
@@ -226,10 +231,10 @@ int16 Map::findNearestWayPoint(int16 x, int16 y) {
length = 30000;
- for (i = 0; i < 40; i++) {
+ for (i = 0; i < _wayPointsCount; i++) {
if (_wayPoints[i].x < 0 ||
- _wayPoints[i].x >= kMapWidth ||
- _wayPoints[i].y < 0 || _wayPoints[i].y >= kMapHeight)
+ _wayPoints[i].x >= _mapWidth ||
+ _wayPoints[i].y < 0 || _wayPoints[i].y >= _mapHeight)
return -1;
tmp = ABS(x - _wayPoints[i].x) + ABS(y - _wayPoints[i].y);
@@ -243,26 +248,24 @@ int16 Map::findNearestWayPoint(int16 x, int16 y) {
return lnearestWayPoint;
}
-void Map::findNearestToGob(void) {
- int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);
-
- if (wayPoint != -1)
- _nearestWayPoint = wayPoint;
-}
-
-void Map::findNearestToDest(void) {
- int16 wayPoint = findNearestWayPoint(_destX, _destY);
-
- if (wayPoint != -1)
- _nearestDest = wayPoint;
-}
-
-int16 Map::checkDirectPath(int16 x0, int16 y0, int16 x1, int16 y1) {
+int16 Map::checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1) {
+ Mult::Mult_Object *obj = 0;
uint16 dir;
+ if ((index >= 0) && (index < _vm->_mult->_objCount))
+ obj = &_vm->_mult->_objects[index];
+
while (1) {
dir = getDirection(x0, y0, x1, y1);
+ if (obj) {
+ if (obj->nearestWayPoint < obj->nearestDest)
+ if (_wayPoints[obj->nearestWayPoint + 1].field_2 == 1)
+ return 3;
+ if (_wayPoints[obj->nearestDest - 1].field_2 == 1)
+ return 3;
+ }
+
if (x0 == x1 && y0 == y1)
return 1;
@@ -326,7 +329,7 @@ int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16
nextLink = 1;
if (nextLink != 0) {
- if (checkDirectPath(x0, y0, x1, y1) == 1)
+ if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
return 1;
nextLink = 0;
@@ -345,7 +348,7 @@ int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16
}
if (i0 == i1 && _wayPoints[i0].x == x0
&& _wayPoints[i0].y == y0) {
- if (checkDirectPath(x0, y0, x1, y1) == 1)
+ if (checkDirectPath(-1, x0, y0, x1, y1) == 1)
return 1;
return 0;
}
@@ -393,24 +396,6 @@ int16 Map::checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16
}
}
-void Map::optimizePoints(void) {
- int16 i;
-
- if (_nearestWayPoint < _nearestDest) {
- for (i = _nearestWayPoint; i <= _nearestDest; i++) {
- if (checkDirectPath(_curGoblinX, _curGoblinY,
- _wayPoints[i].x, _wayPoints[i].y) == 1)
- _nearestWayPoint = i;
- }
- } else if (_nearestWayPoint > _nearestDest) {
- for (i = _nearestWayPoint; i >= _nearestDest; i--) {
- if (checkDirectPath(_curGoblinX, _curGoblinY,
- _wayPoints[i].x, _wayPoints[i].y) == 1)
- _nearestWayPoint = i;
- }
- }
-}
-
void Map::loadDataFromAvo(char *dest, int16 size) {
memcpy(dest, _avoDataPtr, size);
_avoDataPtr += size;
diff --git a/engines/gob/map.h b/engines/gob/map.h
index 1b12f9280f..cb2dc625d1 100644
--- a/engines/gob/map.h
+++ b/engines/gob/map.h
@@ -23,6 +23,8 @@
#ifndef GOB_MAP_H
#define GOB_MAP_H
+#include "gob/util.h"
+
namespace Gob {
// The same numeric values are also used for the arrow keys.
@@ -39,16 +41,13 @@ public:
kDirS = 0x5000,
kDirSE = 0x5100
};
- enum {
- kMapWidth = 26,
- kMapHeight = 28
- };
#pragma START_PACK_STRUCTS
struct Point {
int16 x;
int16 y;
+ int16 field_2; // Gob2
} GCC_PACK;
#define szMap_ItemPos 3
@@ -61,13 +60,22 @@ public:
#pragma END_PACK_STRUCTS
- int8 _passMap[kMapHeight][kMapWidth]; // [y][x]
- int16 _itemsMap[kMapHeight][kMapWidth]; // [y][x]
- Point _wayPoints[40];
+ int16 _mapWidth;
+ int16 _mapHeight;
+ int16 _screenWidth;
+ int16 _tilesWidth;
+ int16 _tilesHeight;
+ int16 _passWidth;
+ bool _bigTiles;
+
+ int8 *_passMap; // [y * _mapWidth + x], getPass(x, y);
+ int16 **_itemsMap; // [y][x]
+ int16 _wayPointsCount;
+ Point *_wayPoints;
int16 _nearestWayPoint;
int16 _nearestDest;
- int16 _curGoblinX;
+ int16 _curGoblinX;
int16 _curGoblinY;
int16 _destX;
int16 _destY;
@@ -79,16 +87,19 @@ public:
void placeItem(int16 x, int16 y, int16 id);
int16 getDirection(int16 x0, int16 y0, int16 x1, int16 y1);
- void findNearestToGob(void);
- void findNearestToDest(void);
- int16 checkDirectPath(int16 x0, int16 y0, int16 x1, int16 y1);
+ int16 checkDirectPath(int16 index, int16 x0, int16 y0, int16 x1, int16 y1);
int16 checkLongPath(int16 x0, int16 y0, int16 x1, int16 y1, int16 i0, int16 i1);
- void optimizePoints(void);
void loadItemToObject(void);
void loadDataFromAvo(char *dest, int16 size);
void loadMapsInitGobs(void);
+ virtual int8 getPass(int x, int y, int heightOff = -1) = 0;
+ virtual void setPass(int x, int y, int8 pass, int heightOff = -1) = 0;
+
virtual void loadMapObjects(char *avjFile) = 0;
+ virtual void findNearestToGob(int16 index) = 0;
+ virtual void findNearestToDest(int16 index) = 0;
+ virtual void optimizePoints(int16 index, int16 x, int16 y) = 0;
Map(GobEngine *vm);
virtual ~Map() {};
@@ -104,14 +115,40 @@ protected:
class Map_v1 : public Map {
public:
virtual void loadMapObjects(char *avjFile);
+ virtual void optimizePoints(int16 index, int16 x, int16 y);
+ virtual void findNearestToGob(int16 index);
+ virtual void findNearestToDest(int16 index);
+
+ virtual inline int8 getPass(int x, int y, int heightOff = -1) {
+ return _passMap[y * _mapWidth + x];
+ }
+
+ virtual inline void setPass(int x, int y, int8 pass, int heightOff = -1) {
+ _passMap[y * _mapWidth + x] = pass;
+ }
Map_v1(GobEngine *vm);
- virtual ~Map_v1() {};
+ virtual ~Map_v1();
};
class Map_v2 : public Map_v1 {
public:
virtual void loadMapObjects(char *avjFile);
+ virtual void optimizePoints(int16 index, int16 x, int16 y);
+ virtual void findNearestToGob(int16 index);
+ virtual void findNearestToDest(int16 index);
+
+ virtual inline int8 getPass(int x, int y, int heightOff = -1) {
+ if (heightOff == -1)
+ heightOff = _passWidth;
+ return _vm->_util->readVariableByte((char *) (_passMap + y * heightOff + x));
+ }
+
+ virtual inline void setPass(int x, int y, int8 pass, int heightOff = -1) {
+ if (heightOff == -1)
+ heightOff = _passWidth;
+ _vm->_util->writeVariableByte((char *) (_passMap + y * heightOff + x) , pass);
+ }
Map_v2(GobEngine *vm);
virtual ~Map_v2() {};
diff --git a/engines/gob/map_v1.cpp b/engines/gob/map_v1.cpp
index 4e9859b89f..7b0da03f51 100644
--- a/engines/gob/map_v1.cpp
+++ b/engines/gob/map_v1.cpp
@@ -29,10 +29,39 @@
#include "gob/dataio.h"
#include "gob/goblin.h"
#include "gob/sound.h"
+#include "gob/scenery.h"
+#include "gob/mult.h"
namespace Gob {
Map_v1::Map_v1(GobEngine *vm) : Map(vm) {
+ int i;
+ int j;
+
+ _mapWidth = 26;
+ _mapHeight = 28;
+
+ _passMap = new int8[_mapHeight * _mapWidth];
+ _itemsMap = new int16*[_mapHeight];
+ for (i = 0; i < _mapHeight; i++) {
+ _itemsMap[i] = new int16[_mapWidth];
+ for (j = 0; j < _mapWidth; j++) {
+ setPass(j, i, 0);
+ _itemsMap[i][j] = 0;
+ }
+ }
+
+ _wayPointsCount = 40;
+ _wayPoints = new Point[40];
+ for (i = 0; i < 40; i++) {
+ _wayPoints[i].x = 0;
+ _wayPoints[i].y = 0;
+ _wayPoints[i].field_2 = 0;
+ }
+}
+
+Map_v1::~Map_v1() {
+ delete[] _passMap;
}
void Map_v1::loadMapObjects(char *avjFile) {
@@ -66,10 +95,10 @@ void Map_v1::loadMapObjects(char *avjFile) {
_vm->_dataio->closeData(handle);
_avoDataPtr = _vm->_dataio->getData(avoName);
dataBuf = _avoDataPtr;
- loadDataFromAvo((char *)_passMap, kMapHeight * kMapWidth);
+ loadDataFromAvo((char *)_passMap, _mapHeight * _mapWidth);
- for (y = 0; y < kMapHeight; y++) {
- for (x = 0; x < kMapWidth; x++) {
+ for (y = 0; y < _mapHeight; y++) {
+ for (x = 0; x < _mapWidth; x++) {
loadDataFromAvo(&item, 1);
_itemsMap[y][x] = item;
}
@@ -343,4 +372,36 @@ void Map_v1::loadMapObjects(char *avjFile) {
}
}
+void Map_v1::optimizePoints(int16 index, int16 x, int16 y) {
+ int16 i;
+
+ if (_nearestWayPoint < _nearestDest) {
+ for (i = _nearestWayPoint; i <= _nearestDest; i++) {
+ if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+ _wayPoints[i].x, _wayPoints[i].y) == 1)
+ _nearestWayPoint = i;
+ }
+ } else if (_nearestWayPoint > _nearestDest) {
+ for (i = _nearestWayPoint; i >= _nearestDest; i--) {
+ if (checkDirectPath(-1, _curGoblinX, _curGoblinY,
+ _wayPoints[i].x, _wayPoints[i].y) == 1)
+ _nearestWayPoint = i;
+ }
+ }
+}
+
+void Map_v1::findNearestToGob(int16 index) {
+ int16 wayPoint = findNearestWayPoint(_curGoblinX, _curGoblinY);
+
+ if (wayPoint != -1)
+ _nearestWayPoint = wayPoint;
+}
+
+void Map_v1::findNearestToDest(int16 index) {
+ int16 wayPoint = findNearestWayPoint(_destX, _destY);
+
+ if (wayPoint != -1)
+ _nearestDest = wayPoint;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp
index d8ef031cc9..6558cd27d9 100644
--- a/engines/gob/map_v2.cpp
+++ b/engines/gob/map_v2.cpp
@@ -33,6 +33,7 @@
#include "gob/game.h"
#include "gob/parse.h"
#include "gob/mult.h"
+#include "gob/scenery.h"
namespace Gob {
@@ -43,11 +44,11 @@ void Map_v2::loadMapObjects(char *avjFile) {
int i;
int j;
int k;
+ uint8 wayPointsCount;
int16 var;
int16 id;
- int16 numChunks;
- int16 chunkLength;
- int16 offVar;
+ int16 mapHeight;
+ int16 mapWidth;
int16 offData;
int16 tmp;
int16 numData;
@@ -61,17 +62,13 @@ void Map_v2::loadMapObjects(char *avjFile) {
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;
+ _passMap = (int8 *)(_vm->_global->_inter_variables + var);
return;
}
@@ -79,51 +76,53 @@ void Map_v2::loadMapObjects(char *avjFile) {
dataPtr = extData;
if (*dataPtr++ == 3) {
- _vm->_mult->_word_2F22A = 640;
- _vm->_mult->_word_2CC84 = 65;
+ _vm->_map->_screenWidth = 640;
+ _vm->_map->_passWidth = 65;
} else {
- _vm->_mult->_word_2F22A = 320;
- _vm->_mult->_word_2CC84 = 40;
+ _vm->_map->_screenWidth = 320;
+ _vm->_map->_passWidth = 40;
}
- byte_2F2AA = *dataPtr++;
- _vm->_mult->_word_2F2B1 = READ_LE_UINT16(dataPtr);
+ _wayPointsCount = *dataPtr++;
+ _vm->_map->_tilesWidth = READ_LE_UINT16(dataPtr);
dataPtr += 2;
- _vm->_mult->_word_2F2AF = READ_LE_UINT16(dataPtr);
+ _vm->_map->_tilesHeight = READ_LE_UINT16(dataPtr);
dataPtr += 2;
- _vm->_mult->_word_2CC86 = _vm->_mult->_word_2F2AF & 0xFF00 ? 0 : 1;
- _vm->_mult->_word_2F2AF &= 0xFF;
+ _vm->_map->_bigTiles = !(_vm->_map->_tilesHeight & 0xFF00);
+ _vm->_map->_tilesHeight &= 0xFF;
- dataPtrBak = dataPtr;
- dataPtr += (_vm->_mult->_word_2F22A / _vm->_mult->_word_2F2B1) * (200 / _vm->_mult->_word_2F2AF);
+ _mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth;
+ _mapHeight = 200 / _vm->_map->_tilesHeight;
- if (*extData == 1) {
- byte_2F2AA = 40;
- var_9 = 40;
- } else {
- if (byte_2F2AA == 0) {
- var_9 = 1;
- } else {
- var_9 = byte_2F2AA;
- }
+ dataPtrBak = dataPtr;
+ dataPtr += _mapWidth * _mapHeight;
+
+ if (*extData == 1)
+ wayPointsCount = _wayPointsCount = 40;
+ else
+ wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount;
+
+ _wayPoints = new Point[wayPointsCount];
+ for (i = 0; i < wayPointsCount; i++) {
+ _wayPoints[i].x = -1;
+ _wayPoints[i].y = -1;
+ _wayPoints[i].field_2 = -1;
+ }
+ for (i = 0; i < _wayPointsCount; i++) {
+ _wayPoints[i].x = *dataPtr++;
+ _wayPoints[i].y = *dataPtr++;
+ _wayPoints[i].field_2 = *dataPtr++;
}
-
- 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));
+ _passMap = (int8 *) variables;
+ mapHeight = 200 / _vm->_map->_tilesHeight;
+ mapWidth = _vm->_map->_screenWidth / _vm->_map->_tilesWidth;
+ for (i = 0; i < mapHeight; i++) {
+ offData = (mapWidth * i);
+ for (j = 0; j < mapWidth; j++) {
+ setPass(j, i, *(dataPtrBak + offData + j), _vm->_map->_passWidth);
}
}
}
@@ -189,4 +188,42 @@ void Map_v2::loadMapObjects(char *avjFile) {
_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
}
+void Map_v2::findNearestToGob(int16 index) {
+ Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+ int16 wayPoint = findNearestWayPoint(obj->goblinX, obj->goblinY);
+
+ if (wayPoint != -1)
+ obj->nearestWayPoint = wayPoint;
+}
+
+void Map_v2::findNearestToDest(int16 index) {
+ Mult::Mult_Object *obj = &_vm->_mult->_objects[index];
+ int16 wayPoint = findNearestWayPoint(obj->destX, obj->destY);
+
+ if (wayPoint != -1)
+ obj->nearestDest = wayPoint;
+}
+
+void Map_v2::optimizePoints(int16 index, int16 x, int16 y) {
+ Mult::Mult_Object *obj;
+ int i;
+
+ int16 var_2;
+
+ obj = &_vm->_mult->_objects[index];
+
+ if (obj->nearestWayPoint < obj->nearestDest) {
+ var_2 = obj->nearestWayPoint;
+ for (i = obj->nearestWayPoint; i <= obj->nearestDest; i++) {
+ if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+ obj->nearestWayPoint = i;
+ }
+ } else {
+ for (i = obj->nearestWayPoint; i >= obj->nearestDest && _wayPoints[i].field_2 != 1; i--) {
+ if (checkDirectPath(index, x, y, _wayPoints[i].x, _wayPoints[i].y) == 1)
+ obj->nearestWayPoint = i;
+ }
+ }
+}
+
} // End of namespace Gob
diff --git a/engines/gob/module.mk b/engines/gob/module.mk
index 9a8ba2c0ea..4841db606d 100644
--- a/engines/gob/module.mk
+++ b/engines/gob/module.mk
@@ -35,6 +35,8 @@ MODULE_OBJS := \
parse_v1.o \
parse_v2.o \
scenery.o \
+ scenery_v1.o \
+ scenery_v2.o \
sound.o \
timer.o \
util.o \
diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp
index 3960cb2b6a..93233bc35c 100644
--- a/engines/gob/mult.cpp
+++ b/engines/gob/mult.cpp
@@ -120,12 +120,6 @@ Mult::Mult(GobEngine *vm) : _vm(vm) {
}
_orderArray = 0;
- 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 d09260fa25..9afa65b447 100644
--- a/engines/gob/mult.h
+++ b/engines/gob/mult.h
@@ -23,6 +23,7 @@
#ifndef GOB_MULT_H
#define GOB_MULT_H
+#include "gob/gob.h"
#include "gob/sound.h"
#include "gob/video.h"
#include "gob/goblin.h"
@@ -77,10 +78,12 @@ public:
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
+ int8 destX; // New in GOB2
+ int8 destY; // New in GOB2
+ int8 gobDestX; // New in GOB2
+ int8 gobDestY; // New in GOB2
+ int8 nearestWayPoint; // New in GOB2
+ int8 nearestDest; // New in GOB2
Goblin::Gob2_State **goblinStates; // New in GOB2
};
@@ -202,12 +205,6 @@ public:
int8 *_orderArray;
- uint16 _word_2F2B1;
- uint16 _word_2F2AF;
- uint16 _word_2CC86;
- uint16 _word_2F22A;
- uint16 _word_2CC84;
-
void zeroMultData(void);
void checkFreeMult(void);
void interGetObjAnimSize(void);
diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp
index 032f1702eb..79269a1100 100644
--- a/engines/gob/mult_v2.cpp
+++ b/engines/gob/mult_v2.cpp
@@ -816,6 +816,7 @@ char Mult_v2::doSoundAnim(char stop, int16 frame) {
return stop;
}
+// "deplaceheros"
void Mult_v2::sub_62DD(int16 index) {
Mult_Object *animObj;
Mult_AnimKey *animKey;
@@ -952,6 +953,7 @@ void Mult_v2::sub_62DD(int16 index) {
WRITE_VAR(18 + index, frame);
}
+// "avancerperso"
void Mult_v2::sub_6A35(void) {
int i;
int j;
@@ -1273,7 +1275,6 @@ void Mult_v2::animate(void) {
void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq,
int16 channel) {
- 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);
@@ -1292,13 +1293,9 @@ void Mult_v2::freeMultKeys(void) {
char animCount;
char staticCount;
- warning("GOB2 Stub! Mult_v2::freeMultKeys()");
-
if (_multData2 == 0)
return;
- // loc_7323
-
staticCount = (_multData2->staticCount + 1) && 0x7F;
animCount = _multData2->animCount + 1;
diff --git a/engines/gob/music.cpp b/engines/gob/music.cpp
index 52b37e7206..a65aaeb0d1 100644
--- a/engines/gob/music.cpp
+++ b/engines/gob/music.cpp
@@ -1,6 +1,6 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2006 The ScummVM project
- * Original ADL-Player source Copyright (C) 2004 by Dorian Gray
+ * Original ADL-Player source Copyright (C) 2004 by Patrick Combet aka Dorian Gray
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -337,6 +337,12 @@ void Music::pollMusic(void) {
setVolume(channel, *(_playPos++));
setKey(channel, note, true, false);
break;
+ case 0x10:
+ warning("GOB2 Stub! ADL command 0x10");
+ break;
+ case 0x50:
+ warning("GOB2 Stub! ADL command 0x50");
+ break;
// Note on
case 0x90:
note = *(_playPos++);
@@ -364,17 +370,23 @@ void Music::pollMusic(void) {
break;
// Special
case 0xF0:
+ switch (instr & 0x0F) {
+ case 0xF: // End instruction
+ _ended = true;
+ break;
+ default:
+ warning("Unknown special command in ADL, stopping playback: %X", instr & 0x0F);
+ _repCount = 0;
+ _ended = true;
+ break;
+ }
break;
default:
- warning("Unknown command in ADL, stopping playback");
+ warning("Unknown command in ADL, stopping playback: %X", instr & 0xF0);
_repCount = 0;
_ended = true;
break;
}
- // End instruction
- if (instr == 0xFF) {
- _ended = true;
- }
// Temporization
tempo = *(_playPos++);
diff --git a/engines/gob/music.h b/engines/gob/music.h
index d736bc9ff5..0079c8f8a2 100644
--- a/engines/gob/music.h
+++ b/engines/gob/music.h
@@ -1,6 +1,6 @@
/* ScummVM - Scumm Interpreter
* Copyright (C) 2006 The ScummVM project
- * Original ADL-Player source Copyright (C) 2004 by Dorian Gray
+ * Original ADL-Player source Copyright (C) 2004 by Patrick Combet aka Dorian Gray
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -25,6 +25,7 @@
#define GOB_MUSIC_H
#include "sound/audiostream.h"
+#include "sound/mixer.h"
#include "sound/fmopl.h"
#include "common/mutex.h"
@@ -37,20 +38,20 @@ class GobEngine;
class Music : public Audio::AudioStream {
public:
Music(GobEngine *vm);
- ~Music();
+ virtual ~Music();
void lock() { _mutex.lock(); }
void unlock() { _mutex.unlock(); }
bool playing() { return _playing; }
bool getRepeating(void) { return _repCount != 0; }
void setRepeating (int32 repCount) { _repCount = repCount; }
- void startPlay(void);
- 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);
+ virtual void startPlay(void);
+ virtual void stopPlay(void) { _mutex.lock(); _playing = false; _mutex.unlock(); }
+ virtual void playTrack(const char *trackname);
+ virtual void playBgMusic(void);
+ virtual bool loadMusic(const char *filename);
+ virtual void loadFromMemory(byte *data);
+ virtual void unloadMusic(void);
// AudioStream API
int readBuffer(int16 *buffer, const int numSamples) {
@@ -96,6 +97,24 @@ protected:
void pollMusic(void);
};
+class Music_Dummy: public Music {
+public:
+ Music_Dummy(GobEngine *vm) : Music(vm) {
+ _vm->_mixer->setupPremix(0);
+ OPLDestroy(_opl);
+ }
+
+ virtual void startPlay(void) {};
+ virtual void stopPlay(void) {};
+ virtual void playTrack(const char *trackname) {};
+ virtual void playBgMusic(void) {};
+ virtual bool loadMusic(const char *filename) { return true; };
+ virtual void loadFromMemory(byte *data) {};
+ virtual void unloadMusic(void) {};
+
+ virtual ~Music_Dummy() {};
+};
+
} // End of namespace Gob
#endif
diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp
index 7079759a8e..328245e69e 100644
--- a/engines/gob/scenery.cpp
+++ b/engines/gob/scenery.cpp
@@ -32,7 +32,6 @@
#include "gob/game.h"
#include "gob/global.h"
#include "gob/util.h"
-#include "gob/anim.h"
#include "gob/parse.h"
#include "gob/cdrom.h"
@@ -489,212 +488,6 @@ int16 Scenery::loadAnim(char search) {
return sceneryIndex + 100;
}
-// flags & 1 - do capture all area animation is occupying
-// flags & 4 == 0 - calculate animation final size
-// flags & 2 != 0 - don't check with "toRedraw"'s
-// flags & 4 != 0 - checkk view toRedraw
-void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
- int16 drawDeltaX, int16 drawDeltaY, char doDraw) {
- AnimLayer *layerPtr;
- PieceDesc **pictPtr;
- AnimFramePiece *framePtr;
-
- uint16 pieceIndex;
- uint16 pictIndex;
-
- int16 left;
- int16 right;
- int16 top;
- int16 bottom;
-
- byte highX;
- byte highY;
-
- int16 i;
- int16 transp;
-
- int16 destX;
- int16 destY;
-
- if (layer >= _animations[animation].layersCount)
- return;
-
- layerPtr = _animations[animation].layers[layer];
-
- if (frame >= layerPtr->framesCount)
- return;
-
- if (flags & 1) // Do capture
- {
- updateAnim(layer, frame, animation, 0, drawDeltaX,
- drawDeltaY, 0);
-
- if (_toRedrawLeft == -12345) // Some magic number?
- return;
-
- _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
- _toRedrawRight - _toRedrawLeft + 1,
- _toRedrawBottom - _toRedrawTop + 1);
-
- *_pCaptureCounter = *_pCaptureCounter + 1;
- }
- pictPtr = _animations[animation].pieces;
- framePtr = layerPtr->frames;
-
- for (i = 0; i < frame; i++, framePtr++) {
- while (framePtr->notFinal == 1)
- framePtr++;
- }
-
- if ((flags & 4) == 0) {
- _toRedrawLeft = -12345;
- } else {
- _toRedrawLeft =
- MAX(_toRedrawLeft, _vm->_anim->_areaLeft);
- _toRedrawTop =
- MAX(_toRedrawTop, _vm->_anim->_areaTop);
- _toRedrawRight =
- MIN(_toRedrawRight,
- (int16)(_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1));
- _toRedrawBottom =
- MIN(_toRedrawBottom,
- (int16)(_vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1));
- }
-
- transp = layerPtr->transp ? 3 : 0;
-
- framePtr--;
- do {
- framePtr++;
-
- pieceIndex = framePtr->pieceIndex;
- pictIndex = framePtr->pictIndex;
-
- destX = framePtr->destX;
- destY = framePtr->destY;
-
- highX = pictIndex & 0xc0;
- highY = pictIndex & 0x30;
- highX >>= 6;
- highY >>= 4;
- if (destX >= 0)
- destX += ((uint16)highX) << 7;
- else
- destX -= ((uint16)highX) << 7;
-
- if (destY >= 0)
- destY += ((uint16)highY) << 7;
- else
- destY -= ((uint16)highY) << 7;
-
- if (drawDeltaX == 1000)
- destX += layerPtr->posX;
- else
- destX += drawDeltaX;
-
- if (drawDeltaY == 1000)
- destY += layerPtr->posY;
- else
- destY += drawDeltaY;
-
- pictIndex = (pictIndex & 15) - 1;
-
- left = FROM_LE_16(pictPtr[pictIndex][pieceIndex].left);
- right = FROM_LE_16(pictPtr[pictIndex][pieceIndex].right);
- top = FROM_LE_16(pictPtr[pictIndex][pieceIndex].top);
- bottom = FROM_LE_16(pictPtr[pictIndex][pieceIndex].bottom);
-
- if (flags & 2) {
- if (destX < _vm->_anim->_areaLeft) {
- left += _vm->_anim->_areaLeft - destX;
- destX = _vm->_anim->_areaLeft;
- }
-
- if (left <= right
- && destX + right - left >=
- _vm->_anim->_areaLeft + _vm->_anim->_areaWidth)
- right -=
- (destX + right - left) -
- (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth) +
- 1;
-
- if (destY < _vm->_anim->_areaTop) {
- top += _vm->_anim->_areaTop - destY;
- destY = _vm->_anim->_areaTop;
- }
-
- if (top <= bottom
- && destY + bottom - top >=
- _vm->_anim->_areaTop + _vm->_anim->_areaHeight)
- bottom -=
- (destY + bottom - top) -
- (_vm->_anim->_areaTop + _vm->_anim->_areaHeight) +
- 1;
-
- } else if (flags & 4) {
- if (destX < _toRedrawLeft) {
- left += _toRedrawLeft - destX;
- destX = _toRedrawLeft;
- }
-
- if (left <= right
- && destX + right - left > _toRedrawRight)
- right -=
- destX + right - left - _toRedrawRight;
-
- if (destY < _toRedrawTop) {
- top += _toRedrawTop - destY;
- destY = _toRedrawTop;
- }
-
- if (top <= bottom
- && destY + bottom - top > _toRedrawBottom)
- bottom -=
- destY + bottom - top - _toRedrawBottom;
- }
-
- if (left > right || top > bottom)
- continue;
-
- if (doDraw) {
- _vm->_draw->_sourceSurface =
- _animPictToSprite[animation * 7 + pictIndex];
- _vm->_draw->_destSurface = 21;
-
- _vm->_draw->_spriteLeft = left;
- _vm->_draw->_spriteTop = top;
- _vm->_draw->_spriteRight = right - left + 1;
- _vm->_draw->_spriteBottom = bottom - top + 1;
- _vm->_draw->_destSpriteX = destX;
- _vm->_draw->_destSpriteY = destY;
- _vm->_draw->_transparency = transp;
- _vm->_draw->spriteOperation(DRAW_BLITSURF);
- }
-
- if ((flags & 4) == 0) {
- if (_toRedrawLeft == -12345) {
- _toRedrawLeft = destX;
- _animLeft = destX;
- _toRedrawTop = destY;
- _animTop = destY;
- _toRedrawRight = destX + right - left;
- _toRedrawBottom = destY + bottom - top;
- } else {
- _toRedrawLeft =
- MIN(_toRedrawLeft, destX);
- _toRedrawTop =
- MIN(_toRedrawTop, destY);
- _toRedrawRight =
- MAX(_toRedrawRight,
- (int16)(destX + right - left));
- _toRedrawBottom =
- MAX(_toRedrawBottom,
- (int16)(destY + bottom - top));
- }
- }
- } while (framePtr->notFinal == 1);
-}
-
void Scenery::freeAnim(int16 animation) {
int16 i;
int16 spr;
@@ -729,23 +522,6 @@ void Scenery::freeAnim(int16 animation) {
_animPictCount[animation] = 0;
}
-void Scenery::interUpdateAnim(void) {
- int16 deltaX;
- int16 deltaY;
- int16 flags;
- int16 frame;
- int16 layer;
- int16 animation;
-
- _vm->_inter->evalExpr(&deltaX);
- _vm->_inter->evalExpr(&deltaY);
- _vm->_inter->evalExpr(&animation);
- _vm->_inter->evalExpr(&layer);
- _vm->_inter->evalExpr(&frame);
- flags = _vm->_inter->load16();
- updateAnim(layer, frame, animation, flags, deltaX, deltaY, 1);
-}
-
void Scenery::interStoreParams(void) {
AnimLayer *layerPtr;
int16 animation;
diff --git a/engines/gob/scenery.h b/engines/gob/scenery.h
index d361d24eaa..9e36556aef 100644
--- a/engines/gob/scenery.h
+++ b/engines/gob/scenery.h
@@ -119,6 +119,8 @@ public:
int16 _animTop;
int16 _animLeft;
+ int16 _animBottom;
+ int16 _animRight;
int16 *_pCaptureCounter;
@@ -129,18 +131,37 @@ public:
void renderStatic(int16 scenery, int16 layer);
void updateStatic(int16 orderFrom);
int16 loadAnim(char search);
- void updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
- int16 drawDeltaX, int16 drawDeltaY, char doDraw);
void freeAnim(int16 animation);
- void interUpdateAnim(void);
void interStoreParams(void);
+ virtual void updateAnim(int16 layer, int16 frame, int16 animation,
+ int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw) = 0;
+
Scenery(GobEngine *vm);
+ virtual ~Scenery() {};
protected:
GobEngine *_vm;
};
+class Scenery_v1 : public Scenery {
+public:
+ virtual void updateAnim(int16 layer, int16 frame, int16 animation,
+ int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw);
+
+ Scenery_v1(GobEngine *vm);
+ virtual ~Scenery_v1() {};
+};
+
+class Scenery_v2 : public Scenery_v1 {
+public:
+ virtual void updateAnim(int16 layer, int16 frame, int16 animation,
+ int16 flags, int16 drawDeltaX, int16 drawDeltaY, char doDraw);
+
+ Scenery_v2(GobEngine *vm);
+ virtual ~Scenery_v2() {};
+};
+
} // End of namespace Gob
#endif /* __SCENERY_H */
diff --git a/engines/gob/scenery_v1.cpp b/engines/gob/scenery_v1.cpp
new file mode 100644
index 0000000000..7904f0e3c4
--- /dev/null
+++ b/engines/gob/scenery_v1.cpp
@@ -0,0 +1,244 @@
+/* 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/scenery.h"
+#include "gob/anim.h"
+#include "gob/draw.h"
+#include "gob/game.h"
+
+namespace Gob {
+
+Scenery_v1::Scenery_v1(GobEngine *vm) : Scenery(vm) {
+}
+
+// flags & 1 - do capture all area animation is occupying
+// flags & 4 == 0 - calculate animation final size
+// flags & 2 != 0 - don't check with "toRedraw"'s
+// flags & 4 != 0 - checkk view toRedraw
+void Scenery_v1::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
+ int16 drawDeltaX, int16 drawDeltaY, char doDraw) {
+ AnimLayer *layerPtr;
+ PieceDesc **pictPtr;
+ AnimFramePiece *framePtr;
+
+ uint16 pieceIndex;
+ uint16 pictIndex;
+
+ int16 left;
+ int16 right;
+ int16 top;
+ int16 bottom;
+
+ byte highX;
+ byte highY;
+
+ int16 i;
+ int16 transp;
+
+ int16 destX;
+ int16 destY;
+
+ if (layer >= _animations[animation].layersCount)
+ return;
+
+ layerPtr = _animations[animation].layers[layer];
+
+ if (frame >= layerPtr->framesCount)
+ return;
+
+ if (flags & 1) // Do capture
+ {
+ updateAnim(layer, frame, animation, 0, drawDeltaX,
+ drawDeltaY, 0);
+
+ if (_toRedrawLeft == -12345) // Some magic number?
+ return;
+
+ _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
+ _toRedrawRight - _toRedrawLeft + 1,
+ _toRedrawBottom - _toRedrawTop + 1);
+
+ *_pCaptureCounter = *_pCaptureCounter + 1;
+ }
+ pictPtr = _animations[animation].pieces;
+ framePtr = layerPtr->frames;
+
+ for (i = 0; i < frame; i++, framePtr++) {
+ while (framePtr->notFinal == 1)
+ framePtr++;
+ }
+
+ if ((flags & 4) == 0) {
+ _toRedrawLeft = -12345;
+ } else {
+ _toRedrawLeft =
+ MAX(_toRedrawLeft, _vm->_anim->_areaLeft);
+ _toRedrawTop =
+ MAX(_toRedrawTop, _vm->_anim->_areaTop);
+ _toRedrawRight =
+ MIN(_toRedrawRight,
+ (int16)(_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1));
+ _toRedrawBottom =
+ MIN(_toRedrawBottom,
+ (int16)(_vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1));
+ }
+
+ transp = layerPtr->transp ? 3 : 0;
+
+ framePtr--;
+ do {
+ framePtr++;
+
+ pieceIndex = framePtr->pieceIndex;
+ pictIndex = framePtr->pictIndex;
+
+ destX = framePtr->destX;
+ destY = framePtr->destY;
+
+ highX = pictIndex & 0xc0;
+ highY = pictIndex & 0x30;
+ highX >>= 6;
+ highY >>= 4;
+ if (destX >= 0)
+ destX += ((uint16)highX) << 7;
+ else
+ destX -= ((uint16)highX) << 7;
+
+ if (destY >= 0)
+ destY += ((uint16)highY) << 7;
+ else
+ destY -= ((uint16)highY) << 7;
+
+ if (drawDeltaX == 1000)
+ destX += layerPtr->posX;
+ else
+ destX += drawDeltaX;
+
+ if (drawDeltaY == 1000)
+ destY += layerPtr->posY;
+ else
+ destY += drawDeltaY;
+
+ pictIndex = (pictIndex & 15) - 1;
+
+ left = FROM_LE_16(pictPtr[pictIndex][pieceIndex].left);
+ right = FROM_LE_16(pictPtr[pictIndex][pieceIndex].right);
+ top = FROM_LE_16(pictPtr[pictIndex][pieceIndex].top);
+ bottom = FROM_LE_16(pictPtr[pictIndex][pieceIndex].bottom);
+
+ if (flags & 2) {
+ if (destX < _vm->_anim->_areaLeft) {
+ left += _vm->_anim->_areaLeft - destX;
+ destX = _vm->_anim->_areaLeft;
+ }
+
+ if (left <= right
+ && destX + right - left >=
+ _vm->_anim->_areaLeft + _vm->_anim->_areaWidth)
+ right -=
+ (destX + right - left) -
+ (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth) +
+ 1;
+
+ if (destY < _vm->_anim->_areaTop) {
+ top += _vm->_anim->_areaTop - destY;
+ destY = _vm->_anim->_areaTop;
+ }
+
+ if (top <= bottom
+ && destY + bottom - top >=
+ _vm->_anim->_areaTop + _vm->_anim->_areaHeight)
+ bottom -=
+ (destY + bottom - top) -
+ (_vm->_anim->_areaTop + _vm->_anim->_areaHeight) +
+ 1;
+
+ } else if (flags & 4) {
+ if (destX < _toRedrawLeft) {
+ left += _toRedrawLeft - destX;
+ destX = _toRedrawLeft;
+ }
+
+ if (left <= right
+ && destX + right - left > _toRedrawRight)
+ right -=
+ destX + right - left - _toRedrawRight;
+
+ if (destY < _toRedrawTop) {
+ top += _toRedrawTop - destY;
+ destY = _toRedrawTop;
+ }
+
+ if (top <= bottom
+ && destY + bottom - top > _toRedrawBottom)
+ bottom -=
+ destY + bottom - top - _toRedrawBottom;
+ }
+
+ if (left > right || top > bottom)
+ continue;
+
+ if (doDraw) {
+ _vm->_draw->_sourceSurface =
+ _animPictToSprite[animation * 7 + pictIndex];
+ _vm->_draw->_destSurface = 21;
+
+ _vm->_draw->_spriteLeft = left;
+ _vm->_draw->_spriteTop = top;
+ _vm->_draw->_spriteRight = right - left + 1;
+ _vm->_draw->_spriteBottom = bottom - top + 1;
+ _vm->_draw->_destSpriteX = destX;
+ _vm->_draw->_destSpriteY = destY;
+ _vm->_draw->_transparency = transp;
+ _vm->_draw->spriteOperation(DRAW_BLITSURF);
+ }
+
+ if ((flags & 4) == 0) {
+ if (_toRedrawLeft == -12345) {
+ _toRedrawLeft = destX;
+ _animLeft = destX;
+ _toRedrawTop = destY;
+ _animTop = destY;
+ _toRedrawRight = destX + right - left;
+ _toRedrawBottom = destY + bottom - top;
+ } else {
+ _toRedrawLeft =
+ MIN(_toRedrawLeft, destX);
+ _toRedrawTop =
+ MIN(_toRedrawTop, destY);
+ _toRedrawRight =
+ MAX(_toRedrawRight,
+ (int16)(destX + right - left));
+ _toRedrawBottom =
+ MAX(_toRedrawBottom,
+ (int16)(destY + bottom - top));
+ }
+ }
+ } while (framePtr->notFinal == 1);
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/scenery_v2.cpp b/engines/gob/scenery_v2.cpp
new file mode 100644
index 0000000000..4c523522ed
--- /dev/null
+++ b/engines/gob/scenery_v2.cpp
@@ -0,0 +1,251 @@
+/* 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/scenery.h"
+#include "gob/anim.h"
+#include "gob/draw.h"
+#include "gob/game.h"
+
+namespace Gob {
+
+Scenery_v2::Scenery_v2(GobEngine *vm) : Scenery_v1(vm) {
+}
+
+// flags & 1 - do capture all area animation is occupying
+// flags & 4 == 0 - calculate animation final size
+// flags & 2 != 0 - don't check with "toRedraw"'s
+// flags & 4 != 0 - checkk view toRedraw
+void Scenery_v2::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
+ int16 drawDeltaX, int16 drawDeltaY, char doDraw) {
+ AnimLayer *layerPtr;
+ PieceDesc **pictPtr;
+ AnimFramePiece *framePtr;
+
+ uint16 pieceIndex;
+ uint16 pictIndex;
+
+ int16 left;
+ int16 right;
+ int16 top;
+ int16 bottom;
+
+ byte highX;
+ byte highY;
+
+ int16 i;
+ int16 transp;
+
+ int16 destX;
+ int16 destY;
+
+ if ((_animPictCount[animation] == 0) || (layer < 0))
+ return;
+ if (layer >= _animations[animation].layersCount)
+ return;
+
+ layerPtr = _animations[animation].layers[layer];
+
+ if (frame >= layerPtr->framesCount)
+ return;
+
+ if (flags & 1) // Do capture
+ {
+ updateAnim(layer, frame, animation, 0, drawDeltaX,
+ drawDeltaY, 0);
+
+ if (_toRedrawLeft == -12345) // Some magic number?
+ return;
+
+ _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
+ _toRedrawRight - _toRedrawLeft + 1,
+ _toRedrawBottom - _toRedrawTop + 1);
+
+ *_pCaptureCounter = *_pCaptureCounter + 1;
+ }
+
+ pictPtr = _animations[animation].pieces;
+ framePtr = layerPtr->frames;
+
+ for (i = 0; i < frame; i++, framePtr++) {
+ while (framePtr->notFinal == 1)
+ framePtr++;
+ }
+
+ if ((flags & 4) == 0) {
+ _toRedrawLeft = -12345;
+ } else {
+ _toRedrawLeft =
+ MAX(_toRedrawLeft, _vm->_anim->_areaLeft);
+ _toRedrawTop =
+ MAX(_toRedrawTop, _vm->_anim->_areaTop);
+ _toRedrawRight =
+ MIN(_toRedrawRight,
+ (int16)(_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1));
+ _toRedrawBottom =
+ MIN(_toRedrawBottom,
+ (int16)(_vm->_anim->_areaTop + _vm->_anim->_areaHeight - 1));
+ }
+
+ transp = layerPtr->transp ? 3 : 0;
+
+ framePtr--;
+ do {
+ framePtr++;
+
+ pieceIndex = framePtr->pieceIndex;
+ pictIndex = framePtr->pictIndex;
+
+ destX = framePtr->destX;
+ destY = framePtr->destY;
+
+ highX = pictIndex & 0xc0;
+ highY = pictIndex & 0x30;
+ highX >>= 6;
+ highY >>= 4;
+ if (destX >= 0)
+ destX += ((uint16)highX) << 7;
+ else
+ destX -= ((uint16)highX) << 7;
+
+ if (destY >= 0)
+ destY += ((uint16)highY) << 7;
+ else
+ destY -= ((uint16)highY) << 7;
+
+ if (drawDeltaX == 1000)
+ destX += layerPtr->posX;
+ else
+ destX += drawDeltaX;
+
+ if (drawDeltaY == 1000)
+ destY += layerPtr->posY;
+ else
+ destY += drawDeltaY;
+
+ pictIndex = (pictIndex & 15) - 1;
+
+ left = FROM_LE_16(pictPtr[pictIndex][pieceIndex].left);
+ right = FROM_LE_16(pictPtr[pictIndex][pieceIndex].right);
+ top = FROM_LE_16(pictPtr[pictIndex][pieceIndex].top);
+ bottom = FROM_LE_16(pictPtr[pictIndex][pieceIndex].bottom);
+
+ if (flags & 2) {
+ if (destX < _vm->_anim->_areaLeft) {
+ left += _vm->_anim->_areaLeft - destX;
+ destX = _vm->_anim->_areaLeft;
+ }
+
+ if (left <= right
+ && destX + right - left >=
+ _vm->_anim->_areaLeft + _vm->_anim->_areaWidth)
+ right -=
+ (destX + right - left) -
+ (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth) +
+ 1;
+
+ if (destY < _vm->_anim->_areaTop) {
+ top += _vm->_anim->_areaTop - destY;
+ destY = _vm->_anim->_areaTop;
+ }
+
+ if (top <= bottom
+ && destY + bottom - top >=
+ _vm->_anim->_areaTop + _vm->_anim->_areaHeight)
+ bottom -=
+ (destY + bottom - top) -
+ (_vm->_anim->_areaTop + _vm->_anim->_areaHeight) +
+ 1;
+
+ } else if (flags & 4) {
+ if (destX < _toRedrawLeft) {
+ left += _toRedrawLeft - destX;
+ destX = _toRedrawLeft;
+ }
+
+ if (left <= right
+ && destX + right - left > _toRedrawRight)
+ right -=
+ destX + right - left - _toRedrawRight;
+
+ if (destY < _toRedrawTop) {
+ top += _toRedrawTop - destY;
+ destY = _toRedrawTop;
+ }
+
+ if (top <= bottom
+ && destY + bottom - top > _toRedrawBottom)
+ bottom -=
+ destY + bottom - top - _toRedrawBottom;
+ }
+
+ // ---
+
+ if (left > right || top > bottom)
+ continue;
+
+ if (doDraw) {
+ _vm->_draw->_sourceSurface =
+ _animPictToSprite[animation * 7 + pictIndex];
+ _vm->_draw->_destSurface = 21;
+
+ _vm->_draw->_spriteLeft = left;
+ _vm->_draw->_spriteTop = top;
+ _vm->_draw->_spriteRight = right - left + 1;
+ _vm->_draw->_spriteBottom = bottom - top + 1;
+ _vm->_draw->_destSpriteX = destX;
+ _vm->_draw->_destSpriteY = destY;
+ _vm->_draw->_transparency = transp;
+ _vm->_draw->spriteOperation(DRAW_DRAWLETTER);
+ }
+
+ if ((flags & 4) == 0) {
+ if (_toRedrawLeft == -12345) {
+ _toRedrawLeft = destX;
+ _animLeft = destX;
+ _toRedrawTop = destY;
+ _animTop = destY;
+ _toRedrawRight = destX + right - left;
+ _animRight = destX + right - left;
+ _toRedrawBottom = destY + bottom - top;
+ _animBottom = destY + bottom - top;
+ } else {
+ _toRedrawLeft =
+ MIN(_toRedrawLeft, destX);
+ _toRedrawTop =
+ MIN(_toRedrawTop, destY);
+ _toRedrawRight =
+ MAX(_toRedrawRight,
+ (int16)(destX + right - left));
+ _toRedrawBottom =
+ MAX(_toRedrawBottom,
+ (int16)(destY + bottom - top));
+ }
+ }
+ } while (framePtr->notFinal == 1);
+}
+
+} // End of namespace Gob
diff --git a/engines/gob/sound.cpp b/engines/gob/sound.cpp
index 6a7446d63d..0c1e612b9f 100644
--- a/engines/gob/sound.cpp
+++ b/engines/gob/sound.cpp
@@ -99,7 +99,7 @@ void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) {
frequency = sndDesc->frequency;
if (frequency <= 0) {
- warning("Attempted to play a sample with a frequency of %d", frequency);
+ warning("Attempted to play a sample with a frequency of %d (sndDesc->freq = %d)", frequency, sndDesc->frequency);
return;
}
// assert(frequency > 0);
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 64426c8fd5..f0caaf04a1 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -246,6 +246,7 @@ void Util::setFrameRate(int16 rate) {
_vm->_global->_frameWaitTime = 1000 / rate;
_vm->_global->_startFrameTime = getTimeKey();
+ _vm->_game->_dword_2F2B6 = 0;
}
void Util::waitEndFrame() {
@@ -256,12 +257,15 @@ void Util::waitEndFrame() {
time = getTimeKey() - _vm->_global->_startFrameTime;
if (time > 1000 || time < 0) {
_vm->_global->_startFrameTime = getTimeKey();
+ _vm->_game->_dword_2F2B6 = 0;
return;
}
if (_vm->_global->_frameWaitTime - time > 0) {
- delay(_vm->_global->_frameWaitTime - time);
+ _vm->_game->_dword_2F2B6 = 0;
+ delay(_vm->_global->_frameWaitTime - _vm->_game->_dword_2F2B6 - time);
}
_vm->_global->_startFrameTime = getTimeKey();
+ _vm->_game->_dword_2F2B6 = time - _vm->_global->_frameWaitTime;
}
int16 joy_getState() {