aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTravis Howell2004-08-28 03:18:52 +0000
committerTravis Howell2004-08-28 03:18:52 +0000
commit22fb004e209f837b86231ec213a07ad7e7b90ec5 (patch)
tree53f797b31e08c781109c4ea12adf9979906718e7
parent13b6cf7c67dce13c1d457d58ecee20345c83e8e2 (diff)
downloadscummvm-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.cpp3
-rw-r--r--scumm/akos.cpp136
-rw-r--r--scumm/debugger.cpp11
-rw-r--r--scumm/intern.h1
-rw-r--r--scumm/resource.cpp12
-rw-r--r--scumm/script.cpp4
-rw-r--r--scumm/script_v72he.cpp28
-rw-r--r--scumm/script_v7he.cpp31
-rw-r--r--scumm/scumm.cpp13
-rw-r--r--scumm/scumm.h7
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);