actor_logic_changeframe was allowing frame counters to increment out of control leading to unpredictable behavior when changing state, animations would be outside their frame range

This commit is contained in:
2025-08-09 08:54:12 -04:00
parent e20752a97e
commit 93bc3addfe
3 changed files with 26 additions and 18 deletions

View File

@@ -91,15 +91,16 @@ ErrorContext *actor_logic_changeframe(actor *obj, sprite *curSprite, SDL_Time cu
obj->curSpriteFrameId -= 1;
}
// are we at the end of the animation?
} else if ( obj->curSpriteFrameId == (curSprite->frames-1) ) {
} else if ( obj->curSpriteFrameId >= (curSprite->frames-1) ) {
// are we set to loop in reverse?
if ( curSprite->loop == true && curSprite->loopReverse == true ) {
obj->curSpriteReversing = true;
obj->curSpriteFrameId -= 1;
// are we set to loop forward?
} else if ( curSprite->loop == true ) {
} else {
// we are at the end of the animation and we either loop forward or do not loop
obj->curSpriteFrameId = 0;
}
}
// we are not looping in reverse and we are not at the end of the animation
} else {
obj->curSpriteFrameId += 1;
@@ -221,6 +222,7 @@ ErrorContext *actor_render(actor *obj, SDL_Renderer *renderer)
} CLEANUP {
} PROCESS(errctx) {
} HANDLE(errctx, ERR_KEY) {
} HANDLE_GROUP(errctx, ERR_OUTOFBOUNDS) {
// If an actor doesn't have a sprite for a state, just log it and move on
LOG_ERROR(errctx);
} FINISH(errctx, true);
@@ -228,6 +230,12 @@ ErrorContext *actor_render(actor *obj, SDL_Renderer *renderer)
if ( ! visible ) {
SUCCEED_RETURN(errctx);
}
if ( (obj->curSpriteFrameId > curSprite->frames) ) {
// This isn't necessarily an error - this actor's frame index is outside the range of
// their current sprite. There are a number of reasons this could happen, and it will
// get cleaned up on the next logic update. Just pass on rendering them this frame.
SUCCEED_RETURN(errctx);
}
src.x = curSprite->width * curSprite->frameids[obj->curSpriteFrameId];
if ( src.x >= curSprite->sheet->texture->w ) {