Previously I talked a little bit about text handling as a preamble to this update which focuses on CI's high score keeping.
The high score table is essentially one big text string containing ranks, initials and scores for the top ten players. As such, rendering the high score table is simply a matter of starting at the beginning of the string and printing each rank in turn, advancing the string pointer by rank_size each time.
When a game is over, the player's score is compared to the lowest ranking in the high score table. If the player hasn't beaten the lowest score the game returns to the Attract sequence.
If the player's score exceeds the lowest ranking it is then compared to ascending ranks until either a higher or equivalent score is encountered or the top of the table is reached. Similar to a Bubble Sort, scores lower than the player's score are shifted down one position enabling the player score to be added if necessary. At the end of this process a pointer to the player's rank is passed to a text entry routine so that the player's initials can be inserted.
The text entry routine revolves around an index. Pushing the controller right increments the index by one and similarly pushing left decrements it by one. If the index exceeds a range of 0-31 in either direction it will wrap around. Due to the magic of two's complement this can be achieved very elegantly in a few lines of code.
Code: Select all
lda <INDEX
adda <INP_XAXIS
anda #$1F
The index serves two functions. By indexing a table of screen addresses the game knows where to draw the cursor graphic. Likewise when a character is input, the index can be easily converted to an offset into the font table. NB: Button input is checked every frame however controller input is only considered every eight frames to avoid cursor movement being too rapid.
The eagled-eyed amongst you may have noticed that my layout has only 28 possible cursor positions so how does the cursor still wrap correctly? Short answer, I liked the layout the way it was so to compensate I padded the screen address table with three entries each for "RUB" and "END".
To render the cursor I call a routine which plots 6 bytes vertically using values in the A and B registers (with a 3 byte gap in the middle)
to construct a bracket. By changing the values in A and B (ie. D) I can render either half of the cursor or indeed erase it altogether. After drawing one half of the cursor the screen draw address is incremented by 2 bytes, or 4 bytes in the case of "RUB" and "END".
When complete, the text entry screen should feature victorious music and audio feedback for cursor movement and character input.