gemrb icon indicating copy to clipboard operation
gemrb copied to clipboard

Animated portraits drawing regression

Open lynxlynxlynx opened this issue 1 year ago • 10 comments

Now they flicker like mad, draw over each other (like the same pixels are used for all of them) ... ok this is hard to reproduce, only a save in ar0800 does it for me.

lynxlynxlynx avatar Jul 20 '23 22:07 lynxlynxlynx

690bf4eeec — SameResource removal. I guess we'd need to know the current cycle to be able to do fewer updates in UpdateAnimatedPortrait?

lynxlynxlynx avatar Jul 21 '23 14:07 lynxlynxlynx

That would match the previous behavior. Seems like that would still interrupt an in progress animation tho (if we even care). We could probably add the current cycle to GetPlayerPortrait.

bradallred avatar Jul 21 '23 14:07 bradallred

Or keep track on the python side, since it's only set there. We were likely interrupting in-progress animations on cycle change before as well.

lynxlynxlynx avatar Jul 21 '23 14:07 lynxlynxlynx

we were, yes. If we don't care about that then its easy.

bradallred avatar Jul 21 '23 15:07 bradallred

I guess it's easy to do it right as well: GetPlayerPortrait could just get also an EndReached key and we skip updates until it's true and the cycle mismatches.

lynxlynxlynx avatar Jul 21 '23 15:07 lynxlynxlynx

yeah, thats good. feels slightly redundant tho, since the animation is removed once it ends there could only be a cycle key while it is animating. If we do that, then we can also drop IE_GUI_BUTTON_PLAYRANDOM, no? Just randomly generate the cycle on the python side.

bradallred avatar Jul 21 '23 15:07 bradallred

I don't know about IE_GUI_BUTTON_PLAYRANDOM, but it's true this is its only use right now. Also I was wrong, we do need to sometimes update to the same animation, otherwise they'd effectively be only playing once if nothing changes.

lynxlynxlynx avatar Jul 21 '23 15:07 lynxlynxlynx

hmmmm, would they? if IE_GUI_BUTTON_PLAYRANDOM is set then the animation should keep selecting animations, and if IE_GUI_BUTTON_PLAYONCE is set then the animation is removed which would mean the cycle would be different (null).

To me, it looks like we can simply drop IE_GUI_BUTTON_PLAYRANDOM, and just use IE_GUI_BUTTON_PLAYONCE so that the animation gets removed, then rerolled on the next update. Might need a time limiter tho, because SpriteAnimation::CalculateNextFrameDelta is more involved than I thought.

bradallred avatar Jul 21 '23 15:07 bradallred

What would then "reroll" it? Anyway, you know this code better, so I leave it you.

lynxlynxlynx avatar Jul 21 '23 15:07 lynxlynxlynx

I thought UpdateAnimatedPortrait was called every frame (or close enough).

I have another idea that might yield cleaner results. What if we add this to Button:

struct Action {
	// !!! Keep these synchronized with GUIDefines.py !!!
	static const Control::Action EndReached = ACTION_CUSTOM(0); // animation has concluded
};

then, we setup a handler on the python side and don't even do this in UpdateAnimatedPortrait. I suspect there are other places this would improve things. Maybe UpdateMageWindow and UpdatePriestWindow could be simplified. A lot of these "update" functions feel like the just get called all the time because we had no better way of knowing when and what to update.

But yeah, I'll poke at it.

bradallred avatar Jul 21 '23 15:07 bradallred