diff options
author | Sven Hesse | 2006-11-27 14:19:30 +0000 |
---|---|---|
committer | Sven Hesse | 2006-11-27 14:19:30 +0000 |
commit | 9afb08341c89d20f54de4b6c9efec69ab60fc79d (patch) | |
tree | 4a4ec7a00af1ff2cd88e0b328d69f2b5ec40cb49 /engines | |
parent | b2fb23a134d7f6486bef0922159fa747411d9f14 (diff) | |
download | scummvm-rg350-9afb08341c89d20f54de4b6c9efec69ab60fc79d.tar.gz scummvm-rg350-9afb08341c89d20f54de4b6c9efec69ab60fc79d.tar.bz2 scummvm-rg350-9afb08341c89d20f54de4b6c9efec69ab60fc79d.zip |
- 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
Diffstat (limited to 'engines')
-rw-r--r-- | engines/gob/cdrom.cpp | 4 | ||||
-rw-r--r-- | engines/gob/cdrom.h | 1 | ||||
-rw-r--r-- | engines/gob/draw_v1.cpp | 2 | ||||
-rw-r--r-- | engines/gob/draw_v2.cpp | 6 | ||||
-rw-r--r-- | engines/gob/game.cpp | 13 | ||||
-rw-r--r-- | engines/gob/game.h | 1 | ||||
-rw-r--r-- | engines/gob/game_v1.cpp | 19 | ||||
-rw-r--r-- | engines/gob/game_v2.cpp | 23 | ||||
-rw-r--r-- | engines/gob/global.cpp | 1 | ||||
-rw-r--r-- | engines/gob/global.h | 54 | ||||
-rw-r--r-- | engines/gob/gob.cpp | 348 | ||||
-rw-r--r-- | engines/gob/gob.h | 53 | ||||
-rw-r--r-- | engines/gob/goblin.cpp | 75 | ||||
-rw-r--r-- | engines/gob/goblin.h | 2 | ||||
-rw-r--r-- | engines/gob/init.cpp | 8 | ||||
-rw-r--r-- | engines/gob/inter.cpp | 1 | ||||
-rw-r--r-- | engines/gob/inter.h | 2 | ||||
-rw-r--r-- | engines/gob/inter_v1.cpp | 22 | ||||
-rw-r--r-- | engines/gob/inter_v2.cpp | 101 | ||||
-rw-r--r-- | engines/gob/map_v2.cpp | 8 | ||||
-rw-r--r-- | engines/gob/mult_v1.cpp | 3 | ||||
-rw-r--r-- | engines/gob/mult_v2.cpp | 3 | ||||
-rw-r--r-- | engines/gob/parse_v1.cpp | 8 | ||||
-rw-r--r-- | engines/gob/parse_v2.cpp | 43 |
24 files changed, 632 insertions, 169 deletions
diff --git a/engines/gob/cdrom.cpp b/engines/gob/cdrom.cpp index 1a21cf0b67..b12aac32b7 100644 --- a/engines/gob/cdrom.cpp +++ b/engines/gob/cdrom.cpp @@ -215,6 +215,10 @@ int32 CDROM::getTrackPos(void) { return -1; } +const char *CDROM::getCurTrack(void) { + return _curTrack; +} + void CDROM::stopPlaying(void) { stop(); diff --git a/engines/gob/cdrom.h b/engines/gob/cdrom.h index 582a4a553a..af178208f8 100644 --- a/engines/gob/cdrom.h +++ b/engines/gob/cdrom.h @@ -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); diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 2b3dcf313d..4628ef1f37 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -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; diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 6858e372d2..084e0cedb9 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -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; diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index e4c4b2fc2a..e73c544edf 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -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'; diff --git a/engines/gob/game.h b/engines/gob/game.h index 73d491afb1..f0c78d692e 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -169,6 +169,7 @@ public: char *_imFileDataArray[5]; char *_variablesArray[5]; char _curTotFileArray[5][14]; + byte *_variablesSizesArray[5]; Imd *_imdFile; char _curImdFile[15]; diff --git a/engines/gob/game_v1.cpp b/engines/gob/game_v1.cpp index fe1404dba7..590ecfa2a7 100644 --- a/engines/gob/game_v1.cpp +++ b/engines/gob/game_v1.cpp @@ -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; diff --git a/engines/gob/game_v2.cpp b/engines/gob/game_v2.cpp index 80dfa5c50f..b64c9629fb 100644 --- a/engines/gob/game_v2.cpp +++ b/engines/gob/game_v2.cpp @@ -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; diff --git a/engines/gob/global.cpp b/engines/gob/global.cpp index cceb0c7bed..972d7b79fd 100644 --- a/engines/gob/global.cpp +++ b/engines/gob/global.cpp @@ -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; diff --git a/engines/gob/global.h b/engines/gob/global.h index 1583e711c8..3dc1876090 100644 --- a/engines/gob/global.h +++ b/engines/gob/global.h @@ -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 diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp index f222414ae1..af08dc7cbd 100644 --- a/engines/gob/gob.cpp +++ b/engines/gob/gob.cpp @@ -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); + 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 - memcpy(oBuf + oOff, buf, size); + 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); diff --git a/engines/gob/gob.h b/engines/gob/gob.h index e13b959955..c90dde4592 100644 --- a/engines/gob/gob.h +++ b/engines/gob/gob.h @@ -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 diff --git a/engines/gob/goblin.cpp b/engines/gob/goblin.cpp index 04f5ce79b9..b6925d0358 100644 --- a/engines/gob/goblin.cpp +++ b/engines/gob/goblin.cpp @@ -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 diff --git a/engines/gob/goblin.h b/engines/gob/goblin.h index 3e3c6d803e..7e823bdae8 100644 --- a/engines/gob/goblin.h +++ b/engines/gob/goblin.h @@ -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; diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 375e849f62..89149a1112 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -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) diff --git a/engines/gob/inter.cpp b/engines/gob/inter.cpp index 09f8900f30..425b3e6df0 100644 --- a/engines/gob/inter.cpp +++ b/engines/gob/inter.cpp @@ -58,6 +58,7 @@ Inter::Inter(GobEngine *vm) : _vm(vm) { _nestLevel = 0; memset(_pasteBuf, 0, 300); + memset(_pasteSizeBuf, 0, 300); _pastePos = 0; } diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 5ecb57e91c..e438d8de43 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -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); diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 09b708a306..e9796c8380 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -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(); diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 7d01d4b145..66ebd8aa05 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -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) { diff --git a/engines/gob/map_v2.cpp b/engines/gob/map_v2.cpp index ac94b39b39..a9b7aca5fe 100644 --- a/engines/gob/map_v2.cpp +++ b/engines/gob/map_v2.cpp @@ -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); diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index f1be776f40..4e662ed714 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -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) { diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index c92aae8504..2fa3f44e70 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -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) { diff --git a/engines/gob/parse_v1.cpp b/engines/gob/parse_v1.cpp index 74660223c4..8d4b192b8e 100644 --- a/engines/gob/parse_v1.cpp +++ b/engines/gob/parse_v1.cpp @@ -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; diff --git a/engines/gob/parse_v2.cpp b/engines/gob/parse_v2.cpp index 5d600061a8..23cd980691 100644 --- a/engines/gob/parse_v2.cpp +++ b/engines/gob/parse_v2.cpp @@ -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; |