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));
}