aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSven Hesse2006-02-24 21:58:03 +0000
committerSven Hesse2006-02-24 21:58:03 +0000
commitca504aca4fc270b277297973a2ce459c998192c5 (patch)
tree94139c847d243700024a0af6f4e3e6e46817603a
parent4aaf6fec8d26f5f8a78c674b50464b3956d49002 (diff)
downloadscummvm-rg350-ca504aca4fc270b277297973a2ce459c998192c5.tar.gz
scummvm-rg350-ca504aca4fc270b277297973a2ce459c998192c5.tar.bz2
scummvm-rg350-ca504aca4fc270b277297973a2ce459c998192c5.zip
Adding GOB2's CD handling opcodes, the CD version of GOB2 now starts
correctly; playMult() doesn't work yet, though svn-id: r20844
-rw-r--r--engines/gob/game.cpp32
-rw-r--r--engines/gob/game.h5
-rw-r--r--engines/gob/inter.h15
-rw-r--r--engines/gob/inter_v1.cpp27
-rw-r--r--engines/gob/inter_v2.cpp279
-rw-r--r--engines/gob/mult.h5
-rw-r--r--engines/gob/mult_v1.cpp7
-rw-r--r--engines/gob/mult_v2.cpp18
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