aboutsummaryrefslogtreecommitdiff
path: root/engines/scumm/costume.cpp
diff options
context:
space:
mode:
authorRobert Crossfield2012-01-24 23:23:19 +1100
committerTobias Gunkel2012-02-11 08:29:22 +0100
commit65fb1f9a09b3460eebaf7d033990fe9e778070f4 (patch)
tree69f3537196fcb679adfb301d24be960c215d3874 /engines/scumm/costume.cpp
parente3f9a09d49aaeb4657862ca734d20279e75c869f (diff)
downloadscummvm-rg350-65fb1f9a09b3460eebaf7d033990fe9e778070f4.tar.gz
scummvm-rg350-65fb1f9a09b3460eebaf7d033990fe9e778070f4.tar.bz2
scummvm-rg350-65fb1f9a09b3460eebaf7d033990fe9e778070f4.zip
SCUMM: Fix the animation system, rename the Limb Frame Repeat variable
Diffstat (limited to 'engines/scumm/costume.cpp')
-rw-r--r--engines/scumm/costume.cpp234
1 files changed, 63 insertions, 171 deletions
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp
index 965cee79a8..c7285ead56 100644
--- a/engines/scumm/costume.cpp
+++ b/engines/scumm/costume.cpp
@@ -72,14 +72,6 @@ static const int v1MMNESLookup[25] = {
0x17, 0x00, 0x01, 0x05, 0x16
};
-static const byte v0ActorTalkArray[0x19] = {
- 0x00, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x00, 0x46, 0x06,
- 0x06, 0x06, 0x06, 0xFF, 0xFF,
- 0x06, 0xC0, 0x06, 0x06, 0x00,
- 0xC0, 0xC0, 0x00, 0x06, 0x06
-};
-
byte ClassicCostumeRenderer::mainRoutine(int xmoveCur, int ymoveCur) {
int i, skip = 0;
byte drawFlag = 1;
@@ -1187,10 +1179,12 @@ static const byte actorColorsMMC64[25] = {
}
byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
+ ActorC64* A = (ActorC64*) a;
+
if (limb >= 8)
return 0;
- if (a->_cost.start[limb] == 0xFFFF)
+ if (a->_cost.curpos[limb] == 0xFFFF || A->_cost.active[limb] == 0xFFFF )
return 0;
if (limb == 0) {
@@ -1198,8 +1192,8 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
_draw_bottom = 0;
}
- bool flipped = (a->_cost.start[limb] & 0x80) != 0;
- byte frameStart = _loaded._frameOffsets[a->_cost.frame[limb]];
+ byte frameB = _loaded._frameOffsets[limb] + a->_cost.active[limb];
+ byte frameStart = _loaded._frameOffsets[ frameB ];
byte frame = _loaded._frameOffsets[frameStart + a->_cost.curpos[limb]];
if (frame == 0xFF)
return 0;
@@ -1231,7 +1225,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
if (!width || !height)
return 0;
- int xpos = _actorX + (flipped ? -1 : +1) * (offsetX * 8 - a->_width / 2);
+ int xpos = _actorX + (A->_limb_flipped[ limb ] ? -1 : +1) * (offsetX * 8 - a->_width / 2);
// +1 as we appear to be 1 pixel away from the original interpreter
int ypos = _actorY - offsetY + 1;
@@ -1241,13 +1235,13 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
byte color = data[y * width + x];
byte pcolor;
- int destX = xpos + (flipped ? -(x + 1) : x) * 8;
+ int destX = xpos + (A->_limb_flipped[ limb ] ? -(x + 1) : x) * 8;
int destY = ypos + y;
if (destY >= 0 && destY < _out.h && destX >= 0 && destX < _out.w) {
byte *dst = (byte *)_out.pixels + destY * _out.pitch + destX;
byte *mask = _vm->getMaskBuffer(0, destY, _zbuf);
- if (flipped) {
+ if (A->_limb_flipped[ limb ]) {
LINE(0, 0); LINE(2, 2); LINE(4, 4); LINE(6, 6);
} else {
LINE(6, 0); LINE(4, 2); LINE(2, 4); LINE(0, 6);
@@ -1258,7 +1252,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) {
_draw_top = MIN(_draw_top, ypos);
_draw_bottom = MAX(_draw_bottom, ypos + height);
- if (flipped)
+ if (A->_limb_flipped[ limb ])
_vm->markRectAsDirty(kMainVirtScreen, xpos - (width * 8), xpos, ypos, ypos + height, _actorID);
else
_vm->markRectAsDirty(kMainVirtScreen, xpos, xpos + (width * 8), ypos, ypos + height, _actorID);
@@ -1291,195 +1285,93 @@ void C64CostumeLoader::loadCostume(int id) {
_maxHeight = 0;
}
-void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) {
- byte limbFrames = 0;
-
- // Each costume-command has 8 limbs (0x2622)
- cmd <<= 3;
-
- for (int limb = 0, pos = 0; limb < 8; ++limb, pos = 0) {
- // get the frame number for the beginning of the costume command
- limbFrames = ((_animCmds + cmd)[limb]);
-
- // Dont change if frame is invalid
- if (limbFrames == 0xFF)
- continue;
-
- // 0x2679
- a->_byte_FCE2[limb] = a->_byte_FD0A;
-
- // Has limb frames ptr changed since last update?
- if (a->_cost.start[limb] == limbFrames)
- continue;
-
- // Set new limb command addresses
- a->_cost.start[limb] = limbFrames;
- a->_cost.frame[limb] = _frameOffsets[limb] + (limbFrames & 0x7f); // limb animation-frames ptr
-
- // Get first entry of a limbs' frames
- byte frameStart = _frameOffsets[ a->_cost.frame[limb]];
-
- // Loop each frame in this limb until we reach the end marker
- while (pos != 0xFF) { // This is just so we dont overflow
- byte frame = _frameOffsets[frameStart + pos];
-
- // Each animation-frame until we find end
- if (frame == 0xFF)
- break;
-
- byte ptrLow = _baseptr[frame];
- byte ptrHigh = ptrLow + _dataOffsets[4];
- int frameOffset = (_baseptr[ptrHigh] << 8) + _baseptr[ptrLow + 2]; // 0x23EF / 0x2400
-
- const byte *data = _baseptr + frameOffset;
-
- if (data[3] > _maxHeight)
- _maxHeight = data[3] + 1;
-
- ++pos;
- }
-
- // Set ending position of limb frames
- a->_cost.end[limb] = pos;
- a->_cost.curpos[limb] = 0;
- }
-}
-
-// based on 0x2BCA, doesn't match disassembly because 'oldDir' variable
-// is not the same value as stored in the original interpreter
-int C64CostumeLoader::dirToDirStop(int oldDir) {
- int res = 0;
-
- switch (oldDir) {
- case 0:
- res = 4; // Left
- break;
-
- case 1:
- res = 5; // Right
- break;
-
- case 2:
- res = 6; // Face Camera
- break;
+void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
+ ActorC64 *A = (ActorC64 *)a;
- default:
- res = 7; // Face Away
- break;
- }
-
- return res;
-}
+ loadCostume(a->_costume);
-void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) {
- if (v0ActorTalkArray[a->_number] & 0x80)
+ if( A->_costCommandNew == 0xFF || (A->_costCommand == A->_costCommandNew) )
return;
- if ((a->_speaking & 0x80))
- cmd += 0x0C;
- else
- cmd += 0x10;
-
- a->_byte_FDE8 = -1;
-}
+ A->_costCommand = A->_costCommandNew;
-void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
- ActorC64 *A = (ActorC64 *)a;
- int dir = newDirToOldDir(a->getFacing());
- int command = dir;
+ int cmd = A->_costCommand;
+ byte limbFrameNumber = 0;
- loadCostume(a->_costume);
+ // Each costume-command has 8 limbs (0x2622)
+ cmd <<= 3;
- // Enable/Disable speaking flag
- if (frame == a->_talkStartFrame) {
+ for (int limb = 0; limb < 8; ++limb) {
- if (v0ActorTalkArray[a->_number] & 0x40)
- return;
+ // get the frame number for the beginning of the costume command
+ limbFrameNumber = ((_animCmds + cmd)[limb]);
- A->_speaking = 1;
- return;
- }
+ if( limbFrameNumber & 0x80 ) {
- if (frame == a->_talkStopFrame) {
+ // 0x263D
+ if( limbFrameNumber == 0xFF )
+ continue;
- A->_speaking = 0;
- return;
- }
+ // 0x2643
+ a->_cost.frame[limb] = (limbFrameNumber & 0x7f); // limb animation-frames ptr
+ if( A->_limb_flipped[limb] != true )
+ a->_cost.start[limb] = 0xFFFF;
- // Different command for stand frame
- if (frame == a->_standFrame)
- command = dirToDirStop(dir);
+ A->_limb_flipped[limb] = true;
- // Update the limb frames
- frameUpdate(A, command);
+ } else {
+ //0x2660
+ a->_cost.frame[limb] = limbFrameNumber;
- // Keep current command/frame mode
- A->_costCommand = dir;
- A->_costFrame = frame;
+ if( A->_limb_flipped[limb] != false )
+ a->_cost.start[limb] = 0xFFFF;
- // Update 'speaking' frames?
- if (A->_speaking) {
- command = dir; // Incase standing frame was set as cmd
- actorSpeak(A, command);
+ A->_limb_flipped[limb] = false;
+ }
- // Update the limb speak frames
- frameUpdate(A, command);
+ // 0x2679
+ A->_limbFrameRepeatNew[limb] = A->_AnimFrameRepeat;
}
}
byte C64CostumeLoader::increaseAnims(Actor *a) {
ActorC64 *A = (ActorC64 *)a;
+
+ if( _frameOffsets == 0 )
+ return 0;
- // check if the actor speak flag has changed since last frame increase
- if (A->_speaking != A->_speakingPrev) {
- int cmd = A->_costCommand;
- A->_speakingPrev = A->_speaking;
-
- actorSpeak(A, cmd);
-
- // Update the limb frames
- frameUpdate(A, cmd);
- }
-
- if (A->_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) {
- if (a->_cost.soundPos == 0)
- a->_cost.soundCounter++;
-
- // Is this the correct location?
- // 0x073C
- if (v0ActorTalkArray[a->_number] & 0x3F)
- a->_cost.soundPos = (a->_cost.soundPos + 1) % 3;
- }
+ uint16 limbPrevious = a->_cost.curpos[A->_limb_current]++;
// increase each frame pos
// 0x2543
- for (int limb = 0; limb < 8; ++limb) {
-
- if (++a->_cost.curpos[limb] >= a->_cost.end[limb]) {
+ byte frameB = _frameOffsets[A->_limb_current] + a->_cost.active[A->_limb_current];
+ byte frameStart = _frameOffsets[ frameB ];
+ byte frame = _frameOffsets[frameStart + a->_cost.curpos[A->_limb_current]];
- // 0x2541
- if( A->_byte_FCE2[limb] == 0 ) {
+ if ( frame == 0xFF ) {
+ // 0x2545
+ if( A->_limbFrameRepeat[A->_limb_current] == 0 ) {
- // 0x2556
- --a->_cost.curpos[limb];
+ // 0x2556
+ --A->_cost.curpos[A->_limb_current];
- //A->_costCommandNew = 0xFF;
- //A->_costCommand = 0xFF;
+ A->_costCommandNew = 0xFF;
+ A->_costCommand = 0xFF;
- // 0x2568
- //A->_limbCommandNew[limb] = 0xFF;
- //A->_limbCommand[limb] = 0xFF;
+ // 0x2568
+ A->_cost.frame[A->_limb_current] = 0xFFFF;
+ A->_cost.start[A->_limb_current] = 0xFFFF;
- } else {
- if( A->_byte_FCE2[limb] != -1 )
- --A->_byte_FCE2[limb];
+ } else {
+ if( A->_limbFrameRepeat[A->_limb_current] != -1 )
+ --A->_limbFrameRepeat[A->_limb_current];
- a->_cost.curpos[limb] = 0;
- }
+ a->_cost.curpos[A->_limb_current] = 0;
}
+ }
-
- }
+ if( limbPrevious == a->_cost.curpos[A->_limb_current] )
+ return 0;
return 1;
}