static void SV_Fraglogfile_f (void) { dstring_t *name; if (sv_fraglogfile) { SV_Printf ("Frag file logging off.\n"); Qclose (sv_fraglogfile); sv_fraglogfile = NULL; return; } name = dstring_new (); if (!QFS_NextFilename (name, va ("%s/frag_", qfs_gamedir->dir.def), ".log")) { SV_Printf ("Can't open any logfiles.\n"); sv_fraglogfile = NULL; } else { SV_Printf ("Logging frags to %s.\n", name->str); sv_fraglogfile = QFS_WOpen (name->str, 0); } dstring_delete (name); }
void gl_Mod_MakeAliasModelDisplayLists (model_t *m, aliashdr_t *hdr, void *_m, int _s, int extra) { dstring_t *cache, *fullpath; unsigned char model_digest[MDFOUR_DIGEST_BYTES]; unsigned char mesh_digest[MDFOUR_DIGEST_BYTES]; int i, j; int *cmds; QFile *f; qboolean remesh = true; qboolean do_cache = false; aliasmodel = m; paliashdr = hdr; cache = dstring_new (); fullpath = dstring_new (); if (!gl_alias_render_tri->int_val) { if (gl_mesh_cache->int_val && gl_mesh_cache->int_val <= paliashdr->mdl.numtris) { do_cache = true; mdfour (model_digest, (unsigned char *) _m, _s); // look for a cached version dstring_copystr (cache, "glquake/"); dstring_appendstr (cache, m->name); QFS_StripExtension (m->name + strlen ("progs/"), cache->str + strlen ("glquake/")); dstring_appendstr (cache, ".qfms"); QFS_FOpenFile (cache->str, &f); if (f) { unsigned char d1[MDFOUR_DIGEST_BYTES]; unsigned char d2[MDFOUR_DIGEST_BYTES]; struct mdfour md; int len, vers; int nc = 0, no = 0; int *c = 0, *vo = 0; memset (d1, 0, sizeof (d1)); memset (d2, 0, sizeof (d2)); Qread (f, &vers, sizeof (int)); Qread (f, &len, sizeof (int)); Qread (f, &nc, sizeof (int)); Qread (f, &no, sizeof (int)); if (vers == 1 && (nc + no) == len) { c = malloc (((nc + 1023) & ~1023) * sizeof (c[0])); vo = malloc (((no + 1023) & ~1023) * sizeof (vo[0])); if (!c || !vo) Sys_Error ("gl_mesh.c: out of memory"); Qread (f, c, nc * sizeof (c[0])); Qread (f, vo, no * sizeof (vo[0])); Qread (f, d1, MDFOUR_DIGEST_BYTES); Qread (f, d2, MDFOUR_DIGEST_BYTES); Qclose (f); mdfour_begin (&md); mdfour_update (&md, (unsigned char *) &vers, sizeof(int)); mdfour_update (&md, (unsigned char *) &len, sizeof(int)); mdfour_update (&md, (unsigned char *) &nc, sizeof(int)); mdfour_update (&md, (unsigned char *) &no, sizeof(int)); mdfour_update (&md, (unsigned char *) c, nc * sizeof (c[0])); mdfour_update (&md, (unsigned char *) vo, no * sizeof (vo[0])); mdfour_update (&md, d1, MDFOUR_DIGEST_BYTES); mdfour_result (&md, mesh_digest); if (memcmp (d2, mesh_digest, MDFOUR_DIGEST_BYTES) == 0 && memcmp (d1, model_digest, MDFOUR_DIGEST_BYTES) == 0) { remesh = false; numcommands = nc; numorder = no; if (numcommands > commands_size) { if (commands) free (commands); commands_size = (numcommands + 1023) & ~1023; commands = c; } else { memcpy (commands, c, numcommands * sizeof (c[0])); free(c); } if (numorder > vertexorder_size) { if (vertexorder) free (vertexorder); vertexorder_size = (numorder + 1023) & ~1023; vertexorder = vo; } else { memcpy (vertexorder, vo, numorder * sizeof (vo[0])); free (vo); } } } } } if (remesh) { // build it from scratch Sys_MaskPrintf (SYS_DEV, "meshing %s...\n", m->name); BuildTris (); // trifans or lists if (do_cache) { // save out the cached version dsprintf (fullpath, "%s/%s", qfs_gamedir->dir.def, cache->str); f = QFS_WOpen (fullpath->str, 9); if (f) { struct mdfour md; int vers = 1; int len = numcommands + numorder; mdfour_begin (&md); mdfour_update (&md, (unsigned char *) &vers, sizeof (int)); mdfour_update (&md, (unsigned char *) &len, sizeof (int)); mdfour_update (&md, (unsigned char *) &numcommands, sizeof (int)); mdfour_update (&md, (unsigned char *) &numorder, sizeof (int)); mdfour_update (&md, (unsigned char *) commands, numcommands * sizeof (commands[0])); mdfour_update (&md, (unsigned char *) vertexorder, numorder * sizeof (vertexorder[0])); mdfour_update (&md, model_digest, MDFOUR_DIGEST_BYTES); mdfour_result (&md, mesh_digest); Qwrite (f, &vers, sizeof (int)); Qwrite (f, &len, sizeof (int)); Qwrite (f, &numcommands, sizeof (int)); Qwrite (f, &numorder, sizeof (int)); Qwrite (f, commands, numcommands * sizeof (commands[0])); Qwrite (f, vertexorder, numorder * sizeof (vertexorder[0])); Qwrite (f, model_digest, MDFOUR_DIGEST_BYTES); Qwrite (f, mesh_digest, MDFOUR_DIGEST_BYTES); Qclose (f); } } } // save the data out paliashdr->poseverts = numorder; cmds = Hunk_Alloc (numcommands * sizeof (int)); paliashdr->commands = (byte *) cmds - (byte *) paliashdr; memcpy (cmds, commands, numcommands * sizeof (int)); } else { tex_coord_t *tex_coord; numorder = 0; for (i=0; i < pheader->mdl.numtris; i++) { add_vertex(triangles[i].vertindex[0]); add_vertex(triangles[i].vertindex[1]); add_vertex(triangles[i].vertindex[2]); } paliashdr->poseverts = numorder; tex_coord = Hunk_Alloc (numorder * sizeof(tex_coord_t)); paliashdr->tex_coord = (byte *) tex_coord - (byte *) paliashdr; for (i=0; i < numorder; i++) { float s, t; int k; k = vertexorder[i]; s = stverts[k].s; t = stverts[k].t; if (!triangles[i/3].facesfront && stverts[k].onseam) s += pheader->mdl.skinwidth / 2; // on back side s = (s + 0.5) / pheader->mdl.skinwidth; t = (t + 0.5) / pheader->mdl.skinheight; tex_coord[i].st[0] = s; tex_coord[i].st[1] = t; } } if (extra) { trivertx16_t *verts; verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx16_t)); paliashdr->posedata = (byte *) verts - (byte *) paliashdr; for (i = 0; i < paliashdr->numposes; i++) { trivertx_t *pv = poseverts[i]; for (j = 0; j < numorder; j++) { trivertx16_t v; // convert MD16's split coordinates into something a little // saner. The first chunk of vertices is fully compatible with // IDPO alias models (even the scale). The second chunk is the // fractional bits of the vertex, giving 8.8. However, it's // easier for us to multiply everything by 256 and adjust the // model scale appropriately VectorMultAdd (pv[vertexorder[j] + hdr->mdl.numverts].v, 256, pv[vertexorder[j]].v, v.v); v.lightnormalindex = poseverts[i][vertexorder[j]].lightnormalindex; *verts++ = v; } } } else { trivertx_t *verts; verts = Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof (trivertx_t)); paliashdr->posedata = (byte *) verts - (byte *) paliashdr; for (i = 0; i < paliashdr->numposes; i++) { for (j = 0; j < numorder; j++) *verts++ = poseverts[i][vertexorder[j]]; } } dstring_delete (cache); dstring_delete (fullpath); }
static void Host_Savegame_f (void) { dstring_t *name; const char *save_name; char *save_text; QFile *f; int i; char *bup1, *bup2 = 0; if (cmd_source != src_command) return; if (!sv.active) { Sys_Printf ("Not playing a local game.\n"); return; } if (cl.intermission) { Sys_Printf ("Can't save in intermission.\n"); return; } if (svs.maxclients != 1) { Sys_Printf ("Can't save multiplayer games.\n"); return; } if (Cmd_Argc () != 2) { Sys_Printf ("save <savename> : save a game\n"); return; } if (strstr (Cmd_Argv (1), "..")) { Sys_Printf ("Relative pathnames are not allowed.\n"); return; } for (i = 0; i < svs.maxclients; i++) { if (svs.clients[i].active && (SVfloat (svs.clients[i].edict, health) <= 0)) { Sys_Printf ("Can't savegame with a dead player\n"); return; } } save_name = Cmd_Argv (1); name = dstring_newstr (); if (strcmp (save_name, "quick") == 0) { bup2 = nva ("%s/%s%d.sav", qfs_gamedir->dir.def, save_name, MAX_QUICK); QFS_Remove (bup2); for (i = MAX_QUICK - 1; i > 0; i--) { bup1 = nva ("%s/%s%d.sav", qfs_gamedir->dir.def, save_name, i); QFS_Rename (bup1, bup2); free (bup2); bup2 = bup1; } } dsprintf (name, "%s/%s", qfs_gamedir->dir.def, save_name); QFS_DefaultExtension (name, ".sav"); if (bup2) { QFS_Rename (name->str, bup2); free (bup2); } Sys_Printf ("Saving game to %s...\n", name->str); f = QFS_WOpen (name->str, 0); dstring_delete (name); if (!f) { Sys_Printf ("ERROR: couldn't open.\n"); return; } save_text = PL_WritePropertyList (game_dict ()); Qprintf (f, "%s\n%s", PACKAGE_NAME, save_text); free (save_text); Qclose (f); Sys_Printf ("done.\n"); }