Wrapping resources (out of TOT, EXT, IM? and EX? files) loading into its own class

svn-id: r41839
This commit is contained in:
Sven Hesse 2009-06-24 21:49:37 +00:00
parent ef33f98a1a
commit d03dc08b64
27 changed files with 1355 additions and 1051 deletions

View File

@ -32,6 +32,7 @@
#include "gob/global.h" #include "gob/global.h"
#include "gob/util.h" #include "gob/util.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/resources.h"
#include "gob/scenery.h" #include "gob/scenery.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/sound/sound.h" #include "gob/sound/sound.h"
@ -173,12 +174,12 @@ void Draw_v1::printTotText(int16 id) {
_vm->_sound->cdPlayMultMusic(); _vm->_sound->cdPlayMultMusic();
if (!_vm->_game->_totTextData || !_vm->_game->_totTextData->dataPtr) TextItem *textItem = _vm->_game->_resources->getTextItem(id);
if (!textItem)
return; return;
dataPtr = _vm->_game->_totTextData->dataPtr + dataPtr = textItem->getData();
_vm->_game->_totTextData->items[id].offset; ptr = dataPtr;
ptr = dataPtr;
destX = READ_LE_UINT16(ptr) & 0x7FFF; destX = READ_LE_UINT16(ptr) & 0x7FFF;
destY = READ_LE_UINT16(ptr + 2); destY = READ_LE_UINT16(ptr + 2);
@ -312,7 +313,9 @@ void Draw_v1::printTotText(int16 id) {
} }
} }
delete textItem;
_renderFlags = savedFlags; _renderFlags = savedFlags;
if (_renderFlags & RENDERFLAG_COLLISIONS) if (_renderFlags & RENDERFLAG_COLLISIONS)
_vm->_game->checkCollisions(0, 0, 0, 0); _vm->_game->checkCollisions(0, 0, 0, 0);
@ -323,11 +326,10 @@ void Draw_v1::printTotText(int16 id) {
} }
void Draw_v1::spriteOperation(int16 operation) { void Draw_v1::spriteOperation(int16 operation) {
uint16 id;
byte *dataBuf;
int16 len; int16 len;
int16 x, y; int16 x, y;
int16 perLine; int16 perLine;
Resource *resource;
if (_sourceSurface >= 100) if (_sourceSurface >= 100)
_sourceSurface -= 80; _sourceSurface -= 80;
@ -396,30 +398,20 @@ void Draw_v1::spriteOperation(int16 operation) {
break; break;
case DRAW_LOADSPRITE: case DRAW_LOADSPRITE:
id = _spriteLeft; resource = _vm->_game->_resources->getResource((uint16) _spriteLeft,
if (id >= 30000) { &_spriteRight, &_spriteBottom);
dataBuf =
_vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom);
_vm->_video->drawPackedSprite(dataBuf,
_spriteRight, _spriteBottom,
_destSpriteX, _destSpriteY,
_transparency, *_spritesArray[_destSurface]);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
delete[] dataBuf;
break;
}
if (!(dataBuf = _vm->_game->loadTotResource(id, 0, &_spriteRight, &_spriteBottom))) if (!resource)
break; break;
_vm->_video->drawPackedSprite(dataBuf, _vm->_video->drawPackedSprite(resource->getData(),
_spriteRight, _spriteBottom, _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
_destSpriteX, _destSpriteY, _transparency, *_spritesArray[_destSurface]);
_transparency, *_spritesArray[_destSurface]);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
delete resource;
break; break;
case DRAW_PRINTTEXT: case DRAW_PRINTTEXT:

View File

@ -33,6 +33,7 @@
#include "gob/util.h" #include "gob/util.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/scenery.h" #include "gob/scenery.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/video.h" #include "gob/video.h"
@ -206,12 +207,6 @@ void Draw_v2::printTotText(int16 id) {
id &= 0xFFF; id &= 0xFFF;
if (!_vm->_game->_totTextData || !_vm->_game->_totTextData->dataPtr ||
(id >= _vm->_game->_totTextData->itemsCount) ||
(_vm->_game->_totTextData->items[id].offset == 0xFFFF) ||
(_vm->_game->_totTextData->items[id].size == 0))
return;
_vm->validateLanguage(); _vm->validateLanguage();
// WORKAROUND: In the scripts of some Gobliins 2 versions, the dialog text IDs // WORKAROUND: In the scripts of some Gobliins 2 versions, the dialog text IDs
@ -235,14 +230,19 @@ void Draw_v2::printTotText(int16 id) {
} }
size = _vm->_game->_totTextData->items[id].size; TextItem *textItem = _vm->_game->_resources->getTextItem(id);
dataPtr = _vm->_game->_totTextData->dataPtr + if (!textItem)
_vm->_game->_totTextData->items[id].offset;
ptr = dataPtr;
if ((_renderFlags & RENDERFLAG_SKIPOPTIONALTEXT) && (ptr[1] & 0x80))
return; return;
size = textItem->getSize();
dataPtr = textItem->getData();
ptr = dataPtr;
if ((_renderFlags & RENDERFLAG_SKIPOPTIONALTEXT) && (ptr[1] & 0x80)) {
delete textItem;
return;
}
if (_renderFlags & RENDERFLAG_DOUBLECOORDS) { if (_renderFlags & RENDERFLAG_DOUBLECOORDS) {
destX = (READ_LE_UINT16(ptr) & 0x7FFF) * 2; destX = (READ_LE_UINT16(ptr) & 0x7FFF) * 2;
spriteRight = READ_LE_UINT16(ptr + 4) * 2 + 1; spriteRight = READ_LE_UINT16(ptr + 4) * 2 + 1;
@ -525,7 +525,7 @@ void Draw_v2::printTotText(int16 id) {
case 10: case 10:
str[0] = (char) 255; str[0] = (char) 255;
WRITE_LE_UINT16((uint16 *) (str + 1), WRITE_LE_UINT16((uint16 *) (str + 1),
ptr - _vm->_game->_totTextData->dataPtr); ptr - _vm->_game->_resources->getTexts());
str[3] = 0; str[3] = 0;
ptr++; ptr++;
for (int i = *ptr++; i > 0; i--) { for (int i = *ptr++; i > 0; i--) {
@ -598,7 +598,9 @@ void Draw_v2::printTotText(int16 id) {
} }
} }
delete textItem;
_renderFlags = savedFlags; _renderFlags = savedFlags;
if (!(_renderFlags & RENDERFLAG_COLLISIONS)) if (!(_renderFlags & RENDERFLAG_COLLISIONS))
return; return;
@ -611,14 +613,13 @@ void Draw_v2::printTotText(int16 id) {
} }
void Draw_v2::spriteOperation(int16 operation) { void Draw_v2::spriteOperation(int16 operation) {
uint16 id;
byte *dataBuf;
int16 len; int16 len;
int16 x, y; int16 x, y;
SurfaceDescPtr sourceSurf, destSurf; SurfaceDescPtr sourceSurf, destSurf;
bool deltaVeto; bool deltaVeto;
int16 left; int16 left;
int16 ratio; int16 ratio;
Resource *resource;
// Always assigned to -1 in Game::loadTotFile() // Always assigned to -1 in Game::loadTotFile()
int16 someHandle = -1; int16 someHandle = -1;
@ -761,41 +762,20 @@ void Draw_v2::spriteOperation(int16 operation) {
break; break;
case DRAW_LOADSPRITE: case DRAW_LOADSPRITE:
id = _spriteLeft; resource = _vm->_game->_resources->getResource((uint16) _spriteLeft,
&_spriteRight, &_spriteBottom);
if ((id >= 30000) || (_vm->_game->_lomHandle >= 0)) { if (!resource)
dataBuf = 0;
if (_vm->_game->_lomHandle >= 0)
warning("Urban Stub: LOADSPRITE %d, LOM", id);
else
dataBuf = _vm->_game->loadExtData(id, &_spriteRight, &_spriteBottom);
if (!dataBuf)
break;
_vm->_video->drawPackedSprite(dataBuf,
_spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
_transparency, *_spritesArray[_destSurface]);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
delete[] dataBuf;
break;
}
// Load from .TOT resources
if (!(dataBuf = _vm->_game->loadTotResource(id, 0, &_spriteRight, &_spriteBottom)))
break; break;
_vm->_video->drawPackedSprite(dataBuf, _vm->_video->drawPackedSprite(resource->getData(),
_spriteRight, _spriteBottom, _spriteRight, _spriteBottom, _destSpriteX, _destSpriteY,
_destSpriteX, _destSpriteY, _transparency, *_spritesArray[_destSurface]);
_transparency, *_spritesArray[_destSurface]);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY, dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
_destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1); _destSpriteX + _spriteRight - 1, _destSpriteY + _spriteBottom - 1);
delete resource;
break; break;
case DRAW_PRINTTEXT: case DRAW_PRINTTEXT:
@ -808,7 +788,7 @@ void Draw_v2::spriteOperation(int16 operation) {
if (((int8) _textToPrint[0]) == -1) { if (((int8) _textToPrint[0]) == -1) {
_vm->validateLanguage(); _vm->validateLanguage();
dataBuf = _vm->_game->_totTextData->dataPtr + _textToPrint[1] + 1; byte *dataBuf = _vm->_game->_resources->getTexts() + _textToPrint[1] + 1;
len = *dataBuf++; len = *dataBuf++;
for (int i = 0; i < len; i++, dataBuf += 2) { for (int i = 0; i < len; i++, dataBuf += 2) {
_vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX, _vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX,

View File

@ -32,6 +32,7 @@
#include "gob/util.h" #include "gob/util.h"
#include "gob/dataio.h" #include "gob/dataio.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/mult.h" #include "gob/mult.h"
@ -41,19 +42,11 @@
namespace Gob { namespace Gob {
Game::Game(GobEngine *vm) : _vm(vm) { Game::Game(GobEngine *vm) : _vm(vm) {
_extTable = 0;
_totResourceTable = 0;
_imFileData = 0;
_extHandle = 0;
_lomHandle = -1;
_collisionAreas = 0; _collisionAreas = 0;
_shouldPushColls = 0; _shouldPushColls = 0;
_captureCount = 0; _captureCount = 0;
_foundTotLoc = false;
_totTextData = 0;
_collStackSize = 0; _collStackSize = 0;
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
@ -62,7 +55,6 @@ Game::Game(GobEngine *vm) : _vm(vm) {
} }
_curTotFile[0] = 0; _curTotFile[0] = 0;
_curExtFile[0] = 0;
_totToLoad[0] = 0; _totToLoad[0] = 0;
_startTimeKey = 0; _startTimeKey = 0;
@ -84,7 +76,6 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_noCd = false; _noCd = false;
_tempStr[0] = 0; _tempStr[0] = 0;
_curImaFile[0] = 0;
_collStr[0] = 0; _collStr[0] = 0;
_backupedCount = 0; _backupedCount = 0;
@ -93,131 +84,19 @@ Game::Game(GobEngine *vm) : _vm(vm) {
for (int i = 0; i < 5; i++) { for (int i = 0; i < 5; i++) {
_cursorHotspotXArray[i] = 0; _cursorHotspotXArray[i] = 0;
_cursorHotspotYArray[i] = 0; _cursorHotspotYArray[i] = 0;
_totTextDataArray[i] = 0;
_totResourceTableArray[i] = 0;
_extTableArray[i] = 0;
_extHandleArray[i] = 0;
_imFileDataArray[i] = 0;
_variablesArray[i] = 0; _variablesArray[i] = 0;
_curTotFileArray[i][0] = 0; _curTotFileArray[i][0] = 0;
_scriptArray[i] = 0;
_resourcesArray[i] = 0;
} }
_script = new Script(_vm); _script = new Script(_vm);
_resources = new Resources(_vm);
} }
Game::~Game() { Game::~Game() {
if (_totTextData) {
if (_totTextData->items)
delete[] _totTextData->items;
delete _totTextData;
}
if (_totResourceTable) {
delete[] _totResourceTable->items;
delete _totResourceTable;
}
delete _script; delete _script;
} delete _resources;
byte *Game::loadExtData(int16 itemId, int16 *pResWidth,
int16 *pResHeight, uint32 *dataSize) {
int16 commonHandle;
int16 itemsCount;
int32 offset;
uint32 size;
uint32 realSize;
ExtItem *item;
bool isPacked;
int16 handle;
int32 tableSize;
char path[20];
byte *dataBuf;
byte *packedBuf;
byte *dataPtr;
itemId -= 30000;
if (_extTable == 0)
return 0;
commonHandle = -1;
itemsCount = _extTable->itemsCount;
item = &_extTable->items[itemId];
tableSize = szGame_ExtTable + szGame_ExtItem * itemsCount;
offset = item->offset;
size = item->size;
isPacked = (item->width & 0x8000) != 0;
if ((pResWidth != 0) && (pResHeight != 0)) {
*pResWidth = item->width & 0x7FFF;
if (*pResWidth & 0x4000)
size += 1 << 16;
if (*pResWidth & 0x2000)
size += 2 << 16;
if (*pResWidth & 0x1000)
size += 4 << 16;
*pResWidth &= 0xFFF;
*pResHeight = item->height;
debugC(7, kDebugFileIO, "loadExtData(%d, %d, %d)",
itemId, *pResWidth, *pResHeight);
}
debugC(7, kDebugFileIO, "loadExtData(%d, 0, 0)", itemId);
if (item->height == 0)
size += (item->width & 0x7FFF) << 16;
debugC(7, kDebugFileIO, "size: %d off: %d", size, offset);
if (offset < 0) {
offset = -(offset + 1);
tableSize = 0;
_vm->_dataIO->closeData(_extHandle);
strcpy(path, "commun.ex1");
path[strlen(path) - 1] = _script->getExFileNumber() + '0';
commonHandle = _vm->_dataIO->openData(path);
handle = commonHandle;
} else
handle = _extHandle;
DataStream *stream = _vm->_dataIO->openAsStream(handle);
debugC(7, kDebugFileIO, "off: %d size: %d", offset, tableSize);
stream->seek(offset + tableSize);
realSize = size;
if (isPacked)
dataBuf = new byte[size + 2];
else
dataBuf = new byte[size];
dataPtr = dataBuf;
while (size > 32000) {
// BUG: huge->far conversion. Need normalization?
stream->read(dataPtr, 32000);
size -= 32000;
dataPtr += 32000;
}
stream->read(dataPtr, size);
delete stream;
if (commonHandle != -1) {
_vm->_dataIO->closeData(commonHandle);
_extHandle = _vm->_dataIO->openData(_curExtFile);
}
if (isPacked) {
packedBuf = dataBuf;
realSize = READ_LE_UINT32(packedBuf);
dataBuf = new byte[realSize];
_vm->_dataIO->unpackData(packedBuf, dataBuf);
delete[] packedBuf;
}
if (dataSize)
*dataSize = realSize;
return dataBuf;
} }
void Game::freeCollision(int16 id) { void Game::freeCollision(int16 id) {
@ -282,39 +161,9 @@ void Game::capturePop(char doDraw) {
_vm->_draw->freeSprite(30 + _captureCount); _vm->_draw->freeSprite(30 + _captureCount);
} }
byte *Game::loadTotResource(int16 id,
int16 *dataSize, int16 *width, int16 *height) {
TotResItem *itemPtr;
int32 offset;
if (id >= _totResourceTable->itemsCount) {
warning("Trying to load non-existent TOT resource (%s, %d/%d)",
_curTotFile, id, _totResourceTable->itemsCount - 1);
return 0;
}
itemPtr = &_totResourceTable->items[id];
offset = itemPtr->offset;
if (dataSize)
*dataSize = itemPtr->size;
if (width)
*width = itemPtr->width;
if (height)
*height = itemPtr->height;
if (offset < 0) {
offset = (-offset - 1) * 4;
return _imFileData + (int32) READ_LE_UINT32(_imFileData + offset);
} else
return _totResourceTable->dataPtr + szGame_TotResTable +
szGame_TotResItem * _totResourceTable->itemsCount + offset;
}
void Game::freeSoundSlot(int16 slot) { void Game::freeSoundSlot(int16 slot) {
if (slot == -1) if (slot == -1)
slot = _script->readValExpr(); slot = _vm->_game->_script->readValExpr();
_vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot)); _vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot));
} }
@ -417,53 +266,6 @@ int16 Game::adjustKey(int16 key) {
return key - 0x20; return key - 0x20;
} }
void Game::loadExtTable(void) {
int16 count;
// Function is correct. [sev]
_extHandle = _vm->_dataIO->openData(_curExtFile);
if (_extHandle < 0)
return;
DataStream *stream = _vm->_dataIO->openAsStream(_extHandle);
count = stream->readUint16LE();
stream->seek(0);
_extTable = new ExtTable;
_extTable->items = 0;
if (count)
_extTable->items = new ExtItem[count];
_extTable->itemsCount = stream->readUint16LE();
_extTable->unknown = stream->readByte();
for (int i = 0; i < count; i++) {
_extTable->items[i].offset = stream->readUint32LE();
_extTable->items[i].size = stream->readUint16LE();
_extTable->items[i].width = stream->readUint16LE();
_extTable->items[i].height = stream->readUint16LE();
}
delete stream;
}
void Game::loadImFile(void) {
char path[20];
if ((_script->getCommunHandling() != 0) && (_script->getImFileNumber() == 0))
return;
strcpy(path, "commun.im1");
if (_script->getImFileNumber() != 0)
path[strlen(path) - 1] = '0' + _script->getImFileNumber();
if (!_vm->_dataIO->existData(path))
return;
_imFileData = _vm->_dataIO->getData(path);
}
void Game::start(void) { void Game::start(void) {
_collisionAreas = new Collision[250]; _collisionAreas = new Collision[250];
memset(_collisionAreas, 0, 250 * sizeof(Collision)); memset(_collisionAreas, 0, 250 * sizeof(Collision));
@ -489,11 +291,7 @@ void Game::totSub(int8 flags, const char *newTotFile) {
_cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
_cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
_scriptArray[_backupedCount] = _script; _scriptArray[_backupedCount] = _script;
_totTextDataArray[_backupedCount] = _totTextData; _resourcesArray[_backupedCount] = _resources;
_totResourceTableArray[_backupedCount] = _totResourceTable;
_extTableArray[_backupedCount] = _extTable;
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_variablesArray[_backupedCount] = _vm->_inter->_variables; _variablesArray[_backupedCount] = _vm->_inter->_variables;
strcpy(_curTotFileArray[_backupedCount], _curTotFile); strcpy(_curTotFileArray[_backupedCount], _curTotFile);
@ -501,9 +299,8 @@ void Game::totSub(int8 flags, const char *newTotFile) {
_backupedCount++; _backupedCount++;
_curBackupPos = _backupedCount; _curBackupPos = _backupedCount;
_totTextData = 0;
_script = new Script(_vm); _script = new Script(_vm);
_totResourceTable = 0; _resources = new Resources(_vm);
if (flags & 1) if (flags & 1)
_vm->_inter->_variables = 0; _vm->_inter->_variables = 0;
@ -537,17 +334,10 @@ void Game::totSub(int8 flags, const char *newTotFile) {
_vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount]; _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount];
_vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount]; _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount];
_totTextData = _totTextDataArray[_backupedCount];
_script = _scriptArray[_backupedCount]; _script = _scriptArray[_backupedCount];
_totResourceTable = _totResourceTableArray[_backupedCount]; _resources = _resourcesArray[_backupedCount];
_extTable = _extTableArray[_backupedCount];
_extHandle = _extHandleArray[_backupedCount];
_imFileData = _imFileDataArray[_backupedCount];
_vm->_inter->_variables = _variablesArray[_backupedCount]; _vm->_inter->_variables = _variablesArray[_backupedCount];
strcpy(_curTotFile, _curTotFileArray[_backupedCount]); strcpy(_curTotFile, _curTotFileArray[_backupedCount]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile) - 4] = '\0';
strcat(_curExtFile, ".EXT");
} }
void Game::switchTotSub(int16 index, int16 skipPlay) { void Game::switchTotSub(int16 index, int16 skipPlay) {
@ -569,12 +359,8 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
if (_curBackupPos == _backupedCount) { if (_curBackupPos == _backupedCount) {
_cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
_cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
_totTextDataArray[_backupedCount] = _totTextData;
_scriptArray[_backupedCount] = _script; _scriptArray[_backupedCount] = _script;
_totResourceTableArray[_backupedCount] = _totResourceTable; _resourcesArray[_backupedCount] = _resources;
_extTableArray[_backupedCount] = _extTable;
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_variablesArray[_backupedCount] = _vm->_inter->_variables; _variablesArray[_backupedCount] = _vm->_inter->_variables;
strcpy(_curTotFileArray[_backupedCount], _curTotFile); strcpy(_curTotFileArray[_backupedCount], _curTotFile);
_backupedCount++; _backupedCount++;
@ -585,17 +371,10 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos]; _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos];
_vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos]; _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos];
_totTextData = _totTextDataArray[_curBackupPos];
_script = _scriptArray[_curBackupPos]; _script = _scriptArray[_curBackupPos];
_totResourceTable = _totResourceTableArray[_curBackupPos]; _resources = _resourcesArray[_curBackupPos];
_imFileData = _imFileDataArray[_curBackupPos];
_extTable = _extTableArray[_curBackupPos];
_extHandle = _extHandleArray[_curBackupPos];
_vm->_inter->_variables = _variablesArray[_curBackupPos]; _vm->_inter->_variables = _variablesArray[_curBackupPos];
strcpy(_curTotFile, _curTotFileArray[_curBackupPos]); strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile) - 4] = '\0';
strcat(_curExtFile, ".EXT");
if (_vm->_inter->_terminate != 0) if (_vm->_inter->_terminate != 0)
return; return;
@ -612,109 +391,10 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_backupedCount = backupedCount; _backupedCount = backupedCount;
_vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos]; _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos];
_vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos]; _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos];
_totTextData = _totTextDataArray[_curBackupPos];
_script = _scriptArray[_curBackupPos]; _script = _scriptArray[_curBackupPos];
_totResourceTable = _totResourceTableArray[_curBackupPos]; _resources = _resourcesArray[_curBackupPos];
_extTable = _extTableArray[_curBackupPos];
_extHandle = _extHandleArray[_curBackupPos];
_imFileData = _imFileDataArray[_curBackupPos];
_vm->_inter->_variables = _variablesArray[_curBackupPos]; _vm->_inter->_variables = _variablesArray[_curBackupPos];
strcpy(_curTotFile, _curTotFileArray[_curBackupPos]); strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile) - 4] = '\0';
strcat(_curExtFile, ".EXT");
}
bool Game::getLocTextFile(char *locTextFile, int language) {
int n = strlen(locTextFile);
if (n < 4)
return false;
locTextFile[n - 4] = 0;
switch (language) {
case 0:
strcat(locTextFile, ".dat");
break;
case 1:
strcat(locTextFile, ".all");
break;
case 3:
strcat(locTextFile, ".esp");
break;
case 4:
strcat(locTextFile, ".ita");
break;
case 5:
strcat(locTextFile, ".usa");
break;
case 6:
strcat(locTextFile, ".ndl");
break;
case 7:
strcat(locTextFile, ".kor");
break;
case 8:
strcat(locTextFile, ".isr");
break;
default:
strcat(locTextFile, ".ang");
break;
}
return _vm->_dataIO->existData(locTextFile);
}
byte *Game::loadLocTexts(int32 *dataSize) {
char locTextFile[20];
strcpy(locTextFile, _curTotFile);
bool found = getLocTextFile(locTextFile, _vm->_global->_languageWanted);
if (found) {
_foundTotLoc = true;
_vm->_global->_language = _vm->_global->_languageWanted;
} else if (!_foundTotLoc) {
// Trying US for GB and vice versa
if (_vm->_global->_languageWanted == 2) {
found = getLocTextFile(locTextFile, 5);
if (found) {
_vm->_global->_language = 5;
found = true;
}
} else if (_vm->_global->_languageWanted == 5) {
found = getLocTextFile(locTextFile, 2);
if (found) {
_vm->_global->_language = 2;
found = true;
}
}
if (!found) {
// Looking for the first existing language
for (int i = 0; i < 10; i++) {
found = getLocTextFile(locTextFile, i);
if (found) {
_vm->_global->_language = i;
break;
}
}
}
}
debugC(1, kDebugFileIO, "Using language %d for %s",
_vm->_global->_language, _curTotFile);
if (found) {
if (dataSize)
*dataSize = _vm->_dataIO->getDataSize(locTextFile);
return _vm->_dataIO->getData(locTextFile);
}
return 0;
} }
void Game::setCollisions(byte arg_0) { void Game::setCollisions(byte arg_0) {

View File

@ -31,6 +31,7 @@
namespace Gob { namespace Gob {
class Script; class Script;
class Resources;
class Game { class Game {
public: public:
@ -51,19 +52,6 @@ public:
Script *script; Script *script;
} PACKED_STRUCT; } PACKED_STRUCT;
#define szGame_TotTextItem (2 + 2)
struct TotTextItem {
uint16 offset;
int16 size;
} PACKED_STRUCT;
#define szGame_TotTextTable (2)
struct TotTextTable {
int16 itemsCount;
TotTextItem *items;
byte *dataPtr;
} PACKED_STRUCT;
struct InputDesc { struct InputDesc {
int16 fontIndex; int16 fontIndex;
int16 backColor; int16 backColor;
@ -76,19 +64,10 @@ public:
Collision *_collisionAreas; Collision *_collisionAreas;
Collision *_collStack[5]; Collision *_collStack[5];
bool _foundTotLoc;
TotTextTable *_totTextData;
Script *_script; Script *_script;
Resources *_resources;
char _curTotFile[14]; char _curTotFile[14];
char _curExtFile[14];
byte *_imFileData;
int16 _extHandle;
int16 _lomHandle;
char _totToLoad[20]; char _totToLoad[20];
int32 _startTimeKey; int32 _startTimeKey;
@ -103,9 +82,6 @@ public:
Game(GobEngine *vm); Game(GobEngine *vm);
virtual ~Game(); virtual ~Game();
byte *loadExtData(int16 dataId, int16 *pResWidth, int16 *pResHeight, uint32 *dataSize = 0);
byte *loadTotResource(int16 id, int16 *dataSize = 0, int16 *width = 0, int16 *height = 0);
void capturePush(int16 left, int16 top, int16 width, int16 height); void capturePush(int16 left, int16 top, int16 width, int16 height);
void capturePop(char doDraw); void capturePop(char doDraw);
@ -145,42 +121,6 @@ public:
virtual void popCollisions(void) = 0; virtual void popCollisions(void) = 0;
protected: protected:
#include "common/pack-start.h" // START STRUCT PACKING
#define szGame_TotResItem (4 + 2 + 2 + 2)
struct TotResItem {
int32 offset; // if > 0, then offset from end of resource table.
// If < 0, then -offset-1 is index in .IM file table
int16 size;
int16 width;
int16 height;
} PACKED_STRUCT;
#define szGame_TotResTable (2 + 1)
struct TotResTable {
int16 itemsCount;
byte unknown;
TotResItem *items;
byte *dataPtr;
} PACKED_STRUCT;
#define szGame_ExtItem (4 + 2 + 2 + 2)
struct ExtItem {
int32 offset; // offset from the table end
uint16 size;
int16 width; // width & 0x7FFF: width, width & 0x8000: pack flag
int16 height; // not zero
} PACKED_STRUCT;
#define szGame_ExtTable (2 + 1)
struct ExtTable {
int16 itemsCount;
byte unknown;
ExtItem *items;
} PACKED_STRUCT;
#include "common/pack-end.h" // END STRUCT PACKING
int16 _lastCollKey; int16 _lastCollKey;
int16 _lastCollAreaIndex; int16 _lastCollAreaIndex;
int16 _lastCollId; int16 _lastCollId;
@ -193,10 +133,6 @@ protected:
char _tempStr[256]; char _tempStr[256];
TotResTable *_totResourceTable;
ExtTable *_extTable;
char _curImaFile[18];
int16 _collStackSize; int16 _collStackSize;
int16 _collStackElemSizes[5]; int16 _collStackElemSizes[5];
@ -213,25 +149,16 @@ protected:
int8 _curBackupPos; int8 _curBackupPos;
int16 _cursorHotspotXArray[5]; int16 _cursorHotspotXArray[5];
int16 _cursorHotspotYArray[5]; int16 _cursorHotspotYArray[5];
TotTextTable *_totTextDataArray[5];
TotResTable *_totResourceTableArray[5];
ExtTable *_extTableArray[5];
int16 _extHandleArray[5];
byte *_imFileDataArray[5];
Variables *_variablesArray[5]; Variables *_variablesArray[5];
char _curTotFileArray[5][14]; char _curTotFileArray[5][14];
Script *_scriptArray[5]; Script *_scriptArray[5];
Resources *_resourcesArray[5];
GobEngine *_vm; GobEngine *_vm;
virtual int16 adjustKey(int16 key); virtual int16 adjustKey(int16 key);
byte *loadLocTexts(int32 *dataSize = 0);
void loadExtTable(void);
void loadImFile(void);
void collAreaSub(int16 index, int8 enter); void collAreaSub(int16 index, int8 enter);
bool getLocTextFile(char *locTextFile, int language);
virtual void setCollisions(byte arg_0 = 1); virtual void setCollisions(byte arg_0 = 1);
virtual void collSub(uint16 offset); virtual void collSub(uint16 offset);

View File

@ -33,6 +33,7 @@
#include "gob/util.h" #include "gob/util.h"
#include "gob/dataio.h" #include "gob/dataio.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/mult.h" #include "gob/mult.h"
@ -93,12 +94,6 @@ void Game_v1::playTot(int16 skipPlay) {
for (int i = 0; i < 20; i++) for (int i = 0; i < 20; i++)
freeSoundSlot(i); freeSoundSlot(i);
_totTextData = 0;
_totResourceTable = 0;
_imFileData = 0;
_extTable = 0;
_extHandle = -1;
_totToLoad[0] = 0; _totToLoad[0] = 0;
if ((_curTotFile[0] == 0) && !_script->isLoaded()) if ((_curTotFile[0] == 0) && !_script->isLoaded())
@ -109,56 +104,7 @@ void Game_v1::playTot(int16 skipPlay) {
break; break;
} }
strcpy(_curImaFile, _curTotFile); _resources->load(_curTotFile);
strcpy(_curExtFile, _curTotFile);
_curImaFile[strlen(_curImaFile) - 4] = 0;
strcat(_curImaFile, ".ima");
_curExtFile[strlen(_curExtFile) - 4] = 0;
strcat(_curExtFile, ".ext");
debugC(4, kDebugFileIO, "IMA: %s", _curImaFile);
debugC(4, kDebugFileIO, "EXT: %s", _curExtFile);
_totTextData = 0;
if (_script->getTextsOffset() != ((uint32) -1)) {
_totTextData = new TotTextTable;
_totTextData->dataPtr = _script->getData() + _script->getTextsOffset();
Common::MemoryReadStream totTextData(_totTextData->dataPtr,
_script->getSize() - _script->getTextsOffset());
_totTextData->itemsCount = totTextData.readSint16LE();
_totTextData->items = new TotTextItem[_totTextData->itemsCount];
for (int i = 0; i < _totTextData->itemsCount; ++i) {
_totTextData->items[i].offset = totTextData.readSint16LE();
_totTextData->items[i].size = totTextData.readSint16LE();
}
}
_totResourceTable = 0;
if (_script->getResourcesOffset() != ((uint32) -1)) {
_totResourceTable = new TotResTable;
_totResourceTable->dataPtr = _script->getData() + _script->getResourcesOffset();
Common::MemoryReadStream totResTable(_totResourceTable->dataPtr,
_script->getSize() - _script->getResourcesOffset());
_totResourceTable->itemsCount = totResTable.readSint16LE();
_totResourceTable->unknown = totResTable.readByte();
_totResourceTable->items =
new TotResItem[_totResourceTable->itemsCount];
for (int 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();
}
}
loadImFile();
loadExtTable();
_vm->_global->_inter_animDataSize = _script->getAnimDataSize(); _vm->_global->_inter_animDataSize = _script->getAnimDataSize();
if (!_vm->_inter->_variables) if (!_vm->_inter->_variables)
@ -183,30 +129,7 @@ void Game_v1::playTot(int16 skipPlay) {
_script->unload(); _script->unload();
if (_totTextData) { _resources->unload();
delete[] _totTextData->items;
delete _totTextData;
}
_totTextData = 0;
if (_totResourceTable) {
delete[] _totResourceTable->items;
delete _totResourceTable;
}
_totResourceTable = 0;
delete[] _imFileData;
_imFileData = 0;
if (_extTable)
delete[] _extTable->items;
delete _extTable;
_extTable = 0;
if (_extHandle >= 0)
_vm->_dataIO->closeData(_extHandle);
_extHandle = -1;
for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++)
capturePop(0); capturePop(0);

View File

@ -33,6 +33,7 @@
#include "gob/util.h" #include "gob/util.h"
#include "gob/dataio.h" #include "gob/dataio.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/goblin.h" #include "gob/goblin.h"
#include "gob/inter.h" #include "gob/inter.h"
@ -55,7 +56,6 @@ void Game_v2::playTot(int16 skipPlay) {
int16 _captureCounter; int16 _captureCounter;
int16 breakFrom; int16 breakFrom;
int16 nestLevel; int16 nestLevel;
bool totTextLoc;
oldNestLevel = _vm->_inter->_nestLevel; oldNestLevel = _vm->_inter->_nestLevel;
oldBreakFrom = _vm->_inter->_breakFromLevel; oldBreakFrom = _vm->_inter->_breakFromLevel;
@ -92,12 +92,6 @@ void Game_v2::playTot(int16 skipPlay) {
} else } else
_vm->_inter->initControlVars(0); _vm->_inter->initControlVars(0);
_totTextData = 0;
_totResourceTable = 0;
_imFileData = 0;
_extTable = 0;
_extHandle = -1;
_vm->_draw->_cursorHotspotXVar = -1; _vm->_draw->_cursorHotspotXVar = -1;
_totToLoad[0] = 0; _totToLoad[0] = 0;
@ -115,85 +109,7 @@ void Game_v2::playTot(int16 skipPlay) {
break; break;
} }
strcpy(_curImaFile, _curTotFile); _resources->load(_curTotFile);
strcpy(_curExtFile, _curTotFile);
_curImaFile[strlen(_curImaFile) - 4] = 0;
strcat(_curImaFile, ".ima");
_curExtFile[strlen(_curExtFile) - 4] = 0;
strcat(_curExtFile, ".ext");
debugC(4, kDebugFileIO, "IMA: %s", _curImaFile);
debugC(4, kDebugFileIO, "EXT: %s", _curExtFile);
_totTextData = 0;
totTextLoc = false;
if (_script->getTextsOffset() != ((uint32) -1)) {
_totTextData = new TotTextTable;
int32 size;
if (_script->getTextsOffset() == 0) {
_totTextData->dataPtr = loadLocTexts(&size);
totTextLoc = true;
} else {
_totTextData->dataPtr = _script->getData() + _script->getTextsOffset();
size = _script->getSize() - _script->getTextsOffset();
_vm->_global->_language = _vm->_global->_languageWanted;
}
_totTextData->items = 0;
if (_totTextData->dataPtr != 0) {
Common::MemoryReadStream totTextData(_totTextData->dataPtr, size);
_totTextData->itemsCount = totTextData.readSint16LE() & 0x3FFF;
_totTextData->items = new TotTextItem[_totTextData->itemsCount];
for (int i = 0; i < _totTextData->itemsCount; ++i) {
_totTextData->items[i].offset = totTextData.readSint16LE();
_totTextData->items[i].size = totTextData.readSint16LE();
}
}
}
_totResourceTable = 0;
int32 resSize;
if (_script->getResourcesOffset() != ((uint32) -1)) {
_totResourceTable = new TotResTable;
_totResourceTable->dataPtr = _script->getData() + _script->getResourcesOffset();
Common::MemoryReadStream totResTable(_totResourceTable->dataPtr,
_script->getSize() - _script->getResourcesOffset());
_totResourceTable->itemsCount = totResTable.readSint16LE();
resSize = _totResourceTable->itemsCount * szGame_TotResItem + szGame_TotResTable;
if (_script->getSize() > (resSize + 0x34)) {
_totResourceTable->unknown = totResTable.readByte();
_totResourceTable->items =
new TotResItem[_totResourceTable->itemsCount];
for (int 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, kDebugFileIO,
"Attempted to load invalid resource table (size = %d, totSize = %d)",
resSize, _script->getSize());
delete _totResourceTable;
_totResourceTable = 0;
}
}
loadImFile();
loadExtTable();
_vm->_global->_inter_animDataSize = _script->getAnimDataSize(); _vm->_global->_inter_animDataSize = _script->getAnimDataSize();
if (!_vm->_inter->_variables) if (!_vm->_inter->_variables)
@ -217,32 +133,7 @@ void Game_v2::playTot(int16 skipPlay) {
_script->unload(); _script->unload();
if (_totTextData) { _resources->unload();
delete[] _totTextData->items;
if (totTextLoc)
delete[] _totTextData->dataPtr;
delete _totTextData;
}
_totTextData = 0;
if (_totResourceTable) {
delete[] _totResourceTable->items;
delete _totResourceTable;
}
_totResourceTable = 0;
delete[] _imFileData;
_imFileData = 0;
if (_extTable)
delete[] _extTable->items;
delete _extTable;
_extTable = 0;
if (_extHandle >= 0)
_vm->_dataIO->closeData(_extHandle);
_extHandle = -1;
for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++) for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++)
capturePop(0); capturePop(0);

View File

@ -32,6 +32,7 @@
#include "gob/helper.h" #include "gob/helper.h"
#include "gob/global.h" #include "gob/global.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/draw.h" #include "gob/draw.h"
@ -53,12 +54,8 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
_cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar; _cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
_cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar; _cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
_totTextDataArray[_backupedCount] = _totTextData;
_scriptArray[_backupedCount] = _script; _scriptArray[_backupedCount] = _script;
_totResourceTableArray[_backupedCount] = _totResourceTable; _resourcesArray[_backupedCount] = _resources;
_extTableArray[_backupedCount] = _extTable;
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_variablesArray[_backupedCount] = _vm->_inter->_variables; _variablesArray[_backupedCount] = _vm->_inter->_variables;
strcpy(_curTotFileArray[_backupedCount], _curTotFile); strcpy(_curTotFileArray[_backupedCount], _curTotFile);
@ -67,8 +64,7 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
_curBackupPos = _backupedCount; _curBackupPos = _backupedCount;
_script = new Script(_vm); _script = new Script(_vm);
_totTextData = 0; _resources = new Resources(_vm);
_totResourceTable = 0;
if (flags & 0x80) if (flags & 0x80)
warning("Urban Stub: Game_v6::totSub(), flags & 0x80"); warning("Urban Stub: Game_v6::totSub(), flags & 0x80");
@ -104,17 +100,10 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
_vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount]; _vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount];
_vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount]; _vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount];
_totTextData = _totTextDataArray[_backupedCount];
_script = _scriptArray[_backupedCount]; _script = _scriptArray[_backupedCount];
_totResourceTable = _totResourceTableArray[_backupedCount]; _resources = _resourcesArray[_backupedCount];
_extTable = _extTableArray[_backupedCount];
_extHandle = _extHandleArray[_backupedCount];
_imFileData = _imFileDataArray[_backupedCount];
_vm->_inter->_variables = _variablesArray[_backupedCount]; _vm->_inter->_variables = _variablesArray[_backupedCount];
strcpy(_curTotFile, _curTotFileArray[_backupedCount]); strcpy(_curTotFile, _curTotFileArray[_backupedCount]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile) - 4] = '\0';
strcat(_curExtFile, ".EXT");
} }
int16 Game_v6::addNewCollision(int16 id, uint16 left, uint16 top, int16 Game_v6::addNewCollision(int16 id, uint16 left, uint16 top,

View File

@ -37,35 +37,36 @@ Global::Global(GobEngine *vm) : _vm(vm) {
_presentVGA = UNDEF; _presentVGA = UNDEF;
_presentHER = UNDEF; _presentHER = UNDEF;
_videoMode = 0; _videoMode = 0;
_fakeVideoMode = 0; _fakeVideoMode = 0;
_oldMode = 3; _oldMode = 3;
_soundFlags = 0; _soundFlags = 0;
_language = 0x8000; _language = 0x8000;
_languageWanted = 0x8000; _languageWanted = 0x8000;
_foundLanguage = false;
_useMouse = UNDEF; _useMouse = UNDEF;
_mousePresent = UNDEF; _mousePresent = UNDEF;
_mouseXShift = 3; _mouseXShift = 3;
_mouseYShift = 3; _mouseYShift = 3;
_mouseMinX = 0; _mouseMinX = 0;
_mouseMinY = 0; _mouseMinY = 0;
_mouseMaxX = 320; _mouseMaxX = 320;
_mouseMaxY = 200; _mouseMaxY = 200;
_useJoystick = 1; _useJoystick = 1;
_primaryWidth = 0; _primaryWidth = 0;
_primaryHeight = 0; _primaryHeight = 0;
_colorCount = 16; _colorCount = 16;
for (int i = 0; i < 256; i++) { for (int i = 0; i < 256; i++) {
_redPalette[i] = 0; _redPalette [i] = 0;
_greenPalette[i] = 0; _greenPalette[i] = 0;
_bluePalette[i] = 0; _bluePalette [i] = 0;
} }
_unusedPalette1[ 0] = (int16) 0x0000; _unusedPalette1[ 0] = (int16) 0x0000;
@ -109,7 +110,7 @@ Global::Global(GobEngine *vm) : _vm(vm) {
_pPaletteDesc = 0; _pPaletteDesc = 0;
_setAllPalette = false; _setAllPalette = false;
_dontSetPalette = false; _dontSetPalette = false;
_debugFlag = 0; _debugFlag = 0;

View File

@ -33,37 +33,51 @@
namespace Gob { namespace Gob {
#define VIDMODE_CGA 0x05 #define VIDMODE_CGA 0x05
#define VIDMODE_EGA 0x0D #define VIDMODE_EGA 0x0D
#define VIDMODE_VGA 0x13 #define VIDMODE_VGA 0x13
#define VIDMODE_HER 7 #define VIDMODE_HER 0x07
#define PROAUDIO_FLAG 0x10 #define MIDI_FLAG 0x4000
#define ADLIB_FLAG 0x08 #define PROAUDIO_FLAG 0x0010
#define BLASTER_FLAG 0x04 #define ADLIB_FLAG 0x0008
#define INTERSOUND_FLAG 0x02 #define BLASTER_FLAG 0x0004
#define SPEAKER_FLAG 0x01 #define INTERSOUND_FLAG 0x0002
#define MIDI_FLAG 0x4000 #define SPEAKER_FLAG 0x0001
#define NO 0 #define NO 0
#define YES 1 #define YES 1
#define UNDEF 2 #define UNDEF 2
#define F1_KEY 0x3B00 #define F1_KEY 0x3B00
#define F2_KEY 0x3C00 #define F2_KEY 0x3C00
#define F3_KEY 0x3D00 #define F3_KEY 0x3D00
#define F4_KEY 0x3E00 #define F4_KEY 0x3E00
#define F5_KEY 0x3F00 #define F5_KEY 0x3F00
#define F6_KEY 0x4000 #define F6_KEY 0x4000
#define ESCAPE 0x001B #define ESCAPE 0x001B
#define ENTER 0x000D #define ENTER 0x000D
/* Video drivers */ /* Video drivers */
#define UNK_DRIVER 0 #define UNK_DRIVER 0
#define VGA_DRIVER 1 #define VGA_DRIVER 1
#define EGA_DRIVER 2 #define EGA_DRIVER 2
#define CGA_DRIVER 3 #define CGA_DRIVER 3
#define HER_DRIVER 4 #define HER_DRIVER 4
enum Language {
kLanguageFrench = 0,
kLanguageGerman = 1,
kLanguageBritish = 2,
kLanguageSpanish = 3,
kLanguageItalian = 4,
kLanguageAmerican = 5,
kLanguageDutch = 6,
kLanguageKorean = 7,
kLanguageHebrew = 8,
kLanguagePortuguese = 9,
kLanguageJapanese = 10
};
class Global { class Global {
public: public:
@ -82,6 +96,7 @@ public:
uint16 _language; uint16 _language;
uint16 _languageWanted; uint16 _languageWanted;
bool _foundLanguage;
char _useMouse; char _useMouse;
int16 _mousePresent; int16 _mousePresent;

View File

@ -247,43 +247,42 @@ Common::Error GobEngine::run() {
switch (_language) { switch (_language) {
case Common::FR_FRA: case Common::FR_FRA:
case Common::RU_RUS: case Common::RU_RUS:
_global->_language = 0; _global->_language = kLanguageFrench;
break; break;
case Common::DE_DEU: case Common::DE_DEU:
_global->_language = 1; _global->_language = kLanguageGerman;
break; break;
case Common::EN_ANY: case Common::EN_ANY:
case Common::EN_GRB: case Common::EN_GRB:
case Common::HU_HUN: case Common::HU_HUN:
_global->_language = 2; _global->_language = kLanguageBritish;
break; break;
case Common::ES_ESP: case Common::ES_ESP:
_global->_language = 3; _global->_language = kLanguageSpanish;
break; break;
case Common::IT_ITA: case Common::IT_ITA:
_global->_language = 4; _global->_language = kLanguageItalian;
break; break;
case Common::EN_USA: case Common::EN_USA:
_global->_language = 5; _global->_language = kLanguageAmerican;
break; break;
case Common::NL_NLD: case Common::NL_NLD:
_global->_language = 6; _global->_language = kLanguageDutch;
break; break;
case Common::KO_KOR: case Common::KO_KOR:
_global->_language = 7; _global->_language = kLanguageKorean;
break; break;
case Common::HB_ISR: case Common::HB_ISR:
_global->_language = 8; _global->_language = kLanguageHebrew;
break; break;
case Common::PT_BRA: case Common::PT_BRA:
_global->_language = 9; _global->_language = kLanguagePortuguese;
break; break;
case Common::JA_JPN: case Common::JA_JPN:
_global->_language = 10; _global->_language = kLanguageJapanese;
break; break;
default: default:
// Default to English _global->_language = kLanguageBritish;
_global->_language = 2;
break; break;
} }
_global->_languageWanted = _global->_language; _global->_languageWanted = _global->_language;

View File

@ -99,7 +99,6 @@ void Init::initGame() {
_vm->_global->_mouseXShift = 1; _vm->_global->_mouseXShift = 1;
_vm->_global->_mouseYShift = 1; _vm->_global->_mouseYShift = 1;
_vm->_game->_totTextData = 0;
_palDesc = new Video::PalDesc; _palDesc = new Video::PalDesc;
_vm->validateVideoMode(_vm->_global->_videoMode); _vm->validateVideoMode(_vm->_global->_videoMode);

View File

@ -36,6 +36,7 @@
#include "gob/game.h" #include "gob/game.h"
#include "gob/expression.h" #include "gob/expression.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/goblin.h" #include "gob/goblin.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/map.h" #include "gob/map.h"
@ -682,28 +683,27 @@ bool Inter_v1::o1_printTotText(OpFuncParams &params) {
} }
bool Inter_v1::o1_loadCursor(OpFuncParams &params) { bool Inter_v1::o1_loadCursor(OpFuncParams &params) {
int16 width, height; int16 id = _vm->_game->_script->readInt16();
byte *dataBuf; int8 index = _vm->_game->_script->readInt8();
int16 id;
int8 index;
id = _vm->_game->_script->readInt16();
index = _vm->_game->_script->readInt8();
if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth()) if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth())
return false; return false;
dataBuf = _vm->_game->loadTotResource(id, 0, &width, &height); Resource *resource = _vm->_game->_resources->getResource(id);
if (!resource)
return false;
_vm->_video->fillRect(*_vm->_draw->_cursorSprites, _vm->_video->fillRect(*_vm->_draw->_cursorSprites,
index * _vm->_draw->_cursorWidth, 0, index * _vm->_draw->_cursorWidth, 0,
index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
_vm->_draw->_cursorHeight - 1, 0); _vm->_draw->_cursorHeight - 1, 0);
_vm->_video->drawPackedSprite(dataBuf, width, height, _vm->_video->drawPackedSprite(resource->getData(),
resource->getWidth(), resource->getHeight(),
index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites); index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites);
_vm->_draw->_cursorAnimLow[index] = 0; _vm->_draw->_cursorAnimLow[index] = 0;
delete resource;
return false; return false;
} }
@ -962,8 +962,8 @@ bool Inter_v1::o1_loadTot(OpFuncParams &params) {
bool Inter_v1::o1_palLoad(OpFuncParams &params) { bool Inter_v1::o1_palLoad(OpFuncParams &params) {
int index1, index2; int index1, index2;
byte *palPtr;
byte cmd; byte cmd;
Resource *resource;
cmd = _vm->_game->_script->readByte(); cmd = _vm->_game->_script->readByte();
switch (cmd & 0x7F) { switch (cmd & 0x7F) {
@ -1091,8 +1091,12 @@ bool Inter_v1::o1_palLoad(OpFuncParams &params) {
break; break;
case 53: case 53:
palPtr = _vm->_game->loadTotResource(_vm->_game->_script->readInt16()); resource = _vm->_game->_resources->getResource(_vm->_game->_script->readInt16());
memcpy((char *) _vm->_draw->_vgaPalette, palPtr, 768); if (!resource)
break;
memcpy((char *) _vm->_draw->_vgaPalette, resource->getData(), MIN(768, resource->getSize()));
delete resource;
break; break;
case 54: case 54:
@ -1102,9 +1106,13 @@ bool Inter_v1::o1_palLoad(OpFuncParams &params) {
case 61: case 61:
index1 = _vm->_game->_script->readByte(); index1 = _vm->_game->_script->readByte();
index2 = (_vm->_game->_script->readByte() - index1 + 1) * 3; index2 = (_vm->_game->_script->readByte() - index1 + 1) * 3;
palPtr = _vm->_game->loadTotResource(_vm->_game->_script->readInt16()); resource = _vm->_game->_resources->getResource(_vm->_game->_script->readInt16());
if (!resource)
break;
memcpy((char *) _vm->_draw->_vgaPalette + index1 * 3, memcpy((char *) _vm->_draw->_vgaPalette + index1 * 3,
palPtr + index1 * 3, index2); resource->getData() + index1 * 3, index2);
delete resource;
if (_vm->_draw->_applyPal) { if (_vm->_draw->_applyPal) {
_vm->_draw->_applyPal = false; _vm->_draw->_applyPal = false;
@ -1697,14 +1705,10 @@ bool Inter_v1::o1_loadFont(OpFuncParams &params) {
delete _vm->_draw->_fonts[index]; delete _vm->_draw->_fonts[index];
_vm->_draw->animateCursor(4); _vm->_draw->animateCursor(4);
if (_vm->_game->_extHandle >= 0)
_vm->_dataIO->closeData(_vm->_game->_extHandle);
_vm->_draw->_fonts[index] = _vm->_draw->_fonts[index] =
_vm->_util->loadFont(_vm->_game->_script->getResultStr()); _vm->_util->loadFont(_vm->_game->_script->getResultStr());
if (_vm->_game->_extHandle >= 0)
_vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile);
return false; return false;
} }
@ -1730,9 +1734,6 @@ bool Inter_v1::o1_readData(OpFuncParams &params) {
offset = _vm->_game->_script->readValExpr(); offset = _vm->_game->_script->readValExpr();
retSize = 0; retSize = 0;
if (_vm->_game->_extHandle >= 0)
_vm->_dataIO->closeData(_vm->_game->_extHandle);
WRITE_VAR(1, 1); WRITE_VAR(1, 1);
handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr()); handle = _vm->_dataIO->openData(_vm->_game->_script->getResultStr());
if (handle >= 0) { if (handle >= 0) {
@ -1755,8 +1756,6 @@ bool Inter_v1::o1_readData(OpFuncParams &params) {
delete stream; delete stream;
} }
if (_vm->_game->_extHandle >= 0)
_vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile);
return false; return false;
} }
@ -2296,11 +2295,8 @@ void Inter_v1::o1_setItemPos(OpGobParams &params) {
void Inter_v1::o1_loadObjects(OpGobParams &params) { void Inter_v1::o1_loadObjects(OpGobParams &params) {
params.extraData = _vm->_game->_script->readInt16(); params.extraData = _vm->_game->_script->readInt16();
if (_vm->_game->_extHandle >= 0)
_vm->_dataIO->closeData(_vm->_game->_extHandle);
_vm->_goblin->loadObjects((char *) VAR_ADDRESS(params.extraData)); _vm->_goblin->loadObjects((char *) VAR_ADDRESS(params.extraData));
_vm->_game->_extHandle = _vm->_dataIO->openData(_vm->_game->_curExtFile);
} }
void Inter_v1::o1_freeObjects(OpGobParams &params) { void Inter_v1::o1_freeObjects(OpGobParams &params) {
@ -2475,38 +2471,24 @@ void Inter_v1::o1_initGoblin(OpGobParams &params) {
} }
int16 Inter_v1::loadSound(int16 slot) { int16 Inter_v1::loadSound(int16 slot) {
byte *dataPtr;
int16 id;
uint32 dataSize;
SoundSource source;
if (slot == -1) if (slot == -1)
slot = _vm->_game->_script->readValExpr(); slot = _vm->_game->_script->readValExpr();
id = _vm->_game->_script->readInt16(); uint16 id = _vm->_game->_script->readUint16();
if (id == -1) { if (id == 0xFFFF) {
_vm->_game->_script->skip(9); _vm->_game->_script->skip(9);
return 0; return 0;
} }
if (id >= 30000) { Resource *resource = _vm->_game->_resources->getResource(id);
source = SOUND_EXT; if (!resource)
return 0;
dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); SoundDesc *sample = _vm->_sound->sampleGetBySlot(slot);
} else { if (!sample)
int16 totSize; return 0;
source = SOUND_TOT; sample->load(SOUND_SND, resource);
dataPtr = (byte *) _vm->_game->loadTotResource(id, &totSize);
dataSize = (uint32) ((int32) totSize);
}
if (dataPtr) {
SoundDesc *sample = _vm->_sound->sampleGetBySlot(slot);
if (sample)
sample->load(SOUND_SND, source, dataPtr, dataSize);
}
return 0; return 0;
} }

View File

@ -38,6 +38,7 @@
#include "gob/game.h" #include "gob/game.h"
#include "gob/expression.h" #include "gob/expression.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/goblin.h" #include "gob/goblin.h"
#include "gob/map.h" #include "gob/map.h"
#include "gob/mult.h" #include "gob/mult.h"
@ -1499,7 +1500,6 @@ int16 Inter_v2::loadSound(int16 search) {
uint16 slotIdMask; uint16 slotIdMask;
uint32 dataSize; uint32 dataSize;
SoundType type; SoundType type;
SoundSource source;
type = SOUND_SND; type = SOUND_SND;
slotIdMask = 0; slotIdMask = 0;
@ -1542,8 +1542,6 @@ int16 Inter_v2::loadSound(int16 search) {
if (id == -1) { if (id == -1) {
char sndfile[14]; char sndfile[14];
source = SOUND_FILE;
strncpy0(sndfile, _vm->_game->_script->readString(9), 9); strncpy0(sndfile, _vm->_game->_script->readString(9), 9);
if (type == SOUND_ADL) if (type == SOUND_ADL)
@ -1551,27 +1549,30 @@ int16 Inter_v2::loadSound(int16 search) {
else else
strcat(sndfile, ".SND"); strcat(sndfile, ".SND");
dataPtr = (byte *) _vm->_dataIO->getData(sndfile); dataPtr = _vm->_dataIO->getData(sndfile);
if (dataPtr) dataSize = _vm->_dataIO->getDataSize(sndfile);
dataSize = _vm->_dataIO->getDataSize(sndfile); if (!dataPtr)
} else if (id >= 30000) { return 0;
source = SOUND_EXT;
dataPtr = (byte *) _vm->_game->loadExtData(id, 0, 0, &dataSize); if (!sample->load(type, dataPtr, dataSize)) {
} else { delete[] dataPtr;
int16 totSize; return 0;
}
source = SOUND_TOT;
dataPtr = (byte *) _vm->_game->loadTotResource(id, &totSize);
dataSize = (uint32) ((int32) totSize);
}
if (dataPtr) {
sample->load(type, source, dataPtr, dataSize);
sample->_id = id; sample->_id = id;
return slot | slotIdMask;
} }
Resource *resource = _vm->_game->_resources->getResource(id);
if (!resource)
return 0;
if (!sample->load(type, resource)) {
delete resource;
return 0;
}
sample->_id = id;
return slot | slotIdMask; return slot | slotIdMask;
} }

View File

@ -33,6 +33,7 @@
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
namespace Gob { namespace Gob {
@ -81,11 +82,11 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams &params) {
stringVar = stringStartVar; stringVar = stringStartVar;
WRITE_VARO_UINT8(stringVar, 0); WRITE_VARO_UINT8(stringVar, 0);
if (!_vm->_game->_totTextData) TextItem *textItem = _vm->_game->_resources->getTextItem(totTextItem);
if (!textItem)
return false; return false;
totData = _vm->_game->_totTextData->dataPtr + totData = textItem->getData();
_vm->_game->_totTextData->items[totTextItem].offset;
// Skip background rectangles // Skip background rectangles
while (((int16) READ_LE_UINT16(totData)) != -1) while (((int16) READ_LE_UINT16(totData)) != -1)
@ -136,6 +137,7 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams &params) {
if ((n != 0) || (*totData == 1) || if ((n != 0) || (*totData == 1) ||
(*totData == 6) || (*totData == 7)) { (*totData == 6) || (*totData == 7)) {
WRITE_VARO_UINT8(stringVar, 0); WRITE_VARO_UINT8(stringVar, 0);
delete textItem;
return false; return false;
} }
@ -167,8 +169,9 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams &params) {
WRITE_VARO_UINT16(stringVar, offX); WRITE_VARO_UINT16(stringVar, offX);
WRITE_VARO_UINT16(stringVar + 2, offY); WRITE_VARO_UINT16(stringVar + 2, offY);
WRITE_VARO_UINT16(stringVar + 4, WRITE_VARO_UINT16(stringVar + 4,
totData - _vm->_game->_totTextData->dataPtr); totData - _vm->_game->_resources->getTexts());
WRITE_VARO_UINT8(stringVar + 6, 0); WRITE_VARO_UINT8(stringVar + 6, 0);
delete textItem;
return false; return false;
} }
@ -235,6 +238,7 @@ bool Inter_v3::o3_getTotTextItemPart(OpFuncParams &params) {
} }
} }
delete textItem;
return false; return false;
} }

View File

@ -34,6 +34,7 @@
#include "gob/game.h" #include "gob/game.h"
#include "gob/expression.h" #include "gob/expression.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/sound/sound.h" #include "gob/sound/sound.h"
#include "gob/videoplayer.h" #include "gob/videoplayer.h"
@ -241,18 +242,21 @@ bool Inter_v6::o6_loadCursor(OpFuncParams &params) {
if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth()) if ((index * _vm->_draw->_cursorWidth) >= _vm->_draw->_cursorSprites->getWidth())
return false; return false;
int16 width, height; Resource *resource = _vm->_game->_resources->getResource((uint16) id);
byte *dataBuf = _vm->_game->loadTotResource(id, 0, &width, &height); if (!resource)
return false;
_vm->_video->fillRect(*_vm->_draw->_cursorSprites, _vm->_video->fillRect(*_vm->_draw->_cursorSprites,
index * _vm->_draw->_cursorWidth, 0, index * _vm->_draw->_cursorWidth, 0,
index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1, index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
_vm->_draw->_cursorHeight - 1, 0); _vm->_draw->_cursorHeight - 1, 0);
_vm->_video->drawPackedSprite(dataBuf, width, height, _vm->_video->drawPackedSprite(resource->getData(),
resource->getWidth(), resource->getHeight(),
index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites); index * _vm->_draw->_cursorWidth, 0, 0, *_vm->_draw->_cursorSprites);
_vm->_draw->_cursorAnimLow[index] = 0; _vm->_draw->_cursorAnimLow[index] = 0;
delete resource;
return false; return false;
} }

View File

@ -32,6 +32,7 @@
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/mult.h" #include "gob/mult.h"
namespace Gob { namespace Gob {
@ -51,7 +52,6 @@ void Map_v2::loadMapObjects(const char *avjFile) {
int16 mapWidth, mapHeight; int16 mapWidth, mapHeight;
int16 tmp; int16 tmp;
byte *variables; byte *variables;
byte *extData;
uint32 tmpPos; uint32 tmpPos;
uint32 passPos; uint32 passPos;
@ -65,8 +65,11 @@ void Map_v2::loadMapObjects(const char *avjFile) {
return; return;
} }
extData = _vm->_game->loadExtData(id, 0, 0); Resource *resource = _vm->_game->_resources->getResource(id);
Common::MemoryReadStream mapData(extData, 4294967295U); if (!resource)
return;
Common::SeekableReadStream &mapData = *resource->stream();
if (mapData.readByte() == 3) { if (mapData.readByte() == 3) {
_screenWidth = 640; _screenWidth = 640;
@ -88,7 +91,7 @@ void Map_v2::loadMapObjects(const char *avjFile) {
passPos = mapData.pos(); passPos = mapData.pos();
mapData.skip(_mapWidth * _mapHeight); mapData.skip(_mapWidth * _mapHeight);
if (*extData == 1) if (resource->getData()[0] == 1)
wayPointsCount = _wayPointsCount = 40; wayPointsCount = _wayPointsCount = 40;
else else
wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount; wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount;
@ -134,7 +137,7 @@ void Map_v2::loadMapObjects(const char *avjFile) {
for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++) for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1); _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
delete[] extData; delete resource;
} }
void Map_v2::loadGoblinStates(Common::SeekableReadStream &data, int index) { void Map_v2::loadGoblinStates(Common::SeekableReadStream &data, int index) {

View File

@ -32,6 +32,7 @@
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/mult.h" #include "gob/mult.h"
namespace Gob { namespace Gob {
@ -49,7 +50,6 @@ void Map_v4::loadMapObjects(const char *avjFile) {
int16 mapWidth, mapHeight; int16 mapWidth, mapHeight;
int16 tmp; int16 tmp;
byte *variables; byte *variables;
byte *extData;
uint32 tmpPos; uint32 tmpPos;
uint32 passPos; uint32 passPos;
@ -66,8 +66,11 @@ void Map_v4::loadMapObjects(const char *avjFile) {
return; return;
} }
extData = _vm->_game->loadExtData(id, 0, 0); Resource *resource = _vm->_game->_resources->getResource(id);
Common::MemoryReadStream mapData(extData, 4294967295U); if (!resource)
return;
Common::SeekableReadStream &mapData = *resource->stream();
_widthByte = mapData.readByte(); _widthByte = mapData.readByte();
if (_widthByte == 4) { if (_widthByte == 4) {
@ -99,7 +102,7 @@ void Map_v4::loadMapObjects(const char *avjFile) {
passPos = mapData.pos(); passPos = mapData.pos();
mapData.skip(_mapWidth * _mapHeight); mapData.skip(_mapWidth * _mapHeight);
if (*extData == 1) if (resource->getData()[0] == 1)
wayPointsCount = _wayPointsCount = 40; wayPointsCount = _wayPointsCount = 40;
else else
wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount; wayPointsCount = _wayPointsCount == 0 ? 1 : _wayPointsCount;
@ -150,7 +153,7 @@ void Map_v4::loadMapObjects(const char *avjFile) {
for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++) for (int i = 0; i < _vm->_goblin->_soundSlotsCount; i++)
_vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1); _vm->_goblin->_soundSlots[i] = _vm->_inter->loadSound(1);
delete[] extData; delete resource;
} }
} // End of namespace Gob } // End of namespace Gob

View File

@ -44,6 +44,7 @@ MODULE_OBJS := \
mult_v1.o \ mult_v1.o \
mult_v2.o \ mult_v2.o \
palanim.o \ palanim.o \
resources.o \
scenery.o \ scenery.o \
scenery_v1.o \ scenery_v1.o \
scenery_v2.o \ scenery_v2.o \

View File

@ -33,6 +33,7 @@
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/scenery.h" #include "gob/scenery.h"
@ -42,9 +43,6 @@ Mult_v1::Mult_v1(GobEngine *vm) : Mult(vm) {
} }
void Mult_v1::loadMult(int16 resId) { void Mult_v1::loadMult(int16 resId) {
uint32 dataSize;
byte *extData;
debugC(4, kDebugGameFlow, "Loading mult"); debugC(4, kDebugGameFlow, "Loading mult");
_multData = new Mult_Data; _multData = new Mult_Data;
@ -53,8 +51,11 @@ void Mult_v1::loadMult(int16 resId) {
_multData->sndSlotsCount = 0; _multData->sndSlotsCount = 0;
_multData->frameStart = 0; _multData->frameStart = 0;
extData = (byte *) _vm->_game->loadExtData(resId, 0, 0, &dataSize); Resource *resource = _vm->_game->_resources->getResource(resId);
Common::MemoryReadStream data(extData, dataSize); if (!resource)
return;
Common::SeekableReadStream &data = *resource->stream();
_multData->staticCount = data.readSByte() + 1; _multData->staticCount = data.readSByte() + 1;
_multData->animCount = data.readSByte() + 1; _multData->animCount = data.readSByte() + 1;
@ -187,7 +188,7 @@ void Mult_v1::loadMult(int16 resId) {
} }
} }
delete[] extData; delete resource;
} }
void Mult_v1::freeMultKeys() { void Mult_v1::freeMultKeys() {

View File

@ -33,6 +33,7 @@
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/goblin.h" #include "gob/goblin.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/scenery.h" #include "gob/scenery.h"
@ -60,8 +61,6 @@ void Mult_v2::loadMult(int16 resId) {
int8 index; int8 index;
uint8 staticCount; uint8 staticCount;
uint8 animCount; uint8 animCount;
uint32 dataSize;
byte *extData;
bool hasImds; bool hasImds;
index = (resId & 0x8000) ? _vm->_game->_script->readByte() : 0; index = (resId & 0x8000) ? _vm->_game->_script->readByte() : 0;
@ -80,8 +79,11 @@ void Mult_v2::loadMult(int16 resId) {
_multData->sndSlotsCount = 0; _multData->sndSlotsCount = 0;
_multData->frameStart = 0; _multData->frameStart = 0;
extData = (byte *) _vm->_game->loadExtData(resId, 0, 0, &dataSize); Resource *resource = _vm->_game->_resources->getResource(resId);
Common::MemoryReadStream data(extData, dataSize); if (!resource)
return;
Common::SeekableReadStream &data = *resource->stream();
_multData->staticCount = staticCount = data.readSByte(); _multData->staticCount = staticCount = data.readSByte();
_multData->animCount = animCount = data.readSByte(); _multData->animCount = animCount = data.readSByte();
@ -243,7 +245,7 @@ void Mult_v2::loadMult(int16 resId) {
if (hasImds) if (hasImds)
loadImds(data); loadImds(data);
delete[] extData; delete resource;
} }
void Mult_v2::loadImds(Common::SeekableReadStream &data) { void Mult_v2::loadImds(Common::SeekableReadStream &data) {

704
engines/gob/resources.cpp Normal file
View File

@ -0,0 +1,704 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/util.h"
#include "common/endian.h"
#include "common/stream.h"
#include "gob/gob.h"
#include "gob/resources.h"
#include "gob/totfile.h"
#include "gob/dataio.h"
#include "gob/game.h"
#include "gob/global.h"
namespace Gob {
Resource::Resource(byte *data, int32 size, bool needFree,
int16 width, int16 height) {
_data = data;
_size = size;
_width = width;
_height = height;
_needFree = needFree;
_stream = new Common::MemoryReadStream(data, size);
}
Resource::~Resource() {
delete _stream;
if (_needFree)
delete[] _data;
}
byte *Resource::getData() const {
return _data;
}
int32 Resource::getSize() const {
return _size;
}
int16 Resource::getWidth() const {
return _width;
}
int16 Resource::getHeight() const {
return _height;
}
Common::MemoryReadStream *Resource::stream() const {
return _stream;
}
TextItem::TextItem(byte *data, int32 size) {
_data = data;
_size = size;
_stream = new Common::MemoryReadStream(data, size);
}
TextItem::~TextItem() {
delete _stream;
}
byte *TextItem::getData() const {
return _data;
}
int32 TextItem::getSize() const {
return _size;
}
Common::MemoryReadStream *TextItem::stream() const {
return _stream;
}
Resources::TOTResourceTable::TOTResourceTable() {
items = 0;
}
Resources::TOTResourceTable::~TOTResourceTable() {
delete[] items;
}
Resources::EXTResourceTable::EXTResourceTable() {
itemsCount = 0;
unknown = 0;
items = 0;
}
Resources::EXTResourceTable::~EXTResourceTable() {
delete[] items;
}
Resources::TOTTextTable::TOTTextTable() {
items = 0;
data = 0;
needFree = false;
}
Resources::TOTTextTable::~TOTTextTable() {
delete[] items;
if (needFree)
delete[] data;
}
Resources::Resources(GobEngine *vm) : _vm(vm) {
unload(false);
}
Resources::~Resources() {
unload();
}
bool Resources::load(const Common::String &fileName) {
unload();
Common::String fileBase;
_totFile = TOTFile::createFileName(fileName, _hasLOM);
if (_hasLOM) {
warning("Stub: Resources::load(%s)", fileName.c_str());
unload();
return false;
}
fileBase = TOTFile::getFileBase(fileName);
_extFile = fileBase + ".ext";
if (!loadTOTResourceTable()) {
unload();
return false;
}
if (!loadEXTResourceTable()) {
unload();
return false;
}
if (!loadTOTTextTable(fileBase)) {
unload();
return false;
}
if (!loadIMFile()) {
unload();
return false;
}
if (!loadEXFile()) {
unload();
return false;
}
return true;
}
void Resources::unload(bool del) {
if (del) {
delete _totResourceTable;
delete _extResourceTable;
delete _totTextTable;
delete[] _totData;
delete[] _imData;
_totFile.clear();
_extFile.clear();
_exFile.clear();
}
_totResourceTable = 0;
_extResourceTable = 0;
_totTextTable = 0;
_totData = 0;
_totSize = 0;
_imData = 0;
_imSize = 0;
}
bool Resources::isLoaded() const {
return (_totResourceTable != 0);
}
bool Resources::loadTOTResourceTable() {
TOTFile totFile(_vm);
if (!totFile.load(_totFile))
return false;
TOTFile::Properties totProps;
if (!totFile.getProperties(totProps))
return false;
Common::SeekableReadStream *stream = totFile.getStream();
if (!stream)
return false;
if ((totProps.resourcesOffset == 0xFFFFFFFF) ||
(totProps.resourcesOffset == 0))
// No resources here
return false;
_totResourceTable = new TOTResourceTable;
stream->seek(totProps.resourcesOffset);
_totResourceTable->itemsCount = stream->readSint16LE();
_totResourceTable->dataOffset = totProps.resourcesOffset + kTOTResTableSize +
_totResourceTable->itemsCount * kTOTResItemSize;
uint32 resSize = _totResourceTable->itemsCount * kTOTResItemSize +
kTOTResTableSize;
// Would the table actually fit into the TOT?
if ((totProps.resourcesOffset + resSize) > ((uint32) stream->size()))
return false;
_totResourceTable->unknown = stream->readByte();
_totResourceTable->items = new TOTResourceItem[_totResourceTable->itemsCount];
for (int i = 0; i < _totResourceTable->itemsCount; ++i) {
TOTResourceItem &item = _totResourceTable->items[i];
item.offset = stream->readSint32LE();
item.size = stream->readSint16LE();
item.width = stream->readSint16LE();
item.height = stream->readSint16LE();
if (item.offset < 0) {
item.type = kResourceIM;
item.index = -item.offset - 1;
} else
item.type = kResourceTOT;
}
_totResStart = totProps.scriptEnd;
_totSize = stream->size() - _totResStart;
if (_totSize <= 0)
return false;
if (!stream->seek(totProps.scriptEnd))
return false;
_totData = new byte[_totSize];
if (stream->read(_totData, _totSize) != _totSize)
return false;
return !stream->err();
}
bool Resources::loadEXTResourceTable() {
_extResourceTable = new EXTResourceTable;
DataStream *stream = _vm->_dataIO->getDataStream(_extFile.c_str());
if (!stream)
return true;
_extResourceTable->itemsCount = stream->readSint16LE();
_extResourceTable->unknown = stream->readByte();
if (_extResourceTable->itemsCount > 0)
_extResourceTable->items = new EXTResourceItem[_extResourceTable->itemsCount];
for (int i = 0; i < _extResourceTable->itemsCount; i++) {
EXTResourceItem &item = _extResourceTable->items[i];
item.offset = stream->readUint32LE();
item.size = stream->readUint16LE();
item.width = stream->readUint16LE();
item.height = stream->readUint16LE();
if (item.offset < 0) {
item.type = kResourceEX;
item.offset = -item.offset - 1;
} else {
item.type = kResourceEXT;
item.offset += kEXTResTableSize +
kEXTResItemSize * _extResourceTable->itemsCount;
}
item.packed = (item.width & 0x8000) != 0;
item.width &= 0x7FFF;
}
delete stream;
return true;
}
bool Resources::loadTOTTextTable(const Common::String &fileBase) {
TOTFile totFile(_vm);
if (!totFile.load(_totFile))
return false;
TOTFile::Properties totProps;
if (!totFile.getProperties(totProps))
return false;
Common::SeekableReadStream *stream = totFile.getStream();
if (!stream)
return false;
if (totProps.textsOffset == ((uint32) -1))
// No texts
return true;
_totTextTable = new TOTTextTable;
bool fromTOT;
if (totProps.textsOffset == 0) {
fromTOT = false;
_totTextTable->data = loadTOTLocTexts(fileBase, _totTextTable->size);
_totTextTable->needFree = true;
} else {
fromTOT = true;
_totTextTable->data = _totData + totProps.textsOffset - _totResStart;
_totTextTable->needFree = false;
_totTextTable->size = _totSize - (totProps.textsOffset - _totResStart);
}
if (_totTextTable->data) {
Common::MemoryReadStream totTextTable(_totTextTable->data, _totTextTable->size);
_totTextTable->itemsCount = totTextTable.readSint16LE() & 0x3FFF;
_totTextTable->items = new TOTTextItem[_totTextTable->itemsCount];
for (int i = 0; i < _totTextTable->itemsCount; ++i) {
TOTTextItem &item = _totTextTable->items[i];
item.offset = totTextTable.readSint16LE();
item.size = totTextTable.readSint16LE();
if (fromTOT)
item.offset -= _totResStart;
}
}
return true;
}
bool Resources::loadIMFile() {
TOTFile totFile(_vm);
if (!totFile.load(_totFile))
return false;
TOTFile::Properties totProps;
if (!totFile.getProperties(totProps))
return false;
if ((totProps.communHandling != 0) && (totProps.imFileNumber == 0))
// No IM file
return true;
Common::String imFile = "commun.im";
char num = totProps.imFileNumber + '0';
if (num == '0')
num = '1';
imFile += num;
DataStream *stream = _vm->_dataIO->getDataStream(imFile.c_str());
if (!stream)
return true;
_imSize = stream->size();
if (_imSize <= 0) {
_imSize = 0;
delete stream;
return true;
}
_imData = new byte[_imSize];
if (stream->read(_imData, _imSize) != _imSize) {
delete[] _imData;
_imData = 0;
_imSize = 0;
}
delete stream;
return true;
}
bool Resources::loadEXFile() {
TOTFile totFile(_vm);
if (!totFile.load(_totFile))
return false;
TOTFile::Properties totProps;
if (!totFile.getProperties(totProps))
return false;
_exFile = "commun.ex";
_exFile += totProps.exFileNumber + '0';
if (!_vm->_dataIO->existData(_exFile.c_str())) {
_exFile.clear();
return true;
}
return true;
}
Common::String Resources::getLocTextFile(const Common::String &fileBase,
int language) {
Common::String locTextFile = fileBase + ".";
switch (language) {
case kLanguageFrench:
locTextFile += "dat";
break;
case kLanguageGerman:
locTextFile += "all";
break;
case kLanguageSpanish:
locTextFile += "esp";
break;
case kLanguageItalian:
locTextFile += "ita";
break;
case kLanguageAmerican:
locTextFile += "usa";
break;
case kLanguageDutch:
locTextFile += "ndl";
break;
case kLanguageKorean:
locTextFile += "kor";
break;
case kLanguageHebrew:
locTextFile += "isr";
break;
default:
locTextFile += "ang";
break;
}
if (!_vm->_dataIO->existData(locTextFile.c_str()))
locTextFile.clear();
return locTextFile;
}
byte *Resources::loadTOTLocTexts(const Common::String &fileBase, int32 &size) {
Common::String locTextFile;
locTextFile = getLocTextFile(fileBase, _vm->_global->_languageWanted);
if (!locTextFile.empty()) {
_vm->_global->_foundLanguage = true;
_vm->_global->_language = _vm->_global->_languageWanted;
} else if (!_vm->_global->_foundLanguage) {
// Trying US for GB and vice versa
if (_vm->_global->_languageWanted == kLanguageBritish) {
locTextFile = getLocTextFile(fileBase, kLanguageAmerican);
if (!locTextFile.empty())
_vm->_global->_language = kLanguageAmerican;
} else if (_vm->_global->_languageWanted == kLanguageAmerican) {
locTextFile = getLocTextFile(fileBase, kLanguageBritish);
if (!locTextFile.empty())
_vm->_global->_language = kLanguageBritish;
}
if (locTextFile.empty()) {
// Looking for the first existing language
for (int i = 0; i < 10; i++) {
locTextFile = getLocTextFile(fileBase, i);
if (!locTextFile.empty()) {
_vm->_global->_language = i;
break;
}
}
}
}
debugC(1, kDebugFileIO, "Using language %d for %s",
_vm->_global->_language, _totFile.c_str());
if (locTextFile.empty())
return 0;
size = _vm->_dataIO->getDataSize(locTextFile.c_str());
return _vm->_dataIO->getData(locTextFile.c_str());
}
Resource *Resources::getResource(uint16 id, int16 *width, int16 *height) const {
if (_hasLOM) {
warning("Stub: Resources::getResource(): Has LOM");
return 0;
}
Resource *resource = 0;
if (id >= 30000)
resource = getEXTResource(id - 30000);
else
resource = getTOTResource(id);
if (!resource)
return 0;
if (width)
*width = resource->getWidth();
if (height)
*height = resource->getHeight();
return resource;
}
TextItem *Resources::getTextItem(uint16 id) const {
if (!_totTextTable || !_totTextTable->data)
return 0;
if (id >= _totTextTable->itemsCount)
return 0;
TOTTextItem &totItem = _totTextTable->items[id];
if ((totItem.offset == 0xFFFF) || (totItem.size == 0))
return 0;
if ((totItem.offset + totItem.size) > (_totTextTable->size))
return 0;
return new TextItem(_totTextTable->data + totItem.offset, totItem.size);
}
byte *Resources::getTexts() const {
if (!_totTextTable)
return 0;
return _totTextTable->data;
}
Resource *Resources::getTOTResource(uint16 id) const {
if (id >= _totResourceTable->itemsCount) {
warning("Trying to load non-existent TOT resource (%s, %d/%d)",
_totFile.c_str(), id, _totResourceTable->itemsCount - 1);
return 0;
}
TOTResourceItem &totItem = _totResourceTable->items[id];
byte *data = 0;
if (totItem.type == kResourceIM)
data = getIMData(totItem);
if (totItem.type == kResourceTOT)
data = getTOTData(totItem);
if (!data)
return 0;
return new Resource(data, totItem.size, false, totItem.width, totItem.height);
}
Resource *Resources::getEXTResource(uint16 id) const {
if (!_extResourceTable || (id > _extResourceTable->itemsCount))
return 0;
EXTResourceItem &extItem = _extResourceTable->items[id];
uint32 size = extItem.size;
if (extItem.width & 0x4000)
size += 1 << 16;
if (extItem.width & 0x2000)
size += 2 << 16;
if (extItem.width & 0x1000)
size += 4 << 16;
if (extItem.height == 0)
size += extItem.width << 16;
byte *data = 0;
if (extItem.type == kResourceEXT)
data = getEXTData(extItem, size);
if (extItem.type == kResourceEX)
data = getEXData(extItem, size);
if (!data)
return 0;
if (extItem.packed) {
byte *packedData = data;
size = READ_LE_UINT32(packedData);
data = new byte[size];
_vm->_dataIO->unpackData(packedData, data);
delete[] packedData;
}
return new Resource(data, size, true, extItem.width & 0xFFF, extItem.height);
}
byte *Resources::getTOTData(TOTResourceItem &totItem) const {
if (totItem.size < 0)
return 0;
int32 offset = _totResourceTable->dataOffset + totItem.offset - _totResStart;
if ((offset < 0) || (((uint32) (offset + totItem.size)) > _totSize))
return 0;
return _totData + offset;
}
byte *Resources::getIMData(TOTResourceItem &totItem) const {
if (totItem.size < 0)
return 0;
int32 indexOffset = totItem.index * 4;
if ((indexOffset < 0) || (((uint32) indexOffset) >= _imSize))
return 0;
uint32 offset = READ_LE_UINT32(_imData + indexOffset);
if ((offset + totItem.size) > _imSize)
return 0;
return _imData + offset;
}
byte *Resources::getEXTData(EXTResourceItem &extItem, uint32 size) const {
DataStream *stream = _vm->_dataIO->getDataStream(_extFile.c_str());
if (!stream)
return 0;
if (!stream->seek(extItem.offset)) {
delete stream;
return 0;
}
byte *data = new byte[extItem.packed ? (size + 2) : size];
if (stream->read(data, size) != size) {
delete[] data;
delete stream;
return 0;
}
return data;
}
byte *Resources::getEXData(EXTResourceItem &extItem, uint32 size) const {
DataStream *stream = _vm->_dataIO->getDataStream(_exFile.c_str());
if (!stream)
return 0;
if (!stream->seek(extItem.offset)) {
delete stream;
return 0;
}
byte *data = new byte[extItem.packed ? (size + 2) : size];
if (stream->read(data, size) != size) {
delete[] data;
delete stream;
return 0;
}
return data;
}
} // End of namespace Gob

207
engines/gob/resources.h Normal file
View File

@ -0,0 +1,207 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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$
*
*/
#ifndef GOB_RESOURCES_H
#define GOB_RESOURCES_H
#include "common/str.h"
namespace Common {
class MemoryReadStream;
}
namespace Gob {
class GobEngine;
class Resource {
public:
Resource(byte *data, int32 size, bool needFree = true,
int16 width = 0, int16 height = 0);
~Resource();
byte *getData () const;
int32 getSize () const;
int16 getWidth () const;
int16 getHeight() const;
Common::MemoryReadStream *stream() const;
private:
byte *_data;
int32 _size;
int16 _width;
int16 _height;
bool _needFree;
Common::MemoryReadStream *_stream;
};
class TextItem {
public:
TextItem(byte *data, int32 size);
~TextItem();
byte *getData() const;
int32 getSize() const;
Common::MemoryReadStream *stream() const;
private:
byte *_data;
int32 _size;
Common::MemoryReadStream *_stream;
};
class Resources {
public:
Resources(GobEngine *vm);
~Resources();
bool load(const Common::String &fileName);
void unload(bool del = true);
bool isLoaded() const;
Resource *getResource(uint16 id, int16 *width = 0, int16 *height = 0) const;
TextItem *getTextItem(uint16 id) const;
byte *getTexts() const;
private:
// Structure sizes in the files
static const int kTOTResItemSize = 4 + 2 + 2 + 2;
static const int kTOTResTableSize = 2 + 1;
static const int kEXTResItemSize = 4 + 2 + 2 + 2;
static const int kEXTResTableSize = 2 + 1;
static const int kTOTTextTableSize = 2;
static const int kTOTTextItemSize = 2 + 2;
enum ResourceType {
kResourceTOT,
kResourceIM,
kResourceEXT,
kResourceEX
};
struct TOTResourceItem {
ResourceType type;
int16 size;
int16 width;
int16 height;
union {
int32 offset;
int32 index;
};
};
struct TOTResourceTable {
int16 itemsCount;
byte unknown;
TOTResourceItem *items;
uint32 dataOffset;
TOTResourceTable();
~TOTResourceTable();
};
struct EXTResourceItem {
ResourceType type;
int32 offset;
uint16 size;
int16 width;
int16 height;
bool packed;
};
struct EXTResourceTable {
int16 itemsCount;
byte unknown;
EXTResourceItem *items;
EXTResourceTable();
~EXTResourceTable();
};
struct TOTTextItem {
uint16 offset;
int16 size;
};
struct TOTTextTable {
bool needFree;
int16 itemsCount;
byte *data;
int32 size;
TOTTextItem *items;
TOTTextTable();
~TOTTextTable();
};
GobEngine *_vm;
Common::String _totFile;
Common::String _extFile;
Common::String _exFile;
byte *_totData;
uint32 _totSize;
byte *_imData;
uint32 _imSize;
bool _hasLOM;
int32 _totResStart;
TOTResourceTable *_totResourceTable;
EXTResourceTable *_extResourceTable;
TOTTextTable *_totTextTable;
bool loadTOTResourceTable();
bool loadEXTResourceTable();
bool loadTOTTextTable(const Common::String &fileBase);
bool loadIMFile();
bool loadEXFile();
byte *loadTOTLocTexts(const Common::String &fileBase, int32 &size);
bool getLocTextFile(char *locTextFile, int language);
Common::String getLocTextFile(const Common::String &fileBase, int language);
Resource *getTOTResource(uint16 id) const;
Resource *getEXTResource(uint16 id) const;
byte *getTOTData(TOTResourceItem &totItem) const;
byte *getIMData(TOTResourceItem &totItem) const;
byte *getEXTData(EXTResourceItem &extItem, uint32 size) const;
byte *getEXData(EXTResourceItem &extItem, uint32 size) const;
};
} // End of namespace Gob
#endif // GOB_RESOURCES_H

View File

@ -32,6 +32,7 @@
#include "gob/draw.h" #include "gob/draw.h"
#include "gob/game.h" #include "gob/game.h"
#include "gob/script.h" #include "gob/script.h"
#include "gob/resources.h"
#include "gob/inter.h" #include "gob/inter.h"
#include "gob/map.h" #include "gob/map.h"
#include "gob/videoplayer.h" #include "gob/videoplayer.h"
@ -40,33 +41,33 @@ namespace Gob {
Scenery::Scenery(GobEngine *vm) : _vm(vm) { Scenery::Scenery(GobEngine *vm) : _vm(vm) {
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
_spriteRefs[i] = 0; _spriteRefs[i] = 0;
_spriteResId[i] = 0; _spriteResId[i] = 0;
} }
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
_staticPictCount[i] = 0; _staticPictCount[i] = 0;
_staticResId[i] = 0; _staticResId[i] = 0;
_animPictCount[i] = 0; _animPictCount[i] = 0;
_animResId[i] = 0; _animResId[i] = 0;
} }
_curStatic = 0; _curStatic = 0;
_curStaticLayer = 0; _curStaticLayer = 0;
_toRedrawLeft = 0; _toRedrawLeft = 0;
_toRedrawRight = 0; _toRedrawRight = 0;
_toRedrawTop = 0; _toRedrawTop = 0;
_toRedrawBottom = 0; _toRedrawBottom = 0;
_animTop = 0; _animTop = 0;
_animLeft = 0; _animLeft = 0;
_pCaptureCounter = 0; _pCaptureCounter = 0;
for (int i = 0; i < 70; i++ ) { for (int i = 0; i < 70; i++ ) {
_staticPictToSprite[i] = 0; _staticPictToSprite[i] = 0;
_animPictToSprite[i] = 0; _animPictToSprite[i] = 0;
} }
} }
@ -79,17 +80,17 @@ Scenery::~Scenery() {
void Scenery::init() { void Scenery::init() {
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
_animPictCount[i] = 0; _animPictCount[i] = 0;
_staticPictCount[i] = -1; _staticPictCount[i] = -1;
} }
for (int i = 0; i < 20; i++) { for (int i = 0; i < 20; i++) {
_spriteRefs[i] = 0; _spriteRefs[i] = 0;
_spriteResId[i] = -1; _spriteResId[i] = -1;
} }
_curStaticLayer = -1; _curStaticLayer = -1;
_curStatic = -1; _curStatic = -1;
} }
int16 Scenery::loadStatic(char search) { int16 Scenery::loadStatic(char search) {
@ -98,8 +99,6 @@ int16 Scenery::loadStatic(char search) {
int16 picsCount; int16 picsCount;
int16 resId; int16 resId;
int16 sceneryIndex; int16 sceneryIndex;
byte *extData = 0;
byte *dataPtr;
Static *ptr; Static *ptr;
int16 width; int16 width;
int16 height; int16 height;
@ -108,11 +107,11 @@ int16 Scenery::loadStatic(char search) {
_vm->_game->_script->evalExpr(&sceneryIndex); _vm->_game->_script->evalExpr(&sceneryIndex);
size = _vm->_game->_script->readInt16(); size = _vm->_game->_script->readInt16();
backsPtr = (int16 *) (_vm->_game->_script->getData() + _vm->_game->_script->pos()); backsPtr = (int16 *) (_vm->_game->_script->getData() + _vm->_game->_script->pos());
_vm->_game->_script->skip(size * 2); _vm->_game->_script->skip(size * 2);
picsCount = _vm->_game->_script->readInt16(); picsCount = _vm->_game->_script->readInt16();
resId = _vm->_game->_script->readInt16(); resId = _vm->_game->_script->readInt16();
if (search) { if (search) {
int i; int i;
@ -129,42 +128,44 @@ int16 Scenery::loadStatic(char search) {
} }
_staticPictCount[sceneryIndex] = picsCount; _staticPictCount[sceneryIndex] = picsCount;
_staticResId[sceneryIndex] = resId; _staticResId[sceneryIndex] = resId;
if (resId >= 30000) { Resource *resource = _vm->_game->_resources->getResource((uint16) resId);
extData = _vm->_game->loadExtData(resId, 0, 0); if (!resource)
dataPtr = extData; return 0;
} else
dataPtr = _vm->_game->loadTotResource(resId);
ptr = &_statics[sceneryIndex]; ptr = &_statics[sceneryIndex];
ptr->layersCount = (int16) READ_LE_UINT16(dataPtr); ptr->layersCount = resource->stream()->readSint16LE();
dataPtr += 2;
ptr->layers = new StaticLayer[ptr->layersCount]; ptr->layers = new StaticLayer[ptr->layersCount];
for (int i = 0; i < ptr->layersCount; i++) { for (int i = 0; i < ptr->layersCount; i++) {
int16 offset = READ_LE_UINT16(dataPtr + i * 2); Common::SeekableReadStream &layerData = *resource->stream();
Common::MemoryReadStream layerData(dataPtr + offset, 4294967295U);
layerData.seek(2 + i * 2);
layerData.seek(layerData.readUint16LE());
ptr->layers[i].backResId = layerData.readSint16LE();
ptr->layers[i].planeCount = layerData.readSint16LE(); ptr->layers[i].planeCount = layerData.readSint16LE();
if (ptr->layers[i].planeCount > 0) {
ptr->layers[i].planes = new StaticPlane[ptr->layers[i].planeCount]; ptr->layers[i].planes = new StaticPlane[ptr->layers[i].planeCount];
for (int j = 0; j < ptr->layers[i].planeCount; ++j) { for (int j = 0; j < ptr->layers[i].planeCount; j++) {
ptr->layers[i].planes[j].pictIndex = layerData.readByte(); ptr->layers[i].planes[j].pictIndex = layerData.readByte();
ptr->layers[i].planes[j].pieceIndex = layerData.readByte(); ptr->layers[i].planes[j].pieceIndex = layerData.readByte();
ptr->layers[i].planes[j].drawOrder = layerData.readByte(); ptr->layers[i].planes[j].drawOrder = layerData.readByte();
ptr->layers[i].planes[j].destX = layerData.readSint16LE(); ptr->layers[i].planes[j].destX = layerData.readSint16LE();
ptr->layers[i].planes[j].destY = layerData.readSint16LE(); ptr->layers[i].planes[j].destY = layerData.readSint16LE();
ptr->layers[i].planes[j].transp = layerData.readSByte(); ptr->layers[i].planes[j].transp = layerData.readSByte();
} }
} else
ptr->layers[i].planes = 0;
ptr->layers[i].backResId = (int16) READ_LE_UINT16(backsPtr); ptr->layers[i].backResId = (int16) READ_LE_UINT16(backsPtr);
backsPtr++; backsPtr++;
} }
ptr->pieces = new PieceDesc*[picsCount]; ptr->pieces = new PieceDesc*[picsCount];
ptr->piecesCount = new uint32[picsCount]; ptr->piecesCount = new uint32[picsCount];
for (int i = 0; i < picsCount; i++) { for (int i = 0; i < picsCount; i++) {
@ -172,8 +173,8 @@ int16 Scenery::loadStatic(char search) {
loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]); loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]);
width = _vm->_game->_script->readInt16(); width = _vm->_game->_script->readInt16();
height = _vm->_game->_script->readInt16(); height = _vm->_game->_script->readInt16();
sprResId = _vm->_game->_script->readInt16(); sprResId = _vm->_game->_script->readInt16();
for (sprIndex = 0; sprIndex < 20; sprIndex++) { for (sprIndex = 0; sprIndex < 20; sprIndex++) {
if (_spriteResId[sprIndex] == sprResId) if (_spriteResId[sprIndex] == sprResId)
@ -184,9 +185,7 @@ int16 Scenery::loadStatic(char search) {
_staticPictToSprite[7 * sceneryIndex + i] = sprIndex; _staticPictToSprite[7 * sceneryIndex + i] = sprIndex;
_spriteRefs[sprIndex]++; _spriteRefs[sprIndex]++;
} else { } else {
for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; for (sprIndex = 19; _vm->_draw->_spritesArray[sprIndex] != 0; sprIndex--);
sprIndex--)
;
_staticPictToSprite[7 * sceneryIndex + i] = sprIndex; _staticPictToSprite[7 * sceneryIndex + i] = sprIndex;
_spriteRefs[sprIndex] = 1; _spriteRefs[sprIndex] = 1;
@ -194,17 +193,16 @@ int16 Scenery::loadStatic(char search) {
_vm->_draw->initSpriteSurf(sprIndex, width, height, 2); _vm->_draw->initSpriteSurf(sprIndex, width, height, 2);
_vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]); _vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]);
_vm->_draw->_destSurface = sprIndex; _vm->_draw->_destSurface = sprIndex;
_vm->_draw->_spriteLeft = sprResId; _vm->_draw->_spriteLeft = sprResId;
_vm->_draw->_transparency = 0; _vm->_draw->_transparency = 0;
_vm->_draw->_destSpriteX = 0; _vm->_draw->_destSpriteX = 0;
_vm->_draw->_destSpriteY = 0; _vm->_draw->_destSpriteY = 0;
_vm->_draw->spriteOperation(DRAW_LOADSPRITE); _vm->_draw->spriteOperation(DRAW_LOADSPRITE);
} }
} }
delete[] extData; delete resource;
return sceneryIndex + 100; return sceneryIndex + 100;
} }
@ -230,12 +228,13 @@ void Scenery::freeStatic(int16 index) {
for (int i = 0; i < _statics[index].layersCount; i++) for (int i = 0; i < _statics[index].layersCount; i++)
delete[] _statics[index].layers[i].planes; delete[] _statics[index].layers[i].planes;
delete[] _statics[index].layers; delete[] _statics[index].layers;
delete[] _statics[index].pieces; delete[] _statics[index].pieces;
delete[] _statics[index].piecesCount; delete[] _statics[index].piecesCount;
_statics[index].layersCount = 0; _statics[index].layersCount = 0;
_staticPictCount[index] = -1; _staticPictCount[index] = -1;
} }
void Scenery::renderStatic(int16 scenery, int16 layer) { void Scenery::renderStatic(int16 scenery, int16 layer) {
@ -262,22 +261,21 @@ void Scenery::renderStatic(int16 scenery, int16 layer) {
_vm->_draw->_spriteLeft = layerPtr->backResId; _vm->_draw->_spriteLeft = layerPtr->backResId;
if (_vm->_draw->_spriteLeft != -1) { if (_vm->_draw->_spriteLeft != -1) {
_vm->_draw->_destSpriteX = 0; _vm->_draw->_destSpriteX = 0;
_vm->_draw->_destSpriteY = 0; _vm->_draw->_destSpriteY = 0;
_vm->_draw->_destSurface = 21; _vm->_draw->_destSurface = 21;
_vm->_draw->_transparency = 0; _vm->_draw->_transparency = 0;
_vm->_draw->spriteOperation(DRAW_LOADSPRITE); _vm->_draw->spriteOperation(DRAW_LOADSPRITE);
} }
planeCount = layerPtr->planeCount; planeCount = layerPtr->planeCount;
for (order = 0; order < 100; order++) { for (order = 0; order < 100; order++) {
for (plane = 0, planePtr = layerPtr->planes; for (plane = 0, planePtr = layerPtr->planes; plane < planeCount; plane++, planePtr++) {
plane < planeCount; plane++, planePtr++) {
if (planePtr->drawOrder != order) if (planePtr->drawOrder != order)
continue; continue;
pieceIndex = planePtr->pieceIndex; pieceIndex = planePtr->pieceIndex;
pictIndex = planePtr->pictIndex - 1; pictIndex = planePtr->pictIndex - 1;
if (pictIndex >= _staticPictCount[scenery]) if (pictIndex >= _staticPictCount[scenery])
continue; continue;
@ -290,19 +288,19 @@ void Scenery::renderStatic(int16 scenery, int16 layer) {
_vm->_draw->_destSpriteX = planePtr->destX; _vm->_draw->_destSpriteX = planePtr->destX;
_vm->_draw->_destSpriteY = planePtr->destY; _vm->_draw->_destSpriteY = planePtr->destY;
left = ptr->pieces[pictIndex][pieceIndex].left; left = ptr->pieces[pictIndex][pieceIndex].left;
right = ptr->pieces[pictIndex][pieceIndex].right; right = ptr->pieces[pictIndex][pieceIndex].right;
top = ptr->pieces[pictIndex][pieceIndex].top; top = ptr->pieces[pictIndex][pieceIndex].top;
bottom = ptr->pieces[pictIndex][pieceIndex].bottom; bottom = ptr->pieces[pictIndex][pieceIndex].bottom;
_vm->_draw->_sourceSurface = _vm->_draw->_sourceSurface =
_staticPictToSprite[scenery * 7 + pictIndex]; _staticPictToSprite[scenery * 7 + pictIndex];
_vm->_draw->_destSurface = 21; _vm->_draw->_destSurface = 21;
_vm->_draw->_spriteLeft = left; _vm->_draw->_spriteLeft = left;
_vm->_draw->_spriteTop = top; _vm->_draw->_spriteTop = top;
_vm->_draw->_spriteRight = right - left + 1; _vm->_draw->_spriteRight = right - left + 1;
_vm->_draw->_spriteBottom = bottom - top + 1; _vm->_draw->_spriteBottom = bottom - top + 1;
_vm->_draw->_transparency = planePtr->transp ? 3 : 0; _vm->_draw->_transparency = planePtr->transp ? 3 : 0;
_vm->_draw->spriteOperation(DRAW_BLITSURF); _vm->_draw->spriteOperation(DRAW_BLITSURF);
} }
} }
@ -338,7 +336,7 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) {
continue; continue;
pieceIndex = planePtr->pieceIndex; pieceIndex = planePtr->pieceIndex;
pictIndex = planePtr->pictIndex - 1; pictIndex = planePtr->pictIndex - 1;
if (pictIndex >= _staticPictCount[index]) if (pictIndex >= _staticPictCount[index])
continue; continue;
@ -352,9 +350,9 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) {
_vm->_draw->_destSpriteX = planePtr->destX; _vm->_draw->_destSpriteX = planePtr->destX;
_vm->_draw->_destSpriteY = planePtr->destY; _vm->_draw->_destSpriteY = planePtr->destY;
left = pictPtr[pictIndex][pieceIndex].left; left = pictPtr[pictIndex][pieceIndex].left;
right = pictPtr[pictIndex][pieceIndex].right; right = pictPtr[pictIndex][pieceIndex].right;
top = pictPtr[pictIndex][pieceIndex].top; top = pictPtr[pictIndex][pieceIndex].top;
bottom = pictPtr[pictIndex][pieceIndex].bottom; bottom = pictPtr[pictIndex][pieceIndex].bottom;
if (_vm->_draw->_destSpriteX > _toRedrawRight) if (_vm->_draw->_destSpriteX > _toRedrawRight)
@ -373,10 +371,10 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) {
_vm->_draw->_destSpriteY = _toRedrawTop; _vm->_draw->_destSpriteY = _toRedrawTop;
} }
_vm->_draw->_spriteLeft = left; _vm->_draw->_spriteLeft = left;
_vm->_draw->_spriteTop = top; _vm->_draw->_spriteTop = top;
_vm->_draw->_spriteRight = right - left + 1; _vm->_draw->_spriteRight = right - left + 1;
_vm->_draw->_spriteBottom = bottom - top + 1; _vm->_draw->_spriteBottom = bottom - top + 1;
if ((_vm->_draw->_spriteRight <= 0) || if ((_vm->_draw->_spriteRight <= 0) ||
(_vm->_draw->_spriteBottom <= 0)) (_vm->_draw->_spriteBottom <= 0))
@ -394,8 +392,8 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) {
_vm->_draw->_sourceSurface = _vm->_draw->_sourceSurface =
_staticPictToSprite[index * 7 + pictIndex]; _staticPictToSprite[index * 7 + pictIndex];
_vm->_draw->_destSurface = 21; _vm->_draw->_destSurface = 21;
_vm->_draw->_transparency = planePtr->transp ? 3 : 0; _vm->_draw->_transparency = planePtr->transp ? 3 : 0;
_vm->_draw->spriteOperation(DRAW_BLITSURF); _vm->_draw->spriteOperation(DRAW_BLITSURF);
} }
} }
@ -423,8 +421,6 @@ int16 Scenery::loadAnim(char search) {
int16 j; int16 j;
int16 sceneryIndex; int16 sceneryIndex;
int16 framesCount; int16 framesCount;
byte *extData;
byte *dataPtr;
Animation *ptr; Animation *ptr;
int16 width; int16 width;
int16 height; int16 height;
@ -432,7 +428,6 @@ int16 Scenery::loadAnim(char search) {
int16 sprIndex; int16 sprIndex;
uint32 layerPos; uint32 layerPos;
extData = 0;
_vm->_game->_script->evalExpr(&sceneryIndex); _vm->_game->_script->evalExpr(&sceneryIndex);
picsCount = _vm->_game->_script->readInt16(); picsCount = _vm->_game->_script->readInt16();
resId = _vm->_game->_script->readInt16(); resId = _vm->_game->_script->readInt16();
@ -452,50 +447,50 @@ int16 Scenery::loadAnim(char search) {
_animPictCount[sceneryIndex] = picsCount; _animPictCount[sceneryIndex] = picsCount;
_animResId[sceneryIndex] = resId; _animResId[sceneryIndex] = resId;
if (resId >= 30000) { Resource *resource = _vm->_game->_resources->getResource((uint16) resId);
extData = _vm->_game->loadExtData(resId, 0, 0); if (!resource)
dataPtr = extData; return 0;
} else
dataPtr = _vm->_game->loadTotResource(resId);
ptr = &_animations[sceneryIndex]; ptr = &_animations[sceneryIndex];
ptr->layersCount = READ_LE_UINT16(dataPtr); ptr->layersCount = resource->stream()->readSint16LE();
dataPtr += 2;
ptr->layers = new AnimLayer[ptr->layersCount]; ptr->layers = new AnimLayer[ptr->layersCount];
for (i = 0; i < ptr->layersCount; i++) { for (i = 0; i < ptr->layersCount; i++) {
int16 offset = READ_LE_UINT16(dataPtr + i * 2); Common::SeekableReadStream &layerData = *resource->stream();
Common::MemoryReadStream layerData(dataPtr + offset - 2, 4294967295U);
ptr->layers[i].unknown0 = layerData.readSint16LE(); layerData.seek(2 + i * 2);
ptr->layers[i].posX = layerData.readSint16LE(); layerData.seek(layerData.readUint16LE());
ptr->layers[i].posY = layerData.readSint16LE();
ptr->layers[i].animDeltaX = layerData.readSint16LE(); ptr->layers[i].unknown0 = layerData.readSint16LE();
ptr->layers[i].animDeltaY = layerData.readSint16LE(); ptr->layers[i].posX = layerData.readSint16LE();
ptr->layers[i].transp = layerData.readSByte(); ptr->layers[i].posY = layerData.readSint16LE();
ptr->layers[i].animDeltaX = layerData.readSint16LE();
ptr->layers[i].animDeltaY = layerData.readSint16LE();
ptr->layers[i].transp = layerData.readSByte();
ptr->layers[i].framesCount = layerData.readSint16LE(); ptr->layers[i].framesCount = layerData.readSint16LE();
// Going through the AnimFramePiece, finding the end for each
layerPos = layerData.pos(); layerPos = layerData.pos();
framesCount = 0; framesCount = 0;
layerData.seek(4, SEEK_CUR); for (j = 0; j < ptr->layers[i].framesCount; j++) {
for (j = 0; j < ptr->layers[i].framesCount; layerData.skip(4); // pictIndex, pieceIndex, destX, destY
j++, framesCount++, layerData.seek(4, SEEK_CUR)) {
while (layerData.readByte() == 1) { while (layerData.readByte() == 1) {
framesCount++; framesCount++;
layerData.seek(4, SEEK_CUR); layerData.skip(4); // pictIndex, pieceIndex, destX, destY
} }
framesCount++;
} }
layerData.seek(layerPos); layerData.seek(layerPos);
ptr->layers[i].frames = new AnimFramePiece[framesCount]; ptr->layers[i].frames = new AnimFramePiece[framesCount];
for (j = 0; j < framesCount; j++) { for (j = 0; j < framesCount; j++) {
ptr->layers[i].frames[j].pictIndex = layerData.readByte(); ptr->layers[i].frames[j].pictIndex = layerData.readByte();
ptr->layers[i].frames[j].pieceIndex = layerData.readByte(); ptr->layers[i].frames[j].pieceIndex = layerData.readByte();
ptr->layers[i].frames[j].destX = layerData.readSByte(); ptr->layers[i].frames[j].destX = layerData.readSByte();
ptr->layers[i].frames[j].destY = layerData.readSByte(); ptr->layers[i].frames[j].destY = layerData.readSByte();
ptr->layers[i].frames[j].notFinal = layerData.readSByte(); ptr->layers[i].frames[j].notFinal = layerData.readSByte();
} }
} }
@ -507,8 +502,8 @@ int16 Scenery::loadAnim(char search) {
loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]); loadPieces(pictDescId, ptr->pieces[i], ptr->piecesCount[i]);
width = _vm->_game->_script->readInt16(); width = _vm->_game->_script->readInt16();
height = _vm->_game->_script->readInt16(); height = _vm->_game->_script->readInt16();
sprResId = _vm->_game->_script->readInt16(); sprResId = _vm->_game->_script->readInt16();
for (sprIndex = 0; sprIndex < 20; sprIndex++) for (sprIndex = 0; sprIndex < 20; sprIndex++)
if (_spriteResId[sprIndex] == sprResId) if (_spriteResId[sprIndex] == sprResId)
@ -523,22 +518,21 @@ int16 Scenery::loadAnim(char search) {
; ;
_animPictToSprite[7 * sceneryIndex + i] = sprIndex; _animPictToSprite[7 * sceneryIndex + i] = sprIndex;
_spriteRefs[sprIndex] = 1; _spriteRefs[sprIndex] = 1;
_spriteResId[sprIndex] = sprResId; _spriteResId[sprIndex] = sprResId;
_vm->_draw->initSpriteSurf(sprIndex, width, height, 2); _vm->_draw->initSpriteSurf(sprIndex, width, height, 2);
_vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]); _vm->_video->clearSurf(*_vm->_draw->_spritesArray[sprIndex]);
_vm->_draw->_destSurface = sprIndex; _vm->_draw->_destSurface = sprIndex;
_vm->_draw->_spriteLeft = sprResId; _vm->_draw->_spriteLeft = sprResId;
_vm->_draw->_transparency = 0; _vm->_draw->_transparency = 0;
_vm->_draw->_destSpriteX = 0; _vm->_draw->_destSpriteX = 0;
_vm->_draw->_destSpriteY = 0; _vm->_draw->_destSpriteY = 0;
_vm->_draw->spriteOperation(DRAW_LOADSPRITE); _vm->_draw->spriteOperation(DRAW_LOADSPRITE);
} }
} }
delete[] extData; delete resource;
return sceneryIndex + 100; return sceneryIndex + 100;
} }
@ -564,6 +558,7 @@ void Scenery::freeAnim(int16 index) {
for (int i = 0; i < _animations[index].layersCount; i++) for (int i = 0; i < _animations[index].layersCount; i++)
delete[] _animations[index].layers[i].frames; delete[] _animations[index].layers[i].frames;
delete[] _animations[index].layers; delete[] _animations[index].layers;
delete[] _animations[index].pieces; delete[] _animations[index].pieces;
delete[] _animations[index].piecesCount; delete[] _animations[index].piecesCount;
@ -608,8 +603,8 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
return; return;
_vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
_toRedrawRight - _toRedrawLeft + 1, _toRedrawRight - _toRedrawLeft + 1,
_toRedrawBottom - _toRedrawTop + 1); _toRedrawBottom - _toRedrawTop + 1);
*_pCaptureCounter = *_pCaptureCounter + 1; *_pCaptureCounter = *_pCaptureCounter + 1;
} }
@ -629,7 +624,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
while (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) <= frame) while (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) <= frame)
_vm->_vidPlayer->slotPlay(obj.videoSlot - 1); _vm->_vidPlayer->slotPlay(obj.videoSlot - 1);
} else { } else {
int16 curFrame = _vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1); int16 curFrame = _vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1);
uint8 frameWrap = curFrame / 256; uint8 frameWrap = curFrame / 256;
frame = (frame + 1) % 256; frame = (frame + 1) % 256;
@ -637,17 +632,17 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
_vm->_vidPlayer->slotPlay(obj.videoSlot - 1); _vm->_vidPlayer->slotPlay(obj.videoSlot - 1);
} }
destX = 0; destX = 0;
destY = 0; destY = 0;
left = *(obj.pPosX); left = *(obj.pPosX);
top = *(obj.pPosY); top = *(obj.pPosY);
right = left + _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - 1; right = left + _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - 1;
bottom = top + _vm->_vidPlayer->getHeight(obj.videoSlot - 1) - 1; bottom = top + _vm->_vidPlayer->getHeight(obj.videoSlot - 1) - 1;
if (flags & 2) { if (flags & 2) {
if (left < _vm->_mult->_animLeft) { if (left < _vm->_mult->_animLeft) {
destX += _vm->_mult->_animLeft - left; destX += _vm->_mult->_animLeft - left;
left = _vm->_mult->_animLeft; left = _vm->_mult->_animLeft;
} }
if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right) if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right)
@ -655,7 +650,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
if (top < _vm->_mult->_animTop) { if (top < _vm->_mult->_animTop) {
destY += _vm->_mult->_animTop - top; destY += _vm->_mult->_animTop - top;
top = _vm->_mult->_animTop; top = _vm->_mult->_animTop;
} }
if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom) if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom)
@ -664,7 +659,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
} else if (flags & 4) { } else if (flags & 4) {
if (left < _toRedrawLeft) { if (left < _toRedrawLeft) {
destX += _toRedrawLeft - left; destX += _toRedrawLeft - left;
left = _toRedrawLeft; left = _toRedrawLeft;
} }
if (right > _toRedrawRight) if (right > _toRedrawRight)
@ -672,16 +667,16 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
if (top < _toRedrawTop) { if (top < _toRedrawTop) {
destY += _toRedrawTop - top; destY += _toRedrawTop - top;
top = _toRedrawTop; top = _toRedrawTop;
} }
if (bottom > _toRedrawBottom) if (bottom > _toRedrawBottom)
bottom = _toRedrawBottom; bottom = _toRedrawBottom;
} else { } else {
_toRedrawTop = top; _toRedrawTop = top;
_toRedrawLeft = left; _toRedrawLeft = left;
_toRedrawRight = right; _toRedrawRight = right;
_toRedrawBottom = bottom; _toRedrawBottom = bottom;
} }
@ -691,7 +686,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
if (left < _vm->_mult->_animLeft) { if (left < _vm->_mult->_animLeft) {
destX += _vm->_mult->_animLeft - left; destX += _vm->_mult->_animLeft - left;
left = _vm->_mult->_animLeft; left = _vm->_mult->_animLeft;
} }
if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right) if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right)
@ -699,40 +694,40 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
if (top < _vm->_mult->_animTop) { if (top < _vm->_mult->_animTop) {
destY += _vm->_mult->_animTop - top; destY += _vm->_mult->_animTop - top;
top = _vm->_mult->_animTop; top = _vm->_mult->_animTop;
} }
if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom) if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom)
bottom = _vm->_mult->_animTop + _vm->_mult->_animHeight - 1; bottom = _vm->_mult->_animTop + _vm->_mult->_animHeight - 1;
_vm->_draw->_spriteLeft = destX; _vm->_draw->_spriteLeft = destX;
_vm->_draw->_spriteTop = destY; _vm->_draw->_spriteTop = destY;
_vm->_draw->_spriteRight = right - left + 1; _vm->_draw->_spriteRight = right - left + 1;
_vm->_draw->_spriteBottom = bottom - top + 1; _vm->_draw->_spriteBottom = bottom - top + 1;
_vm->_draw->_destSpriteX = left; _vm->_draw->_destSpriteX = left;
_vm->_draw->_destSpriteY = top; _vm->_draw->_destSpriteY = top;
_vm->_draw->_transparency = layer; _vm->_draw->_transparency = layer;
if (layer & 0x80) if (layer & 0x80)
_vm->_draw->_spriteLeft = _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - _vm->_draw->_spriteLeft = _vm->_vidPlayer->getWidth(obj.videoSlot - 1) -
(destX + _vm->_draw->_spriteRight); (destX + _vm->_draw->_spriteRight);
_vm->_vidPlayer->slotCopyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getVidMem(), _vm->_vidPlayer->slotCopyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getVidMem(),
_vm->_draw->_spriteLeft, _vm->_draw->_spriteTop, _vm->_draw->_spriteLeft, _vm->_draw->_spriteTop,
_vm->_draw->_spriteRight, _vm->_draw->_spriteBottom, _vm->_draw->_spriteRight, _vm->_draw->_spriteBottom,
_vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY, _vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY,
_vm->_draw->_backSurface->getWidth(), _vm->_draw->_backSurface->getWidth(),
(_vm->_draw->_transparency != 0) ? 0 : -1); (_vm->_draw->_transparency != 0) ? 0 : -1);
_vm->_draw->invalidateRect(_vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY, _vm->_draw->invalidateRect(_vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY,
_vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1, _vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1,
_vm->_draw->_destSpriteY + _vm->_draw->_spriteBottom - 1); _vm->_draw->_destSpriteY + _vm->_draw->_spriteBottom - 1);
} }
if (!(flags & 4)) { if (!(flags & 4)) {
_animLeft = _toRedrawLeft = left; _animLeft = _toRedrawLeft = left;
_animTop = _toRedrawTop = top; _animTop = _toRedrawTop = top;
_animRight = _toRedrawRight = right; _animRight = _toRedrawRight = right;
_animBottom = _toRedrawBottom = bottom; _animBottom = _toRedrawBottom = bottom;
} }
@ -758,13 +753,13 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
return; return;
_vm->_game->capturePush(_toRedrawLeft, _toRedrawTop, _vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
_toRedrawRight - _toRedrawLeft + 1, _toRedrawRight - _toRedrawLeft + 1,
_toRedrawBottom - _toRedrawTop + 1); _toRedrawBottom - _toRedrawTop + 1);
*_pCaptureCounter = *_pCaptureCounter + 1; *_pCaptureCounter = *_pCaptureCounter + 1;
} }
pictPtr = _animations[animation].pieces; pictPtr = _animations[animation].pieces;
framePtr = layerPtr->frames; framePtr = layerPtr->frames;
for (i = 0; i < frame; i++, framePtr++) for (i = 0; i < frame; i++, framePtr++)
@ -772,9 +767,9 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
framePtr++; framePtr++;
if (flags & 4) { if (flags & 4) {
_toRedrawLeft = MAX(_toRedrawLeft, _vm->_mult->_animLeft); _toRedrawLeft = MAX(_toRedrawLeft, _vm->_mult->_animLeft);
_toRedrawTop = MAX(_toRedrawTop, _vm->_mult->_animTop); _toRedrawTop = MAX(_toRedrawTop, _vm->_mult->_animTop);
_toRedrawRight = MIN(_toRedrawRight, _toRedrawRight = MIN(_toRedrawRight,
(int16)(_vm->_mult->_animLeft + _vm->_mult->_animWidth - 1)); (int16)(_vm->_mult->_animLeft + _vm->_mult->_animWidth - 1));
_toRedrawBottom = MIN(_toRedrawBottom, _toRedrawBottom = MIN(_toRedrawBottom,
(int16)(_vm->_mult->_animTop + _vm->_mult->_animHeight - 1)); (int16)(_vm->_mult->_animTop + _vm->_mult->_animHeight - 1));
@ -845,7 +840,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
(_vm->_mult->_animLeft + _vm->_mult->_animWidth) + 1; (_vm->_mult->_animLeft + _vm->_mult->_animWidth) + 1;
if (destY < _vm->_mult->_animTop) { if (destY < _vm->_mult->_animTop) {
top += _vm->_mult->_animTop - destY; top += _vm->_mult->_animTop - destY;
destY = _vm->_mult->_animTop; destY = _vm->_mult->_animTop;
} }
@ -864,7 +859,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
right -= destX + right - left - _toRedrawRight; right -= destX + right - left - _toRedrawRight;
if (destY < _toRedrawTop) { if (destY < _toRedrawTop) {
top += _toRedrawTop - destY; top += _toRedrawTop - destY;
destY = _toRedrawTop; destY = _toRedrawTop;
} }
@ -878,33 +873,33 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
if (doDraw) { if (doDraw) {
_vm->_draw->_sourceSurface = _vm->_draw->_sourceSurface =
_animPictToSprite[animation * 7 + pictIndex]; _animPictToSprite[animation * 7 + pictIndex];
_vm->_draw->_destSurface = 21; _vm->_draw->_destSurface = 21;
_vm->_draw->_spriteLeft = left; _vm->_draw->_spriteLeft = left;
_vm->_draw->_spriteTop = top; _vm->_draw->_spriteTop = top;
_vm->_draw->_spriteRight = right - left + 1; _vm->_draw->_spriteRight = right - left + 1;
_vm->_draw->_spriteBottom = bottom - top + 1; _vm->_draw->_spriteBottom = bottom - top + 1;
_vm->_draw->_destSpriteX = destX; _vm->_draw->_destSpriteX = destX;
_vm->_draw->_destSpriteY = destY; _vm->_draw->_destSpriteY = destY;
_vm->_draw->_transparency = transp; _vm->_draw->_transparency = transp;
_vm->_draw->spriteOperation(DRAW_BLITSURF); _vm->_draw->spriteOperation(DRAW_BLITSURF);
} }
if (!(flags & 4)) { if (!(flags & 4)) {
if (_toRedrawLeft == -12345) { if (_toRedrawLeft == -12345) {
_toRedrawLeft = destX; _toRedrawLeft = destX;
_animLeft = destX; _animLeft = destX;
_toRedrawTop = destY; _toRedrawTop = destY;
_animTop = destY; _animTop = destY;
_toRedrawRight = destX + right - left; _toRedrawRight = destX + right - left;
_animRight = destX + right - left; _animRight = destX + right - left;
_toRedrawBottom = destY + bottom - top; _toRedrawBottom = destY + bottom - top;
_animBottom = destY + bottom - top; _animBottom = destY + bottom - top;
} else { } else {
_toRedrawLeft = MIN(_toRedrawLeft, destX); _toRedrawLeft = MIN(_toRedrawLeft, destX);
_toRedrawTop = MIN(_toRedrawTop, destY); _toRedrawTop = MIN(_toRedrawTop, destY);
_toRedrawRight = _toRedrawRight =
MAX(_toRedrawRight, (int16)(destX + right - left)); MAX(_toRedrawRight, (int16)(destX + right - left));
_toRedrawBottom = _toRedrawBottom =
MAX(_toRedrawBottom, (int16)(destY + bottom - top)); MAX(_toRedrawBottom, (int16)(destY + bottom - top));
} }
@ -953,41 +948,21 @@ Scenery::AnimLayer *Scenery::getAnimLayer(uint16 index, uint16 layer) {
} }
void Scenery::loadPieces(int16 pictDescId, PieceDesc *&pieceDesc, uint32 &piecesCount) { void Scenery::loadPieces(int16 pictDescId, PieceDesc *&pieceDesc, uint32 &piecesCount) {
byte *data; Resource *resource = _vm->_game->_resources->getResource(pictDescId);
uint32 size; if (!resource) {
bool fromExt = false; warning("Scenery::loadPieces(): Can't load %d", pictDescId);
return;
if (pictDescId >= 30000) {
fromExt = true;
uint32 eSize;
data = _vm->_game->loadExtData(pictDescId, 0, 0, &eSize);
size = eSize;
} else {
int16 tSize;
data = _vm->_game->loadTotResource(pictDescId, &tSize);
size = tSize;
} }
if (!data) piecesCount = resource->getSize() / 8;
error("Scenery::loadPieces(): Can't load pictDescId %d", pictDescId);
piecesCount = size / 8;
pieceDesc = new PieceDesc[piecesCount]; pieceDesc = new PieceDesc[piecesCount];
Common::MemoryReadStream pieceData(data, size);
for (uint32 i = 0; i < piecesCount; i++) { for (uint32 i = 0; i < piecesCount; i++) {
pieceDesc[i].left = (int16) pieceData.readUint16LE(); pieceDesc[i].left = resource->stream()->readSint16LE();
pieceDesc[i].right = (int16) pieceData.readUint16LE(); pieceDesc[i].right = resource->stream()->readSint16LE();
pieceDesc[i].top = (int16) pieceData.readUint16LE(); pieceDesc[i].top = resource->stream()->readSint16LE();
pieceDesc[i].bottom = (int16) pieceData.readUint16LE(); pieceDesc[i].bottom = resource->stream()->readSint16LE();
} }
if (fromExt)
delete[] data;
} }
} // End of namespace Gob } // End of namespace Gob

View File

@ -353,7 +353,10 @@ bool Script::loadTOT(const Common::String &fileName) {
if (!stream) if (!stream)
return false; return false;
_totSize = stream->size(); if (!totFile.getProperties(_totProperties))
return false;
_totSize = _totProperties.scriptEnd;
if (_totSize <= 0) if (_totSize <= 0)
return false; return false;
@ -361,9 +364,6 @@ bool Script::loadTOT(const Common::String &fileName) {
if (stream->read(_totData, _totSize) != _totSize) if (stream->read(_totData, _totSize) != _totSize)
return false; return false;
if (!totFile.getProperties(_totProperties))
return false;
return true; return true;
} }

View File

@ -127,7 +127,7 @@ bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName,
return false; return false;
size = _vm->_dataIO->getDataSize(fileName); size = _vm->_dataIO->getDataSize(fileName);
return sndDesc->load(type, SOUND_FILE, data, size); return sndDesc->load(type, data, size);
} }
void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdlib, int index) { void Sound::sampleFree(SoundDesc *sndDesc, bool noteAdlib, int index) {

View File

@ -29,15 +29,17 @@
#include "sound/wave.h" #include "sound/wave.h"
#include "gob/sound/sounddesc.h" #include "gob/sound/sounddesc.h"
#include "gob/resources.h"
namespace Gob { namespace Gob {
SoundDesc::SoundDesc() { SoundDesc::SoundDesc() {
_resource = 0;
_data = _dataPtr = 0; _data = _dataPtr = 0;
_size = 0; _size = 0;
_type = SOUND_SND; _type = SOUND_SND;
_source = SOUND_FILE;
_repCount = 0; _repCount = 0;
_frequency = 0; _frequency = 0;
@ -50,23 +52,31 @@ SoundDesc::~SoundDesc() {
free(); free();
} }
void SoundDesc::set(SoundType type, SoundSource src, void SoundDesc::set(SoundType type, byte *data, uint32 dSize) {
byte *data, uint32 dSize) {
free(); free();
_type = type; _type = type;
_source = src;
_data = _dataPtr = data; _data = _dataPtr = data;
_size = dSize; _size = dSize;
} }
bool SoundDesc::load(SoundType type, SoundSource src, void SoundDesc::set(SoundType type, Resource *resource) {
byte *data, uint32 dSize) { byte *data = 0;
uint32 dSize = 0;
if (resource && (resource->getSize() > 0)) {
data = resource->getData();
dSize = resource->getSize();
}
set(type, data, dSize);
_resource = resource;
}
bool SoundDesc::load(SoundType type, byte *data, uint32 dSize) {
free(); free();
_source = src;
switch (type) { switch (type) {
case SOUND_ADL: case SOUND_ADL:
return loadADL(data, dSize); return loadADL(data, dSize);
@ -79,9 +89,21 @@ bool SoundDesc::load(SoundType type, SoundSource src,
return false; return false;
} }
bool SoundDesc::load(SoundType type, Resource *resource) {
if (!resource || (resource->getSize() <= 0))
return false;
if (!load(type, resource->getData(), resource->getSize()))
return false;
_resource = resource;
return true;
}
void SoundDesc::free() { void SoundDesc::free() {
if (_source != SOUND_TOT) delete _resource;
delete[] _data;
_resource = 0;
_data = _dataPtr = 0; _data = _dataPtr = 0;
_id = 0; _id = 0;
} }

View File

@ -30,18 +30,14 @@
namespace Gob { namespace Gob {
class Resource;
enum SoundType { enum SoundType {
SOUND_SND, SOUND_SND,
SOUND_WAV, SOUND_WAV,
SOUND_ADL SOUND_ADL
}; };
enum SoundSource {
SOUND_FILE,
SOUND_TOT,
SOUND_EXT
};
class SoundDesc { class SoundDesc {
public: public:
int16 _repCount; int16 _repCount;
@ -58,8 +54,11 @@ public:
bool isId(int16 id) const { return _dataPtr && (_id == id); } bool isId(int16 id) const { return _dataPtr && (_id == id); }
void set(SoundType type, SoundSource src, byte *data, uint32 dSize); void set(SoundType type, byte *data, uint32 dSize);
bool load(SoundType type, SoundSource src, byte *data, uint32 dSize); void set(SoundType type, Resource *resource);
bool load(SoundType type, byte *data, uint32 dSize);
bool load(SoundType type, Resource *resource);
void free(); void free();
void convToSigned(); void convToSigned();
@ -71,12 +70,12 @@ public:
~SoundDesc(); ~SoundDesc();
private: private:
Resource *_resource;
byte *_data; byte *_data;
byte *_dataPtr; byte *_dataPtr;
uint32 _size; uint32 _size;
SoundType _type; SoundType _type;
SoundSource _source;
bool loadSND(byte *data, uint32 dSize); bool loadSND(byte *data, uint32 dSize);
bool loadWAV(byte *data, uint32 dSize); bool loadWAV(byte *data, uint32 dSize);