diff options
Diffstat (limited to 'engines/scumm/costume.cpp')
-rw-r--r-- | engines/scumm/costume.cpp | 243 |
1 files changed, 99 insertions, 144 deletions
diff --git a/engines/scumm/costume.cpp b/engines/scumm/costume.cpp index eb3cc3262c..6e7e9ff688 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; @@ -676,7 +668,7 @@ void ClassicCostumeRenderer::procPCEngine(Codec1 &v1) { (v1.mask_ptr && (mask[0] & maskbit)); if (pcolor && !masked) { - WRITE_UINT16(dst, ((uint16*)_palette)[pcolor]); + WRITE_UINT16(dst, ((uint16 *)_palette)[pcolor]); } xPos += xStep; @@ -1171,7 +1163,7 @@ byte NESCostumeLoader::increaseAnim(Actor *a, int slot) { return (a->_cost.curpos[slot] != oldframe); } -static const byte actorColorsMMC64[25] = { +static const byte actorV0Colors[25] = { 0, 7, 2, 6, 9, 1, 3, 7, 7, 1, 1, 9, 1, 4, 5, 5, 4, 1, 0, 5, 4, 2, 2, 7, 7 }; @@ -1186,24 +1178,25 @@ static const byte actorColorsMMC64[25] = { dst[p + 1] = palette[pcolor]; \ } -byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { - if (limb >= 8) - return 0; +byte V0CostumeRenderer::drawLimb(const Actor *a, int limb) { + const Actor_v0* a0 = (const Actor_v0 *)a; - if (a->_cost.start[limb] == 0xFFFF) + if (limb >= 8) return 0; if (limb == 0) { _draw_top = 200; _draw_bottom = 0; } - - bool flipped = (a->_cost.start[limb] & 0x80) != 0; - byte frameStart = _loaded._frameOffsets[a->_cost.frame[limb]]; - byte frame = _loaded._frameOffsets[frameStart + a->_cost.curpos[limb]]; - if (frame == 0xFF) + + // Invalid current position? + if (a->_cost.curpos[limb] == 0xFFFF) return 0; + _loaded.loadCostume(a->_costume); + byte frame = _loaded._frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]]; + + // Get the frame ptr byte ptrLow = _loaded._baseptr[frame]; byte ptrHigh = ptrLow + _loaded._dataOffsets[4]; int frameOffset = (_loaded._baseptr[ptrHigh] << 8) + _loaded._baseptr[ptrLow + 2]; // 0x23EF / 0x2400 @@ -1214,7 +1207,7 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { byte palette[4] = { 0, 0, 0, 0 }; if (_vm->getCurrentLights() & LIGHTMODE_actor_use_colors) { palette[1] = 10; - palette[2] = actorColorsMMC64[_actorID]; + palette[2] = actorV0Colors[_actorID]; } else { palette[2] = 11; palette[3] = 11; @@ -1231,7 +1224,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 + (a0->_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 +1234,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 + (a0->_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 (a0->_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 +1251,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 (a0->_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); @@ -1268,11 +1261,11 @@ byte C64CostumeRenderer::drawLimb(const Actor *a, int limb) { #undef LINE #undef MASK_AT -void C64CostumeRenderer::setCostume(int costume, int shadow) { +void V0CostumeRenderer::setCostume(int costume, int shadow) { _loaded.loadCostume(costume); } -void C64CostumeLoader::loadCostume(int id) { +void V0CostumeLoader::loadCostume(int id) { const byte *ptr = _vm->getResourceAddress(rtCostume, id); _id = id; @@ -1282,166 +1275,128 @@ void C64CostumeLoader::loadCostume(int id) { _numColors = 0; _numAnim = 0; _mirror = 0; - _palette = &actorColorsMMC64[id]; + _palette = &actorV0Colors[id]; _frameOffsets = _baseptr + READ_LE_UINT16(ptr + 5); _dataOffsets = ptr; _animCmds = _baseptr + READ_LE_UINT16(ptr + 7); - - _maxHeight = 0; } -void C64CostumeLoader::frameUpdate(ActorC64 *a, int cmd ) { - byte limbFrames = 0; +void V0CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { + Actor_v0 *a0 = (Actor_v0 *)a; + + if (!a->_costume) + return; + + loadCostume(a->_costume); + + // Invalid costume command? + if (a0->_costCommandNew == 0xFF || (a0->_costCommand == a0->_costCommandNew)) + return; + + a0->_costCommand = a0->_costCommandNew; + + int cmd = a0->_costCommand; + byte limbFrameNumber = 0; // Each costume-command has 8 limbs (0x2622) cmd <<= 3; - for (int limb = 0, pos = 0; limb < 8; ++limb, pos = 0) { - // get a limb frames ptr from the costume command - limbFrames = ((_animCmds + cmd)[limb]); - - // Dont change limb if entry is invalid - if (limbFrames == 0xFF) - continue; + for (int limb = 0; limb < 8; ++limb) { - // Has limb frames ptr changed since last update? - if (a->_cost.start[limb] == limbFrames) - continue; + // get the frame number for the beginning of the costume command + limbFrameNumber = ((_animCmds + cmd)[limb]); - // Set new limb command addresses - a->_cost.start[limb] = limbFrames; - a->_cost.frame[limb] = _frameOffsets[limb] + (limbFrames & 0x7f); // limb animation-frames ptr + // Is this limb flipped? + if (limbFrameNumber & 0x80) { - // Get first entry of a limbs' frames - byte frameStart = _frameOffsets[ a->_cost.frame[limb]]; + // Invalid frame? + if (limbFrameNumber == 0xFF) + continue; - // 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]; + // Store the limb frame number (clear the flipped status) + a->_cost.frame[limb] = (limbFrameNumber & 0x7f); - // Each animation-frame until we find end - if (frame == 0xFF) - break; + if (a0->_limb_flipped[limb] != true) + a->_cost.start[limb] = 0xFFFF; - byte ptrLow = _baseptr[frame]; - byte ptrHigh = ptrLow + _dataOffsets[4]; - int frameOffset = (_baseptr[ptrHigh] << 8) + _baseptr[ptrLow + 2]; // 0x23EF / 0x2400 + a0->_limb_flipped[limb] = true; - const byte *data = _baseptr + frameOffset; + } else { + //Store the limb frame number + a->_cost.frame[limb] = limbFrameNumber; - if (data[3] > _maxHeight) - _maxHeight = data[3] + 1; + if (a0->_limb_flipped[limb] != false) + a->_cost.start[limb] = 0xFFFF; - ++pos; + a0->_limb_flipped[limb] = false; } - // Set ending position of limb frames - a->_cost.end[limb] = pos - 1; - 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) { - switch (oldDir) { - case 0: - return 4; // Left - case 1: - return 5; // Right - case 2: - return 6; // Face Camera - case 3: - return 7; // Face Away + // Set the repeat value + a0->_limbFrameRepeatNew[limb] = a0->_animFrameRepeat; } - // shouldnt' be reached - return 4; } -void C64CostumeLoader::actorSpeak(ActorC64 *a, int &cmd) { - if (v0ActorTalkArray[a->_number] & 0x80) - return; +byte V0CostumeLoader::getFrame(Actor *a, int limb) { + loadCostume(a->_costume); - if ((a->_speaking & 0x80)) - cmd += 0x0C; - else - cmd += 0x10; + // Get the frame number for the current limb / Command + return _frameOffsets[_frameOffsets[limb] + a->_cost.start[limb]]; } -void C64CostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) { - ActorC64 *A = (ActorC64 *)a; - int dir = newDirToOldDir(a->getFacing()); - int command = dir; - - loadCostume(a->_costume); - - // Enable/Disable speaking flag - if (frame == a->_talkStartFrame) { - if (v0ActorTalkArray[a->_number] & 0x40) - return; +byte V0CostumeLoader::increaseAnims(Actor *a) { + Actor_v0 *a0 = (Actor_v0 *)a; + int i; + byte r = 0; - A->_speaking = 1; - return; - } - if (frame == a->_talkStopFrame) { - A->_speaking = 0; - return; + for (i = 0; i != 8; i++) { + a0->limbFrameCheck(i); + r += increaseAnim(a, i); } + return r; +} - // Different command for stand frame - if (frame == a->_standFrame) - command = dirToDirStop(dir); - - // Update the limb frames - frameUpdate(A, command); - - // Keep current command/frame mode - A->_costCommand = dir; - A->_costFrame = frame; +byte V0CostumeLoader::increaseAnim(Actor *a, int limb) { + Actor_v0 *a0 = (Actor_v0 *)a; + const uint16 limbPrevious = a->_cost.curpos[limb]++; - // Update 'speaking' frames? - if (A->_speaking) { - command = dir; // Incase standing frame was set as cmd - actorSpeak(A, command); + loadCostume(a->_costume); - // Update the limb speak frames - frameUpdate(A, command); - } -} + // 0x2543 + byte frame = _frameOffsets[a->_cost.curpos[limb] + a->_cost.active[limb]]; -byte C64CostumeLoader::increaseAnims(Actor *a) { - ActorC64 *A = (ActorC64 *)a; + // Is this frame invalid? + if (frame == 0xFF) { - // 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; + // Repeat timer has reached 0? + if (a0->_limbFrameRepeat[limb] == 0) { - actorSpeak(A, cmd); + // Use the previous frame + --a0->_cost.curpos[limb]; - // Update the limb frames - frameUpdate(A, cmd); - } + // Reset the comstume command + a0->_costCommandNew = 0xFF; + a0->_costCommand = 0xFF; + + // Set the frame/start to invalid + a0->_cost.frame[limb] = 0xFFFF; + a0->_cost.start[limb] = 0xFFFF; - if (A->_moving && _vm->_currentRoom != 1 && _vm->_currentRoom != 44) { - if (a->_cost.soundPos == 0) - a->_cost.soundCounter++; + } else { - // Is this the correct location? - // 0x073C - if (v0ActorTalkArray[a->_number] & 0x3F) - a->_cost.soundPos = (a->_cost.soundPos + 1) % 3; - } + // Repeat timer enabled? + if (a0->_limbFrameRepeat[limb] != -1) + --a0->_limbFrameRepeat[limb]; - // increase each frame pos - for (int limb = 0; limb < 8; ++limb) { - if (a->_cost.curpos[limb] < a->_cost.end[limb]) - a->_cost.curpos[limb]++; - else + // No, restart at frame 0 a->_cost.curpos[limb] = 0; + } } + // Limb frame has changed? + if (limbPrevious == a->_cost.curpos[limb]) + return 0; + return 1; } |