int VCR_GetMessage (qsocket_t * sock) { int ret; long *driverdata = (long *) (char *) &sock->driverdata; if (host_time != next.time || next.op != VCR_OP_GETMESSAGE || next.session != *driverdata) Sys_Error ("VCR missmatch"); Qread (vcrFile, &ret, sizeof (int)); if (ret != 1) { VCR_ReadNext (); return ret; } Qread (vcrFile, &net_message->message->cursize, sizeof (int)); Qread (vcrFile, net_message->message->data, net_message->message->cursize); VCR_ReadNext (); return 1; }
wad_t * wad_open (const char *name) { wad_t *wad = wad_new (name); int i; if (!wad) return 0; wad->handle = Qopen (name, "rbz"); if (!wad->handle) { goto error; } if (Qread (wad->handle, &wad->header, sizeof (wad->header)) != sizeof (wad->header)) { fprintf (stderr, "%s: not a wad file\n", name); errno = 0; goto error; } if (strncmp (wad->header.id, "WAD2", 4)) { fprintf (stderr, "%s: not a wad file\n", name); errno = 0; goto error; } wad->header.infotableofs = LittleLong (wad->header.infotableofs); wad->header.numlumps = LittleLong (wad->header.numlumps); wad->numlumps = wad->header.numlumps; wad->old_numlumps = wad->lumps_size = wad->numlumps; wad->lumps = malloc (wad->lumps_size * sizeof (lumpinfo_t)); if (!wad->lumps) { //fprintf (stderr, "out of memory\n"); goto error; } Qseek (wad->handle, wad->header.infotableofs, SEEK_SET); Qread (wad->handle, wad->lumps, wad->numlumps * sizeof (wad->lumps[0])); for (i = 0; i < wad->numlumps; i++) { wad->lumps[i].filepos = LittleLong (wad->lumps[i].filepos); wad->lumps[i].size = LittleLong (wad->lumps[i].size); //Hash_AddElement (wad->lump_hash, &wad->lumps[i]); } return wad; error: wad_del (wad); return 0; }
VISIBLE void Cmd_Exec_File (cbuf_t *cbuf, const char *path, int qfs) { char *f; int len; QFile *file; if (!path || !*path) return; if (qfs) { QFS_FOpenFile (path, &file); } else { char *newpath = Sys_ExpandSquiggle (path); file = Qopen (newpath, "r"); free (newpath); } if (file) { len = Qfilesize (file); f = (char *) malloc (len + 1); if (f) { f[len] = 0; Qread (file, f, len); Cbuf_InsertText (cbuf, f); free (f); } Qclose (file); } }
void process_wad_script (const char *name) { char *buf; QFile *file; int bytes; script_t *script; file = Qopen (name, "rt"); if (!file) Sys_Error ("couldn't open %s. %s", name, strerror(errno)); bytes = Qfilesize (file); buf = malloc (bytes + 1); bytes = Qread (file, buf, bytes); buf[bytes] = 0; Qclose (file); dstring_copystr (&destfile, name); dstring_appendstr (&destfile, ".wad"); script = Script_New (); Script_Start (script, name, buf); parse_script (script); if (wadfile) wad_close (wadfile); }
static sfx_t * midi_stream_open (sfx_t *sfx) { sfxstream_t *stream = sfx->data.stream; QFile *file; midi *handle; unsigned char *local_buffer; unsigned long int local_buffer_size; midi_file_t *mf; QFS_FOpenFile (stream->file, &file); local_buffer_size = Qfilesize (file); local_buffer = malloc (local_buffer_size); Qread (file, local_buffer, local_buffer_size); Qclose (file); handle = WildMidi_OpenBuffer(local_buffer, local_buffer_size); if (handle == NULL) return NULL; mf = calloc (sizeof (midi_file_t), 1); mf->handle = handle; return SND_SFX_StreamOpen (sfx, mf, midi_stream_read, midi_stream_seek, midi_stream_close); }
int SND_LoadMidi (QFile *file, sfx_t *sfx, char *realname) { wavinfo_t info; midi *handle; unsigned char *local_buffer; unsigned long int local_buffer_size = Qfilesize (file); if (!midi_intiialized) { if (midi_init ()) { return -1; } } local_buffer = malloc (local_buffer_size); Qread (file, local_buffer, local_buffer_size); Qclose (file); // WildMidi takes ownership, so be damned if you touch it handle = WildMidi_OpenBuffer (local_buffer, local_buffer_size); if (handle == NULL) return -1; info = midi_get_info (handle); WildMidi_Close (handle); Sys_MaskPrintf (SYS_DEV, "stream %s\n", realname); // we init stream here cause we will only ever stream SND_SFX_Stream (sfx, realname, info, midi_stream_open); return 0; }
int wad_extract (wad_t *wad, lumpinfo_t *pf) { const char *name = pf->name; size_t count; int len; QFile *file; char buffer[16384]; if (make_parents (name) == -1) return -1; if (!(file = Qopen (name, "wb"))) return -1; Qseek (wad->handle, pf->filepos, SEEK_SET); len = pf->size; while (len) { count = len; if (count > sizeof (buffer)) count = sizeof (buffer); count = Qread (wad->handle, buffer, count); Qwrite (file, buffer, count); len -= count; } Qclose (file); return 0; }
static void VCR_ReadNext (void) { if (Qread (vcrFile, &next, sizeof (next)) == 0) { next.op = 255; Sys_Error ("=== END OF PLAYBACK==="); } if (next.op < 1 || next.op > VCR_MAX_MESSAGE) Sys_Error ("VCR_ReadNext: bad op"); }
int wad_add (wad_t *wad, const char *filename, const char *lumpname, byte type) { lumpinfo_t *pf; lumpinfo_t dummy; QFile *file; char buffer[16384]; int bytes; strncpy (dummy.name, lumpname, 16); dummy.name[15] = 0; pf = Hash_FindElement (wad->lump_hash, &dummy); if (pf) return -1; if (wad->numlumps == wad->lumps_size) { lumpinfo_t *f; wad->lumps_size += 64; f = realloc (wad->lumps, wad->lumps_size * sizeof (lumpinfo_t)); if (!f) return -1; wad->lumps = f; } file = Qopen (filename, "rb"); if (!file) return -1; wad->modified = 1; pf = &wad->lumps[wad->numlumps++]; strncpy (pf->name, lumpname, sizeof (pf->name)); pf->name[sizeof (pf->name) - 1] = 0; Qseek (wad->handle, 0, SEEK_END); pf->filepos = Qtell (wad->handle); pf->type = type; pf->size = 0; while ((bytes = Qread (file, buffer, sizeof (buffer)))) { Qwrite (wad->handle, buffer, bytes); pf->size += bytes; } Qclose (file); if (wad->pad && pf->size & 3) { static char buf[4]; Qwrite (wad->handle, buf, 4 - (pf->size & 3)); } Hash_AddElement (wad->lump_hash, pf); return 0; }
qboolean VCR_CanSendMessage (qsocket_t * sock) { qboolean ret; long *driverdata = (long *) (char *) &sock->driverdata; if (host_time != next.time || next.op != VCR_OP_CANSENDMESSAGE || next.session != *driverdata) Sys_Error ("VCR missmatch"); Qread (vcrFile, &ret, sizeof (int)); VCR_ReadNext (); return ret; }
/* we've opened the trackmap file from the quake resources * go through it, and make ourselves a tracklist map */ static int Load_Tracklist (void) { QFile *oggfile = NULL; char *buffile = NULL; int size; /* kill off the old tracklist, and make sure we're not playing anything */ I_OGGMus_Shutdown (); ogglistvalid = false; mus_enabled = false; if (!mus_ogglist || strequal (mus_ogglist->string, "none")) { return -1; // bail if we don't have a valid filename } oggfile = QFS_FOpenFile (mus_ogglist->string); if (!oggfile) { Sys_Printf ("Mus_OggInit: open of file \"%s\" failed\n", mus_ogglist->string); return -1; } if (!oggfile) { return -1; } /* rewind the stream */ Qseek (oggfile, 0, SEEK_SET); size = Qfilesize (oggfile); buffile = calloc (size+10, sizeof (char)); Qread (oggfile, buffile, size); tracklist = PL_GetPropertyList (buffile); if (!tracklist || PL_Type (tracklist) != QFDictionary) { Sys_Printf ("Malformed or empty tracklist file. check mus_ogglist\n"); return -1; } free (buffile); Qclose (oggfile); ogglistvalid = true; mus_enabled = true; return 0; }
int VCR_Init (void) { net_drivers[0].Init = VCR_Init; net_drivers[0].SearchForHosts = VCR_SearchForHosts; net_drivers[0].Connect = VCR_Connect; net_drivers[0].CheckNewConnections = VCR_CheckNewConnections; net_drivers[0].QGetMessage = VCR_GetMessage; net_drivers[0].QSendMessage = VCR_SendMessage; net_drivers[0].CanSendMessage = VCR_CanSendMessage; net_drivers[0].Close = VCR_Close; net_drivers[0].Shutdown = VCR_Shutdown; Qread (vcrFile, &next, sizeof (next)); return 0; }
static int load_progs (const char *name) { QFile *file; int i, size; char buff[5]; Hash_FlushTable (func_tab); file = open_file (name, &size); if (!file) { perror (name); return 0; } Qread (file, buff, 4); buff[4] = 0; Qseek (file, 0, SEEK_SET); if (!strcmp (buff, QFO)) { qfo = qfo_read (file); Qclose (file); if (!qfo) return 0; if (!need_progs) return 1; convert_qfo (); } else { pr.progs_name = name; PR_LoadProgsFile (&pr, file, size, 1, 0); Qclose (file); if (!pr.progs) return 0; PR_LoadStrings (&pr); PR_ResolveGlobals (&pr); PR_LoadDebug (&pr); } for (i = 0; i < pr.progs->numfunctions; i++) { // don't bother with builtins if (pr.pr_functions[i].first_statement > 0) Hash_AddElement (func_tab, &pr.pr_functions[i]); } return 1; }
static void * load_file (progs_t *pr, const char *name) { QFile *file; int size; char *sym; file = open_file (name, &size); if (!file) { file = open_file (va ("%s.gz", name), &size); if (!file) return 0; } sym = malloc (size + 1); sym[size] = 0; Qread (file, sym, size); return sym; }
qsocket_t * VCR_CheckNewConnections (void) { qsocket_t *sock; long *driverdata; if (host_time != next.time || next.op != VCR_OP_CONNECT) Sys_Error ("VCR missmatch"); if (!next.session) { VCR_ReadNext (); return NULL; } sock = NET_NewQSocket (); driverdata = (long *) (char *) &sock->driverdata; *driverdata = next.session; Qread (vcrFile, sock->address, NET_NAMELEN); VCR_ReadNext (); return sock; }
void LoadTriangleList (char *filename, triangle_t **pptri, int *numtriangles) { QFile *input; char name[256], tex[256]; float start, exitpattern, t; int count, iLevel, magic, i; tf_triangle tri; triangle_t *ptri; t = -FLOAT_START; *((unsigned char *) &exitpattern + 0) = *((unsigned char *) &t + 3); *((unsigned char *) &exitpattern + 1) = *((unsigned char *) &t + 2); *((unsigned char *) &exitpattern + 2) = *((unsigned char *) &t + 1); *((unsigned char *) &exitpattern + 3) = *((unsigned char *) &t + 0); if ((input = Qopen(filename, "rb")) == 0) { fprintf (stderr,"reader: could not open file '%s'\n", filename); exit (0); } iLevel = 0; Qread(input, &magic, sizeof(int)); if (BigLong (magic) != MAGIC) { fprintf (stderr,"File is not a Alias object separated triangle file, " "magic number is wrong.\n"); exit (0); } ptri = malloc (MAXTRIANGLES * sizeof (triangle_t)); *pptri = ptri; while (Qeof(input) == 0) { Qread(input, &start, sizeof (float)); start = BigFloat (start); if (start != exitpattern) { if (start == FLOAT_START) { // Start of an object or group of objects. i = -1; do { // There are probably better ways to read a string from // a file, but this does allow you to do error checking // (which I'm not doing) on a per character basis. i++; Qread(input, &(name[i]), sizeof (char)); } while (name[i] != '\0'); // indent (); // fprintf(stdout,"OBJECT START: %s\n",name); Qread (input, &count, sizeof (int)); count = BigLong (count); ++iLevel; if (count != 0) { // indent(); // fprintf (stdout, "NUMBER OF TRIANGLES: %d\n", count); i = -1; do { i++; Qread (input, &(tex[i]), sizeof (char)); } while (tex[i] != '\0'); // indent(); // fprintf(stdout," Object texture name: '%s'\n",tex); } /* Else (count == 0) this is the start of a group, and */ /* no texture name is present. */ } else if (start == FLOAT_END) { /* End of an object or group. Yes, the name should be */ /* obvious from context, but it is in here just to be */ /* safe and to provide a little extra information for */ /* those who do not wish to write a recursive reader. */ /* Mia culpa. */ iLevel--; i = -1; do { i++; Qread (input, &(name[i]), sizeof (char)); } while (name[i] != '\0'); // indent(); // fprintf(stdout,"OBJECT END: %s\n",name); continue; } } // read the triangles for (i = 0; i < count; ++i) { int j; Qread (input, &tri, sizeof (tf_triangle)); ByteSwapTri (&tri); for (j = 0; j < 3; j++) { int k; for (k = 0; k < 3; k++) { ptri->verts[j][k] = tri.pt[j].p.v[k]; } } ptri++; if ((ptri - *pptri) >= MAXTRIANGLES) Sys_Error ("Error: too many triangles; increase MAXTRIANGLES\n"); } } *numtriangles = ptri - *pptri; Qclose (input); }
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); }
int SND_Load (sfx_t *sfx) { char *realname; char buf[4]; QFile *file; sfx->touch = sfx->retain = snd_fail; sfx->release = snd_noop; sfx->close = snd_noop; sfx->open = snd_open_fail; file = QFS_FOpenFile (sfx->name); if (!file) { Sys_Printf ("Couldn't load %s\n", sfx->name); return -1; } sfx->open = snd_open; if (!strequal (qfs_foundfile.realname, sfx->name)) { realname = strdup (qfs_foundfile.realname); } else { realname = (char *) sfx->name; // won't free if realname == sfx->name } Qread (file, buf, 4); Qseek (file, 0, SEEK_SET); #ifdef HAVE_VORBIS if (strnequal ("OggS", buf, 4)) { Sys_MaskPrintf (SYS_DEV, "SND_Load: ogg file\n"); if (SND_LoadOgg (file, sfx, realname) == -1) goto bail; return 0; } #endif #ifdef HAVE_FLAC if (strnequal ("fLaC", buf, 4)) { Sys_MaskPrintf (SYS_DEV, "SND_Load: flac file\n"); if (SND_LoadFLAC (file, sfx, realname) == -1) goto bail; return 0; } #endif #ifdef HAVE_WILDMIDI if (strnequal ("MThd", buf, 4)) { Sys_MaskPrintf (SYS_DEV, "SND_Load: midi file\n"); if (SND_LoadMidi (file, sfx, realname) == -1) goto bail; return 0; } #endif if (strnequal ("RIFF", buf, 4)) { Sys_MaskPrintf (SYS_DEV, "SND_Load: wav file\n"); if (SND_LoadWav (file, sfx, realname) == -1) goto bail; return 0; } bail: Qclose (file); if (realname != sfx->name) free (realname); return -1; }
static void Host_Loadgame_f (void) { dstring_t *name = 0; QFile *f; char *mapname = 0; script_t *script = 0; plitem_t *game = 0; plitem_t *list; plitem_t *item; char *script_data = 0; int i; int entnum; int count; int version; float spawn_parms[NUM_SPAWN_PARMS]; if (cmd_source != src_command) goto end; if (Cmd_Argc () != 2) { Sys_Printf ("load <savename> : load a game\n"); goto end; } cls.demonum = -1; // stop demo loop in case this fails name = dstring_newstr (); dsprintf (name, "%s/%s", qfs_gamedir->dir.def, Cmd_Argv (1)); QFS_DefaultExtension (name, ".sav"); cl.loading = true; CL_UpdateScreen (cl.time); Sys_Printf ("Loading game from %s...\n", name->str); f = QFS_Open (name->str, "rz"); if (!f) { Sys_Printf ("ERROR: couldn't open.\n"); goto end; } script_data = malloc (Qfilesize (f) + 1); i = Qread (f, script_data, Qfilesize (f)); script_data[i] = 0; Qclose (f); script = Script_New (); script->single = ""; // disable {}()': lexing Script_Start (script, name->str, script_data); Script_GetToken (script, 1); if (strequal (script->token->str, PACKAGE_NAME)) { if (!Script_TokenAvailable (script, 1)) { Sys_Printf ("Unexpected EOF reading %s\n", name->str); goto end; } game = PL_GetPropertyList (script->p); } else { sscanf (script->token->str, "%i", &version); if (version != SAVEGAME_VERSION) { Sys_Printf ("Savegame is version %i, not %i\n", version, SAVEGAME_VERSION); goto end; } game = convert_to_game_dict (script); } item = PL_ObjectForKey (game, "spawn_parms"); for (i = 0; i < NUM_SPAWN_PARMS; i++) { if (i >= PL_A_NumObjects (item)) break; spawn_parms[i] = atof (PL_String (PL_ObjectAtIndex (item, i))); } current_skill = atoi (PL_String (PL_ObjectForKey (game, "current_skill"))); Cvar_SetValue (skill, current_skill); mapname = strdup (PL_String (PL_ObjectForKey (game, "name"))); CL_Disconnect_f (); SV_SpawnServer (mapname); if (!sv.active) { Sys_Printf ("Couldn't load map %s\n", mapname); goto end; } sv.paused = true; // pause until all clients connect sv.loadgame = true; list = PL_ObjectForKey (game, "lightstyles"); for (i = 0; i < MAX_LIGHTSTYLES; i++) { const char *style; char *str; if (i >= PL_A_NumObjects (list)) break; item = PL_ObjectAtIndex (list, i); style = PL_String (item); sv.lightstyles[i] = str = Hunk_Alloc (strlen (style) + 1); strcpy (str, style); } ED_InitGlobals (&sv_pr_state, PL_ObjectForKey (game, "globals")); list = PL_ObjectForKey (game, "entities"); entnum = 0; count = PL_A_NumObjects (list); if (count > sv.max_edicts) Host_Error ("too many entities in saved game. adjust max_edicts\n"); for (entnum = 0; entnum < count; entnum++) { plitem_t *entity = PL_ObjectAtIndex (list, entnum); edict_t *ent = EDICT_NUM (&sv_pr_state, entnum); memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4); ent->free = false; ED_InitEntity (&sv_pr_state, entity, ent); // link it into the bsp tree if (!ent->free) SV_LinkEdict (ent, false); } sv.num_edicts = entnum; sv.time = atof (PL_String (PL_ObjectForKey (game, "time"))); 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 (); } end: if (game) PL_Free (game); if (mapname) free (mapname); if (script) Script_Delete (script); if (script_data) free (script_data); if (name) dstring_delete (name); }