diff --git a/inc/sprite_eng.h b/inc/sprite_eng.h index 853c6f34..ee55f4cc 100644 --- a/inc/sprite_eng.h +++ b/inc/sprite_eng.h @@ -844,14 +844,14 @@ bool SPR_getAutoAnimation(Sprite* sprite); void SPR_setAnimationLoop(Sprite* sprite, bool value); /** * \brief - * Return TRUE if animation ended / looped.
- * This can be used with the frame change callback (see #SPR_setFrameChangeCallback(..)) to detect - * the end of sprite animation and do appropriate action if required. + * Return TRUE if the sprite reached the last frame of the current animation.
+ * When auto animation is enabled (see SPR_setAutoAnimation(..)) the function returns TRUE only when we reach + * the last *tick* of the last animation frame.
+ * When auto animation is disabled the function returns TRUE as soon we are on last animation frame. * - * \see SPR_FLAG_DISABLE_ANIMATION_LOOP - * \see #SPR_setAnimationLoop(Sprite*, bool) + * \see #SPR_setAutoAnimation(Sprite*, bool) */ -bool SPR_getAnimationDone(Sprite* sprite); +bool SPR_isAnimationDone(Sprite* sprite); /** * \brief * Set the VRAM tile position reserved for this sprite. diff --git a/inc/sprite_eng_legacy.h b/inc/sprite_eng_legacy.h index 8180bd1e..38895598 100644 --- a/inc/sprite_eng_legacy.h +++ b/inc/sprite_eng_legacy.h @@ -837,14 +837,14 @@ bool SPR_getAutoAnimation(Sprite* sprite); void SPR_setAnimationLoop(Sprite* sprite, bool value); /** * \brief - * Return TRUE if animation ended / looped.
- * This can be used with the frame change callback (see #SPR_setFrameChangeCallback(..)) to detect - * the end of sprite animation and do appropriate action if required. + * Return TRUE if the sprite reached the last frame of the current animation.
+ * When auto animation is enabled (see SPR_setAutoAnimation(..)) the function returns TRUE only when we reach + * the last *tick* of the last animation frame.
+ * When auto animation is disabled the function returns TRUE as soon we are on last animation frame. * - * \see SPR_FLAG_DISABLE_ANIMATION_LOOP - * \see #SPR_setAnimationLoop(Sprite*, bool) + * \see #SPR_setAutoAnimation(Sprite*, bool) */ -bool SPR_getAnimationDone(Sprite* sprite); +bool SPR_isAnimationDone(Sprite* sprite); /** * \brief * Set the VRAM tile position reserved for this sprite. diff --git a/lib/libmd.a b/lib/libmd.a index c656201b..c682a68c 100644 Binary files a/lib/libmd.a and b/lib/libmd.a differ diff --git a/lib/libmd_debug.a b/lib/libmd_debug.a index 5371804e..542b4b55 100644 Binary files a/lib/libmd_debug.a and b/lib/libmd_debug.a differ diff --git a/src/sprite_eng.c b/src/sprite_eng.c index 8cbc3a8b..347668b0 100644 --- a/src/sprite_eng.c +++ b/src/sprite_eng.c @@ -47,8 +47,6 @@ #define NEED_UPDATE 0x000F -#define STATE_ANIMATION_DONE 0x0010 - // shared from vdp_spr.c unit extern void logVDPSprite(u16 index); @@ -1004,7 +1002,7 @@ void SPR_setAnimAndFrame(Sprite* sprite, s16 anim, s16 frame) KLog_U3("SPR_setAnimAndFrame: #", getSpriteIndex(sprite), " anim=", anim, " frame=", frame); #endif // SPR_DEBUG - sprite->status = (sprite->status & ~STATE_ANIMATION_DONE) | NEED_FRAME_UPDATE; + sprite->status |= NEED_FRAME_UPDATE; } END_PROFIL(PROFIL_SET_ANIM_FRAME) @@ -1040,7 +1038,7 @@ void SPR_setAnim(Sprite* sprite, s16 anim) KLog_U2_("SPR_setAnim: #", getSpriteIndex(sprite), " anim=", anim, " frame=0"); #endif // SPR_DEBUG - sprite->status = (sprite->status & ~STATE_ANIMATION_DONE) | NEED_FRAME_UPDATE; + sprite->status |= NEED_FRAME_UPDATE; } END_PROFIL(PROFIL_SET_ANIM_FRAME) @@ -1091,19 +1089,9 @@ void SPR_nextFrame(Sprite* sprite) if (frameInd >= anim->numFrame) { - // animation done marker - sprite->status |= STATE_ANIMATION_DONE; - // no loop ? if (sprite->status & SPR_FLAG_DISABLE_ANIMATION_LOOP) { - // prevent further animation - SPR_setAutoAnimation(sprite, FALSE); - - // frame change event handler defined ? --> call it now so we let user now about STATE_ANIMATION_DONE - if (sprite->onFrameChange) - sprite->onFrameChange(sprite); - // can quit now END_PROFIL(PROFIL_SET_ANIM_FRAME) return; @@ -1126,7 +1114,7 @@ void SPR_setAutoAnimation(Sprite* sprite, bool value) if (value) { - // disabled ? --> reset timer to current frame timer + // currently disabled ? --> reset timer to current frame timer if (sprite->timer == -1) sprite->timer = sprite->frame->timer; } @@ -1135,6 +1123,10 @@ void SPR_setAutoAnimation(Sprite* sprite, bool value) // disable it sprite->timer = -1; } + +#ifdef SPR_DEBUG + KLog_U2("SPR_setAutoAnimation: #", getSpriteIndex(sprite), " AutoAnimation=", value); +#endif // SPR_DEBUG } bool SPR_getAutoAnimation(Sprite* sprite) @@ -1152,15 +1144,19 @@ void SPR_setAnimationLoop(Sprite* sprite, bool value) if (value) sprite->status &= ~SPR_FLAG_DISABLE_ANIMATION_LOOP; else sprite->status |= SPR_FLAG_DISABLE_ANIMATION_LOOP; -} +#ifdef SPR_DEBUG + KLog_U2("SPR_setAnimationLoop: #", getSpriteIndex(sprite), " loop=", value); +#endif // SPR_DEBUG +} -bool SPR_getAnimationDone(Sprite* sprite) +bool SPR_isAnimationDone(Sprite* sprite) { // for debug checkSpriteValid(sprite, "SPR_getAnimationDone"); - return (sprite->status & STATE_ANIMATION_DONE)?TRUE:FALSE; + // last tick on last animation frame + return (sprite->timer <= 1) && (sprite->frameInd == (sprite->animation->numFrame - 1)); } bool SPR_setVRAMTileIndex(Sprite* sprite, s16 value) diff --git a/src/sprite_eng_legacy.c b/src/sprite_eng_legacy.c index 4a8706fd..e984146e 100644 --- a/src/sprite_eng_legacy.c +++ b/src/sprite_eng_legacy.c @@ -49,7 +49,6 @@ #define NEED_UPDATE 0x001F -#define STATE_ANIMATION_DONE 0x0020 // shared from vdp_spr.c unit extern void logVDPSprite(u16 index); @@ -1018,8 +1017,7 @@ void SPR_setAnimAndFrame(Sprite* sprite, s16 anim, s16 frame) KLog_U3("SPR_setAnimAndFrame: #", getSpriteIndex(sprite), " anim=", anim, " frame=", frame); #endif // SPR_DEBUG - sprite->status = (sprite->status & ~STATE_ANIMATION_DONE) | NEED_FRAME_UPDATE; - //sprite->status |= NEED_FRAME_UPDATE; + sprite->status |= NEED_FRAME_UPDATE; } END_PROFIL(PROFIL_SET_ANIM_FRAME) @@ -1055,8 +1053,7 @@ void SPR_setAnim(Sprite* sprite, s16 anim) KLog_U2_("SPR_setAnim: #", getSpriteIndex(sprite), " anim=", anim, " frame=0"); #endif // SPR_DEBUG - sprite->status = (sprite->status & ~STATE_ANIMATION_DONE) | NEED_FRAME_UPDATE; - //sprite->status |= NEED_FRAME_UPDATE; + sprite->status |= NEED_FRAME_UPDATE; } END_PROFIL(PROFIL_SET_ANIM_FRAME) @@ -1105,21 +1102,11 @@ void SPR_nextFrame(Sprite* sprite) const Animation *anim = sprite->animation; u16 frameInd = sprite->frameInd + 1; - if (frameInd >= anim->numFrame) + if (frameInd >= anim->numFrame) { - // animation done marker - sprite->status |= STATE_ANIMATION_DONE; - // no loop ? if (sprite->status & SPR_FLAG_DISABLE_ANIMATION_LOOP) { - // prevent further animation - SPR_setAutoAnimation(sprite, FALSE); - - // frame change event handler defined ? --> call it now so we let user now about STATE_ANIMATION_DONE - if (sprite->onFrameChange) - sprite->onFrameChange(sprite); - // can quit now END_PROFIL(PROFIL_SET_ANIM_FRAME) return; @@ -1137,29 +1124,34 @@ void SPR_nextFrame(Sprite* sprite) void SPR_setAutoAnimation(Sprite* sprite, bool value) { + // for debug + if (!isSpriteValid(sprite, "SPR_setAutoAnimation")) + return; + if (value) { - // disabled ? --> reset timer to current frame timer + // currently disabled ? --> reset timer to current frame timer if (sprite->timer == -1) sprite->timer = sprite->frame->timer; } else { - // enabled ? --> disable it - if (sprite->timer != -1) - sprite->timer = -1; + // disable it + sprite->timer = -1; } #ifdef SPR_DEBUG KLog_U2("SPR_setAutoAnimation: #", getSpriteIndex(sprite), " AutoAnimation=", value); #endif // SPR_DEBUG - } bool SPR_getAutoAnimation(Sprite* sprite) { - return (sprite->timer != -1)?TRUE:FALSE; + // for debug + if (!isSpriteValid(sprite, "SPR_getAutoAnimation")) + return FALSE; + return (sprite->timer != -1)?TRUE:FALSE; } void SPR_setAnimationLoop(Sprite* sprite, bool value) @@ -1174,18 +1166,16 @@ void SPR_setAnimationLoop(Sprite* sprite, bool value) #ifdef SPR_DEBUG KLog_U2("SPR_setAnimationLoop: #", getSpriteIndex(sprite), " loop=", value); #endif // SPR_DEBUG - } - -bool SPR_getAnimationDone(Sprite* sprite) +bool SPR_isAnimationDone(Sprite* sprite) { // for debug - if (!isSpriteValid(sprite, "SPR_getAnimationDone")) + if (!isSpriteValid(sprite, "SPR_isAnimationDone")) return FALSE; - return (sprite->status & STATE_ANIMATION_DONE)?TRUE:FALSE; - //return sprite->frameInd >= sprite->animation->numFrame; + // last tick on last animation frame + return (sprite->timer <= 1) && (sprite->frameInd == (sprite->animation->numFrame - 1)); }