ref: 0622cb8e9d9874ee52e9881415554bc38570551d
parent: 10cff16795c01635a868ec5d09beb587df4edb79
author: qwx <[email protected]>
date: Wed Jul 28 08:26:19 EDT 2021
fs: fix not loading redundant pics, explicit rules for sprite sharing previously, assumptions were made which make the code difficult to understand and maintain for no gain. data driven programming is nice, stupidity driven programming less so. instead, explicitely specify sprites for all needed states and whether to freeze a frame or not.
--- a/dat.h
+++ b/dat.h
@@ -78,7 +78,8 @@
int teamcol;
int nf;
int nr;
- int iscopy;
+ int shared;
+ int freeze;
};
struct Attack{
@@ -127,6 +128,7 @@
PFpoor = OSpoor,
PFstatemask = (1 << 5) - 1,
+ PFfreezepic = 1<<11,
PFimmutable = 1<<12,
PFglow = 1<<13,
PFalpha = 1<<14,
@@ -180,7 +182,7 @@
double v;
double speed;
Mobjl *movingp;
- Mobjl *mobjl;
+ Mobjl *mapp;
};
struct Mobj{
Obj *o;
--- a/drw.c
+++ b/drw.c
@@ -322,7 +322,7 @@
pp = &mo->o->pics[n][type];
if(pp->pic == nil)
return nil;
- frm = pp->iscopy ? mo->freezefrm : tc % pp->nf;
+ frm = pp->freeze ? mo->freezefrm : tc % pp->nf;
θ = mo->θ * 32.0 / 256;
switch(pp->nr){
case 17: θ = rot17[θ]; break;
--- a/fs.c
+++ b/fs.c
@@ -32,6 +32,7 @@
int type;
int teamcol;
char *name;
+ char *suff;
char iname[64];
int nr;
Pic *p;
@@ -98,7 +99,7 @@
}
static void
-loadobjpic(Pic *pic, Picl *pl, char *suff)
+loadobjpic(Pic *pic, Picl *pl)
{
int n, i, j;
char path[128];
@@ -107,7 +108,7 @@
for(i=0; i<pl->nr; i++){
snprint(path, sizeof path, "%s.%02d.%02d%s.bit",
- pl->name, pl->frm, rot17idx[i], suff);
+ pl->name, pl->frm, rot17idx[i], pl->suff);
loadpic(path, &pic0, pl->type & PFalpha);
if(!pl->teamcol){
memcpy(pic++, &pic0, sizeof *pic);
@@ -163,12 +164,8 @@
p = pl->p;
if(pl->type & PFtile)
loadtilepic(p, pl);
- else if(pl->type & PFshadow)
- loadobjpic(p, pl, ".s");
- else if(pl->type & PFglow)
- loadobjpic(p, pl, ".g");
else
- loadobjpic(p, pl, "");
+ loadobjpic(p, pl);
pic->l = pl->l;
free(pl);
}
@@ -176,16 +173,26 @@
}
static Pic *
-pushpic(char *name, int frm, int type, int nr, int hasteam)
+pushpic(char *name, int frm, int type, int nr, int hasteam, Pics *ps)
{
int n;
- char iname[64];
+ char iname[64], *suff;
Picl *pl;
- snprint(iname, sizeof iname, "%s%02d%02ux", name, frm, type);
+ if(type & PFshadow)
+ suff = ".s";
+ else if(type & PFglow)
+ suff = ".g";
+ else
+ suff = "";
+ snprint(iname, sizeof iname, "%s.%02d%s", name, frm, suff);
for(pl=pic->l; pl!=pic; pl=pl->l)
- if(strcmp(iname, pl->iname) == 0)
+ if(strcmp(iname, pl->iname) == 0){
+ if(ps == nil)
+ sysfatal("pushpic: tile pic cannot be shared");
+ ps->shared = 1;
break;
+ }
if(pl == pic){
pl = emalloc(sizeof *pl);
memcpy(pl->iname, iname, nelem(pl->iname));
@@ -192,6 +199,7 @@
pl->frm = frm;
pl->type = type;
pl->name = name;
+ pl->suff = suff;
pl->nr = nr;
pl->teamcol = hasteam;
if(nr != 17 && nr != 1)
@@ -220,7 +228,7 @@
tl = emalloc(sizeof *tl);
tl->id = id;
tl->t = emalloc(sizeof *tl->t);
- tl->t->p = pushpic("/tile/", id - 1, PFtile, 1, 0);
+ tl->t->p = pushpic("/tile/", id - 1, PFtile, 1, 0, nil);
tl->l = tilel->l;
tilel->l = tl;
}
@@ -482,6 +490,7 @@
sysfatal("readspr %s: pic type %#ux already allocated", o->name, type);
if(ps->nf != 0 && ps->nf != n || ps->nr != 0 && ps->nr != nr)
sysfatal("readspr %s: spriteset phase error", o->name);
+ ps->freeze = (type & PFfreezepic) != 0;
ps->teamcol = (type & PFimmutable) == 0;
ps->nf = n;
ps->nr = nr;
@@ -489,7 +498,7 @@
*ppp = p;
for(pe=p+n; p<pe; p++){
unpack(fld++, "d", &frm);
- *p = pushpic(o->name, frm, type, nr, ps->teamcol);
+ *p = pushpic(o->name, frm, type, nr, ps->teamcol, ps);
}
}
@@ -626,30 +635,13 @@
}
static void
-fixobjspr(void)
+checkobj(void)
{
Obj *o;
- Pics *idle, *move;
- for(o=obj; o<obj+nobj; o++){
- if(o->f & (Fbuild|Fimmutable))
- continue;
- idle = o->pics[OSidle];
- move = o->pics[OSmove];
- if(idle[PTbase].pic == nil && move[PTbase].pic == nil)
+ for(o=obj; o<obj+nobj; o++)
+ if(o->pics[OSidle][PTbase].pic == nil)
sysfatal("obj %s: no base sprites loaded", o->name);
- if(idle[PTbase].pic == nil){
- memcpy(idle+PTbase, move+PTbase, sizeof *idle);
- memcpy(idle+PTshadow, move+PTshadow, sizeof *idle);
- idle[PTbase].iscopy = 1;
- idle[PTshadow].iscopy = 1;
- }else if(move[PTbase].pic == nil){
- memcpy(move+PTbase, idle+PTbase, sizeof *move);
- memcpy(move+PTshadow, idle+PTshadow, sizeof *move);
- move[PTbase].iscopy = 1;
- move[PTshadow].iscopy = 1;
- }
- }
}
static void
@@ -670,10 +662,10 @@
initdb(void)
{
checkdb();
+ checkobj();
initmap();
initmapobj();
cleanup();
- fixobjspr();
}
void
--- a/sce/sce.db
+++ b/sce/sce.db
@@ -25,9 +25,13 @@
# spr: objname, flags (PF enum), rotations, [frame..]
spr,scv,0x0000,17,0
spr,scv,0xc000,17,0
+spr,scv,0x0001,17,0
+spr,scv,0xc001,17,0
spr,scv,0x6001,17,0,1,2,3
spr,control,0x0000,1,0
spr,control,0xc000,1,0
+spr,drone,0x0800,17,0,1,2,3,4
+spr,drone,0xc800,17,0,1,2,3,4
spr,drone,0x0001,17,0,1,2,3,4
spr,drone,0xc001,17,0,1,2,3,4
spr,hatchery,0x0000,1,0,1,2,3,3,2,1,0
--- a/sim.move.c
+++ b/sim.move.c
@@ -12,7 +12,7 @@
Map *m;
m = map + mo->y / Node2Tile * mapwidth + mo->x / Node2Tile;
- mo->mobjl = linkmobj(mo->o->f & Fair ? m->ml.lp : &m->ml, mo, mo->mobjl);
+ mo->mapp = linkmobj(mo->o->f & Fair ? m->ml.lp : &m->ml, mo, mo->mapp);
}
static void
@@ -58,9 +58,19 @@
static void
freemove(Mobj *mo)
{
+ Pics *old, *new;
+
unlinkmobj(mo->movingp);
mo->pathp = nil;
- mo->freezefrm = tc % mo->o->pics[mo->state][PTbase].nf;
+ old = mo->o->pics[mo->state];
+ new = mo->o->pics[OSidle];
+ if(new->freeze && old->shared){
+ mo->freezefrm = tc % old[PTbase].nf;
+ if(mo->freezefrm > new[PTbase].nf)
+ sysfatal("freemove obj %s: invalid frame number %d > %d",
+ mo->o->name, mo->freezefrm, new[PTbase].nf);
+ }else
+ mo->freezefrm = 0;
mo->state = OSidle;
resetcoords(mo);
}
@@ -219,7 +229,7 @@
int r;
updatespeed(mo);
- unlinkmobj(mo->mobjl);
+ unlinkmobj(mo->mapp);
r = trymove(mo);
linktomap(mo);
return r;