- Fixed the Adlib data ugliness

- Worked around the caching of raw sprite video memory to a file

svn-id: r25244
This commit is contained in:
Sven Hesse 2007-01-28 13:19:17 +00:00
parent aae330b4c1
commit b13e7ce8ec
7 changed files with 164 additions and 185 deletions

View File

@ -354,10 +354,13 @@ void Game::freeSoundSlot(int16 slot) {
if (_soundADL[slot]) {
if (_vm->_adlib && (_vm->_adlib->getIndex() == slot))
_vm->_adlib->stopPlay();
if (_soundFromExt[slot] == 1) {
delete[] ((char *) _soundSamples[slot]);
delete[] _soundSamples[slot]->data;
_soundFromExt[slot] = 0;
}
delete _soundSamples;
} else {
char* data = _soundSamples[slot]->data;

View File

@ -151,6 +151,9 @@ Global::Global(GobEngine *vm) : _vm(vm) {
for (i = 0; i < 128; i++)
_pressedKeys[i] = 0;
_savedBack = 0;
_savedBackSize = -1;
}
} // End of namespace Gob

View File

@ -163,6 +163,13 @@ public:
int16 _inter_mouseX;
int16 _inter_mouseY;
// While using the notepad or changing the font, the original executable
// temporarily dumps Draw::_backSurface to a file. Since that's not really
// a nice thing to do, we work around it.
Video::SurfaceDesc *_savedBack;
Video::Color _savedPal[256];
int32 _savedBackSize;
inline void clearVars(uint32 count)
{
uint32 i;

View File

@ -284,7 +284,9 @@ int32 GobEngine::getSaveSize(enum SaveFiles sFile) {
}
#endif // GOB_ORIGSAVES
if ((in = _saveFileMan->openForLoading(_saveFiles[(int) sFile]))) {
if (sFile == SAVE_SAV)
size = _global->_savedBack == 0 ? -1 : _global->_savedBackSize;
else if ((in = _saveFileMan->openForLoading(_saveFiles[(int) sFile]))) {
size = getSaveSize(*in);
delete in;
}
@ -302,70 +304,92 @@ const char *GobEngine::getSaveSlotFile(int slot) {
}
void GobEngine::saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
int32 retSize;
int16 index;
int16 top;
bool writePal;
bool needEnforceEndian;
char *sName;
char *buf;
char *oBuf;
int32 retSize;
int32 iSize;
int32 oSize;
int32 oOff;
Video::SurfaceDesc *destDesc;
Video::SurfaceDesc *srcDesc;
Common::InSaveFile *in;
Common::OutSaveFile *out;
retSize = 0;
index = 0;
oBuf = 0;
in = 0;
writePal = false;
sName = _saveFiles[(int) sFile];
needEnforceEndian = false;
WRITE_VAR(1, 1);
if (size < 0) {
if (sFile == SAVE_SAV) {
_global->_savedBackSize = -1;
if (size >= 0) {
warning("Invalid attempt at saving a sprite");
return;
}
if (size < -1000) {
writePal = true;
size += 1000;
writePal = true;
memcpy((char *) _global->_savedPal, (char *) _global->_pPaletteDesc->vgaPal, 768);
}
index = -size - 1;
assert((index >= 0) && (index < 50)); // Just to be sure...
buf = (char *) _draw->_spritesArray[index]->vidPtr;
size = _draw->getSpriteRectSize(index);
if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else {
int32 varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
if ((index < 0) || (index >= 50)) {
warning("Invalid attempt at saving a sprite");
return;
}
srcDesc = _draw->_spritesArray[index];
if (size == 0) {
dataVar = 0;
size = varSize;
}
buf = _global->_inter_variables + dataVar;
#ifndef GOB_ORIGSAVES
if (sFile == SAVE_CAT) {
if(saveGame((offset - 600) / varSize, dataVar, size, offset))
WRITE_VAR(1, 0);
return;
} else if (offset != 0) {
warning("Can't write file \"%s\": Can't correctly enfore endianness with offset", sName);
return;
}
needEnforceEndian = true;
#endif // GOB_ORIGSAVES
if (_global->_savedBack)
_video->freeSurfDesc(_global->_savedBack);
_global->_savedBack =
_video->initSurfDesc(_vm->_global->_videoMode, srcDesc->width, srcDesc->height, 0);
_vm->_video->drawSprite(srcDesc, _global->_savedBack, 0, 0,
srcDesc->width - 1, srcDesc->height - 1, 0, 0, 0);
_global->_savedBackSize = _draw->getSpriteRectSize(index);
if (writePal)
_global->_savedBackSize += 768;
WRITE_VAR(1, 0);
return;
}
if (size < 0) {
warning("Invalid saving procedure");
return;
}
int32 varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
if (size == 0) {
dataVar = 0;
size = varSize;
}
buf = _global->_inter_variables + dataVar;
#ifndef GOB_ORIGSAVES
if (sFile == SAVE_CAT) {
if(saveGame((offset - 600) / varSize, dataVar, size, offset))
WRITE_VAR(1, 0);
return;
} else if (offset != 0) {
warning("Can't write file \"%s\": Can't correctly enfore endianness with offset", sName);
return;
}
#endif // GOB_ORIGSAVES
if ((in = _saveFileMan->openForLoading(sName)))
iSize = getSaveSize(*in);
else
iSize = 0;
oOff = offset < 0 ? MAX((int32) 0, iSize - (-offset - 1)) : offset;
oSize = MAX(iSize, oOff + ABS(size));
oSize = MAX(iSize, oOff + size);
oBuf = new char[oSize];
memset(oBuf, 0, oSize);
@ -380,33 +404,11 @@ void GobEngine::saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in
return;
}
if (writePal) {
memcpy(oBuf + oOff, (char *) _global->_pPaletteDesc->vgaPal, 768);
oOff += 768;
}
if (!needEnforceEndian) {
if (size < 0) {
srcDesc = _draw->_spritesArray[index];
destDesc = _video->initSurfDesc(_global->_videoMode, srcDesc->width, 25, 0);
for (top = 0, retSize = 0; top < srcDesc->height; top += 25) {
int16 height = MIN(25, srcDesc->height - top);
_video->drawSprite(srcDesc, destDesc, 0, top, srcDesc->width - 1,
top + height - 1, 0, 0, 0);
memcpy(oBuf + oOff, (char *) destDesc->vidPtr, srcDesc->width * 25);
oOff += srcDesc->width * 25;
}
_video->freeSurfDesc(destDesc);
} else
memcpy(oBuf + oOff, buf, size);
out->write(oBuf, oSize);
} else
writeDataEndian(*out, buf, _global->_inter_variablesSizes + dataVar, size);
retSize = writeDataEndian(*out, buf, _global->_inter_variablesSizes + dataVar, size);
out->flush();
if (out->ioFailed())
if (out->ioFailed() || (retSize != size))
warning("Can't write file \"%s\"", sName);
else {
debugC(1, kDebugFileIO, "Saved file \"%s\" (%d, %d bytes at %d)",
@ -494,57 +496,77 @@ void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in
int32 sSize;
int32 retSize;
int16 index;
int16 y;
char *buf;
char *sName;
bool readPal;
bool needEnforceEndian;
Video::SurfaceDesc *destDesc;
Video::SurfaceDesc *srcDesc;
Common::InSaveFile *in;
index = 0;
readPal = false;
sName = _saveFiles[(int) sFile];
needEnforceEndian = false;
WRITE_VAR(1, 1);
if (size < 0) {
if (sFile == SAVE_SAV) {
if (size >= 0) {
warning("Invalid attempt at loading a sprite");
return;
}
if (size < -1000) {
readPal = true;
size += 1000;
readPal = true;
memcpy((char *) _global->_pPaletteDesc->vgaPal, (char *) _global->_savedPal, 768);
}
index = -size - 1;
assert((index >= 0) && (index < 50)); // Just to be sure...
buf = (char *) _draw->_spritesArray[index]->vidPtr;
size = _draw->getSpriteRectSize(index);
if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else {
int32 varSize;
varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
if (size == 0) {
dataVar = 0;
size = varSize;
}
buf = _global->_inter_variables + dataVar;
#ifndef GOB_ORIGSAVES
if (sFile == SAVE_CAT) {
if(loadGame((offset - 600) / varSize, dataVar, size, offset))
WRITE_VAR(1, 0);
return;
} else if (offset != 0) {
warning("Can't read file \"%s\": Can't correctly enfore endianness with offset", sName);
if ((index < 0) || (index >= 50)) {
warning("Invalid attempt at loading a sprite");
return;
}
needEnforceEndian = true;
#endif // GOB_ORIGSAVES
destDesc = _draw->_spritesArray[index];
if ((destDesc->width != _global->_savedBack->width) ||
(destDesc->height != _global->_savedBack->height)) {
warning("Resolution doesn't match while loading a sprite");
return;
}
_vm->_video->drawSprite(_global->_savedBack, destDesc, 0, 0,
destDesc->width - 1, destDesc->height - 1, 0, 0, 0);
if (index == 21) {
_video->drawSprite(_draw->_backSurface, _draw->_frontSurface, 0, 0,
_draw->_frontSurface->width - 1, _draw->_frontSurface->height - 1, 0, 0, 0);
_video->waitRetrace(_global->_videoMode);
}
WRITE_VAR(1, 0);
return;
}
if (size < 0) {
warning("Invalid loading procedure");
return;
}
int32 varSize;
varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
if (size == 0) {
dataVar = 0;
size = varSize;
}
buf = _global->_inter_variables + dataVar;
#ifndef GOB_ORIGSAVES
if (sFile == SAVE_CAT) {
if(loadGame((offset - 600) / varSize, dataVar, size, offset))
WRITE_VAR(1, 0);
return;
} else if (offset != 0) {
warning("Can't read file \"%s\": Can't correctly enfore endianness with offset", sName);
return;
}
#endif // GOB_ORIGSAVES
if (_global->_inter_resStr[0] == 0) {
if (readPal)
size += 768;
WRITE_VAR(1, size);
return;
}
@ -564,30 +586,7 @@ void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, in
else
in->seek(offset, 0);
if (readPal) {
retSize = in->read((char *) _global->_pPaletteDesc->vgaPal, 768);
_draw->_applyPal = 1;
}
if (!needEnforceEndian) {
if (size < 0) {
destDesc = _draw->_spritesArray[index];
srcDesc = _video->initSurfDesc(_global->_videoMode, destDesc->width, 25, 0);
for (y = 0, retSize = 0; y < destDesc->height; y += 25) {
int16 height = MIN(25, destDesc->height - y);
retSize += in->read((char *) srcDesc->vidPtr, destDesc->width * 25);
_video->drawSprite(srcDesc, destDesc, 0, 0, destDesc->width - 1, height - 1, 0, y, 0);
}
_video->freeSurfDesc(srcDesc);
} else
retSize = in->read(buf, size);
if (index == 21) {
_video->drawSprite(_draw->_backSurface, _draw->_frontSurface, 0, 0,
_draw->_frontSurface->width - 1, _draw->_frontSurface->height - 1, 0, 0, 0);
_video->waitRetrace(_global->_videoMode);
}
} else
retSize = readDataEndian(*in, buf, _global->_inter_variablesSizes + dataVar, size);
retSize = readDataEndian(*in, buf, _global->_inter_variablesSizes + dataVar, size);
if (retSize == size)
WRITE_VAR(1, 0);

View File

@ -110,8 +110,8 @@ enum {
enum SaveFiles {
SAVE_CAT = 0, // Saves
SAVE_SAV, // Draw::_backSurface (as a temporary buffer when using the notepad
// and changing the font. TODO: That probably should be worked around
SAVE_SAV, // Holds a sprite, normally a cache for Draw::_backBuffer
// (see Global::_savedBack)
SAVE_BLO // Notes
};

View File

@ -933,8 +933,8 @@ void Inter_v2::o2_stub0x85(void) {
}
int16 Inter_v2::loadSound(int16 search) {
int16 id; // si
int16 slot; // di
int16 id;
int16 slot;
uint32 i;
bool isADL;
char sndfile[14];
@ -969,7 +969,7 @@ int16 Inter_v2::loadSound(int16 search) {
_vm->_game->_soundIds[slot] = id;
_vm->_game->_soundADL[slot] = isADL;
if (id == -1) { // loc_969D
if (id == -1) {
strcpy(sndfile, _vm->_global->_inter_execPtr);
_vm->_global->_inter_execPtr += 9;
if (!isADL) {
@ -977,12 +977,16 @@ int16 Inter_v2::loadSound(int16 search) {
_vm->_game->_soundSamples[slot] = _vm->_game->loadSND(sndfile, 3);
} else {
strcat(sndfile, ".ADL");
// TODO: This is very ugly
_vm->_game->_soundSamples[slot] = (Snd::SoundDesc *) _vm->_dataio->getData(sndfile);
dataPtr = _vm->_dataio->getData(sndfile);
if (dataPtr == 0)
return slot;
_vm->_game->_soundSamples[slot] = new Snd::SoundDesc;
_vm->_game->_soundSamples[slot]->data = dataPtr;
}
_vm->_game->_soundTypes[slot] = 2;
} else { // loc_9735
if (id >= 30000) { // loc_973E
} else {
if (id >= 30000) {
if (!isADL && (_vm->_game->_totFileData[0x29] >= 51)) { // loc_9763
if (_vm->_inter->_terminate != 0)
return slot;
@ -993,43 +997,41 @@ int16 Inter_v2::loadSound(int16 search) {
return slot;
}
soundDesc->data = extData + 6;
soundDesc->frequency = (extData[4] << 8) + extData[5];
soundDesc->frequency = MAX((extData[4] << 8) + extData[5], 4700);
soundDesc->size = (extData[1] << 16) + (extData[2] << 8) + extData[3];
soundDesc->flag = 0;
if (soundDesc->frequency < 4700)
soundDesc->frequency = 4700;
soundDesc->frequency = -soundDesc->frequency;
for (i = 0, dataPtr = soundDesc->data; i < soundDesc->size; i++, dataPtr++)
*dataPtr ^= 0x80;
_vm->_game->_soundFromExt[slot] = 1;
_vm->_game->_soundTypes[slot] = 4;
_vm->_game->_soundSamples[slot] = soundDesc;
_vm->_game->_soundFromExt[slot] = 1;
} else { // loc_99BC
} else {
uint32 dataSize;
extData = _vm->_game->loadExtData(id, 0, 0, &dataSize);
if (extData == 0)
return slot;
_vm->_game->_soundTypes[slot] = 1;
if (!isADL)
_vm->_game->loadSound(slot, extData, dataSize);
else
// TODO: This is very ugly
_vm->_game->_soundSamples[slot] = (Snd::SoundDesc *) extData;
_vm->_game->_soundFromExt[slot] = 1;
_vm->_game->_soundTypes[slot] = 1;
if (isADL) {
_vm->_game->_soundSamples[slot] = new Snd::SoundDesc;
_vm->_game->_soundSamples[slot]->data = extData;
} else
_vm->_game->loadSound(slot, extData, dataSize);
}
} else { // loc_9A13
} else {
int16 dataSize;
extData = _vm->_game->loadTotResource(id, &dataSize);
if (!isADL)
if (isADL) {
_vm->_game->_soundSamples[slot] = new Snd::SoundDesc;
_vm->_game->_soundSamples[slot]->data = extData;
} else
_vm->_game->loadSound(slot, extData, dataSize);
else
// TODO: This is very ugly
_vm->_game->_soundSamples[slot] = (Snd::SoundDesc *) extData;
}
}
// loc_9A4E
if (isADL)
_vm->_game->_soundTypes[slot] |= 8;
@ -1362,18 +1364,11 @@ bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
int32 retSize;
int32 size;
int32 offset;
int16 dataVar; // si
int16 dataVar;
int16 handle;
int16 index;
int16 y;
char *buf;
char tmp[4];
bool readPal;
Video::SurfaceDesc *destDesc;
Video::SurfaceDesc *srcDesc;
index = 0;
readPal = false;
evalExpr(0);
dataVar = _vm->_parse->parseVarIndex();
size = _vm->_parse->parseValExpr();
@ -1398,28 +1393,16 @@ bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
}
if (size < 0) {
if (size < -1000) {
readPal = true;
size += 1000;
}
index = -size - 1;
assert((index >= 0) && (index < 50)); // Just to be sure...
buf = (char *) _vm->_draw->_spritesArray[index]->vidPtr;
size = _vm->_draw->getSpriteRectSize(index);
if ((_vm->_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else {
if (size == 0) {
dataVar = 0;
size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
}
buf = _vm->_global->_inter_variables + dataVar;
memset(_vm->_global->_inter_variablesSizes + dataVar, 0, size);
warning("Attempted to read a raw sprite from file \"%s\"", _vm->_global->_inter_resStr);
return false ;
} else if (size == 0) {
dataVar = 0;
size = READ_LE_UINT32(_vm->_game->_totFileData + 0x2C) * 4;
}
buf = _vm->_global->_inter_variables + dataVar;
memset(_vm->_global->_inter_variablesSizes + dataVar, 0, size);
if (_vm->_global->_inter_resStr[0] == 0) {
if (readPal)
size += 768;
WRITE_VAR(1, size);
return false;
}
@ -1436,21 +1419,7 @@ bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
else
_vm->_dataio->seekData(handle, offset, 0);
if (readPal) {
retSize = _vm->_dataio->readData(handle, (char *) _vm->_global->_pPaletteDesc->vgaPal, 768);
_vm->_draw->_applyPal = 1;
}
if (size < 0) {
destDesc = _vm->_draw->_spritesArray[index];
srcDesc = _vm->_video->initSurfDesc(_vm->_global->_videoMode, destDesc->width, 25, 0);
for (y = 0, retSize = 0; y < destDesc->height; y += 25) {
int16 height = MIN(25, destDesc->height - y);
retSize += _vm->_dataio->readData(handle, (char *) srcDesc->vidPtr, destDesc->width * 25);
_vm->_video->drawSprite(srcDesc, destDesc, 0, 0, destDesc->width - 1, height - 1, 0, y, 0);
}
_vm->_video->freeSurfDesc(srcDesc);
} else if (((dataVar >> 2) == 59) && (size == 4)) {
if (((dataVar >> 2) == 59) && (size == 4)) {
retSize = _vm->_dataio->readData(handle, tmp, 4);
WRITE_VAR(59, READ_LE_UINT32(tmp));
} else
@ -1603,7 +1572,7 @@ bool Inter_v2::o2_playSound(char &cmdCount, int16 &counter, int16 &retFlag) {
// loc_E2F3
if ((_vm->_game->_soundTypes[index] & 8)) {
if (_vm->_adlib) {
_vm->_adlib->load((byte *) _vm->_game->_soundSamples[index], index);
_vm->_adlib->load((byte *) _vm->_game->_soundSamples[index]->data, index);
_vm->_adlib->setRepeating(repCount - 1);
_vm->_adlib->startPlay();
}

View File

@ -114,7 +114,6 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) {
int16 brackPos;
static int16 flag = 0;
int16 oldflag;
int16 foo;
oldflag = flag;
if (flag == 0) {
@ -189,8 +188,7 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) {
break;
case 24:
foo = _vm->_inter->load16();
*valPtr = READ_VARO_UINT16(foo * 4);
*valPtr = READ_VARO_UINT16(_vm->_inter->load16() * 4);
break;
case 25:
@ -441,7 +439,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) {
case 21:
*operPtr = 20;
*valPtr = *((int8 *) _vm->_global->_inter_execPtr++);
*valPtr = (int8) (*_vm->_global->_inter_execPtr++);
break;
case 22: