- Properly implemented o2_getCDTrackPos()

- Each save has now its own file (.s??). They also should be endian-safe now
  (Can be disabled for testing by uncommenting #define GOB_ORIGSAVES in gob.cpp)
- General endianness-fixes

svn-id: r24794
This commit is contained in:
Sven Hesse 2006-11-27 14:19:30 +00:00
parent b2fb23a134
commit 9afb08341c
24 changed files with 633 additions and 170 deletions

View file

@ -215,6 +215,10 @@ int32 CDROM::getTrackPos(void) {
return -1;
}
const char *CDROM::getCurTrack(void) {
return _curTrack;
}
void CDROM::stopPlaying(void) {
stop();

View file

@ -35,6 +35,7 @@ public:
void playMultMusic();
void play(uint32 from, uint32 to);
int32 getTrackPos(void);
const char *getCurTrack(void);
void stopPlaying(void);
void stop(void);
void testCD(int trySubst, const char *label);

View file

@ -154,7 +154,7 @@ void Draw_v1::printText(void) {
} else if (cmd == 1) {
val = READ_LE_UINT16(ptr2 + 18) * 4;
strcpy(buf, _vm->_global->_inter_variables + val);
strcpy(buf, GET_VARO_STR(val));
} else {
val = READ_LE_UINT16(ptr2 + 18) * 4;

View file

@ -403,7 +403,7 @@ void Draw_v2::printText(void) {
sprintf(buf, "%d", VAR_OFFSET(val));
} else if (cmd == 1) {
val = READ_LE_UINT16(ptr2 + 18) * 4;
strcpy(buf, _vm->_global->_inter_variables + val);
strcpy(buf, GET_VARO_STR(val));
} else {
val = READ_LE_UINT16(ptr2 + 18) * 4;
sprintf(buf, "%d", VAR_OFFSET(val));
@ -714,7 +714,7 @@ void Draw_v2::spriteOperation(int16 operation) {
left = _destSpriteX;
if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) {
if (_fonts[_fontIndex]->extraData == 0) {
if (((signed) _textToPrint[0]) == -1) {
if (((signed int) _textToPrint[0]) == -1) {
dataBuf = _vm->_game->_totTextData->dataPtr + _textToPrint[1] + 1;
len = *dataBuf++;
for (i = 0; i < len; i++) {
@ -895,12 +895,14 @@ void Draw_v2::animateCursor(int16 cursor) {
_showCursor |= 2;
/*
if (((_backSurface->width - 9) < _vm->_global->_inter_mouseX) ||
((_backSurface->height - 4) < _vm->_global->_inter_mouseY)) {
_vm->_global->_inter_mouseX = MIN((int) _vm->_global->_inter_mouseX, _backSurface->width - 9);
_vm->_global->_inter_mouseY = MIN((int) _vm->_global->_inter_mouseY, _backSurface->height - 4);
_vm->_util->setMousePos(_vm->_global->_inter_mouseX, _vm->_global->_inter_mouseY);
}
*/
// .-- _draw_animateCursorSUB1 ---
cursorIndex = cursor;

View file

@ -472,6 +472,7 @@ void Game::totSub(int8 flags, char *newTotFile) {
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_variablesArray[_backupedCount] = _vm->_global->_inter_variables;
_variablesSizesArray[_backupedCount] = _vm->_global->_inter_variablesSizes;
strcpy(_curTotFileArray[_backupedCount], _curTotFile);
curBackupPos = _curBackupPos;
@ -481,8 +482,10 @@ void Game::totSub(int8 flags, char *newTotFile) {
_totTextData = 0;
_totFileData = 0;
_totResourceTable = 0;
if (flags & 1)
if (flags & 1) {
_vm->_global->_inter_variables = 0;
_vm->_global->_inter_variablesSizes = 0;
}
strcpy(_curTotFile, newTotFile);
strcat(_curTotFile, ".TOT");
@ -502,8 +505,10 @@ void Game::totSub(int8 flags, char *newTotFile) {
popCollisions();
if ((flags & 1) && (_vm->_global->_inter_variables != 0))
if ((flags & 1) && (_vm->_global->_inter_variables != 0)) {
delete[] _vm->_global->_inter_variables;
delete[] _vm->_global->_inter_variablesSizes;
}
_backupedCount--;
_curBackupPos = curBackupPos;
@ -517,6 +522,7 @@ void Game::totSub(int8 flags, char *newTotFile) {
_extHandle = _extHandleArray[_backupedCount];
_imFileData = _imFileDataArray[_backupedCount];
_vm->_global->_inter_variables = _variablesArray[_backupedCount];
_vm->_global->_inter_variablesSizes = _variablesSizesArray[_backupedCount];
strcpy(_curTotFile, _curTotFileArray[_backupedCount]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile)-4] = '\0';
@ -542,6 +548,7 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_extHandleArray[_backupedCount] = _extHandle;
_imFileDataArray[_backupedCount] = _imFileData;
_variablesArray[_backupedCount] = _vm->_global->_inter_variables;
_variablesSizesArray[_backupedCount] = _vm->_global->_inter_variablesSizes;
strcpy(_curTotFileArray[_backupedCount], _curTotFile);
_backupedCount++;
}
@ -558,6 +565,7 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_extTable = _extTableArray[_curBackupPos];
_extHandle = _extHandleArray[_curBackupPos];
_vm->_global->_inter_variables = _variablesArray[_curBackupPos];
_vm->_global->_inter_variablesSizes = _variablesSizesArray[_curBackupPos];
strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile)-4] = '\0';
@ -585,6 +593,7 @@ void Game::switchTotSub(int16 index, int16 skipPlay) {
_extHandle = _extHandleArray[_curBackupPos];
_imFileData = _imFileDataArray[_curBackupPos];
_vm->_global->_inter_variables = _variablesArray[_curBackupPos];
_vm->_global->_inter_variablesSizes = _variablesSizesArray[_curBackupPos];
strcpy(_curTotFile, _curTotFileArray[_curBackupPos]);
strcpy(_curExtFile, _curTotFile);
_curExtFile[strlen(_curExtFile)-4] = '\0';

View file

@ -169,6 +169,7 @@ public:
char *_imFileDataArray[5];
char *_variablesArray[5];
char _curTotFileArray[5][14];
byte *_variablesSizesArray[5];
Imd *_imdFile;
char _curImdFile[15];

View file

@ -55,9 +55,9 @@ void Game_v1::playTot(int16 skipPlay) {
int16 breakFrom;
int16 nestLevel;
int32 variablesCount;
int32 i;
char *filePtr;
char *savedIP;
int16 i;
if (skipPlay < 0)
skipPlay = 0;
@ -172,6 +172,7 @@ void Game_v1::playTot(int16 skipPlay) {
if (_vm->_global->_inter_variables == 0) {
variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c);
_vm->_global->_inter_variables = new char[variablesCount * 4];
_vm->_global->_inter_variablesSizes = new byte[variablesCount * 4];
for (i = 0; i < variablesCount; i++)
WRITE_VAR(i, 0);
}
@ -1079,20 +1080,19 @@ void Game_v1::collisionsBlock(void) {
if ((_collisionAreas[i].flags & 0x0f) > 8) {
char *ptr;
strcpy(_tempStr,
_vm->_global->_inter_variables + _collisionAreas[i].key);
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
while ((ptr = strchr(_tempStr, ' ')) != 0) {
_vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
ptr = strchr(_tempStr, ' ');
}
strcpy(_vm->_global->_inter_variables + _collisionAreas[i].key, _tempStr);
WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
}
if ((_collisionAreas[i].flags & 0x0f) >= 5 &&
(_collisionAreas[i].flags & 0x0f) <= 8) {
str = descArray[var_24].ptr;
strcpy(_tempStr, _vm->_global->_inter_variables + _collisionAreas[i].key);
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
if ((_collisionAreas[i].flags & 0x0f) < 7)
_vm->_util->prepareStr(_tempStr);
@ -1171,7 +1171,7 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
if ((collArea->flags & 0x0f) > 10)
continue;
strcpy(_tempStr, _vm->_global->_inter_variables + collArea->key);
strcpy(_tempStr, GET_VARO_STR(collArea->key));
_vm->_draw->_destSpriteX = collArea->left;
_vm->_draw->_destSpriteY = collArea->top;
@ -1193,9 +1193,8 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
descInd++;
}
for (i = 0; i < 40; i++) {
for (i = 0; i < 40; i++)
WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
}
while (1) {
descInd = 0;
@ -1231,8 +1230,8 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
collArea->right - collArea->left + 1,
collArea->bottom - collArea->top + 1,
inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
_vm->_global->_inter_variables + collArea->key,
inpDesc[*pCurPos].fontIndex, collArea->flags, &time, collResId, collIndex);
GET_VARO_STR(collArea->key), inpDesc[*pCurPos].fontIndex,
collArea->flags, &time, collResId, collIndex);
if (_vm->_inter->_terminate)
return 0;

View file

@ -55,9 +55,9 @@ void Game_v2::playTot(int16 skipPlay) {
int16 nestLevel;
int32 variablesCount;
int32 totSize;
int32 i;
char *filePtr;
char *savedIP;
int16 i;
oldNestLevel = _vm->_inter->_nestLevel;
oldBreakFrom = _vm->_inter->_breakFromLevel;
@ -199,7 +199,9 @@ void Game_v2::playTot(int16 skipPlay) {
if (_vm->_global->_inter_variables == 0) {
variablesCount = READ_LE_UINT32((char *)_totFileData + 0x2c);
_vm->_global->_inter_variables = new char[variablesCount * 4];
memset(_vm->_global->_inter_variables, 0, variablesCount * 4);
_vm->_global->_inter_variablesSizes = new byte[variablesCount * 4];
for (i = 0; i < variablesCount; i++)
WRITE_VAR(i, 0);
}
_vm->_global->_inter_execPtr = (char *)_totFileData;
@ -479,6 +481,7 @@ int16 Game_v2::checkCollisions(char handleMouse, int16 deltaTime, int16 *pResId,
&_mouseButtons, handleMouse);
// TODO: What of this is needed?
// Scrolling?
int16 width;
int16 height;
int16 sWidth;
@ -1145,13 +1148,12 @@ void Game_v2::collisionsBlock(void) {
if ((_collisionAreas[i].flags & 0x0f) > 8) {
char *ptr;
strcpy(_tempStr,
_vm->_global->_inter_variables + _collisionAreas[i].key);
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
while ((ptr = strchr(_tempStr, ' ')) != 0) {
_vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
ptr = strchr(_tempStr, ' ');
}
strcpy(_vm->_global->_inter_variables + _collisionAreas[i].key, _tempStr);
WRITE_VARO_STR(_collisionAreas[i].key, _tempStr);
if (_vm->_language == 2) { // loc_16080
warning("GOB2 Stub! Game_v2::collisionsBlock(), language == 2");
}
@ -1161,7 +1163,7 @@ void Game_v2::collisionsBlock(void) {
(_collisionAreas[i].flags & 0x0f) <= 8) {
str = descArray[var_24].ptr;
strcpy(_tempStr, _vm->_global->_inter_variables + _collisionAreas[i].key);
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
if ((_collisionAreas[i].flags & 0x0f) < 7)
_vm->_util->prepareStr(_tempStr);
@ -1250,7 +1252,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
if ((collArea->flags & 0x0F) > 10)
continue;
strcpy(_tempStr, _vm->_global->_inter_variables + collArea->key);
strcpy(_tempStr, GET_VARO_STR(collArea->key));
_vm->_draw->_destSpriteX = collArea->left;
_vm->_draw->_destSpriteY = collArea->top;
@ -1281,9 +1283,8 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
descInd++;
}
for (i = 0; i < 40; i++) {
for (i = 0; i < 40; i++)
WRITE_VAR_OFFSET(i * 4 + 0x44, 0);
}
while (1) {
descInd = 0;
@ -1319,8 +1320,8 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos, InputDesc * in
collArea->right - collArea->left + 1,
collArea->bottom - collArea->top + 1,
inpDesc[*pCurPos].backColor, inpDesc[*pCurPos].frontColor,
_vm->_global->_inter_variables + collArea->key,
inpDesc[*pCurPos].fontIndex, collArea->flags, &time, collResId, collIndex);
GET_VARO_STR(collArea->key), inpDesc[*pCurPos].fontIndex,
collArea->flags, &time, collResId, collIndex);
if (_vm->_inter->_terminate)
return 0;

View file

@ -141,6 +141,7 @@ Global::Global(GobEngine *vm) : _vm(vm) {
_inter_resStr[0] = 0;
_inter_resVal = 0;
_inter_variablesSizes = 0;
_inter_variables = 0;
_inter_execPtr = 0;
_inter_animDataSize = 10;

View file

@ -155,6 +155,7 @@ public:
char _inter_resStr[200];
int32 _inter_resVal;
byte *_inter_variablesSizes; // 0: single byte, 1: two bytes, 3: four bytes
char *_inter_variables;
char *_inter_execPtr;
int16 _inter_animDataSize;
@ -162,10 +163,63 @@ public:
int16 _inter_mouseX;
int16 _inter_mouseY;
inline void writeVarSizeStr(uint32 offset, uint32 len) {
uint32 i;
uint32 inVar;
uint32 varOff;
inVar = offset % 4;
varOff = (offset >> 2) << 2;
for (i = 0; i < 4; i++) {
if (_inter_variablesSizes[varOff + i] == 3)
_inter_variablesSizes[varOff + i] = 0;
else if ((inVar == (i+1)) && (_inter_variablesSizes[varOff + i] == 1))
_inter_variablesSizes[varOff + i] = 0;
}
memset(_inter_variablesSizes + offset, 0, len);
}
inline void writeVar(uint32 offset, uint32 val) {
(*(uint32 *)(_inter_variables + offset)) = val;
writeVarSize(offset, 3);
}
inline void writeVar(uint32 offset, uint16 val) {
(*(uint16 *)(_inter_variables + offset)) = val;
writeVarSize(offset, 1);
}
inline void writeVar(uint32 offset, uint8 val) {
(*(uint8 *)(_inter_variables + offset)) = val;
writeVarSize(offset, 0);
}
inline void writeVar(uint32 offset, const char *str) {
writeVarSizeStr(offset, strlen(str));
strcpy(_inter_variables + offset, str);
}
Global(GobEngine *vm);
protected:
GobEngine *_vm;
inline void writeVarSize(uint32 offset, byte n) {
uint32 i;
uint32 inVar;
uint32 varOff;
inVar = offset % 4;
varOff = (offset >> 2) << 2;
for (i = 0; i < 4; i++) {
if (_inter_variablesSizes[varOff + i] == 3)
_inter_variablesSizes[varOff + i] = 0;
else if ((inVar == (i+1)) && (_inter_variablesSizes[varOff + i] == 1))
_inter_variablesSizes[varOff + i] = 0;
}
_inter_variablesSizes[offset] = n;
for (; n > 0; n--)
_inter_variablesSizes[offset + n] = 0;
}
};
} // End of namespace Gob

View file

@ -50,6 +50,10 @@
#include "sound/mididrv.h"
// Use the original saves. Just for testing purposes, will be removed later
// The new method is more convenient, and, more importantly, endian-safe
//#define GOB_ORIGSAVES
namespace Gob {
enum {
@ -176,6 +180,10 @@ GobEngine::GobEngine(OSystem * syst, uint32 features, Common::Language lang,
sprintf(_saveFiles[0], "%s.cat", _targetName.c_str());
sprintf(_saveFiles[1], "%s.sav", _targetName.c_str());
sprintf(_saveFiles[2], "%s.blo", _targetName.c_str());
_saveSlotFile = new char[_targetName.size() + 5];
sprintf(_saveSlotFile, "%s.s00", _targetName.c_str());
memset(_saveIndex, 0, 600);
memset(_saveIndexSizes, 0, 600);
Common::addSpecialDebugLevel(DEBUG_FUNCOP, "FuncOpcodes", "Script FuncOpcodes debug level");
Common::addSpecialDebugLevel(DEBUG_DRAWOP, "DrawOpcodes", "Script DrawOpcodes debug level");
@ -216,6 +224,7 @@ GobEngine::~GobEngine() {
for (i = 0; i < 3; i++)
delete[] _saveFiles[i];
delete[] _saveFiles;
delete[] _saveSlotFile;
}
int GobEngine::go() {
@ -228,11 +237,6 @@ void GobEngine::shutdown() {
_quitRequested = true;
}
void GobEngine::writeVarDebug(uint32 offs, uint32 v) {
warning("Setting var %u(%u) to %u", offs, offs >> 2, v);
(*(uint32 *)(_global->_inter_variables + (offs))) = v;
}
// Seeking with SEEK_END (and therefore also pos()) doesn't work with
// gzip'd save files, so reading the whole thing in is necessary
uint32 GobEngine::getSaveSize(Common::InSaveFile &in) {
@ -255,22 +259,44 @@ int32 GobEngine::getSaveSize(enum SaveFiles sFile) {
int32 size;
Common::InSaveFile *in;
size = -1;
#ifndef GOB_ORIGSAVES
int i;
if (sFile == SAVE_CAT) {
for (i = 14; i >= 0; i--)
if ((in = _saveFileMan->openForLoading(getSaveSlotFile(i)))) {
size = (i + 1) * READ_LE_UINT32(_game->_totFileData + 0x2C) * 4 + 600;
delete in;
break;
}
debugC(1, DEBUG_FILEIO, "Requested save games size: %d", size);
return size;
}
#endif // GOB_ORIGSAVES
if ((in = _saveFileMan->openForLoading(_saveFiles[(int) sFile]))) {
size = getSaveSize(*in);
delete in;
} else
size = -1;
}
debugC(1, DEBUG_FILEIO, "Requested size of file \"%s\": %d", _saveFiles[(int) sFile], size);
return size;
}
void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
const char *GobEngine::getSaveSlotFile(int slot) {
static char *slotBase = _saveSlotFile + strlen(_targetName.c_str()) + 2;
snprintf(slotBase, 3, "%02d", slot);
return _saveSlotFile;
}
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;
@ -287,9 +313,9 @@ void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
in = 0;
writePal = false;
sName = _saveFiles[(int) sFile];
needEnforceEndian = false;
// WRITE_VAR(1, 1)
*((uint32*)(_global->_inter_variables + 4)) = 1;
WRITE_VAR(1, 1);
if (size < 0) {
if (size < -1000) {
@ -302,12 +328,26 @@ void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
size = _draw->getSpriteRectSize(index);
if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else if (size == 0) {
dataVar = 0;
size = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
buf = _global->_inter_variables;
} else
} else {
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;
}
needEnforceEndian = true;
#endif // GOB_ORIGSAVES
}
if ((in = _saveFileMan->openForLoading(sName)))
iSize = getSaveSize(*in);
@ -325,7 +365,7 @@ void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
}
if(!(out = _saveFileMan->openForSaving(sName))) {
warning("Can't write file \"%s\"", sName);
warning("Can't open file \"%s\" for writing", sName);
delete[] oBuf;
return;
}
@ -335,21 +375,25 @@ void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
oOff += 768;
}
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);
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);
out->write(oBuf, oSize);
out->flush();
if (out->ioFailed())
@ -357,28 +401,115 @@ void GobEngine::saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
else {
debugC(1, DEBUG_FILEIO, "Saved file \"%s\" (%d, %d bytes at %d)",
sName, dataVar, size, offset);
// WRITE_VAR(1, 0)
*((uint32*)(_global->_inter_variables + 4)) = 0;
WRITE_VAR(1, 0);
}
delete out;
delete[] oBuf;
}
void GobEngine::loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
bool GobEngine::saveGame(int saveSlot, int16 dataVar, int32 size, int32 offset) {
int32 varSize;
char *varBuf;
byte *sizeBuf;
Common::OutSaveFile *out;
varBuf = _global->_inter_variables + dataVar;
sizeBuf = _global->_inter_variablesSizes + dataVar;
varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
if ((offset == 0) && (size == 600)) {
memcpy(_saveIndex, varBuf, size);
memcpy(_saveIndexSizes, sizeBuf, size);
return true;
} else if((((offset - 600) % varSize) == 0) && (size == varSize)) {
if (!(out = _saveFileMan->openForSaving(getSaveSlotFile(saveSlot)))) {
warning("Can't open file \"%s\" for writing", getSaveSlotFile(saveSlot));
return false;
}
writeDataEndian(*out, _saveIndex + saveSlot * 40, _saveIndexSizes + saveSlot * 40, 40);
writeDataEndian(*out, varBuf, sizeBuf, size);
out->flush();
if (out->ioFailed()) {
warning("Can't save to slot %d", saveSlot);
return false;
}
debugC(1, DEBUG_FILEIO, "Saved to slot %d", saveSlot);
delete out;
return true;
} else {
warning("Invalid saving procedure");
return false;
}
}
uint32 GobEngine::writeDataEndian(Common::OutSaveFile &out, char *varBuf, byte *sizeBuf,
int32 size) {
#ifndef GOB_ORIGSAVES
uint32 written;
#ifdef SCUMM_BIG_ENDIAN
int i;
char tmp[4];
written = 0;
for (i = 0; i < size; i++, varBuf++) {
if (sizeBuf[i] == 3)
WRITE_LE_UINT32(tmp, *((uint32 *) varBuf));
else if (sizeBuf[i] == 1)
WRITE_LE_UINT16(tmp, *((uint16 *) varBuf));
else if (sizeBuf[i] == 0)
*tmp = *varBuf;
else {
warning("Can't write data, corrupted variables sizes");
return 0;
}
written += out.write(tmp, sizeBuf[i] + 1);
varBuf += sizeBuf[i];
i += sizeBuf[i];
}
#else // SCUMM_BIG_ENDIAN
written = out.write(varBuf, size);
#endif // SCUMM_BIG_ENDIAN
out.write(sizeBuf, size);
return written;
#else // GOB_ORIGSAVES
return out.write(varBuf, size);
#endif // GOB_ORIGSAVES
}
void GobEngine::loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset) {
int32 sSize;
int32 retSize;
int16 index = 0;
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 (size < -1000) {
readPal = true;
@ -390,25 +521,38 @@ void GobEngine::loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
size = _draw->getSpriteRectSize(index);
if ((_draw->_spritesArray[index]->vidMode & 0x80) == 0)
size = -size;
} else if (size == 0) {
dataVar = 0;
size = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
buf = _global->_inter_variables;
} else
} 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);
return;
}
needEnforceEndian = true;
#endif // GOB_ORIGSAVES
}
if (_global->_inter_resStr[0] == 0) {
if (readPal)
size += 768;
// WRITE_VAR(1, size)
*((uint32*)(_global->_inter_variables + 4)) = (uint32) size;
WRITE_VAR(1, size);
return;
}
// WRITE_VAR(1, 1)
*((uint32*)(_global->_inter_variables + 4)) = 1;
if(!(in = _saveFileMan->openForLoading(sName)))
if(!(in = _saveFileMan->openForLoading(sName))) {
warning("Can't open file \"%s\" for reading", sName);
return;
}
debugC(1, DEBUG_FILEIO, "Loading file \"%s\" (%d, %d bytes at %d)",
sName, dataVar, size, offset);
@ -425,26 +569,119 @@ void GobEngine::loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32
_draw->_applyPal = 1;
}
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);
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);
} else
retSize = in->read(buf, size);
retSize = readDataEndian(*in, buf, _global->_inter_variablesSizes + dataVar, size);
if (retSize == size)
// WRITE_VAR(1, 0)
*((uint32*)(_global->_inter_variables + 4)) = 0;
WRITE_VAR(1, 0);
delete in;
return;
}
bool GobEngine::loadGame(int saveSlot, int16 dataVar, int32 size, int32 offset) {
int i;
int32 varSize;
char *varBuf;
byte *sizeBuf;
Common::InSaveFile *in;
varBuf = _global->_inter_variables + dataVar;
sizeBuf = _global->_inter_variablesSizes + dataVar;
varSize = READ_LE_UINT32(_game->_totFileData + 0x2C) * 4;
if ((offset == 0) && (size == 600)) {
for (i = 0; i < 15; i++, varBuf += 40) {
if ((in = _saveFileMan->openForLoading(getSaveSlotFile(i)))) {
in->read(varBuf, 40);
delete in;
} else
memset(varBuf, 0, 40);
}
return true;
} else if((((offset - 600) % varSize) == 0) && (size == varSize)) {
if (!(in = _saveFileMan->openForLoading(getSaveSlotFile(saveSlot)))) {
warning("Can't load from slot %d", saveSlot);
return false;
}
if (((getSaveSize(*in) / 2) - 40) != (uint32) varSize) {
warning("Can't load from slot %d: Wrong size", saveSlot);
return false;
}
in->seek(80);
readDataEndian(*in, varBuf, sizeBuf, size);
delete in;
debugC(1, DEBUG_FILEIO, "Loading from slot %d", saveSlot);
return true;
} else {
warning("Invalid loading procedure");
return false;
}
}
uint32 GobEngine::readDataEndian(Common::InSaveFile &in, char *varBuf, byte *sizeBuf,
int32 size) {
#ifndef GOB_ORIGSAVES
uint32 read;
char *vars;
char *sizes;
vars = new char[size];
sizes = new char[size];
read = in.read(vars, size);
if (in.read(sizes, size) != read) {
warning("Can't read data: Corrupted variables sizes");
delete[] vars;
delete[] sizes;
return 0;
}
#ifdef SCUMM_BIG_ENDIAN
int i;
for (i = 0; i < size; i++) {
if (sizes[i] == 3)
*((uint32 *) (vars + i)) = READ_LE_UINT32(vars + i);
else if (sizes[i] == 1)
*((uint16 *) (vars + i)) = READ_LE_UINT16(vars + i);
else if (sizes[i] != 0) {
warning("Can't read data: Corrupted variables sizes");
return 0;
}
i += sizes[i];
}
#endif // SCUMM_BIG_ENDIAN
memcpy(varBuf, vars, size);
memcpy(sizeBuf, sizes, size);
delete[] vars;
delete[] sizes;
return read;
#else // GOB_ORIGSAVES
return in.read(varBuf, size);
#endif // GOB_ORIGSAVES
}
int GobEngine::init() {
_snd = new Snd(this);
_global = new Global(this);
@ -487,6 +724,7 @@ int GobEngine::init() {
else
_music = new Music(this);
}
_vm = this;
_system->beginGFXTransaction();
initCommonGFX(false);

View file

@ -52,13 +52,38 @@ class GTimer;
class Util;
class Music;
/*
#define VAR_OFFSET(offs) (*(uint32 *)(_vm->_global->_inter_variables + (offs)))
#define VAR(var) VAR_OFFSET((var) << 2)
#define VAR_ADDRESS(var) (&VAR(var))
//#define WRITE_VAR_OFFSET(offs, val) _vm->writeVarDebug(offs, val)
#define WRITE_VAR_OFFSET(offs, val) (VAR_OFFSET(offs) = (val))
#define WRITE_VAR(var, val) WRITE_VAR_OFFSET((var) << 2, (val))
*/
#define VARP(offs) (_vm->_global->_inter_variables + (offs))
#define WRITE_VARO_UINT32(offs, val) _vm->_global->writeVar(offs, (uint32) (val))
#define WRITE_VARO_UINT16(offs, val) _vm->_global->writeVar(offs, (uint16) (val))
#define WRITE_VARO_UINT8(offs, val) _vm->_global->writeVar(offs, (uint8) (val))
#define WRITE_VARO_STR(offs, str) _vm->_global->writeVar(offs, (const char *) (str))
#define WRITE_VAR_UINT32(var, val) WRITE_VARO_UINT32((var) << 2, (val))
#define WRITE_VAR_UINT16(var, val) WRITE_VARO_UINT16((var) << 2, (val))
#define WRITE_VAR_UINT8(var, val) WRITE_VARO_UINT8((var) << 2, (val))
#define WRITE_VAR_STR(var, str) WRITE_VARO_STR((var) << 2, (str))
#define READ_VARO_UINT32(offs) (*((uint32 *) VARP(offs)))
#define READ_VARO_UINT16(offs) (*((uint16 *) VARP(offs)))
#define READ_VARO_UINT8(offs) (*((uint8 *) VARP(offs)))
#define READ_VAR_UINT32(var) READ_VARO_UINT32((var) << 2)
#define READ_VAR_UINT16(var) READ_VARO_UINT16((var) << 2)
#define READ_VAR_UINT8(var) READ_VARO_UINT8((var) << 2)
#define GET_VARO_STR(offs) ((char *) VARP(offs))
#define GET_VAR_STR(var) GET_VARO_STR((var) << 2)
#define WRITE_VAR_OFFSET(offs, val) WRITE_VARO_UINT32((offs), (val))
#define WRITE_VAR(var, val) WRITE_VAR_UINT32((var), (val))
#define VAR_OFFSET(offs) READ_VARO_UINT32(offs)
#define VAR(var) READ_VAR_UINT32(var)
#define VAR_ADDRESS(var) ((uint32 *) VARP((var) << 2))
enum {
GF_GOB1 = 1 << 0,
@ -83,16 +108,28 @@ enum {
};
enum SaveFiles {
SAVE_CAT = 0,
SAVE_SAV,
SAVE_BLO
SAVE_CAT = 0, // Saves
SAVE_SAV, // Draw::_backSurface (why?)
SAVE_BLO // Notes
};
class GobEngine : public Engine {
protected:
char **_saveFiles;
char *_saveSlotFile;
char _saveIndex[600];
byte _saveIndexSizes[600];
int go();
int init();
inline uint32 getSaveSize(Common::InSaveFile &in);
const char *getSaveSlotFile(int slot);
bool saveGame(int saveSlot, int16 dataVar, int32 size, int32 offset);
bool loadGame(int saveSlot, int16 dataVar, int32 size, int32 offset);
uint32 writeDataEndian(Common::OutSaveFile &out, char *varBuf, byte *sizeBuf, int32 size);
uint32 readDataEndian(Common::InSaveFile &in, char *varBuf, byte *sizeBuf, int32 size);
public:
GobEngine(OSystem *syst, uint32 features, Common::Language lang, const char *startTotBase);
virtual ~GobEngine();
@ -105,7 +142,6 @@ public:
Common::Language _language;
char *_startTot;
char *_startTot0;
char **_saveFiles;
bool _copyProtection;
bool _quitRequested;
@ -129,12 +165,13 @@ public:
Util *_util;
Inter *_inter;
Music *_music;
GobEngine *_vm;
void writeVarDebug(uint32 offs, uint32 v);
inline uint32 getSaveSize(Common::InSaveFile &in);
int32 getSaveSize(enum SaveFiles sFile);
void saveGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
void loadGame(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
void saveGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
void loadGameData(enum SaveFiles sFile, int16 dataVar, int32 size, int32 offset);
};
} // End of namespace Gob

View file

@ -166,9 +166,10 @@ Goblin::~Goblin() {
if (_goblins[i]) {
if (_goblins[i]->stateMach) {
for (state = 0; state < (i == 3 ? 70 : 40); state++)
for (col = 0; col < 6; col++)
if (_goblins[i]->stateMach[state][col])
delete _goblins[i]->stateMach[state][col];
if (_goblins[i]->stateMach[state])
for (col = 0; col < 6; col++)
if (_goblins[i]->stateMach[state][col])
delete _goblins[i]->stateMach[state][col];
delete []_goblins[i]->stateMach;
}
delete _goblins[i];
@ -1892,10 +1893,10 @@ void Goblin::sub_19BD3(void) {
pass = _vm->_map->getPass(gob1X, gob1Y);
if ((pass > 17) && (pass < 21))
warning("GOB2 Stub! sub_19AB7(anim0);");
sub_19AB7(anim0);
pass = _vm->_map->getPass(gob2X, gob2Y);
if ((pass > 17) && (pass < 21))
warning("GOB2 Stub! sub_19B45(anim1);");
sub_19B45(anim1);
if ((di < 0) || (di > 39) || (si < 0) || (si > 39))
return;
@ -2159,4 +2160,68 @@ void Goblin::sub_197A6(int16 destX, int16 destY, int16 objIndex) {
initiateMove(obj);
}
void Goblin::sub_19AB7(Mult::Mult_AnimData *animData) {
switch(animData->state) {
case 2:
animData->layer = 8;
break;
case 6:
animData->layer = 9;
break;
case 17:
animData->layer = 26;
break;
case 18:
animData->layer = 32;
break;
case 21:
animData->layer = 22;
break;
case 22:
animData->layer = 20;
break;
case 23:
animData->layer = 21;
break;
}
}
void Goblin::sub_19B45(Mult::Mult_AnimData *animData) {
switch(animData->state) {
case 2:
animData->layer = 10;
break;
case 6:
animData->layer = 11;
break;
case 17:
animData->layer = 29;
break;
case 18:
animData->layer = 35;
break;
case 21:
animData->layer = 25;
break;
case 22:
animData->layer = 23;
break;
case 23:
animData->layer = 24;
break;
}
}
} // End of namespace Gob

View file

@ -221,6 +221,8 @@ public:
void sub_195C7(int16 index, int16 state);
void sub_11984(Mult::Mult_Object *obj);
void sub_197A6(int16 destX, int16 destY, int16 objIndex);
void sub_19AB7(Mult::Mult_AnimData *animData);
void sub_19B45(Mult::Mult_AnimData *animData);
virtual void placeObject(Gob_Object * objDesc, char animated,
int16 index, int16 x, int16 y, int16 state) = 0;

View file

@ -89,8 +89,8 @@ void Init::cleanup(void) {
void Init::initGame(char *totName) {
int16 handle2;
int16 i;
int16 handle;
int32 i;
char *infBuf;
char *infPtr;
char *infEnd;
@ -132,6 +132,7 @@ memBlocks = word ptr -2*/
_vm->_game->_totFileData = 0;
_vm->_game->_totResourceTable = 0;
_vm->_global->_inter_variables = 0;
_vm->_global->_inter_variablesSizes = 0;
_palDesc = new Video::PalDesc;
if (_vm->_global->_videoMode != 0x13)
@ -204,7 +205,9 @@ memBlocks = word ptr -2*/
_vm->_dataio->closeData(handle);
_vm->_global->_inter_variables = new char[varsCount * 4];
memset(_vm->_global->_inter_variables, 0, varsCount * 4);
_vm->_global->_inter_variablesSizes = new byte[varsCount * 4];
for (i = 0; i < varsCount; i++)
WRITE_VAR(i, 0);
WRITE_VAR(58, 1);
strcpy(_vm->_game->_curTotFile, buffer);
@ -217,6 +220,7 @@ memBlocks = word ptr -2*/
_vm->_cdrom->freeLICbuffer();
delete[] _vm->_global->_inter_variables;
delete[] _vm->_global->_inter_variablesSizes;
delete[] _vm->_game->_totFileData;
if (_vm->_game->_totTextData) {
if (_vm->_game->_totTextData->items)

View file

@ -58,6 +58,7 @@ Inter::Inter(GobEngine *vm) : _vm(vm) {
_nestLevel = 0;
memset(_pasteBuf, 0, 300);
memset(_pasteSizeBuf, 0, 300);
_pastePos = 0;
}

View file

@ -52,6 +52,7 @@ public:
int32 peek32(char *ptr);
char _pasteBuf[300];
byte _pasteSizeBuf[300];
int16 _pastePos;
char evalExpr(int16 *pRes);
@ -319,6 +320,7 @@ protected:
void o2_stub0x54(void);
void o2_stub0x55(void);
void o2_stub0x80(void);
void o2_stub0x81(void);
void o2_stub0x82(void);
void o2_stub0x85(void);
bool o2_getFreeMem(char &cmdCount, int16 &counter, int16 &retFlag);

View file

@ -672,9 +672,9 @@ bool Inter_v1::o1_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag)
case 25:
case 28:
if (token == 20)
*(_vm->_global->_inter_variables + varOff) = result;
WRITE_VARO_UINT8(varOff, result);
else
strcpy(_vm->_global->_inter_variables + varOff, _vm->_global->_inter_resStr);
WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr);
break;
}
@ -739,7 +739,7 @@ bool Inter_v1::o1_printText(char &cmdCount, int16 &counter, int16 &retFlag) {
case 25:
case 28:
sprintf(buf + i, "%s", _vm->_global->_inter_variables + _vm->_parse->parseVarIndex());
sprintf(buf + i, "%s", GET_VARO_STR(_vm->_parse->parseVarIndex()));
break;
}
_vm->_global->_inter_execPtr++;
@ -1010,7 +1010,8 @@ bool Inter_v1::o1_prepareStr(char &cmdCount, int16 &counter, int16 &retFlag) {
int16 var;
var = _vm->_parse->parseVarIndex();
_vm->_util->prepareStr(_vm->_global->_inter_variables + var);
_vm->_util->prepareStr(GET_VARO_STR(var));
_vm->_global->writeVarSizeStr(var, strlen(GET_VARO_STR(var)));
return false;
}
@ -1021,7 +1022,8 @@ bool Inter_v1::o1_insertStr(char &cmdCount, int16 &counter, int16 &retFlag) {
strVar = _vm->_parse->parseVarIndex();
evalExpr(0);
pos = _vm->_parse->parseValExpr();
_vm->_util->insertStr(_vm->_global->_inter_resStr, _vm->_global->_inter_variables + strVar, pos);
_vm->_util->insertStr(_vm->_global->_inter_resStr, GET_VARO_STR(strVar), pos);
_vm->_global->writeVarSizeStr(strVar, strlen(GET_VARO_STR(strVar)));
return false;
}
@ -1033,7 +1035,7 @@ bool Inter_v1::o1_cutStr(char &cmdCount, int16 &counter, int16 &retFlag) {
var = _vm->_parse->parseVarIndex();
pos = _vm->_parse->parseValExpr();
size = _vm->_parse->parseValExpr();
_vm->_util->cutFromStr(_vm->_global->_inter_variables + var, pos, size);
_vm->_util->cutFromStr(GET_VARO_STR(var), pos, size);
return false;
}
@ -1046,8 +1048,8 @@ bool Inter_v1::o1_strstr(char &cmdCount, int16 &counter, int16 &retFlag) {
evalExpr(0);
resVar = _vm->_parse->parseVarIndex();
char *res = strstr(_vm->_global->_inter_variables + strVar, _vm->_global->_inter_resStr);
pos = res ? (res - (_vm->_global->_inter_variables + strVar)) : -1;
char *res = strstr(GET_VARO_STR(strVar), _vm->_global->_inter_resStr);
pos = res ? (res - (GET_VARO_STR(strVar))) : -1;
WRITE_VAR_OFFSET(resVar, pos);
return false;
}
@ -1062,7 +1064,7 @@ bool Inter_v1::o1_istrlen(char &cmdCount, int16 &counter, int16 &retFlag) {
int16 var;
var = _vm->_parse->parseVarIndex();
len = strlen(_vm->_global->_inter_variables + var);
len = strlen(GET_VARO_STR(var));
var = _vm->_parse->parseVarIndex();
WRITE_VAR_OFFSET(var, len);
@ -1076,7 +1078,7 @@ bool Inter_v1::o1_strToLong(char &cmdCount, int16 &counter, int16 &retFlag) {
int32 res;
strVar = _vm->_parse->parseVarIndex();
strcpy(str, _vm->_global->_inter_variables + strVar);
strcpy(str, GET_VARO_STR(strVar));
res = atol(str);
destVar = _vm->_parse->parseVarIndex();

View file

@ -286,7 +286,7 @@ void Inter_v2::setupOpcodes(void) {
{NULL, ""},
/* 80 */
OPCODE(o2_stub0x80),
OPCODE(o2_drawStub),
OPCODE(o2_stub0x81),
OPCODE(o2_stub0x82),
OPCODE(o2_playImd),
/* 84 */
@ -881,6 +881,23 @@ void Inter_v2::o2_stub0x80(void) {
}
}
void Inter_v2::o2_stub0x81(void) {
int16 var1;
int16 var2;
int16 var3;
int16 var4;
int16 var5;
int16 var6;
var1 = _vm->_parse->parseValExpr();
var2 = _vm->_parse->parseValExpr();
var3 = _vm->_parse->parseValExpr();
var4 = _vm->_parse->parseValExpr();
var5 = _vm->_parse->parseValExpr();
var6 = _vm->_parse->parseValExpr();
warning("GOB2 Stub! o2_stub0x81(%d, %d, %d, %d, %d, %d)", var1, var2, var3, var4, var5, var6);
}
void Inter_v2::o2_stub0x82(void) {
int16 expr;
@ -1026,14 +1043,19 @@ void Inter_v2::o2_copyVars(void) {
_vm->_global->_inter_execPtr++;
memcpy(_pasteBuf + _pastePos, _vm->_global->_inter_variables + varOff,
_vm->_global->_inter_animDataSize * 4);
memcpy(_pasteSizeBuf + _pastePos, _vm->_global->_inter_variablesSizes + varOff,
_vm->_global->_inter_animDataSize * 4);
_pastePos += _vm->_global->_inter_animDataSize * 4;
_pasteBuf[_pastePos] = _vm->_global->_inter_animDataSize * 4;
_pasteSizeBuf[_pastePos] = _vm->_global->_inter_animDataSize * 4;
} else {
if (evalExpr(&varOff) == 20)
_vm->_global->_inter_resVal = 0;
memcpy(_pasteBuf + _pastePos, &_vm->_global->_inter_resVal, 4);
memcpy(_pasteSizeBuf + _pastePos, &_vm->_global->_inter_resVal, 4);
_pastePos += 4;
_pasteBuf[_pastePos] = 4;
_pasteSizeBuf[_pastePos] = 4;
}
_pastePos++;
}
@ -1042,15 +1064,19 @@ void Inter_v2::o2_copyVars(void) {
void Inter_v2::o2_pasteVars(void) {
byte count;
int16 varOff;
int16 size;
int16 sizeV;
int16 sizeS;
int i;
count = *_vm->_global->_inter_execPtr++;
for (i = 0; i < count; i++) {
varOff = _vm->_parse->parseVarIndex();
size = _pasteBuf[--_pastePos];
_pastePos -= size;
memcpy(_vm->_global->_inter_variables + varOff, _pasteBuf + _pastePos, size);
sizeV = _pasteBuf[--_pastePos];
sizeS = _pasteSizeBuf[_pastePos];
assert(sizeV == sizeS);
_pastePos -= sizeV;
memcpy(_vm->_global->_inter_variables + varOff, _pasteBuf + _pastePos, sizeV);
memcpy(_vm->_global->_inter_variablesSizes + varOff, _pasteSizeBuf + _pastePos, sizeS);
}
}
@ -1332,13 +1358,15 @@ bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
int32 offset;
int16 dataVar; // si
int16 handle;
int16 index = 0;
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();
@ -1347,19 +1375,19 @@ bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
offset = _vm->_global->_inter_resVal;
if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf")) {
_vm->loadGame(SAVE_CAT, dataVar, size, offset);
_vm->loadGameData(SAVE_CAT, dataVar, size, offset);
return false;
}
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat")) {
_vm->loadGame(SAVE_CAT, dataVar, size, offset);
_vm->loadGameData(SAVE_CAT, dataVar, size, offset);
return false;
}
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf")) {
_vm->loadGame(SAVE_SAV, dataVar, size, offset);
_vm->loadGameData(SAVE_SAV, dataVar, size, offset);
return false;
}
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf")) {
_vm->loadGame(SAVE_BLO, dataVar, size, offset);
_vm->loadGameData(SAVE_BLO, dataVar, size, offset);
return false;
}
@ -1374,12 +1402,14 @@ bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
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;
} else
} 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)
@ -1414,6 +1444,9 @@ bool Inter_v2::o2_readData(char &cmdCount, int16 &counter, int16 &retFlag) {
_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)) {
retSize = _vm->_dataio->readData(handle, tmp, 4);
WRITE_VAR(59, READ_LE_UINT32(tmp));
} else
retSize = _vm->_dataio->readData(handle, buf, size);
@ -1436,13 +1469,13 @@ bool Inter_v2::o2_writeData(char &cmdCount, int16 &counter, int16 &retFlag) {
offset = _vm->_global->_inter_resVal;
if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.inf"))
_vm->saveGame(SAVE_CAT, dataVar, size, offset);
_vm->saveGameData(SAVE_CAT, dataVar, size, offset);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "cat.cat"))
_vm->saveGame(SAVE_CAT, dataVar, size, offset);
_vm->saveGameData(SAVE_CAT, dataVar, size, offset);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "save.inf"))
_vm->saveGame(SAVE_SAV, dataVar, size, offset);
_vm->saveGameData(SAVE_SAV, dataVar, size, offset);
else if (!scumm_stricmp(_vm->_global->_inter_resStr, "bloc.inf"))
_vm->saveGame(SAVE_BLO, dataVar, size, offset);
_vm->saveGameData(SAVE_BLO, dataVar, size, offset);
else
warning("Attempted to write to file \"%s\"", _vm->_global->_inter_resStr);
@ -1619,12 +1652,12 @@ bool Inter_v2::o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag)
switch (savedPos[0]) {
case 16:
case 18:
*(_vm->_global->_inter_variables + varOff + i) = _vm->_global->_inter_resVal;
WRITE_VARO_UINT8(varOff + i, _vm->_global->_inter_resVal);
break;
case 17:
case 27:
*(uint16*)(_vm->_global->_inter_variables + varOff + i * 2) = _vm->_global->_inter_resVal;
WRITE_VARO_UINT16(varOff + i * 2, _vm->_global->_inter_resVal);
break;
case 23:
@ -1633,15 +1666,15 @@ bool Inter_v2::o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag)
break;
case 24:
*(uint16*)(_vm->_global->_inter_variables + varOff + i * 4) = _vm->_global->_inter_resVal;
WRITE_VARO_UINT16(varOff + i * 4, _vm->_global->_inter_resVal);
break;
case 25:
case 28:
if (token == 20)
*(_vm->_global->_inter_variables + varOff) = result;
WRITE_VARO_UINT8(varOff, result);
else
strcpy(_vm->_global->_inter_variables + varOff, _vm->_global->_inter_resStr);
WRITE_VARO_STR(varOff, _vm->_global->_inter_resStr);
break;
}
}
@ -1927,6 +1960,8 @@ void Inter_v2::o2_initMult(void) {
_vm->_mult->_objects[i].pAnimData =
(Mult::Mult_AnimData *) (_vm->_global->_inter_variables + animDataVar +
i * 4 * _vm->_global->_inter_animDataSize);
memset(_vm->_global->_inter_variablesSizes + i * 4 * _vm->_global->_inter_animDataSize, 0,
_vm->_global->_inter_animDataSize);
_vm->_mult->_objects[i].pAnimData->isStatic = 1;
_vm->_mult->_objects[i].tick = 0;
@ -2056,22 +2091,16 @@ void Inter_v2::o2_freeLIC(void) {
}
void Inter_v2::o2_getCDTrackPos(void) {
int16 trackpospos;
int16 tracknamepos;
int32 trackpos;
int16 varPos;
int16 varName;
_vm->_util->longDelay(1);
trackpospos = _vm->_parse->parseVarIndex();
// The currently playing trackname would be written there to
// notice trackbound overruns. Since we stop on trackend and
// CDROM::getTrackPos() returns -1 then anyway, we can ignore it.
tracknamepos = _vm->_parse->parseVarIndex();
trackpos = _vm->_cdrom->getTrackPos();
if (trackpos == -1)
trackpos = 32767;
varPos = _vm->_parse->parseVarIndex();
varName = _vm->_parse->parseVarIndex();
WRITE_VAR(trackpospos >> 2, trackpos);
WRITE_VAR_OFFSET(varPos, _vm->_cdrom->getTrackPos());
WRITE_VARO_STR(varName, _vm->_cdrom->getCurTrack());
}
void Inter_v2::o2_playMult(void) {

View file

@ -114,12 +114,18 @@ void Map_v2::loadMapObjects(char *avjFile) {
dataPos1 = mapData.pos();
mapData.seek(dataPos2);
if (variables != _vm->_global->_inter_variables) {
byte *sizes;
_passMap = (int8 *) variables;
mapHeight = 200 / _tilesHeight;
mapWidth = _screenWidth / _tilesWidth;
for (i = 0; i < mapHeight; i++)
sizes = _vm->_global->_inter_variablesSizes +
(((char *) _passMap) - _vm->_global->_inter_variables);
for (i = 0; i < mapHeight; i++) {
for (j = 0; j < mapWidth; j++)
setPass(j, i, mapData.readSByte());
memset(sizes + i * _passWidth, 0, mapWidth);
}
}
mapData.seek(dataPos1);

View file

@ -330,9 +330,8 @@ void Mult_v1::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_vm->_snd->stopSound(10);
WRITE_VAR(57, (uint32)-1);
} else {
} else
WRITE_VAR(57, _frame - 1 - _frameStart);
}
}
char Mult_v1::drawStatics(char stop) {

View file

@ -586,9 +586,8 @@ void Mult_v2::playMult(int16 startFrame, int16 endFrame, char checkEscape,
_vm->_snd->stopSound(10);
WRITE_VAR(57, (uint32)-1);
} else {
} else
WRITE_VAR(57, _frame - 1 - _multData2->frameStart);
}
}
char Mult_v2::drawStatics(char stop) {

View file

@ -138,7 +138,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) {
temp = _vm->_inter->load16() * 4;
_vm->_global->_inter_execPtr++;
temp += parseValExpr(12);
*valPtr = (uint8)*(_vm->_global->_inter_variables + temp);
*valPtr = READ_VARO_UINT8(temp);
break;
case 26:
@ -157,7 +157,7 @@ int16 Parse_v1::parseValExpr(unsigned stopToken) {
} else {
_vm->_global->_inter_execPtr++;
temp2 = parseValExpr(12);
*valPtr = (uint8)*(_vm->_global->_inter_variables + temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
*valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
}
break;
@ -374,7 +374,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) {
_vm->_global->_inter_execPtr++;
temp += parseValExpr(12);
*operPtr = 20;
*valPtr = (uint8)*(_vm->_global->_inter_variables + temp);
*valPtr = READ_VARO_UINT8(temp);
}
break;
@ -401,7 +401,7 @@ int16 Parse_v1::parseExpr(char stopToken, byte *arg_2) {
_vm->_global->_inter_execPtr++;
temp2 = parseValExpr(12);
*operPtr = 20;
*valPtr = (uint8)*(_vm->_global->_inter_variables + temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
*valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
}
break;

View file

@ -114,6 +114,7 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) {
int16 brackPos;
static int16 flag = 0;
int16 oldflag;
int16 foo;
oldflag = flag;
if (flag == 0) {
@ -148,29 +149,31 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) {
offset = arrDesc[dim] * offset + temp2;
}
if (operation == 16)
*valPtr = *(int8 *)(_vm->_global->_inter_variables + temp + offset);
*valPtr = (int8) READ_VARO_UINT8(temp + offset);
else if (operation == 26)
*valPtr = *(uint16 *)(_vm->_global->_inter_variables + temp * 4 + offset * 4);
*valPtr = (uint16) READ_VARO_UINT32(temp * 4 + offset * 4);
else if (operation == 27)
*valPtr = *(uint16 *)(_vm->_global->_inter_variables + temp * 2 + offset * 2);
*valPtr = READ_VARO_UINT16(temp * 2 + offset * 2);
else if (operation == 28) {
_vm->_global->_inter_execPtr++;
temp2 = parseValExpr(12);
*valPtr = *(uint8 *)(_vm->_global->_inter_variables + temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
*valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
}
break;
case 17:
*valPtr = *(uint16 *)(_vm->_global->_inter_variables + _vm->_inter->load16() * 2);
*valPtr = READ_VARO_UINT16(_vm->_inter->load16() * 2);
break;
case 18:
*valPtr = *(int8 *)(_vm->_global->_inter_variables + _vm->_inter->load16());
*valPtr = (int8) READ_VARO_UINT8(_vm->_inter->load16());
break;
case 19:
*valPtr = _vm->_inter->load16();
_vm->_global->_inter_execPtr += 2;
/* *valPtr = _vm->_inter->load16();
_vm->_global->_inter_execPtr += 2;*/
*valPtr = (uint16) READ_LE_UINT32(_vm->_global->_inter_execPtr);
_vm->_global->_inter_execPtr += 4;
break;
case 20:
@ -182,15 +185,19 @@ int16 Parse_v2::parseValExpr(unsigned stopToken) {
break;
case 23:
*valPtr = (uint16) VAR(_vm->_inter->load16());
break;
case 24:
*valPtr = *(uint16 *)(_vm->_global->_inter_variables + _vm->_inter->load16() * 4);
foo = _vm->_inter->load16();
*valPtr = READ_VARO_UINT16(foo * 4);
break;
case 25:
temp = _vm->_inter->load16() * 4;
_vm->_global->_inter_execPtr++;
temp += parseValExpr(12);
*valPtr = *(uint8 *)(_vm->_global->_inter_variables + temp);
*valPtr = READ_VARO_UINT8(temp);
break;
case 29:
@ -395,30 +402,30 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) {
offset = offset * arrDescPtr[dim] + temp2;
}
if (operation == 16)
*valPtr = *(int8 *)(_vm->_global->_inter_variables + temp + offset);
*valPtr = (int8) READ_VARO_UINT8(temp + offset);
else if (operation == 26)
*valPtr = *(uint32 *)(_vm->_global->_inter_variables + temp * 4 + offset * 4);
*valPtr = READ_VARO_UINT32(temp * 4 + offset * 4);
else if (operation == 27)
*valPtr = *(int16 *)(_vm->_global->_inter_variables + temp * 2 + offset * 2);
*valPtr = (int16) READ_VARO_UINT16(temp * 2 + offset * 2);
else if (operation == 28) {
*valPtr = encodePtr(_vm->_global->_inter_variables + temp * 4 + offset * _vm->_global->_inter_animDataSize * 4, kInterVar);
if (*_vm->_global->_inter_execPtr == 13) {
_vm->_global->_inter_execPtr++;
temp2 = parseValExpr(12);
*operPtr = 20;
*valPtr = *(uint8 *)(_vm->_global->_inter_variables + temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
*valPtr = READ_VARO_UINT8(temp * 4 + offset * 4 * _vm->_global->_inter_animDataSize + temp2);
}
}
break;
case 17:
*operPtr = 20;
*valPtr = *(int16 *)(_vm->_global->_inter_variables + _vm->_inter->load16() * 2);
*valPtr = (int16) READ_VARO_UINT16(_vm->_inter->load16() * 2);
break;
case 18:
*operPtr = 20;
*valPtr = *(int8 *)(_vm->_global->_inter_variables + _vm->_inter->load16());
*valPtr = (int8) READ_VARO_UINT8(_vm->_inter->load16());
break;
case 19:
@ -450,7 +457,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) {
case 24:
*operPtr = 20;
*valPtr = *(int16 *)(_vm->_global->_inter_variables + _vm->_inter->load16() * 4);
*valPtr = (int16) READ_VARO_UINT16(_vm->_inter->load16() * 4);
break;
case 25:
@ -461,7 +468,7 @@ int16 Parse_v2::parseExpr(char stopToken, byte *arg_2) {
_vm->_global->_inter_execPtr++;
temp += parseValExpr(12);
*operPtr = 20;
*valPtr = *(uint8 *)(_vm->_global->_inter_variables + temp);
*valPtr = READ_VARO_UINT8(temp);
}
break;