/* * highscore.c * * Handle uploads and downloads to the highscore database */ #include #include #include #include #include #include "grv.h" #include "highscore.h" #include "network.h" static const char score_server[] = "grvscore.zytor.com"; static int score_dl_port = 22392; static int score_ul_port = 22393; static const char score_file[] = "grvscore.dat"; void highscore_load(void) { FILE *f; f = fopen(score_file, "r"); if ( !f ) return; highscore_parse(f, fgets, 1); fclose(f); } void highscore_download(void) { netcon_t n; if ( opt.nonet ) return; n = fopen_network(score_server, score_dl_port, 0); if ( !n ) return; highscore_parse(n, fgets_network, 0); fclose_network(n); } void highscore_save(void) { FILE *f; f = fopen(score_file, "w"); if ( !f ) return; highscore_write(f, fputs, 1); fclose(f); } void highscore_upload(void) { netcon_t n; if ( opt.nonet ) return; if ( !have_upload_scores() ) return; n = fopen_network(score_server, score_ul_port, 1); if ( !n ) return; highscore_write(n, fputs_network, 0); fclose_network(n); } /* * Allow the user to enter the name for the high score */ static void enter_name(int rank, char *player) { static const unsigned char *symbols[3] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ\x8f\x8e\x99""0123456789?", "\x01\x02\x0e\x0f\x10\x11\x18\x19._-/:;+$%&^!*@=,'`~<>()\xae\xaf\"\x80\x90\x92\x9a\xed\xa5", "\x13\xe4\xea\xef\xb1\xf9\xcd\xfe\xeb\xf1\xec\xe5 SPACE DELETE ENTER " }; int x, y, x1, y1; int ly, ry, vy; SDL_KeyboardEvent *ke; int len = 0; char sbuf[2]; char *s; sbuf[1] = '\0'; SDL_EnableKeyRepeat(250, 33); color(0,gp.c); lprint(15,11,"ENTER YOUR INITIALS!"); color(0,gp.c2); lprint(17,1,symbols[0]); lprint(18,1,symbols[1]); lprint(19,1,symbols[2]); x = 0; y = 0; while ( 1 ) { if ( x == 2 && y >= 12 ) { if ( y >= 12 && y <= 20 ) { y = 12; ly = 11; vy = 16; ry = 21; s = " SPACE "; sbuf[0] = ' '; } else if ( y >= 21 && y <= 30 ) { y = 21; ly = 12; vy = 25; ry = 31; s = " DELETE "; } else { y = 31; ly = 21; vy = 35; ry = 31; s = " ENTER "; } } else { ly = max(0,y-1); vy = y; ry = min(39,y+1); sbuf[0] = symbols[x][y]; s = sbuf; } color(15,gp.c2); lprint(x+17,y+1,s); x1 = x; y1 = y; do { ke = get_key(); if ( ke->keysym.sym == kbd_keys[0] ) { x = max(0,x-1); if ( x != x1 ) y = vy; } else if ( ke->keysym.sym == kbd_keys[1] ) { y = ly; } else if ( ke->keysym.sym == kbd_keys[2] ) { y = ry; } else if ( ke->keysym.sym == kbd_keys[3] ) { x = min(2,x+1); if ( x != x1 ) y = vy; } else if ( ke->keysym.sym == SDLK_RETURN ) { if ( x == 2 && y == 21 ) { if ( len > 0 ) { len--; color(0,gp.c2); lprint(rank+3,len+23,"."); } } else if ( x == 2 && y == 31 ) { if ( len == 9 ) { player[len] = '\0'; color(0,gp.c2); lprint(rank+3,23,player); return; } } else { if ( len < 9 ) { player[len] = sbuf[0]; color(15,gp.c2); lprint(rank+3,len+23,sbuf); len++; } } } } while ( x == x1 && y == y1 ); color(0,gp.c2); lprint(x1+17,y1+1,s); } } /* * Display highscore screen; optionally show the user rank * and (if <= 10) let the user enter name */ void highscore_show(int myrank, int save) { int i, x, y; levelscreen(); color(0,gp.c); lprint(1,15,"THE TOP TEN"); for ( i = 0 ; i < 10 ; i++ ) { if ( bests.total[i].score ) lprintf(i+4,4,"%2d %-13" PRId64 " %-9.9s (%2d)", i+1, bests.total[i].score, bests.total[i].player, bests.total[i].endlvl+1); if ( i+1 == myrank ) { color(0,gp.c2); lprint(i+4,23,"........."); color(0,gp.c); } } if ( myrank > 0 && myrank <= 10 ) enter_name(myrank, bests.total[myrank-1].player); /* This can't be done until we have let the user enter name, and this is as good of a place as any, especially since there is no blink on the screen right now... */ if (save) highscore_save(); highscore_upload(); color(0,gp.c); lprint(21,8,"Please press any key . . ."); get_key(); initscreen(80); x = 1; y = 1; for ( i = 10 ; i < 100 ; i++ ) { if ( i+1 == myrank ) color(16,gp.c2); else color(0,gp.c); /* Don't use %3d; we only want the highlight bar to wrap the text, not spill over. Therefore we need to adjust the starting position to make the numbers line up... */ if ( bests.total[i].score ) lprintf(x,y+(i < 99), " %d %" PRId64 " ", i+1, bests.total[i].score); x++; if ( x > 23 ) { x = 1; y += 20; } } color(0,gp.c); lprintf(25,28,"Please press any key . . ."); get_key(); } /* * Call at end of game to show and possibly enter highscore * Note: always upload even if this wasn't a highscore -- we might have * entries in our database from old games */ void highscore_endgame(void) { int myrank; highscore_download(); if ( gp.Cheat ) myrank = 0; else myrank = highscore_add_total(gp.gameid, gp.Sc, gp.MLev, NULL, 1); highscore_show(myrank, 1); }