- Hiscore submission now works

- Added new hiscore music
- Added commandline options -hs and -hp to override default hiscore server
This commit is contained in:
Rob Pearce 2008-10-22 19:40:10 +00:00
parent 807381a53e
commit 63802db4ae
5 changed files with 312 additions and 40 deletions

BIN
data/music/hiscore.mod Normal file

Binary file not shown.

10
defs.h
View File

@ -66,7 +66,7 @@
#define TT_HELPSHADOW 2
#define TT_GAMEOVER 3
#define GAMEOVERWAIT 2 // # of seconds to wait before going back to title
#define GAMEOVERWAIT 3 // # of seconds to wait before going back to title
// text delays
#define TEXTSPEED 2 // how fast text zooms in
@ -83,8 +83,9 @@
#define DIEDELAY 80
#define HELPDELAY 80
#define LEVELDELAY 100
//#define GAMEOVERDELAY 200
#define GAMEOVERDELAY 20
// TODO: put back!
#define GAMEOVERDELAY 200
//#define GAMEOVERDELAY 20
#define POKERDELAY 170
@ -193,6 +194,7 @@
#define MAXJOYBUTTONS 20
#define MAXHISCORES 10
#define MAXHISCORENAME 10
// Fixed text buffer sizes
#define BUFLEN 512
@ -801,7 +803,7 @@ extern int toggletimer;
extern TTF_Font *font[];
extern TTF_Font *cardfont;
extern int musicplaying;
extern Mix_Music *music, *normalmusic, *fastmusic, *bossmusic;
extern Mix_Music *music, *normalmusic, *fastmusic, *bossmusic,*hiscoremusic;
extern Mix_Chunk *sfx[];
extern int oldexitdir;
extern int levelcomplete;

View File

@ -34,7 +34,7 @@ sprite_t *player; // pointer to the player's sprite
sprite_t *boss; // point to current boss on level (normally NULL)
sprite_t *mask; // point to scuba mask
Mix_Music *music, *fastmusic, *normalmusic,*bossmusic;
Mix_Music *music, *fastmusic, *normalmusic,*bossmusic,*hiscoremusic;
Mix_Chunk *sfx[MAXFX];
text_t *text, *lasttext;

323
rc.c
View File

@ -34,8 +34,12 @@ SDL_Surface *credittext;
TTF_Font *font[MAXLETTERHEIGHT];
char hiscoreserver[BUFLEN];
int hiscoreport;
hiscore_t hiscore[MAXHISCORES];
int numhiscores;
int wanthiscores;
int gothiscore = -1;
int havejoysticks;
int joybuttons;
@ -153,6 +157,10 @@ int main (int argc, char **argv) {
datadir = NULL;
// default
sprintf(hiscoreserver, "photos.nethack.net");
hiscoreport = 80;
/* handle arguments */
if (argc >= 2) {
for (i = 1; i < argc; i++) {
@ -177,6 +185,41 @@ int main (int argc, char **argv) {
}
skipto = atoi(argv[i]);
printf("Skipping to level %d.\n",skipto);
} else if (!strcmp(argv[i], "-hs")) {
if (++i >= argc) {
printf("Missing hiscore server name.\n");
usage();
exit(1);
}
if (strstr(argv[i], ":")) {
char *p,*p2;
// use port as well
p2 = hiscoreserver;
for (p = argv[i];p; p++) {
if (*p == ':') {
p++;
break;
} else {
*p2 = *p;
}
p2++;
}
*p2 = '\0';
hiscoreport = atoi(p);
printf("Hiscore server set to '%s'\n",hiscoreserver);
printf("Hiscore port set to '%d'\n",hiscoreport);
} else {
sprintf(hiscoreserver, "%s",argv[i]);
printf("Hiscore server set to '%s'\n",hiscoreserver);
}
} else if (!strcmp(argv[i], "-hp")) {
if (++i >= argc) {
printf("Missing hiscore port.\n");
usage();
exit(1);
}
hiscoreport = atoi(argv[i]);
printf("Hiscore port set to '%d'\n",hiscoreport);
} else {
usage();
exit(1);
@ -264,6 +307,17 @@ int main (int argc, char **argv) {
gamemode = GM_NORM; // default
// try to get hiscores
printf("Attepting to download hiscores from %s:%d...\n",hiscoreserver,hiscoreport); fflush(stdout);
if (gethiscores()) {
printf("Couldn't download hiscores. Disabling hiscore code.\n");
wanthiscores = B_FALSE;
} else {
printf("Hiscores successfully downloaded.\n");
wanthiscores = B_TRUE;
}
// outside loop
while (1) {
// title screen
@ -655,11 +709,20 @@ int main (int argc, char **argv) {
// clear screen
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,black.r,black.g,black.b));
if (wanthiscores) {
// check for a hiscore, if so submit it
checkhiscores();
// clear screen
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,black.r,black.g,black.b));
// show high scores
showhiscores();
// clear screen ready to start again...
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,black.r,black.g,black.b));
}
} // end outside loop
return 0;
@ -5227,6 +5290,8 @@ void usage(void) {
printf("usage: rc [-fs] [-l xx]\n");
printf(" -fs Start in full-screen mode.\n");
printf(" -l xx Skip to level xx.\n");
printf(" -hs xx Set hiscore_server to http://xx.\n");
printf(" -hp xx Connect to hiscore_server on port xx.\n");
printf("\n");
}
@ -5355,6 +5420,13 @@ int initsound(void) {
return B_TRUE;
}
sprintf(filename, "%s/music/hiscore.mod",datadir);
hiscoremusic = Mix_LoadMUS(filename);
if (!hiscoremusic) {
printf("can't load music\n");
return B_TRUE;
}
return B_FALSE;
}
@ -5465,9 +5537,11 @@ void dumpsprites(void) {
printf("\n\n");
}
void drawoutlinetext(SDL_Surface *where,int x, int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol) {
// returns width
int drawoutlinetext(SDL_Surface *where,int x, int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol) {
SDL_Surface *surf;
SDL_Rect area;
int wid;
area.w=0;area.h=0;
@ -5487,7 +5561,10 @@ void drawoutlinetext(SDL_Surface *where,int x, int y, int size, char *msg, SDL_C
SDL_SetColors(surf, col, 1, 1);
area.x = x; area.y = y; SDL_BlitSurface(surf, NULL, where, &area);
wid = surf->w;
SDL_FreeSurface(surf);
return wid;
}
void drawoutlinecentretext(SDL_Surface *where, int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol) {
@ -5906,6 +5983,8 @@ void initsdl(void) {
havejoysticks = B_FALSE;
printf("No joysticks found.\n");
}
SDL_EnableUNICODE(1);
}
// player collects the given fruit
@ -6699,7 +6778,7 @@ void handleinput(void) {
levelcomplete = oldlevelcomplete;
}
}
} else if (event.type == SDL_JOYBUTTONUP) {
} else if (havejoysticks && (event.type == SDL_JOYBUTTONUP)) {
if (levelcomplete == LV_HELPFREEZE) {
if (joybuttontokey(event.jbutton.button) == SDLK_z) {
levelcomplete = oldlevelcomplete;
@ -6783,6 +6862,7 @@ void handleinput(void) {
if (keydown(SDLK_ESCAPE)) {
exit(1);
}
if (cheat) {
if (keydown(SDLK_q)) {
gtime = nexthurryup-1;
//gtime = nexthurryup+14;
@ -6849,6 +6929,7 @@ void handleinput(void) {
toggletimer = 50;
}
}
}
@ -7216,14 +7297,6 @@ void dotitlescreen(void) {
joyx = SDL_JoystickGetAxis(joy,0);
joyy = SDL_JoystickGetAxis(joy,1);
/*
for (i = 0; i < 20; i++) {
joybut[i] = SDL_JoystickGetButton(joy,i);
if (joybut[i]) printf("button %d down\n",i);
}
*/
//printf("joystick coords are: %d,%d button0=%d, button1=%d\n",joyx,joyy,joybut[0],joybut[1]);
if (joyy <= -6000) handletitleinput(SDLK_UP);
if (joyy >= 6000) handletitleinput(SDLK_DOWN);
@ -7375,6 +7448,8 @@ void startgame(void) {
pokerpoints = 0;
skiplevels = 0;
gothiscore = -1;
curfruittype = 0;
curpoweruptype = 0;
@ -7550,8 +7625,7 @@ void drawcredits(void) {
}
/*
int submithiscore(int score,char *name,char *rank,char *text) {
int submithiscore(int score,int level, char *name) {
struct sockaddr_in serveraddress;
struct hostent *server;
int rv;
@ -7559,28 +7633,28 @@ int submithiscore(int score,char *name,char *rank,char *text) {
char buf[1500];
char newtext[BUFLEN];
char buf2[512];
int serverport = 80;
char *p,*p2;
server = gethostbyname("www.nethack.net");
server = gethostbyname(hiscoreserver);
sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
printf("Error getting socket.\n");
return B_TRUE;
}
//bzero((char *) &serveraddress, sizeof(serveraddress));
memset(&serveraddress, 0, sizeof(serveraddress));
serveraddress.sin_family = AF_INET;
memcpy(&serveraddress.sin_addr.s_addr, server->h_addr,
server->h_length);
serveraddress.sin_port = htons(serverport);
serveraddress.sin_port = htons(hiscoreport);
serveraddress.sin_port = htons(serverport);
// replace spaces in text with %20s
// replace spaces in name with %20s
p2 = newtext;
for (p = text ; *p != '\0'; p++) {
for (p = name ; *p != '\0'; p++) {
if (*p == ' ') {
*p2 = '%'; *p2++;
*p2 = '2'; *p2++;
@ -7593,12 +7667,13 @@ int submithiscore(int score,char *name,char *rank,char *text) {
// connect
if (connect(sock,(struct sockaddr *)&serveraddress,sizeof(serveraddress)) < 0) {
printf("Error connecting to hiscore server.\n");
return B_TRUE;
}
// send request
sprintf(buf2, "GET HTTP://www.nethack.net/software/gala/hiscores/submitscore.php?score=%d&name=%s&rank=%s&text=%s HTTP/1.0\n\n",
score,name,rank,newtext);
sprintf(buf2, "GET HTTP://photos.nethack.net/rc/submitscore.php?score=%d&name=%s&level=%d HTTP/1.0\n\n",
score,newtext,level);
write(sock,buf2,strlen(buf2));
// wait for data
@ -7611,7 +7686,6 @@ int submithiscore(int score,char *name,char *rank,char *text) {
return B_FALSE;
}
*/
int gethiscores(void) {
struct sockaddr_in serveraddress;
@ -7621,13 +7695,12 @@ int gethiscores(void) {
char buf[BUFLEN];
char buf2[512];
int state = 0;
//int serverport = 80;
int serverport = 1234;
int pos;
int finished;
// TODO: put back in
//server = gethostbyname("photos.nethack.net");
server = gethostbyname("localhost");
server = gethostbyname(hiscoreserver);
if (!server) {
printf("can't resolve hiscore server name\n");
return B_TRUE;
@ -7643,7 +7716,7 @@ int gethiscores(void) {
serveraddress.sin_family = AF_INET;
memcpy(&serveraddress.sin_addr.s_addr, server->h_addr,
server->h_length);
serveraddress.sin_port = htons(serverport);
serveraddress.sin_port = htons(hiscoreport);
// connect
@ -7692,8 +7765,13 @@ int gethiscores(void) {
p = strtok(NULL, "^");
sprintf(hiscore[pos].name,"%s", p);
pos++;
if (pos >= MAXHISCORES) {
// too many - cut it off here
finished = B_TRUE;
}
}
}
//rv = read(sock, buf, 1500);
rv = socket_readline(sock, buf);
}
@ -7704,6 +7782,185 @@ int gethiscores(void) {
return B_FALSE;
}
void checkhiscores(void){
int finished = B_FALSE;
int i;
char srank[BUFLEN],sscore[BUFLEN],slevel[BUFLEN],sname[BUFLEN];
//char line[BUFLEN];
char commascore[BUFLEN];
int x,y,sx,sy;
char thisname[BUFLEN];
int timer = 0;
int capital = B_TRUE;
// contact server and read list
if (gethiscores()) {
printf("Cannot contact hiscore server!\n");
return;
}
// check if we are higher than any
gothiscore = -1;
for (i = 0; i < numhiscores; i++) {
if (player->score > hiscore[i].score) {
// we got a hi score
gothiscore = i;
break;
}
}
if (gothiscore == -1) {
// didn't get a hiscore
return;
}
// play hiscore music
stopmusic();
playmusic(hiscoremusic);
// prompt user for a name
strcpy(thisname, "");
while (!finished) {
SDL_Color *fg, *bg;
SDL_Event event;
// clear
SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format,black.r,black.g,black.b));
//draw hiscore heading
sx = 110;
sy = 100;
x = sx;
y = sy;
// headings
drawoutlinecentretext(screen, 50, TEXTSIZE_HISCORE, "New high score!", &green, &red);
// print rank
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, "Rank", &cyan, &blue);
x += 70;
// print score
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, "Score", &cyan, &blue);
x += 150;
// print level
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, "Level", &cyan, &blue);
x += 90;
// print name
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, "Name", &cyan, &blue);
y += 40;
x = sx;
// player's score...
// generate hiscore lines
sprintf(srank, "%-2d.",gothiscore+1);
addcommas(commascore, player->score );
sprintf(sscore, "%-14s",commascore);
sprintf(slevel, "%1d-%-2d",getworld(curlevelnum),getlevel(curlevelnum));
if (strlen(thisname) > 0) {
sprintf(sname, "%-32s",thisname);
}
fg = &green;
bg = &red;
// print rank
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, srank, fg, bg);
x += 70;
// print score
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, sscore, fg, bg);
x += 150;
// print level
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, slevel, fg, bg);
x += 90;
// print name
if (strlen(thisname) > 0) {
int wid;
wid = drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, thisname, fg, bg);
x += (wid + 2);
}
// print cursor
if (((timer / 10) % 2) == 0) {
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, "_", fg, bg);
}
if (++timer == 100) {
timer = 0;
}
// wait for a key...
if (SDL_PollEvent(&event)) {
int key = -1;
int keyval;
switch (event.type) {
case SDL_KEYUP:
key = event.key.keysym.sym;
keyval = event.key.keysym.unicode & 0x7F;
break;
case SDL_JOYBUTTONUP:
key = joybuttontokey(event.jbutton.button);
break;
}
if (key != -1) {
if (key == SDLK_ESCAPE) {
// quit
exit(0);
} else if ((key == SDLK_RETURN) || (havejoysticks && (key == SDLK_z))) {
if (strlen(thisname) > 0) {
finished = B_TRUE;
}
} else {
// check for printable key
if (((keyval >= 'a') && (keyval <= 'z')) || (keyval == ' ')) {
char let[2];
// capital
if (capital) {
if ((keyval >= 'a') && (keyval <= 'z')) {
keyval -= 32;
capital = B_FALSE;
}
}
let[0] = keyval;
let[1] = '\0';
strcat(thisname, let);
// don't let name get too long
if (strlen(thisname) >= MAXHISCORENAME) {
finished = B_TRUE;
}
if (keyval == ' ') {
// next letter is a capital
capital = B_TRUE;
}
}
}
}
}
SDL_UpdateRect(screen, 0,0,640,480);
}
// submit the hiscore
if (submithiscore(player->score, curlevelnum, thisname)) {
printf("failed to submit hiscore.\n");
} else {
// downlaod the hiscores again
gethiscores();
}
}
void showhiscores(void){
int finished = B_FALSE;
int i;
@ -7712,11 +7969,13 @@ void showhiscores(void){
char commascore[BUFLEN];
int x,y,sx,sy;
// TODO: contact server and read list
// contact server and read list
/*
if (gethiscores()) {
printf("Cannot contact hiscore server!\n");
return;
}
*/
/*
hiscore[0].score = 55000;
hiscore[0].level = 24;
@ -7765,8 +8024,13 @@ void showhiscores(void){
sprintf(slevel, "%1d-%-2d",getworld(hiscore[i].level),getlevel(hiscore[i].level));
sprintf(sname, "%-32s",hiscore[i].name);
if ((gothiscore != -1) && (i == gothiscore)) {
fg = &green;
bg = &red;
} else {
fg = &red;
bg = &red2;
}
// print rank
drawoutlinetext(screen, x, y, TEXTSIZE_HISCORE, srank, fg, bg);
@ -7811,6 +8075,9 @@ void showhiscores(void){
SDL_UpdateRect(screen, 0,0,640,480);
}
// stop music ready for title screen again (it will only be playing if
// we got a hiscore)
stopmusic();
}
int socket_readline(int sock, char* out) {

5
rc.h
View File

@ -88,7 +88,10 @@ void setjoymappings(void);
int keytojoybutton(int key);
int joybuttontokey(int buttonnum);
void drawcredits(void);
void drawoutlinetext(SDL_Surface *where,int x, int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol);
int drawoutlinetext(SDL_Surface *where,int x, int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol);
void drawoutlinetextcentre(SDL_Surface *where,int y, int size, char *msg, SDL_Color *col, SDL_Color *bgcol);
int socket_readline(int sock, char *out);
void showhiscores(void);
void checkhiscores(void);
int gethiscores(void);
int submithiscore(int score,int level, char *name);