From 2768fa24fc809168784d3cde79fcb4ac6ad513c0 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Tue, 21 Nov 2006 13:28:45 +0000 Subject: - Fixed the crashes in Gob1 EGA and Gob2 Demo - Fixed the compile error in GobEngine::saveGame on some systems svn-id: r24756 --- engines/gob/draw_v1.cpp | 4 ++++ engines/gob/game.cpp | 7 ++++++- engines/gob/game.h | 2 +- engines/gob/game_v2.cpp | 34 +++++++++++++++++++++++++--------- engines/gob/gob.cpp | 4 ++-- engines/gob/inter_v2.cpp | 10 +++++++--- engines/gob/mult.h | 2 +- engines/gob/mult_v2.cpp | 9 ++++++--- 8 files changed, 52 insertions(+), 20 deletions(-) (limited to 'engines') 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) { -- cgit v1.2.3