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

View File

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

View File

@ -32,6 +32,7 @@
#include "gob/util.h"
#include "gob/dataio.h"
#include "gob/script.h"
#include "gob/resources.h"
#include "gob/inter.h"
#include "gob/draw.h"
#include "gob/mult.h"
@ -41,19 +42,11 @@
namespace Gob {
Game::Game(GobEngine *vm) : _vm(vm) {
_extTable = 0;
_totResourceTable = 0;
_imFileData = 0;
_extHandle = 0;
_lomHandle = -1;
_collisionAreas = 0;
_shouldPushColls = 0;
_captureCount = 0;
_foundTotLoc = false;
_totTextData = 0;
_collStackSize = 0;
for (int i = 0; i < 5; i++) {
@ -62,7 +55,6 @@ Game::Game(GobEngine *vm) : _vm(vm) {
}
_curTotFile[0] = 0;
_curExtFile[0] = 0;
_totToLoad[0] = 0;
_startTimeKey = 0;
@ -84,7 +76,6 @@ Game::Game(GobEngine *vm) : _vm(vm) {
_noCd = false;
_tempStr[0] = 0;
_curImaFile[0] = 0;
_collStr[0] = 0;
_backupedCount = 0;
@ -93,131 +84,19 @@ Game::Game(GobEngine *vm) : _vm(vm) {
for (int i = 0; i < 5; i++) {
_cursorHotspotXArray[i] = 0;
_cursorHotspotYArray[i] = 0;
_totTextDataArray[i] = 0;
_totResourceTableArray[i] = 0;
_extTableArray[i] = 0;
_extHandleArray[i] = 0;
_imFileDataArray[i] = 0;
_variablesArray[i] = 0;
_curTotFileArray[i][0] = 0;
_scriptArray[i] = 0;
_resourcesArray[i] = 0;
}
_script = new Script(_vm);
_resources = new Resources(_vm);
}
Game::~Game() {
if (_totTextData) {
if (_totTextData->items)
delete[] _totTextData->items;
delete _totTextData;
}
if (_totResourceTable) {
delete[] _totResourceTable->items;
delete _totResourceTable;
}
delete _script;
}
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;
delete _resources;
}
void Game::freeCollision(int16 id) {
@ -282,39 +161,9 @@ void Game::capturePop(char doDraw) {
_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) {
if (slot == -1)
slot = _script->readValExpr();
slot = _vm->_game->_script->readValExpr();
_vm->_sound->sampleFree(_vm->_sound->sampleGetBySlot(slot));
}
@ -417,53 +266,6 @@ int16 Game::adjustKey(int16 key) {
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) {
_collisionAreas = new Collision[250];
memset(_collisionAreas, 0, 250 * sizeof(Collision));
@ -489,11 +291,7 @@ void Game::totSub(int8 flags, const char *newTotFile) {
_cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
_cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
_scriptArray[_backupedCount] = _script;
_totTextDataArray[_backupedCount] = _totTextData;
_totResourceTableArray[_backupedCount] = _totResourceTable;
_extTableArray[_backupedCount] = _extTable;
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_resourcesArray[_backupedCount] = _resources;
_variablesArray[_backupedCount] = _vm->_inter->_variables;
strcpy(_curTotFileArray[_backupedCount], _curTotFile);
@ -501,9 +299,8 @@ void Game::totSub(int8 flags, const char *newTotFile) {
_backupedCount++;
_curBackupPos = _backupedCount;
_totTextData = 0;
_script = new Script(_vm);
_totResourceTable = 0;
_resources = new Resources(_vm);
if (flags & 1)
_vm->_inter->_variables = 0;
@ -537,17 +334,10 @@ void Game::totSub(int8 flags, const char *newTotFile) {
_vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_backupedCount];
_vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount];
_totTextData = _totTextDataArray[_backupedCount];
_script = _scriptArray[_backupedCount];
_totResourceTable = _totResourceTableArray[_backupedCount];
_extTable = _extTableArray[_backupedCount];
_extHandle = _extHandleArray[_backupedCount];
_imFileData = _imFileDataArray[_backupedCount];
_resources = _resourcesArray[_backupedCount];
_vm->_inter->_variables = _variablesArray[_backupedCount];
strcpy(_curTotFile, _curTotFileArray[_backupedCount]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile) - 4] = '\0';
strcat(_curExtFile, ".EXT");
}
void Game::switchTotSub(int16 index, int16 skipPlay) {
@ -569,12 +359,8 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
if (_curBackupPos == _backupedCount) {
_cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
_cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
_totTextDataArray[_backupedCount] = _totTextData;
_scriptArray[_backupedCount] = _script;
_totResourceTableArray[_backupedCount] = _totResourceTable;
_extTableArray[_backupedCount] = _extTable;
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_resourcesArray[_backupedCount] = _resources;
_variablesArray[_backupedCount] = _vm->_inter->_variables;
strcpy(_curTotFileArray[_backupedCount], _curTotFile);
_backupedCount++;
@ -585,17 +371,10 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos];
_vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos];
_totTextData = _totTextDataArray[_curBackupPos];
_script = _scriptArray[_curBackupPos];
_totResourceTable = _totResourceTableArray[_curBackupPos];
_imFileData = _imFileDataArray[_curBackupPos];
_extTable = _extTableArray[_curBackupPos];
_extHandle = _extHandleArray[_curBackupPos];
_resources = _resourcesArray[_curBackupPos];
_vm->_inter->_variables = _variablesArray[_curBackupPos];
strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile) - 4] = '\0';
strcat(_curExtFile, ".EXT");
if (_vm->_inter->_terminate != 0)
return;
@ -612,109 +391,10 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_backupedCount = backupedCount;
_vm->_draw->_cursorHotspotXVar = _cursorHotspotXArray[_curBackupPos];
_vm->_draw->_cursorHotspotYVar = _cursorHotspotYArray[_curBackupPos];
_totTextData = _totTextDataArray[_curBackupPos];
_script = _scriptArray[_curBackupPos];
_totResourceTable = _totResourceTableArray[_curBackupPos];
_extTable = _extTableArray[_curBackupPos];
_extHandle = _extHandleArray[_curBackupPos];
_imFileData = _imFileDataArray[_curBackupPos];
_resources = _resourcesArray[_curBackupPos];
_vm->_inter->_variables = _variablesArray[_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) {

View File

@ -31,6 +31,7 @@
namespace Gob {
class Script;
class Resources;
class Game {
public:
@ -51,19 +52,6 @@ public:
Script *script;
} 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 {
int16 fontIndex;
int16 backColor;
@ -76,19 +64,10 @@ public:
Collision *_collisionAreas;
Collision *_collStack[5];
bool _foundTotLoc;
TotTextTable *_totTextData;
Script *_script;
Resources *_resources;
char _curTotFile[14];
char _curExtFile[14];
byte *_imFileData;
int16 _extHandle;
int16 _lomHandle;
char _totToLoad[20];
int32 _startTimeKey;
@ -103,9 +82,6 @@ public:
Game(GobEngine *vm);
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 capturePop(char doDraw);
@ -145,42 +121,6 @@ public:
virtual void popCollisions(void) = 0;
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 _lastCollAreaIndex;
int16 _lastCollId;
@ -193,10 +133,6 @@ protected:
char _tempStr[256];
TotResTable *_totResourceTable;
ExtTable *_extTable;
char _curImaFile[18];
int16 _collStackSize;
int16 _collStackElemSizes[5];
@ -213,25 +149,16 @@ protected:
int8 _curBackupPos;
int16 _cursorHotspotXArray[5];
int16 _cursorHotspotYArray[5];
TotTextTable *_totTextDataArray[5];
TotResTable *_totResourceTableArray[5];
ExtTable *_extTableArray[5];
int16 _extHandleArray[5];
byte *_imFileDataArray[5];
Variables *_variablesArray[5];
char _curTotFileArray[5][14];
Script *_scriptArray[5];
Resources *_resourcesArray[5];
GobEngine *_vm;
virtual int16 adjustKey(int16 key);
byte *loadLocTexts(int32 *dataSize = 0);
void loadExtTable(void);
void loadImFile(void);
void collAreaSub(int16 index, int8 enter);
bool getLocTextFile(char *locTextFile, int language);
virtual void setCollisions(byte arg_0 = 1);
virtual void collSub(uint16 offset);

View File

@ -33,6 +33,7 @@
#include "gob/util.h"
#include "gob/dataio.h"
#include "gob/script.h"
#include "gob/resources.h"
#include "gob/draw.h"
#include "gob/inter.h"
#include "gob/mult.h"
@ -93,12 +94,6 @@ void Game_v1::playTot(int16 skipPlay) {
for (int i = 0; i < 20; i++)
freeSoundSlot(i);
_totTextData = 0;
_totResourceTable = 0;
_imFileData = 0;
_extTable = 0;
_extHandle = -1;
_totToLoad[0] = 0;
if ((_curTotFile[0] == 0) && !_script->isLoaded())
@ -109,56 +104,7 @@ void Game_v1::playTot(int16 skipPlay) {
break;
}
strcpy(_curImaFile, _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();
_resources->load(_curTotFile);
_vm->_global->_inter_animDataSize = _script->getAnimDataSize();
if (!_vm->_inter->_variables)
@ -183,30 +129,7 @@ void Game_v1::playTot(int16 skipPlay) {
_script->unload();
if (_totTextData) {
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;
_resources->unload();
for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++)
capturePop(0);

View File

@ -33,6 +33,7 @@
#include "gob/util.h"
#include "gob/dataio.h"
#include "gob/script.h"
#include "gob/resources.h"
#include "gob/draw.h"
#include "gob/goblin.h"
#include "gob/inter.h"
@ -55,7 +56,6 @@ void Game_v2::playTot(int16 skipPlay) {
int16 _captureCounter;
int16 breakFrom;
int16 nestLevel;
bool totTextLoc;
oldNestLevel = _vm->_inter->_nestLevel;
oldBreakFrom = _vm->_inter->_breakFromLevel;
@ -92,12 +92,6 @@ void Game_v2::playTot(int16 skipPlay) {
} else
_vm->_inter->initControlVars(0);
_totTextData = 0;
_totResourceTable = 0;
_imFileData = 0;
_extTable = 0;
_extHandle = -1;
_vm->_draw->_cursorHotspotXVar = -1;
_totToLoad[0] = 0;
@ -115,85 +109,7 @@ void Game_v2::playTot(int16 skipPlay) {
break;
}
strcpy(_curImaFile, _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();
_resources->load(_curTotFile);
_vm->_global->_inter_animDataSize = _script->getAnimDataSize();
if (!_vm->_inter->_variables)
@ -217,32 +133,7 @@ void Game_v2::playTot(int16 skipPlay) {
_script->unload();
if (_totTextData) {
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;
_resources->unload();
for (int i = 0; i < *_vm->_scenery->_pCaptureCounter; i++)
capturePop(0);

View File

@ -32,6 +32,7 @@
#include "gob/helper.h"
#include "gob/global.h"
#include "gob/script.h"
#include "gob/resources.h"
#include "gob/inter.h"
#include "gob/draw.h"
@ -53,12 +54,8 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
_cursorHotspotXArray[_backupedCount] = _vm->_draw->_cursorHotspotXVar;
_cursorHotspotYArray[_backupedCount] = _vm->_draw->_cursorHotspotYVar;
_totTextDataArray[_backupedCount] = _totTextData;
_scriptArray[_backupedCount] = _script;
_totResourceTableArray[_backupedCount] = _totResourceTable;
_extTableArray[_backupedCount] = _extTable;
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_resourcesArray[_backupedCount] = _resources;
_variablesArray[_backupedCount] = _vm->_inter->_variables;
strcpy(_curTotFileArray[_backupedCount], _curTotFile);
@ -67,8 +64,7 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) {
_curBackupPos = _backupedCount;
_script = new Script(_vm);
_totTextData = 0;
_totResourceTable = 0;
_resources = new Resources(_vm);
if (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->_cursorHotspotYVar = _cursorHotspotYArray[_backupedCount];
_totTextData = _totTextDataArray[_backupedCount];
_script = _scriptArray[_backupedCount];
_totResourceTable = _totResourceTableArray[_backupedCount];
_extTable = _extTableArray[_backupedCount];
_extHandle = _extHandleArray[_backupedCount];
_imFileData = _imFileDataArray[_backupedCount];
_resources = _resourcesArray[_backupedCount];
_vm->_inter->_variables = _variablesArray[_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,

View File

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

View File

@ -33,37 +33,51 @@
namespace Gob {
#define VIDMODE_CGA 0x05
#define VIDMODE_EGA 0x0D
#define VIDMODE_VGA 0x13
#define VIDMODE_HER 7
#define VIDMODE_CGA 0x05
#define VIDMODE_EGA 0x0D
#define VIDMODE_VGA 0x13
#define VIDMODE_HER 0x07
#define PROAUDIO_FLAG 0x10
#define ADLIB_FLAG 0x08
#define BLASTER_FLAG 0x04
#define INTERSOUND_FLAG 0x02
#define SPEAKER_FLAG 0x01
#define MIDI_FLAG 0x4000
#define MIDI_FLAG 0x4000
#define PROAUDIO_FLAG 0x0010
#define ADLIB_FLAG 0x0008
#define BLASTER_FLAG 0x0004
#define INTERSOUND_FLAG 0x0002
#define SPEAKER_FLAG 0x0001
#define NO 0
#define YES 1
#define UNDEF 2
#define NO 0
#define YES 1
#define UNDEF 2
#define F1_KEY 0x3B00
#define F2_KEY 0x3C00
#define F3_KEY 0x3D00
#define F4_KEY 0x3E00
#define F5_KEY 0x3F00
#define F6_KEY 0x4000
#define ESCAPE 0x001B
#define ENTER 0x000D
#define F1_KEY 0x3B00
#define F2_KEY 0x3C00
#define F3_KEY 0x3D00
#define F4_KEY 0x3E00
#define F5_KEY 0x3F00
#define F6_KEY 0x4000
#define ESCAPE 0x001B
#define ENTER 0x000D
/* Video drivers */
#define UNK_DRIVER 0
#define VGA_DRIVER 1
#define EGA_DRIVER 2
#define CGA_DRIVER 3
#define HER_DRIVER 4
#define UNK_DRIVER 0
#define VGA_DRIVER 1
#define EGA_DRIVER 2
#define CGA_DRIVER 3
#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 {
public:
@ -82,6 +96,7 @@ public:
uint16 _language;
uint16 _languageWanted;
bool _foundLanguage;
char _useMouse;
int16 _mousePresent;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -34,6 +34,7 @@
#include "gob/game.h"
#include "gob/expression.h"
#include "gob/script.h"
#include "gob/resources.h"
#include "gob/draw.h"
#include "gob/sound/sound.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())
return false;
int16 width, height;
byte *dataBuf = _vm->_game->loadTotResource(id, 0, &width, &height);
Resource *resource = _vm->_game->_resources->getResource((uint16) id);
if (!resource)
return false;
_vm->_video->fillRect(*_vm->_draw->_cursorSprites,
index * _vm->_draw->_cursorWidth, 0,
index * _vm->_draw->_cursorWidth + _vm->_draw->_cursorWidth - 1,
_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);
_vm->_draw->_cursorAnimLow[index] = 0;
delete resource;
return false;
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -127,7 +127,7 @@ bool Sound::sampleLoad(SoundDesc *sndDesc, SoundType type, const char *fileName,
return false;
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) {

View File

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

View File

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