Jump to content
IGNORED

Part 8 - Score & Timer


SpiceWare

Recommended Posts

Added score & timer
 
Source Code
 
Download and unzip this in your shared directory.

Collect3_20200211.zip

 

ROM for reference

collect3_20200211.bin

 

 

 

Score & Timer

 

I like to implement routines for displaying the score early on in a project - you can see that in these early builds of Collect, Frantic, Medieval Mayhem, and Space Rocks.  Even though I'm not ready to show the score, the display is very useful for showing diagnostic information such as in this build of Frantic were I used the score to display the results of the software sprite collision1 routines.


One of the challenges when developing DPC+ARM code is that Stella does not emulate how long ARM code takes to run. As far as it's concerned, all ARM code will finish executing in 0 cycles of 6507 time. Because of this it's very easy to write something that will run just fine in emulation, but will cause screen jitters and/or rolls, or even a fatal crash when run on a real Atari. We're already checking timers in our 6507 code, so we can easily save those values and display them in the score.

 

For the game we need to display two scores and a timer. In the 2K version of Collect I used the playfield to show that information. For Collect 3 we're going to do this:

 

  • players are set to 3 copies with medium spacing
  • players are positioned so the middle copies occupy the middle 16 pixels of the display
  • playfield pixels are turned on behind all copies of the players
  • just like the ShowTwoColorGraphic routine used to display the menu, the players are colored black and used as stencils
  • playfield color is changed on the fly so each group of 16 pixels has a different color
  • use a 3 pixel font, and 1 pixel spacing, so we can display 4 digit scores for each player

 

For diagnostic purposes the difficult switches are used to control what is displayed:

 

Left B and Right B - Score and Timer for the game

collect3.thumb.png.98470e702ba7001ec7279a1460fa1dfd.png

 

Left A and Right B - Test Pattern

collect3_1.thumb.png.d7babd5e2f3c331cf81bf0ad1605131e.png

 

Left B and Right A - Timing Remaining in Vertical Blank and Overscan

collect3_3.thumb.png.06e56618299c582333522f0318c706d1.png

 

Left A and Right A - sprite X Y positions

collect3_2.thumb.png.43ed0c78846b44edce9df908210e166c.png

 

The test pattern shows an improvement over the prior version of the score & timer kernel that I used for the unfinished DPC+ tutorial:

score timer test pattern.png

 

Previously the update of player1 for the right player's score was 1 pixel too late, resulting in bit 7 of the timer being shown.  I worked around it then by designing the font to not use bit 7.

 

PrepScoreDatastreams()

 

A new function was added to prepare the datastreams for the score kernel.  Since we're using a skinny font, each datastream will contain graphics for 2 digits.  MergeCharacters() handles this:

 

void MergeCharacters(int datastream, int left_character, int right_character)
{
    int i;
    unsigned char *stream = RAM + datastream;
    unsigned char *left = ROM + _FONT + left_character * _FONT_HEIGHT;
    unsigned char *right = ROM + _FONT + right_character * _FONT_HEIGHT;
    
    for (i=0;i<_FONT_HEIGHT;i++)
        *stream++ = ((*left++) & 0xf0) + ((*right++) & 0x0f);
}


The character values of 0-15 correspond to graphics of 0-9 and A-F so that hex values can be shown using simple masking and/or bit shifting. These two calls prep the right score to show 4 hex digits of the frame counter:

        MergeCharacters(_BUF_SCORE1_A, (frame >> 12) & 0x0f, (frame >> 8) & 0x0f);
        MergeCharacters(_BUF_SCORE1_B, (frame >> 4) & 0x0f, frame & 0x0f);

 

This also means we'll be using binary-coded decimal (BCD) for the score, which you should already be familiar with from writing 6507 code.

 

Character values 16 and above are used for special characters, such as the colon used to show 2:00 in the timer display.

        MergeCharacters(_BUF_TIMERA, 2, 17);
        MergeCharacters(_BUF_TIMERB, 0, 0);

 

Constants are defined for these to make the source code easier to understand:

        MergeCharacters(_BUF_TIMERA, 2, _FONT_COLON);
        MergeCharacters(_BUF_TIMERB, 0, 0);

 

The 6507 does not support hardware multiplication, so score fonts tend to be designed to use 8 scanlines. This is because times 8 can be calculated using 3 ASL commands.  The ARM does support hardware multiplication, so the font for Collect3 uses 7 scanlines to show we have that option. Do note the ARM in the Harmony/Melody does not support hardware division.

 

 

TIA's hardware collision registers are not very helpful when multiplexing a multitude of sprite images through TIA's two players, some of the images might never be drawn on the same frame, so collision detection must be handled in software.

 

  • Like 2
Link to comment
Share on other sites

  • 2 months later...

I thought the break would be a week max, turned out to be a month. The last feature request is quite nice, I should have thought of it myself - you can now start a new game of Kaboom! Deluxe! via the paddle button.

 

Anyway, this weekend I plan to review where I left off on the CDFJ tutorial, then start work on Part 9 - Arena.

  • Like 1
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...