示例#1
0
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;
}
示例#2
0
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;
}
示例#3
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);
	}
}
示例#4
0
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);
}
示例#5
0
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);
}
示例#6
0
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;
}
示例#7
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;
}
示例#8
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");
}
示例#9
0
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;
}
示例#10
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;
}
示例#11
0
文件: cd_file.c 项目: luaman/qforge-1
/* 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;
}
示例#12
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;
}
示例#13
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;
}
示例#14
0
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;
}
示例#15
0
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;
}
示例#16
0
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);
}
示例#17
0
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);
}
示例#18
0
文件: snd_mem.c 项目: luaman/qforge-1
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;
}
示例#19
0
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);
}