Highscore display is all nice and dandy, but we want to see our score and name in there! So this step adds name entry. For this we rely on the Kernal (it's with 'a' on the C64) functions to read the pressed keys from the keyboard.
Adding to the score moving we find the spot for the name, shift all lower score names down and let the player enter his name.
The Kernal routine we're using is called GETIN and is placed in the ROM at $FFE4.
The following huge code snippet is placed in the old CheckForHighscore routine. For explanation reasons it's separated.
The first block moves the name entries of lower scores downwards. Remember, the name entries are stored continously in the location at HIGHSCORE_NAME.
;move names down
;shift older entries down, add new entry
lda #( HIGHSCORE_ENTRY_COUNT - 1 )
sta PARAM2
;y carries the offset in the score text, position at start of second last entry
ldy #( ( HIGHSCORE_NAME_SIZE + 1 ) * ( HIGHSCORE_ENTRY_COUNT - 2 ) )
.CopyName
lda PARAM2
cmp PARAM1
beq .SetNewName
;copy name
ldx #0
.CopyNextNameChar
lda HIGHSCORE_NAME,y
sta HIGHSCORE_NAME + ( HIGHSCORE_NAME_SIZE + 1 ),y
iny
inx
cpx #HIGHSCORE_NAME_SIZE
bne .CopyNextNameChar
tya
sec
sbc #( HIGHSCORE_NAME_SIZE + HIGHSCORE_NAME_SIZE + 1 )
tay
dec PARAM2
jmp .CopyName
Here's the interesting part. First the proper offset of the new name inside the big text is calculated and the old name cleared out.
.SetNewName
;calc y for new name offset
ldy PARAM1
lda #0
.AddNameOffset
cpy #0
beq .NameOffsetFound
clc
adc #( HIGHSCORE_NAME_SIZE + 1 )
dey
jmp .AddNameOffset
.NameOffsetFound
tay
;clear old name
ldx #0
sty PARAM3
lda #32
.ClearNextChar
sta HIGHSCORE_NAME,y
iny
inx
cpx #HIGHSCORE_NAME_SIZE
bne .ClearNextChar
Here's the meat, the actual name entry. Of course with Backspace support and Enter to finalize the entry. Out of sheer lazyness the newly entered char is only inserted in the text and the text then fully displayed.
ldy PARAM3
;enter name
ldx #0
stx PARAM3
jmp .ShowChar
.GetNextChar
sty PARAM4
;use ROM routines, read char
jsr KERNAL_GETIN
beq .GetNextChar
;return pressed?cmp #13
beq .EnterPressed
;DEL pressed?cmp #20
bne .NotDel
;DEL pressed
ldy PARAM4
ldx PARAM3
beq .GetNextChar
dec PARAM3
dey
dex
lda #32
sta HIGHSCORE_NAME,y
jmp .ShowChar
.NotDel
ldy PARAM4
;pressed key >= 32 or <= 96?cmp #32
bcc .GetNextChar
cmp #96
bcs .GetNextChar
;max length reached already?
ldx PARAM3
cpx #HIGHSCORE_NAME_SIZE
bcs .GetNextChar
;save text
sta HIGHSCORE_NAME,y
iny
inx
.ShowChar
stx PARAM3
sty PARAM4
;display high scores;x,y pos of name
lda #6
sta PARAM1
lda #10
sta PARAM2
lda #<HIGHSCORE_NAME
sta ZEROPAGE_POINTER_1
lda #>HIGHSCORE_NAME
sta ZEROPAGE_POINTER_1 + 1
jsr DisplayText
ldx PARAM3
ldy PARAM4
jmp .GetNextChar
.EnterPressed;fill entry with blanks
lda #32
ldx PARAM3
ldy PARAM4
.FillNextChar
cpx #HIGHSCORE_NAME_SIZE
beq .FilledUp
sta HIGHSCORE_NAME,y
iny
inx
jmp .FillNextChar
.FilledUpjmp TitleScreen