diff --git a/bomber.h b/bomber.h index 522b8b6..7a2ebf0 100644 --- a/bomber.h +++ b/bomber.h @@ -65,7 +65,7 @@ struct listhead { }; typedef struct player { - listhead list; + listhead list, list_all_players; int xpos,ypos; int flags; int abilities; @@ -81,6 +81,7 @@ typedef struct player { int color; int controller; int fixx,fixy; + int kills, deaths; figure *figure; } player; @@ -210,7 +211,7 @@ enum tile_types { #define MAXSPRITES 256 #define MAXDAMAGES 512 -extern char exitflag; +extern volatile char exitflag; extern uchar needwhole; extern figure walking[MAXSETS][60]; diff --git a/game.c b/game.c index f24a759..b57c5a0 100644 --- a/game.c +++ b/game.c @@ -18,6 +18,7 @@ static listhead activegeneric; static listhead detonatebombs; static listhead activeflames; static listhead activeplayers; +static listhead allplayers; figure walking[MAXSETS][NUMWALKFRAMES]; solid background, backgroundoriginal; @@ -26,7 +27,7 @@ solid background, backgroundoriginal; unsigned char field[32][32]; void *info[32][32]; -char exitflag = 0; +volatile char exitflag = 0; static int framecount = 0; char playername[16]; @@ -46,8 +47,6 @@ TILE_NONE,160 static GameOptions gameoptions; -static int host_kills, host_deaths; - static const unsigned char playerpositions[MAXNETNODES*3] = { /* color, x, y */ 2,0,0, 3,14,10, @@ -59,28 +58,41 @@ static const unsigned char playerpositions[MAXNETNODES*3] = { /* color, x, y */ 8,14,4, }; +static void resetplayer(player *pl, int color, int x, int y) { + pl->speed=SPEEDSTART; + pl->flags=0; + pl->flamelength=gameoptions.flames+1; + pl->bombsavailable=gameoptions.bombs+1; + + pl->color=color; + + pl->xpos=arraytoscreenx(x); + pl->ypos=arraytoscreeny(y); + + field[y][x]=FIELD_EMPTY; + if(x) field[y][x-1]=FIELD_EMPTY; + if(y) field[y-1][x]=FIELD_EMPTY; + if(xxpos=arraytoscreenx(x); - pl->ypos=arraytoscreeny(y); - pl->color=color; - pl->speed=SPEEDSTART; - pl->flags=0; + + list_add_tail(&allplayers, &pl->list_all_players); + + pl->controller=controller; pl->fixx=-4; pl->fixy=-40; - pl->flamelength=gameoptions.flames+1; - pl->bombsavailable=gameoptions.bombs+1; - pl->controller=controller; - field[y][x]=FIELD_EMPTY; - if(x) field[y][x-1]=FIELD_EMPTY; - if(y) field[y-1][x]=FIELD_EMPTY; - if(xkills = pl->deaths = 0; + + resetplayer(pl, color, x, y); } static void initplayers(void) { @@ -102,22 +114,36 @@ static void initplayers(void) { } } -static void resetstats(void) { - int i; +static void resetplayers(void) { + const unsigned char *p; + int c,x,y; + player *pl; - host_deaths = host_kills = 0; - for (i = 0; i < MAXNETNODES; i++) { - netnodes[i].deaths = netnodes[i].kills = 0; + p=playerpositions; + list_for_each_entry(pl, &allplayers, list_all_players) { + c=*p++; + x=*p++; + y=*p++; + resetplayer(pl, c, x, y); } } static void firstzero(void) { + alloc_things(); + list_init_head(&activebombs); + list_init_head(&detonatebombs); + list_init_head(&activeflames); + list_init_head(&activedecays); + list_init_head(&activebonus); + list_init_head(&activeplayers); + list_init_head(&activegeneric); + list_init_head(&allplayers); + mycount = mydatacount = 0; memset(latestactions,0,sizeof(latestactions)); memset(latestcounts,0,sizeof(latestcounts)); memset(actionblock,0,sizeof(actionblock)); actioncount = 0; - resetstats(); } static void initgame() { @@ -130,14 +156,14 @@ static void initgame() { if (network != NETWORK_SLAVE) set_game_options(&configopts); gameframe=0; - allocthings(); - list_init_head(&activebombs); - list_init_head(&detonatebombs); - list_init_head(&activeflames); - list_init_head(&activedecays); - list_init_head(&activebonus); + + things_list_clear(&activebombs); + things_list_clear(&detonatebombs); + things_list_clear(&activeflames); + things_list_clear(&activedecays); + things_list_clear(&activebonus); list_init_head(&activeplayers); - list_init_head(&activegeneric); + things_list_clear(&activegeneric); p=bonuschances; bonustotal=0; @@ -160,7 +186,7 @@ static void initgame() { solidcopyany(&backgroundoriginal,&background,0,0,IXSIZE,IYSIZE); - initplayers(); + resetplayers(); for(j=0;jcontroller == -1) { - host_deaths++; - } else { - netnodes[pl->controller].deaths++; - } + pl->deaths++; pl->flags|=FLG_DEAD; playsound(2); adddeath(pl); @@ -561,23 +583,19 @@ static void drawgenerics(void) { } static void drawstats(void) { - int d, k, p = 0, i; + player *pl; + int p = 0; const char *n; char buf[16]; solidcopy(&background, 0, 0, IXSIZE, arraystarty); - for (i = -1; i < MAXNETNODES; i++) { - if (i >= 0) { - if (!netnodes[i].used) continue; - k = netnodes[i].kills; - d = netnodes[i].deaths; - n = netnodes[i].name; + list_for_each_entry(pl, &allplayers, list_all_players) { + if (pl->controller >= 0) { + n = netnodes[pl->controller].name; } else { - k = host_kills; - d = host_deaths; n = playername; } - snprintf(buf, sizeof(buf), "%-8.8s %2i/%2i", n, k % 100, d % 100); + snprintf(buf, sizeof(buf), "%-8.8s %2i/%2i", n, pl->kills % 100, pl->deaths % 100); drawstring(11 + (p/2) * (15 * fontxsize + 7), 11 + (p%2) * (fontysize+2), buf); p++; } @@ -754,6 +772,7 @@ static void doplayer(player *pl) { if(what==ACT_QUIT) { killplayer(pl); + list_del(&pl->list_all_players); return; } @@ -761,6 +780,12 @@ static void doplayer(player *pl) { playsound((myrand()&1) ? 1 : 5); applybonus(pl,info[py][px]); } else if(there==FIELD_FLAME) { + flame *fl = info[py][px]; + if (fl->owner == pl) { + pl->kills--; + } else { + fl->owner->kills++; + } killplayer(pl); return; } @@ -935,6 +960,7 @@ void run_single_player(void) { network = NETWORK_NONE; firstzero(); + initplayers(); do { initgame(); while(!(code=iterate()) && !exitflag) ++framecount; @@ -945,6 +971,7 @@ void run_network_game(void) { int code; firstzero(); + initplayers(); do { initgame(); while (!(code=iterate()) && !exitflag) ++framecount; diff --git a/list.c b/list.c index 85df0e5..fce072c 100644 --- a/list.c +++ b/list.c @@ -6,6 +6,7 @@ typedef union genericlistitem genericlistitem; union genericlistitem { genericlistitem *next; + listhead list; bomb b; flame f; brickdecay bc; @@ -18,21 +19,26 @@ union genericlistitem { static genericlistitem *things=0; static genericlistitem *free_things; -void allocthings(void) { +static int count_used = 0; + +static const int num = MAXTHINGS; + +void alloc_things(void) { int i; - const int num = MAXTHINGS; if (!things) { - things = calloc(sizeof(genericlistitem), num); + things = calloc(sizeof(genericlistitem), MAXTHINGS); } else { - memset(things, 0, sizeof(genericlistitem)*num); + memset(things, 0, sizeof(genericlistitem)*MAXTHINGS); } - if(!things) nomem("Trying to allocate thing memory"); - for(i=0;i sizeof(genericlistitem)) return 0; if (free_things) { + count_used++; free_things = free_things->next; memset(entry, 0, sizeof(genericlistitem)); } @@ -51,6 +58,7 @@ void freeentry(void *ptr) { genericlistitem *entry = ptr; entry->next = free_things; free_things = entry; + count_used--; } void list_add_tail(listhead *head, listhead *entry) { @@ -70,3 +78,13 @@ void list_init_head(listhead *head) { head->next = head; head->prev = head; } + +void things_list_clear(listhead *head) { + genericlistitem *entry; + + while (head->next != head) { + entry = container_of(head->next, typeof(*entry), list); + list_del(head->next); + freeentry(entry); + } +} diff --git a/list.h b/list.h index bf11f20..e1c2f56 100644 --- a/list.h +++ b/list.h @@ -15,7 +15,7 @@ */ #define list_entry(ptr, type, member) container_of(ptr, type, member) -void allocthings(void); +void alloc_things(void); void *_allocentry(size_t size); #define allocentry(type) (type*) _allocentry(sizeof(type)) void freeentry(void *ptr); @@ -29,6 +29,7 @@ void list_del(listhead *entry); void list_init_head(listhead *head); +void things_list_clear(listhead *head); /* listhead member must be the first member */ /** * list_for_each_entry - iterate over list of given type