Implement pause when playback ends to pause when a macro completes, and start/stop timer automatically so that the timer will start and stop and the beginning and end of macro playback.
For pause when playback ends, I tested that when playing a macro that is 20 frames long, all macro frames are applied and we end with the pause display showing 20/20. Frame advancing or unpausing from here will let the game continue normally (my first try blocked advancing past the end frame entirely unless you stopped movie playback, which I thought was a little annoying).
For start/stop timer automatically, I moved the timer logic closer to the pausing logic in state_main_hook. I added a new gz struct member to detect if the pause state changed. I considered updating gz.timer_active every time we modify gz.frames_queued, but that seemed fragile, and it's easy to make off-by-one errors: since updating the timer adds the time between the previous frame and the current frame, any change should take effect on the next frame.
I tested this by timing a macro with some pauses, loading zone transitions, and laggy areas and it seems decently accurate. The timer works even when frame advancing although it's somewhat inaccurate. I also changed the timer display to show hundredths of a second.
There doesn't seem to be any infrastructure for updating the settings version so I hope adding these new settings in-place is fine. I added a memset to explicitly set unused settings to 0 for future versions.
Implement pause when playback ends to pause when a macro completes, and start/stop timer automatically so that the timer will start and stop and the beginning and end of macro playback.
For pause when playback ends, I tested that when playing a macro that is 20 frames long, all macro frames are applied and we end with the pause display showing 20/20. Frame advancing or unpausing from here will let the game continue normally (my first try blocked advancing past the end frame entirely unless you stopped movie playback, which I thought was a little annoying).
For start/stop timer automatically, I moved the timer logic closer to the pausing logic in
state_main_hook
. I added a newgz
struct member to detect if the pause state changed. I considered updatinggz.timer_active
every time we modifygz.frames_queued
, but that seemed fragile, and it's easy to make off-by-one errors: since updating the timer adds the time between the previous frame and the current frame, any change should take effect on the next frame.I tested this by timing a macro with some pauses, loading zone transitions, and laggy areas and it seems decently accurate. The timer works even when frame advancing although it's somewhat inaccurate. I also changed the timer display to show hundredths of a second.
There doesn't seem to be any infrastructure for updating the settings version so I hope adding these new settings in-place is fine. I added a
memset
to explicitly set unused settings to 0 for future versions.