diff options
author | Travis Howell | 2004-08-28 03:18:52 +0000 |
---|---|---|
committer | Travis Howell | 2004-08-28 03:18:52 +0000 |
commit | 22fb004e209f837b86231ec213a07ad7e7b90ec5 (patch) | |
tree | 53f797b31e08c781109c4ea12adf9979906718e7 | |
parent | 13b6cf7c67dce13c1d457d58ecee20345c83e8e2 (diff) | |
download | scummvm-rg350-22fb004e209f837b86231ec213a07ad7e7b90ec5.tar.gz scummvm-rg350-22fb004e209f837b86231ec213a07ad7e7b90ec5.tar.bz2 scummvm-rg350-22fb004e209f837b86231ec213a07ad7e7b90ec5.zip |
akos should queue commmands and executate after drawing costumes (Caused race issues in HE games).
Remove some duplciate code
Enable from HE games
Add a few stubs for some additional akos codes
svn-id: r14799
-rw-r--r-- | scumm/actor.cpp | 3 | ||||
-rw-r--r-- | scumm/akos.cpp | 136 | ||||
-rw-r--r-- | scumm/debugger.cpp | 11 | ||||
-rw-r--r-- | scumm/intern.h | 1 | ||||
-rw-r--r-- | scumm/resource.cpp | 12 | ||||
-rw-r--r-- | scumm/script.cpp | 4 | ||||
-rw-r--r-- | scumm/script_v72he.cpp | 28 | ||||
-rw-r--r-- | scumm/script_v7he.cpp | 31 | ||||
-rw-r--r-- | scumm/scumm.cpp | 13 | ||||
-rw-r--r-- | scumm/scumm.h | 7 |
10 files changed, 148 insertions, 98 deletions
diff --git a/scumm/actor.cpp b/scumm/actor.cpp index 0e81f7062a..eb8a66f44e 100644 --- a/scumm/actor.cpp +++ b/scumm/actor.cpp @@ -962,6 +962,9 @@ void ScummEngine::processActors() { } delete [] actors; + + if (_features & GF_NEW_COSTUMES) + akos_processQueue(); } // Used in Scumm v8, to allow the verb coin to be drawn over the inventory diff --git a/scumm/akos.cpp b/scumm/akos.cpp index 38879636a3..31054c01e1 100644 --- a/scumm/akos.cpp +++ b/scumm/akos.cpp @@ -29,6 +29,8 @@ #include "scumm/imuse_digi/dimuse.h" #include "scumm/sound.h" +#include "common/util.h" + namespace Scumm { #if !defined(__GNUC__) @@ -59,6 +61,7 @@ enum AkosOpcodes { AKC_SetVar = 0xC010, AKC_CmdQue3 = 0xC015, AKC_ComplexChan = 0xC020, + AKC_Unk3 = 0xC021, AKC_Unk2 = 0xC025, AKC_Jump = 0xC030, AKC_JumpIfSet = 0xC031, @@ -96,6 +99,7 @@ enum AkosOpcodes { AKC_SkipG = 0xC094, AKC_SkipGE = 0xC095, AKC_ClearFlag = 0xC09F, + AKC_Unk4 = 0xC0A1, AKC_EndSeq = 0xC0FF }; @@ -282,6 +286,9 @@ byte AkosRenderer::drawLimb(const CostumeData &cost, int limb) { if (code == AKC_Return || code == AKC_EndSeq) return 0; + if (code == 0xC025) + error("akos_drawLimb: unsupported case %x", code); + if (code != AKC_ComplexChan) { off = akof + (code & 0xFFF); @@ -1163,6 +1170,7 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const case AKC_Flip: case AKC_Jump: case AKC_StartAnimInActor: + case AKC_Unk4: curpos += 4; break; case AKC_ComplexChan: @@ -1173,10 +1181,14 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const curpos += (aksq[curpos] & 0x80) ? 2 : 1; } break; + case AKC_Unk3: + curpos += aksq[curpos + 2]; + break; default: if ((code & 0xC000) == 0xC000) error("akos_increaseAnim: invalid code %x", code); curpos += (code & 0x8000) ? 2 : 1; + break; } break; case 2: @@ -1296,6 +1308,7 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const case AKC_ComplexChan: case AKC_Unk1: case AKC_Unk2: + case AKC_Unk3: break; case AKC_Cmd3: @@ -1314,6 +1327,9 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const flag_value = true; continue; + case AKC_Unk4: + curpos = GUW(2); + break; default: if ((code & 0xC000) == 0xC000) error("Undefined uSweat token %X", code); @@ -1332,56 +1348,84 @@ bool ScummEngine::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const } void ScummEngine::akos_queCommand(byte cmd, Actor *a, int param_1, int param_2) { - switch (cmd) { - case 1: - a->putActor(0, 0, 0); - break; - case 2: - warning("unimplemented akos_queCommand(2,%d,%d,%d)", a->number, param_1, param_2); - // start script token in actor - break; - case 3: - if (param_1 != 0) { - if (_features & GF_DIGI_IMUSE) - _imuseDigital->startSfx(param_1, 63); - else - _sound->addSoundToQueue(param_1); - } - break; - case 4: - a->startAnimActor(param_1); - break; - case 5: - a->forceClip = param_1; - break; - case 6: - a->offs_x = param_1; - a->offs_y = param_2; - break; - case 7: - if (param_1 != 0) { - if (_imuseDigital) { - _imuseDigital->setVolume(param_1, param_2); + if (_queuePos > 32) + error("overflow"); +; + _queuePos++; + _queueCmd[_queuePos] = cmd; + _queueActor[_queuePos] = a->number; + _queueParam1[_queuePos] = param_1; + _queueParam2[_queuePos] = param_2; + + + warning("_queuePos %d", _queuePos); +} + + + +void ScummEngine::akos_processQueue() { + byte cmd; + int actor, param_1, param_2; + + while (_queuePos) { + cmd = _queueCmd[_queuePos]; + actor = _queueActor[_queuePos]; + param_1 = _queueParam1[_queuePos]; + param_2 = _queueParam2[_queuePos]; + _queuePos--; + + Actor *a = derefActor(actor, "akos_processQueue"); + + switch (cmd) { + case 1: + a->putActor(0, 0, 0); + break; + case 2: + warning("unimplemented akos_queCommand(2,%d,%d,%d)", a->number, param_1, param_2); + // start script token in actor + break; + case 3: + if (param_1 != 0) { + if (_features & GF_DIGI_IMUSE) + _imuseDigital->startSfx(param_1, 63); + else + _sound->addSoundToQueue(param_1); } - } - break; - case 8: - if (param_1 != 0) { - if (_imuseDigital) { - _imuseDigital->setPan(param_1, param_2); + break; + case 4: + a->startAnimActor(param_1); + break; + case 5: + a->forceClip = param_1; + break; + case 6: + a->offs_x = param_1; + a->offs_y = param_2; + break; + case 7: + if (param_1 != 0) { + if (_imuseDigital) { + _imuseDigital->setVolume(param_1, param_2); + } } - } - break; - case 9: - if (param_1 != 0) { - if (_imuseDigital) { - _imuseDigital->setPriority(param_1, param_2); + break; + case 8: + if (param_1 != 0) { + if (_imuseDigital) { + _imuseDigital->setPan(param_1, param_2); + } } + break; + case 9: + if (param_1 != 0) { + if (_imuseDigital) { + _imuseDigital->setPriority(param_1, param_2); + } + } + break; + default: + warning("akos_queCommand(%d,%d,%d,%d)", cmd, a->number, param_1, param_2); } - break; - - default: - warning("akos_queCommand(%d,%d,%d,%d)", cmd, a->number, param_1, param_2); } } diff --git a/scumm/debugger.cpp b/scumm/debugger.cpp index 896afb27d0..17df7b036f 100644 --- a/scumm/debugger.cpp +++ b/scumm/debugger.cpp @@ -364,7 +364,7 @@ bool ScummDebugger::Cmd_PrintScript(int argc, const char **argv) { bool ScummDebugger::Cmd_Actor(int argc, const char **argv) { Actor *a; int actnum; - int value = 0; + int value = 0, value2 = 0; if (argc < 3) { DebugPrintf("Syntax: actor <actornum> <command> <parameter>\n"); @@ -380,8 +380,15 @@ bool ScummDebugger::Cmd_Actor(int argc, const char **argv) { a = &_vm->_actors[actnum]; if (argc > 3) value = atoi(argv[3]); + if (argc > 4) + value2 = atoi(argv[4]); - if (!strcmp(argv[2], "ignoreboxes")) { + if (!strcmp(argv[2], "animvar")) { + + a->setAnimVar(value, value2); + DebugPrintf("Actor[%d].animVar[%d] = %d\n", actnum, value, a->getAnimVar(value)); + + } else if (!strcmp(argv[2], "ignoreboxes")) { a->ignoreBoxes = (value > 0); DebugPrintf("Actor[%d].ignoreBoxes = %d\n", actnum, a->ignoreBoxes); } else if (!strcmp(argv[2], "x")) { diff --git a/scumm/intern.h b/scumm/intern.h index 74ae480c74..d6856e572b 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -711,7 +711,6 @@ protected: void o72_getPixel(); void o72_pickVarRandom(); void o72_redimArray(); - void o72_stringLen(); void o72_readINI(); void o72_unknownF4(); void o72_unknownF8(); diff --git a/scumm/resource.cpp b/scumm/resource.cpp index 0b542b9d91..cfc491e63e 100644 --- a/scumm/resource.cpp +++ b/scumm/resource.cpp @@ -992,19 +992,17 @@ int ScummEngine::readSoundResource(int type, int idx) { total_size = _fileHandle.readUint32BE(); _fileHandle.read(createResource(type, idx, total_size), total_size - 8); return 1; + } else if (basetag == MKID('HDHS')) { + _fileHandle.seek(-12, SEEK_CUR); + total_size = _fileHandle.readUint32BE(); + _fileHandle.read(createResource(type, idx, total_size), total_size - 8); + return 1; } else if (basetag == MKID('TALK')) { - debugC(DEBUG_SOUND, "Found base tag TALK in sound %d, size %d", idx, total_size); - debugC(DEBUG_SOUND, "It was at position %d", _fileHandle.pos()); - _fileHandle.seek(-12, SEEK_CUR); total_size = _fileHandle.readUint32BE(); _fileHandle.read(createResource(type, idx, total_size), total_size - 8); return 1; } else if (basetag == MKID('DIGI')) { - // Use in Putt-Putt Demo - debugC(DEBUG_SOUND, "Found base tag DIGI in sound %d, size %d", idx, total_size); - debugC(DEBUG_SOUND, "It was at position %d", _fileHandle.pos()); - _fileHandle.seek(-12, SEEK_CUR); total_size = _fileHandle.readUint32BE(); _fileHandle.read(createResource(type, idx, total_size), total_size - 8); diff --git a/scumm/script.cpp b/scumm/script.cpp index d33bfb5069..a53053eb18 100644 --- a/scumm/script.cpp +++ b/scumm/script.cpp @@ -516,7 +516,7 @@ int ScummEngine::readVar(uint var) { } if (var & 0x8000) { - if (_gameId == GID_PAJAMA) { + if (_gameId == GID_PAJAMA || _gameId == GID_WATER) { var &= 0xFFF; checkRange(_numRoomVariables - 1, 0, var, "Room variable %d out of range(w)"); return _roomVars[var]; @@ -599,7 +599,7 @@ void ScummEngine::writeVar(uint var, int value) { } if (var & 0x8000) { - if (_gameId == GID_PAJAMA) { + if (_gameId == GID_PAJAMA || _gameId == GID_WATER) { var &= 0xFFF; checkRange(_numRoomVariables - 1, 0, var, "Room variable %d out of range(w)"); _roomVars[var] = value; diff --git a/scumm/script_v72he.cpp b/scumm/script_v72he.cpp index 9f62462a9e..78275dd12a 100644 --- a/scumm/script_v72he.cpp +++ b/scumm/script_v72he.cpp @@ -343,7 +343,7 @@ void ScummEngine_v72he::setupOpcodes() { /* EC */ OPCODE(o6_invalid), OPCODE(o6_invalid), - OPCODE(o72_stringLen), + OPCODE(o7_stringLen), OPCODE(o6_invalid), /* F0 */ OPCODE(o6_invalid), @@ -1142,24 +1142,6 @@ void ScummEngine_v72he::redimArray(int arrayId, int newDim2start, int newDim2end } -void ScummEngine_v72he::o72_stringLen() { - int a, len; - byte *addr; - - a = pop(); - - addr = getStringAddress(a); - if (!addr) { - // FIXME: should be error here - warning("o72_stringLen: Reference to zeroed array pointer (%d)", a); - push(0); - return; - } - - len = strlen((char *)getStringAddress(a)); - push(len); -} - void ScummEngine_v72he::o72_readINI() { byte name[100]; int type; @@ -1185,16 +1167,22 @@ void ScummEngine_v72he::o72_readINI() { void ScummEngine_v72he::o72_unknownF4() { byte b; + byte name[256], name2[1024]; + b = fetchScriptByte(); switch (b) { case 6: pop(); + copyScriptString(name); break; + warning("o72_unknownF4 stub (%s)", name); case 7: + copyScriptString(name2); + copyScriptString(name); + warning("o72_unknownF4 stub (%s, %s)", name, name2); break; } - warning("o72_unknownF4 stub"); } void ScummEngine_v72he::o72_unknownFA() { diff --git a/scumm/script_v7he.cpp b/scumm/script_v7he.cpp index 7b361eb3c2..9b50528888 100644 --- a/scumm/script_v7he.cpp +++ b/scumm/script_v7he.cpp @@ -41,12 +41,6 @@ namespace Scumm { -// Compatibility notes: -// -// FREDDEMO (freddemo) -// stringLen is completely different -// unknownF4 is completely different - #define OPCODE(x) { &ScummEngine_v7he::x, #x } void ScummEngine_v7he::setupOpcodes() { @@ -421,9 +415,14 @@ void ScummEngine_v7he::o7_cursorCommand() { switch (subOp) { case 0x13: // HE 7.2 (Not all games) case 0x14: - // Maybe load cursor image + // Loads cursors from another resource + // Use old cursors for now a = pop(); - warning("o7_cursorCommand: case %d (%d)", subOp, a); + if (a == 2) + _Win32ResExtractor->setCursor(102); + else if (a == 5) + _Win32ResExtractor->setCursor(103); + debug(1, "o7_cursorCommand: case %x (%d)", subOp, a); break; case 0x90: // SO_CURSOR_ON Turn cursor on _cursor.state = 1; @@ -718,20 +717,16 @@ void ScummEngine_v7he::o7_quitPauseRestart() { } void ScummEngine_v7he::o7_stringLen() { - int a, len; + int id, len; byte *addr; - a = pop(); + id = pop(); - addr = getStringAddress(a); - if (!addr) { - // FIXME: should be error here - warning("o7_stringLen: Reference to zeroed array pointer (%d)", a); - push(0); - return; - } + addr = getStringAddress(id); + if (!addr) + error("o72_stringLen: Reference to zeroed array pointer (%d)", id); - len = stringLen(addr); + len = strlen((char *)getStringAddress(id)); push(len); } diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 0b032ae914..84c7cc12b4 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -277,7 +277,6 @@ static const ScummGameSettings scumm_settings[] = { {"pajama", "Pajama Sam 1: No Need to Hide When It's Dark Outside", GID_PAJAMA, 6, 72, MDT_NONE, GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0}, -#ifdef HEGAMES // Humongous Entertainment Scumm Version 9.0 ? Scummsys.90 {"kinddemo", "Big Thinkers Kindergarten (Demo)", GID_PAJAMA, 6, 90, MDT_NONE, GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0}, @@ -304,6 +303,7 @@ static const ScummGameSettings scumm_settings[] = { {"chase", "Spy Fox in Cheese Chase Game", GID_HEGAME, 6, 90, MDT_NONE, GF_NEW_OPCODES | GF_USE_KEY | GF_HUMONGOUS | GF_NEW_COSTUMES, 0, 0}, +#ifdef HEGAMES // Humongous Entertainment Scumm Version 9.8 ? Scummsys.98 // these and later games can easily be identified by the .(a) file instead of a .he1 // and INIB chunk in the .he0 @@ -659,6 +659,12 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS _heSndSoundFreq = 0; memset(_timers, 0, sizeof(_timers)); + memset(_queueCmd, 0, sizeof(_queueCmd)); + memset(_queueActor, 0, sizeof(_queueActor)); + memset(_queueParam1, 0, sizeof(_queueParam1)); + memset(_queueParam2, 0, sizeof(_queueParam2)); + _queuePos = 0; + // // Init all VARS to 0xFF // @@ -1367,8 +1373,11 @@ void ScummEngine::initScummVars() { } else if (_version >= 7) { VAR(VAR_V6_EMSSPACE) = 10000; VAR(VAR_NUM_GLOBAL_OBJS) = _numGlobalObjects - 1; - } else if (_heversion >= 72) { + } else if (_heversion >= 71) { // TODO + + // Set amount of sound channels + VAR(9) = 8; } else { VAR(VAR_CURRENTDRIVE) = 0; switch (_midiDriver) { diff --git a/scumm/scumm.h b/scumm/scumm.h index 3bf455fa27..b68608896e 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -840,9 +840,16 @@ public: int cost_frameToAnim(Actor *a, int frame); // Akos Class + int16 _queueCmd[32]; + int16 _queueActor[32]; + int16 _queueParam1[32]; + int16 _queueParam2[32]; + int16 _queuePos; + bool akos_increaseAnims(const byte *akos, Actor *a); bool akos_increaseAnim(Actor *a, int i, const byte *aksq, const uint16 *akfo, int numakfo); void akos_queCommand(byte cmd, Actor *a, int param_1, int param_2); + void akos_processQueue(); void akos_decodeData(Actor *a, int frame, uint usemask); int akos_frameToAnim(Actor *a, int frame); bool akos_hasManyDirections(int costume); |