Adding GOB2's CD handling opcodes, the CD version of GOB2 now starts

correctly; playMult() doesn't work yet, though

svn-id: r20844
This commit is contained in:
Sven Hesse 2006-02-24 21:58:03 +00:00
parent 4aaf6fec8d
commit ca504aca4f
8 changed files with 309 additions and 85 deletions

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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];
result = evalExpr(NULL);
strcpy(str, _vm->_global->_inter_resStr);
int16 Inter_v2::loadSound(int16 search) {
int16 id;
int16 slot;
/* int i;
int8 var_7;
char *pointer;
char sndfile[14];
warning("STUB: Gob2 drawOperation 0x23 (%d, \"%s\")", result, str);
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;*/
/* char *dataPtr;
int16 id;
if (slot == -1)
slot = _vm->_parse->parseValExpr();
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;
index = load16();
if (_vm->_draw->_spritesArray[index] == 0)
return false;
_vm->_draw->freeSprite(index);
return false;
}
void Inter_v2::o2_loadCurLayer(void) {
_vm->_scenery->_curStatic = _vm->_parse->parseValExpr();
_vm->_scenery->_curStaticLayer = _vm->_parse->parseValExpr();
}
void Inter_v2::o2_playCDTrack(void) {
if ((_vm->_draw->_renderFlags & 0x200) == 0)
_vm->_draw->blitInvalidated();
evalExpr(NULL);
_vm->_cdrom->startTrack(_vm->_global->_inter_resStr);
}
void Inter_v2::o2_stopCD(void) {
_vm->_cdrom->stopPlaying();
}
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_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

View File

@ -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);
};

View File

@ -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

View File

@ -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