示例#1
0
/*
================
FS_LoadSound

loading and unpack to wav any known sound
================
*/
wavdata_t *FS_LoadSound( const char *filename, const byte *buffer, size_t size )
{
          const char	*ext = FS_FileExtension( filename );
	string		path, loadname;
	qboolean		anyformat = true;
	int		filesize = 0;
	const loadwavfmt_t	*format;
	byte		*f;

	Sound_Reset(); // clear old sounddata
	Q_strncpy( loadname, filename, sizeof( loadname ));

	if( Q_stricmp( ext, "" ))
	{
		// we needs to compare file extension with list of supported formats
		// and be sure what is real extension, not a filename with dot
		for( format = sound.loadformats; format && format->formatstring; format++ )
		{
			if( !Q_stricmp( format->ext, ext ))
			{
				FS_StripExtension( loadname );
				anyformat = false;
				break;
			}
		}
	}

	// HACKHACK: skip any checks, load file from buffer
	if( filename[0] == '#' && buffer && size ) goto load_internal;

	// now try all the formats in the selected list
	for( format = sound.loadformats; format && format->formatstring; format++)
	{
		if( anyformat || !Q_stricmp( ext, format->ext ))
		{
			Q_sprintf( path, format->formatstring, loadname, "", format->ext );
			f = FS_LoadFile( path, &filesize, false );
			if( f && filesize > 0 )
			{
				if( format->loadfunc( path, f, filesize ))
				{
					Mem_Free(f); // release buffer
					return SoundPack(); // loaded
				}
				else Mem_Free(f); // release buffer
			}
		}
	}

load_internal:
	for( format = sound.loadformats; format && format->formatstring; format++ )
	{
		if( anyformat || !Q_stricmp( ext, format->ext ))
		{
			if( buffer && size > 0  )
			{
				if( format->loadfunc( loadname, buffer, size ))
					return SoundPack(); // loaded
			}
		}
	}

	if( !sound.loadformats || sound.loadformats->ext == NULL )
		MsgDev( D_NOTE, "FS_LoadSound: soundlib offline\n" );
	else if( filename[0] != '#' )
		MsgDev( D_WARN, "FS_LoadSound: couldn't load \"%s\"\n", loadname );

	return NULL;
}
示例#2
0
文件: cmd.c 项目: Slipyx/r1q2
/*
===============
Cmd_Exec_f
===============
*/
void Cmd_Exec_f (void)
{
	const char *path;
	char	*f, *p;
	int	len;
	char	f2[COMMAND_BUFFER_SIZE+2];

	if (Cmd_Argc () != 2)
	{
		Com_Printf ("exec <filename> : execute a config file\n", LOG_GENERAL);
		return;
	}

	path = Cmd_Argv(1);

	//r1: normalize
	while ((p = strchr (path, '\\')) != NULL)
		p[0] = '/';

	//r1: deny traversing outside the q2 directory
	p = strstr (path, "../");
	if (p)
	{
		p += 3;
		if (strstr (p, "../"))
		{
			Com_Printf ("WARNING: Illegal config path '%s'\n", LOG_GENERAL, path);
			return;
		}
	}

	//r1: sanity check length first so people don't exec pak0.pak and eat 300MB ram
	len = FS_LoadFile (path, NULL);
	if (len > COMMAND_BUFFER_SIZE - 2)
	{
		Com_Printf ("WARNING: %s exceeds maximum config file length\n", LOG_GENERAL, Cmd_Argv(1));
		len = COMMAND_BUFFER_SIZE - 2;
	}

	len = FS_LoadFile (path, (void **)&f);
	if (!f || len <= 0)
	{
		//ugly hack to avoid printing missing config errors before startup finishes
		if (q2_initialized)
			Com_Printf ("couldn't exec %s\n", LOG_GENERAL, path);
		return;
	}

#ifndef DEDICATED_ONLY
	if (Com_ServerState())
#endif
		Com_Printf ("execing %s\n", LOG_GENERAL, path);
#ifndef DEDICATED_ONLY
	else
		Com_DPrintf ("execing %s\n",path);
#endif

	// the file doesn't have a trailing 0, so we need to copy it off
	//f2 = Z_TagMalloc(len+2, TAGMALLOC_CMDBUFF);
	//f2 = alloca (len+2);
	memcpy (f2, f, len);

	//r1: fix for "no trailing newline = 'u or s'" bug.
	f2[len] = '\n';
	f2[len+1] = 0;

	if ((p = strchr(f2, '\r')) != NULL && *(p+1) != '\n')
		Com_Printf ("WARNING: Raw \\r found in config file %s\n", LOG_GENERAL|LOG_WARNING, path);

	Cbuf_InsertText (f2);

	//Z_Free (f2);
	FS_FreeFile (f);
}
示例#3
0
/*
====================
Curl_FindPackURL

finds the URL where to find a given package.

For this, it reads a file "curl_urls.txt" of the following format:

	data*.pk3	-
	revdm*.pk3	http://revdm/downloads/are/here/
	*			http://any/other/stuff/is/here/

The URLs should end in /. If not, downloads will still work, but the cached files
can't be just put into the data directory with the same download configuration
(you might want to do this if you want to tag downloaded files from your
server, but you should not). "-" means "don't download".

If no single pattern matched, the cvar sv_curl_defaulturl is used as download
location instead.

Note: pak1.pak and data*.pk3 are excluded from autodownload at another point in
this file for obvious reasons.
====================
*/
static const char *Curl_FindPackURL(const char *filename)
{
	static char foundurl[1024];
	fs_offset_t filesize;
	char *buf = (char *) FS_LoadFile("curl_urls.txt", tempmempool, true, &filesize);
	if(buf && filesize)
	{
		// read lines of format "pattern url"
		char *p = buf;
		char *pattern = NULL, *patternend = NULL, *url = NULL, *urlend = NULL;
		qboolean eof = false;

		pattern = p;
		while(!eof)
		{
			switch(*p)
			{
				case 0:
					eof = true;
					// fallthrough
				case '\n':
				case '\r':
					if(pattern && url && patternend)
					{
						if(!urlend)
							urlend = p;
						*patternend = 0;
						*urlend = 0;
						if(matchpattern(filename, pattern, true))
						{
							strlcpy(foundurl, url, sizeof(foundurl));
							Z_Free(buf);
							return foundurl;
						}
					}
					pattern = NULL;
					patternend = NULL;
					url = NULL;
					urlend = NULL;
					break;
				case ' ':
				case '\t':
					if(pattern && !patternend)
						patternend = p;
					else if(url && !urlend)
						urlend = p;
					break;
				default:
					if(!pattern)
						pattern = p;
					else if(pattern && patternend && !url)
						url = p;
					break;
			}
			++p;
		}
	}
	if(buf)
		Z_Free(buf);
	return sv_curl_defaulturl.string;
}
示例#4
0
文件: ogg.c 项目: tomgreen66/yquake2
/*
 * Play Ogg Vorbis file (with absolute or relative index).
 */
qboolean
OGG_Open(ogg_seek_t type, int offset)
{
	int size;     /* File size. */
	int pos = -1; /* Absolute position. */
	int res;      /* Error indicator. */

	switch (type)
	{
		case ABS:

			/* Absolute index. */
			if ((offset < 0) || (offset >= ogg_numfiles))
			{
				Com_Printf("OGG_Open: %d out of range.\n", offset + 1);
				return false;
			}
			else
			{
				pos = offset;
			}

			break;
		case REL:

			/* Simulate a loopback. */
			if ((ogg_curfile == -1) && (offset < 0))
			{
				offset++;
			}

			while (ogg_curfile + offset < 0)
			{
				offset += ogg_numfiles;
			}

			while (ogg_curfile + offset >= ogg_numfiles)
			{
				offset -= ogg_numfiles;
			}

			pos = ogg_curfile + offset;
			break;
	}

	/* Check running music. */
	if (ogg_status == PLAY)
	{
		if (ogg_curfile == pos)
		{
			return true;
		}

		else
		{
			OGG_Stop();
		}
	}

	/* Find file. */
	if ((size = FS_LoadFile(ogg_filelist[pos], (void **)&ogg_buffer)) == -1)
	{
		Com_Printf("OGG_Open: could not open %d (%s): %s.\n",
				pos, ogg_filelist[pos], strerror(errno));
		return false;
	}

	/* Open ogg vorbis file. */
	if ((res = ov_open(NULL, &ovFile, (char *)ogg_buffer, size)) < 0)
	{
		Com_Printf("OGG_Open: '%s' is not a valid Ogg Vorbis file (error %i).\n",
				ogg_filelist[pos], res); FS_FreeFile(ogg_buffer);
		ogg_buffer = NULL;
		return false;
	}

	ogg_info = ov_info(&ovFile, 0);

	if (!ogg_info)
	{
		Com_Printf("OGG_Open: Unable to get stream information for %s.\n",
				ogg_filelist[pos]);
		ov_clear(&ovFile);
		FS_FreeFile(ogg_buffer);
		ogg_buffer = NULL;
		return false;
	}

	/* Play file. */
	ovSection = 0;
	ogg_curfile = pos;
	ogg_status = PLAY;

	return true;
}
示例#5
0
static void ParseMasterArgs(netadr_t *broadcast)
{
    void *data;
    int len;
    void (*parse)(void *, size_t, size_t);
    size_t chunk;
    char *s, *p;
    int i, argc;

    Cmd_TokenizeString(m_servers.args, false);

    argc = Cmd_Argc();
    if (!argc) {
        // default action to take when no URLs are given
        ParseAddressBook();
        broadcast->type = NA_BROADCAST;
        broadcast->port = BigShort(PORT_SERVER);
        return;
    }

    for (i = 0; i < argc; i++) {
        s = Cmd_Argv(i);
        if (!*s)
            continue;

        // parse binary format specifier
        parse = ParsePlain;
        chunk = 0;
        if (*s == '+' || *s == '-') {
            parse = ParseBinary;
            chunk = strtoul(s, &p, 10);
            if (s == p) {
                chunk = 6;
                s = p + 1;
            } else {
                if (chunk < 6)
                    goto ignore;
                s = p;
            }
        }

        if (!strncmp(s, "file://", 7)) {
            len = FS_LoadFile(s + 7, &data);
            if (len < 0)
                continue;
            (*parse)(data, len, chunk);
            FS_FreeFile(data);
            continue;
        }

        if (!strncmp(s, "http://", 7)) {
#if USE_CURL
            len = HTTP_FetchFile(s + 7, &data);
            if (len < 0)
                continue;
            (*parse)(data, len, chunk);
            Z_Free(data);
#else
            Com_Printf("Can't fetch '%s', no HTTP support compiled in.\n", s);
#endif
            continue;
        }

        if (!strncmp(s, "favorites://", 12)) {
            ParseAddressBook();
            continue;
        }

        if (!strncmp(s, "broadcast://", 12)) {
            broadcast->type = NA_BROADCAST;
            broadcast->port = BigShort(PORT_SERVER);
            continue;
        }

        if (!strncmp(s, "quake2://", 9)) {
            AddServer(NULL, s + 9);
            continue;
        }

ignore:
        Com_Printf("Ignoring invalid master URL: %s\n", s);
    }
}
示例#6
0
/*
=====================================
Cmd_GetMapList

Prints or complete map filename
=====================================
*/
qboolean Cmd_GetMapList( const char *s, char *completedname, int length )
{
	search_t		*t;
	file_t		*f;
	string		message;
	string		matchbuf;
	byte		buf[MAX_SYSPATH]; // 1 kb
	int		i, nummaps;

	t = FS_Search( va( "maps/%s*.bsp", s ), true, con_gamemaps->integer );
	if( !t ) return false;

	FS_FileBase( t->filenames[0], matchbuf ); 
	Q_strncpy( completedname, matchbuf, length );
	if( t->numfilenames == 1 ) return true;

	for( i = 0, nummaps = 0; i < t->numfilenames; i++ )
	{
		char		entfilename[CS_SIZE];
		int		ver = -1, mapver = -1, lumpofs = 0, lumplen = 0;
		const char	*ext = FS_FileExtension( t->filenames[i] ); 
		char		*ents = NULL, *pfile;
		qboolean		paranoia = false;
		qboolean		gearbox = false;
			
		if( Q_stricmp( ext, "bsp" )) continue;
		Q_strncpy( message, "^1error^7", sizeof( message ));
		f = FS_Open( t->filenames[i], "rb", con_gamemaps->integer );
	
		if( f )
		{
			dheader_t	*header;
			dextrahdr_t	*hdrext;

			Q_memset( buf, 0, sizeof( buf ));
			FS_Read( f, buf, sizeof( buf ));
			header = (dheader_t *)buf;
			ver = header->version;
                              
			switch( ver )
			{
			case Q1BSP_VERSION:
			case HLBSP_VERSION:
			case XTBSP_VERSION:
				if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 && !(header->lumps[LUMP_ENTITIES].filelen % sizeof(dplane_t)))
				{
					lumpofs = header->lumps[LUMP_PLANES].fileofs;
					lumplen = header->lumps[LUMP_PLANES].filelen;
					gearbox = true;
				}
				else
				{
					lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
					lumplen = header->lumps[LUMP_ENTITIES].filelen;
					gearbox = false;
				}
				break;
			}

			if( ver == XTBSP_VERSION )
				hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader31_t ));
			else hdrext = (dextrahdr_t *)((byte *)buf + sizeof( dheader_t ));

			if( hdrext->id == IDEXTRAHEADER && hdrext->version == EXTRA_VERSION )
				paranoia = true;

			Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
			FS_StripExtension( entfilename );
			FS_DefaultExtension( entfilename, ".ent" );
			ents = FS_LoadFile( entfilename, NULL, true );

			if( !ents && lumplen >= 10 )
			{
				FS_Seek( f, lumpofs, SEEK_SET );
				ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
				FS_Read( f, ents, lumplen );
			}

			if( ents )
			{
				// if there are entities to parse, a missing message key just
				// means there is no title, so clear the message string now
				char	token[2048];

				message[0] = 0;
				pfile = ents;

				while(( pfile = COM_ParseFile( pfile, token )) != NULL )
				{
					if( !Q_strcmp( token, "{" )) continue;
					else if(!Q_strcmp( token, "}" )) break;
					else if(!Q_strcmp( token, "message" ))
					{
						// get the message contents
						pfile = COM_ParseFile( pfile, message );
					}
					else if(!Q_strcmp( token, "mapversion" ))
					{
						// get the message contents
						pfile = COM_ParseFile( pfile, token );
						mapver = Q_atoi( token );
					}
				}
				Mem_Free( ents );
			}
		}

		if( f ) FS_Close(f);
		FS_FileBase( t->filenames[i], matchbuf );

		switch( ver )
		{
		case Q1BSP_VERSION:
			if( mapver == 220 ) Q_strncpy( buf, "Half-Life Alpha", sizeof( buf ));
			else Q_strncpy( buf, "Quake", sizeof( buf ));
			break;
		case HLBSP_VERSION:
			if( gearbox ) Q_strncpy( buf, "Blue-Shift", sizeof( buf ));
			else if( paranoia ) Q_strncpy( buf, "Paranoia 2", sizeof( buf ));
			else Q_strncpy( buf, "Half-Life", sizeof( buf ));
			break;
		case XTBSP_VERSION:
			if( paranoia ) Q_strncpy( buf, "Paranoia 2", sizeof( buf ));
			else Q_strncpy( buf, "Xash3D", sizeof( buf ));
			break;
		default:
			Q_strncpy( buf, "??", sizeof( buf ));
			break;
		}

		Msg( "%16s (%s) ^3%s^7\n", matchbuf, buf, message );
		nummaps++;
	}

	Msg( "\n^3 %i maps found.\n", nummaps );
	Mem_Free( t );

	// cut shortestMatch to the amount common with s
	for( i = 0; matchbuf[i]; i++ )
	{
		if( Q_tolower( completedname[i] ) != Q_tolower( matchbuf[i] ))
			completedname[i] = 0;
	}
	return true;
}
示例#7
0
/*
==============
SCR_LoadPCX
==============
*/
void SCR_LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
{
	byte	*raw;
	pcx_t	*pcx;
	int		x, y;
	int		len;
	int		dataByte, runLength;
	byte	*out, *pix;

	*pic = NULL;

	//
	// load the file
	//
	len = FS_LoadFile (filename, (void **)&raw);
	if (!raw)
		return;	// Com_Printf ("Bad pcx file %s.\n", filename);

	//
	// parse the PCX file
	//
	pcx = (pcx_t *)raw;
	raw = &pcx->data;

	if (pcx->manufacturer != 0x0a
		|| pcx->version != 5
		|| pcx->encoding != 1
		|| pcx->bits_per_pixel != 8
		|| pcx->xmax >= 640
		|| pcx->ymax >= 480)
	{
		Com_Printf ("Bad pcx file %s.\n", filename);
		return;
	}

	out = Z_Malloc ( (pcx->ymax+1) * (pcx->xmax+1) );

	*pic = out;

	pix = out;

	if (palette)
	{
		*palette = Z_Malloc(768);
		memcpy (*palette, (byte *)pcx + len - 768, 768);
	}

	if (width)
		*width = pcx->xmax+1;
	if (height)
		*height = pcx->ymax+1;

	for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
	{
		for (x=0 ; x<=pcx->xmax ; )
		{
			dataByte = *raw++;

			if ((dataByte & 0xC0) == 0xC0)
			{
				runLength = dataByte & 0x3F;
				dataByte = *raw++;
			}
			else
				runLength = 1;

			while(runLength-- > 0)
				pix[x++] = dataByte;
		}

	}

	if ( raw - (byte *)pcx > len)
	{
		Com_Printf ("PCX file %s was malformed.", filename);
		Z_Free (*pic);
		*pic = NULL;
	}

	FS_FreeFile (pcx);
}
示例#8
0
static void Palette_Load(void)
{
	int i;
	unsigned char *out;
	float gamma, scale, base;
	fs_offset_t filesize;
	unsigned char *palfile;
	unsigned char texturegammaramp[256];
	union
	{
		unsigned char b[4];
		unsigned int i;
	}
	bgra;

	gamma = 1;
	scale = 1;
	base = 0;
// COMMANDLINEOPTION: Client: -texgamma <number> sets the quake palette gamma, allowing you to make quake textures brighter/darker, not recommended
	i = COM_CheckParm("-texgamma");
	if (i)
		gamma = atof(com_argv[i + 1]);
// COMMANDLINEOPTION: Client: -texcontrast <number> sets the quake palette contrast, allowing you to make quake textures brighter/darker, not recommended
	i = COM_CheckParm("-texcontrast");
	if (i)
		scale = atof(com_argv[i + 1]);
// COMMANDLINEOPTION: Client: -texbrightness <number> sets the quake palette brightness (brightness of black), allowing you to make quake textures brighter/darker, not recommended
	i = COM_CheckParm("-texbrightness");
	if (i)
		base = atof(com_argv[i + 1]);
	gamma = bound(0.01, gamma, 10.0);
	scale = bound(0.01, scale, 10.0);
	base = bound(0, base, 0.95);

	BuildGammaTable8(1.0f, gamma, scale, base, 1, texturegammaramp, 256);

	palfile = (unsigned char *)FS_LoadFile ("gfx/palette.lmp", tempmempool, false, &filesize);
	if (palfile && filesize >= 768)
		memcpy(palette_rgb, palfile, 768);
	else
	{
		Con_DPrint("Couldn't load gfx/palette.lmp, falling back on internal palette\n");
		memcpy(palette_rgb, host_quakepal, 768);
	}
	if (palfile)
		Mem_Free(palfile);

	out = (unsigned char *) palette_bgra_complete; // palette is accessed as 32bit for speed reasons, but is created as 8bit bytes
	for (i = 0;i < 256;i++)
	{
		out[i*4+2] = texturegammaramp[palette_rgb[i][0]];
		out[i*4+1] = texturegammaramp[palette_rgb[i][1]];
		out[i*4+0] = texturegammaramp[palette_rgb[i][2]];
		out[i*4+3] = 255;
	}

	if(*r_colormap_palette.string)
		palfile = (unsigned char *)FS_LoadFile (r_colormap_palette.string, tempmempool, false, &filesize);
	else
		palfile = NULL;

	if (palfile && filesize >= 48*2)
	{
		memcpy(palette_rgb_shirtcolormap[0], palfile, 48);
		memcpy(palette_rgb_shirtscoreboard[0], palfile + 48, 48);
	}
	else
	{
		for(i = 0;i < 16;i++)
		{
			VectorCopy(palette_rgb[(i << 4) | ((i >= 8 && i <= 13) ? 0x04 : 0x0C)], palette_rgb_shirtcolormap[i]);
			VectorCopy(palette_rgb[(i << 4) | 0x08], palette_rgb_shirtscoreboard[i]);
		}
	}

	if (palfile && filesize >= 48*4)
	{
		memcpy(palette_rgb_pantscolormap[0], palfile + 48*2, 48);
		memcpy(palette_rgb_pantsscoreboard[0], palfile + 48*3, 48);
	}
	else
	{
		memcpy(palette_rgb_pantscolormap, palette_rgb_shirtcolormap, sizeof(palette_rgb_pantscolormap));
		memcpy(palette_rgb_pantsscoreboard, palette_rgb_shirtscoreboard, sizeof(palette_rgb_pantsscoreboard));
	}

	if(palfile)
		Mem_Free(palfile);

	memset(palette_bgra_embeddedpic, 0, sizeof(palette_bgra_embeddedpic));
	for (i = '1';i <= '7';i++)
	{
		Vector4Set(bgra.b, 255, 255, 255, (i - '0') * 255 / 7);
		palette_bgra_embeddedpic[i] = bgra.i;
	}

	Palette_SetupSpecialPalettes();

	Palette_LoadQ2Colormap();
}
示例#9
0
static void Palette_SetupSpecialPalettes(void)
{
	int i;
	int fullbright_start, fullbright_end;
	int pants_start, pants_end;
	int shirt_start, shirt_end;
	int reversed_start, reversed_end;
	int transparentcolor;
	unsigned char *colormap;
	fs_offset_t filesize;
	union
	{
		int i;
		unsigned char b[4];
	}
	u;

	colormap = FS_LoadFile("gfx/colormap.lmp", tempmempool, true, &filesize);
	if (colormap && filesize >= 16385)
		fullbright_start = 256 - colormap[16384];
	else
		fullbright_start = 256;
	if (colormap)
		Mem_Free(colormap);
	fullbright_end = 256;
	pants_start = 96;
	pants_end = 112;
	shirt_start = 16;
	shirt_end = 32;
	reversed_start = 128;
	reversed_end = 224;
	transparentcolor = 255;

	for (i = 0;i < 256;i++)
		palette_featureflags[i] = PALETTEFEATURE_STANDARD;
	for (i = reversed_start;i < reversed_end;i++)
		palette_featureflags[i] = PALETTEFEATURE_REVERSED;
	for (i = pants_start;i < pants_end;i++)
		palette_featureflags[i] = PALETTEFEATURE_PANTS;
	for (i = shirt_start;i < shirt_end;i++)
		palette_featureflags[i] = PALETTEFEATURE_SHIRT;
	for (i = fullbright_start;i < fullbright_end;i++)
		palette_featureflags[i] = PALETTEFEATURE_GLOW;
	palette_featureflags[0] = PALETTEFEATURE_ZERO;
	palette_featureflags[transparentcolor] = PALETTEFEATURE_TRANSPARENT;

	for (i = 0;i < 256;i++)
		palette_bgra_transparent[i] = palette_bgra_complete[i];
	palette_bgra_transparent[transparentcolor] = 0;

	for (i = 0;i < fullbright_start;i++)
		palette_bgra_nofullbrights[i] = palette_bgra_complete[i];
	for (i = fullbright_start;i < fullbright_end;i++)
		palette_bgra_nofullbrights[i] = palette_bgra_complete[0];

	for (i = 0;i < 256;i++)
		palette_bgra_onlyfullbrights[i] = 0;
	for (i = fullbright_start;i < fullbright_end;i++)
		palette_bgra_onlyfullbrights[i] = palette_bgra_complete[i];

	for (i = 0;i < 256;i++)
		palette_bgra_nocolormapnofullbrights[i] = palette_bgra_complete[i];
	for (i = pants_start;i < pants_end;i++)
		palette_bgra_nocolormapnofullbrights[i] = 0;
	for (i = shirt_start;i < shirt_end;i++)
		palette_bgra_nocolormapnofullbrights[i] = 0;
	for (i = fullbright_start;i < fullbright_end;i++)
		palette_bgra_nocolormapnofullbrights[i] = 0;

	for (i = 0;i < 256;i++)
		palette_bgra_nocolormap[i] = palette_bgra_complete[i];
	for (i = pants_start;i < pants_end;i++)
		palette_bgra_nocolormap[i] = 0;
	for (i = shirt_start;i < shirt_end;i++)
		palette_bgra_nocolormap[i] = 0;

	for (i = 0;i < 256;i++)
		palette_bgra_pantsaswhite[i] = 0;
	for (i = pants_start;i < pants_end;i++)
	{
		if (i >= reversed_start && i < reversed_end)
			palette_bgra_pantsaswhite[i] = palette_bgra_complete[15 - (i - pants_start)];
		else
			palette_bgra_pantsaswhite[i] = palette_bgra_complete[i - pants_start];
	}

	for (i = 0;i < 256;i++)
		palette_bgra_shirtaswhite[i] = 0;
	for (i = shirt_start;i < shirt_end;i++)
	{
		if (i >= reversed_start && i < reversed_end)
			palette_bgra_shirtaswhite[i] = palette_bgra_complete[15 - (i - shirt_start)];
		else
			palette_bgra_shirtaswhite[i] = palette_bgra_complete[i - shirt_start];
	}

	for (i = 0;i < 256;i++)
		palette_bgra_alpha[i] = 0xFFFFFFFF;
	u.i = 0xFFFFFFFF;
	u.b[3] = 0;
	palette_bgra_alpha[transparentcolor] = u.i;

	for (i = 0;i < 256;i++)
		palette_bgra_font[i] = palette_bgra_complete[i];
	palette_bgra_font[0] = 0;
}
示例#10
0
/**
 * @brief Load material definitions for each map that has one
 * @param[in] map the base name of the map to load the material for
 */
void R_LoadMaterials (const char *map)
{
	char path[MAX_QPATH];
	byte *fileBuffer;
	const char *buffer;
	bool inmaterial;
	image_t *image;
	material_t *m;
	materialStage_t *ss;

	/* clear previously loaded materials */
	R_ImageClearMaterials();

	if (map[0] == '+' || map[0] == '-')
		map++;
	else if (map[0] == '-')
		return;

	/* load the materials file for parsing */
	Com_sprintf(path, sizeof(path), "materials/%s.mat", Com_SkipPath(map));

	if (FS_LoadFile(path, &fileBuffer) < 1) {
		Com_DPrintf(DEBUG_RENDERER, "Couldn't load %s\n", path);
		return;
	} else {
		Com_Printf("load material file: '%s'\n", path);
		if (!r_materials->integer)
			Com_Printf("...ignore materials (r_materials is deactivated)\n");
	}

	buffer = (const char *)fileBuffer;

	inmaterial = false;
	image = nullptr;
	m = nullptr;

	while (true) {
		const char *c = Com_Parse(&buffer);

		if (c[0] == '\0')
			break;

		if (*c == '{' && !inmaterial) {
			inmaterial = true;
			continue;
		}

		if (Q_streq(c, "material")) {
			c = Com_Parse(&buffer);
			image = R_GetImage(va("textures/%s", c));
			if (image == nullptr)
				Com_DPrintf(DEBUG_RENDERER, "R_LoadMaterials: skip texture: %s - not used in the map\n", c);

			continue;
		}

		if (!image)
			continue;

		m = &image->material;

		if (Q_streq(c, "normalmap")){
			c = Com_Parse(&buffer);
			image->normalmap = R_FindImage(va("textures/%s", c), it_normalmap);

			if (image->normalmap == r_noTexture){
				Com_Printf("R_LoadMaterials: Failed to resolve normalmap: %s\n", c);
				image->normalmap = nullptr;
			}
		}

		if (Q_streq(c, "glowmap")){
			c = Com_Parse(&buffer);
			image->glowmap = R_FindImage(va("textures/%s", c), it_glowmap);

			if (image->glowmap == r_noTexture){
				Com_Printf("R_LoadMaterials: Failed to resolve glowmap: %s\n", c);
				image->glowmap = nullptr;
			}
		}

		if (Q_streq(c, "bump")) {
			m->bump = atof(Com_Parse(&buffer));
			if (m->bump < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid bump value for %s\n", image->name);
				m->bump = defaultMaterial.bump;
			}
		}

		if (Q_streq(c, "parallax")) {
			m->parallax = atof(Com_Parse(&buffer));
			if (m->parallax < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid parallax value for %s\n", image->name);
				m->parallax = defaultMaterial.parallax;
			}
		}

		if (Q_streq(c, "hardness")) {
			m->hardness = atof(Com_Parse(&buffer));
			if (m->hardness < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid hardness value for %s\n", image->name);
				m->hardness = defaultMaterial.hardness;
			}
		}

		if (Q_streq(c, "specular")) {
			m->specular = atof(Com_Parse(&buffer));
			if (m->specular < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid specular value for %s\n", image->name);
				m->specular = defaultMaterial.specular;
			}
		}

		if (Q_streq(c, "glowscale")) {
			m->glowscale = atof(Com_Parse(&buffer));
			if (m->glowscale < 0.0) {
				Com_Printf("R_LoadMaterials: Invalid glowscale value for %s\n", image->name);
				m->glowscale = defaultMaterial.glowscale;
			}
		}

		if (*c == '{' && inmaterial) {
			materialStage_t* const s = Mem_PoolAllocType(materialStage_t, vid_imagePool);
			s->glowscale = defaultMaterial.glowscale;

			if (R_ParseStage(s, &buffer) == -1) {
				Mem_Free(s);
				continue;
			}

			/* load animation frame images */
			if (s->flags & STAGE_ANIM) {
				if (R_LoadAnimImages(s) == -1) {
					Mem_Free(s);
					continue;
				}
			}

			/* append the stage to the chain */
			if (!m->stages)
				m->stages = s;
			else {
				ss = m->stages;
				while (ss->next)
					ss = ss->next;
				ss->next = s;
			}

			m->flags |= s->flags;
			m->num_stages++;
			continue;
		}

		if (*c == '}' && inmaterial) {
			Com_DPrintf(DEBUG_RENDERER, "Parsed material %s with %d stages\n", image->name, m->num_stages);
			inmaterial = false;
			image = nullptr;
			/* multiply stage glowscale values by material glowscale */
			ss = m->stages;
			while (ss) {
				ss->glowscale *= m->glowscale;
				ss = ss->next;
			}
		}
	}

	FS_FreeFile(fileBuffer);

	R_CreateMaterialData();
}
示例#11
0
void R_ParseDetailTextures( const char *filename )
{
	char	*afile, *pfile;
	string	token, texname, detail_texname;
	float	xScale, yScale;
	texture_t	*tex;
	int	i;

	if( r_detailtextures->integer >= 2 && !FS_FileExists( filename, false ))
	{
		// use built-in generator for detail textures
		R_CreateDetailTexturesList( filename );
	}

	afile = FS_LoadFile( filename, NULL, false );
	if( !afile ) return;

	pfile = afile;

	// format: 'texturename' 'detailtexture' 'xScale' 'yScale'
	while(( pfile = COM_ParseFile( pfile, token )) != NULL )
	{
		texname[0] = '\0';

		// read texname
		if( token[0] == '{' )
		{
			// NOTE: COM_ParseFile handled some symbols seperately
			// this code will be fix it
			pfile = COM_ParseFile( pfile, token );
			Q_strncat( texname, "{", sizeof( texname ));
			Q_strncat( texname, token, sizeof( texname ));
		}
		else Q_strncpy( texname, token, sizeof( texname ));

		// read detailtexture name
		pfile = COM_ParseFile( pfile, token );
		Q_snprintf( detail_texname, sizeof( detail_texname ), "gfx/%s.tga", token );

		// read scales
		pfile = COM_ParseFile( pfile, token );
		xScale = Q_atof( token );		

		pfile = COM_ParseFile( pfile, token );
		yScale = Q_atof( token );

		if( xScale <= 0.0f || yScale <= 0.0f )
			continue;

		// search for existing texture and uploading detail texture
		for( i = 0; i < cl.worldmodel->numtextures; i++ )
		{
			tex = cl.worldmodel->textures[i];

			if( Q_stricmp( tex->name, texname ))
				continue;

			tex->dt_texturenum = GL_LoadTexture( detail_texname, NULL, 0, TF_FORCE_COLOR );

			// texture is loaded
			if( tex->dt_texturenum )
			{
				gltexture_t	*glt;

				GL_SetTextureType( tex->dt_texturenum, TEX_DETAIL );
				glt = R_GetTexture( tex->gl_texturenum );
				glt->xscale = xScale;
				glt->yscale = yScale;
			}
			break;
		}
	}

	Mem_Free( afile );
}
示例#12
0
文件: gl_image.c 项目: mattx86/myq2
void LoadPNG (char *name, byte **pic, int *width, int *height)
{
	int				i, rowptr;
	png_structp		png_ptr;
	png_infop		info_ptr;
	png_infop		end_info;

	unsigned char	**row_pointers;

	TPngFileBuffer	PngFileBuffer = {NULL,0};

	*pic = NULL;

	FS_LoadFile (name, &PngFileBuffer.Buffer);

    if (!PngFileBuffer.Buffer)
		return;

	if ((png_check_sig(PngFileBuffer.Buffer, 8)) == 0)
	{
		FS_FreeFile (PngFileBuffer.Buffer); 
		VID_Printf (PRINT_ALL, "Not a PNG file: %s\n", name);
		return;
    }

	PngFileBuffer.Pos=0;

    png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL,  NULL, NULL);

    if (!png_ptr)
	{
		FS_FreeFile (PngFileBuffer.Buffer);
		VID_Printf (PRINT_ALL, "Bad PNG file: %s\n", name);
		return;
	}

    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
	{
        png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
		FS_FreeFile (PngFileBuffer.Buffer);
		VID_Printf (PRINT_ALL, "Bad PNG file: %s\n", name);
		return;
    }
    
	end_info = png_create_info_struct(png_ptr);
    if (!end_info)
	{
        png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
		FS_FreeFile (PngFileBuffer.Buffer);
		VID_Printf (PRINT_ALL, "Bad PNG file: %s\n", name);
		return;
    }

	png_set_read_fn (png_ptr,(png_voidp)&PngFileBuffer,(png_rw_ptr)PngReadFunc);

	png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);

	row_pointers = png_get_rows(png_ptr, info_ptr);

	rowptr = 0;

	*pic = malloc (info_ptr->width * info_ptr->height * sizeof(int));

	if (info_ptr->channels == 4)
	{
		for (i = 0; i < info_ptr->height; i++)
		{
			memcpy (*pic + rowptr, row_pointers[i], info_ptr->rowbytes);
			rowptr += info_ptr->rowbytes;
		}
	}
	else
	{
		int j, x;
		memset (*pic, 255, info_ptr->width * info_ptr->height * sizeof(int));
		x = 0;
		for (i = 0; i < info_ptr->height; i++)
		{
			for (j = 0; j < info_ptr->rowbytes; j+=info_ptr->channels)
			{
				memcpy (*pic + x, row_pointers[i] + j, info_ptr->channels);
				x+= sizeof(int);
			}
			rowptr += info_ptr->rowbytes;
		}
	}

	*width = info_ptr->width;
	*height = info_ptr->height;

	png_destroy_read_struct(&png_ptr, &info_ptr, &end_info);

	FS_FreeFile (PngFileBuffer.Buffer);
}
示例#13
0
文件: gl_image.c 项目: mattx86/myq2
/*
==============
LoadPCX
==============
*/
void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
{
	byte	*raw;
	pcx_t	*pcx;
	int		x, y;
	int		len;
	int		dataByte, runLength;
	byte	*out, *pix;

	*pic = NULL;
	*palette = NULL;

	//
	// load the file
	//
	len = FS_LoadFile (filename, (void **)&raw);
	if (!raw)
	{
		VID_Printf (PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
		return;
	}

	//
	// parse the PCX file
	//
	pcx = (pcx_t *)raw;

    pcx->xmin = LittleShort(pcx->xmin);
    pcx->ymin = LittleShort(pcx->ymin);
    pcx->xmax = LittleShort(pcx->xmax);
    pcx->ymax = LittleShort(pcx->ymax);
    pcx->hres = LittleShort(pcx->hres);
    pcx->vres = LittleShort(pcx->vres);
    pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
    pcx->palette_type = LittleShort(pcx->palette_type);

	raw = &pcx->data;

	if (pcx->manufacturer != 0x0a
		|| pcx->version != 5
		|| pcx->encoding != 1
		|| pcx->bits_per_pixel != 8
		|| pcx->xmax >= 640
		|| pcx->ymax >= 480)
	{
		VID_Printf (PRINT_ALL, "Bad pcx file %s\n", filename);
		return;
	}

	out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );

	*pic = out;

	pix = out;

	if (palette)
	{
		*palette = malloc(768);
		memcpy (*palette, (byte *)pcx + len - 768, 768);
	}

	if (width)
		*width = pcx->xmax+1;
	if (height)
		*height = pcx->ymax+1;

	for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
	{
		for (x=0 ; x<=pcx->xmax ; )
		{
			dataByte = *raw++;

			if((dataByte & 0xC0) == 0xC0)
			{
				runLength = dataByte & 0x3F;
				dataByte = *raw++;
			}
			else
				runLength = 1;

			while(runLength-- > 0)
				pix[x++] = dataByte;
		}

	}

	if ( raw - (byte *)pcx > len)
	{
		VID_Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename);
		free (*pic);
		*pic = NULL;
	}

	FS_FreeFile (pcx);
}
示例#14
0
/**
 * @sa M_Stop
 */
static void M_Start (const char* file)
{
	if (Q_strnull(file))
		return;

	if (!s_env.initialized) {
		Com_Printf("M_Start: No sound started!\n");
		return;
	}

	if (music.playingStream || !music.playing)
		return;

	char name[MAX_QPATH];
	Com_StripExtension(file, name, sizeof(name));
	const size_t len = strlen(name);
	if (len + 4 >= MAX_QPATH) {
		Com_Printf("M_Start: MAX_QPATH exceeded: " UFO_SIZE_T "\n", len + 4);
		return;
	}

	/* we are already playing that track */
	if (Q_streq(name, music.currentTrack) && music.data && Mix_PlayingMusic())
		return;

	/* we are still playing some background track - fade it out */
	if (music.data && Mix_PlayingMusic()) {
		if (!Mix_FadeOutMusic(1500))
			M_Stop();
		Q_strncpyz(music.nextTrack, name, sizeof(music.nextTrack));
		return;
	}

	/* make really sure the last track is closed and freed */
	M_Stop();

	/* load it in */
	byte* musicBuf;
	const int size = FS_LoadFile(va("music/%s.ogg", name), &musicBuf);
	if (size == -1) {
		Com_Printf("M_Start: Could not load '%s' background track!\n", name);
		return;
	}

	SDL_RWops* rw = SDL_RWFromMem(musicBuf, size);
	if (!rw) {
		Com_Printf("M_Start: Could not load music: 'music/%s'!\n", name);
		FS_FreeFile(musicBuf);
		return;
	}
#if SDL_VERSION_ATLEAST(2,0,0)
	music.data = Mix_LoadMUS_RW(rw, 1);
#else
	music.data = Mix_LoadMUS_RW(rw);
#endif
	if (!music.data) {
		Com_Printf("M_Start: Could not load music: 'music/%s' (%s)!\n", name, Mix_GetError());
		SDL_FreeRW(rw);
		FS_FreeFile(musicBuf);
		return;
	}

	Q_strncpyz(music.currentTrack, name, sizeof(music.currentTrack));
	music.buffer = musicBuf;
	if (Mix_FadeInMusic(music.data, 1, 1500) == -1)
		Com_Printf("M_Start: Could not play music: 'music/%s' (%s)!\n", name, Mix_GetError());
}
示例#15
0
/*
==============
S_LoadWavFile
==============
*/
qboolean S_LoadWavFile (const char *filename, sfx_t *sfx)
{
	fs_offset_t filesize;
	unsigned char *data;
	wavinfo_t info;
	int i, len;
	const unsigned char *inb;
	unsigned char *outb;

	// Already loaded?
	if (sfx->fetcher != NULL)
		return true;

	// Load the file
	data = FS_LoadFile(filename, snd_mempool, false, &filesize);
	if (!data)
		return false;

	// Don't try to load it if it's not a WAV file
	if (memcmp (data, "RIFF", 4) || memcmp (data + 8, "WAVE", 4))
	{
		Mem_Free(data);
		return false;
	}

	if (developer_loading.integer >= 2)
		Con_Printf ("Loading WAV file \"%s\"\n", filename);

	info = GetWavinfo (sfx->name, data, (int)filesize);
	if (info.channels < 1 || info.channels > 2)  // Stereo sounds are allowed (intended for music)
	{
		Con_Printf("%s has an unsupported number of channels (%i)\n",sfx->name, info.channels);
		Mem_Free(data);
		return false;
	}
	//if (info.channels == 2)
	//	Log_Printf("stereosounds.log", "%s\n", sfx->name);

	sfx->format.speed = info.rate;
	sfx->format.width = info.width;
	sfx->format.channels = info.channels;
	sfx->fetcher = &wav_fetcher;
	sfx->fetcher_data = Mem_Alloc(snd_mempool, info.samples * sfx->format.width * sfx->format.channels);
	sfx->total_length = info.samples;
	sfx->memsize += filesize;
	len = info.samples * sfx->format.channels * sfx->format.width;
	inb = data + info.dataofs;
	outb = (unsigned char *)sfx->fetcher_data;
	if (info.width == 2)
	{
		if (mem_bigendian)
		{
			// we have to byteswap the data at load (better than doing it while mixing)
			for (i = 0;i < len;i += 2)
			{
				outb[i] = inb[i+1];
				outb[i+1] = inb[i];
			}
		}
		else
		{
			// we can just copy it straight
			memcpy(outb, inb, len);
		}
	}
	else
	{
		// convert unsigned byte sound data to signed bytes for quicker mixing
		for (i = 0;i < len;i++)
			outb[i] = inb[i] - 0x80;
	}

	if (info.loopstart < 0)
		sfx->loopstart = sfx->total_length;
	else
		sfx->loopstart = info.loopstart;
	sfx->loopstart = min(sfx->loopstart, sfx->total_length);
	sfx->flags &= ~SFXFLAG_STREAMED;

	return true;
}
示例#16
0
文件: script.c 项目: m4son/q2pro
static qboolean Parse_File(const char *path, int depth)
{
    char *raw, *data, *p, *cmd;
    int argc;
    menuFrameWork_t *menu = NULL;
    qerror_t ret;

    ret = FS_LoadFile(path, (void **)&raw);
    if (!raw) {
        if (ret != Q_ERR_NOENT || depth) {
            Com_WPrintf("Couldn't %s %s: %s\n", depth ? "include" : "load",
                        path, Q_ErrorString(ret));
        }
        return qfalse;
    }

    data = raw;
    COM_Compress(data);

    while (*data) {
        p = strchr(data, '\n');
        if (p) {
            *p = 0;
        }

        Cmd_TokenizeString(data, qtrue);

        argc = Cmd_Argc();
        if (argc) {
            cmd = Cmd_Argv(0);
            if (menu) {
                if (!strcmp(cmd, "end")) {
                    if (menu->nitems) {
                        List_Append(&ui_menus, &menu->entry);
                    } else {
                        Com_WPrintf("Menu entry without items\n");
                        menu->free(menu);
                    }
                    menu = NULL;
                } else if (!strcmp(cmd, "title")) {
                    if (menu->title) {
                        Z_Free(menu->title);
                    }
                    menu->title = UI_CopyString(Cmd_Argv(1));
                } else if (!strcmp(cmd, "plaque")) {
                    Parse_Plaque(menu);
                } else if (!strcmp(cmd, "banner")) {
                    Parse_Banner(menu);
                } else if (!strcmp(cmd, "background")) {
                    Parse_Background(menu);
                } else if (!strcmp(cmd, "style")) {
                    Parse_Style(menu);
                } else if (!strcmp(cmd, "values")) {
                    Parse_Spin(menu, MTYPE_SPINCONTROL);
                } else if (!strcmp(cmd, "strings")) {
                    Parse_Spin(menu, MTYPE_STRINGS);
                } else if (!strcmp(cmd, "pairs")) {
                    Parse_Pairs(menu);
                } else if (!strcmp(cmd, "range")) {
                    Parse_Range(menu);
                } else if (!strcmp(cmd, "action")) {
                    Parse_Action(menu);
                } else if (!strcmp(cmd, "bitmap")) {
                    Parse_Bitmap(menu);
                } else if (!strcmp(cmd, "bind")) {
                    Parse_Bind(menu);
                } else if (!strcmp(cmd, "savegame")) {
                    Parse_Savegame(menu, MTYPE_SAVEGAME);
                } else if (!strcmp(cmd, "loadgame")) {
                    Parse_Savegame(menu, MTYPE_LOADGAME);
                } else if (!strcmp(cmd, "toggle")) {
                    Parse_Toggle(menu);
                } else if (!strcmp(cmd, "field")) {
                    Parse_Field(menu);
                } else if (!strcmp(cmd, "blank")) {
                    Parse_Blank(menu);
                } else {
                    Com_WPrintf("Unknown keyword '%s'\n", cmd);
                }
            } else {
                if (!strcmp(cmd, "begin")) {
                    char *s = Cmd_Argv(1);
                    if (!*s) {
                        Com_WPrintf("Expected menu name after '%s'\n", cmd);
                        break;
                    }
                    menu = UI_FindMenu(s);
                    if (menu) {
                        if (menu->free) {
                            menu->free(menu);
                        }
                        List_Remove(&menu->entry);
                    }
                    menu = UI_Mallocz(sizeof(*menu));
                    menu->name = UI_CopyString(s);
                    menu->push = Menu_Push;
                    menu->pop = Menu_Pop;
                    menu->free = Menu_Free;
                    menu->image = uis.backgroundHandle;
                    menu->color.u32 = uis.color.background.u32;
                    menu->transparent = uis.transparent;
                } else if (!strcmp(cmd, "include")) {
                    char *s = Cmd_Argv(1);
                    if (!*s) {
                        Com_WPrintf("Expected file name after '%s'\n", cmd);
                        break;
                    }
                    if (depth == 16) {
                        Com_WPrintf("Includes too deeply nested\n");
                    } else {
                        Parse_File(s, depth + 1);
                    }
                } else if (!strcmp(cmd, "color")) {
                    Parse_Color();
                } else if (!strcmp(cmd, "background")) {
                    char *s = Cmd_Argv(1);

                    if (SCR_ParseColor(s, &uis.color.background)) {
                        uis.backgroundHandle = 0;
                        uis.transparent = uis.color.background.u8[3] != 255;
                    } else {
                        uis.backgroundHandle = R_RegisterPic(s);
                        uis.transparent = R_GetPicSize(NULL, NULL, uis.backgroundHandle);
                    }
                } else if (!strcmp(cmd, "font")) {
                    uis.fontHandle = R_RegisterFont(Cmd_Argv(1));
                } else if (!strcmp(cmd, "cursor")) {
                    uis.cursorHandle = R_RegisterPic(Cmd_Argv(1));
                    R_GetPicSize(&uis.cursorWidth,
                                 &uis.cursorHeight, uis.cursorHandle);
                } else if (!strcmp(cmd, "weapon")) {
                    Cmd_ArgvBuffer(1, uis.weaponModel, sizeof(uis.weaponModel));
                } else {
                    Com_WPrintf("Unknown keyword '%s'\n", cmd);
                    break;
                }
            }
        }

        if (!p) {
            break;
        }

        data = p + 1;
    }

    FS_FreeFile(raw);

    if (menu) {
        Com_WPrintf("Menu entry without 'end' terminator\n");
        menu->free(menu);
    }

    return qtrue;
}
示例#17
0
文件: sv_user.c 项目: luaman/qforge-2
/*
==================
SV_BeginDownload_f
==================
*/
void SV_BeginDownload_f(void){
	char	*name;
	extern	cvar_t *allow_download;
	extern	cvar_t *allow_download_players;
	extern	cvar_t *allow_download_models;
	extern	cvar_t *allow_download_sounds;
	extern	cvar_t *allow_download_maps;
	extern	int	file_from_pak; // ZOID did file come from pak?
	int offset = 0;

	name = Cmd_Argv(1);

	if(Cmd_Argc() > 2)
		offset = atoi(Cmd_Argv(2)); // downloaded offset

	// hacked by zoid to allow more conrol over download
	// first off, no .. or global allow check
	if(strstr(name, "..") || strstr(name, "\\/") || !allow_download->value
			// leading dot is no good
			|| *name == '.'
			// leading slash bad as well, must be in subdir
			|| *name == '/'
			// next up, skin check
			||(strncmp(name, "players/", 6) == 0 && !allow_download_players->value)
			// now models
			||(strncmp(name, "models/", 6) == 0 && !allow_download_models->value)
			// now sounds
			||(strncmp(name, "sound/", 6) == 0 && !allow_download_sounds->value)
			// now maps(note special case for maps, must not be in pak)
			||(strncmp(name, "maps/", 6) == 0 && !allow_download_maps->value)
			// MUST be in a subdirectory
			|| !strstr(name, "/")){	// don't allow anything with .. path
		MSG_WriteByte(&sv_client->netchan.message, svc_download);
		MSG_WriteShort(&sv_client->netchan.message, -1);
		MSG_WriteByte(&sv_client->netchan.message, 0);
		return;
	}


	if(sv_client->download)
		FS_FreeFile(sv_client->download);

	sv_client->downloadsize = FS_LoadFile(name, (void **)(char *)&sv_client->download);
	sv_client->downloadcount = offset;

	if(offset > sv_client->downloadsize)
		sv_client->downloadcount = sv_client->downloadsize;

	if(!sv_client->download
			// special check for maps, if it came from a pak file, don't allow
			// download  ZOID
			||(strncmp(name, "maps/", 5) == 0 && file_from_pak)){
		Com_DPrintf("Couldn't download %s to %s\n", name, sv_client->name);
		if(sv_client->download){
			FS_FreeFile(sv_client->download);
			sv_client->download = NULL;
		}

		MSG_WriteByte(&sv_client->netchan.message, svc_download);
		MSG_WriteShort(&sv_client->netchan.message, -1);
		MSG_WriteByte(&sv_client->netchan.message, 0);
		return;
	}

	SV_NextDownload_f();
	Com_DPrintf("Downloading %s to %s\n", name, sv_client->name);
}
示例#18
0
/*
===============
CL_Download_f

Request a download from the server
===============
*/
void	CL_Download_f (void)
{
	char filename[MAX_OSPATH];
	int len;

	if (Cmd_Argc() != 2) {
		Com_Printf("Usage: download <filename>\n");
		return;
	}

	Com_sprintf(filename, sizeof(filename), "%s", Cmd_Argv(1));

	if (strstr (filename, ".."))
	{
		Com_Printf ("Refusing to download a path with ..\n");
		return;
	}

	// NeVo - hack to not download if we have the image (any type)
	len = strlen(filename);
	if ((!strcmp(filename+len-4, ".pcx")) || (!strcmp(filename+len-4, ".wal")))
	{
		COM_StripExtension (filename, filename);
		strcat (filename, ".tga");
		if (FS_LoadFile (filename, NULL) != -1)
		{	// it exists, no need to download
			Com_Printf("File already exists.\n");
			return;
		}
		else
		{
			COM_StripExtension (filename, filename);
			strcat (filename, ".jpg");
			if (FS_LoadFile (filename, NULL) != -1)
			{	// it exists, no need to download
				Com_Printf("File already exists.\n");
				return;
			}
			else
			{
				COM_StripExtension (filename, filename);
				strcat (filename, ".m32");
				if (FS_LoadFile (filename, NULL) != -1)
				{	// it exists, no need to download
					Com_Printf("File already exists.\n");
					return;
				}
				else
				{
					COM_StripExtension (filename, filename);
					strcat (filename, ".pcx");
					if (FS_LoadFile (filename, NULL) != -1)
					{	// it exists, no need to download
						Com_Printf("File already exists.\n");
						return;
					}
					else
					{
						COM_StripExtension (filename, filename);
						strcat (filename, ".wal");
						if (FS_LoadFile (filename, NULL) != -1)
						{	// it exists, no need to download
							Com_Printf("File already exists.\n");
							return;
						}
					}
				}
			}
		}
	}
	else if (FS_LoadFile (filename, NULL) != -1)
	{	// it exists, no need to download
		return;
	}

	strcpy (cls.downloadname, filename);
	Com_Printf ("Downloading %s\n", cls.downloadname);

	// download to a temp name, and only rename
	// to the real name when done, so if interrupted
	// a runt file wont be left
	COM_StripExtension (cls.downloadname, cls.downloadtempname);
	strcat (cls.downloadtempname, ".tmp");

	MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
	MSG_WriteString (&cls.netchan.message,
		va("download %s", cls.downloadname));

	cls.downloadnumber++;
}
示例#19
0
qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir )
{
	byte	buf[MAX_SYSPATH];
	char	*buffer;
	string	result;
	int	i, size;
	search_t	*t;
	file_t	*f;

	if( FS_FileSize( "maps.lst", onlyingamedir ) > 0 && !fRefresh )
	{
		MsgDev( D_NOTE, "maps.lst is exist: %s\n", onlyingamedir ? "basedir" : "gamedir" );
		return true; // exist 
	}

	t = FS_Search( "maps/*.bsp", false, onlyingamedir );

	if( !t )
	{
		if( onlyingamedir )
		{
			// mod doesn't contain any maps (probably this is a bot)
			return Cmd_CheckMapsList_R( fRefresh, false );
		}

		return false;
	}

	buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result ));

	for( i = 0; i < t->numfilenames; i++ )
	{
		char		*ents = NULL, *pfile;
		int		ver = -1, lumpofs = 0, lumplen = 0;
		string		mapname, message, entfilename;
		const char	*ext = FS_FileExtension( t->filenames[i] ); 

		if( Q_stricmp( ext, "bsp" )) continue;
		f = FS_Open( t->filenames[i], "rb", onlyingamedir );
		FS_FileBase( t->filenames[i], mapname );

		if( f )
		{
			int	num_spawnpoints = 0;
			dheader_t	*header;

			Q_memset( buf, 0, MAX_SYSPATH );
			FS_Read( f, buf, MAX_SYSPATH );
			ver = *(uint *)buf;
                              
			switch( ver )
			{
			case Q1BSP_VERSION:
			case HLBSP_VERSION:
			case XTBSP_VERSION:
				header = (dheader_t *)buf;
				if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 )
				{
					lumpofs = header->lumps[LUMP_PLANES].fileofs;
					lumplen = header->lumps[LUMP_PLANES].filelen;
				}
				else
				{
					lumpofs = header->lumps[LUMP_ENTITIES].fileofs;
					lumplen = header->lumps[LUMP_ENTITIES].filelen;
				}
				break;
			}

			Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename ));
			FS_StripExtension( entfilename );
			FS_DefaultExtension( entfilename, ".ent" );
			ents = FS_LoadFile( entfilename, NULL, true );

			if( !ents && lumplen >= 10 )
			{
				FS_Seek( f, lumpofs, SEEK_SET );
				ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 );
				FS_Read( f, ents, lumplen );
			}

			if( ents )
			{
				// if there are entities to parse, a missing message key just
				// means there is no title, so clear the message string now
				char	token[2048];
				qboolean	worldspawn = true;

				Q_strncpy( message, "No Title", MAX_STRING );
				pfile = ents;

				while(( pfile = COM_ParseFile( pfile, token )) != NULL )
				{
					if( token[0] == '}' && worldspawn )
						worldspawn = false;
					else if( !Q_strcmp( token, "message" ) && worldspawn )
					{
						// get the message contents
						pfile = COM_ParseFile( pfile, message );
					}
					else if( !Q_strcmp( token, "classname" ))
					{
						pfile = COM_ParseFile( pfile, token );
						if( !Q_strcmp( token, GI->mp_entity ))
							num_spawnpoints++;
					}
					if( num_spawnpoints ) break; // valid map
				}
				Mem_Free( ents );
			}

			if( f ) FS_Close( f );

			if( num_spawnpoints )
			{
				// format: mapname "maptitle"\n
				Q_sprintf( result, "%s \"%s\"\n", mapname, message );
				Q_strcat( buffer, result ); // add new string
			}
		}
	}

	if( t ) Mem_Free( t ); // free search result
	size = Q_strlen( buffer );

	if( !size )
	{
          	if( buffer ) Mem_Free( buffer );

		if( onlyingamedir )
			return Cmd_CheckMapsList_R( fRefresh, false );
		return false;
	}

	// write generated maps.lst
	if( FS_WriteFile( "maps.lst", buffer, Q_strlen( buffer )))
	{
          	if( buffer ) Mem_Free( buffer );
		return true;
	}
	return false;
}
示例#20
0
/*
===============
CL_CheckOrDownloadFile

Returns 1 if the file exists, otherwise it attempts
to start a download from the server.
===============
*/
int	CL_CheckOrDownloadFile (char *filename)
{
	FILE	*fp;
	char	name[MAX_OSPATH];
	int		len;

	if (strstr (filename, ".."))
	{
		Com_Printf ("Refusing to download a path with ..\n");
		return 1;
	}

	// NeVo - hack to not download if we have the image (any type)
	len = strlen(filename);
	if ((!strcmp(filename+len-4, ".pcx")) || (!strcmp(filename+len-4, ".wal")))
	{
		COM_StripExtension (filename, filename);
		strcat (filename, ".tga");
		if (FS_LoadFile (filename, NULL) != -1)
		{	// it exists, no need to download
			return 1;
		}
		else
		{
			COM_StripExtension (filename, filename);
			strcat (filename, ".jpg");
			if (FS_LoadFile (filename, NULL) != -1)
			{	// it exists, no need to download
				return 1;
			}
			else
			{
				COM_StripExtension (filename, filename);
				strcat (filename, ".m32");
				if (FS_LoadFile (filename, NULL) != -1)
				{	// it exists, no need to download
					return 1;
				}
				else
				{
					COM_StripExtension (filename, filename);
					strcat (filename, ".pcx");
					if (FS_LoadFile (filename, NULL) != -1)
					{	// it exists, no need to download
						return 1;
					}
					else
					{
						COM_StripExtension (filename, filename);
						strcat (filename, ".wal");
						if (FS_LoadFile (filename, NULL) != -1)
						{	// it exists, no need to download
							return 1;
						}
					}
				}
			}
		}
	}
	else if (FS_LoadFile (filename, NULL) != -1)
	{	// it exists, no need to download
		return 1;
	}

	strcpy (cls.downloadname, filename);

	// download to a temp name, and only rename
	// to the real name when done, so if interrupted
	// a runt file wont be left
	COM_StripExtension (cls.downloadname, cls.downloadtempname);
	strcat (cls.downloadtempname, ".tmp");

//ZOID
	// check to see if we already have a tmp for this file, if so, try to resume
	// open the file if not opened yet
	CL_DownloadFileName(name, sizeof(name), cls.downloadtempname);

//	FS_CreatePath (name);

	fp = fopen (name, "r+b");
	if (fp) { // it exists
		int len;
		fseek(fp, 0, SEEK_END);
		len = ftell(fp);

		cls.download = fp;

		// give the server an offset to start the download
		Com_Printf ("Resuming %s\n", cls.downloadname);
		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
		MSG_WriteString (&cls.netchan.message,
			va("download %s %i", cls.downloadname, len));
	} else {
		Com_Printf ("Downloading %s\n", cls.downloadname);
		MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
		MSG_WriteString (&cls.netchan.message,
			va("download %s", cls.downloadname));
	}

	cls.downloadnumber++;

	return 0;
}
示例#21
0
/*
====================
ModPlug_LoadmodplugFile

Load an modplug file into memory
====================
*/
qboolean ModPlug_LoadModPlugFile (const char *filename, sfx_t *sfx)
{
	unsigned char *data;
	fs_offset_t filesize;
	ModPlugFile *mf;
	modplug_stream_persfx_t* per_sfx;
	ModPlug_Settings s;

	if (!modplug_dll)
		return false;

	// Already loaded?
	if (sfx->fetcher != NULL)
		return true;

	// Load the file
	data = FS_LoadFile (filename, snd_mempool, false, &filesize);
	if (data == NULL)
		return false;

	if (developer_loading.integer >= 2)
		Con_Printf ("Loading ModPlug file \"%s\"\n", filename);

	qModPlug_GetSettings(&s);
	s.mFlags = MODPLUG_ENABLE_OVERSAMPLING | MODPLUG_ENABLE_NOISE_REDUCTION | MODPLUG_ENABLE_REVERB;
	s.mChannels = 2;
	s.mBits = 16;
	s.mFrequency = 44100;
	s.mResamplingMode = MODPLUG_RESAMPLE_SPLINE;
	s.mLoopCount = -1;
	qModPlug_SetSettings(&s);

	// Open it with the modplugFile API
	if (!(mf = qModPlug_Load (data, filesize)))
	{
		Con_Printf ("error while opening ModPlug file \"%s\"\n", filename);
		Mem_Free(data);
		return false;
	}

#ifndef SND_MODPLUG_STATIC
	if(qModPlug_SetMasterVolume)
#endif
		qModPlug_SetMasterVolume(mf, 512); // max volume, DP scales down!

	if (developer_loading.integer >= 2)
		Con_Printf ("\"%s\" will be streamed\n", filename);
	per_sfx = (modplug_stream_persfx_t *)Mem_Alloc (snd_mempool, sizeof (*per_sfx));
	per_sfx->file = data;
	per_sfx->filesize = filesize;
	sfx->memsize += sizeof(*per_sfx);
	sfx->memsize += filesize;
	sfx->format.speed = 44100; // modplug always works at that rate
	sfx->format.width = 2;  // We always work with 16 bits samples
	sfx->format.channels = 2; // stereo rulez ;) (MAYBE default to mono because Amiga MODs sound better then?)
	sfx->fetcher_data = per_sfx;
	sfx->fetcher = &modplug_fetcher;
	sfx->flags |= SFXFLAG_STREAMED;
	sfx->total_length = 1<<30; // 2147384647; // they always loop (FIXME this breaks after 6 hours, we need support for a real "infinite" value!)
	sfx->loopstart = sfx->total_length; // modplug does it

	return true;
}
示例#22
0
/*
* ML_InitFromCache
* Fills map list array from cache, much faster
*/
static void ML_InitFromCache( void )
{
    int count, i, total, len;
    size_t size = 0;
    char *buffer, *chr, *current, *curend;
    char *temp, *maps, *map;
    mapdir_t *dir, *curmap, *prev;

    if( ml_initialized )
        return;

    total = FS_GetFileListExt( "maps", ".bsp", NULL, &size, 0, 0 );
    if( !total )
        return;

    // load maps from directory reading into a list
    maps = temp = ( char* )Mem_TempMalloc( size + sizeof( mapdir_t ) * total );
    temp += size;
    FS_GetFileList( "maps", ".bsp", maps, size, 0, 0 );
    len = 0;
    prev = NULL;
    dir = NULL;
    for( i = 0; i < total; i++ )
    {
        map = maps + len;
        len += strlen( map ) + 1;

        curmap = ( mapdir_t * )temp;
        temp += sizeof( mapdir_t );

        COM_StripExtension( map );

        if( !i )
            dir = curmap;
        else
        {
            prev->next = curmap;
            curmap->prev = prev;
        }

        curmap->filename = map;
        prev = curmap;
    }

    FS_LoadFile( MLIST_CACHE, (void **)&buffer, NULL, 0 );
    if( !buffer )
    {
        Mem_TempFree( maps );
        return;
    }

    current = curend = buffer;
    count = 0;

    for( chr = buffer; *chr; chr++ )
    {
        // current character is a delimiter
        if( *chr == '\n' )
        {
            if( *(chr-1) == '\r' )
                *(chr-1) = '\0';	// clear the CR too
            *chr = '\0';			// clear the LF

            // if we have got both params
            if( !( ++count & 1 ) )
            {
                // check if its in the maps directory
                for( curmap = dir; curmap; curmap = curmap->next )
                {
                    if( !Q_stricmp( curmap->filename, current ) )
                    {
                        if( curmap->prev )
                            curmap->prev->next = curmap->next;
                        else
                            dir = curmap->next;

                        if( curmap->next )
                            curmap->next->prev = curmap->prev;
                        break;
                    }
                }

                // if we found it in the maps directory
                if( curmap )
                {
                    COM_SanitizeFilePath( current );

                    // well, if we've got a map with an unknown fullname, load it from map
                    if( !strcmp( curend + 1, MLIST_UNKNOWN_MAPNAME ) )
                        ML_AddMap( current, NULL );
                    else
                        ML_AddMap( current, curend + 1 );
                }
                current = chr + 1;
            }
            else
                curend = chr;
        }
    }

    // we've now loaded the mapcache, but there may be files which
    // have been added to maps directory, and the mapcache isnt aware
    // these will be left over in our directory list
    for( curmap = dir; curmap; curmap = curmap->next )
        ML_AddMap( curmap->filename, NULL );

    Mem_TempFree( maps );
    FS_FreeFile( buffer );
}
示例#23
0
文件: snd_mem.c 项目: mattx86/myq2
/*
==============
S_LoadSound
==============
*/
sfxcache_t *S_LoadSound (sfx_t *s)
{
    char	namebuffer[MAX_QPATH];
	byte	*data;
	wavinfo_t	info;
	int		len;
	float	stepscale;
	sfxcache_t	*sc;
	int		size;
	char	*name;

	if (s->name[0] == '*')
		return NULL;

// see if still in memory
	sc = s->cache;
	if (sc)
		return sc;

//S_Printf(PRINT_ALL, "S_LoadSound: %x\n", (int)stackbuf);
// load it in
	if (s->truename)
		name = s->truename;
	else
		name = s->name;

	if (name[0] == '#')
		strcpy(namebuffer, &name[1]);
	else
		Com_sprintf (namebuffer, sizeof(namebuffer), "sound/%s", name);

//	S_Printf(PRINT_ALL, "loading %s\n",namebuffer);

	size = FS_LoadFile (namebuffer, (void **)&data);

	if (!data)
	{
		S_Printf(PRINT_DEVELOPER, "Couldn't load %s\n", namebuffer);
		return NULL;
	}

	info = GetWavinfo (s->name, data, size);
	if (info.channels != 1)
	{
		S_Printf(PRINT_ALL, "%s is a stereo sample\n",s->name);
		FS_FreeFile (data);
		return NULL;
	}

	stepscale = (float)info.rate / dma.speed;	
	len = info.samples / stepscale;

	len = len * info.width * info.channels;

	sc = s->cache = Z_Malloc (len + sizeof(sfxcache_t));
	if (!sc)
	{
		FS_FreeFile (data);
		return NULL;
	}
	
	sc->length = info.samples;
	sc->loopstart = info.loopstart;
	sc->speed = info.rate;
	sc->width = info.width;
	sc->stereo = info.channels;

	ResampleSfx (s, sc->speed, sc->width, data + info.dataofs);

	FS_FreeFile (data);

	return sc;
}
示例#24
0
void
SV_BeginDownload_f(void)
{
	char *name;
	extern cvar_t *allow_download;
	extern cvar_t *allow_download_players;
	extern cvar_t *allow_download_models;
	extern cvar_t *allow_download_sounds;
	extern cvar_t *allow_download_maps;
	extern int file_from_pak;
	int offset = 0;

	name = Cmd_Argv(1);

	if (Cmd_Argc() > 2)
	{
		offset = (int)strtol(Cmd_Argv(2), (char **)NULL, 10); /* downloaded offset */
	}

	/* hacked by zoid to allow more conrol over download
	   first off, no .. or global allow check */
	if (strstr(name, "..") || strstr(name, "\\") || !allow_download->value
		/* leading dot is no good */
		|| (*name == '.')
		/* leading slash bad as well, must be in subdir */
		|| (*name == '/')
		/* next up, skin check */
		|| ((strncmp(name, "players/", 6) == 0) && !allow_download_players->value)
		/* now models */
		|| ((strncmp(name, "models/", 6) == 0) && !allow_download_models->value)
		/* now sounds */
		|| ((strncmp(name, "sound/", 6) == 0) && !allow_download_sounds->value)
		/* now maps (note special case for maps, must not be in pak) */
		|| ((strncmp(name, "maps/", 6) == 0) && !allow_download_maps->value)
		/* MUST be in a subdirectory */
		|| !strstr(name, "/"))
	{
		MSG_WriteByte(&sv_client->netchan.message, svc_download);
		MSG_WriteShort(&sv_client->netchan.message, -1);
		MSG_WriteByte(&sv_client->netchan.message, 0);
		return;
	}

	if (sv_client->download)
	{
		FS_FreeFile(sv_client->download);
	}

	sv_client->downloadsize = FS_LoadFile(name, (void **)&sv_client->download);
	sv_client->downloadcount = offset;

	if (offset > sv_client->downloadsize)
	{
		sv_client->downloadcount = sv_client->downloadsize;
	}

	if (!sv_client->download || ((strncmp(name, "maps/", 5) == 0) && file_from_pak))
	{
		Com_DPrintf("Couldn't download %s to %s\n", name, sv_client->name);

		if (sv_client->download)
		{
			FS_FreeFile(sv_client->download);
			sv_client->download = NULL;
		}

		MSG_WriteByte(&sv_client->netchan.message, svc_download);
		MSG_WriteShort(&sv_client->netchan.message, -1);
		MSG_WriteByte(&sv_client->netchan.message, 0);
		return;
	}

	SV_NextDownload_f();
	Com_DPrintf("Downloading %s to %s\n", name, sv_client->name);
}
示例#25
0
/**
 * @brief Tries to load a mdx file that contains the normals and the tangents for a model.
 * @sa R_ModCalcNormalsAndTangents
 * @sa R_ModCalcUniqueNormalsAndTangents
 * @param mod The model to load the mdx file for
 */
qboolean R_ModLoadMDX (model_t *mod)
{
	int i;
	for (i = 0; i < mod->alias.num_meshes; i++) {
		mAliasMesh_t *mesh = &mod->alias.meshes[i];
		char mdxFileName[MAX_QPATH];
		byte *buffer = NULL, *buf;
		const int32_t *intbuf;
		uint32_t version;
		int sharedTris[MAX_ALIAS_VERTS];

		Com_StripExtension(mod->name, mdxFileName, sizeof(mdxFileName));
		Com_DefaultExtension(mdxFileName, sizeof(mdxFileName), ".mdx");

		if (FS_LoadFile(mdxFileName, &buffer) == -1)
			return qfalse;

		buf = buffer;
		if (strncmp((const char *) buf, IDMDXHEADER, strlen(IDMDXHEADER)))
			Com_Error(ERR_DROP, "No mdx file buffer given");
		buffer += strlen(IDMDXHEADER) * sizeof(char);
		version = LittleLong(*(uint32_t*) buffer);
		if (version != MDX_VERSION)
			Com_Error(ERR_DROP, "Invalid version of the mdx file, expected %i, found %i",
					MDX_VERSION, version);
		buffer += sizeof(uint32_t);

		intbuf = (const int32_t *) buffer;

		mesh->num_verts = LittleLong(*intbuf);
		if (mesh->num_verts <= 0 || mesh->num_verts > MAX_ALIAS_VERTS)
			Com_Error(ERR_DROP, "mdx file for %s has to many (or no) vertices: %i", mod->name, mesh->num_verts);
		intbuf++;
		mesh->num_indexes = LittleLong(*intbuf);
		intbuf++;

		mesh->indexes = (int32_t *)Mem_PoolAlloc(sizeof(int32_t) * mesh->num_indexes, vid_modelPool, 0);
		mesh->revIndexes = (mIndexList_t *)Mem_PoolAlloc(sizeof(mIndexList_t) * mesh->num_verts, vid_modelPool, 0);
		mesh->vertexes = (mAliasVertex_t *)Mem_PoolAlloc(sizeof(mAliasVertex_t) * mod->alias.num_frames * mesh->num_verts, vid_modelPool, 0);

		/* load index that maps triangle verts to Vertex objects */
		for (i = 0; i < mesh->num_indexes; i++) {
			mesh->indexes[i] = LittleLong(*intbuf);
			intbuf++;
		}

		for (i = 0; i < mesh->num_verts; i++)
			sharedTris[i] = 0;

		/* set up reverse-index that maps Vertex objects to a list of triangle verts */
		for (i = 0; i < mesh->num_indexes; i++)
			sharedTris[mesh->indexes[i]]++;

		for (i = 0; i < mesh->num_verts; i++) {
			mesh->revIndexes[i].length = 0;
			mesh->revIndexes[i].list = (int32_t *)Mem_PoolAlloc(sizeof(int32_t) * sharedTris[i], vid_modelPool, 0);
		}

		for (i = 0; i < mesh->num_indexes; i++)
			mesh->revIndexes[mesh->indexes[i]].list[mesh->revIndexes[mesh->indexes[i]].length++] = i;

		FS_FreeFile(buf);
	}

	return qtrue;
}
示例#26
0
/**
 * @sa CM_AddMapTile
 * @sa R_ModBeginLoading
 * @param[in] name The name of the map. Relative to maps/ and without extension
 * @param[in] day Load the day lightmap
 * @param[in] sX Shift x grid units
 * @param[in] sY Shift y grid units
 * @param[in] sZ Shift z grid units
 * @sa UNIT_SIZE
 */
static void R_ModAddMapTile (const char *name, qboolean day, int sX, int sY, int sZ)
{
	int i;
	byte *buffer;
	dBspHeader_t *header;
	const int lightingLump = day ? LUMP_LIGHTING_DAY : LUMP_LIGHTING_NIGHT;

	/* get new model */
	if (r_numModels < 0 || r_numModels >= MAX_MOD_KNOWN)
		Com_Error(ERR_DROP, "R_ModAddMapTile: r_numModels >= MAX_MOD_KNOWN");

	if (r_numMapTiles < 0 || r_numMapTiles >= MAX_MAPTILES)
		Com_Error(ERR_DROP, "R_ModAddMapTile: Too many map tiles");

	/* alloc model and tile */
	r_worldmodel = &r_models[r_numModels++];
	r_mapTiles[r_numMapTiles++] = r_worldmodel;
	OBJZERO(*r_worldmodel);
	Com_sprintf(r_worldmodel->name, sizeof(r_worldmodel->name), "maps/%s.bsp", name);

	/* load the file */
	FS_LoadFile(r_worldmodel->name, &buffer);
	if (!buffer)
		Com_Error(ERR_DROP, "R_ModAddMapTile: %s not found", r_worldmodel->name);

	/* init */
	r_worldmodel->type = mod_bsp;

	/* prepare shifting */
	VectorSet(shift, sX * UNIT_SIZE, sY * UNIT_SIZE, sZ * UNIT_SIZE);

	/* test version */
	header = (dBspHeader_t *) buffer;
	i = LittleLong(header->version);
	if (i != BSPVERSION)
		Com_Error(ERR_DROP, "R_ModAddMapTile: %s has wrong version number (%i should be %i)", r_worldmodel->name, i, BSPVERSION);

	/* swap all the lumps */
	mod_base = (byte *) header;

	for (i = 0; i < (int)sizeof(dBspHeader_t) / 4; i++)
		((int *) header)[i] = LittleLong(((int *) header)[i]);

	/* load into heap */
	R_ModLoadVertexes(&header->lumps[LUMP_VERTEXES]);
	R_ModLoadNormals(&header->lumps[LUMP_NORMALS]);
	R_ModLoadEdges(&header->lumps[LUMP_EDGES]);
	R_ModLoadSurfedges(&header->lumps[LUMP_SURFEDGES]);
	R_ModLoadLighting(&header->lumps[lightingLump]);
	R_ModLoadPlanes(&header->lumps[LUMP_PLANES]);
	R_ModLoadTexinfo(&header->lumps[LUMP_TEXINFO]);
	R_ModLoadSurfaces(day, &header->lumps[LUMP_FACES]);
	R_ModLoadLeafs(&header->lumps[LUMP_LEAFS]);
	R_ModLoadNodes(&header->lumps[LUMP_NODES]);
	R_ModLoadSubmodels(&header->lumps[LUMP_MODELS]);

	R_SetupSubmodels();

	R_LoadBspVertexArrays(r_worldmodel);

	/* in case of random map assembly shift some vectors */
	if (VectorNotEmpty(shift))
		R_ModShiftTile();

	FS_FreeFile(buffer);
}
示例#27
0
文件: gl_rpart.c 项目: Reedych/xash3d
/*
===============
CL_ReadPointFile_f

===============
*/
void CL_ReadPointFile_f( void )
{
	char		*afile, *pfile;
	vec3_t		org;
	int		count;
	particle_t	*p;
	char		filename[64];
	string		token;
	
	Q_snprintf( filename, sizeof( filename ), "maps/%s.pts", clgame.mapname );
	afile = (char *)FS_LoadFile( filename, NULL, false );

	if( !afile )
	{
		MsgDev( D_ERROR, "couldn't open %s\n", filename );
		return;
	}
	
	Msg( "Reading %s...\n", filename );

	count = 0;
	pfile = afile;

	while( 1 )
	{
		pfile = COM_ParseFile( pfile, token );
		if( !pfile ) break;
		org[0] = Q_atof( token );

		pfile = COM_ParseFile( pfile, token );
		if( !pfile ) break;
		org[1] = Q_atof( token );

		pfile = COM_ParseFile( pfile, token );
		if( !pfile ) break;
		org[2] = Q_atof( token );

		count++;
		
		if( !cl_free_particles )
		{
			MsgDev( D_ERROR, "CL_ReadPointFile: not enough free particles!\n" );
			break;
		}

		// NOTE: can't use CL_AllocateParticles because running from the console
		p = cl_free_particles;
		cl_free_particles = p->next;
		p->next = cl_active_particles;
		cl_active_particles = p;

		p->ramp = 0;		
		p->die = 99999;
		p->color = (-count) & 15;
		p->type = pt_static;
		VectorClear( p->vel );
		VectorCopy( org, p->org );
	}

	Mem_Free( afile );

	if( count ) Msg( "%i points read\n", count );
	else Msg( "map %s has no leaks!\n", clgame.mapname );
}
示例#28
0
static qboolean SV_AntiCheat_ReadFile (const char *filename, void (*func)(char *, int, const char *))
{
	int			len;
	char		line[256];
	char		*q;
	char		*buff, *ptr;
	int			line_number;

	len = FS_LoadFile (filename, (void **)&buff);

	if (len == -1)
		return false;

	ptr = buff;
	q = buff;

	line_number = 1;

	while (len)
	{
		switch (buff[0])
		{
			case '\n':
			case '\r':
				buff[0] = 0;
				if (q)
				{
					qboolean	parse;
					char		*p;

					Q_strncpy (line, q, sizeof(line)-1);
					parse = true;

					p = strchr (line, '\n');
					if (p)
						p[0] = 0;

					p = strchr (line, '\r');
					if (p)
						p[0] = 0;

					if (line[0] == '#' || line[0] == '/' || line[0] == '\0')
						parse = false;
					else if (line[0] == '\\')
					{
						if (!strncmp (line + 1, "include ", 8))
						{
							char	*path;

							path = line + 9;

							if (!SV_AntiCheat_ReadFile (path, func))
								Com_Printf ("ANTICHEAT WARNING: Unable to read included file '%s' from line %d of %s\n", LOG_WARNING|LOG_ANTICHEAT|LOG_SERVER, path, line_number, filename);
						}
						else
						{
							Com_Printf ("ANTICHEAT WARNING: Unknown directive '%s' on line %d of %s\n", LOG_WARNING|LOG_ANTICHEAT|LOG_SERVER, line + 1, line_number, filename);
						}

						parse = false;
					}

					if (parse)
						func (line, line_number, filename);
					q = NULL;
					line_number++;
				}
				buff++;
				break;
			case '\0':
				buff++;
				break;
			default:
				if (!q)
					q = buff;
				buff++;
				break;
		}
		len--;
	}

	FS_FreeFile (ptr);

	return true;
}
示例#29
0
/**
 * @brief Do our own preprocessing to the shader file, before the
 * GLSL implementation calls it's preprocessor.
 *
 * "#if/#endif" pairs, "#unroll", "#endunroll", "#include", "#replace" are handled by our
 * preprocessor, not the GLSL implementation's preprocessor (except "#include" which may
 * also be handled by the implementation's preprocessor).  "#if" operates off
 * of the value of a cvar interpreted as a bool. Note the GLSL implementation
 * preprocessor handles "#ifdef" and "#ifndef", not "#if".
 * @param[in] name The file name of the shader (e.g. "world_fs.glsl").
 * @param[in] inPtr The non-preprocessed shader string.
 * @param[in,out] out The preprocessed shader string, nullptr if we don't want to write to it.
 * @param[in,out] remainingOutChars The number of characters left in the out buffer.
 * @param[in] nested If true, parsing a part of "#if" clause, so "#else" and "#endif" tokens are allowed
 * @param[in] inElse If true, parsing an "#else" clause and shouldn't expect another "#else"
 * @return The number of characters added to the buffer pointed to by out.
 */
static size_t R_PreprocessShaderR (const char* name, const char** inPtr, char* out, long* remainingOutChars, bool nested, bool inElse)
{
	const size_t INITIAL_REMAINING_OUT_CHARS = (size_t)*remainingOutChars;
	/* Keep looping till we reach the end of the shader string, or a parsing error.*/
	while (**inPtr) {
		if ('#' == **inPtr) {
			bool endBlockToken;
			(*inPtr)++;

			endBlockToken = !strncmp(*inPtr, "endif", 5);

			if (!strncmp(*inPtr, "else", 4)) {
				if (inElse) {
					/* Error in shader! Print a message saying our preprocessor failed parsing.*/
					Com_Error(ERR_DROP, "R_PreprocessShaderR: #else without #if: %s", name);
				}
				endBlockToken = true;
			}

			if (endBlockToken) {
				if (!nested) {
					/* Error in shader! Print a message saying our preprocessor failed parsing.*/
					Com_Error(ERR_DROP, "R_PreprocessShaderR: Unmatched #endif/#else: %s", name);
				}
				/* Whoever called us will have to deal with closing the block */
				return (INITIAL_REMAINING_OUT_CHARS - (size_t)*remainingOutChars);
			}

			if (!strncmp((*inPtr), "if ", 3)) {
				/* The line looks like "#if r_postprocess".*/
				(*inPtr) += 3;
				/* Get the corresponding cvar value.*/
				float f = Cvar_GetValue(Com_Parse(inPtr));
				if (f) { /* Condition is true, recursively preprocess #if block, and skip over #else block, if any */
					int size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, false);
					if (out) out += size;

					if (!strncmp((*inPtr), "else", 4)) {/* Preprocess and skip #else block */
						(*inPtr) +=4 ;
						R_PreprocessShaderR(name, inPtr, (char*)0, remainingOutChars, true, true);
					}
				} else {
					/* The cvar was false, don't add to out. Lets look and see if we hit a #else, or #endif.*/
					R_PreprocessShaderR(name, inPtr, (char*)0, remainingOutChars, true, false);
					if (!strncmp((*inPtr), "else", 4)) {
						int size;
						/* All right, we want to add this to out.*/
						(*inPtr) +=4 ;
						size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, true);
						if (out) out += size;
					}
				}
				/* skip #endif, if any (could also get here by unexpected EOF */
				if (!strncmp((*inPtr), "endif", 5))
					(*inPtr) +=5 ;
			} else if (!strncmp((*inPtr), "ifndef", 6) || !strncmp((*inPtr), "ifdef", 5)) { /* leave those for GLSL compiler, but follow #else/#endif nesting */
				int size;
				if (out) {
					if (*remainingOutChars <= 0)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					*out++ = '#';
					(*remainingOutChars)--;
				}

				size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, false);
				if (out) out += size;

				if (!strncmp((*inPtr), "else", 4)) {
					if (out) {
						if (*remainingOutChars <= 0)
							Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
						*out++ = '#';
						(*remainingOutChars)--;
					}
					size = R_PreprocessShaderR(name, inPtr, out, remainingOutChars, true, true);
					if (out) out += size;
				}

				if (out) {
					if (*remainingOutChars <= 0)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					*out++ = '#';
					(*remainingOutChars)--;
				}

			} else if (!strncmp((*inPtr), "include", 7)) {
				char path[MAX_QPATH];
				byte* buf = (byte*)0;
				const char* bufAsChar = (const char*)0;
				const char** bufAsCharPtr = (const char**)0;
				(*inPtr) += 8;
				Com_sprintf(path, sizeof(path), "shaders/%s", Com_Parse(inPtr));
				if (FS_LoadFile(path, &buf) == -1) {
					Com_Printf("Failed to resolve #include: %s.\n", path);
					continue;
				}
				bufAsChar = (const char*)buf;
				bufAsCharPtr = &bufAsChar;
				if (out) {
					out += R_PreprocessShaderR(name, bufAsCharPtr, out, remainingOutChars, nested, false);
				} else {
					R_PreprocessShaderR(name, bufAsCharPtr, out, remainingOutChars, nested, false);
				}
				FS_FreeFile(buf);
			} else if (!strncmp((*inPtr), "unroll", 6)) {
				/* loop unrolling */
				size_t subLength = 0;
				byte* const buffer = Mem_PoolAllocTypeN(byte, SHADER_BUF_SIZE, vid_imagePool);
				(*inPtr) += 6;
				int z = Cvar_GetValue(Com_Parse(inPtr));
				while (*(*inPtr)) {
					if (!strncmp((*inPtr), "#endunroll", 10)) {
						(*inPtr) += 10;
						break;
					}
					buffer[subLength++] = *(*inPtr)++;
					if (subLength >= SHADER_BUF_SIZE)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
				}
				if (out) {
					for (int j = 0; j < z; j++) {
						for (int l = 0; l < subLength; l++) {
							if (buffer[l] == '$') {
								byte insertedLen = (j / 10) + 1;
								if (!Com_sprintf(out, (size_t)*remainingOutChars, "%d", j))
									Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
								out += insertedLen;
								(*remainingOutChars) -= insertedLen;
							} else {
								if (*remainingOutChars <= 0)
									Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
								*out++ = buffer[l];
								(*remainingOutChars)--;
							}
						}
					}
				}
				Mem_Free(buffer);
			} else if (!strncmp((*inPtr), "replace", 7)) {
				int r = 0;
				(*inPtr) += 8;
				r = Cvar_GetValue(Com_Parse(inPtr));
				if (out) {
					byte insertedLen = 0;
					if (!Com_sprintf(out, (size_t)*remainingOutChars, "%d", r))
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					insertedLen = (r / 10) + 1;
					out += insertedLen;
					(*remainingOutChars) -= insertedLen;
				}
			} else {
				/* general case is to copy so long as the buffer has room */
				if (out) {
					if (*remainingOutChars <= 0)
						Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
					*out++ = '#';
					(*remainingOutChars)--;
				}
			}
		} else {
			/* general case is to copy so long as the buffer has room */
			if (out) {
				if (*remainingOutChars <= 0)
					Com_Error(ERR_FATAL, "R_PreprocessShaderR: Overflow in shader loading '%s'", name);
				*out++ = *(*inPtr);
				(*remainingOutChars)--;
			}
			(*inPtr)++;
		}
	}
	/* Return the number of characters added to the buffer.*/
	return (INITIAL_REMAINING_OUT_CHARS - *remainingOutChars);
}
示例#30
0
文件: gl_model.c 项目: mattx86/myq2
/*
==================
Mod_ForName

Loads in a model for the given name
==================
*/
model_t *Mod_ForName (char *name, qboolean crash)
{
	model_t	*mod;
	unsigned *buf;
	int		i;
	
	if (!name[0])
		VID_Printf (ERR_DROP, "Mod_ForName: NULL name");
		
	//
	// inline models are grabbed only from worldmodel
	//
	if (name[0] == '*')
	{
		i = atoi(name+1);
		if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
			VID_Printf (ERR_DROP, "bad inline model number");
		return &mod_inline[i];
	}

	//
	// search the currently loaded models
	//
	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
	{
		if (!mod->name[0])
			continue;
		if (!strcmp (mod->name, name) )
			return mod;
	}
	
	//
	// find a free model slot spot
	//
	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
	{
		if (!mod->name[0])
			break;	// free spot
	}
	if (i == mod_numknown)
	{
		if (mod_numknown == MAX_MOD_KNOWN)
			VID_Printf (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
		mod_numknown++;
	}
	strcpy (mod->name, name);
	
	//
	// load the file
	//
	modfilelen = FS_LoadFile (mod->name, &buf);
	if (!buf)
	{
		if (crash)
			VID_Printf (ERR_DROP, "Mod_NumForName: %s not found", mod->name);
		memset (mod->name, 0, sizeof(mod->name));
		return NULL;
	}
	
	loadmodel = mod;

	//
	// fill it in
	//


	// call the apropriate loader
	
	switch (LittleLong(*(unsigned *)buf))
	{
	case IDALIASHEADER:
		loadmodel->extradata = Hunk_Begin (0x200000);
		Mod_LoadAliasModel (mod, buf);
		break;
		
	case IDSPRITEHEADER:
		loadmodel->extradata = Hunk_Begin (0x10000);
		Mod_LoadSpriteModel (mod, buf);
		break;
	
	case IDBSPHEADER:
		loadmodel->extradata = Hunk_Begin (0x1000000);
		Mod_LoadBrushModel (mod, buf);
		break;

	default:
		VID_Printf (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name);
		break;
	}

	loadmodel->extradatasize = Hunk_End ();

	FS_FreeFile (buf);

	return mod;
}