From ca504aca4fc270b277297973a2ce459c998192c5 Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 24 Feb 2006 21:58:03 +0000 Subject: Adding GOB2's CD handling opcodes, the CD version of GOB2 now starts correctly; playMult() doesn't work yet, though svn-id: r20844 --- engines/gob/game.cpp | 32 ------ engines/gob/game.h | 5 +- engines/gob/inter.h | 15 ++- engines/gob/inter_v1.cpp | 27 ++++- engines/gob/inter_v2.cpp | 279 ++++++++++++++++++++++++++++++++++++++++------- engines/gob/mult.h | 5 +- engines/gob/mult_v1.cpp | 7 +- engines/gob/mult_v2.cpp | 18 ++- 8 files changed, 306 insertions(+), 82 deletions(-) diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index 929855f7b9..d48405a668 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -83,9 +83,6 @@ Game::Game(GobEngine *vm) : _vm(vm) { _curImaFile[0] = 0; _soundFromExt[0] = 0; _collStr[0] = 0; - - - // Capture } char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight) { @@ -409,35 +406,6 @@ void Game::loadSound(int16 slot, char *dataPtr) { soundDesc->flag = 0; } -void Game::interLoadSound(int16 slot) { - char *dataPtr; - int16 id; - - if (slot == -1) - slot = _vm->_parse->parseValExpr(); - - id = _vm->_inter->load16(); - if (id == -1) { - _vm->_global->_inter_execPtr += 9; - return; - } - - if (id >= 30000) { - dataPtr = loadExtData(id, 0, 0); - _soundFromExt[slot] = 1; - } else { - dataPtr = loadTotResource(id); - _soundFromExt[slot] = 0; - } - - if (_vm->_features & Gob::GF_GOB2) { - warning("STUB: interLoadSound()"); - return; - } - - loadSound(slot, dataPtr); -} - void Game::freeSoundSlot(int16 slot) { if (slot == -1) slot = _vm->_parse->parseValExpr(); diff --git a/engines/gob/game.h b/engines/gob/game.h index f1548d4386..3b81163853 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -115,6 +115,8 @@ public: int32 _startTimeKey; int16 _mouseButtons; + char _soundFromExt[20]; + Game(GobEngine *vm); char *loadExtData(int16 dataId, int16 *pResWidth, int16 *pResHeight); @@ -123,7 +125,6 @@ public: void capturePush(int16 left, int16 top, int16 width, int16 height); void capturePop(char doDraw); - void interLoadSound(int16 slot); void freeSoundSlot(int16 slot); int16 checkKeys(int16 *pMousex, int16 *pMouseY, int16 *pButtons, char handleMouse); @@ -167,8 +168,6 @@ protected: int16 _collStackSize; int16 _collStackElemSizes[3]; - char _soundFromExt[20]; - char _shouldPushColls; // Capture diff --git a/engines/gob/inter.h b/engines/gob/inter.h index 7649e73984..bdb6c900c8 100644 --- a/engines/gob/inter.h +++ b/engines/gob/inter.h @@ -61,6 +61,7 @@ public: void initControlVars(void); void renewTimeInVars(void); void manipulateMap(int16 xPos, int16 yPos, int16 item); + virtual int16 loadSound(int16 slot) = 0; Inter(GobEngine *vm); virtual ~Inter() {}; @@ -81,6 +82,7 @@ class Inter_v1 : public Inter { public: Inter_v1(GobEngine *vm); virtual ~Inter_v1() {}; + virtual int16 loadSound(int16 slot); protected: typedef void (Inter_v1::*OpcodeDrawProcV1)(void); @@ -269,6 +271,7 @@ class Inter_v2 : public Inter_v1 { public: Inter_v2(GobEngine *vm); virtual ~Inter_v2() {}; + virtual int16 loadSound(int16 search); protected: typedef void (Inter_v2::*OpcodeDrawProcV2)(void); @@ -301,14 +304,20 @@ protected: void o2_drawStub(void) { warning("Gob2 stub"); } void o2_stub0x80(void); - void o2_stub0x23(void); bool o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag); bool o2_palLoad(char &cmdCount, int16 &counter, int16 &retFlag); - void o2_setRenderFlags(void); bool o2_loadTot(char &cmdCount, int16 &counter, int16 &retFlag); - void o2_initMult(void); bool o2_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag); + bool o2_loadSound(char &cmdCount, int16 &counter, int16 &retFlag); + void o2_setRenderFlags(void); + void o2_initMult(void); void o2_loadCurLayer(void); + void o2_playCDTrack(void); + void o2_stopCD(void); + void o2_readLIC(void); + void o2_freeLIC(void); + void o2_getCDTrackPos(void); + void o2_playMult(void); }; } // End of namespace Gob diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 8e32e766db..1022d2cf48 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -1973,7 +1973,7 @@ bool Inter_v1::o1_setBackDelta(char &cmdCount, int16 &counter, int16 &retFlag) { } bool Inter_v1::o1_loadSound(char &cmdCount, int16 &counter, int16 &retFlag) { - _vm->_game->interLoadSound(-1); + loadSound(-1); return false; } @@ -2689,4 +2689,29 @@ void Inter_v1::o1_initGoblin(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Obj _vm->_util->beep(50); } +int16 Inter_v1::loadSound(int16 slot) { + char *dataPtr; + int16 id; + + if (slot == -1) + slot = _vm->_parse->parseValExpr(); + + id = load16(); + if (id == -1) { + _vm->_global->_inter_execPtr += 9; + return 0; + } + + if (id >= 30000) { + dataPtr = _vm->_game->loadExtData(id, 0, 0); + _vm->_game->_soundFromExt[slot] = 1; + } else { + dataPtr = _vm->_game->loadTotResource(id); + _vm->_game->_soundFromExt[slot] = 0; + } + + _vm->_game->loadSound(slot, dataPtr); + return 0; +} + } // End of namespace Gob diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index c698229f8d..0fee8b4331 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -120,7 +120,7 @@ void Inter_v2::setupOpcodes(void) { static const OpcodeDrawEntryV2 opcodesDraw[256] = { /* 00 */ OPCODE(o1_loadMult), - OPCODE(o1_playMult), + OPCODE(o2_playMult), OPCODE(o1_freeMult), {NULL, ""}, /* 04 */ @@ -159,13 +159,13 @@ void Inter_v2::setupOpcodes(void) { {NULL, ""}, {NULL, ""}, /* 20 */ + OPCODE(o2_playCDTrack), OPCODE(o2_drawStub), - OPCODE(o2_drawStub), - OPCODE(o2_drawStub), - OPCODE(o2_stub0x23), + OPCODE(o2_stopCD), + OPCODE(o2_readLIC), /* 24 */ - OPCODE(o2_drawStub), - OPCODE(o2_drawStub), + OPCODE(o2_freeLIC), + OPCODE(o2_getCDTrackPos), {NULL, ""}, {NULL, ""}, /* 28 */ @@ -514,7 +514,7 @@ void Inter_v2::setupOpcodes(void) { /* 38 */ OPCODE(o1_playSound), OPCODE(o1_stopSound), - OPCODE(o1_loadSound), + OPCODE(o2_loadSound), OPCODE(o1_freeSoundSlot), /* 3C */ OPCODE(o1_waitEndPlay), @@ -715,14 +715,156 @@ void Inter_v2::o2_stub0x80(void) { warning("STUB: Gob2 drawOperation 0x80 (%d %d)", expr1, expr2); } -void Inter_v2::o2_stub0x23(void) { - byte result; - char str[40]; +int16 Inter_v2::loadSound(int16 search) { + int16 id; + int16 slot; +/* int i; + int8 var_7; + char *pointer; + char sndfile[14]; + + char *dword_2EBF0[60]; + int16 word_2EAFE[60]; + int8 byte_2EB8A[60]; + + for (i = 0; i < 60; i++) + dword_2EBF0[i] = 0;*/ + + warning("STUB: loadSound()"); + + slot = 0; + if (search == 0) { + slot = _vm->_parse->parseValExpr(); + } + id = load16(); + +// warning("==> %d %d", slot, id); + + if (id == -1) + _vm->_global->_inter_execPtr += 9; + + return slot; + +/* var_7 = 0; + if (search == 0) { + slot = _vm->_parse->parseValExpr(); + if (slot < 0) { + var_7 = 1; + slot = -slot; + } + id = load16(); + } + else { + // loc_961D + id = load16(); + + for (slot = 0; slot < 60; slot++) + if ((dword_2EBF0[slot] != 0) && (word_2EAFE[slot] = id)) + return slot | 0x8000; + + for (slot = 59; slot >= 0; slot--) + if (dword_2EBF0[slot] == 0) break; + + } + + if (dword_2EBF0[slot] != 0) + _vm->_game->freeSoundSlot(slot); + + word_2EAFE[slot] = id; + + if (id == -1) { + strcpy(sndfile, _vm->_global->_inter_execPtr); + _vm->_global->_inter_execPtr += 9; + if (var_7 == 0) { + // loc_96EB + strcat(sndfile, ".SND"); +// dword_2EBF0[slot] = sub_1F5D0(sndfile); + } + else { + strcat(sndfile, ".ADL"); + dword_2EBF0[slot] = _vm->_dataio->getData(sndfile); + } + byte_2EB8A[slot] = 2; + // loc_969D + } + else { + // loc_9735 + if (id >= 30000) { + // loc_973E + if ((var_7 == 0) && + (_vm->_global->_soundFlags & 0x14) && + (_vm->_game->_totFileData[0x29] >= 51)) { + // loc_9763 + if (_vm->_global->_soundFlags & 0x14) { + // loc_976E +// var_E = new char[16]; + if (_vm->_inter->_terminate) + return slot; + pointer = _vm->_game->loadExtData(id, NULL, NULL); + if (pointer == NULL) { +// delete[] var_E; + return slot; + } + // loc_97C5 +// var_E->pointer = pointer+6; +// var_E->0x0C = pointer[4] << 8 + pointer[5]; + // ... +// dword_2EBF0[slot] = var_E; + delete[] pointer; + return slot; + } + else { + // loc_9A59 + return slot; + } + } + else { + // loc_99BC + pointer = _vm->_game->loadExtData(id, NULL, NULL); + // ... + delete[] pointer; + return slot; + } + } + else { + // loc_9A13 +// pointer = _vm->_game->loadTotResource(id); + return slot; + } + } + + if (var_7 != 0) + byte_2EB8A[slot] |= 8; + + if (dword_2EBF0[slot]) + delete[] dword_2EBF0[slot]; + + return slot;*/ - result = evalExpr(NULL); - strcpy(str, _vm->_global->_inter_resStr); +/* char *dataPtr; + int16 id; + + if (slot == -1) + slot = _vm->_parse->parseValExpr(); - warning("STUB: Gob2 drawOperation 0x23 (%d, \"%s\")", result, str); + id = load16(); + if (id == -1) { + _vm->_global->_inter_execPtr += 9; + return; + } + + if (id >= 30000) { + dataPtr = _vm->_game->loadExtData(id, 0, 0); + _vm->_game->_soundFromExt[slot] = 1; + } else { + dataPtr = _vm->_game->loadTotResource(id); + _vm->_game->_soundFromExt[slot] = 0; + } + + warning("STUB: loadSound()"); + return; + + _vm->_game->loadSound(slot, dataPtr);*/ } bool Inter_v2::o2_evaluateStore(char &cmdCount, int16 &counter, int16 &retFlag) { @@ -951,22 +1093,6 @@ bool Inter_v2::o2_palLoad(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } -void Inter_v2::o2_setRenderFlags(void) { - int16 expr; - - expr = _vm->_parse->parseValExpr(); - - if (expr & 0x8000) { - _vm->_draw->_renderFlags |= expr & 0x3fff; - } - else { - if (expr & 0x4000) - _vm->_draw->_renderFlags &= expr & 0x3fff; - else - _vm->_draw->_renderFlags = _vm->_parse->parseValExpr(); - } -} - bool Inter_v2::o2_loadTot(char &cmdCount, int16 &counter, int16 &retFlag) { char buf[20]; int8 size; @@ -996,6 +1122,39 @@ bool Inter_v2::o2_loadTot(char &cmdCount, int16 &counter, int16 &retFlag) { return false; } +bool Inter_v2::o2_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag) { + int16 index; + + index = load16(); + if (_vm->_draw->_spritesArray[index] == 0) + return false; + + _vm->_draw->freeSprite(index); + + return false; +} + +bool Inter_v2::o2_loadSound(char &cmdCount, int16 &counter, int16 &retFlag) { + loadSound(0); + return false; +} + +void Inter_v2::o2_setRenderFlags(void) { + int16 expr; + + expr = _vm->_parse->parseValExpr(); + + if (expr & 0x8000) { + _vm->_draw->_renderFlags |= expr & 0x3fff; + } + else { + if (expr & 0x4000) + _vm->_draw->_renderFlags &= expr & 0x3fff; + else + _vm->_draw->_renderFlags = _vm->_parse->parseValExpr(); + } +} + void Inter_v2::o2_initMult(void) { int16 oldAnimHeight; int16 oldAnimWidth; @@ -1112,21 +1271,63 @@ void Inter_v2::o2_initMult(void) { debug(4, " _vm->_mult->_objCount = %d, animation data size = %d", _vm->_mult->_objCount, _vm->_global->_inter_animDataSize); } -bool Inter_v2::o2_freeSprite(char &cmdCount, int16 &counter, int16 &retFlag) { - int16 index; +void Inter_v2::o2_loadCurLayer(void) { + _vm->_scenery->_curStatic = _vm->_parse->parseValExpr(); + _vm->_scenery->_curStaticLayer = _vm->_parse->parseValExpr(); +} - index = load16(); - if (_vm->_draw->_spritesArray[index] == 0) - return false; +void Inter_v2::o2_playCDTrack(void) { + if ((_vm->_draw->_renderFlags & 0x200) == 0) + _vm->_draw->blitInvalidated(); + evalExpr(NULL); + _vm->_cdrom->startTrack(_vm->_global->_inter_resStr); +} - _vm->_draw->freeSprite(index); +void Inter_v2::o2_stopCD(void) { + _vm->_cdrom->stopPlaying(); +} - return false; +void Inter_v2::o2_readLIC(void) { + byte result; + char path[40]; + + result = evalExpr(NULL); + strcpy(path, _vm->_global->_inter_resStr); + strcat(path, ".LIC"); + + _vm->_cdrom->readLIC(path); } -void Inter_v2::o2_loadCurLayer(void) { - _vm->_scenery->_curStatic = _vm->_parse->parseValExpr(); - _vm->_scenery->_curStaticLayer = _vm->_parse->parseValExpr(); +void Inter_v2::o2_freeLIC(void) { + _vm->_cdrom->freeLICbuffer(); +} + +void Inter_v2::o2_getCDTrackPos(void) { + int16 trackpospos; + int16 tracknamepos; + int32 trackpos; + + _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; + + WRITE_VAR(trackpospos >> 2, trackpos); +} + +void Inter_v2::o2_playMult(void) { + int16 checkEscape; + + checkEscape = load16(); + + _vm->_mult->setMultData(checkEscape >> 1); + _vm->_mult->playMult(VAR(57), -1, checkEscape & 0x1, 0); } } // End of namespace Gob diff --git a/engines/gob/mult.h b/engines/gob/mult.h index e67bfad3a8..d69ee3b6c1 100644 --- a/engines/gob/mult.h +++ b/engines/gob/mult.h @@ -187,6 +187,7 @@ public: void playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq, int16 channel); + virtual void setMultData(uint16 multindex) = 0; virtual void loadMult(int16 resId) = 0; Mult(GobEngine *vm); @@ -210,6 +211,7 @@ public: Mult_v1(GobEngine *vm); virtual ~Mult_v1() {}; + virtual void setMultData(uint16 multindex); virtual void loadMult(int16 resId); }; @@ -244,7 +246,7 @@ public: Mult_SndKey *sndKeys; int16 sndSlotsCount; - int16 sndSlot; + int16 sndSlot[60]; int16 frameRate; Video::Color fadePal[5][16]; @@ -274,6 +276,7 @@ public: Mult_v2(GobEngine *vm); virtual ~Mult_v2() {}; + virtual void setMultData(uint16 multindex); virtual void loadMult(int16 resId); }; diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index ee29c0b0d0..72328c42cf 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -26,6 +26,7 @@ #include "gob/game.h" #include "gob/scenery.h" #include "gob/global.h" +#include "gob/inter.h" namespace Gob { @@ -178,7 +179,7 @@ void Mult_v1::loadMult(int16 resId) { } } if (i == j) { - _vm->_game->interLoadSound(19 - _sndSlotsCount); + _vm->_inter->loadSound(19 - _sndSlotsCount); _sndKeys[i].soundIndex = 19 - _sndSlotsCount; _sndSlotsCount++; @@ -196,4 +197,8 @@ void Mult_v1::loadMult(int16 resId) { } } +void Mult_v1::setMultData(uint16 multindex) { + error("Switching mults not supported for Gob1"); +} + } // End of namespace Gob diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 087754f9a8..839649d1b2 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -181,7 +181,12 @@ void Mult_v2::loadMult(int16 resId) { _multData2->sndKeys = new Mult_SndKey[_multData2->sndKeysCount]; + warning("SoundKeyCount: %d", _multData2->sndKeysCount); + + // TODO: There's still something wrong here, preventing GOB2 floppy + // to start correctly for (i = 0; i < _multData2->sndKeysCount; i++) { + warning("-> %d", i); _multData2->sndKeys[i].frame = (int16)READ_LE_UINT16(_dataPtr); _multData2->sndKeys[i].cmd = (int16)READ_LE_UINT16(_dataPtr + 2); _multData2->sndKeys[i].freq = (int16)READ_LE_UINT16(_dataPtr + 4); @@ -213,9 +218,10 @@ void Mult_v2::loadMult(int16 resId) { if (i == j) { warning("GOB2 Stub! Mult_Data.sndSlot"); warning("GOB2 Stub! Game::interLoadSound() differs!"); - // _multData2->sndSlot[_multData2->sndSlotsCount] = _vm->_game->interLoadSound(1); + _multData2->sndSlot[_multData2->sndSlotsCount] = _vm->_inter->loadSound(1); + _vm->_inter->loadSound(1); // _multData2->sndKeys[i].soundIndex = _multData2->sndSlot[_multData2->sndSlotsCount] & 0x7FFF; - // _multData2->sndSlotsCount++; + _multData2->sndSlotsCount++; } break; @@ -260,4 +266,12 @@ void Mult_v2::loadMult(int16 resId) { delete[] extData; } +void Mult_v2::setMultData(uint16 multindex) { + if (multindex > 7) + error("Multindex out of range"); + + debug(4, "Switching to mult %d", multindex); + _multData2 = _multDatas[multindex]; +} + } // End of namespace Gob -- cgit v1.2.3