I recently recieved a feature request to implement a "lag detector" in Gens.
Initially I dismissed the request, thinking that it would be far too difficult to implement something to detect all forms of lag.
However, there's a very simple way to detect 98% of lag in every game.
it works like this:
On new frame: Set "Lag flag" on.
On controller read: Set "Lag flag" off.
If "Lag flag" set at end of frame: Display something.
This is a very simple feature to code, and it will come in quite handy while TASing, to know whether or not your input was read on any given frame.
How fleeting are all human passions compared with the massive continuity of ducks.
Snes9x 1.51 actually has this. There's a config option called "MovieNotifyIgnored" that shows something in the frame counter if the last frame didn't do any controller reads. It wasn't completely trivial to implement because the SNES has several different ways of doing controller reads. I think one of them was only used by a few games and detecting it made most other games give less-useful lag information.
Uhh, I wanted to add my 2cents, but somehow it evolved into huge post. 8-[] Ok, here's my take on lag problem.
Usually, detecting lag frames isn't so hard even without additional indicator. It would be more useful to keep a track of lag summary during various periods of playing - to know exactly how much lag you caused by providing a line of input. With this you can not only try to prevent lag at each frame possible, but to manage lag as you wish.
So, indicator isn't real step here. Simple lag counter can provide much flexible approach to handling lag (while it can be realized almost as easy as indicator).
For example, I applied such counter to Darkwing Duck TAS I'm working on with Randil. To say the least, this counter helped to improve run very efficiently - now we can directly compare saveral movies and find the best route with which the final sum of lag frames would be the least.
Also I used this counter to arrange lag frames with better use. For example, if I let 3 lag frames happen at the beginning + 4 lag frames at the middle of level, it finally appeared to be better then allowing 5 lag frames at the beginning + 2 at the middle.
And no, there was no way to reduce lag to less then 7 frames in total. So I haven't reduced lag, but still with careful rearranging I've got 2 frames saved by shifting lag into less important frames of gameplay.
I doubt such result would be acieved by simply detecting lag.
Here I'll explain how my lag counter works. Well, there are RAM addresses in the game which can indicate lag in current frame, but I didn't use them for counting. The idea is more closer to theoretical definitio of "lag". Lag appears when game loop can't catch to real clock. For example, if a game tries to sync with Vblank (as usually games do), it tries to execute 60 iterations of its loop per a second. Thus there should be 60 controller reads per second and so on.
I've initialized new timer, inserted code (that increments this timer) into NMI handler and another code (that decrements this timer) into joystick reading subroutine (although that was not the only possible place to insert it).
Yeah, I'm not so familiar with FCEU modding, so I inserted new tool right into the game (Darkwing Duck ROM) - there were a couple of troubles to shoot (like optimizing original code to retrieve several CPU ticks for INC/DEC instructions - because movie should sync with both modified and original ROM), but also there's one advantage - final result can be played anywhere - from NES hardware to Famtasia emulator (I used it to see lag in currently published movie).
If there's still something unclear, here's how this timer works. Every time (normally - every frame) when game reads joypad input, it decrements the timer by 1. But then NMI (generated every frame - that's for sure :)) increases the timer back to zero (or whatever it was initialized with).
When the game doesn't read input (lag frame), NMI still increases timer. So, for every frame of lag the timer will be increased by 1. In my example (Darkwing Duck.nes) I used RAM to store the timer, thus one address in Memory Watcher can be used both as lag indicator and lag counter.
Well, of course it's better to insert such tool into emulator, not a game. But I'm not sure when I'd feel like modifying FCEU myself, plus the idea is universal for all emulators (FCEU, Gens, Snes9x, VBA), so I drew the picture to fully disclose the concept (well, + dream tool added ;)).
Another picture with some explanations...
Here's how this tool could be used for TASing.
First, of course it would provide new degree of freedom in reducing lag - you can dynamically analyze cpu usage and search for causes of possible lag.
Then, it can be used to optimize unavoidable lag and still get some advantage of rearranging lag frames.
Finally, it could be used for creating lag deliberately - it opens new way to abusing glitches and programm features. E.g. there are games that don't verify collisions during lag frames (I've personally met it in Rockin' Kats, also heard smth like this about Rockman2).
After all, polishing movie is not only about reducing lag, it's about managing lag in needed ways.
At least on the SNES, checking for when the input is used will give you some interesting additional information besides knowing when the game is lagging. For example, "oh, it's not even looking at my input while this dialogue box is up, so I don't need to try making it go away on then". So, while it can't tell lag apart from normally ignored input, I would say that's not a bad thing.
One annoying thing about any such indicator is that without it using some rewind mechanism it can only know after the frame if the input was ignored. It would be more helpful to know before the frame is recorded, so you wouldn't have to waste time recording that frame and then mentally subtracting one from the frame count to know which frame the lag happened on.
I meant that initially it would catch some useful things that it really shouldn't have because although it happened to be correct in the game I was testing, other games could do the same thing and not be ignoring the input. I shouldn't have said less useful, it's simply more strict.
So, that's why it's better to have a list of possible options - at which point emulator should set "Lag flag" off (or to decrement Lag Counter in my example). For some games it will be controller read, for other - some graphic event (like filling sprite buffer on NES - FCEU should catch writing to port $4014), and for very uncommon cases there should be a way to manually find checkpoint (by tracing code in debugger or just by pure luck) and stick lag indicator to that piece of code.
I don't object to what you're saying (I can't argue that adding a flexible system like that would be a bad thing), but I do object to the way you're using what I said as a motivator for it. I did not say I have ever seen the controller-check method fail to catch lag. In fact I wish I hadn't brought it up because I think I was remembering a specific problem I already corrected.
Actually I want to thank you for bringing the question up. :) I think, it's kinda important. Well, I also haven't seen conrollercheck-method fail to catch lag (well, in theory, some obscure games might read input via interrupt handler, that'd be the case). But this method still provides too much fake outcome (for example, in DarkwingDuck I had to keep several Counter resets to be able to strictly distinguish uncontrollable points and actual lag), thus signal-to-noise result isn't very good. I think, tools should be as much comfortable for random TASer as possible.
Excuse my somewhat offtopic post, but do you think this method is accurate? The reason I'm asking this is because I tried hacking a counter in a game before, but even after I matched the new subroutine to the old one (in amount of CPU cycles taken) the movie would eventually desync.
Edit: I forgot to mention that adding 9 more CPU cylces than the original subroutine actually makes the movie sync for 30 more minutes. So I really have no idea what's going on here...
The method isn't accurate. You have to be really lucky (also very careful with managing CPU cycles).
In theory, if you made everything right, it should sync well, but as emulators aren't perfect, it depends. Also note that SNES/GBA emulation is still much less accurate than NES emulation.
So that's only temporary and risky solution, it's better to insert tools into emulator environment.