SCUMM: fix minor (and rare) costume rendering glitch

(DOTT bug mentioned here: https://github.com/scummvm/scummvm/pull/3795/)

I found this in all versions from 1 to 6, so I applied the fix to all non-AKOS and non-v0 costumes.
This commit is contained in:
athrxx 2022-04-20 01:24:53 +02:00
parent 4d45a0f152
commit 2adc35e261
3 changed files with 24 additions and 8 deletions

View file

@ -1516,6 +1516,16 @@ void Actor::setDirection(int direction) {
vald = _cost.frame[i];
if (vald == 0xFFFF)
continue;
if (!(_vm->_game.features & GF_NEW_COSTUMES)) {
// Fix bug mentioned here: https://github.com/scummvm/scummvm/pull/3795/
// For versions 1 to 6 we need to store the direction info in the frame array (like
// the original interpreters do). I haven't found any signs that v7/8 require it, though.
// I haven't checked HE, but since it uses the same AKOS costumes as v7/8 I leave that
// as it is...
if ((vald & 3) == newDirToOldDir(direction))
continue;
vald >>= 2;
}
_vm->_costumeLoader->costumeDecodeData(this, vald, (_vm->_game.version <= 2) ? 0xFFFF : aMask);
}
@ -3800,6 +3810,14 @@ void Actor::saveLoadWithSerializer(Common::Serializer &s) {
setDirection(_facing);
}
if (s.isLoading() && _vm->_game.version > 0 && !(_vm->_game.features & GF_NEW_COSTUMES) && s.getVersion() < VER(105)) {
// For older saves, we can't reconstruct the frame's direction if it is different from the actor
// direction, this is the best we can do. However, it seems to be relevant only for very rare
// edge cases, anyway...
for (int i = 0; i < 16; ++i)
_cost.frame[i] = (_cost.frame[i] << 2) | newDirToOldDir(_facing);
}
}
void Actor_v3::saveLoadWithSerializer(Common::Serializer &s) {

View file

@ -773,7 +773,7 @@ byte NESCostumeRenderer::drawLimb(const Actor *a, int limb) {
palette = darkpalette;
src = _loaded._dataOffsets;
anim = 4 * cost.frame[limb] + newDirToOldDir(a->getFacing());
anim = cost.frame[limb];
frameNum = cost.curpos[limb];
frame = src[src[2 * anim] + frameNum];
@ -967,10 +967,8 @@ void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask)
loadCostume(a->_costume);
anim = newDirToOldDir(a->getFacing()) + frame * 4;
if (anim > _numAnim) {
if (anim > _numAnim)
return;
}
if (_vm->_game.id == GID_LOOM && _vm->_game.platform == Common::kPlatformPCEngine)
baseptr = _dataOffsets + anim * 2 + 2;
@ -1006,7 +1004,7 @@ void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask)
if (j == 0xFFFF) {
a->_cost.curpos[i] = 0xFFFF;
a->_cost.start[i] = 0;
a->_cost.frame[i] = frame;
a->_cost.frame[i] = anim;
} else {
extra = *r++;
cmd = _animCmds[j];
@ -1019,7 +1017,7 @@ void ClassicCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask)
a->_cost.end[i] = j + (extra & 0x7F);
if (extra & 0x80)
a->_cost.curpos[i] |= 0x8000;
a->_cost.frame[i] = frame;
a->_cost.frame[i] = anim;
}
}
} else {
@ -1162,7 +1160,7 @@ void NESCostumeLoader::costumeDecodeData(Actor *a, int frame, uint usemask) {
a->_cost.curpos[0] = 0;
a->_cost.start[0] = 0;
a->_cost.end[0] = _dataOffsets[2 * anim + 1];
a->_cost.frame[0] = frame;
a->_cost.frame[0] = anim;
}
byte NESCostumeLoader::increaseAnims(Actor *a) {

View file

@ -67,7 +67,7 @@ struct SaveInfoSection {
#define SaveInfoSectionSize (4+4+4 + 4+4 + 4+2)
#define CURRENT_VER 104
#define CURRENT_VER 105
#define INFOSECTION_VERSION 2
#pragma mark -