Jitter 3, Recovery Time
Last time around I added jitter emulation to Stella, which became part of the official build with version 4.6.5. The jitter emulation basically moves the screen up/down in response to inconsistent scanline counts, similar to that which occurs on a real TV. I added it because people without an Atari would often write games with variable scanline counts, but not realize it until others play-tested the game on real hardware.
One thing it didn't emulate was a recovery time - if the difference in scanline counts is large a real TV will take multiple frames to recover. Instead, the original implementation would recover in just a single frame - blink and you might miss it.
TIA.hxx
Added a variable for recovery time:
// large jitter values will take multiple frames to recover from Int32 myJitterRecovery;
TIA.cxx
Added a constant for the threshold for triggering recovery time. I went with 5, but it can easily be changed.
#define JITTER_RECOVERY 5
Initialize the new variable:
void TIA::initialize() { ... myNextFrameJitter = myCurrentFrameJitter = myJitterRecovery = 0; ... }
Update the jitter logic to use the new variable and constant:
inline void TIA::endFrame() { ... // Account for frame jitter, skipping the first few frames if(myJitterEnabled && myFrameCounter > 3) { // Set the jitter amount for the current frame myCurrentFrameJitter = (myNextFrameJitter + myJitterRecovery*JITTER_RECOVERY)* 160; if (myJitterRecovery < 0) myJitterRecovery++; else if (myJitterRecovery > 0) myJitterRecovery--; // Calculate the jitter amount for the next frame. // Jitter amount of a frame depends upon the difference // between the scanline counts of the prior two frames. myNextFrameJitter = myScanlineCountForLastFrame - previousCount; if(myNextFrameJitter < -1) { if (myNextFrameJitter/JITTER_RECOVERY < myJitterRecovery) { myJitterRecovery = myNextFrameJitter/JITTER_RECOVERY; myNextFrameJitter = 0; // Make sure currentFrameBuffer() doesn't return a pointer that // results in memory being accessed outside of the 160*320 bytes // allocated for the frame buffer if(myJitterRecovery*JITTER_RECOVERY < -Int32(myFrameYStart)) myJitterRecovery = myFrameYStart/JITTER_RECOVERY; } else { myNextFrameJitter = (myNextFrameJitter-1) / 2; // Make sure currentFrameBuffer() doesn't return a pointer that // results in memory being accessed outside of the 160*320 bytes // allocated for the frame buffer if(myNextFrameJitter + myJitterRecovery*JITTER_RECOVERY < -Int32(myFrameYStart)) myNextFrameJitter = myFrameYStart; } } else if(myNextFrameJitter > 1) { if (myNextFrameJitter/JITTER_RECOVERY > myJitterRecovery) { myJitterRecovery = myNextFrameJitter/JITTER_RECOVERY; myNextFrameJitter = 0; // Make sure currentFrameBuffer() doesn't return a pointer that // results in memory being accessed outside of the 160*320 bytes // allocated for the frame buffer if(myJitterRecovery*JITTER_RECOVERY > 320 - Int32(myFrameYStart) - Int32(myFrameHeight)) myJitterRecovery = (320 - myFrameYStart - myFrameHeight)/JITTER_RECOVERY; } else { myNextFrameJitter = (myNextFrameJitter+1) / 2; // Make sure currentFrameBuffer() doesn't return a pointer that // results in memory being accessed outside of the 160*320 bytes // allocated for the frame buffer if(myNextFrameJitter + myJitterRecovery*JITTER_RECOVERY > 320 - Int32(myFrameYStart) - Int32(myFrameHeight)) myNextFrameJitter = 320 - myFrameYStart - myFrameHeight; } } else myNextFrameJitter = 0; } ... }
How to Test
To test it, I built a new program called Jitter. The rainbow section defaults to 128 scanlines:
Use joystick up/down/left/right to change the displayed count:
Hold down FIRE to activate that count:
Release FIRE and the rainbow section will revert back to 128 scanlines. The displayed count will stay whatever you set it to, it only becomes active when FIRE is held. Hit GAME RESET if you wish to reset the count back to 128.
Additionally you can use the TV Type switch to specify NTSC(Color) or PAL(B&W) screen size. If you change this be sure to use CONTROL-F to set Stella to display using the correct TV standard.
Test build of Stella for OS X. I changed the version to display 4.7 dgs so you can easily compare the difference with the release version 4.7:
Stella Jitter Improvement.app.zip
The above build uses 5 for JITTER_RECOVERY, this build uses 10:
Stella Jitter Improvement 10.app.zip
I'm not set up to build Stella for other platforms, so here's the source changes for the TIA files. Not included is the version, you can change that in common/Version.hxx:
TIA source.zip
Jitter ROM:
jitter.bin
Jitter Source:
Jitter.zip
If this looks good to y'all I'll submit the changes to stephena.
- 4
8 Comments
Recommended Comments