diff --git a/bomber.h b/bomber.h index 265c1a3..522b8b6 100644 --- a/bomber.h +++ b/bomber.h @@ -158,17 +158,6 @@ typedef struct generic { int data1,data2; } generic; -typedef union genericlistitem genericlistitem; -union genericlistitem { - listhead h; - bomb b; - flame f; - brickdecay bc; - player p; - bonustile bt; - generic g; -}; - enum tile_types { TILE_NONE = -1, TILE_DISEASE = 0, diff --git a/draw.c b/draw.c index c6439e1..a625051 100644 --- a/draw.c +++ b/draw.c @@ -53,7 +53,7 @@ int bigfontxsize,bigfontysize,bigfontyspace; static int textx,texty; -static char *remapstring="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.:!?\177/\\*-,>< ="; +static const unsigned char *remapstring = (const unsigned char*) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.:!?\177/\\*-,>< ="; static char asciiremap[256]; /* On screen array variables */ @@ -202,16 +202,16 @@ static void texthome(void) { textx=texty=10; } -// static void drawstring(int xpos,int ypos,char *str) { -// char ch; -// -// while((ch=*str++)) { -// drawfigure(xpos,ypos,font+asciiremap[toupper(ch)]); -// xpos+=fontxsize; -// } -// } +void drawstring(int xpos, int ypos, const char *str) { + char ch; -void drawbigstring(int xpos,int ypos,char *str) { + while((ch=*str++)) { + drawfigure(xpos,ypos,font+asciiremap[toupper(ch)]); + xpos+=fontxsize; + } +} + +void drawbigstring(int xpos, int ypos, const char *str) { char ch; while('\0' != (ch=*str++)) { @@ -220,7 +220,7 @@ void drawbigstring(int xpos,int ypos,char *str) { } } -void centerbig(int y,char *str) { +void centerbig(int y, const char *str) { int w; w=strlen(str)*bigfontxsize; @@ -363,7 +363,7 @@ int arraytoscreeny(int y) { static void loadfonts(void) { int i,j; - char *p; + const unsigned char *p; getsingle(fontname,font,NUMCHARACTERS); getsingle(bigfontname,bigfont,NUMCHARACTERS); @@ -377,7 +377,7 @@ static void loadfonts(void) { memset(asciiremap,j,sizeof(asciiremap)); p=remapstring; i=0; - while(*p && i<40) + while(*p && ixpos=arraytoscreenx(px); @@ -243,7 +255,7 @@ static void adddecay(int px,int py) { static void addbonus(int px,int py,int type) { bonustile *bonus; - bonus=allocentry(); + bonus = allocentry(bonustile); if(!bonus) return; addtail(&activebonus,bonus); bonus->px=px; @@ -277,7 +289,8 @@ static void deletebonus(bonustile *bonus) { py=bonus->py; field[py][px]=0; info[py][px]=0; - delink(bonus); + list_del(&bonus->list); + freeentry(bonus); } static void adddetonate(bomb *bmb) { @@ -294,7 +307,7 @@ static void adddetonate(bomb *bmb) { static void processbombs() { bomb *bmb, *next; - foreach_list_safe(&activebombs, bmb, next) { + list_for_each_entry_safe(bmb, next, &activebombs, list) { ++(bmb->figcount); ++bmb->timer; switch(bmb->type) { @@ -357,7 +370,8 @@ static void detonatebomb(bomb *bmb) { py=bmb->py; power=bmb->power; owner=bmb->owner; - delink(bmb); + list_del(&bmb->list); + freeentry(bmb); addflame(owner,px,py); flameshaft(owner,px,py,-1,0,power); flameshaft(owner,px,py,0,-1,power); @@ -380,13 +394,14 @@ static void dodetonations(void) { static void processflames(void) { flame *fl, *next; - foreach_list_safe(&activeflames, fl, next) { + list_for_each_entry_safe(fl, next, &activeflames, list) { ++(fl->timer); if(fl->timer==FLAMELIFE) { field[fl->py][fl->px]=FIELD_EMPTY; info[fl->py][fl->px]=0; - delink(fl); + list_del(&fl->list); + freeentry(fl); } } } @@ -394,12 +409,13 @@ static void processflames(void) { static void processdecays() { brickdecay *bd, *next; - foreach_list_safe(&activedecays, bd, next) { + list_for_each_entry_safe(bd, next, &activedecays, list) { ++(bd->timer); if(bd->timer == DECAYLIFE) { field[bd->py][bd->px] = FIELD_EMPTY; trybonus(bd->px, bd->py); - delink(bd); + list_del(&bd->list); + freeentry(bd); } } } @@ -411,7 +427,7 @@ static void drawbombs(void) { int color; int xpos,ypos; - foreach_list_fast(&activebombs, bmb) { + list_for_each_entry(bmb, &activebombs, list) { color=bmb->owner->color; figtab=(bmb->type==BOMB_NORMAL) ? bombs1[color] : bombs2[color]; j=bmb->figcount % (NUMBOMBFRAMES<<1); @@ -429,7 +445,7 @@ static void drawflames(void) { int color; int fig; - foreach_list_fast(&activeflames, fl) { + list_for_each_entry(fl, &activeflames, list) { color=fl->owner->color; xpos=tovideox(fl->xpos); ypos=tovideoy(fl->ypos); @@ -443,7 +459,7 @@ static void drawflames(void) { static void drawdecays() { brickdecay *bd; - foreach_list_fast(&activedecays, bd) { + list_for_each_entry(bd, &activedecays, list) { addsprite(tovideox(bd->xpos),tovideoy(bd->ypos), blocksx+(bd->timer*9)/DECAYLIFE); } @@ -452,7 +468,7 @@ static void drawdecays() { static void drawbonus() { bonustile *bonus; - foreach_list_fast(&activebonus, bonus) { + list_for_each_entry(bonus, &activebonus, list) { addsprite(tovideox(bonus->xpos),tovideoy(bonus->ypos), tiles+bonus->type); } @@ -462,7 +478,7 @@ static void drawplayers() { player *pl; int xpos,ypos; - foreach_list_fast(&activeplayers, pl) { + list_for_each_entry(pl, &activeplayers, list) { if(!(pl->flags & FLG_DEAD)) { if(!pl->figure) pl->figure=walking[pl->color]+30; @@ -476,15 +492,17 @@ static void drawplayers() { static void detonatecontrolled(player *pl) { bomb *bmb, *next; - foreach_list_safe(&activebombs, bmb, next) { + list_for_each_entry_safe(bmb, next, &activebombs, list) { if(bmb->owner==pl && bmb->type==BOMB_CONTROLLED) adddetonate(bmb); } } static void playonce(generic *gen) { - if(gen->timer==gen->data1) - delink(gen); + if (gen->timer == gen->data1) { + list_del(&gen->list); + freeentry(gen); + } } static void drawgeneric(generic *gen) { @@ -494,7 +512,7 @@ static void drawgeneric(generic *gen) { static void queuesequence(int xpos,int ypos,figure *fig,int count) { generic *gen; - gen=allocentry(); + gen = allocentry(generic); if(!gen) return; gen->xpos=xpos; gen->ypos=ypos; @@ -514,6 +532,11 @@ static void adddeath(player *pl) { } static void killplayer(player *pl) { + if (pl->controller == -1) { + host_deaths++; + } else { + netnodes[pl->controller].deaths++; + } pl->flags|=FLG_DEAD; playsound(2); adddeath(pl); @@ -523,7 +546,7 @@ static void killplayer(player *pl) { static void processgenerics(void) { generic *gen, *next; - foreach_list_safe(&activegeneric, gen, next) { + list_for_each_entry_safe(gen, next, &activegeneric, list) { ++(gen->timer); gen->process(gen); } @@ -532,11 +555,34 @@ static void processgenerics(void) { static void drawgenerics(void) { generic *gen; - foreach_list_fast(&activegeneric, gen) { + list_for_each_entry(gen, &activegeneric, list) { gen->draw(gen); } } +static void drawstats(void) { + int d, k, p = 0, i; + 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; + } else { + k = host_kills; + d = host_deaths; + n = playername; + } + snprintf(buf, sizeof(buf), "%-8.8s %2i/%2i", n, k % 100, d % 100); + drawstring(11 + (p/2) * (15 * fontxsize + 7), 11 + (p%2) * (fontysize+2), buf); + p++; + } +} + static int centerxchange(player *pl) { int speed; int val; @@ -764,7 +810,7 @@ static void doplayer(player *pl) { static void processplayers(void) { player *pl, *next; - foreach_list_safe(&activeplayers, pl, next) { + list_for_each_entry_safe(pl, next, &activeplayers, list) { doplayer(pl); } } @@ -850,6 +896,7 @@ static int iterate(void) { drawdecays(); drawflames(); drawplayers(); + drawstats(); plotsprites(); copyup(); if (list_empty(&activegeneric)) { @@ -858,7 +905,7 @@ static int iterate(void) { int deadplayers = 0; i = 0; - foreach_list_fast(&activeplayers, pl) { + list_for_each_entry(pl, &activeplayers, list) { if(!(pl->flags & FLG_DEAD)) ++i; else diff --git a/list.c b/list.c index 186ef3d..85df0e5 100644 --- a/list.c +++ b/list.c @@ -3,9 +3,20 @@ #include "list.h" #include "utils.h" +typedef union genericlistitem genericlistitem; +union genericlistitem { + genericlistitem *next; + bomb b; + flame f; + brickdecay bc; + player p; + bonustile bt; + generic g; +}; + /* doesn't use prev link */ static genericlistitem *things=0; -static listhead *free_things; +static genericlistitem *free_things; void allocthings(void) { int i; @@ -18,14 +29,16 @@ void allocthings(void) { } if(!things) nomem("Trying to allocate thing memory"); for(i=0;i sizeof(genericlistitem)) return 0; if (free_things) { free_things = free_things->next; @@ -34,34 +47,26 @@ void *allocentry(void) { return entry; } -void _freeentry(listhead *entry) { +void freeentry(void *ptr) { + genericlistitem *entry = ptr; entry->next = free_things; - entry->prev = NULL; free_things = entry; } -void _addtail(listhead *head, listhead *entry) { +void list_add_tail(listhead *head, listhead *entry) { entry->next = head; entry->prev = head->prev; head->prev->next = entry; head->prev = entry; } -void _removeitem(listhead *entry) { +void list_del(listhead *entry) { entry->next->prev = entry->prev; entry->prev->next = entry->next; + entry->next = entry->prev = entry; } -listhead* delinkhead(listhead *entry) { - listhead *result = entry->prev; - - _removeitem(entry); - _freeentry(entry); - return result; -} - -void initheader(listhead *head) { +void list_init_head(listhead *head) { head->next = head; head->prev = head; } - diff --git a/list.h b/list.h index f6ad7ea..bf11f20 100644 --- a/list.h +++ b/list.h @@ -1,32 +1,59 @@ #ifndef LIST_H #define LIST_H -void allocthings(void); -void *allocentry(void); -void _freeentry(listhead *entry); -#define freeentry(entry) _freeentry(&(entry->list)); +/* from linux kernel */ -void _addtail(listhead *header, listhead *entry); -#define addtail(head, entry) _addtail(head, &(entry->list)); +#define container_of(ptr, type, member) ({ \ + const typeof( ((type *)0)->member ) *__mptr = (ptr); \ + (type *)( (char *)__mptr - offsetof(type,member) );}) + +/** + * list_entry - get the struct for this entry + * @ptr: the &struct list_head pointer. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) container_of(ptr, type, member) + +void allocthings(void); +void *_allocentry(size_t size); +#define allocentry(type) (type*) _allocentry(sizeof(type)) +void freeentry(void *ptr); + +void list_add_tail(listhead *header, listhead *entry); +#define addtail(head, entry) list_add_tail(head, &(entry->list)); /* remove entry from list */ -void _removeitem(listhead *entry); -#define removeitem(entry) _removeitem(&(entry->list)); +void list_del(listhead *entry); +#define removeitem(entry) list_del(&(entry->list)); -/* returns previous entry, deletes entry */ -listhead* delinkhead(listhead *entry); -#define delink(entry) delinkhead(&(entry->list)); +void list_init_head(listhead *head); -void initheader(listhead *head); +/** + * list_for_each_entry - iterate over list of given type + * @pos: the type * to use as a loop cursor. + * @head: the head for your list. + * @member: the name of the list_struct within the struct. + */ +#define list_for_each_entry(pos, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member); \ + /* prefetch(pos->member.next), */ \ + &pos->member != (head); \ + pos = list_entry(pos->member.next, typeof(*pos), member)) -/* listhead *head, XXX *item */ -#define foreach_list_fast(head, item) \ - for (item = (void*) (head)->next; (listhead*) item != (head); item = (void*) ((listhead*)item)->next) - -/* listhead *head, XXX *item, XXX *next : you are allowed to delink(item) */ -#define foreach_list_safe(head, item, next) \ - for (item = (void*) (head)->next, next = (void*) ((listhead*)item)->next; (listhead*) item != (head); item = next, next = (void*) ((listhead*)item)->next) +/** + * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry + * @pos:<-->the type * to use as a loop cursor. + * @n:<><-->another type * to use as temporary storage + * @head:<->the head for your list. + * @member:>the name of the list_struct within the struct. + */ +#define list_for_each_entry_safe(pos, n, head, member) \ + for (pos = list_entry((head)->next, typeof(*pos), member), \ + n = list_entry(pos->member.next, typeof(*pos), member); \ + &pos->member != (head); \ + pos = n, n = list_entry(n->member.next, typeof(*n), member)) #define list_empty(head) ((head) == (head)->next) diff --git a/network.h b/network.h index 7ac98dd..e666429 100644 --- a/network.h +++ b/network.h @@ -5,12 +5,16 @@ #include #include -#define MAXNETNODES 8 +enum { + MAXNETNODES = 8 +} maxnetnodesconst; struct netnode { struct sockaddr_in netname; char name[16]; char used; + + int kills, deaths; }; extern struct netnode netnodes[MAXNETNODES];