From 4c516766ba1b1397f6789f34da08f1db6d979972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20B=C3=BChler?= Date: Tue, 11 Aug 2009 17:19:43 +0200 Subject: [PATCH] List rewrite --- Makefile | 2 +- bomber.h | 52 ++++++++++++----------- game.c | 127 ++++++++++++++++++++++++------------------------------- list.c | 50 ++++++++++++---------- list.h | 20 +++++++-- 5 files changed, 126 insertions(+), 125 deletions(-) diff --git a/Makefile b/Makefile index 6bd384f..d28716d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ DBG = -g CC = gcc WARNFLAGS = -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wformat-security -override CFLAGS += -D_REENTRANT -O2 $(shell sdl-config --cflags) $(DBG) $(WARNFLAGS) +override CFLAGS += -D_REENTRANT $(shell sdl-config --cflags) $(DBG) $(WARNFLAGS) .PHONY: all clean install all: sdlbomber diff --git a/bomber.h b/bomber.h index b526e67..c76234c 100644 --- a/bomber.h +++ b/bomber.h @@ -59,9 +59,13 @@ typedef struct solid uchar *graphics; } solid; -typedef struct player -{ - struct player *next; +typedef struct listhead listhead; +struct listhead { + listhead *prev, *next; +}; + +typedef struct player { + listhead list; int xpos,ypos; int flags; int abilities; @@ -95,12 +99,8 @@ typedef struct damage { int xsize,ysize; } damage; -typedef struct list { - void *next; -} list; - typedef struct bomb { - struct bomb *next; + listhead list; int type; int xpos,ypos; int px,py; @@ -119,7 +119,7 @@ typedef struct bomb { #define DECAYLIFE 15 typedef struct flame { - struct flame *next; + listhead list; int xpos,ypos; int px,py; int timer; @@ -133,23 +133,21 @@ typedef struct flame { #define FL_RIGHT 4 typedef struct brickdecay { - struct brickdecay *next; + listhead list; int xpos,ypos; int px,py; int timer; } brickdecay; -typedef union listitem listitem; -union listitem { - listitem *next; - bomb b; - flame f; - brickdecay bc; - player p; -}; +typedef struct bonustile { + listhead list; + int xpos,ypos; + int px,py; + int type; +} bonustile; typedef struct generic { - struct generic *next; + listhead list; int xpos,ypos; int px,py; int timer; @@ -159,12 +157,16 @@ typedef struct generic { int data1,data2; } generic; -typedef struct bonustile { - struct bonustile *next; - int xpos,ypos; - int px,py; - int type; -} bonustile; +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, diff --git a/game.c b/game.c index 0a28b5a..e00757f 100644 --- a/game.c +++ b/game.c @@ -11,20 +11,20 @@ static int gameframe; -static list activebombs; -static list activedecays; -static list activebonus; -static list activegeneric; +static listhead activebombs; +static listhead activedecays; +static listhead activebonus; +static listhead activegeneric; static bomb *detonated[MAXBOMBSDETONATED]; static int detonateput=0; static int detonatetake=0; -static list activeflames; -static list activeplayers; +static listhead activeflames; +static listhead activeplayers; figure walking[MAXSETS][NUMWALKFRAMES]; -solid background,backgroundoriginal; +solid background, backgroundoriginal; /* The playfield array, contains FIELD_* equates */ unsigned char field[32][32]; @@ -68,7 +68,6 @@ static void initplayer(int color,int x,int y,int controller) { if(!pl) nomem("Couldn't get player structure (allocentry())"); addtail(&activeplayers,pl); - memset(pl,0,sizeof(player)); pl->xpos=arraytoscreenx(x); pl->ypos=arraytoscreeny(y); pl->color=color; @@ -239,9 +238,9 @@ static void adddetonate(bomb *bmb) { static void processbombs() { bomb *bmb; + listhead *iter; - bmb=activebombs.next; - while(bmb) { + foreach_list_entry(&activebombs, iter, bmb) { switch(bmb->type) { case BOMB_NORMAL: ++bmb->timer; @@ -253,7 +252,6 @@ static void processbombs() { ++(bmb->figcount); break; } - bmb=bmb->next; } } @@ -313,7 +311,7 @@ static void deletebonus(bonustile *bonus) { py=bonus->py; field[py][px]=0; info[py][px]=0; - delink(&activebonus,bonus); + delink(bonus); } static void flameshaft(player *owner,int px,int py,int dx,int dy,int power) { @@ -361,7 +359,7 @@ static void detonatebomb(bomb *bmb) { py=bmb->py; power=bmb->power; owner=bmb->owner; - delink(&activebombs,bmb); + delink(bmb); addflame(owner,px,py); flameshaft(owner,px,py,-1,0,power); flameshaft(owner,px,py,0,-1,power); @@ -381,53 +379,43 @@ static void dodetonations(void) { } static void processflames(void) { - flame *fl,*fl2; + flame *fl; + listhead *iter; - fl=activeflames.next; - while(fl) { + foreach_list_entry(&activeflames, iter, fl) { ++(fl->timer); - fl=fl->next; - } - fl=activeflames.next; - while(fl) { - if(fl->timer==FLAMELIFE) - { + + if(fl->timer==FLAMELIFE) { field[fl->py][fl->px]=FIELD_EMPTY; info[fl->py][fl->px]=0; - fl2=fl; - fl=fl->next; - delink(&activeflames,fl2); - } else - fl=fl->next; + iter = delinkhead(iter); + } } } static void processdecays() { - brickdecay *bd,*bd2; + brickdecay *bd; + listhead *iter; - bd=activedecays.next; - while(bd) { + foreach_list_entry(&activedecays, iter, bd) { ++(bd->timer); - if(bd->timer==DECAYLIFE) { - field[bd->py][bd->px]=FIELD_EMPTY; - trybonus(bd->px,bd->py); - bd2=bd; - bd=bd->next; - delink(&activedecays,bd2); - } else - bd=bd->next; + if(bd->timer == DECAYLIFE) { + field[bd->py][bd->px] = FIELD_EMPTY; + trybonus(bd->px, bd->py); + iter = delinkhead(iter); + } } } static void drawbombs(void) { int j; bomb *bmb; + listhead *iter; struct figure *figtab; int color; int xpos,ypos; - bmb=activebombs.next; - while(bmb) { + foreach_list_entry(&activebombs, iter, bmb) { color=bmb->owner->color; figtab=(bmb->type==BOMB_NORMAL) ? bombs1[color] : bombs2[color]; j=bmb->figcount % (NUMBOMBFRAMES<<1); @@ -436,18 +424,17 @@ static void drawbombs(void) { ypos=tovideoy(bmb->ypos)-3; addsprite(xpos,ypos,figtab+j); - bmb=bmb->next; } } static void drawflames(void) { flame *fl; + listhead *iter; int xpos,ypos; int color; int fig; - fl=activeflames.next; - while(fl) { + foreach_list_entry(&activeflames, iter, fl) { color=fl->owner->color; xpos=tovideox(fl->xpos); ypos=tovideoy(fl->ypos); @@ -455,39 +442,35 @@ static void drawflames(void) { if(fig>=5) fig=9-fig; fig+=5*fl->lurd; addsprite(xpos,ypos,flamefigs[0/* color */]+fig); - fl=fl->next; } } static void drawdecays() { + listhead *iter; brickdecay *bd; - bd=activedecays.next; - while(bd) { + foreach_list_entry(&activedecays, iter, bd) { addsprite(tovideox(bd->xpos),tovideoy(bd->ypos), blocksx+(bd->timer*9)/DECAYLIFE); - bd=bd->next; } } static void drawbonus() { bonustile *bonus; + listhead *iter; - bonus=activebonus.next; - while(bonus) { + foreach_list_entry(&activebonus, iter, bonus) { addsprite(tovideox(bonus->xpos),tovideoy(bonus->ypos), tiles+bonus->type); - bonus=bonus->next; } } static void drawplayers() { player *pl; int xpos,ypos; + listhead *iter; - pl=activeplayers.next; - - while(pl) { + foreach_list_entry(&activeplayers, iter, pl) { if(!(pl->flags & FLG_DEAD)) { if(!pl->figure) pl->figure=walking[pl->color]+30; @@ -495,24 +478,22 @@ static void drawplayers() { ypos=tovideoy(pl->ypos)+pl->fixy; addsprite(xpos,ypos,pl->figure); } - pl=pl->next; } } static void detonatecontrolled(player *pl) { bomb *bmb; + listhead *iter; - bmb=activebombs.next; - while(bmb) { + foreach_list_entry(&activebombs, iter, bmb) { if(bmb->owner==pl && bmb->type==BOMB_CONTROLLED) adddetonate(bmb); - bmb=bmb->next; } } static void playonce(generic *gen) { if(gen->timer==gen->data1) - delink(&activegeneric,gen); + delink(gen); } static void drawgeneric(generic *gen) { @@ -551,10 +532,10 @@ static void killplayer(player *pl) { static void processgenerics(void) { generic *gen,*gen2; - gen=activegeneric.next; - while(gen) { - gen2=gen; - gen=gen->next; + gen = (generic*) activegeneric.next; + while ((listhead*) gen != &activegeneric) { + gen2 = gen; + gen = (generic*) gen->list.next; ++(gen2->timer); gen2->process(gen2); } @@ -562,11 +543,10 @@ static void processgenerics(void) { static void drawgenerics(void) { generic *gen; + listhead *iter; - gen=activegeneric.next; - while(gen) { + foreach_list_entry(&activegeneric, iter, gen) { gen->draw(gen); - gen=gen->next; } } @@ -795,12 +775,12 @@ static void doplayer(player *pl) { } static void processplayers(void) { - player *pl,*pl2; + player *pl, *pl2; - pl=activeplayers.next; - while(pl) { - pl2=pl; - pl=pl->next; + pl = (player*) activeplayers.next; + while ((listhead*) pl != &activeplayers) { + pl2 = pl; + pl = (player*) pl->list.next; doplayer(pl2); } } @@ -888,11 +868,14 @@ static int iterate(void) { drawplayers(); plotsprites(); copyup(); - if(!activegeneric.next) { + if (activegeneric.next == &activegeneric) { player *pl; + listhead *iter; + int deadplayers = 0; i = 0; - for (pl = activeplayers.next; pl; pl = pl->next) { + + foreach_list_entry(&activeplayers, iter, pl) { if(!(pl->flags & FLG_DEAD)) ++i; else diff --git a/list.c b/list.c index b6658de..f10b0fb 100644 --- a/list.c +++ b/list.c @@ -3,60 +3,64 @@ #include "list.h" #include "utils.h" -static listitem *things=0, *free_things; +/* doesn't use prev link */ +static genericlistitem *things=0; +static listhead *free_things; void allocthings(void) { int i; const int num = MAXTHINGS; if (!things) { - things = calloc(sizeof(listitem), num); + things = calloc(sizeof(genericlistitem), num); } else { - memset(things, 0, sizeof(listitem)*num); + memset(things, 0, sizeof(genericlistitem)*num); } if(!things) nomem("Trying to allocate thing memory"); for(i=0;inext; - memset(entry, 0, sizeof(*entry)); + memset(entry, 0, sizeof(genericlistitem)); } return entry; } -void freeentry(void *_entry) { - listitem *entry = _entry; +static void freeentry(void *_entry) { + listhead *entry = _entry; entry->next = free_things; + entry->prev = NULL; free_things = entry; } -void addtail(void *_header,void *_entry) { - listitem *header = _header, *entry = _entry; - - while (header->next) header = header->next; - header->next = entry; - entry->next = 0; +void _addtail(listhead *head, listhead *entry) { + entry->next = head; + entry->prev = head->prev; + head->prev->next = entry; + head->prev = entry; } -void delink(void *_header,void *_entry) { - listitem *header = _header, *entry = _entry; +listhead* delinkhead(listhead *entry) { + listhead *result = entry->prev; + + entry->next->prev = entry->prev; + entry->prev->next = entry->next; - while (header->next != entry) header = header->next; - header->next = entry->next; - entry->next = 0; freeentry(entry); + return result; } -void initheader(void *p) { - memset(p,0,sizeof(list)); +void initheader(listhead *head) { + head->next = head; + head->prev = head; } diff --git a/list.h b/list.h index b2a628f..3dd7e68 100644 --- a/list.h +++ b/list.h @@ -3,10 +3,22 @@ void allocthings(void); void *allocentry(void); -void freeentry(void *entry); -void addtail(void *header,void *entry); -void delink(void *header,void *entry); -void initheader(void *p); +void _addtail(listhead *header, listhead *entry); +#define addtail(head, entry) _addtail(head, &(entry->list)); + +/* returns previous entry, use as + * iter = delinkhead(iter); + * in foreach_list_entry loops + */ +listhead* delinkhead(listhead *entry); +#define delink(entry) delinkhead(&(entry->list)); + + +void initheader(listhead *head); + +/* listhead *head, listhead *iter, XXX *item */ +#define foreach_list_entry(head, iter, item) \ + for (iter = (head)->next, item = (void*) iter; iter != (head); iter = iter->next, item = (void*) iter) #endif