#include "fbgfx.bi"
Using FB

const num_of_entries = 10 ' Flags the number of entries in the 
                          ' high score file.

DECLARE SUB ReadHighScore (highscore_file AS STRING)
DECLARE SUB WriteHighScore (highscore_file AS STRING, users_score AS INTEGER)
DECLARE SUB InputName

DIM SHARED workpage AS INTEGER
DIM SHARED hname(num_of_entries) AS STRING ' Flags high score table names.
DIM SHARED hscore(num_of_entries) AS INTEGER ' Flags high score table scores.
DIM SHARED playername AS STRING ' Flags player's name to be inputted in the high score.

SCREENRES 640, 480, 32, 2, GFX_ALPHA_PRIMITIVES+GFX_WINDOWED
SCREENSET 1, 0

' We need to call our subroutine with the appropriate file
' and then end program.
ReadHighScore "high_scores.dat"
WriteHighScore "high_scores.dat", 4500
END

SUB ReadHighScore (highscore_file AS STRING)

' Dimension the variable that will hold
' the information about the free
' file handle.
DIM free_filehandle AS INTEGER

' Pass the free file handle to the free_filehandle
' variable.
free_filehandle = FreeFile

' Open our high score file with the free file
' handle for reading (FOR INPUT).
OPEN highscore_file FOR INPUT AS #free_filehandle

' Loop through the high score entries and place
' them in appropriate variables (hname and hscore).
' hscore(1) will hold the highest score, while
' hscore(num_of_entries) the lowest score.
FOR count_entry AS INTEGER = 1 TO num_of_entries
INPUT #free_filehandle, hname(count_entry)
INPUT #free_filehandle, hscore(count_entry)
' If the end of file is reached, exit the FOR loop.
IF EOF(free_filehandle) THEN EXIT FOR
NEXT count_entry

' Close the file we just open.
CLOSE #free_filehandle

' Start a DO...LOOP to display our high score table.
DO

screenlock
screenset workpage, workpage xor 1

' Clear the screen.
LINE (0,0)-(639,479), RGBA(0, 0, 0, 255), BF

' Print TOP SCORES title with WHITE color.
Draw String (285, 120), "TOP SCORES", RGBA(255,255, 255, 255)

' Loop through high score entries, print names and
' scores on appropriate positions, with each new score
' using more translucency. Change * 12 to a higher number
' to get more space between scores.
FOR count_entry AS INTEGER = 1 TO num_of_entries
Draw String (270, 140 + count_entry * 12), hname(count_entry), RGBA(255,255, 255, 250-count_entry*10)
Draw String (340, 140 + (count_entry) * 12), STR$(hscore(count_entry)), RGBA(255,255, 255, 250-count_entry*10)
NEXT count_entry

Draw String (245, 400), "Press ESCAPE to exit", RGBA(255,255, 255, 220)

workpage xor = 1
screenunlock

SLEEP 10

LOOP UNTIL MULTIKEY(SC_ESCAPE) ' Loop until ESCAPE is pressed.

END SUB

SUB WriteHighScore (highscore_file AS STRING, users_score AS INTEGER)
    
WHILE MULTIKEY(SC_ESCAPE)
SLEEP 10
WEND

' Dimension the variable that will hold
' the information about the free
' file handle.
DIM free_filehandle AS INTEGER

' Will flag where the new entry is to be
' placed (on which position in the high
' score table).
DIM startwrite AS INTEGER

' Pass the free file handle to the free_filehandle
' variable.
free_filehandle = FreeFile

' Open our high score file with the free file
' handle for reading (FOR INPUT).
OPEN highscore_file FOR INPUT AS #free_filehandle

' Loop through the high score entries and place
' them in appropriate variables (hname and hscore).
' hscore(1) will hold the highest score, while
' hscore(num_of_entries) the lowest score.
FOR count_entry AS INTEGER = 1 TO num_of_entries
INPUT #free_filehandle, hname(count_entry)
INPUT #free_filehandle, hscore(count_entry)
' If the end of file is reached, exit the FOR loop.
IF EOF(free_filehandle) THEN EXIT FOR
NEXT count_entry

' If the player's score is higher
' that the lowest score in the
' high score table check the entire high 
' score table, otherwise do nothing.
IF users_score > hscore(num_of_entries) THEN

' Loop through all scores, from highest to lowest.
FOR check_score AS INTEGER = 1 TO num_of_entries

' If the user's score is higher than the current
' in the loop (and the loop goes FROM THE HIGHEST
' TO THE LOWEST), call name inputting sub, and
' write the new data into the high score table file.
IF users_score > hscore(check_score) THEN
InputName
' Record the position where the new score is
' to placed and exit FOR loop.
startwrite = check_score
EXIT FOR
END IF

NEXT check_score

' The code that bumps down lower scores onto
' lower positions before the new table
' is saved. Example, if your score is
' second, the previous second needs to
' be bumped on the third position, while
' the one from the third position needs
' to be bumped on the forth position.

' If the score to be inputted in the
' high score table is the last, we
' only need to record new data
' on that last position, and no "bumping"
' of lower scores (which there are none)
' is needed.
IF startwrite = num_of_entries THEN
hscore(startwrite) = users_score
hname(startwrite) = playername
ELSE
' If the new entry in the high score table is not
' the last, we need to loop from the BOTTOM of the
' high score table to the NEW ENTRY position.
' Each loop one high score table name and score 
' under the new entry is passed one position 
' lower (counting from bottom to top).
' For example, when write_pos is 9, then
' the values from that position (hscore(9) and 
' hname(9)) are passed one position down to
' hscore (9 + 1) and hname (9 + 1). 
FOR write_pos AS INTEGER = (num_of_entries - 1) TO startwrite STEP -1
hscore(write_pos + 1) = hscore(write_pos)
hname(write_pos + 1) = hname(write_pos)
NEXT write_pos
' We also need to save the new
' entry (name and score) on
' appropriate position.
hscore(startwrite) = users_score
hname(startwrite) = playername
END IF

free_filehandle = FreeFile

' No we need to open the high score table file again,
' but this time for writing (FOR OUTPUT) to store the 
' new high score data into it.
OPEN highscore_file FOR OUTPUT AS free_filehandle
FOR count_entry AS INTEGER = 1 TO num_of_entries
PRINT #free_filehandle, hname(count_entry)
PRINT #free_filehandle, hscore(count_entry)
NEXT count_entry
CLOSE free_filehandle

' This is optional, but I like for the high score
' table to be called every time a new entry is written
' into it.
ReadHighScore highscore_file

END IF
    
END SUB

SUB InputName

screenset workpage, workpage xor 1
SCREENSET 0,0
LINE (0,0)-(639,479), RGBA(0, 0, 0, 255), BF
LOCATE 12, 17
INPUT ; "Please input your name: ", playername

END SUB