ref: f47ac12115f687ad7ec5348679fda15b4cfc4009
parent: facd1d4e9b6a5c1cd9c5faf96f7520c62746144b
author: Konstantinn Bonnet <qu7uux@gmail.com>
date: Tue Feb 28 15:15:01 EST 2017
bikeshed file i/o further - fs: add remaining stdio FILE functions using libbio - in: close iproc pipe if it was created - qk1: fatal: parse args before Host_Shutdown - style changes; use va() where appropriate - don't print lump name when using %r - misc fixes
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -4,7 +4,7 @@
#include "quakedef.h"
static void
-dmtimeend(void)
+timedm(void)
{
int f;
float t;
@@ -14,9 +14,37 @@
t = realtime - cls.td_starttime;
if(t == 0.0)
t = 1;
- Con_Printf("%d frames %5.1f seconds %5.1f fps\n", f, t, f/t);
+ Con_Printf("%d frames %5.1f seconds %5.1f fps\n", f, t, f / t);
}
+void
+abortdemo(void)
+{
+ if(!cls.demoplayback)
+ return;
+ closedm();
+ cls.demoplayback = 0;
+ cls.state = ca_disconnected;
+ if(cls.timedemo)
+ timedm();
+}
+
+void
+stopdemo(void)
+{
+ if(cmd_source != src_command)
+ return;
+ if(!cls.demorecording){
+ Con_Printf("stop: no recording in progress\n");
+ return;
+ }
+ SZ_Clear(&net_message);
+ MSG_WriteByte(&net_message, svc_disconnect);
+ writedm();
+ closedm();
+ cls.demorecording = 0;
+}
+
static int
dmmsg(void)
{
@@ -30,7 +58,7 @@
}else if(cl.time <= cl.mtime[0])
return 0;
}
- if(rlmpmsg() < 0){
+ if(readdm() < 0){
abortdemo();
return 0;
}
@@ -38,7 +66,7 @@
}
int
-clmsg(void)
+readcl(void)
{
int r;
@@ -54,36 +82,27 @@
break;
}
if(cls.demorecording)
- wlmpmsg();
+ writedm();
return r;
}
void
-abortdemo(void)
+timedemo(void)
{
- if(!cls.demoplayback)
- return;
- endlmp();
- cls.demoplayback = 0;
- cls.state = ca_disconnected;
- if(cls.timedemo)
- dmtimeend();
-}
-
-void
-stopdemo(void)
-{
if(cmd_source != src_command)
return;
- if(!cls.demorecording){
- Con_Printf("stop: no recording in progress\n");
+ if(Cmd_Argc() != 2){
+ Con_Printf("timedemo <demoname> : gets demo speeds\n");
return;
}
- SZ_Clear(&net_message);
- MSG_WriteByte(&net_message, svc_disconnect);
- wlmpmsg();
- endlmp();
- cls.demorecording = 0;
+ playdemo();
+ if(cls.demoplayback != 1)
+ return;
+ /* cls.td_starttime will be grabbed at the second frame of the demo, so
+ * all the loading time doesn't get counted */
+ cls.timedemo = 1;
+ cls.td_startframe = host_framecount;
+ cls.td_lastframe = -1; /* get a new message this frame */
}
void
@@ -90,7 +109,7 @@
recdemo(void)
{
int c, trk;
- char f[Nfspath];
+ char *s, *a;
if(cmd_source != src_command)
return;
@@ -108,12 +127,13 @@
return;
}else if(c == 4)
trk = atoi(Cmd_Argv(3));
- snprint(f, sizeof f, "%s/%s", fsdir, Cmd_Argv(1));
- ext(f, ".dem");
+ a = Cmd_Argv(1);
if(c > 2)
Cmd_ExecuteString(va("map %s", Cmd_Argv(2)), src_command);
- if(reclmp(f, trk) < 0){
- Con_Printf("recdemo: can't open %s: %r\n", f);
+ s = va("%s/%s%s", fsdir, a, ext(a, ".dem"));
+ dprint("recdemo: writing to file %s\n", s);
+ if(opendm(s, trk) < 0){
+ Con_Printf("recdemo: %r\n");
return;
}
cls.demorecording = 1;
@@ -126,7 +146,7 @@
void
playdemo(void)
{
- char f[Nfspath];
+ char *s, *a;
if(cmd_source != src_command)
return;
@@ -135,33 +155,14 @@
return;
}
CL_Disconnect();
- memset(f, 0, sizeof f);
- strncpy(f, Cmd_Argv(1), sizeof(f)-5);
- ext(f, ".dem");
- if(demolmp(f) < 0){
- Con_Printf("playdemo: can't open %s: %r\n", f);
+ a = Cmd_Argv(1);
+ s = va("%s%s", a, ext(a, ".dem"));
+ dprint("playdemo: writing to file %s\n", s);
+ if(loaddm(s) < 0){
+ Con_Printf("playdemo: %r\n");
cls.demonum = -1;
return;
}
cls.demoplayback = 1;
cls.state = ca_connected;
-}
-
-void
-timedemo(void)
-{
- if(cmd_source != src_command)
- return;
- if(Cmd_Argc() != 2){
- Con_Printf("timedemo <demoname> : gets demo speeds\n");
- return;
- }
- playdemo();
- if(cls.demoplayback != 1)
- return;
- /* cls.td_starttime will be grabbed at the second frame of the demo, so
- * all the loading time doesn't get counted */
- cls.timedemo = 1;
- cls.td_startframe = host_framecount;
- cls.td_lastframe = -1; /* get a new message this frame */
}
--- a/cl_main.c
+++ b/cl_main.c
@@ -31,7 +31,7 @@
efrag_t cl_efrags[MAX_EFRAGS];
entity_t cl_entities[MAX_EDICTS];
entity_t cl_static_entities[MAX_STATIC_ENTITIES];
-lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
+lightstyle_t cl_lightstyle[Nlights];
dlight_t cl_dlights[MAX_DLIGHTS];
int cl_numvisedicts;
@@ -599,7 +599,7 @@
do
{
- ret = clmsg ();
+ ret = readcl ();
if (ret == -1)
Host_Error ("CL_ReadFromServer: lost server connection");
if (!ret)
--- a/cl_parse.c
+++ b/cl_parse.c
@@ -146,11 +146,11 @@
do
{
- ret = clmsg ();
+ ret = readcl ();
switch (ret)
{
default:
- Host_Error ("CL_KeepaliveMessage: clmsg failed");
+ Host_Error ("CL_KeepaliveMessage: readcl failed");
case 0:
break; // nothing waiting
case 1:
@@ -783,8 +783,8 @@
case svc_lightstyle:
i = MSG_ReadByte ();
- if (i >= MAX_LIGHTSTYLES)
- fatal ("svc_lightstyle > MAX_LIGHTSTYLES");
+ if (i >= Nlights)
+ fatal ("svc_lightstyle > Nlights");
strcpy(cl_lightstyle[i].map, MSG_ReadString());
cl_lightstyle[i].length = strlen(cl_lightstyle[i].map);
break;
--- a/client.h
+++ b/client.h
@@ -242,7 +242,7 @@
extern efrag_t cl_efrags[MAX_EFRAGS];
extern entity_t cl_entities[MAX_EDICTS];
extern entity_t cl_static_entities[MAX_STATIC_ENTITIES];
-extern lightstyle_t cl_lightstyle[MAX_LIGHTSTYLES];
+extern lightstyle_t cl_lightstyle[Nlights];
extern dlight_t cl_dlights[MAX_DLIGHTS];
extern entity_t cl_temp_entities[MAX_TEMP_ENTITIES];
extern beam_t cl_beams[MAX_BEAMS];
--- a/cvar.c
+++ b/cvar.c
@@ -142,24 +142,6 @@
return true;
}
-
-/*
-============
-Cvar_WriteVariables
-
-Writes lines containing "set variable value" for all variables
-with the archive flag set to true.
-============
-*/
-void Cvar_WriteVariables (FILE *f)
-{
- cvar_t *var;
-
- for (var = cvar_vars ; var ; var = var->next)
- if (var->archive)
- fprintf (f, "%s \"%s\"\n", var->name, var->string);
-}
-
void
setcvar(char *k, char *v)
{
--- a/cvar.h
+++ b/cvar.h
@@ -61,10 +61,6 @@
// command. Returns true if the command was a variable reference that
// was handled. (print or change)
-void Cvar_WriteVariables (FILE *f);
-// Writes lines containing "set variable value" for all variables
-// with the archive flag set to true.
-
cvar_t *Cvar_FindVar (char *var_name);
extern cvar_t *cvar_vars;
--- a/dat.h
+++ b/dat.h
@@ -1,8 +1,15 @@
enum{
Npath = 64,
Nfspath = 128,
- Nmsg = 8000
+ Nmsg = 8000,
+ Nsav = 12,
+ Nsavcm = 40,
+ Nsavver = 5,
+ Nparms = 16
};
extern char fsdir[];
extern u16int crcn;
+
+extern char savs[][Nsavcm];
+extern int savcanld[];
--- a/fns.h
+++ b/fns.h
@@ -1,25 +1,28 @@
void setcvar(char*, char*);
void setcvarv(char*, float);
-int clmsg(void);
void abortdemo(void);
void stopdemo(void);
+int readcl(void);
+void timedemo(void);
void recdemo(void);
void playdemo(void);
-void timedemo(void);
-void* loadhunklmp(char *, int *);
-void* loadcachelmp(char *, cache_user_t *);
-void* loadstklmp(char *, void *, int, int *);
-void pointlmp(void);
-void endlmp(void);
-int rlmpmsg(void);
-void wlmpmsg(void);
-int reclmp(char*, int);
-int demolmp(char*);
void crc(u8int);
void initcrc(void);
-void ext(char*, char*);
+char* ext(char*, char*);
void radix(char*, char*);
-void unloadfs(void);
+void* loadhunklmp(char *, int *);
+void* loadcachelmp(char *, cache_user_t *);
+void* loadstklmp(char *, void *, int, int *);
+void loadpoints(void);
+void dumpcfg(void);
+void savnames(void);
+int dumpsav(char*, char*);
+int loadsav(char*);
+void closedm(void);
+void writedm(void);
+int readdm(void);
+int loaddm(char*);
+int opendm(char*, int);
void initfs(void);
void dprint(char*, ...);
void fatal(char*, ...);
--- a/fs.c
+++ b/fs.c
@@ -99,12 +99,11 @@
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
-static int notid1;
+static int notid1;
static int loadsize;
static uchar *loadbuf;
static cache_user_t *loadcache;
-
static Biobuf *demobf;
static vlong demoofs;
@@ -111,6 +110,54 @@
#define GBIT32(p) ((p)[0]|((p)[1]<<8)|((p)[2]<<16)|((p)[3]<<24))
#define PBIT32(p,v) (p)[0]=(v);(p)[1]=(v)>>8;(p)[2]=(v)>>16;(p)[3]=(v)>>24
+void
+crc(u8int v)
+{
+ crcn = crcn << 8 ^ crct[crcn >> 8 ^ v];
+}
+
+void
+initcrc(void)
+{
+ crcn = Ncrc0;
+}
+
+char *
+ext(char *f, char *e)
+{
+ return strrchr(f, '.') > strrchr(f, '/') ? "" : e;
+}
+
+void
+radix(char *f, char *d)
+{
+ char *s, *e;
+
+ s = strrchr(f, '/');
+ e = strrchr(f, '.');
+ if(s == nil)
+ s = f;
+ s++;
+ if(e - s < 1)
+ strcpy(d, "?model?");
+ else{
+ strncpy(d, s, e - s);
+ d[e - s] = 0;
+ }
+}
+
+static void
+path(void)
+{
+ Paklist *pl;
+
+ for(pl=pkl; pl!=nil; pl=pl->pl)
+ if(pl->p)
+ Con_Printf("%s (%zd files)\n", pl->p->f, pl->p->e - pl->p->l);
+ else
+ Con_Printf("%s\n", pl->f);
+}
+
static Biobuf *
bopen(char *f, int m, int arm)
{
@@ -225,113 +272,23 @@
d = dirfstat(Bfildes(bf));
if(d == nil)
- sysfatal("bstat: %r");
+ fatal("bstat: %r");
n = d->length;
free(d);
return n;
}
-static Pak *
-pak(char *f)
-{
- int n, ofs, len, nlmp;
- uchar u[8];
- Biobuf *bf;
- Lump *l;
- Pak *p;
-
- bf = bopen(f, OREAD, 1);
- if(bf == nil)
- return nil;
- memset(u, 0, sizeof u);
- eread(bf, u, 4);
- if(memcmp(u, "PACK", 4) != 0)
- fatal("pak %s: invalid pak file", f);
- ofs = get32(bf);
- len = get32(bf);
- nlmp = len / Npaksz;
- if(nlmp > Npaklmp)
- fatal("pak %s: invalid lump number %d", f, nlmp);
- if(nlmp != Npak0lmp)
- notid1 = 1;
- l = Hunk_AllocName(nlmp * sizeof *l, "pak");
- p = Hunk_Alloc(sizeof *p);
- strncpy(p->f, f, sizeof(p->f)-1);
- p->bf = bf;
- p->l = l;
- p->e = l + nlmp;
- Bseek(bf, ofs, 0);
- initcrc();
- while(l < p->e){
- eread(bf, l->f, 56);
- for(n=0; n<56; n++)
- crc(l->f[n]);
- eread(bf, u, 8);
- for(n=0; n<8; n++)
- crc(u[n]);
- l->ofs = GBIT32(u);
- l->len = GBIT32(u+4);
- l++;
- }
- if(crcn != Npak0crc)
- notid1 = 1;
- return p;
-}
-
static void
-pakdir(char *d)
+closelmp(Biobuf *bf)
{
- int n;
- char f[Nfspath];
Paklist *pl;
- Pak *p;
- strncpy(fsdir, d, sizeof(fsdir)-1);
- pl = Hunk_Alloc(sizeof *pl);
- strncpy(pl->f, d, sizeof(pl->f)-1);
- pl->pl = pkl;
- pkl = pl;
- for(n=0; ; n++){
- snprint(f, sizeof f, "%s/pak%d.pak", d, n);
- p = pak(f);
- if(p == nil){
- dprint("pakdir: can't open %s: %r", f);
- break;
- }
- pl = Hunk_Alloc(sizeof *pl);
- pl->p = p;
- pl->pl = pkl;
- pkl = pl;
- }
+ for(pl=pkl; pl!=nil; pl=pl->pl)
+ if(pl->p && pl->p->bf == bf)
+ return;
+ Bterm(bf);
}
-static void
-initns(void)
-{
- int i;
- char d[Nfspath], *e;
-
- memset(d, 0, sizeof d);
- i = COM_CheckParm("-basedir");
- if(i != 0 && i < com_argc - 1)
- strncpy(d, com_argv[i+1], sizeof(d)-1);
- else
- strncpy(d, host_parms.basedir, sizeof(d)-1);
- e = d + strlen(d) - 1;
- if(e > d && *e == '/')
- *e = 0;
- pakdir(va("%s%s", d, "/id1"));
- if(COM_CheckParm("-rogue"))
- pakdir(va("%s%s", d, "/rogue"));
- if(COM_CheckParm("-hipnotic"))
- pakdir(va("%s%s", d, "/hipnotic"));
- i = COM_CheckParm("-game");
- if(i != 0 && i < com_argc - 1){
- notid1 = 1;
- pakdir(va("%s/%s", d, com_argv[i+1]));
- }
-}
-
static Biobuf *
openlmp(char *f, int *len)
{
@@ -370,17 +327,6 @@
return nil;
}
-static void
-closelmp(Biobuf *bf)
-{
- Paklist *pl;
-
- for(pl=pkl; pl!=nil; pl=pl->pl)
- if(pl->p && pl->p->bf == bf)
- return;
- Bterm(bf);
-}
-
static uchar *
loadlmp(char *f, int mth, int *n)
{
@@ -411,41 +357,6 @@
return buf;
}
-static void
-path(void)
-{
- Paklist *pl;
-
- for(pl=pkl; pl!=nil; pl=pl->pl)
- if(pl->p)
- Con_Printf("%s (%zd files)\n", pl->p->f, pl->p->e - pl->p->l);
- else
- Con_Printf("%s\n", pl->f);
-}
-
-static void
-chkreg(void)
-{
- u16int *p;
- Biobuf *bf;
-
- Cvar_RegisterVariable(®istered);
- bf = openlmp("gfx/pop.lmp", nil);
- if(bf == nil){
- dprint("chkreg: shareware version");
- if(notid1)
- fatal("chkreg: phase error -- %r");
- return;
- }
- p = pop;
- while(p < pop + nelem(pop))
- if(*p++ != get16b(bf))
- fatal("chkreg: corrupted pop lump");
- closelmp(bf);
- setcvar("registered", "1");
- dprint("chkreg: registered version");
-}
-
void *
loadhunklmp(char *f, int *n)
{
@@ -469,19 +380,17 @@
}
void
-pointlmp(void)
+loadpoints(void)
{
int i, n, nv;
- char f[Nfspath];
Biobuf *bf;
vec3_t v3;
vec_t *v;
particle_t *p;
- snprint(f, sizeof f, "maps/%s.pts", sv.name);
- bf = openlmp(f, &n);
+ bf = openlmp(va("maps/%s.pts", sv.name), &n);
if(bf == nil){
- Con_Printf("pointlmp: can't open %s: %r\n", f);
+ Con_Printf("loadpoints: %r\n");
return;
}
nv = 0;
@@ -495,7 +404,7 @@
n -= 3*4+3;
nv++;
if(free_particles == nil){
- Con_Printf("pointlmp: insufficient free particles\n");
+ Con_Printf("loadpoints: insufficient free particles\n");
break;
}
p = free_particles;
@@ -509,18 +418,303 @@
VectorCopy(v3, p->org);
}
closelmp(bf);
- Con_Printf("pointlmp: %d points read\n", nv);
+ Con_Printf("loadpoints: %d points read\n", nv);
}
+static void
+dumpcvars(Biobuf *bf)
+{
+ cvar_t *c;
+
+ for(c=cvar_vars; c!=nil; c=c->next)
+ if(c->archive)
+ if(Bprint(bf, "%s \"%s\"\n", c->name, c->string) == Beof)
+ fatal("dumpcvars: %r");
+}
+
+static void
+dumpkeys(Biobuf *bf)
+{
+ char **k;
+
+ for(k=keybindings; k<keybindings+256; k++)
+ if(*k != nil && **k != 0)
+ Bprint(bf, "bind \"%s\" \"%s\"\n",
+ Key_KeynumToString(k-keybindings), *k);
+}
+
void
-endlmp(void)
+dumpcfg(void)
{
+ Biobuf *bf;
+
+ if(!host_initialized || isDedicated)
+ return;
+ bf = bopen(va("%s/config.cfg", fsdir), OWRITE, 1);
+ if(bf == nil){
+ fprint(2, "dumpcfg: %r\n");
+ return;
+ }
+ dumpkeys(bf);
+ dumpcvars(bf);
+ Bterm(bf);
+}
+
+void
+savnames(void)
+{
+ int n, *canld;
+ char (*e)[Nsavcm], (*s)[Nsavcm], *p;
+ Biobuf *bf;
+
+ s = savs;
+ canld = savcanld;
+ for(n=0, e=savs+Nsav; s<e; n++, s++, canld++){
+ *canld = 0;
+ memset(*s, 0, sizeof *s);
+ strcpy(*s, "--- UNUSED SLOT ---");
+ bf = bopen(va("%s/s%d.sav", fsdir, n), OREAD, 1);
+ if(bf == nil){
+ dprint("savnames: %r");
+ continue;
+ }
+ if((p = Brdline(bf, '\n'), p == nil) /* discard version */
+ || (p = Brdline(bf, '\n'), p == nil)){
+ dprint("savnames: short read: %r");
+ continue;
+ }
+ strncpy(*s, p, sizeof(*s)-1);
+ for(p=*s; p<*(s+1); p++)
+ if(*p == '_')
+ *p = ' ';
+ *canld = 1;
+ Bterm(bf);
+ }
+}
+
+static void
+dumpedicts(Biobuf *bf, edict_t *ed)
+{
+ int *vp, *ve;
+ char *s;
+ uchar *ev;
+ ddef_t *d, *de;
+ eval_t *v;
+
+ Bprint(bf, "{\n");
+ if(ed->free)
+ goto end;
+ ev = (uchar *)&ed->v;
+ de = pr_fielddefs + progs->numfielddefs;
+ for(d=pr_fielddefs+1; d<de; d++){
+ s = PR_Str(d->s_name);
+ if(s[strlen(s)-2] == '_')
+ continue;
+ /* TODO: pragma pack hazard */
+ vp = (int *)(ev + d->ofs * 4);
+ ve = vp + type_size[d->type & ~DEF_SAVEGLOBAL];
+ v = (eval_t *)vp;
+ for(; vp<ve; vp++)
+ if(*vp != 0)
+ break;
+ if(vp == ve)
+ continue;
+ Bprint(bf, "\"%s\" ", s);
+ Bprint(bf, "\"%s\"\n", PR_UglyValueString(d->type, v));
+ }
+end:
+ Bprint(bf, "}\n");
+}
+
+static void
+dumpdefs(Biobuf *bf)
+{
+ ushort t;
+ ddef_t *d, *de;
+
+ Bprint(bf, "{\n");
+ de = pr_globaldefs + progs->numglobaldefs;
+ for(d=pr_globaldefs; d<de; d++){
+ t = d->type;
+ if((t & DEF_SAVEGLOBAL) == 0)
+ continue;
+ t &= ~DEF_SAVEGLOBAL;
+ if(t != ev_string && t != ev_float && t != ev_entity)
+ continue;
+ Bprint(bf, "\"%s\" \"%s\"\n", PR_Str(d->s_name),
+ PR_UglyValueString(t, (eval_t *)&pr_globals[d->ofs]));
+ }
+ Bprint(bf, "}\n");
+}
+
+int
+dumpsav(char *f, char *cm)
+{
+ int i;
+ char **s, **e;
+ float *fs, *fe;
+ Biobuf *bf;
+
+ bf = bopen(f, OWRITE, 1);
+ if(bf == nil)
+ return -1;
+ Bprint(bf, "%d\n%s\n", Nsavver, cm);
+ fs = svs.clients->spawn_parms;
+ fe = fs + nelem(svs.clients->spawn_parms);
+ while(fs < fe)
+ Bprint(bf, "%f\n", *fs++);
+ Bprint(bf, "%d\n%s\n%f\n", current_skill, sv.name, sv.time);
+ s = sv.lightstyles;
+ e = s + nelem(sv.lightstyles);
+ while(s < e){
+ Bprint(bf, "%s\n", *s != nil ? *s : "m");
+ s++;
+ }
+ dumpdefs(bf);
+ for(i=0; i<sv.num_edicts; i++)
+ dumpedicts(bf, EDICT_NUM(i));
+ Bterm(bf);
+ return 0;
+}
+
+static void
+loadedicts(Biobuf *bf)
+{
+ int ent, c;
+ char sb[32768], *s;
+ edict_t *ed;
+
+ ent = -1;
+ c = 0;
+ do{
+ for(s=sb; s<sb+sizeof(sb)-1; s++){
+ c = Bgetc(bf);
+ if(c == Beof || c == 0)
+ break;
+ *s = c;
+ if(c == '}'){
+ s++;
+ break;
+ }
+ }
+ if(s == sb + sizeof(sb) - 1)
+ fatal("loadgame: buffer overflow");
+ *s = 0;
+ s = COM_Parse(sb);
+ if(com_token[0] == 0)
+ break;
+ if(strcmp(com_token, "{") != 0)
+ fatal("loadgame: missing opening brace");
+ if(ent == -1)
+ ED_ParseGlobals(s);
+ else{
+ ed = EDICT_NUM(ent);
+ /* TODO: pragma pack hazard */
+ memset(&ed->v, 0, progs->entityfields * 4);
+ ed->free = 0;
+ ED_ParseEdict(s, ed);
+ if(!ed->free)
+ SV_LinkEdict(ed, 0);
+ }
+ ent++;
+ }while(c != Beof);
+ sv.num_edicts = ent;
+}
+
+static int
+loadparms(Biobuf *bf, char *f)
+{
+ int r;
+ float sp[Nparms], *p;
+ char *s, **lp;
+
+ r = -1;
+ p = sp;
+ while(p < sp + nelem(sp)){
+ if(s = Brdline(bf, '\n'), s == nil)
+ goto exit;
+ *p++ = (float)strtod(s, nil);
+ }
+ if(s = Brdline(bf, '\n'), s == nil)
+ goto exit;
+ current_skill = (int)(strtod(s, nil) + 0.1);
+ setcvarv("skill", (float)current_skill);
+ if(s = Brdstr(bf, '\n', 1), s == nil)
+ goto exit;
+ CL_Disconnect_f();
+ SV_SpawnServer(s);
+ free(s);
+ if(!sv.active){
+ werrstr("failed to load map %s", f);
+ goto exit;
+ }
+ sv.paused = 1;
+ sv.loadgame = 1;
+ if(s = Brdline(bf, '\n'), s == nil)
+ goto exit;
+ sv.time = strtod(s, nil);
+ lp = sv.lightstyles;
+ while(lp < sv.lightstyles + nelem(sv.lightstyles)){
+ if(s = Brdstr(bf, '\n', 1), s == nil)
+ goto exit;
+ *lp = Hunk_Alloc(strlen(s)+1);
+ strcpy(*lp++, s);
+ free(s);
+ }
+ r = 0;
+ loadedicts(bf);
+ memcpy(svs.clients->spawn_parms, sp, sizeof sp);
+exit:
+ return r;
+}
+
+int
+loadsav(char *f)
+{
+ int n, r;
+ char *s;
+ Biobuf *bf;
+
+ bf = bopen(f, OREAD, 0);
+ if(bf == nil)
+ return -1;
+ r = -1;
+ if(s = Brdline(bf, '\n'), s == nil)
+ goto exit;
+ n = strtol(s, nil, 10);
+ if(n != Nsavver){
+ werrstr("invalid version %d\n", n);
+ goto exit;
+ }
+ Brdline(bf, '\n');
+ r = loadparms(bf, f);
+exit:
+ Bterm(bf);
+ return r;
+}
+
+void
+closedm(void)
+{
+ if(demobf == nil)
+ return;
closelmp(demobf);
demobf = nil;
}
+void
+writedm(void)
+{
+ int i;
+
+ put32(demobf, net_message.cursize);
+ for(i=0; i<3; i++)
+ putfl(demobf, cl.viewangles[i]);
+ ewrite(demobf, net_message.data, net_message.cursize);
+}
+
int
-rlmpmsg(void)
+readdm(void)
{
int n;
vec_t *f;
@@ -531,44 +725,21 @@
for(n=0, f=cl.mviewangles[0]; n<3; n++)
*f++ = getfl(demobf);
if(net_message.cursize > Nmsg)
- fatal("rlmpmsg: invalid message size %d\n", net_message.cursize);
+ fatal("readdm: invalid message size %d\n", net_message.cursize);
n = Bread(demobf, net_message.data, net_message.cursize);
demoofs = Bseek(demobf, 0, 1);
if(n < 0)
- dprint("rlmpmsg: bad read: %r");
+ dprint("readdm: bad read: %r");
if(n != net_message.cursize){
- dprint("rlmpmsg: short read: %r");
+ dprint("readdm: short read: %r");
n = -1;
}
return n;
}
-void
-wlmpmsg(void)
-{
- int i;
-
- put32(demobf, net_message.cursize);
- for(i=0; i<3; i++)
- putfl(demobf, cl.viewangles[i]);
- ewrite(demobf, net_message.data, net_message.cursize);
-}
-
int
-reclmp(char *f, int trk)
+loaddm(char *f)
{
- char s[16];
-
- demobf = bopen(f, OWRITE, 0);
- if(demobf == nil)
- return -1;
- sprint(s, "%d\n", trk);
- ewrite(demobf, s, strlen(s));
- return 0;
-}
-
-demolmp(char *f)
-{
int n;
char *s;
@@ -578,7 +749,7 @@
s = Brdline(demobf, '\n');
n = Blinelen(demobf) - 1;
if(s == nil || n < 0 || n > 11){
- dprint("demolmp: invalid trk field");
+ dprint("loaddm: invalid trk field");
closelmp(demobf);
return -1;
}
@@ -588,56 +759,141 @@
return 0;
}
-void
-crc(u8int v)
+int
+opendm(char *f, int trk)
{
- crcn = crcn << 8 ^ crct[crcn >> 8 ^ v];
+ char s[16];
+
+ demobf = bopen(f, OWRITE, 0);
+ if(demobf == nil)
+ return -1;
+ sprint(s, "%d\n", trk);
+ ewrite(demobf, s, strlen(s));
+ return 0;
}
-void
-initcrc(void)
+static Pak *
+pak(char *f)
{
- crcn = Ncrc0;
+ int n, ofs, len, nlmp;
+ uchar u[8];
+ Biobuf *bf;
+ Lump *l;
+ Pak *p;
+
+ bf = bopen(f, OREAD, 1);
+ if(bf == nil)
+ return nil;
+ memset(u, 0, sizeof u);
+ eread(bf, u, 4);
+ if(memcmp(u, "PACK", 4) != 0)
+ fatal("pak %s: invalid pak file", f);
+ ofs = get32(bf);
+ len = get32(bf);
+ nlmp = len / Npaksz;
+ if(nlmp > Npaklmp)
+ fatal("pak %s: invalid lump number %d", f, nlmp);
+ if(nlmp != Npak0lmp)
+ notid1 = 1;
+ l = Hunk_AllocName(nlmp * sizeof *l, "pak");
+ p = Hunk_Alloc(sizeof *p);
+ strncpy(p->f, f, sizeof(p->f)-1);
+ p->bf = bf;
+ p->l = l;
+ p->e = l + nlmp;
+ Bseek(bf, ofs, 0);
+ initcrc();
+ while(l < p->e){
+ eread(bf, l->f, 56);
+ for(n=0; n<56; n++)
+ crc(l->f[n]);
+ eread(bf, u, 8);
+ for(n=0; n<8; n++)
+ crc(u[n]);
+ l->ofs = GBIT32(u);
+ l->len = GBIT32(u+4);
+ l++;
+ }
+ if(crcn != Npak0crc)
+ notid1 = 1;
+ return p;
}
-void
-ext(char *f, char *e)
+static void
+pakdir(char *d)
{
- char *s, *d;
+ int n;
+ char f[Nfspath];
+ Paklist *pl;
+ Pak *p;
- s = strrchr(f, '/');
- d = strrchr(f, '.');
- if(d > s)
- return;
- strcat(f, e);
+ strncpy(fsdir, d, sizeof(fsdir)-1);
+ pl = Hunk_Alloc(sizeof *pl);
+ strncpy(pl->f, d, sizeof(pl->f)-1);
+ pl->pl = pkl;
+ pkl = pl;
+ for(n=0; ; n++){
+ snprint(f, sizeof f, "%s/pak%d.pak", d, n);
+ p = pak(f);
+ if(p == nil){
+ dprint("pakdir: %r");
+ break;
+ }
+ pl = Hunk_Alloc(sizeof *pl);
+ pl->p = p;
+ pl->pl = pkl;
+ pkl = pl;
+ }
}
-void
-radix(char *f, char *d)
+static void
+initns(void)
{
- char *s, *e;
+ int i;
+ char d[Nfspath], *e;
- s = strrchr(f, '/');
- e = strrchr(f, '.');
- if(s == nil)
- s = f;
- s++;
- if(e - s < 1)
- strcpy(d, "?model?");
- else{
- strncpy(d, s, e - s);
- d[e - s] = 0;
+ memset(d, 0, sizeof d);
+ i = COM_CheckParm("-basedir");
+ if(i != 0 && i < com_argc - 1)
+ strncpy(d, com_argv[i+1], sizeof(d)-1);
+ else
+ strncpy(d, host_parms.basedir, sizeof(d)-1);
+ e = d + strlen(d) - 1;
+ if(e > d && *e == '/')
+ *e = 0;
+ pakdir(va("%s%s", d, "/id1"));
+ if(COM_CheckParm("-rogue"))
+ pakdir(va("%s%s", d, "/rogue"));
+ if(COM_CheckParm("-hipnotic"))
+ pakdir(va("%s%s", d, "/hipnotic"));
+ i = COM_CheckParm("-game");
+ if(i != 0 && i < com_argc - 1){
+ notid1 = 1;
+ pakdir(va("%s/%s", d, com_argv[i+1]));
}
}
-void
-unloadfs(void)
+static void
+chkreg(void)
{
- Paklist *pl;
+ u16int *p;
+ Biobuf *bf;
- for(pl=pkl; pl!=nil; pl=pl->pl)
- if(pl->p != nil)
- Bterm(pl->p->bf);
+ Cvar_RegisterVariable(®istered);
+ bf = openlmp("gfx/pop.lmp", nil);
+ if(bf == nil){
+ dprint("chkreg: shareware version");
+ if(notid1)
+ fatal("chkreg: phase error -- %r");
+ return;
+ }
+ p = pop;
+ while(p < pop + nelem(pop))
+ if(*p++ != get16b(bf))
+ fatal("chkreg: corrupted pop lump");
+ closelmp(bf);
+ setcvar("registered", "1");
+ dprint("chkreg: registered version");
}
/* TODO: nuke these from orbit */
--- a/host.c
+++ b/host.c
@@ -207,38 +207,7 @@
host_time = 1.0; // so a think at time 0 won't get called
}
-
/*
-===============
-Host_WriteConfiguration
-
-Writes key bindings and archived cvars to config.cfg
-===============
-*/
-void Host_WriteConfiguration (void)
-{
- FILE *f;
-
-// dedicated servers initialize the host but don't parse and set the
-// config.cfg cvars
- if (host_initialized & !isDedicated)
- {
- f = fopen (va("%s/config.cfg",fsdir), "w");
- if (!f)
- {
- Con_Printf ("Couldn't write config.cfg.\n");
- return;
- }
-
- Key_WriteBindings (f);
- Cvar_WriteVariables (f);
-
- fclose (f);
- }
-}
-
-
-/*
=================
SV_ClientPrintf
@@ -781,13 +750,12 @@
// keep Con_Printf from trying to update the screen
scr_disabled_for_loading = true;
- Host_WriteConfiguration ();
+ dumpcfg();
CDAudio_Shutdown ();
NET_Shutdown ();
S_Shutdown();
IN_Shutdown ();
- unloadfs();
if (cls.state != ca_dedicated)
{
--- a/host_cmd.c
+++ b/host_cmd.c
@@ -1,14 +1,9 @@
#include <u.h>
#include <libc.h>
-#include <stdio.h>
#include "quakedef.h"
-extern cvar_t pausable;
-
int current_skill;
-void Mod_Print (void);
-
/*
==================
Host_Quit_f
@@ -327,18 +322,12 @@
SV_SpawnServer (mapname);
}
-/*
-==================
-Host_Reconnect_f
-
-This command causes the client to wait for the signon messages again.
-This is sent just before a server changes levels
-==================
-*/
-void Host_Reconnect_f (void)
+/* wait for signon messages; sent before server level change */
+static void
+reconnect(void)
{
- SCR_BeginLoadingPlaque ();
- cls.signon = 0; // need new connection messages
+ SCR_BeginLoadingPlaque();
+ cls.signon = 0;
}
/*
@@ -360,287 +349,10 @@
}
strcpy (name, Cmd_Argv(1));
CL_EstablishConnection (name);
- Host_Reconnect_f ();
+ reconnect();
}
-
/*
-===============================================================================
-
-LOAD / SAVE GAME
-
-===============================================================================
-*/
-
-#define SAVEGAME_VERSION 5
-
-/*
-===============
-Host_SavegameComment
-
-Writes a SAVEGAME_COMMENT_LENGTH character comment describing the current
-===============
-*/
-void Host_SavegameComment (char *text)
-{
- int i;
- char kills[20];
-
- for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
- text[i] = ' ';
- memcpy (text, cl.levelname, strlen(cl.levelname));
- sprint (kills,"kills:%3d/%3d", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
- memcpy (text+22, kills, strlen(kills));
-// convert space to _ to make stdio happy
- for (i=0 ; i<SAVEGAME_COMMENT_LENGTH ; i++)
- if (text[i] == ' ')
- text[i] = '_';
- text[SAVEGAME_COMMENT_LENGTH] = '\0';
-}
-
-
-/*
-===============
-Host_Savegame_f
-===============
-*/
-void Host_Savegame_f (void)
-{
- char name[256];
- FILE *f;
- int i;
- char comment[SAVEGAME_COMMENT_LENGTH+1];
-
- if (cmd_source != src_command)
- return;
-
- if (!sv.active)
- {
- Con_Printf ("Not playing a local game.\n");
- return;
- }
-
- if (cl.intermission)
- {
- Con_Printf ("Can't save in intermission.\n");
- return;
- }
-
- if (svs.maxclients != 1)
- {
- Con_Printf ("Can't save multiplayer games.\n");
- return;
- }
-
- if (Cmd_Argc() != 2)
- {
- Con_Printf ("save <savename> : save a game\n");
- return;
- }
-
- if (strstr(Cmd_Argv(1), ".."))
- {
- Con_Printf ("Relative pathnames are not allowed.\n");
- return;
- }
-
- for (i=0 ; i<svs.maxclients ; i++)
- {
- if (svs.clients[i].active && (svs.clients[i].edict->v.health <= 0) )
- {
- Con_Printf ("Can't savegame with a dead player\n");
- return;
- }
- }
-
- sprint (name, "%s/%s", fsdir, Cmd_Argv(1));
- ext(name, ".sav");
-
- Con_Printf ("Saving game to %s...\n", name);
- f = fopen (name, "w");
- if (!f)
- {
- Con_Printf ("ERROR: couldn't open.\n");
- return;
- }
-
- fprintf (f, "%d\n", SAVEGAME_VERSION);
- Host_SavegameComment (comment);
- fprintf (f, "%s\n", comment);
- for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
- fprintf (f, "%f\n", svs.clients->spawn_parms[i]);
- fprintf (f, "%d\n", current_skill);
- fprintf (f, "%s\n", sv.name);
- fprintf (f, "%f\n",sv.time);
-
-// write the light styles
-
- for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
- {
- if (sv.lightstyles[i])
- fprintf (f, "%s\n", sv.lightstyles[i]);
- else
- fprintf (f,"m\n");
- }
-
-
- ED_WriteGlobals (f);
- for (i=0 ; i<sv.num_edicts ; i++)
- {
- ED_Write (f, EDICT_NUM(i));
- fflush (f);
- }
- fclose (f);
- Con_Printf ("done.\n");
-}
-
-
-/*
-===============
-Host_Loadgame_f
-===============
-*/
-void Host_Loadgame_f (void)
-{
- char name[Nfspath];
- FILE *f;
- char mapname[Npath];
- float time, tfloat;
- char str[32768], *start;
- int i, r;
- edict_t *ent;
- int entnum;
- int version;
- float spawn_parms[NUM_SPAWN_PARMS];
-
- if (cmd_source != src_command)
- return;
-
- if (Cmd_Argc() != 2)
- {
- Con_Printf ("load <savename> : load a game\n");
- return;
- }
-
- cls.demonum = -1; // stop demo loop in case this fails
-
- sprint (name, "%s/%s", fsdir, Cmd_Argv(1));
- ext(name, ".sav");
-
-// we can't call SCR_BeginLoadingPlaque, because too much stack space has
-// been used. The menu calls it before stuffing loadgame command
-// SCR_BeginLoadingPlaque ();
-
- Con_Printf ("Loading game from %s...\n", name);
- f = fopen (name, "r");
- if (!f)
- {
- Con_Printf ("ERROR: couldn't open.\n");
- return;
- }
-
- fscanf (f, "%d\n", &version);
- if (version != SAVEGAME_VERSION)
- {
- fclose (f);
- Con_Printf ("Savegame is version %d, not %d\n", version, SAVEGAME_VERSION);
- return;
- }
- fscanf (f, "%s\n", str);
- for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
- fscanf (f, "%f\n", &spawn_parms[i]);
-// this silliness is so we can load 1.06 save files, which have float skill values
- fscanf (f, "%f\n", &tfloat);
- current_skill = (int)(tfloat + 0.1);
- setcvarv ("skill", (float)current_skill);
-
- fscanf (f, "%s\n",mapname);
- fscanf (f, "%f\n",&time);
-
- CL_Disconnect_f ();
-
- SV_SpawnServer (mapname);
- if (!sv.active)
- {
- Con_Printf ("Couldn't load map\n");
- return;
- }
- sv.paused = true; // pause until all clients connect
- sv.loadgame = true;
-
-// load the light styles
-
- for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
- {
- fscanf (f, "%s\n", str);
- sv.lightstyles[i] = Hunk_Alloc (strlen(str)+1);
- strcpy (sv.lightstyles[i], str);
- }
-
-// load the edicts out of the savegame file
- entnum = -1; // -1 is the globals
- while (!feof(f))
- {
- for (i=0 ; i<sizeof(str)-1 ; i++)
- {
- r = fgetc (f);
- if (r == EOF || !r)
- break;
- str[i] = r;
- if (r == '}')
- {
- i++;
- break;
- }
- }
- if (i == sizeof(str)-1)
- fatal ("Loadgame buffer overflow");
- str[i] = 0;
- start = COM_Parse(str);
- if (!com_token[0])
- break; // end of file
- if(strcmp(com_token, "{") != 0)
- fatal ("First token isn't a brace");
-
- if (entnum == -1)
- { // parse the global vars
- ED_ParseGlobals (start);
- }
- else
- { // parse an edict
-
- ent = EDICT_NUM(entnum);
- memset (&ent->v, 0, progs->entityfields * 4);
- ent->free = false;
- ED_ParseEdict (start, ent);
-
- // link it into the bsp tree
- if (!ent->free)
- SV_LinkEdict (ent, false);
- }
-
- entnum++;
- }
-
- sv.num_edicts = entnum;
- sv.time = time;
-
- fclose (f);
-
- for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
- svs.clients->spawn_parms[i] = spawn_parms[i];
-
- if (cls.state != ca_dedicated)
- {
- CL_EstablishConnection ("local");
- Host_Reconnect_f ();
- }
-}
-
-
-//============================================================================
-
-/*
======================
Host_Name_f
======================
@@ -1046,12 +758,11 @@
memset (&ent->v, 0, progs->entityfields * 4);
ent->v.colormap = NUM_FOR_EDICT(ent);
ent->v.team = (host_client->colors & 15) + 1;
- /* FIXME: amd64 */
ent->v.netname = host_client->name - pr_strings;
// copy spawn parms out of the client_t
- for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
+ for (i=0 ; i< Nparms ; i++)
(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
// call the spawn function
@@ -1088,7 +799,7 @@
}
// send all current light styles
- for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
+ for (i=0 ; i<Nlights ; i++)
{
MSG_WriteByte (&host_client->message, svc_lightstyle);
MSG_WriteByte (&host_client->message, (char)i);
@@ -1150,9 +861,97 @@
host_client->spawned = true;
}
-//===========================================================================
+static void
+savecomment(char *cm)
+{
+ char *s, *p, *e;
+ s = cm;
+ e = cm + Nsavcm - 1;
+ memset(s, '_', e - s);
+ p = seprint(s, e+1, "%s", cl.levelname);
+ if(p < e)
+ *p = '_';
+ while(p >= s){
+ if(*p == ' ')
+ *p = '_'; /* because scanf */
+ p--;
+ }
+ p = seprint(s+22, e+1, "kills:%3d/%3d", cl.stats[STAT_MONSTERS], cl.stats[STAT_TOTALMONSTERS]);
+ if(p < e)
+ *p = '_';
+ *e = 0;
+}
+static void
+savegame(void)
+{
+ char *s, *a, cm[Nsavcm];
+ client_t *c, *e;
+
+ if(cmd_source != src_command)
+ return;
+ else if(!sv.active){
+ Con_Printf("savegame: not a local game\n");
+ return;
+ }else if(cl.intermission){
+ Con_Printf("savegame: intermission in progress\n");
+ return;
+ }else if(svs.maxclients != 1){
+ Con_Printf("savegame: multiplayer game in progress\n");
+ return;
+ }else if(Cmd_Argc() != 2){
+ Con_Printf("save <savename> : save a game\n");
+ return;
+ }else if(strstr(Cmd_Argv(1), "..") != nil){
+ Con_Printf("savegame: invalid path\n");
+ return;
+ }
+ c = svs.clients;
+ e = c + svs.maxclients;
+ while(c < e){
+ if(c->active && c->edict->v.health <= 0){
+ Con_Printf("savegame: extant dead client\n");
+ return;
+ }
+ c++;
+ }
+ a = Cmd_Argv(1);
+ s = va("%s/%s%s", fsdir, a, ext(a, ".sav"));
+ Con_Printf("Writing game to %s\n", s);
+ savecomment(cm);
+ if(dumpsav(s, cm) < 0)
+ Con_Printf("savegame: %r\n");
+}
+
+static void
+loadgame(void)
+{
+ char *s, *a;
+
+ if(cmd_source != src_command)
+ return;
+ if(Cmd_Argc() != 2){
+ Con_Printf("load <savename> : load a game\n");
+ return;
+ }
+ cls.demonum = -1;
+ a = Cmd_Argv(1);
+ s = va("%s/%s%s", fsdir, a, ext(a, ".sav"));
+ /* Can't call SCR_BeginLoadingPlaque, because too much stack space has
+ * been used. The menu calls it before stuffing loadgame command */
+ //SCR_BeginLoadingPlaque();
+ dprint("loadgame: reading from %s", s);
+ if(loadsav(s) < 0){
+ Con_Printf("loadgame: %r\n");
+ return;
+ }
+ if(cls.state != ca_dedicated){
+ CL_EstablishConnection("local");
+ reconnect();
+ }
+}
+
/*
==================
Host_Kick_f
@@ -1626,7 +1425,7 @@
Cmd_AddCommand ("restart", Host_Restart_f);
Cmd_AddCommand ("changelevel", Host_Changelevel_f);
Cmd_AddCommand ("connect", Host_Connect_f);
- Cmd_AddCommand ("reconnect", Host_Reconnect_f);
+ Cmd_AddCommand("reconnect", reconnect);
Cmd_AddCommand ("name", Host_Name_f);
Cmd_AddCommand ("noclip", Host_Noclip_f);
Cmd_AddCommand ("version", Host_Version_f);
@@ -1644,8 +1443,8 @@
Cmd_AddCommand ("prespawn", Host_PreSpawn_f);
Cmd_AddCommand ("kick", Host_Kick_f);
Cmd_AddCommand ("ping", Host_Ping_f);
- Cmd_AddCommand ("load", Host_Loadgame_f);
- Cmd_AddCommand ("save", Host_Savegame_f);
+ Cmd_AddCommand("load", loadgame);
+ Cmd_AddCommand("save", savegame);
Cmd_AddCommand ("give", Host_Give_f);
Cmd_AddCommand ("startdemos", Host_Startdemos_f);
--- a/in.c
+++ b/in.c
@@ -309,8 +309,10 @@
{
IN_Grabm(0);
threadintgrp(THin);
- close(pfd[0]);
- close(pfd[1]);
+ if(pfd[0] > 0)
+ close(pfd[0]);
+ if(pfd[1] > 0)
+ close(pfd[1]);
if(kchan != nil){
chanfree(kchan);
kchan = nil;
--- a/keys.c
+++ b/keys.c
@@ -468,24 +468,6 @@
}
/*
-============
-Key_WriteBindings
-
-Writes lines containing "bind key value"
-============
-*/
-void Key_WriteBindings (FILE *f)
-{
- int i;
-
- for (i=0 ; i<256 ; i++)
- if (keybindings[i])
- if (*keybindings[i])
- fprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString(i), keybindings[i]);
-}
-
-
-/*
===================
Key_Init
===================
--- a/keys.h
+++ b/keys.h
@@ -107,7 +107,6 @@
void Key_Event (int key, qboolean down);
void Key_Init (void);
-void Key_WriteBindings (FILE *f);
void Key_SetBinding (int keynum, char *binding);
void Key_ClearStates (void);
--- a/menu.c
+++ b/menu.c
@@ -3,6 +3,10 @@
#include <stdio.h>
#include "quakedef.h"
+char savs[Nsav][Nsavcm];
+int savcanld[Nsav];
+
+/* FIXME: useless and redefined in vid.c? */
void (*vid_menudrawfn)(void);
void (*vid_menukeyfn)(int key);
@@ -411,46 +415,14 @@
//=============================================================================
/* LOAD/SAVE MENU */
-int load_cursor; // 0 < load_cursor < MAX_SAVEGAMES
+int load_cursor; // 0 < load_cursor < Nsav
-#define MAX_SAVEGAMES 12
-char m_filenames[MAX_SAVEGAMES][SAVEGAME_COMMENT_LENGTH+1];
-int loadable[MAX_SAVEGAMES];
-
-void M_ScanSaves (void)
-{
- int i, j;
- char name[Nfspath];
- FILE *f;
- int version;
-
- for (i=0 ; i<MAX_SAVEGAMES ; i++)
- {
- strcpy (m_filenames[i], "--- UNUSED SLOT ---");
- loadable[i] = false;
- sprint (name, "%s/s%d.sav", fsdir, i);
- f = fopen (name, "r");
- if (!f)
- continue;
- fscanf (f, "%i\n", &version);
- fscanf (f, "%79s\n", name);
- strncpy (m_filenames[i], name, sizeof(m_filenames[i])-1);
-
- // change _ back to space
- for (j=0 ; j<SAVEGAME_COMMENT_LENGTH ; j++)
- if (m_filenames[i][j] == '_')
- m_filenames[i][j] = ' ';
- loadable[i] = true;
- fclose (f);
- }
-}
-
void M_Menu_Load_f (void)
{
m_entersound = true;
m_state = m_load;
key_dest = key_menu;
- M_ScanSaves ();
+ savnames();
}
@@ -465,7 +437,7 @@
m_entersound = true;
m_state = m_save;
key_dest = key_menu;
- M_ScanSaves ();
+ savnames();
}
@@ -477,8 +449,8 @@
p = Draw_CachePic ("gfx/p_load.lmp");
M_DrawPic ( (320-p->width)/2, 4, p);
- for (i=0 ; i< MAX_SAVEGAMES; i++)
- M_Print (16, 32 + 8*i, m_filenames[i]);
+ for (i=0 ; i< Nsav; i++)
+ M_Print (16, 32 + 8*i, savs[i]);
// line cursor
M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*4)&1));
@@ -493,8 +465,8 @@
p = Draw_CachePic ("gfx/p_save.lmp");
M_DrawPic ( (320-p->width)/2, 4, p);
- for (i=0 ; i<MAX_SAVEGAMES ; i++)
- M_Print (16, 32 + 8*i, m_filenames[i]);
+ for (i=0 ; i<Nsav ; i++)
+ M_Print (16, 32 + 8*i, savs[i]);
// line cursor
M_DrawCharacter (8, 32 + load_cursor*8, 12+((int)(realtime*4)&1));
@@ -511,7 +483,7 @@
case K_ENTER:
S_LocalSound ("misc/menu2.wav");
- if (!loadable[load_cursor])
+ if (!savcanld[load_cursor])
return;
m_state = m_none;
key_dest = key_game;
@@ -529,7 +501,7 @@
S_LocalSound ("misc/menu1.wav");
load_cursor--;
if (load_cursor < 0)
- load_cursor = MAX_SAVEGAMES-1;
+ load_cursor = Nsav-1;
break;
case K_DOWNARROW:
@@ -536,7 +508,7 @@
case K_RIGHTARROW:
S_LocalSound ("misc/menu1.wav");
load_cursor++;
- if (load_cursor >= MAX_SAVEGAMES)
+ if (load_cursor >= Nsav)
load_cursor = 0;
break;
}
@@ -562,7 +534,7 @@
S_LocalSound ("misc/menu1.wav");
load_cursor--;
if (load_cursor < 0)
- load_cursor = MAX_SAVEGAMES-1;
+ load_cursor = Nsav-1;
break;
case K_DOWNARROW:
@@ -569,7 +541,7 @@
case K_RIGHTARROW:
S_LocalSound ("misc/menu1.wav");
load_cursor++;
- if (load_cursor >= MAX_SAVEGAMES)
+ if (load_cursor >= Nsav)
load_cursor = 0;
break;
}
--- a/model.c
+++ b/model.c
@@ -256,7 +256,7 @@
buf = loadstklmp(mod->name, stackbuf, sizeof stackbuf, nil);
if(buf == nil){
if(crash)
- fatal("Mod_LoadModel %s: not found: %r", mod->name);
+ fatal("Mod_LoadModel: %r");
return nil;
}
--- a/model.h
+++ b/model.h
@@ -357,3 +357,4 @@
mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
byte *Mod_LeafPVS (mleaf_t *leaf, model_t *model);
+void Mod_Print(void);
--- a/pr_cmds.c
+++ b/pr_cmds.c
@@ -1471,7 +1471,7 @@
// copy spawn parms out of the client_t
client = svs.clients + (i-1);
- for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
+ for (i=0 ; i< Nparms ; i++)
(&pr_global_struct->parm1)[i] = client->spawn_parms[i];
}
--- a/pr_edict.c
+++ b/pr_edict.c
@@ -465,53 +465,6 @@
}
}
-/*
-=============
-ED_Write
-
-For savegames
-=============
-*/
-void ED_Write (FILE *f, edict_t *ed)
-{
- ddef_t *d;
- int *v;
- int i, j;
- char *name;
- int type;
-
- fprintf (f, "{\n");
-
- if (ed->free)
- {
- fprintf (f, "}\n");
- return;
- }
-
- for (i=1 ; i<progs->numfielddefs ; i++)
- {
- d = &pr_fielddefs[i];
- name = PR_Str(d->s_name);
- if (name[strlen(name)-2] == '_')
- continue; // skip _x, _y, _z vars
-
- v = (int *)((char *)&ed->v + d->ofs*4);
-
- // if the value is still all 0, skip the field
- type = d->type & ~DEF_SAVEGLOBAL;
- for (j=0 ; j<type_size[type] ; j++)
- if (v[j])
- break;
- if (j == type_size[type])
- continue;
-
- fprintf (f,"\"%s\" ",name);
- fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
- }
-
- fprintf (f, "}\n");
-}
-
void ED_PrintNum (int ent)
{
ED_Print (EDICT_NUM(ent));
@@ -600,39 +553,6 @@
/*
=============
-ED_WriteGlobals
-=============
-*/
-void ED_WriteGlobals (FILE *f)
-{
- ddef_t *def;
- int i;
- char *name;
- int type;
-
- fprintf (f,"{\n");
- for (i=0 ; i<progs->numglobaldefs ; i++)
- {
- def = &pr_globaldefs[i];
- type = def->type;
- if ( !(def->type & DEF_SAVEGLOBAL) )
- continue;
- type &= ~DEF_SAVEGLOBAL;
-
- if (type != ev_string
- && type != ev_float
- && type != ev_entity)
- continue;
-
- name = PR_Str(def->s_name);
- fprintf (f,"\"%s\" ", name);
- fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
- }
- fprintf (f,"}\n");
-}
-
-/*
-=============
ED_ParseGlobals
=============
*/
@@ -984,7 +904,7 @@
progs = loadhunklmp("progs.dat", &n);
if(progs == nil)
- fatal("PR_LoadProgs: failed to load progs.dat: %r");
+ fatal("PR_LoadProgs: %r");
print("Programs occupy %dK.\n", n/1024);
for (i=0 ; i<n ; i++)
--- a/progs.h
+++ b/progs.h
@@ -49,6 +49,7 @@
void PR_LoadProgs (void);
char *PR_Str (int ofs);
+char *PR_UglyValueString (etype_t, eval_t *);
void PR_Profile_f (void);
@@ -59,10 +60,8 @@
// returns a copy of the string allocated from the server's string heap
void ED_Print (edict_t *ed);
-void ED_Write (FILE *f, edict_t *ed);
char *ED_ParseEdict (char *data, edict_t *ent);
-void ED_WriteGlobals (FILE *f);
void ED_ParseGlobals (char *data);
void ED_LoadFromFile (char *data);
--- a/qk1.c
+++ b/qk1.c
@@ -19,13 +19,17 @@
fprint(2, "%s\n", s);
}
+/* FIXME: merge dprint/fatal? */
void
fatal(char *fmt, ...)
{
+ char s[1024];
va_list arg;
- Host_Shutdown();
va_start(arg, fmt);
- sysfatal(fmt, arg);
+ vseprint(s, s+sizeof s, fmt, arg);
va_end(arg);
+ Host_Shutdown();
+ fprint(2, "%s: %s\n", argv0, s);
+ exits(s);
}
--- a/quakedef.h
+++ b/quakedef.h
@@ -36,12 +36,10 @@
// per-level limits
//
#define MAX_EDICTS 600 // FIXME: ouch! ouch! ouch!
-#define MAX_LIGHTSTYLES 64
+#define Nlights 64
#define MAX_MODELS 256 // these are sent over the net as bytes
#define MAX_SOUNDS 256 // so they cannot be blindly increased
-#define SAVEGAME_COMMENT_LENGTH 39
-
#define MAX_STYLESTRING 64
//
@@ -240,6 +238,7 @@
void Host_ClientCommands (char *fmt, ...);
void Host_ShutdownServer (qboolean crash);
+extern cvar_t pausable;
extern qboolean msg_suppress_1; // suppresses resolution and cache size console output
// an fullscreen DIB focus gain/loss
extern int current_skill; // skill level for currently loaded level (in case
--- a/r_light.c
+++ b/r_light.c
@@ -19,7 +19,7 @@
// light animations
// 'm' is normal light, 'a' is no light, 'z' is double bright
i = (int)(cl.time*10);
- for (j=0 ; j<MAX_LIGHTSTYLES ; j++)
+ for (j=0 ; j<Nlights ; j++)
{
if (!cl_lightstyle[j].length)
{
--- a/r_main.c
+++ b/r_main.c
@@ -171,7 +171,7 @@
R_InitTurb ();
Cmd_AddCommand ("timerefresh", R_TimeRefresh_f);
- Cmd_AddCommand("pointfile", pointlmp);
+ Cmd_AddCommand("pointfile", loadpoints);
Cvar_RegisterVariable (&r_draworder);
Cvar_RegisterVariable (&r_speeds);
--- a/server.h
+++ b/server.h
@@ -29,7 +29,7 @@
char *model_precache[MAX_MODELS]; // NULL terminated
struct model_s *models[MAX_MODELS];
char *sound_precache[MAX_SOUNDS]; // NULL terminated
- char *lightstyles[MAX_LIGHTSTYLES];
+ char *lightstyles[Nlights];
int num_edicts;
int max_edicts;
edict_t *edicts; // can NOT be array indexed, because
@@ -49,7 +49,6 @@
#define NUM_PING_TIMES 16
-#define NUM_SPAWN_PARMS 16
typedef struct client_s
{
@@ -78,7 +77,7 @@
int num_pings; // ping_times[num_pings%NUM_PING_TIMES]
// spawn parms are carried from level to level
- float spawn_parms[NUM_SPAWN_PARMS];
+ float spawn_parms[Nparms];
// client known data for deltas
int old_frags;
--- a/sv_main.c
+++ b/sv_main.c
@@ -227,7 +227,7 @@
void SV_ConnectClient (int clientnum)
{
int i, edictnum;
- float spawn_parms[NUM_SPAWN_PARMS];
+ float spawn_parms[Nparms];
edict_t *ent;
client_t *client;
struct qsocket_s *netconnection;
@@ -268,7 +268,7 @@
else{
// call the progs to get default spawn parms for the new client
PR_ExecuteProgram(pr_global_struct->SetNewParms);
- for(i=0; i<NUM_SPAWN_PARMS; i++)
+ for(i=0; i<Nparms; i++)
client->spawn_parms[i] = (&pr_global_struct->parm1)[i];
}
@@ -993,7 +993,7 @@
// call the progs to get default spawn parms for the new client
pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
PR_ExecuteProgram (pr_global_struct->SetChangeParms);
- for (j=0 ; j<NUM_SPAWN_PARMS ; j++)
+ for (j=0 ; j<Nparms ; j++)
host_client->spawn_parms[j] = (&pr_global_struct->parm1)[j];
}
}