List rewrite

This commit is contained in:
Stefan Bühler 2009-08-11 17:19:43 +02:00
parent f00652cac7
commit 4c516766ba
5 changed files with 126 additions and 125 deletions

View File

@ -1,7 +1,7 @@
DBG = -g DBG = -g
CC = gcc CC = gcc
WARNFLAGS = -Wall -Wmissing-declarations -Wdeclaration-after-statement -Wcast-align -Winline -Wsign-compare -Wnested-externs -Wpointer-arith -Wformat-security 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 .PHONY: all clean install
all: sdlbomber all: sdlbomber

View File

@ -59,9 +59,13 @@ typedef struct solid
uchar *graphics; uchar *graphics;
} solid; } solid;
typedef struct player typedef struct listhead listhead;
{ struct listhead {
struct player *next; listhead *prev, *next;
};
typedef struct player {
listhead list;
int xpos,ypos; int xpos,ypos;
int flags; int flags;
int abilities; int abilities;
@ -95,12 +99,8 @@ typedef struct damage {
int xsize,ysize; int xsize,ysize;
} damage; } damage;
typedef struct list {
void *next;
} list;
typedef struct bomb { typedef struct bomb {
struct bomb *next; listhead list;
int type; int type;
int xpos,ypos; int xpos,ypos;
int px,py; int px,py;
@ -119,7 +119,7 @@ typedef struct bomb {
#define DECAYLIFE 15 #define DECAYLIFE 15
typedef struct flame { typedef struct flame {
struct flame *next; listhead list;
int xpos,ypos; int xpos,ypos;
int px,py; int px,py;
int timer; int timer;
@ -133,23 +133,21 @@ typedef struct flame {
#define FL_RIGHT 4 #define FL_RIGHT 4
typedef struct brickdecay { typedef struct brickdecay {
struct brickdecay *next; listhead list;
int xpos,ypos; int xpos,ypos;
int px,py; int px,py;
int timer; int timer;
} brickdecay; } brickdecay;
typedef union listitem listitem; typedef struct bonustile {
union listitem { listhead list;
listitem *next; int xpos,ypos;
bomb b; int px,py;
flame f; int type;
brickdecay bc; } bonustile;
player p;
};
typedef struct generic { typedef struct generic {
struct generic *next; listhead list;
int xpos,ypos; int xpos,ypos;
int px,py; int px,py;
int timer; int timer;
@ -159,12 +157,16 @@ typedef struct generic {
int data1,data2; int data1,data2;
} generic; } generic;
typedef struct bonustile { typedef union genericlistitem genericlistitem;
struct bonustile *next; union genericlistitem {
int xpos,ypos; listhead h;
int px,py; bomb b;
int type; flame f;
} bonustile; brickdecay bc;
player p;
bonustile bt;
generic g;
};
enum tile_types { enum tile_types {
TILE_NONE = -1, TILE_NONE = -1,

127
game.c
View File

@ -11,20 +11,20 @@
static int gameframe; static int gameframe;
static list activebombs; static listhead activebombs;
static list activedecays; static listhead activedecays;
static list activebonus; static listhead activebonus;
static list activegeneric; static listhead activegeneric;
static bomb *detonated[MAXBOMBSDETONATED]; static bomb *detonated[MAXBOMBSDETONATED];
static int detonateput=0; static int detonateput=0;
static int detonatetake=0; static int detonatetake=0;
static list activeflames; static listhead activeflames;
static list activeplayers; static listhead activeplayers;
figure walking[MAXSETS][NUMWALKFRAMES]; figure walking[MAXSETS][NUMWALKFRAMES];
solid background,backgroundoriginal; solid background, backgroundoriginal;
/* The playfield array, contains FIELD_* equates */ /* The playfield array, contains FIELD_* equates */
unsigned char field[32][32]; unsigned char field[32][32];
@ -68,7 +68,6 @@ static void initplayer(int color,int x,int y,int controller) {
if(!pl) if(!pl)
nomem("Couldn't get player structure (allocentry())"); nomem("Couldn't get player structure (allocentry())");
addtail(&activeplayers,pl); addtail(&activeplayers,pl);
memset(pl,0,sizeof(player));
pl->xpos=arraytoscreenx(x); pl->xpos=arraytoscreenx(x);
pl->ypos=arraytoscreeny(y); pl->ypos=arraytoscreeny(y);
pl->color=color; pl->color=color;
@ -239,9 +238,9 @@ static void adddetonate(bomb *bmb) {
static void processbombs() { static void processbombs() {
bomb *bmb; bomb *bmb;
listhead *iter;
bmb=activebombs.next; foreach_list_entry(&activebombs, iter, bmb) {
while(bmb) {
switch(bmb->type) { switch(bmb->type) {
case BOMB_NORMAL: case BOMB_NORMAL:
++bmb->timer; ++bmb->timer;
@ -253,7 +252,6 @@ static void processbombs() {
++(bmb->figcount); ++(bmb->figcount);
break; break;
} }
bmb=bmb->next;
} }
} }
@ -313,7 +311,7 @@ static void deletebonus(bonustile *bonus) {
py=bonus->py; py=bonus->py;
field[py][px]=0; field[py][px]=0;
info[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) { 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; py=bmb->py;
power=bmb->power; power=bmb->power;
owner=bmb->owner; owner=bmb->owner;
delink(&activebombs,bmb); delink(bmb);
addflame(owner,px,py); addflame(owner,px,py);
flameshaft(owner,px,py,-1,0,power); flameshaft(owner,px,py,-1,0,power);
flameshaft(owner,px,py,0,-1,power); flameshaft(owner,px,py,0,-1,power);
@ -381,53 +379,43 @@ static void dodetonations(void) {
} }
static void processflames(void) { static void processflames(void) {
flame *fl,*fl2; flame *fl;
listhead *iter;
fl=activeflames.next; foreach_list_entry(&activeflames, iter, fl) {
while(fl) {
++(fl->timer); ++(fl->timer);
fl=fl->next;
} if(fl->timer==FLAMELIFE) {
fl=activeflames.next;
while(fl) {
if(fl->timer==FLAMELIFE)
{
field[fl->py][fl->px]=FIELD_EMPTY; field[fl->py][fl->px]=FIELD_EMPTY;
info[fl->py][fl->px]=0; info[fl->py][fl->px]=0;
fl2=fl; iter = delinkhead(iter);
fl=fl->next; }
delink(&activeflames,fl2);
} else
fl=fl->next;
} }
} }
static void processdecays() { static void processdecays() {
brickdecay *bd,*bd2; brickdecay *bd;
listhead *iter;
bd=activedecays.next; foreach_list_entry(&activedecays, iter, bd) {
while(bd) {
++(bd->timer); ++(bd->timer);
if(bd->timer==DECAYLIFE) { if(bd->timer == DECAYLIFE) {
field[bd->py][bd->px]=FIELD_EMPTY; field[bd->py][bd->px] = FIELD_EMPTY;
trybonus(bd->px,bd->py); trybonus(bd->px, bd->py);
bd2=bd; iter = delinkhead(iter);
bd=bd->next; }
delink(&activedecays,bd2);
} else
bd=bd->next;
} }
} }
static void drawbombs(void) { static void drawbombs(void) {
int j; int j;
bomb *bmb; bomb *bmb;
listhead *iter;
struct figure *figtab; struct figure *figtab;
int color; int color;
int xpos,ypos; int xpos,ypos;
bmb=activebombs.next; foreach_list_entry(&activebombs, iter, bmb) {
while(bmb) {
color=bmb->owner->color; color=bmb->owner->color;
figtab=(bmb->type==BOMB_NORMAL) ? bombs1[color] : bombs2[color]; figtab=(bmb->type==BOMB_NORMAL) ? bombs1[color] : bombs2[color];
j=bmb->figcount % (NUMBOMBFRAMES<<1); j=bmb->figcount % (NUMBOMBFRAMES<<1);
@ -436,18 +424,17 @@ static void drawbombs(void) {
ypos=tovideoy(bmb->ypos)-3; ypos=tovideoy(bmb->ypos)-3;
addsprite(xpos,ypos,figtab+j); addsprite(xpos,ypos,figtab+j);
bmb=bmb->next;
} }
} }
static void drawflames(void) { static void drawflames(void) {
flame *fl; flame *fl;
listhead *iter;
int xpos,ypos; int xpos,ypos;
int color; int color;
int fig; int fig;
fl=activeflames.next; foreach_list_entry(&activeflames, iter, fl) {
while(fl) {
color=fl->owner->color; color=fl->owner->color;
xpos=tovideox(fl->xpos); xpos=tovideox(fl->xpos);
ypos=tovideoy(fl->ypos); ypos=tovideoy(fl->ypos);
@ -455,39 +442,35 @@ static void drawflames(void) {
if(fig>=5) fig=9-fig; if(fig>=5) fig=9-fig;
fig+=5*fl->lurd; fig+=5*fl->lurd;
addsprite(xpos,ypos,flamefigs[0/* color */]+fig); addsprite(xpos,ypos,flamefigs[0/* color */]+fig);
fl=fl->next;
} }
} }
static void drawdecays() { static void drawdecays() {
listhead *iter;
brickdecay *bd; brickdecay *bd;
bd=activedecays.next; foreach_list_entry(&activedecays, iter, bd) {
while(bd) {
addsprite(tovideox(bd->xpos),tovideoy(bd->ypos), addsprite(tovideox(bd->xpos),tovideoy(bd->ypos),
blocksx+(bd->timer*9)/DECAYLIFE); blocksx+(bd->timer*9)/DECAYLIFE);
bd=bd->next;
} }
} }
static void drawbonus() { static void drawbonus() {
bonustile *bonus; bonustile *bonus;
listhead *iter;
bonus=activebonus.next; foreach_list_entry(&activebonus, iter, bonus) {
while(bonus) {
addsprite(tovideox(bonus->xpos),tovideoy(bonus->ypos), addsprite(tovideox(bonus->xpos),tovideoy(bonus->ypos),
tiles+bonus->type); tiles+bonus->type);
bonus=bonus->next;
} }
} }
static void drawplayers() { static void drawplayers() {
player *pl; player *pl;
int xpos,ypos; int xpos,ypos;
listhead *iter;
pl=activeplayers.next; foreach_list_entry(&activeplayers, iter, pl) {
while(pl) {
if(!(pl->flags & FLG_DEAD)) { if(!(pl->flags & FLG_DEAD)) {
if(!pl->figure) if(!pl->figure)
pl->figure=walking[pl->color]+30; pl->figure=walking[pl->color]+30;
@ -495,24 +478,22 @@ static void drawplayers() {
ypos=tovideoy(pl->ypos)+pl->fixy; ypos=tovideoy(pl->ypos)+pl->fixy;
addsprite(xpos,ypos,pl->figure); addsprite(xpos,ypos,pl->figure);
} }
pl=pl->next;
} }
} }
static void detonatecontrolled(player *pl) { static void detonatecontrolled(player *pl) {
bomb *bmb; bomb *bmb;
listhead *iter;
bmb=activebombs.next; foreach_list_entry(&activebombs, iter, bmb) {
while(bmb) {
if(bmb->owner==pl && bmb->type==BOMB_CONTROLLED) if(bmb->owner==pl && bmb->type==BOMB_CONTROLLED)
adddetonate(bmb); adddetonate(bmb);
bmb=bmb->next;
} }
} }
static void playonce(generic *gen) { static void playonce(generic *gen) {
if(gen->timer==gen->data1) if(gen->timer==gen->data1)
delink(&activegeneric,gen); delink(gen);
} }
static void drawgeneric(generic *gen) { static void drawgeneric(generic *gen) {
@ -551,10 +532,10 @@ static void killplayer(player *pl) {
static void processgenerics(void) { static void processgenerics(void) {
generic *gen,*gen2; generic *gen,*gen2;
gen=activegeneric.next; gen = (generic*) activegeneric.next;
while(gen) { while ((listhead*) gen != &activegeneric) {
gen2=gen; gen2 = gen;
gen=gen->next; gen = (generic*) gen->list.next;
++(gen2->timer); ++(gen2->timer);
gen2->process(gen2); gen2->process(gen2);
} }
@ -562,11 +543,10 @@ static void processgenerics(void) {
static void drawgenerics(void) { static void drawgenerics(void) {
generic *gen; generic *gen;
listhead *iter;
gen=activegeneric.next; foreach_list_entry(&activegeneric, iter, gen) {
while(gen) {
gen->draw(gen); gen->draw(gen);
gen=gen->next;
} }
} }
@ -795,12 +775,12 @@ static void doplayer(player *pl) {
} }
static void processplayers(void) { static void processplayers(void) {
player *pl,*pl2; player *pl, *pl2;
pl=activeplayers.next; pl = (player*) activeplayers.next;
while(pl) { while ((listhead*) pl != &activeplayers) {
pl2=pl; pl2 = pl;
pl=pl->next; pl = (player*) pl->list.next;
doplayer(pl2); doplayer(pl2);
} }
} }
@ -888,11 +868,14 @@ static int iterate(void) {
drawplayers(); drawplayers();
plotsprites(); plotsprites();
copyup(); copyup();
if(!activegeneric.next) { if (activegeneric.next == &activegeneric) {
player *pl; player *pl;
listhead *iter;
int deadplayers = 0; int deadplayers = 0;
i = 0; i = 0;
for (pl = activeplayers.next; pl; pl = pl->next) {
foreach_list_entry(&activeplayers, iter, pl) {
if(!(pl->flags & FLG_DEAD)) if(!(pl->flags & FLG_DEAD))
++i; ++i;
else else

50
list.c
View File

@ -3,60 +3,64 @@
#include "list.h" #include "list.h"
#include "utils.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) { void allocthings(void) {
int i; int i;
const int num = MAXTHINGS; const int num = MAXTHINGS;
if (!things) { if (!things) {
things = calloc(sizeof(listitem), num); things = calloc(sizeof(genericlistitem), num);
} else { } else {
memset(things, 0, sizeof(listitem)*num); memset(things, 0, sizeof(genericlistitem)*num);
} }
if(!things) nomem("Trying to allocate thing memory"); if(!things) nomem("Trying to allocate thing memory");
for(i=0;i<num-1;++i) { for(i=0;i<num-1;++i) {
things[i].next = &things[i+1]; things[i].h.next = (listhead*) &things[i+1];
} }
things[i].next = 0; things[i].h.next = 0;
free_things = things; free_things = (listhead*) things;
} }
void *allocentry(void) { void *allocentry(void) {
listitem *entry = free_things; listhead *entry = free_things;
if (free_things) { if (free_things) {
free_things = free_things->next; free_things = free_things->next;
memset(entry, 0, sizeof(*entry)); memset(entry, 0, sizeof(genericlistitem));
} }
return entry; return entry;
} }
void freeentry(void *_entry) { static void freeentry(void *_entry) {
listitem *entry = _entry; listhead *entry = _entry;
entry->next = free_things; entry->next = free_things;
entry->prev = NULL;
free_things = entry; free_things = entry;
} }
void addtail(void *_header,void *_entry) { void _addtail(listhead *head, listhead *entry) {
listitem *header = _header, *entry = _entry; entry->next = head;
entry->prev = head->prev;
while (header->next) header = header->next; head->prev->next = entry;
header->next = entry; head->prev = entry;
entry->next = 0;
} }
void delink(void *_header,void *_entry) { listhead* delinkhead(listhead *entry) {
listitem *header = _header, *entry = _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); freeentry(entry);
return result;
} }
void initheader(void *p) { void initheader(listhead *head) {
memset(p,0,sizeof(list)); head->next = head;
head->prev = head;
} }

20
list.h
View File

@ -3,10 +3,22 @@
void allocthings(void); void allocthings(void);
void *allocentry(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 #endif