JANITORIAL: SCUMM: Improve readability of AKOS code

This is part of an on-going effort on my end to document the AKOS code, and fix strange stuff
such as integers being used as booleans, and variable_names instead of variableNames
This commit is contained in:
AndywinXp 2022-09-27 00:14:26 +02:00
parent 72463db407
commit 8f744954c3
6 changed files with 322 additions and 265 deletions

View File

@ -2674,7 +2674,7 @@ void Actor_v0::limbFrameCheck(int limb) {
_limbFrameRepeat[limb] = _limbFrameRepeatNew[limb];
// 0x25C3
_cost.active[limb] = ((V0CostumeLoader *)_vm->_costumeLoader)->getFrame(this, limb);
_cost.animType[limb] = ((V0CostumeLoader *)_vm->_costumeLoader)->getFrame(this, limb);
_cost.curpos[limb] = 0;
_needRedraw = true;
@ -2734,7 +2734,7 @@ void Actor::animateLimb(int limb, int f) {
size = _vm->getResourceDataSize(akfo) / 2;
while (f--) {
if (_cost.active[limb] != 0)
if (_cost.animType[limb] != AKAT_Empty)
((ScummEngine_v6 *)_vm)->akos_increaseAnim(this, limb, aksq, (const uint16 *)akfo, size);
}
@ -3816,7 +3816,7 @@ void Actor::saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsUint16LE(_walkdata.point3.x, VER(42));
s.syncAsUint16LE(_walkdata.point3.y, VER(42));
s.syncBytes(_cost.active, 16, VER(8));
s.syncBytes(_cost.animType, 16, VER(8));
s.syncAsUint16LE(_cost.stopped, VER(8));
s.syncArray(_cost.curpos, 16, Common::Serializer::Uint16LE, VER(8));
s.syncArray(_cost.start, 16, Common::Serializer::Uint16LE, VER(8));

View File

@ -27,7 +27,6 @@
#include "common/serializer.h"
#include "scumm/scumm.h"
namespace Scumm {
enum {
@ -47,7 +46,7 @@ enum MoveFlags {
};
struct CostumeData {
byte active[16];
byte animType[16];
uint16 animCounter;
byte soundCounter;
byte soundPos;
@ -65,7 +64,7 @@ struct CostumeData {
void reset() {
stopped = 0;
for (int i = 0; i < 16; i++) {
active[i] = 0;
animType[i] = 0; // AKAT_Empty
curpos[i] = start[i] = end[i] = frame[i] = 0xFFFF;
}
}

View File

@ -52,20 +52,28 @@ struct AkosOffset {
#include "common/pack-end.h" // END STRUCT PACKING
static bool akos_compare(int a, int b, byte cmd) {
static bool akosCompare(int a, int b, byte cmd) {
switch (cmd) {
case 0:
case AKC_IfVarEQJump:
case AKC_IfVarEQDo:
return a == b;
case 1:
case AKC_IfVarNEJump:
case AKC_IfVarNEDo:
return a != b;
case 2:
case AKC_IfVarLTJump:
case AKC_IfVarLTDo:
return a < b;
case 3:
case AKC_IfVarLEJump:
case AKC_IfVarLEDo:
return a <= b;
case 4:
case AKC_IfVarGTJump:
case AKC_IfVarGTDo:
return a > b;
default:
case AKC_IfVarGEJump:
case AKC_IfVarGEDo:
return a >= b;
default:
return false;
}
}
@ -120,15 +128,15 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
i = 0;
mask = READ_LE_UINT16(r); r += 2;
do {
if (mask & 0x8000) {
if (mask & AKC_ExtendWordBit) {
const uint8 *akst = akstPtr;
const uint8 *aksf = aksfPtr;
code = *r++;
if (usemask & 0x8000) {
if (usemask & AKC_ExtendWordBit) {
switch (code) {
case 1:
a->_cost.active[i] = 0;
a->_cost.animType[i] = AKAT_Empty;
a->_cost.frame[i] = frame;
a->_cost.end[i] = 0;
a->_cost.start[i] = 0;
@ -184,7 +192,7 @@ void AkosCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
}
}
a->_cost.active[i] = code;
a->_cost.animType[i] = code;
a->_cost.frame[i] = frame;
a->_cost.end[i] = start + len;
a->_cost.start[i] = start;
@ -318,17 +326,17 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
if (_skipLimbs)
return 0;
if (_vm->_game.heversion >= 70 && cost.active[limb] == 8)
if (_vm->_game.heversion >= 70 && cost.animType[limb] == AKAT_DeltaAnim)
return 0;
if (!cost.active[limb] || cost.stopped & (1 << limb))
if (!cost.animType[limb] || cost.stopped & (1 << limb))
return 0;
useCondMask = false;
p = aksq + cost.curpos[limb];
code = p[0];
if (code & 0x80)
if (code & AKC_ExtendBit)
code = READ_BE_UINT16(p);
if (_vm->_game.heversion >= 90)
@ -368,13 +376,13 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
_ymove -= (int16)READ_LE_UINT16(&costumeInfo->move_y);
switch (_codec) {
case 1:
case AKOS_BYLE_RLE_CODEC:
result |= codec1(xmoveCur, ymoveCur);
break;
case 5:
case AKOS_CDAT_RLE_CODEC:
result |= codec5(xmoveCur, ymoveCur);
break;
case 16:
case AKOS_RUN_MAJMIN_CODEC:
result |= codec16(xmoveCur, ymoveCur);
break;
default:
@ -393,7 +401,7 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
for (i = 0; i != extra; i++) {
code = p[4];
if (code & 0x80)
if (code & AKC_ExtendBit)
code = READ_BE_UINT16(p + 4);
off = akof + (code & 0xFFF);
@ -438,7 +446,7 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
}
}
p += (p[4] & 0x80) ? 6 : 5;
p += (p[4] & AKC_ExtendBit) ? 6 : 5;
if (decflag == 0)
continue;
@ -446,21 +454,21 @@ byte AkosRenderer::drawLimb(const Actor *a, int limb) {
if (_vm->_game.heversion >= 90) {
if (_vm->_game.heversion >= 99)
_shadow_mode = 0;
if (xmap && (shadowMask & 0x8000))
if (xmap && (shadowMask & AKC_ExtendWordBit))
_shadow_mode = 3;
}
switch (_codec) {
case 1:
case AKOS_BYLE_RLE_CODEC:
result |= codec1(xmoveCur, ymoveCur);
break;
case 5:
case AKOS_CDAT_RLE_CODEC:
result |= codec5(xmoveCur, ymoveCur);
break;
case 16:
case AKOS_RUN_MAJMIN_CODEC:
result |= codec16(xmoveCur, ymoveCur);
break;
case 32:
case AKOS_TRLE_CODEC:
result |= codec32(xmoveCur, ymoveCur);
break;
default:
@ -1291,7 +1299,6 @@ byte AkosCostumeLoader::increaseAnims(Actor *a) {
bool ScummEngine_v6::akos_increaseAnims(const byte *akos, Actor *a) {
const byte *aksq, *akfo;
int i;
uint size;
bool result;
@ -1301,35 +1308,35 @@ bool ScummEngine_v6::akos_increaseAnims(const byte *akos, Actor *a) {
size = getResourceDataSize(akfo) / 2;
result = false;
for (i = 0; i < 16; i++) {
if (a->_cost.active[i] != 0)
for (int i = 0; i < 16; i++) {
if (a->_cost.animType[i] != AKAT_Empty)
result |= akos_increaseAnim(a, i, aksq, (const uint16 *)akfo, size);
}
return result;
}
bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, const uint16 *akfo, int numakfo) {
byte active;
uint old_curpos, curpos, end;
byte animType;
uint startState, curState, endState;
uint code;
bool skipNextState, needRedraw;
int tmp, tmp2;
int counter, tmp2;
active = a->_cost.active[chan];
end = a->_cost.end[chan];
old_curpos = curpos = a->_cost.curpos[chan];
animType = a->_cost.animType[chan];
endState = a->_cost.end[chan];
startState = curState = a->_cost.curpos[chan];
skipNextState = false;
needRedraw = false;
do {
code = aksq[curpos];
if (code & 0x80)
code = READ_BE_UINT16(aksq + curpos);
code = aksq[curState];
if (code & AKC_ExtendBit)
code = READ_BE_UINT16(aksq + curState);
switch (active) {
case 6:
case 8:
switch (animType) {
case AKAT_AlwaysRun:
case AKAT_DeltaAnim:
switch (code) {
case AKC_IfVarGoTo:
case AKC_AddVar:
@ -1345,7 +1352,7 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_IfNotSoundInVarRunningGoTo:
case AKC_IfSoundRunningGoTo:
case AKC_IfNotSoundRunningGoTo:
curpos += 5;
curState += 5;
break;
case AKC_JumpToOffsetInVar:
case AKC_SetActorZClipping:
@ -1358,18 +1365,18 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_SoftSound:
case AKC_SoftVarSound:
case AKC_StartTalkieInVar:
curpos += 3;
curState += 3;
break;
case AKC_SoundStuff:
if (_game.heversion >= 61)
curpos += 6;
curState += 6;
else
curpos += 8;
curState += 8;
break;
case AKC_StartActionOn:
case AKC_SetActorVar:
case AKC_SetDrawOffs:
curpos += 6;
curState += 6;
break;
case AKC_EndOfIfDo:
case AKC_HideActor:
@ -1377,7 +1384,7 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_StartSound_SpecialCase:
case AKC_EmptyCel:
case AKC_EndSeq:
curpos += 2;
curState += 2;
break;
case AKC_IfVarGEJump:
case AKC_IfVarGTJump:
@ -1386,7 +1393,7 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_IfVarNEJump:
case AKC_IfVarEQJump:
case AKC_SetVarRandom:
curpos += 7;
curState += 7;
break;
case AKC_Flip:
case AKC_GoToState:
@ -1394,17 +1401,17 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_StartActorTalkie:
case AKC_IfTalkingGoTo:
case AKC_IfNotTalkingGoTo:
curpos += 4;
curState += 4;
break;
case AKC_RelativeOffsetDrawMany:
curpos += 4;
curState += 4;
// Fall through
case AKC_DrawMany:
curpos += 3;
tmp = aksq[curpos - 1];
while (--tmp >= 0) {
curpos += 4;
curpos += (aksq[curpos] & 0x80) ? 2 : 1;
curState += 3;
counter = aksq[curState - 1];
while (--counter >= 0) {
curState += 4;
curState += (aksq[curState] & AKC_ExtendBit) ? 2 : 1;
}
break;
case AKC_CondDrawMany:
@ -1413,34 +1420,37 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_SetVarToUserCondition:
case AKC_SetTalkCondition:
case AKC_SetVarToTalkCondition:
needRedraw = 1;
curpos += aksq[curpos + 2];
needRedraw = true;
curState += aksq[curState + 2];
break;
case AKC_DisplayAuxFrame:
akos_queCommand(7, a, GW(2), 0);
curpos += 4;
curState += 4;
break;
default:
curpos += (code & 0x8000) ? 2 : 1;
curState += (code & AKC_ExtendWordBit) ? 2 : 1;
break;
}
break;
case 2:
curpos += (code & 0x8000) ? 2 : 1;
if (curpos > end)
curpos = a->_cost.start[chan];
case AKAT_LoopLayer:
curState += (code & AKC_ExtendWordBit) ? 2 : 1;
if (curState > endState)
curState = a->_cost.start[chan];
break;
case 3:
if (curpos != end)
curpos += (code & 0x8000) ? 2 : 1;
case AKAT_RunLayer:
if (curState != endState)
curState += (code & AKC_ExtendWordBit) ? 2 : 1;
break;
case AKAT_UserConstant:
// Script controlled animation: do nothing
break;
default:
break;
}
code = aksq[curpos];
if (code & 0x80)
code = READ_BE_UINT16(aksq + curpos);
code = aksq[curState];
if (code & AKC_ExtendBit)
code = READ_BE_UINT16(aksq + curState);
if (skipNextState && code != AKC_EndOfIfDo)
continue;
@ -1459,8 +1469,8 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_IfVarLTJump:
case AKC_IfVarNEJump:
case AKC_IfVarEQJump:
if (akos_compare(a->getAnimVar(GB(4)), GW(5), code - AKC_ConditionalJumpStart) != 0) {
curpos = GUW(2);
if (akosCompare(a->getAnimVar(GB(4)), GW(5), code)) {
curState = GUW(2);
break;
}
continue;
@ -1478,11 +1488,11 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
continue;
case AKC_StartSound:
if (_game.heversion >= 61)
tmp = GB(2);
counter = GB(2);
else
tmp = GB(2) - 1;
if ((uint) tmp < 24)
akos_queCommand(3, a, a->_sound[tmp], 0);
counter = GB(2) - 1;
if ((uint) counter < 24)
akos_queCommand(3, a, a->_sound[counter], 0);
continue;
case AKC_StartSound_SpecialCase:
akos_queCommand(3, a, a->_sound[0], 0);
@ -1505,13 +1515,13 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_SoundStuff:
if (_game.heversion >= 61)
continue;
tmp = GB(2) - 1;
if (tmp >= 8)
counter = GB(2) - 1;
if (counter >= 8)
continue;
tmp2 = GB(4);
if (tmp2 < 1 || tmp2 > 3)
error("akos_increaseAnim:8 invalid code %d", tmp2);
akos_queCommand(tmp2 + 6, a, a->_sound[tmp], GB(6));
akos_queCommand(tmp2 + 6, a, a->_sound[counter], GB(6));
continue;
case AKC_SetDrawOffs:
akos_queCommand(6, a, GW(2), GW(4));
@ -1519,22 +1529,22 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_JumpToOffsetInVar:
if (akfo == nullptr)
error("akos_increaseAnim: no AKFO table");
tmp = a->getAnimVar(GB(2)) - 1;
counter = a->getAnimVar(GB(2)) - 1;
if (_game.heversion >= 80) {
if (tmp < 0 || tmp > a->_cost.heJumpCountTable[chan] - 1)
error("akos_increaseAnim: invalid jump value %d", tmp);
curpos = READ_LE_UINT16(akfo + a->_cost.heJumpOffsetTable[chan] + tmp * 2);
if (counter < 0 || counter > a->_cost.heJumpCountTable[chan] - 1)
error("akos_increaseAnim: invalid jump value %d", counter);
curState = READ_LE_UINT16(akfo + a->_cost.heJumpOffsetTable[chan] + counter * 2);
} else {
if (tmp < 0 || tmp > numakfo - 1)
error("akos_increaseAnim: invalid jump value %d", tmp);
curpos = READ_LE_UINT16(&akfo[tmp]);
if (counter < 0 || counter > numakfo - 1)
error("akos_increaseAnim: invalid jump value %d", counter);
curState = READ_LE_UINT16(&akfo[counter]);
}
break;
case AKC_IfVarGoTo:
if (!a->getAnimVar(GB(4)))
continue;
a->setAnimVar(GB(4), 0);
curpos = GUW(2);
curState = GUW(2);
break;
case AKC_EndOfIfDo:
@ -1542,15 +1552,15 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
continue;
case AKC_GoToState:
curpos = GUW(2);
curState = GUW(2);
// WORKAROUND bug #3813: In the German version of SPY Fox 3: Operation Ozone
// the wig maker room 21 contains a costume animation 352 of an LED ticker
// with a jump to an erroneous position 846.
// To prevent an undefined 'uSweat token' the animation is reset to its start.
if (_game.id == GID_HEGAME && _language == Common::DE_DEU && \
_currentRoom == 21 && a->_costume == 352 && curpos == 846) {
curpos = a->_cost.start[chan];
_currentRoom == 21 && a->_costume == 352 && curState == 846) {
curState = a->_cost.start[chan];
}
break;
@ -1563,7 +1573,7 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_CondDrawMany:
case AKC_CondRelativeOffsetDrawMany:
needRedraw = 1;
needRedraw = true;
break;
case AKC_StartActionOn:
@ -1582,30 +1592,30 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
case AKC_IfVarLEDo:
case AKC_IfVarGTDo:
case AKC_IfVarGEDo:
if (akos_compare(a->getAnimVar(GB(4)), GW(2), code - AKC_ConditionalDoStart) == 0)
if (!akosCompare(a->getAnimVar(GB(4)), GW(2), code))
skipNextState = true;
continue;
case AKC_IfSoundInVarRunningGoTo:
if (_sound->isSoundRunning( a->_sound[a->getAnimVar(GB(4))])) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
case AKC_IfNotSoundInVarRunningGoTo:
if (!_sound->isSoundRunning(a->_sound[a->getAnimVar(GB(4))])) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
case AKC_IfSoundRunningGoTo:
if (_sound->isSoundRunning(a->_sound[GB(4)])) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
case AKC_IfNotSoundRunningGoTo:
if (!_sound->isSoundRunning(a->_sound[GB(4)])) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
@ -1632,13 +1642,13 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
continue;
case AKC_IfTalkingGoTo:
if (((ActorHE *)a)->_heTalking != 0) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
case AKC_IfNotTalkingGoTo:
if (((ActorHE *)a)->_heTalking == 0) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
@ -1647,36 +1657,36 @@ bool ScummEngine_v6::akos_increaseAnim(Actor *a, int chan, const byte *aksq, con
continue;
case AKC_IfAnyTalkingGoTo:
if (VAR(VAR_TALK_ACTOR) != 0) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
case AKC_IfNotAnyTalkingGoTo:
if (VAR(VAR_TALK_ACTOR) == 0) {
curpos = GUW(2);
curState = GUW(2);
break;
}
continue;
default:
if ((code & 0xC000) == 0xC000)
if ((code & AKC_CommandMask) == AKC_CommandMask)
error("Undefined uSweat token %X", code);
}
break;
} while (1);
} while (true);
int code2 = aksq[curpos];
if (code2 & 0x80)
code2 = READ_BE_UINT16(aksq + curpos);
int code2 = aksq[curState];
if (code2 & AKC_ExtendBit)
code2 = READ_BE_UINT16(aksq + curState);
if ((code2 & 0xC000) == 0xC000 && code2 != AKC_DrawMany && code2 != AKC_EmptyCel && code2 != AKC_EndSeq && code2 != AKC_DisplayAuxFrame && code2 != AKC_RelativeOffsetDrawMany && code2 != AKC_CondDrawMany && code2 != AKC_CondRelativeOffsetDrawMany)
if ((code2 & AKC_CommandMask) == AKC_CommandMask && code2 != AKC_DrawMany && code2 != AKC_EmptyCel && code2 != AKC_EndSeq && code2 != AKC_DisplayAuxFrame && code2 != AKC_RelativeOffsetDrawMany && code2 != AKC_CondDrawMany && code2 != AKC_CondRelativeOffsetDrawMany)
error("Ending with undefined uSweat token %X", code2);
a->_cost.curpos[chan] = curpos;
a->_cost.curpos[chan] = curState;
if (needRedraw)
return 1;
return true;
else
return curpos != old_curpos;
return curState != startState;
}
void ScummEngine_v6::akos_queCommand(byte cmd, Actor *a, int param_1, int param_2) {
@ -1703,29 +1713,29 @@ void ScummEngine_v6::akos_processQueue() {
Actor *a = derefActor(actor, "akos_processQueue");
switch (cmd) {
case 1:
case AKQC_PutActorInTheVoid:
a->putActor(0, 0, 0);
break;
case 3:
case AKQC_StartSound:
_sound->addSoundToQueue(param_1, 0, -1, 0);
break;
case 4:
case AKQC_StartAnimation:
a->startAnimActor(param_1);
break;
case 5:
case AKQC_SetZClipping:
a->_forceClip = param_1;
break;
case 6:
case AKQC_SetXYOffset:
a->_heOffsX = param_1;
a->_heOffsY = param_2;
break;
case 7:
case AKQC_DisplayAuxFrame:
#ifdef ENABLE_HE
assert(_game.heversion >= 71);
((ScummEngine_v71he *)this)->queueAuxEntry(a->_number, param_1);
#endif
break;
case 8:
case AKQC_StartTalkie:
_actorToPrintStrFor = a->_number;
a->_talkPosX = ((ActorHE *)a)->_heTalkQueue[param_1].posX;
@ -1737,7 +1747,7 @@ void ScummEngine_v6::akos_processQueue() {
actorTalk(((ActorHE *)a)->_heTalkQueue[param_1].sentence);
break;
case 9:
case AKQC_SoftStartSound:
_sound->addSoundToQueue(param_1, 0, -1, 4);
break;
default:
@ -1768,41 +1778,41 @@ void ScummEngine_v7::akos_processQueue() {
Actor *a = derefActor(actor, "akos_processQueue");
switch (cmd) {
case 1:
case AKQC_PutActorInTheVoid:
a->putActor(0, 0, 0);
break;
case 3:
case AKQC_StartSound:
if (param_1 != 0) {
if (_imuseDigital) {
_imuseDigital->startSfx(param_1, 63);
}
}
break;
case 4:
case AKQC_StartAnimation:
a->startAnimActor(param_1);
break;
case 5:
case AKQC_SetZClipping:
a->_forceClip = param_1;
break;
case 6:
case AKQC_SetXYOffset:
a->_heOffsX = param_1;
a->_heOffsY = param_2;
break;
case 7:
case AKQC_SetSoundVolume:
if (param_1 != 0) {
if (_imuseDigital) {
_imuseDigital->setVolume(param_1, param_2);
}
}
break;
case 8:
case AKQC_SetSoundPan:
if (param_1 != 0) {
if (_imuseDigital) {
_imuseDigital->setPan(param_1, param_2);
}
}
break;
case 9:
case AKQC_SetSoundPriority:
if (param_1 != 0) {
if (_imuseDigital) {
_imuseDigital->setPriority(param_1, param_2);

View File

@ -26,6 +26,11 @@
namespace Scumm {
#define AKOS_BYLE_RLE_CODEC 1
#define AKOS_CDAT_RLE_CODEC 5
#define AKOS_RUN_MAJMIN_CODEC 16
#define AKOS_TRLE_CODEC 32
struct CostumeData;
struct AkosHeader;
struct AkosOffset;
@ -123,74 +128,117 @@ protected:
void markRectAsDirty(Common::Rect rect);
};
enum AkosOpcodes {
AKC_EmptyCel = 0xC001,
AKC_SetVar = 0xC010,
AKC_StartSound = 0xC015,
AKC_IfSoundInVarRunningGoTo = 0xC016,
AKC_IfNotSoundInVarRunningGoTo = 0xC017,
AKC_IfSoundRunningGoTo = 0xC018,
AKC_IfNotSoundRunningGoTo = 0xC019,
AKC_DrawMany = 0xC020,
AKC_CondDrawMany = 0xC021,
AKC_CondRelativeOffsetDrawMany = 0xC022,
AKC_RelativeOffsetDrawMany = 0xC025,
AKC_GoToState = 0xC030,
AKC_IfVarGoTo = 0xC031,
AKC_AddVar = 0xC040,
AKC_SoftSound = 0xC042,
AKC_SoftVarSound = 0xC044,
AKC_SetUserCondition = 0xC045,
AKC_SetVarToUserCondition = 0xC046,
AKC_SetTalkCondition = 0xC047,
AKC_SetVarToTalkCondition = 0xC048,
AKC_StartScript = 0xC050,
AKC_IncVar = 0xC060,
AKC_StartSound_SpecialCase = 0xC061,
AKC_ConditionalJumpStart = 0xC070,
AKC_IfVarEQJump = 0xC070,
AKC_IfVarNEJump = 0xC071,
AKC_IfVarLTJump = 0xC072,
AKC_IfVarLEJump = 0xC073,
AKC_IfVarGTJump = 0xC074,
AKC_IfVarGEJump = 0xC075,
AKC_StartAnim = 0xC080,
AKC_StartVarAnim = 0xC081,
AKC_SetVarRandom = 0xC082,
AKC_SetActorZClipping = 0xC083,
AKC_StartActorAnim = 0xC084,
AKC_SetActorVar = 0xC085,
AKC_HideActor = 0xC086,
AKC_SetDrawOffs = 0xC087,
AKC_JumpToOffsetInVar = 0xC088,
AKC_SoundStuff = 0xC089,
AKC_Flip = 0xC08A,
AKC_StartActionOn = 0xC08B,
AKC_StartScriptVar = 0xC08C,
AKC_StartSoundVar = 0xC08D,
AKC_DisplayAuxFrame = 0xC08E,
AKC_ConditionalDoStart = 0xC090,
AKC_IfVarEQDo = 0xC090,
AKC_IfVarNEDo = 0xC091,
AKC_IfVarLTDo = 0xC092,
AKC_IfVarLEDo = 0xC093,
AKC_IfVarGTDo = 0xC094,
AKC_IfVarGEDo = 0xC095,
AKC_EndOfIfDo = 0xC09F,
AKC_StartActorTalkie = 0xC0A0,
AKC_IfTalkingGoTo = 0xC0A1,
AKC_IfNotTalkingGoTo = 0xC0A2,
AKC_StartTalkieInVar = 0xC0A3,
AKC_IfAnyTalkingGoTo = 0xC0A4,
AKC_IfNotAnyTalkingGoTo = 0xC0A5,
AKC_IfTalkingPickGoTo = 0xC0A6,
AKC_IfNotTalkingPickGoTo = 0xC0A7,
AKC_EndSeq = 0xC0FF
enum AkosSequenceCodes {
// Auxiliary uSweat tokens:
AKC_ExtendBit = 0x80,
AKC_ExtendWordBit = 0x8000,
// Opcode uSweat tokens:
AKC_CommandMask = 0xC000,
AKC_EmptyCel = (AKC_CommandMask | 0x0001),
AKC_SetVar = (AKC_CommandMask | 0x0010),
AKC_StartSound = (AKC_CommandMask | 0x0015),
AKC_IfSoundInVarRunningGoTo = (AKC_CommandMask | 0x0016),
AKC_IfNotSoundInVarRunningGoTo = (AKC_CommandMask | 0x0017),
AKC_IfSoundRunningGoTo = (AKC_CommandMask | 0x0018),
AKC_IfNotSoundRunningGoTo = (AKC_CommandMask | 0x0019),
AKC_DrawMany = (AKC_CommandMask | 0x0020),
AKC_CondDrawMany = (AKC_CommandMask | 0x0021),
AKC_CondRelativeOffsetDrawMany = (AKC_CommandMask | 0x0022),
AKC_RelativeOffsetDrawMany = (AKC_CommandMask | 0x0025),
AKC_GoToState = (AKC_CommandMask | 0x0030),
AKC_IfVarGoTo = (AKC_CommandMask | 0x0031),
AKC_AddVar = (AKC_CommandMask | 0x0040),
AKC_SoftSound = (AKC_CommandMask | 0x0042),
AKC_SoftVarSound = (AKC_CommandMask | 0x0044),
AKC_SetUserCondition = (AKC_CommandMask | 0x0045),
AKC_SetVarToUserCondition = (AKC_CommandMask | 0x0046),
AKC_SetTalkCondition = (AKC_CommandMask | 0x0047),
AKC_SetVarToTalkCondition = (AKC_CommandMask | 0x0048),
AKC_StartScript = (AKC_CommandMask | 0x0050),
AKC_IncVar = (AKC_CommandMask | 0x0060),
AKC_StartSound_SpecialCase = (AKC_CommandMask | 0x0061),
AKC_IfVarEQJump = (AKC_CommandMask | 0x0070),
AKC_IfVarNEJump = (AKC_CommandMask | 0x0071),
AKC_IfVarLTJump = (AKC_CommandMask | 0x0072),
AKC_IfVarLEJump = (AKC_CommandMask | 0x0073),
AKC_IfVarGTJump = (AKC_CommandMask | 0x0074),
AKC_IfVarGEJump = (AKC_CommandMask | 0x0075),
AKC_StartAnim = (AKC_CommandMask | 0x0080),
AKC_StartVarAnim = (AKC_CommandMask | 0x0081),
AKC_SetVarRandom = (AKC_CommandMask | 0x0082),
AKC_SetActorZClipping = (AKC_CommandMask | 0x0083),
AKC_StartActorAnim = (AKC_CommandMask | 0x0084),
AKC_SetActorVar = (AKC_CommandMask | 0x0085),
AKC_HideActor = (AKC_CommandMask | 0x0086),
AKC_SetDrawOffs = (AKC_CommandMask | 0x0087),
AKC_JumpToOffsetInVar = (AKC_CommandMask | 0x0088),
AKC_SoundStuff = (AKC_CommandMask | 0x0089),
AKC_Flip = (AKC_CommandMask | 0x008A),
AKC_StartActionOn = (AKC_CommandMask | 0x008B),
AKC_StartScriptVar = (AKC_CommandMask | 0x008C),
AKC_StartSoundVar = (AKC_CommandMask | 0x008D),
AKC_DisplayAuxFrame = (AKC_CommandMask | 0x008E),
AKC_IfVarEQDo = (AKC_CommandMask | 0x0090),
AKC_IfVarNEDo = (AKC_CommandMask | 0x0091),
AKC_IfVarLTDo = (AKC_CommandMask | 0x0092),
AKC_IfVarLEDo = (AKC_CommandMask | 0x0093),
AKC_IfVarGTDo = (AKC_CommandMask | 0x0094),
AKC_IfVarGEDo = (AKC_CommandMask | 0x0095),
AKC_EndOfIfDo = (AKC_CommandMask | 0x009F),
AKC_StartActorTalkie = (AKC_CommandMask | 0x00A0),
AKC_IfTalkingGoTo = (AKC_CommandMask | 0x00A1),
AKC_IfNotTalkingGoTo = (AKC_CommandMask | 0x00A2),
AKC_StartTalkieInVar = (AKC_CommandMask | 0x00A3),
AKC_IfAnyTalkingGoTo = (AKC_CommandMask | 0x00A4),
AKC_IfNotAnyTalkingGoTo = (AKC_CommandMask | 0x00A5),
AKC_IfTalkingPickGoTo = (AKC_CommandMask | 0x00A6),
AKC_IfNotTalkingPickGoTo = (AKC_CommandMask | 0x00A7),
AKC_EndSeq = (AKC_CommandMask | 0x00FF)
};
#define GW(o) ((int16)READ_LE_UINT16(aksq+curpos+(o)))
#define GUW(o) READ_LE_UINT16(aksq+curpos+(o))
#define GB(o) aksq[curpos+(o)]
enum AkosQueuedCommands {
AKQC_PutActorInTheVoid = 1,
AKQC_StartSound = 3,
AKQC_StartAnimation = 4,
AKQC_SetZClipping = 5,
AKQC_SetXYOffset = 6,
AKQC_DisplayAuxFrame = 7,
AKQC_StartTalkie = 8,
AKQC_SoftStartSound = 9,
// For V7-8
AKQC_SetSoundVolume = 7,
AKQC_SetSoundPan = 8,
AKQC_SetSoundPriority = 9
};
enum AkosAnimTypes {
AKAT_Empty = 0x00,
AKAT_KillLayer = 0x01,
AKAT_LoopLayer = 0x02,
AKAT_RunLayer = 0x03,
AKAT_LayerInvisible = 0x04,
AKAT_LayerVisible = 0x05,
AKAT_AlwaysRun = 0x06,
AKAT_UserConstant = 0x07,
AKAT_DeltaAnim = 0x08
};
#define GW(o) ((int16)READ_LE_UINT16(aksq + curState + (o)))
#define GUW(o) READ_LE_UINT16(aksq + curState + (o))
#define GB(o) aksq[curState + (o)]
} // End of namespace Scumm

View File

@ -1257,7 +1257,7 @@ byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) {
return 0;
_loaded.loadCostume(a->_costume);
byte frame = _loaded._frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]];
byte frame = _loaded._frameOffsets[a->_cost.curpos[limb] + a->_cost.animType[limb]];
// Get the frame ptr
byte ptrLow = _loaded._baseptr[frame];
@ -1426,7 +1426,7 @@ byte V0CostumeLoader::increaseAnim(Actor *a, int limb) {
loadCostume(a->_costume);
// 0x2543
byte frame = _frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]];
byte frame = _frameOffsets[a->_cost.curpos[limb] + a->_cost.animType[limb]];
// Is this frame invalid?
if (frame == 0xFF) {

View File

@ -531,7 +531,7 @@ bool ScummDebugger::Cmd_PrintScript(int argc, const char **argv) {
bool ScummDebugger::Cmd_Cosdump(int argc, const char **argv) {
const byte *akos;
const byte *aksq;
uint32 curpos;
uint32 curState;
uint32 code;
uint32 aend;
int costume;
@ -551,7 +551,7 @@ bool ScummDebugger::Cmd_Cosdump(int argc, const char **argv) {
akos = _vm->getResourceAddress(rtCostume, costume);
curpos = 0;
curState = 0;
aksq = _vm->findResourceData(MKTAG('A','K','S','Q'), akos);
if (aksq == nullptr) {
debugPrintf("Costume %d does not have AKSQ block\n", costume);
@ -559,231 +559,231 @@ bool ScummDebugger::Cmd_Cosdump(int argc, const char **argv) {
}
aend = READ_BE_UINT32(aksq - 4) - 8;
debugPrintf("DUMP COSTUME SCRIPT %d (size %d)\n", costume, aend);
while (curpos < aend) {
while (curState < aend) {
code = GB(0);
if (code & 0x80)
code = READ_BE_UINT16(aksq + curpos);
debugPrintf("[%04x] (%04x) ", curpos, code);
code = READ_BE_UINT16(aksq + curState);
debugPrintf("[%04x] (%04x) ", curState, code);
switch (code) {
case AKC_EmptyCel:
debugPrintf("RETURN\n");
curpos += 2;
curState += 2;
break;
case AKC_SetVar:
debugPrintf("VAR[%d] = %d\n", GB(4), GW(2));
curpos += 5;
curState += 5;
break;
case AKC_StartSound:
debugPrintf("START SOUND %d\n", GB(2));
curpos += 3;
curState += 3;
break;
case AKC_IfSoundInVarRunningGoTo:
debugPrintf("IF SOUND RUNNING VAR[%d] GOTO [%04x]\n", GB(4), GUW(2));
curpos += 5;
curState += 5;
break;
case AKC_IfNotSoundInVarRunningGoTo:
debugPrintf("IF NOT SOUND RUNNING VAR[%d] GOTO [%04x]\n", GB(4), GUW(2));
curpos += 5;
curState += 5;
break;
case AKC_IfSoundRunningGoTo:
debugPrintf("IF SOUND RUNNING %d GOTO [%04x]\n", GB(4), GUW(2));
curpos += 5;
curState += 5;
break;
case AKC_IfNotSoundRunningGoTo:
debugPrintf("IF NOT SOUND RUNNING %d GOTO [%04x]\n", GB(4), GUW(2));
curpos += 5;
curState += 5;
break;
case AKC_DrawMany:
debugPrintf("DRAW:\n");
curpos += 2;
curState += 2;
count = GB(0);
curpos++;
curState++;
for (i = 0; i < count; i++) {
code = GB(4);
if (code & 0x80) {
code = READ_BE_UINT16(aksq + curpos + 4);
code = READ_BE_UINT16(aksq + curState + 4);
debugPrintf("\tEXTENDED OFFSET %d POS %d,%d\n", code, GW(0), GW(2));
curpos++;
curState++;
} else {
debugPrintf("\tOFFSET %d POS %d,%d\n", code, GW(0), GW(2));
}
curpos += 5;
curState += 5;
}
break;
case AKC_CondDrawMany:
debugPrintf("CONDITION MASK DRAW [%04x] [", curpos + GB(2));
debugPrintf("CONDITION MASK DRAW [%04x] [", curState + GB(2));
count = GB(3);
for (i = 0; i < count; i++) {
if (i)
debugPrintf(", ");
debugPrintf("%d", GB(4));
curpos++;
curState++;
}
debugPrintf("]\n");
curpos += 4;
curState += 4;
count = GB(0);
curpos++;
curState++;
for (i = 0; i < count; i++) {
code = GB(4);
if (code & 0x80) {
code = READ_BE_UINT16(aksq + curpos + 4);
code = READ_BE_UINT16(aksq + curState + 4);
debugPrintf("\tEXTENDED OFFSET %d POS %d,%d\n", code, GW(0), GW(2));
curpos++;
curState++;
} else {
debugPrintf("\tOFFSET %d POS %d,%d\n", code, GW(0), GW(2));
}
curpos += 5;
curState += 5;
}
break;
case AKC_CondRelativeOffsetDrawMany:
debugPrintf("CONDITION MASK DRAW [%04x] [", curpos + GB(2));
debugPrintf("CONDITION MASK DRAW [%04x] [", curState + GB(2));
count = GB(3);
for (i = 0; i < count; i++) {
if (i)
debugPrintf(", ");
debugPrintf("%d", GB(4));
curpos++;
curState++;
}
debugPrintf("] AT OFFSET %d, %d:\n", GW(2), GW(4));
curpos += 6;
curState += 6;
count = GB(0);
curpos++;
curState++;
for (i = 0; i < count; i++) {
code = GB(4);
if (code & 0x80) {
code = READ_BE_UINT16(aksq + curpos + 4);
code = READ_BE_UINT16(aksq + curState + 4);
debugPrintf("\tEXTENDED OFFSET %d POS %d,%d\n", code, GW(0), GW(2));
curpos++;
curState++;
} else {
debugPrintf("\tOFFSET %d POS %d,%d\n", code, GW(0), GW(2));
}
curpos += 5;
curState += 5;
}
break;
case AKC_RelativeOffsetDrawMany:
debugPrintf("DRAW AT OFFSET %d, %d:\n", GW(2), GW(4));
curpos += 6;
curState += 6;
count = GB(0);
curpos++;
curState++;
for (i = 0; i < count; i++) {
code = GB(4);
if (code & 0x80) {
code = READ_BE_UINT16(aksq + curpos + 4);
code = READ_BE_UINT16(aksq + curState + 4);
debugPrintf("\tEXTENDED OFFSET %d POS %d,%d\n", code, GW(0), GW(2));
curpos++;
curState++;
} else {
debugPrintf("\tOFFSET %d POS %d,%d\n", code, GW(0), GW(2));
}
curpos += 5;
curState += 5;
}
break;
case AKC_GoToState:
debugPrintf("GOTO [%04x]\n", GUW(2));
curpos += 4;
curState += 4;
break;
case AKC_IfVarGoTo:
debugPrintf("IF VAR[%d] GOTO [%04x]\n", GB(4), GUW(2));
curpos += 5;
curState += 5;
break;
case AKC_AddVar:
debugPrintf("VAR[%d] += %d\n", GB(4), GW(2));
curpos += 5;
curState += 5;
break;
case AKC_SoftSound:
debugPrintf("START SOUND %d SOFT\n", GB(2));
curpos += 3;
curState += 3;
break;
case AKC_SoftVarSound:
debugPrintf("START SOUND VAR[%d] SOFT\n", GB(2));
curpos += 3;
curState += 3;
break;
case AKC_SetUserCondition:
debugPrintf("USER CONDITION %d = VAR[%d] GOTO [%04x] \n", GB(3), GB(4), GB(2));
curpos += 5;
curState += 5;
break;
case AKC_SetVarToUserCondition:
debugPrintf("VAR[%d] = USER CONDITION %d GOTO [%04x] \n", GB(4), GB(3), GB(2));
curpos += 5;
curState += 5;
break;
case AKC_SetTalkCondition:
debugPrintf("TALK CONDITION %d SET GOTO [%04x] \n", GB(3), GB(2));
curpos += 4;
curState += 4;
break;
case AKC_SetVarToTalkCondition:
debugPrintf("VAR[%d] = TALK CONDITION %d GOTO [%04x] \n", GB(4), GB(3), GB(2));
curpos += 5;
curState += 5;
break;
case AKC_StartScript:
debugPrintf("IGNORE %d\n", GB(2));
curpos += 3;
curState += 3;
break;
case AKC_IncVar:
debugPrintf("VAR[0]++\n");
curpos += 2;
curState += 2;
break;
case AKC_StartSound_SpecialCase:
debugPrintf("START SOUND QUICK\n");
curpos += 2;
curState += 2;
break;
case AKC_IfVarEQJump:
debugPrintf("IF VAR[%d] == %d GOTO [%04x]\n", GB(4), GW(5), GUW(2));
curpos += 7;
curState += 7;
break;
case AKC_IfVarNEJump:
debugPrintf("IF VAR[%d] != %d GOTO [%04x]\n", GB(4), GW(5), GUW(2));
curpos += 7;
curState += 7;
break;
case AKC_IfVarLTJump:
debugPrintf("IF VAR[%d] < %d GOTO [%04x]\n", GB(4), GW(5), GUW(2));
curpos += 7;
curState += 7;
break;
case AKC_IfVarLEJump:
debugPrintf("IF VAR[%d] <= %d GOTO [%04x]\n", GB(4), GW(5), GUW(2));
curpos += 7;
curState += 7;
break;
case AKC_IfVarGTJump:
debugPrintf("IF VAR[%d] > %d GOTO [%04x]\n", GB(4), GW(5), GUW(2));
curpos += 7;
curState += 7;
break;
case AKC_IfVarGEJump:
debugPrintf("IF VAR[%d] >= %d GOTO [%04x]\n", GB(4), GW(5), GUW(2));
curpos += 7;
curState += 7;
break;
case AKC_StartAnim:
debugPrintf("START ANIMATION %d\n", GB(2));
curpos += 3;
curState += 3;
break;
case AKC_StartVarAnim:
debugPrintf("START ANIMATION VAR[%d]\n", GB(2));
curpos += 3;
curState += 3;
break;
case AKC_SetVarRandom:
debugPrintf("VAR[%d] = RANDOM BETWEEN %d AND %d\n", GB(6), GW(2), GW(4));
curpos += 7;
curState += 7;
break;
case AKC_SetActorZClipping:
debugPrintf("ZCLIP %d\n", GB(2));
curpos += 3;
curState += 3;
break;
case AKC_StartActorAnim:
debugPrintf("START ANIMATION ACTOR VAR[%d] VAR[%d]\n", GB(2), GB(3));
curpos += 4;
curState += 4;
break;
case AKC_SetActorVar:
debugPrintf("ACTOR VAR[%d] VAR[%d] = %d\n", GB(2), GB(3), GW(4));
curpos += 6;
curState += 6;
break;
case AKC_HideActor:
debugPrintf("DESTROY ACTOR\n");
curpos += 2;
curState += 2;
break;
case AKC_SetDrawOffs:
debugPrintf("SET DRAW OFFSETS %d %d\n", GW(2), GW(4));
curpos += 6;
curState += 6;
break;
case AKC_JumpToOffsetInVar:
debugPrintf("GOTO OFFSET AT VAR[%d]\n", GB(2));
curpos += 3;
curState += 3;
break;
// case AKC_SoundStuff:
// break;
@ -795,7 +795,7 @@ bool ScummDebugger::Cmd_Cosdump(int argc, const char **argv) {
// break;
case AKC_StartSoundVar:
debugPrintf("START SOUND VAR[%d]\n", GB(2));
curpos += 3;
curState += 3;
break;
// case AKC_DisplayAuxFrame:
// break;
@ -815,19 +815,19 @@ bool ScummDebugger::Cmd_Cosdump(int argc, const char **argv) {
// break;
case AKC_StartActorTalkie:
debugPrintf("START TALK %d {%d}\n", GB(2), GB(3));
curpos += 4;
curState += 4;
break;
case AKC_IfTalkingGoTo:
debugPrintf("IF ACTOR TALKING GOTO [%04x]\n", GUW(2));
curpos += 4;
curState += 4;
break;
case AKC_IfNotTalkingGoTo:
debugPrintf("IF NOT ACTOR TALKING GOTO [%04x]\n", GUW(2));
curpos += 4;
curState += 4;
break;
case AKC_StartTalkieInVar:
debugPrintf("START TALK VAR[%d]\n", GB(2));
curpos += 3;
curState += 3;
break;
// case AKC_IfAnyTalkingGoTo:
// break;
@ -839,7 +839,7 @@ bool ScummDebugger::Cmd_Cosdump(int argc, const char **argv) {
// break;
case AKC_EndSeq:
debugPrintf("STOP\n");
curpos += 2;
curState += 2;
break;
default:
warning("DEFAULT OP, breaking...\n");