/* * grv.c * * Main program - converted from BASIC */ #include #include #include #include #include #include "highscore.h" #include "graphics.h" #include "grv.h" #ifdef __unix__ #include #include #include #include int xread(int fd, void *buf, size_t count) { char *b = (char *)buf; int n = 0; int rv; while ( count ) { rv = read(fd, b, count); if ( rv == -1 ) { if ( errno == EINTR || errno == EAGAIN ) continue; else return n ? n : -1; } else if ( rv == 0 ) { return n; } count -= rv; n += rv; b += rv; } return n; } #endif struct gameparams gp; struct monster ghost[MAXGHOST]; void init_gameparams(void) { gp.Sc = gp.SBs = 0; gp.Life = 3; gp.SBs = 0; gp.Lvf = 0; gp.GkCh = 0; gp.MLev = 0; gp.KulSpr = 0; gp.Level = 0; gp.Cheat = 0; gp.EOLWait = 1; /* As good a start as any... */ gp.have_id = 0; gp.gameid = (uint64_t)genrand_int32() << 32; #ifdef __unix__ { /* We might have /dev/urandom */ int fd = open("/dev/urandom", O_RDONLY); if ( fd >= 0 ) { if ( xread(fd, &gp.gameid, sizeof(gp.gameid)) == sizeof(gp.gameid) ) gp.have_id = 1; close(fd); } } #endif } static int screen_width = 40; void initscreen(int w) { if ( w != screen_width ) width(screen_width = w); color(0,gp.c); cls(); } void newlevel(void) { gp.Bon = 0; gp.TF = -1; gp.Hyp = 0; gp.Bar = 0; gp.ChBd = gp.GkCh; gp.FS = 1; /* Ghosts are not frozen or reversed */ /* 150 ms/step is the speed for level 0 */ gp.Speed = (150*ELev)/(gp.Level+ELev); gp.Tid = 0.0; if ( gp.Level < ELev-1 ) gp.ZLevel = ELev-1; if ( gp.Level >= 15 && gp.MLev < 15 ) { /* Announce Escape option */ levelscreen(); color(0,gp.c2); lprint(12,1," Now you have completed the first 15 "); lprint(13,1," levels of this game. Now you can use "); lprint(14,1," your Escape key to get away! "); if ( gp.EOLWait ) mymssleep(5000); } gp.EOLWait = 1; gp.MLev = max(gp.Level, gp.MLev); reset_actions(); addaction(0, 0, 1800.0, act_toolate); /* 30 minutes -> dead */ if ( gp.Level == ELev-1 ) { /* Last level */ gp.KulSpr = 0; } else { /* Not the last level */ int e; for ( e = gp.KulSpr ; e ; e-- ) { if ( irnd(10) ) gp.KulSpr--; /* 10% chance to keep unused shots */ } if ( gp.KulSpr > 80 ) gp.KulSpr = 80; } if ( gp.Level > gp.MLev ) gp.MLev = gp.Level; drawlevel(); play(); } void game(void) { init_gameparams(); while ( gp.Level < ELev && gp.Life >= 0 ) { newlevel(); } highscore_endgame(); } struct opts opt; int main(int argc, char *argv[]) { int i; randomize(); memset(&opt, 0, sizeof opt); for ( i = 1 ; i < argc ; i++ ) { if ( !strcmp(argv[i], "-nonet") || !strcmp(argv[i], "-no-net") ) opt.nonet = 1; else if ( !strcmp(argv[i], "-window") ) opt.window = 1; else if ( !strcmp(argv[i], "-debug") ) opt.debug = 1; } /* On Unix, save stuff in a ~/.grv directory */ #ifdef __unix__ { char *home = getenv("HOME"); char *grvd = getenv("GRV_DIR"); if ( !grvd ) { grvd = alloca(strlen(home)+6); if ( grvd ) { sprintf(grvd, "%s/.grv", home); mkdir(grvd, 0777); /* Make .grv directory if missing */ } } if ( grvd ) chdir(grvd); /* Change to .grv directory */ } #endif /* Init the highscore data structures */ /* This is done here because it's a destructive operation and must only be done once! */ highscore_init(); load_prefs(); if ( screen_init(opt.window) ) { fprintf(stderr, "%s: Cannot initalize graphics!\n", argv[0]); exit(1); } highscore_download(); /* Here for testing... */ while ( 1 ) { intro(); switch ( get_key()->keysym.sym ) { case SDLK_k: set_keys(); break; case SDLK_p: game(); break; case SDLK_q: return 0; case SDLK_v: highscore_show(0,0); break; default: break; } } }