ref: 6141459776d34b526b6a7b500929210020cf3a6d
parent: c357c95979607c5a1e897aefff881e8991f8e2f2
author: qwx <>
date: Sun Sep 10 22:47:53 EDT 2017
refactor load/save code using cinap packing technology also reduce calls to disking() to bare minimum, since these just slow everything down
--- a/fns.h
+++ b/fns.h
@@ -2,8 +2,10 @@
void grab(int);
void toss(void);
void flush(void);
-int wrsav(int);
-int ldsav(int);
+void pack(char*, ...);
+void unpack(char*, ...);
+void wrsav(int);
+void ldsav(int);
char* demof(char*);
void wrconf(void);
void rdconf(void);
@@ -64,8 +66,8 @@
Obj* ospawn(Tile*, State*);
void uworld(void);
void mapmus(void);
-uchar* wrmap(uchar*);
-int ldmap(uchar*, uchar**);
+void wrmap(void);
+void ldmap(void);
void initmap(void);
void sodmap(void);
void dieturn(void);
@@ -81,8 +83,8 @@
void nextmap(void);
void game(void);
void spshunt(void);
-uchar* wrgm(uchar*);
-uchar* ldgm(uchar*);
+void wrgm(void);
+void ldgm(void);
void greset(void);
void ginit(uchar*, int, int);
uchar* opl2out(uchar*, int);
@@ -96,10 +98,3 @@
void stopmus(void);
void mus(int);
void initsnd(void);
-
-#define GET8(p) ((p)[0]);(p)++
-#define GET16(p) ((p)[0]|((p)[1]<<8));(p)+=2
-#define GET32(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24));(p)+=4
-#define PUT8(p,v) (p)[0]=(v);(p)++
-#define PUT16(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)+=2
-#define PUT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24;(p)+=4
--- a/fs.c
+++ b/fs.c
@@ -1,6 +1,7 @@
#include <u.h>
#include <libc.h>
#include <bio.h>
+#include <fcall.h>
#include "dat.h"
#include "fns.h"
@@ -446,20 +447,13 @@
enum{
Nplane = 2,
Planesz = Mapa * Nplane,
- Mapsz = Planesz * Nplane,
- Svgmsz = 2+2+4+4+4+17*2+4+4+4+2+2+2+4+4+1+1,
- Svmapsz = Mapa * (2+2+1+1) + Narea + Narea * Narea,
- Svobjsz = 2+2+2+2+1+4+4+4+2+2+1+2+2+4+2+2+4+2+2,
- Svstsz = 2+2+1+1,
- Svdrsz = 2+1+1+2+2+2,
- Svpshsz = 2+2+2+2,
- Svsz = sizeof(savs[0]) + Svgmsz + Svmapsz + Svobjsz + 2 + 2 + 2 + Svpshsz,
- Svmax = Svsz + Nobj * Svobjsz + (Nstc-1) * Svstsz + (Ndoor-1) * Svdrsz
+ Mapsz = Planesz * Nplane
};
static Dat *pcms;
static int alofs, npcm;
static u16int rlewtag;
static u32int *mapofs, *mape;
+static Biobuf *outbf;
struct Conf{
char *s;
@@ -477,8 +471,6 @@
};
static int badconf;
-#define GBIT16(p) ((p)[0]|((p)[1]<<8))
-
static Biobuf *
bopen(char *f, int m)
{
@@ -504,6 +496,13 @@
return bf;
}
+static void
+ewrite(Biobuf *bf, void *u, long n)
+{
+ if(Bwrite(bf, u, n) != n)
+ sysfatal("ewrite: short write: %r");
+}
+
static long
eread(Biobuf *bf, void *u, long n)
{
@@ -1089,53 +1088,121 @@
}
}
-int
+void
+vpack(char *fmt, va_list a)
+{
+ long n;
+ void *p;
+ u32int v;
+ uchar u[4];
+
+ for(;;){
+ switch(*fmt++){
+ default: sysfatal("unknown format %c", fmt[-1]);
+ case 0: return;
+ out8:
+ ewrite(outbf, u, sizeof(u8int));
+ break;
+ out16:
+ PBIT16(u, v);
+ ewrite(outbf, u, sizeof(u16int));
+ break;
+ case 'b':
+ u[0] = va_arg(a, int);
+ goto out8;
+ case 'B':
+ u[0] = va_arg(a, u8int);
+ goto out8;
+ case 'w':
+ v = va_arg(a, int);
+ goto out16;
+ case 'W':
+ v = va_arg(a, u16int);
+ goto out16;
+ case 'd':
+ v = va_arg(a, int);
+ PBIT32(u, v);
+ ewrite(outbf, u, sizeof(u32int));
+ break;
+ case 'n':
+ p = va_arg(a, void*);
+ n = va_arg(a, long);
+ ewrite(outbf, p, n);
+ break;
+ }
+ }
+}
+
+void
+vunpack(char *fmt, va_list a)
+{
+ long n;
+ void *p;
+
+ for(;;){
+ switch(*fmt++){
+ default: sysfatal("unknown format %c", fmt[-1]);
+ case 0: return;
+ case 'b': *va_arg(a, int*) = get8(outbf); break;
+ case 'B': *va_arg(a, u8int*) = get8(outbf); break;
+ case 'w': *va_arg(a, int*) = get16(outbf); break;
+ case 'W': *va_arg(a, u16int*) = get16(outbf); break;
+ case 'd': *va_arg(a, int*) = get32(outbf); break;
+ case 's': *va_arg(a, int*) = (s16int)get16(outbf); break;
+ case 'S': *va_arg(a, int*) = (s32int)get32(outbf); break;
+ case 'n':
+ p = va_arg(a, void*);
+ n = va_arg(a, long);
+ eread(outbf, p, n);
+ break;
+ }
+ }
+}
+
+void
+pack(char *fmt, ...)
+{
+ va_list a;
+
+ va_start(a, fmt);
+ vpack(fmt, a);
+ va_end(a);
+}
+
+void
+unpack(char *fmt, ...)
+{
+ va_list a;
+
+ va_start(a, fmt);
+ vunpack(fmt, a);
+ va_end(a);
+}
+
+void
wrsav(int i)
{
- int r;
- vlong n;
- uchar *u, *p;
char s[10] = "savegam?.";
- Biobuf *bf;
s[7] = '0' + i;
- bf = eopen(s, OWRITE);
- u = emalloc(Svmax);
- memcpy(u, savs[i], sizeof savs[0]);
- p = wrgm(u + sizeof savs[0]);
- p = wrmap(p);
- assert(p <= u + Svmax);
- n = p - u;
- r = Bwrite(bf, u, n) != n ? -1 : 0;
- Bterm(bf);
- free(u);
- return r;
+ outbf = eopen(s, OWRITE);
+ ewrite(outbf, savs[i], sizeof savs[0]);
+ wrgm();
+ wrmap();
+ Bterm(outbf);
}
-int
+void
ldsav(int i)
{
- int r;
- vlong n;
- uchar *u, *p;
char s[10] = "savegam?.";
- Biobuf *bf;
s[7] = '0' + i;
- bf = eopen(s, OREAD);
- n = bsize(bf);
- if(n < Svsz){
- werrstr("ldsav: short map");
- return -1;
- }
- u = emalloc(n);
- eread(bf, u, n);
- Bterm(bf);
- p = ldgm(u + sizeof savs[0]);
- r = ldmap(p, &p);
- assert(p <= u + n);
- free(u);
- return r;
+ outbf = eopen(s, OREAD);
+ Bseek(outbf, sizeof savs[0], 0);
+ ldgm();
+ ldmap();
+ Bterm(outbf);
}
u16int *
--- a/gm.c
+++ b/gm.c
@@ -2664,80 +2664,27 @@
oplr->areaid = oplr->tl->p0 - MTfloor;
}
-uchar *
-wrgm(uchar *p)
+void
+wrgm(void)
{
disking();
- PUT16(p, gm.difc);
- PUT16(p, gm.map);
- PUT32(p, gm.oldpt);
- PUT32(p, gm.pt);
- PUT32(p, gm.to1up);
- PUT16(p, gm.lives);
- PUT16(p, gm.hp);
- PUT16(p, gm.ammo);
- PUT16(p, gm.keys);
- PUT16(p, gm.bestw);
- PUT16(p, gm.w);
- PUT16(p, gm.lastw);
- PUT16(p, gm.facefrm);
- PUT16(p, atkfrm);
- PUT16(p, atktc);
- PUT16(p, gm.wfrm);
- PUT16(p, gm.sp);
- PUT16(p, gm.tp);
- PUT16(p, gm.kp);
- PUT16(p, gm.stot);
- PUT16(p, gm.ttot);
- PUT16(p, gm.ktot);
- PUT32(p, gm.tc);
- PUT32(p, killx);
- PUT32(p, killy);
- PUT16(p, gm.epk);
- PUT16(p, gm.eps);
- PUT16(p, gm.ept);
- PUT32(p, gm.eptm);
- PUT8(p, dirty);
- PUT8(p, firing);
- return p;
+ pack("wwdddwwwwwwwwwwwwwwwwwdddwwwdbb", gm.difc, gm.map, gm.oldpt,
+ gm.pt, gm.to1up, gm.lives, gm.hp, gm.ammo, gm.keys, gm.bestw,
+ gm.w, gm.lastw, gm.facefrm, atkfrm, atktc, gm.wfrm, gm.sp,
+ gm.tp, gm.kp, gm.stot, gm.ttot, gm.ktot, gm.tc, killx, killy,
+ gm.epk, gm.eps, gm.ept, gm.eptm, dirty, firing);
}
-uchar *
-ldgm(uchar *p)
+void
+ldgm(void)
{
disking();
- gm.difc = GET16(p);
- gm.map = GET16(p);
- gm.oldpt = GET32(p);
- gm.pt = GET32(p);
- gm.to1up = GET32(p);
- gm.lives = GET16(p);
- gm.hp = GET16(p);
- gm.ammo = GET16(p);
- gm.keys = GET16(p);
- gm.bestw = GET16(p);
- gm.w = GET16(p);
- gm.lastw = GET16(p);
- gm.facefrm = GET16(p);
- atkfrm = GET16(p);
- atktc = (s16int)GET16(p);
- gm.wfrm = GET16(p);
- gm.sp = GET16(p);
- gm.tp = GET16(p);
- gm.kp = GET16(p);
- gm.stot = GET16(p);
- gm.ttot = GET16(p);
- gm.ktot = GET16(p);
- gm.tc = GET32(p);
- killx = GET32(p);
- killy = GET32(p);
- gm.epk = GET16(p);
- gm.eps = GET16(p);
- gm.ept = GET16(p);
- gm.eptm = GET32(p);
- dirty = GET8(p);
- firing = GET8(p);
- return p;
+ unpack("wwdddwwwwwwwwwswwwwwwwdddwwwdbb", &gm.difc, &gm.map, &gm.oldpt,
+ &gm.pt, &gm.to1up, &gm.lives, &gm.hp, &gm.ammo, &gm.keys,
+ &gm.bestw, &gm.w, &gm.lastw, &gm.facefrm, &atkfrm, &atktc,
+ &gm.wfrm, &gm.sp, &gm.tp, &gm.kp, &gm.stot, &gm.ttot, &gm.ktot,
+ &gm.tc, &killx, &killy, &gm.epk, &gm.eps, &gm.ept, &gm.eptm,
+ &dirty, &firing);
}
void
--- a/hub.c
+++ b/hub.c
@@ -664,23 +664,16 @@
n = mp->p - mp->s;
if(qsp == ql+Lwrsav){
qsp->q = ql+Lftoctl;
- if(wrsav(n) < 0)
- goto err;
+ wrsav(n);
}else{
qsp->q = ql+Lldsav2;
ginit(nil, -1, 0);
greset();
- if(ldsav(n) < 0)
- goto err;
+ ldsav(n);
ingctl();
loaded++;
}
sfx(Sshoot);
- return;
-err:
- memset(savs[n], 0, sizeof savs[0]);
- qsp->q = ql+Lftoctl;
- sfx(Snoway);
}
static void
--- a/map.c
+++ b/map.c
@@ -819,8 +819,8 @@
mus(ver < SDM ? wlmus[gm.map] : sdmus[gm.map]);
}
-uchar *
-wrmap(uchar *p)
+void
+wrmap(void)
{
Tile *tl;
Obj *o;
@@ -827,62 +827,25 @@
Static *s;
Door *d;
+ for(tl=tiles; tl<tiles+nelem(tiles); tl++)
+ pack("WWBB", tl->p0, tl->p1, tl->tl, tl->to);
+ pack("nn", conarea, sizeof conarea, plrarea, sizeof plrarea);
disking();
- for(tl=tiles; tl<tiles+nelem(tiles); tl++){
- PUT16(p, tl->p0);
- PUT16(p, tl->p1);
- PUT8(p, tl->tl);
- PUT8(p, tl->to);
- }
- memcpy(p, conarea, sizeof conarea); p+=sizeof conarea;
- memcpy(p, plrarea, sizeof plrarea); p+=sizeof plrarea;
- for(o=oplr; o!=objs; o=o->n){
- disking();
- PUT16(p, o->on);
- PUT16(p, o->tc);
- PUT16(p, o->type);
- PUT16(p, o->s - stt);
- PUT8(p, o->f);
- PUT32(p, o->Δr);
- PUT32(p, o->x);
- PUT32(p, o->y);
- PUT16(p, o->tx);
- PUT16(p, o->ty);
- PUT8(p, o->areaid);
- PUT16(p, o->vwx);
- PUT16(p, o->vwdy);
- PUT32(p, o->vwdx);
- PUT16(p, o->θ);
- PUT16(p, o->hp);
- PUT32(p, o->v);
- PUT16(p, o->atkdt);
- PUT16(p, o->sdt);
- }
- PUT16(p, 0xffff);
+ for(o=oplr; o!=objs; o=o->n)
+ pack("wwwwbdddwwbwwdwwdww", o->on, o->tc, o->type, (int)(o->s - stt),
+ o->f, o->Δr, o->x, o->y, o->tx, o->ty, o->areaid,
+ o->vwx, o->vwdy, o->vwdx, o->θ, o->hp, o->v, o->atkdt,
+ o->sdt);
disking();
- PUT16(p, stce - stcs);
- for(s=stcs; s<stce; s++){
- PUT16(p, s->tl != nil ? s->tl - tiles : 0xffff);
- PUT16(p, s->spr - sprs);
- PUT8(p, s->f);
- PUT8(p, s->item);
- }
- disking();
- PUT16(p, doore - doors);
- for(d=doors; d<doore; d++){
- PUT16(p, d->tl - tiles);
- PUT8(p, d->isvert);
- PUT8(p, d->lock);
- PUT16(p, d->φ);
- PUT16(p, d->tc);
- PUT16(p, d->dopen);
- }
- disking();
- PUT16(p, pusher.φ);
- PUT16(p, pusher.tl - tiles);
- PUT16(p, pusher.isvert);
- PUT16(p, pusher.dopen);
- return p;
+ pack("ww", 0xffff, (int)(stce - stcs));
+ for(s=stcs; s<stce; s++)
+ pack("wwbb", s->tl != nil ? (int)(s->tl - tiles) : 0xffff,
+ (int)(s->spr - sprs), s->f, s->item);
+ pack("w", (int)(doore - doors));
+ for(d=doors; d<doore; d++)
+ pack("wbbwwW", (int)(d->tl - tiles), d->isvert, d->lock, d->φ,d->tc,
+ d->dopen);
+ pack("wwwW", pusher.φ, (int)(pusher.tl - tiles), pusher.isvert, pusher.dopen);
}
static void
@@ -927,52 +890,32 @@
sttdtinit();
}
-int
-ldmap(uchar *p, uchar **ep)
+void
+ldmap(void)
{
- int n;
+ int n, m;
Tile *tl;
Obj *o;
Static *s;
Door *d;
- disking();
nukemap();
+ for(tl=tiles; tl<tiles+nelem(tiles); tl++)
+ unpack("WWBB", &tl->p0, &tl->p1, &tl->tl, &tl->to);
+ unpack("nn", conarea, sizeof conarea, plrarea, sizeof plrarea);
disking();
- for(tl=tiles; tl<tiles+nelem(tiles); tl++){
- tl->p0 = GET16(p);
- tl->p1 = GET16(p);
- tl->tl = GET8(p);
- tl->to = GET8(p);
- }
- disking();
- memcpy(conarea, p, sizeof conarea); p+=sizeof conarea;
- memcpy(plrarea, p, sizeof plrarea); p+=sizeof plrarea;
for(o=nil;;){
- n = GET16(p);
+ unpack("w", &n);
if(n == 0xffff)
break;
o = o == nil ? oplr : onew();
o->on = n;
- o->tc = (s16int)GET16(p);
- o->type = GET16(p);
- o->s = stt + GET16(p);
- o->f = GET8(p);
- o->Δr = (s32int)GET32(p);
- o->x = GET32(p);
- o->y = GET32(p);
- o->tx = GET16(p);
- o->ty = GET16(p);
+ unpack("swwbSddwwbwwdswdsw", &o->tc, &o->type, &n, &o->f,
+ &o->Δr, &o->x, &o->y, &o->tx, &o->ty, &o->areaid,
+ &o->vwx, &o->vwdy, &o->vwdx, &o->θ, &o->hp, &o->v,
+ &o->atkdt, &o->sdt);
+ o->s = stt + n;
o->tl = tiles + o->ty * Mapdxy + o->tx;
- o->areaid = GET8(p);
- o->vwx = GET16(p);
- o->vwdy = GET16(p);
- o->vwdx = GET32(p);
- o->θ = (s16int)GET16(p);
- o->hp = GET16(p);
- o->v = GET32(p);
- o->atkdt = (s16int)GET16(p);
- o->sdt = GET16(p);
if(o != oplr && ((o->f & OFnevermark) == 0
|| (o->f & OFnomark) == 0 || o->tl->o == nil)){
o->tl->o = o;
@@ -980,39 +923,26 @@
}
}
disking();
- stce = stcs + GET16(p);
- if(stce > stcs + nelem(stcs)){
- werrstr("ldmap: static object overflow");
- return -1;
- }
+ unpack("w", &n);
+ stce = stcs + n;
+ if(stce > stcs + nelem(stcs))
+ sysfatal("ldmap: static object overflow");
for(s=stcs; s<stce; s++){
- n = GET16(p);
+ unpack("wwbb", &n, &m, &s->f, &s->item);
s->tl = n == 0xffff ? nil : tiles + n;
- s->spr = sprs + GET16(p);
- s->f = GET8(p);
- s->item = GET8(p);
+ s->spr = sprs + m;
}
- disking();
- doore = doors + GET16(p);
- if(doore > doors + nelem(doors)){
- werrstr("ldmap: door overflow");
- return -1;
- }
+ unpack("w", &n);
+ doore = doors + n;
+ if(doore > doors + nelem(doors))
+ sysfatal("ldmap: door overflow");
for(d=doors; d<doore; d++){
- d->tl = tiles + GET16(p);
- d->isvert = GET8(p);
- d->lock = GET8(p);
- d->φ = GET16(p);
- d->tc = GET16(p);
- d->dopen = GET16(p);
+ unpack("wbbwwW", &n, &d->isvert, &d->lock, &d->φ, &d->tc,
+ &d->dopen);
+ d->tl = tiles + n;
}
- disking();
- pusher.φ = GET16(p);
- pusher.tl = tiles + GET16(p);
- pusher.isvert = GET16(p);
- pusher.dopen = GET16(p);
- *ep = p;
- return 0;
+ unpack("wwwW", &pusher.φ, &n, &pusher.isvert, &pusher.dopen);
+ pusher.tl = tiles + n;
}
void