Flickerama
Think I figured out the cause of the glitch.
I use 4 datastreams to draw all the players(sprites in 2600 terminology) on the screen. Each player gets 2 datastreams, one for the image and one for the color. A 0 value in the color datastream is used to trigger a reposition of a player. The color datastreams are pre filled with 15 (white) so that missiles will be visible on scanlines without the corresponding player present.
When a reposition is triggered, 2 bytes in the image datastream are used to point to the reposition routine (there's 11 per player), and an additional byte in the color datastream holds the fine-adjustment value that goes into HMP0 or HMP1.
This sets it for Player 0
gP0DataStream[y + position ] = flashdata[P0_HMOVE + hmove * 2 ]; gP0DataStream[y + position + 1] = flashdata[P0_HMOVE + hmove * 2 +1 ]; gC0DataStream[y + position ] = 0; // 0 triggers reposition gC0DataStream[y + position + 1] = x; // HMP0
while this sets it for Player 1
gP1DataStream[y + position + 1] = flashdata[P1_HMOVE + hmove * 2 ]; gP1DataStream[y + position + 2] = flashdata[P1_HMOVE + hmove * 2 +1 ]; gC1DataStream[y + position ] = 0; // 0 triggers reposition gC1DataStream[y + position + 2] = x; // HMP1
Player 0 takes 2 scanlines for a reposition, player 1 takes 3.
2 repositions cannot be occuring at the same time, so each routine looks for a conflicting 0 in the color datastream, and adjusts if necessary so no conflict occurs. Player 0 uses:
// it takes 2 scanlines to reposition Player 0 // make sure we don't conflict with a reposition of Player 1, which takes 3 scanlines // -6 0 -6 // -5 1 0 0 -5 // -4 1 0 0 1 -4 // -3 1 0 0 1 1 -3 // -2 0 0 1 1 1 -2 // -1 0 1 1 1 -1 position = -2; // it takes 2 scanlines to reposition Player 0 // make sure we don't conflict with a reposition of Player 1, which takes 3 scanlines if (gC1DataStream[y-1] == 0) position = -3; if (gC1DataStream[y-2] == 0) position = -4; if (gC1DataStream[y-3] == 0) position = -5; if (gC1DataStream[y-4] == 0) position = -6;
while player 1 uses:
// it takes 3 scanlines to reposition Player 1 // make sure we don't conflict with a reposition of Player 0, which takes 2 scanlines // -7 1 -7 // -6 1 1 -6 // -5 0 1 1 1 -5 // -4 0 1 1 1 0 -4 // -3 1 1 1 0 0 -3 // -2 1 1 0 0 -2 // -1 1 0 0 -1 position = -3; if (gC0DataStream[y-1] == 0) position = -4; if (gC0DataStream[y-2] == 0) position = -5; if (gC0DataStream[y-3] == 0) position = -6; if (gC0DataStream[y-4] == 0) position = -7;
The conflict was happening when the HMP0 or HMP1 value was 0. If HMP1 was 0, then the routines to position player 0 became confused when it was checking for a reposition conflict. Likewise if HMP1 was 0 then player 1's routine became confused.
The HMPx register only needs the upper 4 bits of the byte, so to prevent the 0 conflict I set the bottommost bit to 1.
The last digit of the score is the worst case flicker for at last 1 player on the current display.
0 = no flicker
1 = 30 hz (every other frame)
2 = 20 hz (every 3rd frame)
3 = 15 hz (every 4th frame)
Stella only does the phosphor effect over 2 frames, so if anything is at a flicker level of 2 or higher then robots will be missing from snapshots.
The Berzerk style maze with 5 robots per horizontal band ends up with 1 or 2
The Frenzy style maze with 6 robots per horizontal band ends up with 2, with a rare appearance of 1
This is the worse-case for the starting point of the display. In an actual game you won't always see the maximum number of robots on a particular level, so 0 flicker is possible.
I've also re-evaluted the PAL version and decided to do it as PAL60.
ROM
Source
5 Comments
Recommended Comments