aboutsummaryrefslogtreecommitdiff
path: root/engines/gob
diff options
context:
space:
mode:
authorSven Hesse2006-11-21 13:28:45 +0000
committerSven Hesse2006-11-21 13:28:45 +0000
commit2768fa24fc809168784d3cde79fcb4ac6ad513c0 (patch)
tree5448797e78304046d294c06fab37cbdafc0e36aa /engines/gob
parentfada662a1f01a18dc020b5af02798d47650f7a4a (diff)
downloadscummvm-rg350-2768fa24fc809168784d3cde79fcb4ac6ad513c0.tar.gz
scummvm-rg350-2768fa24fc809168784d3cde79fcb4ac6ad513c0.tar.bz2
scummvm-rg350-2768fa24fc809168784d3cde79fcb4ac6ad513c0.zip
- Fixed the crashes in Gob1 EGA and Gob2 Demo
- Fixed the compile error in GobEngine::saveGame on some systems svn-id: r24756
Diffstat (limited to 'engines/gob')
-rw-r--r--engines/gob/draw_v1.cpp4
-rw-r--r--engines/gob/game.cpp7
-rw-r--r--engines/gob/game.h2
-rw-r--r--engines/gob/game_v2.cpp34
-rw-r--r--engines/gob/gob.cpp4
-rw-r--r--engines/gob/inter_v2.cpp10
-rw-r--r--engines/gob/mult.h2
-rw-r--r--engines/gob/mult_v2.cpp9
8 files changed, 52 insertions, 20 deletions
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 5b799dff3f..2b3dcf313d 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -329,6 +329,10 @@ void Draw_v1::spriteOperation(int16 operation) {
}
delete[] dataBuf;
break;
+ } else if (id >= _vm->_game->_totResourceTable->itemsCount) {
+ warning("Trying to load non-existent sprite (id = %d, count = %d)", id,
+ _vm->_game->_totResourceTable->itemsCount);
+ break;
}
// Load from .TOT resources
itemPtr = &_vm->_game->_totResourceTable->items[id];
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp
index 0807eb0094..e4c4b2fc2a 100644
--- a/engines/gob/game.cpp
+++ b/engines/gob/game.cpp
@@ -366,16 +366,21 @@ int16 Game::adjustKey(int16 key) {
return key - 0x20;
}
-void Game::loadTotFile(char *path) {
+int32 Game::loadTotFile(char *path) {
int16 handle;
+ int32 size;
+ size = -1;
handle = _vm->_dataio->openData(path);
if (handle >= 0) {
_vm->_dataio->closeData(handle);
+ size = _vm->_dataio->getDataSize(path);
_totFileData = _vm->_dataio->getData(path);
} else {
_totFileData = 0;
}
+
+ return size;
}
void Game::loadExtTable(void) {
diff --git a/engines/gob/game.h b/engines/gob/game.h
index 8097c577c9..73d491afb1 100644
--- a/engines/gob/game.h
+++ b/engines/gob/game.h
@@ -196,7 +196,7 @@ public:
void loadSound(int16 slot, char *dataPtr);
int16 adjustKey(int16 key);
- void loadTotFile(char *path);
+ int32 loadTotFile(char *path);
void loadExtTable(void);
void loadImFile(void);
void start(void);
diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp
index 696ecfa0d5..80dfa5c50f 100644
--- a/engines/gob/game_v2.cpp
+++ b/engines/gob/game_v2.cpp
@@ -54,6 +54,7 @@ void Game_v2::playTot(int16 skipPlay) {
int16 breakFrom;
int16 nestLevel;
int32 variablesCount;
+ int32 totSize;
char *filePtr;
char *savedIP;
int16 i;
@@ -112,7 +113,7 @@ void Game_v2::playTot(int16 skipPlay) {
if (_curTotFile[0] == 0 && _totFileData == 0)
break;
- loadTotFile(_curTotFile);
+ totSize = loadTotFile(_curTotFile);
if (_totFileData == 0) {
_vm->_draw->blitCursor();
_vm->_inter->_terminate = 2;
@@ -159,20 +160,35 @@ void Game_v2::playTot(int16 skipPlay) {
filePtr = (char *)_totFileData + 0x34;
_totResourceTable = 0;
+ int32 resSize;
if (READ_LE_UINT32(filePtr) != (uint32)-1) {
_totResourceTable = new TotResTable;
_totResourceTable->dataPtr = _totFileData + READ_LE_UINT32((char *)_totFileData + 0x34);
Common::MemoryReadStream totResTable((byte *) _totResourceTable->dataPtr, 4294967295U);
_totResourceTable->itemsCount = totResTable.readSint16LE();
- _totResourceTable->unknown = totResTable.readByte();
-
- _totResourceTable->items = new TotResItem[_totResourceTable->itemsCount];
- for (i = 0; i < _totResourceTable->itemsCount; ++i) {
- _totResourceTable->items[i].offset = totResTable.readSint32LE();
- _totResourceTable->items[i].size = totResTable.readSint16LE();
- _totResourceTable->items[i].width = totResTable.readSint16LE();
- _totResourceTable->items[i].height = totResTable.readSint16LE();
+ resSize = _totResourceTable->itemsCount * szGame_TotResItem + szGame_TotResTable;
+ if (totSize > (resSize + 0x34)) {
+ _totResourceTable->unknown = totResTable.readByte();
+
+ _totResourceTable->items = new TotResItem[_totResourceTable->itemsCount];
+ for (i = 0; i < _totResourceTable->itemsCount; ++i) {
+ _totResourceTable->items[i].offset = totResTable.readSint32LE();
+ _totResourceTable->items[i].size = totResTable.readSint16LE();
+ _totResourceTable->items[i].width = totResTable.readSint16LE();
+ _totResourceTable->items[i].height = totResTable.readSint16LE();
+ }
+ }
+ else {
+ // WORKAROUND: In the original asm, _totResourceTable is only assigned
+ // in playTot and evaluated later, right before using it. In the
+ // Gobliins 2 demo, there is a dummy tot that loads another tot, overwriting
+ // the dummy pointer with the real one.
+ debugC(1, DEBUG_FILEIO,
+ "Attempted to load invalid resource table (size = %d, totSize = %d)",
+ resSize, totSize);
+ delete _totResourceTable;
+ _totResourceTable = 0;
}
}
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 20b040ee93..87d9633563 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -229,7 +229,7 @@ void GobEngine::shutdown() {
}
void GobEngine::writeVarDebug(uint32 offs, uint32 v) {
- warning("Setting var %d(%d) to %d", offs, offs >> 2, v);
+ warning("Setting var %u(%u) to %u", offs, offs >> 2, v);
(*(uint32 *)(_global->_inter_variables + (offs))) = v;
}
@@ -314,7 +314,7 @@ void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
else
iSize = 0;
- oOff = offset < 0 ? MAX(0, iSize - (-offset - 1)) : offset;
+ oOff = offset < 0 ? MAX((int32) 0, iSize - (-offset - 1)) : offset;
oSize = MAX(iSize, oOff + ABS(size));
oBuf = new char[oSize];
memset(oBuf, 0, oSize);
diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp
index 963dcaa27a..0d05f659dd 100644
--- a/engines/gob/inter_v2.cpp
+++ b/engines/gob/inter_v2.cpp
@@ -1948,6 +1948,7 @@ void Inter_v2::o2_initMult(void) {
else
delete _vm->_anim->_animSurf;
_vm->_draw->_spritesArray[22] = 0;
+ _vm->_anim->_animSurf = 0;
}
_vm->_draw->adjustCoords(0, &_vm->_anim->_areaWidth, &_vm->_anim->_areaHeight);
@@ -1962,17 +1963,20 @@ void Inter_v2::o2_initMult(void) {
_vm->_anim->_animSurf->vidPtr += 0x0C000;
_vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf;
} else {
- if (_vm->_global->_videoMode == 20) {
+ if ((_vm->_global->_videoMode == 0x13) && _vm->_video->_extraMode) {
if (((_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height) / 2
+ (_vm->_anim->_areaWidth * _vm->_anim->_areaHeight) / 4) < 65536) {
- _vm->_anim->_animSurf = new Video::SurfaceDesc;
+ warning("GOB2 Stub! Inter_v2::o2_initMult(), wide frontSurface, using the extra space as animSurf");
+/* _vm->_anim->_animSurf = new Video::SurfaceDesc;
memcpy(_vm->_anim->_animSurf, _vm->_draw->_frontSurface, sizeof(Video::SurfaceDesc));
_vm->_anim->_animSurf->width = (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1) | 7;
_vm->_anim->_animSurf->width -= (_vm->_anim->_areaLeft & 0x0FF8) - 1;
_vm->_anim->_animSurf->height = _vm->_anim->_areaHeight;
_vm->_anim->_animSurf->vidPtr = _vm->_draw->_backSurface->vidPtr +
_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height / 4;
- _vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf;
+ _vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf;*/
+ _vm->_draw->initBigSprite(22, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0);
+ _vm->_anim->_animSurf = _vm->_draw->_spritesArray[22];
} else
_vm->_draw->initBigSprite(22, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0);
_vm->_anim->_animSurf = _vm->_draw->_spritesArray[22];
diff --git a/engines/gob/mult.h b/engines/gob/mult.h
index c6602b89a6..c8adfd3443 100644
--- a/engines/gob/mult.h
+++ b/engines/gob/mult.h
@@ -36,7 +36,7 @@ public:
struct Mult_AnimData {
int8 animation;
- int8 layer;
+ uint8 layer;
int8 frame;
int8 animType;
int8 order;
diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp
index 20b61626e8..c92aae8504 100644
--- a/engines/gob/mult_v2.cpp
+++ b/engines/gob/mult_v2.cpp
@@ -476,14 +476,17 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
if ((_vm->_global->_videoMode == 0x13) && _vm->_video->_extraMode &&
((_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height) / 2
+ (_vm->_anim->_areaWidth * _vm->_anim->_areaHeight) / 4) < 64000) {
- _vm->_anim->_animSurf = new Video::SurfaceDesc;
+ warning("GOB2 Stub! Mult_v2::playMult(), wide frontSurface, using the extra space as animSurf");
+/* _vm->_anim->_animSurf = new Video::SurfaceDesc;
memcpy(_vm->_anim->_animSurf, _vm->_draw->_frontSurface, sizeof(Video::SurfaceDesc));
_vm->_anim->_animSurf->width = (_vm->_anim->_areaLeft + _vm->_anim->_areaWidth - 1) | 7;
_vm->_anim->_animSurf->width -= (_vm->_anim->_areaLeft & 0x0FFF8) - 1;
_vm->_anim->_animSurf->height = _vm->_anim->_areaHeight;
_vm->_anim->_animSurf->vidPtr +=
(_vm->_draw->_backSurface->width * _vm->_draw->_backSurface->height) / 2;
- _vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf;
+ _vm->_draw->_spritesArray[22] = _vm->_anim->_animSurf;*/
+ _vm->_draw->initBigSprite(22, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0);
+ _vm->_anim->_animSurf = _vm->_draw->_spritesArray[22];
} else {
_vm->_draw->initBigSprite(22, _vm->_anim->_areaWidth, _vm->_anim->_areaHeight, 0);
_vm->_anim->_animSurf = _vm->_draw->_spritesArray[22];
@@ -1333,6 +1336,7 @@ void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq,
void Mult_v2::freeMult(void) {
if (_vm->_anim->_animSurf != 0)
delete _vm->_anim->_animSurf;
+ _vm->_anim->_animSurf = 0;
delete[] _objects;
delete[] _renderData2;
@@ -1341,7 +1345,6 @@ void Mult_v2::freeMult(void) {
_objects = 0;
_renderData2 = 0;
_orderArray = 0;
- _vm->_anim->_animSurf = 0;
}
void Mult_v2::freeMultKeys(void) {