Ejemplo n.º 1
0
/*
================
Con_Init
================
*/
void Con_Init (void)
{
#define MAXGAMEDIRLEN	1000
	char	temp[MAXGAMEDIRLEN+1];
	char	*ch;	// JPG - added this
	int		fd, n;	// JPG - added these
    time_t  ltime;		// JPG - for console log file

	con_debuglog = COM_CheckParm("-condebug");

	if (con_debuglog)
	{
		// JPG - check for different file name
		if ((con_debuglog < com_argc - 1) && (*com_argv[con_debuglog+1] != '-') && (*com_argv[con_debuglog+1] != '+'))
		{
			if ((ch = strchr(com_argv[con_debuglog+1], '%')) && (ch[1] == 'd'))
			{
				n = 0;
				do
				{
					n = n + 1;
					dpsnprintf(logfilename, sizeof(logfilename), com_argv[con_debuglog+1], n);
					strcat(logfilename, ".log");
					dpsnprintf(temp, sizeof(temp), "%s/%s", com_gamedir, logfilename);
					fd = open(temp, O_CREAT | O_EXCL | O_WRONLY, 0666);
				}
				while (fd == -1);
				close(fd);
			}
			else
				dpsnprintf(logfilename, sizeof(logfilename), "%s.log", com_argv[con_debuglog+1]);
		}
		else
			strcpy(logfilename, "qconsole.log");

		// JPG - changed t2 to logfilename
		if (strlen (com_gamedir) < (MAXGAMEDIRLEN - strlen (logfilename)))
		{
			dpsnprintf (temp, sizeof(temp), "%s/%s", com_gamedir, logfilename); // JPG - added the '/'
			unlink (temp);
		}

		// JPG - print initial message
		Con_Printf("Log file initialized.\n");
		Con_Printf("%s/%s\n", com_gamedir, logfilename);
		time( &ltime );
		Con_Printf( "%s\n", ctime( &ltime ) );
	}

	// used by some mods
	con_text = Hunk_AllocName (CON_TEXTSIZE, "context");
	memset (con_text, ' ', CON_TEXTSIZE);

	Con_Printf ("Console initialized.\n");

	// register our commands
	Cmd_AddCommand ("clear", Con_Clear_f);
}
Ejemplo n.º 2
0
static int R_LoadSkyBox(void)
{
	int i, j, success;
	int indices[4] = {0,1,2,3};
	char name[MAX_INPUTLINE];
	unsigned char *image_buffer;
	unsigned char *temp;
	char vabuf[1024];

	R_UnloadSkyBox();

	if (!skyname[0])
		return true;

	for (j=0; j<3; j++)
	{
		success = 0;
		for (i=0; i<6; i++)
		{
			if (dpsnprintf(name, sizeof(name), "%s_%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL)))
			{
				if (dpsnprintf(name, sizeof(name), "%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL)))
				{
					if (dpsnprintf(name, sizeof(name), "env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL)))
					{
						if (dpsnprintf(name, sizeof(name), "gfx/env/%s%s", skyname, suffix[j][i].suffix) < 0 || !(image_buffer = loadimagepixelsbgra(name, false, false, false, NULL)))
							continue;
					}
				}
			}
			temp = (unsigned char *)Mem_Alloc(tempmempool, image_width*image_height*4);
			Image_CopyMux (temp, image_buffer, image_width, image_height, suffix[j][i].flipx, suffix[j][i].flipy, suffix[j][i].flipdiagonal, 4, 4, indices);
			skyboxskinframe[i] = R_SkinFrame_LoadInternalBGRA(va(vabuf, sizeof(vabuf), "skyboxside%d", i), TEXF_CLAMP | (gl_texturecompression_sky.integer ? TEXF_COMPRESS : 0), temp, image_width, image_height, vid.sRGB3D);
			Mem_Free(image_buffer);
			Mem_Free(temp);
			success++;
		}

		if (success)
			break;
	}

	if (j == 3)
		return false;

	if (developer_loading.integer)
		Con_Printf("loading skybox \"%s\"\n", name);

	return true;
}
Ejemplo n.º 3
0
const char *LHNETADDRESS_GetInterfaceName(const lhnetaddress_t *vaddress, char *ifname, size_t ifnamelength)
{
#ifndef NOSUPPORTIPV6
	lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;

	if (address && address->addresstype == LHNETADDRESSTYPE_INET6)
	{
#ifndef _WIN32

		if (if_indextoname(address->addr.in6.sin6_scope_id, ifname) == ifname)
			return ifname;

#else

		// The Win32 API doesn't have if_indextoname() until Windows Vista,
		// but luckily it just uses the interface ID as the interface name

		if (dpsnprintf(ifname, ifnamelength, "%lu", address->addr.in6.sin6_scope_id) > 0)
			return ifname;

#endif
	}
#endif

	return NULL;
}
Ejemplo n.º 4
0
/*
============
Cvar_SetValue
============
*/
void Cvar_SetValue (char *var_name, float value)
{
	char	val[32];

	dpsnprintf (val, sizeof(val), "%f",value);
	Cvar_Set (var_name, val);
}
Ejemplo n.º 5
0
void PRVM_ShortStackTrace(prvm_prog_t *prog, char *buf, size_t bufsize)
{
    mfunction_t	*f;
    int			i;
    char vabuf[1024];

    if(prog)
    {
        dpsnprintf(buf, bufsize, "(%s) ", prog->name);
    }
    else
    {
        strlcpy(buf, "<NO PROG>", bufsize);
        return;
    }

    prog->stack[prog->depth].s = prog->xstatement;
    prog->stack[prog->depth].f = prog->xfunction;
    for (i = prog->depth; i > 0; i--)
    {
        f = prog->stack[i].f;

        if(strlcat(buf,
                   f
                   ? va(vabuf, sizeof(vabuf), "%s:%s(%i) ", PRVM_GetString(prog, f->s_file), PRVM_GetString(prog, f->s_name), prog->stack[i].s - f->first_statement)
                   : "<NULL> ",
                   bufsize
                  ) >= bufsize)
            break;
    }
}
Ejemplo n.º 6
0
void CDAudio_Play (int track, qboolean looping)
{
	char buf[20];
	if (music_playlist_index.integer >= 0)
		return;
	dpsnprintf(buf, sizeof(buf), "%d", (int) track);
	CDAudio_Play_byName(buf, looping, true, 0);
}
Ejemplo n.º 7
0
// operating system specific code
static void adddirentry(stringlist_t *list, const char *path, const char *name)
{
	if (strcmp(name, ".") && strcmp(name, ".."))
	{
		char temp[MAX_OSPATH];
		dpsnprintf( temp, sizeof( temp ), "%s%s", path, name );
		stringlistappend(list, temp);
	}
}
Ejemplo n.º 8
0
static void cl_gecko_destroy_f( void ) {
	char name[MAX_QPATH];

	if (Cmd_Argc() != 2)
	{
		Con_Print("usage: gecko_destroy <name>\ndestroys a browser\n");
		return;
	}

	dpsnprintf(name, sizeof(name), CLGECKOPREFIX "%s", Cmd_Argv(1));
	CL_Gecko_DestroyBrowser( CL_Gecko_FindBrowser( name ) );
}
Ejemplo n.º 9
0
static void cl_gecko_create_f( void ) {
	char name[MAX_QPATH];

	if (Cmd_Argc() != 2)
	{
		Con_Print("usage: gecko_create <name>\npcreates a browser (full texture path " CLGECKOPREFIX "<name>)\n");
		return;
	}

	dpsnprintf(name, sizeof(name), CLGECKOPREFIX "%s", Cmd_Argv(1));
	CL_Gecko_CreateBrowser( name, -1 );
}
Ejemplo n.º 10
0
void listdirectory(stringlist_t *list, const char *basepath, const char *path)
{
    char fullpath[MAX_OSPATH];
    DIR *dir;
    struct dirent *ent;
    dpsnprintf(fullpath, sizeof(fullpath), "%s%s", basepath, *path ? path : "./");
    dir = opendir(fullpath);
    if (!dir)
        return;
    while ((ent = readdir(dir)))
        adddirentry(list, path, ent->d_name);
    closedir(dir);
}
Ejemplo n.º 11
0
void listdirectory(stringlist_t *list, const char *basepath, const char *path)
{
	char fullpath[MAX_OSPATH];
	DIR *dir;
	struct dirent *ent;
	dpsnprintf(fullpath, sizeof(fullpath), "%s%s", basepath, path);
#ifdef __ANDROID__
	// SDL currently does not support listing assets, so we have to emulate
	// it. We're using relative paths for assets, so that will do.
	if (basepath[0] != '/')
	{
		char listpath[MAX_OSPATH];
		qfile_t *listfile;
		dpsnprintf(listpath, sizeof(listpath), "%sls.txt", fullpath);
		char *buf = (char *) FS_SysLoadFile(listpath, tempmempool, true, NULL);
		if (!buf)
			return;
		char *p = buf;
		for (;;)
		{
			char *q = strchr(p, '\n');
			if (q == NULL)
				break;
			*q = 0;
			adddirentry(list, path, p);
			p = q + 1;
		}
		Mem_Free(buf);
		return;
	}
#endif
	dir = opendir(fullpath);
	if (!dir)
		return;

	while ((ent = readdir(dir)))
		adddirentry(list, path, ent->d_name);
	closedir(dir);
}
Ejemplo n.º 12
0
static void cl_gecko_navigate_f( void ) {
	char name[MAX_QPATH];
	const char *URI;

	if (Cmd_Argc() != 3)
	{
		Con_Print("usage: gecko_navigate <name> <URI>\nnavigates to a certain URI\n");
		return;
	}

	dpsnprintf(name, sizeof(name), CLGECKOPREFIX "%s", Cmd_Argv(1));
	URI = Cmd_Argv( 2 );
	CL_Gecko_NavigateToURI( CL_Gecko_FindBrowser( name ), URI );
}
Ejemplo n.º 13
0
static void gl_gecko_movecursor_f( void ) {
	char name[MAX_QPATH];
	float x, y;

	if (Cmd_Argc() != 4)
	{
		Con_Print("usage: gecko_movecursor <name> <x> <y>\nmove the cursor to a certain position\n");
		return;
	}

	dpsnprintf(name, sizeof(name), CLGECKOPREFIX "%s", Cmd_Argv(1));
	x = atof( Cmd_Argv( 2 ) );
	y = atof( Cmd_Argv( 3 ) );

	CL_Gecko_Event_CursorMove( CL_Gecko_FindBrowser( name ), x, y );
}
Ejemplo n.º 14
0
static void cl_gecko_injecttext_f( void ) {
	char name[MAX_QPATH];
	const char *text;
	clgecko_t *instance;
	const char *p;

	if (Cmd_Argc() < 3)
	{
		Con_Print("usage: gecko_injecttext <name> <text>\ninjects a certain text into the browser\n");
		return;
	}

	dpsnprintf(name, sizeof(name), CLGECKOPREFIX "%s", Cmd_Argv(1));
	instance = CL_Gecko_FindBrowser( name );
	if( !instance ) {
		Con_Printf( "cl_gecko_injecttext_f: gecko instance '%s' couldn't be found!\n", name );
		return;
	}

	text = Cmd_Argv( 2 );

	for( p = text ; *p ; p++ ) {
		unsigned key = *p;
		switch( key ) {
			case ' ':
				key = K_SPACE;
				break;
			case '\\':
				key = *++p;
				switch( key ) {
				case 'n':
					key = K_ENTER;
					break;
				case '\0':
					--p;
					key = '\\';
					break;
				}
				break;
		}

		CL_Gecko_Event_Key( instance, (keynum_t) key, CLG_BET_PRESS );
	}
}
Ejemplo n.º 15
0
static int LHNETADDRESS_Resolve(lhnetaddressnative_t *address, const char *name, int port)
{
	char port_buff [16];
	struct addrinfo hints;
	struct addrinfo* addrinf;
	int err;

	dpsnprintf (port_buff, sizeof (port_buff), "%d", port);
	port_buff[sizeof (port_buff) - 1] = '\0';

	memset(&hints, 0, sizeof (hints));
	hints.ai_family = AF_UNSPEC;
	hints.ai_socktype = SOCK_DGRAM;
	//hints.ai_flags = AI_PASSIVE;

	err = getaddrinfo(name, port_buff, &hints, &addrinf);
	if (err != 0 || addrinf == NULL)
		return 0;
	if (addrinf->ai_addr->sa_family != AF_INET6 && addrinf->ai_addr->sa_family != AF_INET)
	{
		freeaddrinfo (addrinf);
		return 0;
	}

	// great it worked
	if (addrinf->ai_addr->sa_family == AF_INET6)
	{
		address->addresstype = LHNETADDRESSTYPE_INET6;
		memcpy(&address->addr.in6, addrinf->ai_addr, sizeof(address->addr.in6));
	}
	else
	{
		address->addresstype = LHNETADDRESSTYPE_INET4;
		memcpy(&address->addr.in, addrinf->ai_addr, sizeof(address->addr.in));
	}
	address->port = port;
	
	freeaddrinfo (addrinf);
	return 1;
}
Ejemplo n.º 16
0
static qboolean CL_Gecko_Embedding_Init (void)
{
	char profile_path [MAX_OSPATH];
	OSGK_GeckoResult grc;
	OSGK_EmbeddingOptions *options;
	OSGK_ScriptObjectTemplate* dpGlobalTemplate;

	if (!osgk_dll) return false;

	if( cl_geckoembedding != NULL ) return true;

	Con_DPrintf( "CL_Gecko_Embedding_Init: setting up gecko embedding\n" );

	options = osgk_embedding_options_create();
#ifdef XULRUNNER_DIR_SUFFIX
	osgk_embedding_options_add_search_path( options, "./xulrunner-" XULRUNNER_DIR_SUFFIX "/" );
#endif
	osgk_embedding_options_add_search_path( options, "./xulrunner/" );
	dpsnprintf (profile_path, sizeof (profile_path), "%s/xulrunner_profile/", fs_gamedir);
	osgk_embedding_options_set_profile_dir( options, profile_path, 0 );
	cl_geckoembedding = osgk_embedding_create_with_options( options, &grc );
	osgk_release( options );
        	
	if( cl_geckoembedding == NULL ) {
		Con_Printf( "CL_Gecko_Embedding_Init: Couldn't retrieve gecko embedding object (%.8x)!\n", grc );
		return false;
	} 
	
	Con_DPrintf( "CL_Gecko_Embedding_Init: Embedding set up correctly\n" );

	dpGlobalTemplate = osgk_sot_create( cl_geckoembedding, dpGlobal_create, NULL, NULL );

	osgk_sot_add_function (dpGlobalTemplate, "query", 0, dpGlobal_query);

	osgk_sot_register (dpGlobalTemplate, cl_geckoembedding, "Darkplaces", 0);
	osgk_release( dpGlobalTemplate );

	return true;
}
Ejemplo n.º 17
0
/*
=====================
CL_NextDemo

Called to play the next demo in the demo loop
=====================
*/
void CL_NextDemo (void)
{
	char	str[MAX_INPUTLINE];

	if (cls.demonum == -1)
		return;		// don't play demos

	if (!cls.demos[cls.demonum][0] || cls.demonum == MAX_DEMOS)
	{
		cls.demonum = 0;
		if (!cls.demos[cls.demonum][0])
		{
			Con_Print("No demos listed with startdemos\n");
			cls.demonum = -1;
			return;
		}
	}

	dpsnprintf (str, sizeof(str), "playdemo %s\n", cls.demos[cls.demonum]);
	Cbuf_InsertText (str);
	cls.demonum++;
}
Ejemplo n.º 18
0
/*
====================
CleanURL

Returns a "cleaned up" URL for display (to strip login data)
====================
*/
static const char *CleanURL(const char *url, char *urlbuf, size_t urlbuflength)
{
	const char *p, *q, *r;

	// if URL is of form anything://foo-without-slash@rest, replace by anything://rest
	p = strstr(url, "://");
	if(p)
	{
		q = strchr(p + 3, '@');
		if(q)
		{
			r = strchr(p + 3, '/');
			if(!r || q < r)
			{
				dpsnprintf(urlbuf, urlbuflength, "%.*s%s", (int)(p - url + 3), url, q + 1);
				return urlbuf;
			}
		}
	}

	return url;
}
Ejemplo n.º 19
0
/*
====================
Curl_SendRequirements

Makes the current host_clients download all files he needs.
This is done by sending him the following console commands:

	curl --clear_autodownload
	curl --pak --for maps/pushmoddm1.bsp --forthismap http://where/this/darn/map/is/pushmoddm1.pk3
	curl --finish_autodownload
====================
*/
static qboolean Curl_SendRequirement(const char *filename, qboolean foundone, char *sendbuffer, size_t sendbuffer_len)
{
	const char *p;
	const char *thispack = FS_WhichPack(filename);
	const char *packurl;

	if(!thispack)
		return false;

	p = strrchr(thispack, '/');
	if(p)
		thispack = p + 1;

	packurl = Curl_FindPackURL(thispack);

	if(packurl && *packurl && strcmp(packurl, "-"))
	{
		if(!foundone)
			strlcat(sendbuffer, "curl --clear_autodownload\n", sendbuffer_len);

		strlcat(sendbuffer, "curl --pak --forthismap --as ", sendbuffer_len);
		strlcat(sendbuffer, thispack, sendbuffer_len);
		if(sv_curl_maxspeed.value > 0)
			dpsnprintf(sendbuffer + strlen(sendbuffer), sendbuffer_len - strlen(sendbuffer), " --maxspeed=%.1f", sv_curl_maxspeed.value);
		strlcat(sendbuffer, " --for ", sendbuffer_len);
		strlcat(sendbuffer, filename, sendbuffer_len);
		strlcat(sendbuffer, " ", sendbuffer_len);
		strlcat(sendbuffer, packurl, sendbuffer_len);
		strlcat(sendbuffer, thispack, sendbuffer_len);
		strlcat(sendbuffer, "\n", sendbuffer_len);

		return true;
	}

	return false;
}
Ejemplo n.º 20
0
/*
====================
Curl_Begin

Starts a download of a given URL to the file name portion of this URL (or name
if given) in the "dlcache/" folder.
====================
*/
static qboolean Curl_Begin(const char *URL, const char *extraheaders, double maxspeed, const char *name, qboolean ispak, qboolean forthismap, const char *post_content_type, const unsigned char *postbuf, size_t postbufsize, unsigned char *buf, size_t bufsize, curl_callback_t callback, void *cbdata)
{
	if(!curl_dll)
	{
		return false;
	}
	else
	{
		char fn[MAX_OSPATH];
		char urlbuf[1024];
		const char *p, *q;
		size_t length;
		downloadinfo *di;

		// if URL is protocol:///* or protocol://:port/*, insert the IP of the current server
		p = strchr(URL, ':');
		if(p)
		{
			if(!strncmp(p, ":///", 4) || !strncmp(p, "://:", 4))
			{
				char addressstring[128];
				*addressstring = 0;
				InfoString_GetValue(cls.userinfo, "*ip", addressstring, sizeof(addressstring));
				q = strchr(addressstring, ':');
				if(!q)
					q = addressstring + strlen(addressstring);
				if(*addressstring)
				{
					dpsnprintf(urlbuf, sizeof(urlbuf), "%.*s://%.*s%s", (int) (p - URL), URL, (int) (q - addressstring), addressstring, URL + (p - URL) + 3);
					URL = urlbuf;
				}
			}
		}

		// Note: This extraction of the file name portion is NOT entirely correct.
		//
		// It does the following:
		//
		//   http://host/some/script.cgi/SomeFile.pk3?uid=ABCDE -> SomeFile.pk3
		//   http://host/some/script.php?uid=ABCDE&file=/SomeFile.pk3 -> SomeFile.pk3
		//   http://host/some/script.php?uid=ABCDE&file=SomeFile.pk3 -> script.php
		//
		// However, I'd like to keep this "buggy" behavior so that PHP script
		// authors can write download scripts without having to enable
		// AcceptPathInfo on Apache. They just have to ensure that their script
		// can be called with such a "fake" path name like
		// http://host/some/script.php?uid=ABCDE&file=/SomeFile.pk3
		//
		// By the way, such PHP scripts should either send the file or a
		// "Location:" redirect; PHP code example:
		//
		//   header("Location: http://www.example.com/");
		//
		// By the way, this will set User-Agent to something like
		// "Nexuiz build 22:27:55 Mar 17 2006" (engineversion) and Referer to
		// dp://serverhost:serverport/ so you can filter on this; an example
		// httpd log file line might be:
		//
		//   141.2.16.3 - - [17/Mar/2006:22:32:43 +0100] "GET /maps/tznex07.pk3 HTTP/1.1" 200 1077455 "dp://141.2.16.7:26000/" "Nexuiz Linux 22:07:43 Mar 17 2006"

		if(!name)
			name = CleanURL(URL);

		if(!buf)
		{
			p = strrchr(name, '/');
			p = p ? (p+1) : name;
			q = strchr(p, '?');
			length = q ? (size_t)(q - p) : strlen(p);
			dpsnprintf(fn, sizeof(fn), "dlcache/%.*s", (int)length, p);

			name = fn; // make it point back

			// already downloading the file?
			{
				downloadinfo *di = Curl_Find(fn);
				if(di)
				{
					Con_Printf("Can't download %s, already getting it from %s!\n", fn, CleanURL(di->url));

					// however, if it was not for this map yet...
					if(forthismap && !di->forthismap)
					{
						di->forthismap = true;
						// this "fakes" a download attempt so the client will wait for
						// the download to finish and then reconnect
						++numdownloads_added;
					}

					return false;
				}
			}

			if(ispak && FS_FileExists(fn))
			{
				qboolean already_loaded;
				if(FS_AddPack(fn, &already_loaded, true))
				{
					Con_DPrintf("%s already exists, not downloading!\n", fn);
					if(already_loaded)
						Con_DPrintf("(pak was already loaded)\n");
					else
					{
						if(forthismap)
						{
							++numdownloads_added;
							++numdownloads_success;
						}
					}

					return false;
				}
				else
				{
					qfile_t *f = FS_OpenRealFile(fn, "rb", false);
					if(f)
					{
						char buf[4] = {0};
						FS_Read(f, buf, sizeof(buf)); // no "-1", I will use memcmp

						if(memcmp(buf, "PK\x03\x04", 4) && memcmp(buf, "PACK", 4))
						{
							Con_DPrintf("Detected non-PAK %s, clearing and NOT resuming.\n", fn);
							FS_Close(f);
							f = FS_OpenRealFile(fn, "wb", false);
							if(f)
								FS_Close(f);
						}
						else
						{
							// OK
							FS_Close(f);
						}
					}
				}
			}
		}

		// if we get here, we actually want to download... so first verify the
		// URL scheme (so one can't read local files using file://)
		if(strncmp(URL, "http://", 7) && strncmp(URL, "ftp://", 6) && strncmp(URL, "https://", 8))
		{
			Con_Printf("Curl_Begin(\"%s\"): nasty URL scheme rejected\n", URL);
			return false;
		}

		if(forthismap)
			++numdownloads_added;
		di = (downloadinfo *) Z_Malloc(sizeof(*di));
		strlcpy(di->filename, name, sizeof(di->filename));
		strlcpy(di->url, URL, sizeof(di->url));
		dpsnprintf(di->referer, sizeof(di->referer), "dp://%s/", cls.netcon ? cls.netcon->address : "notconnected.invalid");
		di->forthismap = forthismap;
		di->stream = NULL;
		di->startpos = 0;
		di->curle = NULL;
		di->started = false;
		di->ispak = (ispak && !buf);
		di->maxspeed = maxspeed;
		di->bytes_received = 0;
		di->bytes_received_curl = 0;
		di->bytes_sent_curl = 0;
		di->extraheaders = extraheaders;
		di->next = downloads;
		di->prev = NULL;
		if(di->next)
			di->next->prev = di;

		di->buffer = buf;
		di->buffersize = bufsize;
		if(callback == NULL)
		{
			di->callback = curl_default_callback;
			di->callback_data = di;
		}
		else
		{
			di->callback = callback;
			di->callback_data = cbdata;
		}

		if(post_content_type)
		{
			di->post_content_type = post_content_type;
			di->postbuf = postbuf;
			di->postbufsize = postbufsize;
		}
		else
		{
			di->post_content_type = NULL;
			di->postbuf = NULL;
			di->postbufsize = 0;
		}

		downloads = di;
		return true;
	}
}
Ejemplo n.º 21
0
/*
====================
Curl_Curl_f

implements the "curl" console command

curl --info
curl --cancel
curl --cancel filename
curl url

For internal use:

curl [--pak] [--forthismap] [--for filename filename...] url
	--pak: after downloading, load the package into the virtual file system
	--for filename...: only download of at least one of the named files is missing
	--forthismap: don't reconnect on failure

curl --clear_autodownload
	clears the download success/failure counters

curl --finish_autodownload
	if at least one download has been started, disconnect and drop to the menu
	once the last download completes successfully, reconnect to the current server
====================
*/
void Curl_Curl_f(void)
{
	double maxspeed = 0;
	int i;
	int end;
	qboolean pak = false;
	qboolean forthismap = false;
	const char *url;
	const char *name = 0;

	if(!curl_dll)
	{
		Con_Print("libcurl DLL not found, this command is inactive.\n");
		return;
	}

	if(!cl_curl_enabled.integer)
	{
		Con_Print("curl support not enabled. Set cl_curl_enabled to 1 to enable.\n");
		return;
	}

	if(Cmd_Argc() < 2)
	{
		Con_Print("usage:\ncurl --info, curl --cancel [filename], curl url\n");
		return;
	}

	url = Cmd_Argv(Cmd_Argc() - 1);
	end = Cmd_Argc();

	for(i = 1; i != end; ++i)
	{
		const char *a = Cmd_Argv(i);
		if(!strcmp(a, "--info"))
		{
			Curl_Info_f();
			return;
		}
		else if(!strcmp(a, "--cancel"))
		{
			if(i == end - 1) // last argument
				Curl_CancelAll();
			else
			{
				downloadinfo *di = Curl_Find(url);
				if(di)
					Curl_EndDownload(di, CURL_DOWNLOAD_ABORTED, CURLE_OK);
				else
					Con_Print("download not found\n");
			}
			return;
		}
		else if(!strcmp(a, "--pak"))
		{
			pak = true;
		}
		else if(!strcmp(a, "--for")) // must be last option
		{
			for(i = i + 1; i != end - 1; ++i)
			{
				if(!FS_FileExists(Cmd_Argv(i)))
					goto needthefile; // why can't I have a "double break"?
			}
			// if we get here, we have all the files...
			return;
		}
		else if(!strcmp(a, "--forthismap"))
		{
			forthismap = true;
		}
		else if(!strcmp(a, "--as"))
		{
			if(i < end - 1)
			{
				++i;
				name = Cmd_Argv(i);
			}
		}
		else if(!strcmp(a, "--clear_autodownload"))
		{
			// mark all running downloads as "not for this map", so if they
			// fail, it does not matter
			Curl_Clear_forthismap();
			return;
		}
		else if(!strcmp(a, "--finish_autodownload"))
		{
			if(numdownloads_added)
			{
				char donecommand[256];
				if(cls.netcon)
				{
					if(cl.loadbegun) // curling won't inhibit loading the map any more when at this stage, so bail out and force a reconnect
					{
						dpsnprintf(donecommand, sizeof(donecommand), "connect %s", cls.netcon->address);
						Curl_CommandWhenDone(donecommand);
						noclear = TRUE;
						CL_Disconnect();
						noclear = FALSE;
						Curl_CheckCommandWhenDone();
					}
					else
						Curl_Register_predownload();
				}
			}
			return;
		}
		else if(!strncmp(a, "--maxspeed=", 11))
		{
			maxspeed = atof(a + 11);
		}
		else if(*a == '-')
		{
			Con_Printf("curl: invalid option %s\n", a);
			// but we ignore the option
		}
	}

needthefile:
	Curl_Begin_ToFile(url, maxspeed, name, pak, forthismap);
}
Ejemplo n.º 22
0
/*
====================
Curl_GetDownloadInfo

returns an array of Curl_downloadinfo_t structs for usage by GUIs.
The number of elements in the array is returned in int *nDownloads.
const char **additional_info may be set to a string of additional user
information, or to NULL if no such display shall occur. The returned
array must be freed later using Z_Free.
====================
*/
Curl_downloadinfo_t *Curl_GetDownloadInfo(int *nDownloads, const char **additional_info)
{
	int i;
	downloadinfo *di;
	Curl_downloadinfo_t *downinfo;
	static char addinfo[128];

	if(!curl_dll)
	{
		*nDownloads = 0;
		if(additional_info)
			*additional_info = NULL;
		return NULL;
	}

	i = 0;
	for(di = downloads; di; di = di->next)
		++i;

	downinfo = (Curl_downloadinfo_t *) Z_Malloc(sizeof(*downinfo) * i);
	i = 0;
	for(di = downloads; di; di = di->next)
	{
		// do not show infobars for background downloads
		if(developer.integer <= 0)
			if(di->buffer)
				continue;
		strlcpy(downinfo[i].filename, di->filename, sizeof(downinfo[i].filename));
		if(di->curle)
		{
			downinfo[i].progress = Curl_GetDownloadAmount(di);
			downinfo[i].speed = Curl_GetDownloadSpeed(di);
			downinfo[i].queued = false;
		}
		else
		{
			downinfo[i].queued = true;
		}
		++i;
	}

	if(additional_info)
	{
		// TODO: can I clear command_when_done as soon as the first download fails?
		if(*command_when_done && !numdownloads_fail && numdownloads_added)
		{
			if(!strncmp(command_when_done, "connect ", 8))
				dpsnprintf(addinfo, sizeof(addinfo), "(will join %s when done)", command_when_done + 8);
			else if(!strcmp(command_when_done, "cl_begindownloads"))
				dpsnprintf(addinfo, sizeof(addinfo), "(will enter the game when done)");
			else
				dpsnprintf(addinfo, sizeof(addinfo), "(will do '%s' when done)", command_when_done);
			*additional_info = addinfo;
		}
		else
			*additional_info = NULL;
	}

	*nDownloads = i;
	return downinfo;
}
Ejemplo n.º 23
0
/*
====================
Host_Init
====================
*/
static void Host_Init (void)
{
	int i;
	const char* os;
	char vabuf[1024];

	if (COM_CheckParm("-profilegameonly"))
		Sys_AllowProfiling(false);

	// LordHavoc: quake never seeded the random number generator before... heh
	if (COM_CheckParm("-benchmark"))
		srand(0); // predictable random sequence for -benchmark
	else
		srand((unsigned int)time(NULL));

	// FIXME: this is evil, but possibly temporary
	// LordHavoc: doesn't seem very temporary...
	// LordHavoc: made this a saved cvar
// COMMANDLINEOPTION: Console: -developer enables warnings and other notices (RECOMMENDED for mod developers)
	if (COM_CheckParm("-developer"))
	{
		developer.value = developer.integer = 1;
		developer.string = "1";
	}

	if (COM_CheckParm("-developer2") || COM_CheckParm("-developer3"))
	{
		developer.value = developer.integer = 1;
		developer.string = "1";
		developer_extra.value = developer_extra.integer = 1;
		developer_extra.string = "1";
		developer_insane.value = developer_insane.integer = 1;
		developer_insane.string = "1";
		developer_memory.value = developer_memory.integer = 1;
		developer_memory.string = "1";
		developer_memorydebug.value = developer_memorydebug.integer = 1;
		developer_memorydebug.string = "1";
	}

	if (COM_CheckParm("-developer3"))
	{
		gl_paranoid.integer = 1;gl_paranoid.string = "1";
		gl_printcheckerror.integer = 1;gl_printcheckerror.string = "1";
	}

// COMMANDLINEOPTION: Console: -nostdout disables text output to the terminal the game was launched from
	if (COM_CheckParm("-nostdout"))
		sys_nostdout = 1;

	// used by everything
	Memory_Init();

	// initialize console command/cvar/alias/command execution systems
	Cmd_Init();

	// initialize memory subsystem cvars/commands
	Memory_Init_Commands();

	// initialize console and logging and its cvars/commands
	Con_Init();

	// initialize various cvars that could not be initialized earlier
	u8_Init();
	Curl_Init_Commands();
	Cmd_Init_Commands();
	Sys_Init_Commands();
	COM_Init_Commands();
	FS_Init_Commands();

	// initialize console window (only used by sys_win.c)
	Sys_InitConsole();

	// initialize the self-pack (must be before COM_InitGameType as it may add command line options)
	FS_Init_SelfPack();

	// detect gamemode from commandline options or executable name
	COM_InitGameType();

	// construct a version string for the corner of the console
	os = DP_OS_NAME;
	dpsnprintf (engineversion, sizeof (engineversion), "%s %s %s", gamename, os, buildstring);
	Con_Printf("%s\n", engineversion);

	// initialize process nice level
	Sys_InitProcessNice();

	// initialize ixtable
	Mathlib_Init();

	// initialize filesystem (including fs_basedir, fs_gamedir, -game, scr_screenshot_name)
	FS_Init();

	// register the cvars for session locking
	Host_InitSession();

	// must be after FS_Init
	Crypto_Init();
	Crypto_Init_Commands();

	NetConn_Init();
	Curl_Init();
	//PR_Init();
	//PR_Cmd_Init();
	PRVM_Init();
	Mod_Init();
	World_Init();
	SV_Init();
	V_Init(); // some cvars needed by server player physics (cl_rollangle etc)
	Host_InitCommands();
	Host_InitLocal();
	Host_ServerOptions();

	Thread_Init();

	if (cls.state == ca_dedicated)
		Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server (or disconnect all clients if running a server)");
	else
	{
		Con_DPrintf("Initializing client\n");

		R_Modules_Init();
		Palette_Init();
#ifdef CONFIG_MENU
		MR_Init_Commands();
#endif
		VID_Shared_Init();
		VID_Init();
		Render_Init();
		S_Init();
		CDAudio_Init();
		Key_Init();
		CL_Init();
	}

	// save off current state of aliases, commands and cvars for later restore if FS_GameDir_f is called
	// NOTE: menu commands are freed by Cmd_RestoreInitState
	Cmd_SaveInitState();

	// FIXME: put this into some neat design, but the menu should be allowed to crash
	// without crashing the whole game, so this should just be a short-time solution

	// here comes the not so critical stuff
	if (setjmp(host_abortframe)) {
		return;
	}

	Host_AddConfigText();
	Cbuf_Execute();

	// if stuffcmds wasn't run, then quake.rc is probably missing, use default
	if (!host_stuffcmdsrun)
	{
		Cbuf_AddText("exec default.cfg\nexec " CONFIGFILENAME "\nexec autoexec.cfg\nstuffcmds\n");
		Cbuf_Execute();
	}

	// put up the loading image so the user doesn't stare at a black screen...
	SCR_BeginLoadingPlaque(true);

#ifdef CONFIG_MENU
	if (cls.state != ca_dedicated)
	{
		MR_Init();
	}
#endif

	// check for special benchmark mode
// COMMANDLINEOPTION: Client: -benchmark <demoname> runs a timedemo and quits, results of any timedemo can be found in gamedir/benchmark.log (for example id1/benchmark.log)
	i = COM_CheckParm("-benchmark");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "timedemo %s\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

	// check for special demo mode
// COMMANDLINEOPTION: Client: -demo <demoname> runs a playdemo and quits
	i = COM_CheckParm("-demo");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

// COMMANDLINEOPTION: Client: -capturedemo <demoname> captures a playdemo and quits
	i = COM_CheckParm("-capturedemo");
	if (i && i + 1 < com_argc)
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText(va(vabuf, sizeof(vabuf), "playdemo %s\ncl_capturevideo 1\n", com_argv[i + 1]));
		Cbuf_Execute();
	}

	if (cls.state == ca_dedicated || COM_CheckParm("-listen"))
	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
		Cbuf_AddText("startmap_dm\n");
		Cbuf_Execute();
	}

	if (!sv.active && !cls.demoplayback && !cls.connect_trying)
	{
#ifdef CONFIG_MENU
		Cbuf_AddText("togglemenu 1\n");
#endif
		Cbuf_Execute();
	}

	Con_DPrint("========Initialized=========\n");

	//Host_StartVideo();

	if (cls.state != ca_dedicated)
		SV_StartThread();
}
Ejemplo n.º 24
0
int LHNETADDRESS_ToString(const lhnetaddress_t *vaddress, char *string, int stringbuffersize, int includeport)
{
	lhnetaddressnative_t *address = (lhnetaddressnative_t *)vaddress;
	const unsigned char *a;
	if (!address || !string || stringbuffersize < 1)
		return 0;
	*string = 0;
	switch(address->addresstype)
	{
	default:
		break;
	case LHNETADDRESSTYPE_LOOP:
		if (includeport)
		{
			if (stringbuffersize >= 12)
			{
				dpsnprintf(string, stringbuffersize, "local:%d", address->port);
				return 1;
			}
		}
		else
		{
			if (stringbuffersize >= 6)
			{
				memcpy(string, "local", 6);
				return 1;
			}
		}
		break;
	case LHNETADDRESSTYPE_INET4:
		a = (const unsigned char *)(&address->addr.in.sin_addr);
		if (includeport)
		{
			if (stringbuffersize >= 22)
			{
				dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d:%d", a[0], a[1], a[2], a[3], address->port);
				return 1;
			}
		}
		else
		{
			if (stringbuffersize >= 16)
			{
				dpsnprintf(string, stringbuffersize, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
				return 1;
			}
		}
		break;
#ifndef NOSUPPORTIPV6
	case LHNETADDRESSTYPE_INET6:
		a = (const unsigned char *)(&address->addr.in6.sin6_addr);
		if (includeport)
		{
			if (stringbuffersize >= 88)
			{
				dpsnprintf(string, stringbuffersize, "[%x:%x:%x:%x:%x:%x:%x:%x]:%d", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15], address->port);
				return 1;
			}
		}
		else
		{
			if (stringbuffersize >= 80)
			{
				dpsnprintf(string, stringbuffersize, "%x:%x:%x:%x:%x:%x:%x:%x", a[0] * 256 + a[1], a[2] * 256 + a[3], a[4] * 256 + a[5], a[6] * 256 + a[7], a[8] * 256 + a[9], a[10] * 256 + a[11], a[12] * 256 + a[13], a[14] * 256 + a[15]);
				return 1;
			}
		}
		break;
#endif
	}
	return 0;
}
Ejemplo n.º 25
0
void CDAudio_Play_byName (const char *trackname, qboolean looping, qboolean tryreal, float startposition)
{
	unsigned int track;
	sfx_t* sfx;
	char filename[MAX_QPATH];

	Host_StartVideo();

	if (!enabled)
		return;

	if(tryreal && strspn(trackname, "0123456789") == strlen(trackname))
	{
		track = (unsigned char) atoi(trackname);
#ifdef MAXTRACKS
		if(track > 0 && track < MAXTRACKS)
			if(*remap[track])
			{
				if(strspn(remap[track], "0123456789") == strlen(remap[track]))
				{
					trackname = remap[track];
				}
				else
				{
					// ignore remappings to fake tracks if we're going to play a real track
					switch(cdaudio.integer)
					{
						case 0: // we never access CD
						case 1: // we have a replacement
							trackname = remap[track];
							break;
						case 2: // we only use fake track replacement if CD track is invalid
							CDAudio_GetAudioDiskInfo();
							if(!cdValid || track > maxTrack)
								trackname = remap[track];
							break;
						case 3: // we always play from CD - ignore this remapping then
						case 4: // we randomize anyway
							break;
					}
				}
			}
#endif
	}

	if(tryreal && strspn(trackname, "0123456789") == strlen(trackname))
	{
		track = (unsigned char) atoi(trackname);
		if (track < 1)
		{
			Con_DPrintf("CDAudio: Bad track number %u.\n", track);
			return;
		}
	}
	else
		track = 0;

	// div0: I assume this code was intentionally there. Maybe turn it into a cvar?
	if (cdPlaying && cdPlayTrack == track && faketrack == -1)
		return;
	CDAudio_Stop ();

	if(track >= 1)
	{
		if(cdaudio.integer == 3) // only play real CD tracks at all
		{
			if(CDAudio_Play_real(track, looping, true))
				goto success;
			return;
		}

		if(cdaudio.integer == 2) // prefer real CD track over fake
		{
			if(CDAudio_Play_real(track, looping, false))
				goto success;
		}
	}

	if(cdaudio.integer == 4) // only play real CD tracks, EVEN instead of fake tracks!
	{
		if(CDAudio_Play_real(track, looping, false))
			goto success;
		
		if(cdValid && maxTrack > 0)
		{
			track = 1 + (rand() % maxTrack);
			if(CDAudio_Play_real(track, looping, true))
				goto success;
		}
		else
		{
			Con_DPrint ("No CD in player.\n");
		}
		return;
	}

	// Try playing a fake track (sound file) first
	if(track >= 1)
	{
		                              dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%03u.wav", track);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%03u.ogg", track);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/track%03u.ogg", track);// added by motorsep
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/cdtracks/track%03u.ogg", track);// added by motorsep
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%02u.wav", track);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/track%02u.ogg", track);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/track%02u.ogg", track);// added by motorsep
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/cdtracks/track%02u.ogg", track);// added by motorsep
	}
	else
	{
		                              dpsnprintf(filename, sizeof(filename), "%s", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "%s.wav", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "%s.ogg", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/%s", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/%s.wav", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/%s.ogg", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/%s", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/%s.wav", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "sound/cdtracks/%s.ogg", trackname);
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/%s.ogg", trackname); // added by motorsep
		if (!FS_FileExists(filename)) dpsnprintf(filename, sizeof(filename), "music/cdtracks/%s.ogg", trackname); // added by motorsep
	}
	if (FS_FileExists(filename) && (sfx = S_PrecacheSound (filename, false, true)))
	{
		faketrack = S_StartSound_StartPosition (-1, 0, sfx, vec3_origin, cdvolume, 0, startposition);
		if (faketrack != -1)
		{
			if (looping)
				S_SetChannelFlag (faketrack, CHANNELFLAG_FORCELOOP, true);
			S_SetChannelFlag (faketrack, CHANNELFLAG_FULLVOLUME, true);
			S_SetChannelFlag (faketrack, CHANNELFLAG_LOCALSOUND, true); // not pausable
			if(track >= 1)
			{
				if(cdaudio.integer != 0) // we don't need these messages if only fake tracks can be played anyway
					Con_DPrintf ("Fake CD track %u playing...\n", track);
			}
			else
				Con_DPrintf ("BGM track %s playing...\n", trackname);
		}
	}

	// If we can't play a fake CD track, try the real one
	if (faketrack == -1)
	{
		if(cdaudio.integer == 0 || track < 1)
		{
			Con_Print("Could not load BGM track.\n");
			return;
		}
		else
		{
			if(!CDAudio_Play_real(track, looping, true))
				return;
		}
	}

success:
	cdPlayLooping = looping;
	cdPlayTrack = track;
	cdPlaying = true;

	if (cdvolume == 0.0 || bgmvolume.value == 0)
		CDAudio_Pause ();
}
Ejemplo n.º 26
0
static void Mod_Sprite_SharedSetup(const unsigned char *datapointer, int version, const unsigned int *palette, qboolean additive)
{
	int					i, j, groupframes, realframes, x, y, origin[2], width, height;
	qboolean			fullbright;
	dspriteframetype_t	*pinframetype;
	dspriteframe_t		*pinframe;
	dspritegroup_t		*pingroup;
	dspriteinterval_t	*pinintervals;
	skinframe_t			*skinframe;
	float				modelradius, interval;
	char				name[MAX_QPATH], fogname[MAX_QPATH];
	const void			*startframes;
	int                 texflags = (r_mipsprites.integer ? TEXF_MIPMAP : 0) | ((gl_texturecompression.integer && gl_texturecompression_sprites.integer) ? TEXF_COMPRESS : 0) | TEXF_ISSPRITE | TEXF_PICMIP | TEXF_ALPHA | TEXF_CLAMP;
	modelradius = 0;

	if (loadmodel->numframes < 1)
		Host_Error ("Mod_Sprite_SharedSetup: Invalid # of frames: %d", loadmodel->numframes);

	// LordHavoc: hack to allow sprites to be non-fullbright
	fullbright = true;
	for (i = 0;i < MAX_QPATH && loadmodel->name[i];i++)
		if (loadmodel->name[i] == '!')
			fullbright = false;

//
// load the frames
//
	startframes = datapointer;
	realframes = 0;
	for (i = 0;i < loadmodel->numframes;i++)
	{
		pinframetype = (dspriteframetype_t *)datapointer;
		datapointer += sizeof(dspriteframetype_t);

		if (LittleLong (pinframetype->type) == SPR_SINGLE)
			groupframes = 1;
		else
		{
			pingroup = (dspritegroup_t *)datapointer;
			datapointer += sizeof(dspritegroup_t);

			groupframes = LittleLong(pingroup->numframes);

			datapointer += sizeof(dspriteinterval_t) * groupframes;
		}

		for (j = 0;j < groupframes;j++)
		{
			pinframe = (dspriteframe_t *)datapointer;
			if (version == SPRITE32_VERSION)
				datapointer += sizeof(dspriteframe_t) + LittleLong(pinframe->width) * LittleLong(pinframe->height) * 4;
			else //if (version == SPRITE_VERSION || version == SPRITEHL_VERSION)
				datapointer += sizeof(dspriteframe_t) + LittleLong(pinframe->width) * LittleLong(pinframe->height);
		}
		realframes += groupframes;
	}

	loadmodel->animscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes);
	loadmodel->sprite.sprdata_frames = (mspriteframe_t *)Mem_Alloc(loadmodel->mempool, sizeof(mspriteframe_t) * realframes);
	loadmodel->num_textures = realframes;
	loadmodel->num_texturesperskin = 1;
	loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, sizeof(texture_t) * loadmodel->num_textures);

	datapointer = (unsigned char *)startframes;
	realframes = 0;
	for (i = 0;i < loadmodel->numframes;i++)
	{
		pinframetype = (dspriteframetype_t *)datapointer;
		datapointer += sizeof(dspriteframetype_t);

		if (LittleLong (pinframetype->type) == SPR_SINGLE)
		{
			groupframes = 1;
			interval = 0.1f;
		}
		else
		{
			pingroup = (dspritegroup_t *)datapointer;
			datapointer += sizeof(dspritegroup_t);

			groupframes = LittleLong(pingroup->numframes);

			pinintervals = (dspriteinterval_t *)datapointer;
			datapointer += sizeof(dspriteinterval_t) * groupframes;

			interval = LittleFloat(pinintervals[0].interval);
			if (interval < 0.01f)
				Host_Error("Mod_Sprite_SharedSetup: invalid interval");
		}

		dpsnprintf(loadmodel->animscenes[i].name, sizeof(loadmodel->animscenes[i].name), "frame %i", i);
		loadmodel->animscenes[i].firstframe = realframes;
		loadmodel->animscenes[i].framecount = groupframes;
		loadmodel->animscenes[i].framerate = 1.0f / interval;
		loadmodel->animscenes[i].loop = true;

		for (j = 0;j < groupframes;j++)
		{
			pinframe = (dspriteframe_t *)datapointer;
			datapointer += sizeof(dspriteframe_t);

			origin[0] = LittleLong (pinframe->origin[0]);
			origin[1] = LittleLong (pinframe->origin[1]);
			width = LittleLong (pinframe->width);
			height = LittleLong (pinframe->height);

			loadmodel->sprite.sprdata_frames[realframes].left = origin[0];
			loadmodel->sprite.sprdata_frames[realframes].right = origin[0] + width;
			loadmodel->sprite.sprdata_frames[realframes].up = origin[1];
			loadmodel->sprite.sprdata_frames[realframes].down = origin[1] - height;

			x = (int)max(loadmodel->sprite.sprdata_frames[realframes].left * loadmodel->sprite.sprdata_frames[realframes].left, loadmodel->sprite.sprdata_frames[realframes].right * loadmodel->sprite.sprdata_frames[realframes].right);
			y = (int)max(loadmodel->sprite.sprdata_frames[realframes].up * loadmodel->sprite.sprdata_frames[realframes].up, loadmodel->sprite.sprdata_frames[realframes].down * loadmodel->sprite.sprdata_frames[realframes].down);
			if (modelradius < x + y)
				modelradius = x + y;

			if (cls.state != ca_dedicated)
			{
				skinframe = NULL;
				// note: Nehahra's null.spr has width == 0 and height == 0
				if (width > 0 && height > 0)
				{
					if (groupframes > 1)
					{
						dpsnprintf (name, sizeof(name), "%s_%i_%i", loadmodel->name, i, j);
						dpsnprintf (fogname, sizeof(fogname), "%s_%i_%ifog", loadmodel->name, i, j);
					}
					else
					{
						dpsnprintf (name, sizeof(name), "%s_%i", loadmodel->name, i);
						dpsnprintf (fogname, sizeof(fogname), "%s_%ifog", loadmodel->name, i);
					}
					if (!(skinframe = R_SkinFrame_LoadExternal(name, texflags | TEXF_COMPRESS, false)))
					{
						unsigned char *pixels = (unsigned char *) Mem_Alloc(loadmodel->mempool, width*height*4);
						if (version == SPRITE32_VERSION)
						{
							for (x = 0;x < width*height;x++)
							{
								pixels[x*4+2] = datapointer[x*4+0];
								pixels[x*4+1] = datapointer[x*4+1];
								pixels[x*4+0] = datapointer[x*4+2];
								pixels[x*4+3] = datapointer[x*4+3];
							}
						}
						else //if (version == SPRITEHL_VERSION || version == SPRITE_VERSION)
							Image_Copy8bitBGRA(datapointer, pixels, width*height, palette ? palette : palette_bgra_transparent);
						skinframe = R_SkinFrame_LoadInternalBGRA(name, texflags, pixels, width, height, false);
						// texflags |= TEXF_COMPRESS;
						Mem_Free(pixels);
					}
				}
				if (skinframe == NULL)
					skinframe = R_SkinFrame_LoadMissing();
				Mod_SpriteSetupTexture(&loadmodel->data_textures[realframes], skinframe, fullbright, additive);
			}

			if (version == SPRITE32_VERSION)
				datapointer += width * height * 4;
			else //if (version == SPRITE_VERSION || version == SPRITEHL_VERSION)
				datapointer += width * height;
			realframes++;
		}
	}

	modelradius = sqrt(modelradius);
	for (i = 0;i < 3;i++)
	{
		loadmodel->normalmins[i] = loadmodel->yawmins[i] = loadmodel->rotatedmins[i] = -modelradius;
		loadmodel->normalmaxs[i] = loadmodel->yawmaxs[i] = loadmodel->rotatedmaxs[i] = modelradius;
	}
	loadmodel->radius = modelradius;
	loadmodel->radius2 = modelradius * modelradius;
}
Ejemplo n.º 27
0
void Mod_IDS2_Load(dp_model_t *mod, void *buffer, void *bufferend)
{
	int i, version;
	qboolean fullbright;
	const dsprite2_t *pinqsprite;
	skinframe_t *skinframe;
	float modelradius;
	int texflags = (r_mipsprites.integer ? TEXF_MIPMAP : 0) | TEXF_ISSPRITE | TEXF_PICMIP | TEXF_COMPRESS | TEXF_ALPHA | TEXF_CLAMP;

	loadmodel->modeldatatypestring = "SPR2";

	loadmodel->type = mod_sprite;

	loadmodel->DrawSky = NULL;
	loadmodel->Draw = R_Model_Sprite_Draw;
	loadmodel->DrawDepth = NULL;
	loadmodel->CompileShadowVolume = NULL;
	loadmodel->DrawShadowVolume = NULL;
	loadmodel->DrawLight = NULL;
	loadmodel->DrawAddWaterPlanes = NULL;

	pinqsprite = (dsprite2_t *)buffer;

	version = LittleLong(pinqsprite->version);
	if (version != SPRITE2_VERSION)
		Host_Error("Mod_IDS2_Load: %s has wrong version number (%i should be 2 (quake 2)", loadmodel->name, version);

	loadmodel->numframes = LittleLong (pinqsprite->numframes);
	if (loadmodel->numframes < 1)
		Host_Error ("Mod_IDS2_Load: Invalid # of frames: %d", loadmodel->numframes);
	loadmodel->sprite.sprnum_type = SPR_VP_PARALLEL;
	loadmodel->synctype = ST_SYNC;

	// LordHavoc: hack to allow sprites to be non-fullbright
	fullbright = true;
	for (i = 0;i < MAX_QPATH && loadmodel->name[i];i++)
		if (loadmodel->name[i] == '!')
			fullbright = false;

	loadmodel->animscenes = (animscene_t *)Mem_Alloc(loadmodel->mempool, sizeof(animscene_t) * loadmodel->numframes);
	loadmodel->sprite.sprdata_frames = (mspriteframe_t *)Mem_Alloc(loadmodel->mempool, sizeof(mspriteframe_t) * loadmodel->numframes);
	loadmodel->num_textures = loadmodel->numframes;
	loadmodel->num_texturesperskin = 1;
	loadmodel->data_textures = (texture_t *)Mem_Alloc(loadmodel->mempool, sizeof(texture_t) * loadmodel->num_textures);

	modelradius = 0;
	for (i = 0;i < loadmodel->numframes;i++)
	{
		int origin[2], x, y, width, height;
		const dsprite2frame_t *pinframe;
		mspriteframe_t *sprframe;

		dpsnprintf(loadmodel->animscenes[i].name, sizeof(loadmodel->animscenes[i].name), "frame %i", i);
		loadmodel->animscenes[i].firstframe = i;
		loadmodel->animscenes[i].framecount = 1;
		loadmodel->animscenes[i].framerate = 10;
		loadmodel->animscenes[i].loop = true;

		pinframe = &pinqsprite->frames[i];

		origin[0] = LittleLong (pinframe->origin_x);
		origin[1] = LittleLong (pinframe->origin_y);
		width = LittleLong (pinframe->width);
		height = LittleLong (pinframe->height);

		sprframe = &loadmodel->sprite.sprdata_frames[i];

		// note that sp2 origin[0] is positive, where as it is negative in
		// spr/spr32/hlspr
		sprframe->left = -origin[0];
		sprframe->right = -origin[0] + width;
		sprframe->up = origin[1];
		sprframe->down = origin[1] - height;

		x = (int)max(sprframe->left * sprframe->left, sprframe->right * sprframe->right);
		y = (int)max(sprframe->up * sprframe->up, sprframe->down * sprframe->down);
		if (modelradius < x + y)
			modelradius = x + y;
	}

	if (cls.state != ca_dedicated)
	{
		for (i = 0;i < loadmodel->numframes;i++)
		{
			const dsprite2frame_t *pinframe;
			pinframe = &pinqsprite->frames[i];
			if (!(skinframe = R_SkinFrame_LoadExternal(pinframe->name, texflags, false)))
			{
				Con_Printf("Mod_IDS2_Load: failed to load %s", pinframe->name);
				skinframe = R_SkinFrame_LoadMissing();
			}
			Mod_SpriteSetupTexture(&loadmodel->data_textures[i], skinframe, fullbright, false);
		}
	}

	modelradius = sqrt(modelradius);
	for (i = 0;i < 3;i++)
	{
		loadmodel->normalmins[i] = loadmodel->yawmins[i] = loadmodel->rotatedmins[i] = -modelradius;
		loadmodel->normalmaxs[i] = loadmodel->yawmaxs[i] = loadmodel->rotatedmaxs[i] = modelradius;
	}
	loadmodel->radius = modelradius;
	loadmodel->radius2 = modelradius * modelradius;

	// TODO: Note that isanimated only means whether vertices change due to
	// the animation. This may happen due to sprframe parameters changing.
	// Mere texture chanegs OTOH shouldn't require isanimated to be 1.
	loadmodel->surfmesh.isanimated = loadmodel->numframes > 1 || (loadmodel->animscenes && loadmodel->animscenes[0].framecount > 1);
}