Example #1
0
/*
======================
CL_RegisterSounds
======================
*/
void CL_RegisterSounds (void)
{
	int32_t		i;

	S_BeginRegistration ();
	CL_RegisterTEntSounds ();

	// Knightmare- 1/2/2002- ULTRA-CHEESY HACK for old demos or
	// connected to server using old protocol
	// Changed config strings require different offsets
	if ( LegacyProtocol() )
	{
		for (i=1; i < OLD_MAX_SOUNDS; i++)
		{
			if (!cl.configstrings[OLD_CS_SOUNDS+i][0])
				break;
			cl.sound_precache[i] = S_RegisterSound (cl.configstrings[OLD_CS_SOUNDS+i]);
			Sys_SendKeyEvents ();	// pump message loop
		}

	}
	else
	{
		for (i=1; i < MAX_SOUNDS; i++)
		{
			if (!cl.configstrings[CS_SOUNDS+i][0])
				break;
			cl.sound_precache[i] = S_RegisterSound (cl.configstrings[CS_SOUNDS+i]);
			Sys_SendKeyEvents ();	// pump message loop
		}
	}
	//end Knightmare
	S_EndRegistration ();
}
Example #2
0
/*
==================
CL_ParseServerData
==================
*/
void CL_ParseServerData (void)
{
	extern cvar_t	*fs_gamedirvar;
	char	*str;
	int		i;
	
	Com_DPrintf ("Serverdata packet received.\n");
//
// wipe the client_state_t struct
//
	CL_ClearState ();
	cls.state = ca_connected;

// parse protocol version number
	i = MSG_ReadLong (&net_message);
	cls.serverProtocol = i;

	// BIG HACK to let demos from release work with the 3.0x patch!!!
	// Knightmare- also allow connectivity with servers using the old protocol
//	if (Com_ServerState() && (i < PROTOCOL_VERSION) /*== 35*/)
	if ( LegacyProtocol() ) {} // do nothing
	else if (i != PROTOCOL_VERSION)
		Com_Error (ERR_DROP,"Server returned version %i, not %i", i, PROTOCOL_VERSION);

	cl.servercount = MSG_ReadLong (&net_message);
	cl.attractloop = MSG_ReadByte (&net_message);

	// game directory
	str = MSG_ReadString (&net_message);
	strncpy (cl.gamedir, str, sizeof(cl.gamedir)-1);

	// set gamedir
	if ( ( (*str && (!fs_gamedirvar->string || !*fs_gamedirvar->string || strcmp(fs_gamedirvar->string, str)))
		|| (!*str && (fs_gamedirvar->string || *fs_gamedirvar->string)) )
		&& !cl.attractloop ) // Knightmare- don't allow demos to change this
		Cvar_Set("game", str);

	// parse player entity number
	cl.playernum = MSG_ReadShort (&net_message);

	// get the full level name
	str = MSG_ReadString (&net_message);

	if (cl.playernum == -1)
	{	// playing a cinematic or showing a pic, not a level
		SCR_PlayCinematic (str);
	}
	else
	{
		// seperate the printfs so the server message can have a color
		Com_Printf("\n\n\35\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\36\37\n\n");
		con.ormask = 128;
		Com_Printf ("%c"S_COLOR_SHADOW S_COLOR_ALT"%s\n", 2, str);
		con.ormask = 0;

		// need to prep refresh at next oportunity
		cl.refresh_prepped = false;
	}
}
Example #3
0
/*
==================
CL_ParseStartSoundPacket
==================
*/
void CL_ParseStartSoundPacket(void)
{
    vec3_t  pos_v;
	float	*pos;
    int32_t 	channel, ent;
    int32_t 	sound_num;
    float 	volume;
    float 	attenuation;  
	int32_t		flags;
	float	ofs;

	flags = MSG_ReadByte (&net_message);

	// Knightmare- 12/23/2001
	// read sound indices as bytes only if playing old demos or
	// connected to server using old protocol; otherwise, read as shorts
	if ( LegacyProtocol() )
		sound_num = MSG_ReadByte (&net_message);
	else
		sound_num = MSG_ReadShort (&net_message);
	//end Knightmare

    if (flags & SND_VOLUME)
		volume = MSG_ReadByte (&net_message) / 255.0;
	else
		volume = DEFAULT_SOUND_PACKET_VOLUME;
	
    if (flags & SND_ATTENUATION)
		attenuation = MSG_ReadByte (&net_message) / 64.0;
	else
		attenuation = DEFAULT_SOUND_PACKET_ATTENUATION;	

    if (flags & SND_OFFSET)
		ofs = MSG_ReadByte (&net_message) / 1000.0;
	else
		ofs = 0;

	if (flags & SND_ENT)
	{	// entity reletive
		channel = MSG_ReadShort(&net_message); 
		ent = channel>>3;
		if (ent > MAX_EDICTS)
			Com_Error (ERR_DROP,"CL_ParseStartSoundPacket: ent = %i", ent);

		channel &= 7;
	}
Example #4
0
/*
================
CL_ParseClientinfo

Load the skin, icon, and model for a client
================
*/
void CL_ParseClientinfo (int32_t player)
{
	char			*s;
	clientinfo_t	*ci;

	// Knightmare- 1/2/2002- GROSS HACK for old demos or
	// connected to server using old protocol
	// Changed config strings require different offsets
	if ( LegacyProtocol() )
		s = cl.configstrings[player+OLD_CS_PLAYERSKINS];
	else
		s = cl.configstrings[player+CS_PLAYERSKINS];
	//end Knightmare

	ci = &cl.clientinfo[player];

	CL_LoadClientinfo (ci, s);
}
Example #5
0
void CL_SetLightstyle (int32_t i)
{
	char	*s;
	int32_t		j, k;

	// Knightmare- BIG UGLY HACK for old connected to server using old protocol
	// Changed config strings require different parsing
	if ( LegacyProtocol() )
		s = cl.configstrings[i+OLD_CS_LIGHTS];
	else
		s = cl.configstrings[i+CS_LIGHTS];

	j = strlen (s);
	if (j >= MAX_QPATH)
		Com_Error (ERR_DROP, "svc_lightstyle length=%i", j);

	cl_lightstyle[i].length = j;

	for (k=0 ; k<j ; k++)
		cl_lightstyle[i].map[k] = (float)(s[k]-'a')/(float)('m'-'a');
}
Example #6
0
/*
================
CL_ParseConfigString
================
*/
void CL_ParseConfigString (void)
{
	int32_t		i;
	char	*s;
	char	olds[MAX_QPATH];
    char	scratch[1024];

	i = MSG_ReadShort (&net_message);
	if (i < 0 || i >= MAX_CONFIGSTRINGS)
		Com_Error (ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
	s = MSG_ReadString(&net_message);

	strncpy (olds, cl.configstrings[i], sizeof(olds));
	olds[sizeof(olds) - 1] = 0;

	strcpy (cl.configstrings[i], s);

	// do something apropriate 

	// Knightmare- 1/2/2002- BIG UGLY HACK for old demos or
	// connected to server using old protocol
	// Changed config strings require different parsing
	if ( LegacyProtocol())
	{
		if (i >= OLD_CS_LIGHTS && i < OLD_CS_LIGHTS+MAX_LIGHTSTYLES)
			CL_SetLightstyle (i - OLD_CS_LIGHTS);
		else if (i == CS_CDTRACK)
		{
			if (cl.refresh_prepped)
				CL_PlayBackgroundTrack ();
		}
		else if (i >= CS_MODELS && i < CS_MODELS+OLD_MAX_MODELS)
		{
			if (cl.refresh_prepped)
			{
				cl.model_draw[i-CS_MODELS] = R_RegisterModel (cl.configstrings[i]);
				if (cl.configstrings[i][0] == '*')
					cl.model_clip[i-CS_MODELS] = CM_InlineModel (cl.configstrings[i]);
				else
					cl.model_clip[i-CS_MODELS] = NULL;
			}
		}
		else if (i >= OLD_CS_SOUNDS && i < OLD_CS_SOUNDS+OLD_MAX_SOUNDS)
		{
			if (cl.refresh_prepped)
				cl.sound_precache[i-OLD_CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]);
		}
		else if (i >= OLD_CS_IMAGES && i < OLD_CS_IMAGES+OLD_MAX_IMAGES)
		{
			if (cl.refresh_prepped)
				cl.image_precache[i-OLD_CS_IMAGES] = R_DrawFindPic (cl.configstrings[i]);
		}
		else if (i >= OLD_CS_PLAYERSKINS && i < OLD_CS_PLAYERSKINS+MAX_CLIENTS)
		{
			if (cl.refresh_prepped && strcmp(olds, s))
				CL_ParseClientinfo (i-OLD_CS_PLAYERSKINS);
        } else if (i >= OLD_CS_ITEMS && i < OLD_CS_ITEMS + MAX_ITEMS) {
            int j;
            int item = i - OLD_CS_ITEMS;
            int32_t token;
            Com_sprintf (scratch, sizeof(scratch), "use %s", cl.configstrings[i]);
            token = Q_STLookup(&key_table, scratch);
            cl.inventorykey[item] = -1;
            if (token >= 0) {
                for (j=0; j<MAX_KEYEVENTS; j++)
                {
                    if (keytokens[j] == token)
                    {
                        cl.inventorykey[item] = j;
                        break;
                    }
                }
                
            }
        }
	}
	else // new configstring offsets
	{
		if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES)
			CL_SetLightstyle (i - CS_LIGHTS);
		else if (i == CS_CDTRACK)
		{
			if (cl.refresh_prepped)
				CL_PlayBackgroundTrack ();
		}
		else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS)
		{
			if (cl.refresh_prepped)
			{
				cl.model_draw[i-CS_MODELS] = R_RegisterModel (cl.configstrings[i]);
				if (cl.configstrings[i][0] == '*')
					cl.model_clip[i-CS_MODELS] = CM_InlineModel (cl.configstrings[i]);
				else
					cl.model_clip[i-CS_MODELS] = NULL;
			}
		}
		else if (i >= CS_SOUNDS && i < CS_SOUNDS+MAX_SOUNDS) //Knightmare- was MAX_MODELS
		{
			if (cl.refresh_prepped)
				cl.sound_precache[i-CS_SOUNDS] = S_RegisterSound (cl.configstrings[i]);
		}
		else if (i >= CS_IMAGES && i < CS_IMAGES+MAX_IMAGES) //Knightmare- was MAX_MODELS
		{
			if (cl.refresh_prepped)
				cl.image_precache[i-CS_IMAGES] = R_DrawFindPic (cl.configstrings[i]);
		}
		else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS)
		{
			if (cl.refresh_prepped && strcmp(olds, s))
				CL_ParseClientinfo (i-CS_PLAYERSKINS);
        }
        else if (i >= CS_ITEMS && i < CS_ITEMS + MAX_ITEMS)
        {
            int j;
            int item = i - CS_ITEMS;
            int32_t token;
            Com_sprintf (scratch, sizeof(scratch), "use %s", cl.configstrings[i]);
            token = Q_STLookup(&key_table, scratch);
            cl.inventorykey[item] = -1;
            if (token >= 0) {
                for (j=0; j<MAX_KEYEVENTS; j++)
                {
                    if (keytokens[j] == token)
                    {
                        cl.inventorykey[item] = j;
                        break;
                    }
                }
                
            }
        }
	}
	//end Knightmare
}
Example #7
0
/*
=================
CL_RequestNextDownload
=================
*/
void CL_RequestNextDownload (void)
{
	unsigned	map_checksum;		// for detecting cheater maps
	char fn[MAX_OSPATH];
	dmdl_t *pheader;

	if (cls.state != ca_connected)
		return;

	// clear failed download list
	if (precache_check == CS_MODELS)
		CL_InitFailedDownloadList ();

	// Knightmare- BIG UGLY HACK for connected to server using old protocol
	// Changed config strings require different parsing
	if ( LegacyProtocol() )
	{	// Old download code
		if (!allow_download->value && precache_check < OLD_ENV_CNT)
			precache_check = OLD_ENV_CNT;

		//ZOID
		if (precache_check == CS_MODELS) { // confirm map
			precache_check = CS_MODELS+2; // 0 isn't used
			if (allow_download_maps->value)
				if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1]))
					return; // started a download
		}
		if (precache_check >= CS_MODELS && precache_check < CS_MODELS+OLD_MAX_MODELS) {
			if (allow_download_models->value) {
				while (precache_check < CS_MODELS+OLD_MAX_MODELS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*' ||
						cl.configstrings[precache_check][0] == '#') {
						precache_check++;
						continue;
					}
					if (precache_model_skin == 0) {
						if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check])) {
							precache_model_skin = 1;
							return; // started a download
						}
						precache_model_skin = 1;
					}

					// checking for skins in the model
					if (!precache_model) {

						FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model);
						if (!precache_model) {
							precache_model_skin = 0;
							precache_check++;
							continue; // couldn't load it
						}
						if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER) {
							// not an alias model
							FS_FreeFile(precache_model);
							precache_model = 0;
							precache_model_skin = 0;
							precache_check++;
							continue;
						}
						pheader = (dmdl_t *)precache_model;
						if (LittleLong (pheader->version) != ALIAS_VERSION) {
							precache_check++;
							precache_model_skin = 0;
							continue; // couldn't load it
						}
					}

					pheader = (dmdl_t *)precache_model;

					while (precache_model_skin - 1 < LittleLong(pheader->num_skins)) {
						if (!CL_CheckOrDownloadFile((char *)precache_model +
							LittleLong(pheader->ofs_skins) + 
							(precache_model_skin - 1)*MAX_SKINNAME)) {
							precache_model_skin++;
							return; // started a download
						}
						precache_model_skin++;
					}
					if (precache_model) { 
						FS_FreeFile(precache_model);
						precache_model = 0;
					}
					precache_model_skin = 0;
					precache_check++;
				}
			}
			precache_check = OLD_CS_SOUNDS;
		}
		if (precache_check >= OLD_CS_SOUNDS && precache_check < OLD_CS_SOUNDS+OLD_MAX_SOUNDS) { 
			if (allow_download_sounds->value) {
				if (precache_check == OLD_CS_SOUNDS)
					precache_check++; // zero is blank
				while (precache_check < OLD_CS_SOUNDS+OLD_MAX_SOUNDS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*') {
						precache_check++;
						continue;
					}
					Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_CS_IMAGES;
		}
		if (precache_check >= OLD_CS_IMAGES && precache_check < CS_IMAGES+OLD_MAX_IMAGES) {
			if (precache_check == OLD_CS_IMAGES)
				precache_check++; // zero is blank
			while (precache_check < OLD_CS_IMAGES+OLD_MAX_IMAGES &&
				cl.configstrings[precache_check][0]) {
				Com_sprintf(fn, sizeof(fn), "pics/%s.pcx", cl.configstrings[precache_check++]);
				if (!CL_CheckOrDownloadFile(fn))
					return; // started a download
			}
			precache_check = OLD_CS_PLAYERSKINS;
		}
		// skins are special, since a player has three things to download:
		// model, weapon model and skin
		// so precache_check is now *3
		if (precache_check >= OLD_CS_PLAYERSKINS && precache_check < OLD_CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
			if (allow_download_players->value)
			{
				while (precache_check < OLD_CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT)
				{
					int32_t i, n;
					char model[MAX_QPATH], skin[MAX_QPATH], *p;

					i = (precache_check - OLD_CS_PLAYERSKINS)/PLAYER_MULT;
					n = (precache_check - OLD_CS_PLAYERSKINS)%PLAYER_MULT;

					if (!cl.configstrings[OLD_CS_PLAYERSKINS+i][0]) {
						precache_check = OLD_CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
						continue;
					}

					if ((p = strchr(cl.configstrings[OLD_CS_PLAYERSKINS+i], '\\')) != NULL)
						p++;
					else
						p = cl.configstrings[OLD_CS_PLAYERSKINS+i];
					strcpy(model, p);
					p = strchr(model, '/');
					if (!p)
						p = strchr(model, '\\');
					if (p) {
						*p++ = 0;
						strcpy(skin, p);
					} else
						*skin = 0;

					switch (n) {
					case 0: // model
						Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 1;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 1: // weapon model
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 2;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 2: // weapon skin
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.pcx", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 3;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 3: // skin
						Com_sprintf(fn, sizeof(fn), "players/%s/%s.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 4;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 4: // skin_i
						Com_sprintf(fn, sizeof(fn), "players/%s/%s_i.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = OLD_CS_PLAYERSKINS + i * PLAYER_MULT + 5;
							return; // started a download
						}
						// move on to next model
						precache_check = OLD_CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
					}
				}
			}
			// precache phase completed
			precache_check = OLD_ENV_CNT;
		}

		if (precache_check == OLD_ENV_CNT) {
			precache_check = OLD_ENV_CNT + 1;

			CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum);

			if (map_checksum != atoi(cl.configstrings[CS_MAPCHECKSUM])) {
				Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n",
					map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
				return;
			}
		}

		if (precache_check > OLD_ENV_CNT && precache_check < OLD_TEXTURE_CNT) {
			if (allow_download->value && allow_download_maps->value) {
				while (precache_check < OLD_TEXTURE_CNT) {
					int32_t n = precache_check++ - OLD_ENV_CNT - 1;

					if (n & 1)
						Com_sprintf(fn, sizeof(fn), "env/%s%s.pcx", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					else
						Com_sprintf(fn, sizeof(fn), "env/%s%s.tga", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_TEXTURE_CNT;
		}

		if (precache_check == OLD_TEXTURE_CNT) {
			precache_check = OLD_TEXTURE_CNT+1;
			precache_tex = 0;
		}

		// confirm existance of .wal textures, download any that don't exist
		if (precache_check == OLD_TEXTURE_CNT+1) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value)
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					sprintf(fn, "textures/%s.wal", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
					{ // Knightmare - jump to next different texture name
					/*	char lasttexname[MAX_OSPATH];
						char nexttexname[MAX_OSPATH];

						sprintf(lasttexname, "%s", map_surfaces[precache_tex].rname);
						while ((precache_tex < numtexinfo))
						{
							sprintf(nexttexname, "%s", map_surfaces[precache_tex+1].rname);
							if (strcmp(lasttexname, nexttexname))
								break;
							precache_tex++;
						}*/
						return; // started a download
					}
				}
			}
			//precache_check = OLD_TEXTURE_CNT+999;
			precache_check = OLD_TEXTURE_CNT+2;
			precache_tex = 0;
		}

		// confirm existance of .jpg textures, try to download any that don't exist
		if (precache_check == OLD_TEXTURE_CNT+2) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value)
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.jpg", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_TEXTURE_CNT+3;
			precache_tex = 0;
		}

		// confirm existance of .tga textures, try to download any that don't exist
		if (precache_check == OLD_TEXTURE_CNT+3) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value)
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.tga", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = OLD_TEXTURE_CNT+999;
		}
	}	//end old download code
	else // New download code
	{
		if (!allow_download->value && precache_check < ENV_CNT)
			precache_check = ENV_CNT;

		// Try downloading pk3 file for current map from server, hack by Jay Dolan
		if (precache_check == CS_MODELS && precache_pak == 0) {
			precache_pak++;
			if (strlen(cl.configstrings[CS_PAKFILE])) {
				if (!CL_CheckOrDownloadFile(cl.configstrings[CS_PAKFILE]))
					return;  // started a download
			}
		}

		// ZOID
		if (precache_check == CS_MODELS) { // confirm map
			precache_check = CS_MODELS+2; // 0 isn't used
			if (allow_download_maps->value)
				if (!CL_CheckOrDownloadFile(cl.configstrings[CS_MODELS+1]))
					return; // started a download
		}
		if (precache_check >= CS_MODELS && precache_check < CS_MODELS+MAX_MODELS)
		{
			if (allow_download_models->value)
			{
				while (precache_check < CS_MODELS+MAX_MODELS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*' ||
						cl.configstrings[precache_check][0] == '#') {
						precache_check++;
						continue;
					}
					if (precache_model_skin == 0) {
						if (!CL_CheckOrDownloadFile(cl.configstrings[precache_check])) {
							precache_model_skin = 1;
							return; // started a download
						}
						precache_model_skin = 1;
					}

					// checking for skins in the model
					if (!precache_model)
					{

						FS_LoadFile (cl.configstrings[precache_check], (void **)&precache_model);
						if (!precache_model) {
							precache_model_skin = 0;
							precache_check++;
							continue; // couldn't load it
						}
						if (LittleLong(*(unsigned *)precache_model) != IDALIASHEADER) {
							// not an alias model
							FS_FreeFile(precache_model);
							precache_model = 0;
							precache_model_skin = 0;
							precache_check++;
							continue;
						}
						pheader = (dmdl_t *)precache_model;
						if (LittleLong (pheader->version) != ALIAS_VERSION) {
							precache_check++;
							precache_model_skin = 0;
							continue; // couldn't load it
						}
					}

					pheader = (dmdl_t *)precache_model;

					while (precache_model_skin - 1 < LittleLong(pheader->num_skins)) {
						if (!CL_CheckOrDownloadFile((char *)precache_model +
							LittleLong(pheader->ofs_skins) + 
							(precache_model_skin - 1)*MAX_SKINNAME)) {
							precache_model_skin++;
							return; // started a download
						}
						precache_model_skin++;
					}
					if (precache_model) { 
						FS_FreeFile(precache_model);
						precache_model = 0;
					}
					precache_model_skin = 0;
					precache_check++;
				}
			}
			precache_check = CS_SOUNDS;
		}
		if (precache_check >= CS_SOUNDS && precache_check < CS_SOUNDS+MAX_SOUNDS) { 
			if (allow_download_sounds->value) {
				if (precache_check == CS_SOUNDS)
					precache_check++; // zero is blank
				while (precache_check < CS_SOUNDS+MAX_SOUNDS &&
					cl.configstrings[precache_check][0]) {
					if (cl.configstrings[precache_check][0] == '*') {
						precache_check++;
						continue;
					}
					Com_sprintf(fn, sizeof(fn), "sound/%s", cl.configstrings[precache_check++]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = CS_IMAGES;
		}
		if (precache_check >= CS_IMAGES && precache_check < CS_IMAGES+MAX_IMAGES) {
			if (precache_check == CS_IMAGES)
				precache_check++; // zero is blank
			while (precache_check < CS_IMAGES+MAX_IMAGES &&
				cl.configstrings[precache_check][0])
			{	
				Com_sprintf(fn, sizeof(fn), "pics/%s.pcx", cl.configstrings[precache_check++]);
				if (!CL_CheckOrDownloadFile(fn))
					return; // started a download
			}
			precache_check = CS_PLAYERSKINS;
		}
		// skins are special, since a player has three things to download:
		// model, weapon model and skin
		// so precache_check is now *3
		if (precache_check >= CS_PLAYERSKINS && precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
			if (allow_download_players->value) {
				while (precache_check < CS_PLAYERSKINS + MAX_CLIENTS * PLAYER_MULT) {
					int32_t i, n;
					char model[MAX_QPATH], skin[MAX_QPATH], *p;

					i = (precache_check - CS_PLAYERSKINS)/PLAYER_MULT;
					n = (precache_check - CS_PLAYERSKINS)%PLAYER_MULT;

					if (!cl.configstrings[CS_PLAYERSKINS+i][0]) {
						precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
						continue;
					}

					if ((p = strchr(cl.configstrings[CS_PLAYERSKINS+i], '\\')) != NULL)
						p++;
					else
						p = cl.configstrings[CS_PLAYERSKINS+i];
					strcpy(model, p);
					p = strchr(model, '/');
					if (!p)
						p = strchr(model, '\\');
					if (p) {
						*p++ = 0;
						strcpy(skin, p);
					} else
						*skin = 0;

					switch (n) {
					case 0: // model
						Com_sprintf(fn, sizeof(fn), "players/%s/tris.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 1;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 1: // weapon model
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.md2", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 2;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 2: // weapon skin
						Com_sprintf(fn, sizeof(fn), "players/%s/weapon.pcx", model);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 3;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 3: // skin
						Com_sprintf(fn, sizeof(fn), "players/%s/%s.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 4;
							return; // started a download
						}
						n++;
						/*FALL THROUGH*/

					case 4: // skin_i
						Com_sprintf(fn, sizeof(fn), "players/%s/%s_i.pcx", model, skin);
						if (!CL_CheckOrDownloadFile(fn)) {
							precache_check = CS_PLAYERSKINS + i * PLAYER_MULT + 5;
							return; // started a download
						}
						// move on to next model
						precache_check = CS_PLAYERSKINS + (i + 1) * PLAYER_MULT;
					}
				}
			}
			// precache phase completed
			precache_check = ENV_CNT;
		}

		if (precache_check == ENV_CNT) {
			precache_check = ENV_CNT + 1;

			CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &map_checksum);

			if (map_checksum != atoi(cl.configstrings[CS_MAPCHECKSUM])) {
				Com_Error (ERR_DROP, "Local map version differs from server: %i != '%s'\n",
					map_checksum, cl.configstrings[CS_MAPCHECKSUM]);
				return;
			}
		}

		if (precache_check > ENV_CNT && precache_check < TEXTURE_CNT) {
			if (allow_download->value && allow_download_maps->value) {
				while (precache_check < TEXTURE_CNT) {
					int32_t n = precache_check++ - ENV_CNT - 1;

					if (n & 1)
						Com_sprintf(fn, sizeof(fn), "env/%s%s.pcx", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					else
						Com_sprintf(fn, sizeof(fn), "env/%s%s.tga", 
							cl.configstrings[CS_SKY], env_suf[n/2]);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = TEXTURE_CNT;
		}

		if (precache_check == TEXTURE_CNT) {
			precache_check = TEXTURE_CNT+1;
			precache_tex = 0;
		}
		// confirm existance of .wal textures, download any that don't exist
		if (precache_check == TEXTURE_CNT+1) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value && !Com_ServerState())
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.wal", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			//precache_check = TEXTURE_CNT+999;
			precache_check = TEXTURE_CNT+2;
			precache_tex = 0;
		}

		// confirm existance of .jpg textures, try to download any that don't exist
		if (precache_check == TEXTURE_CNT+2) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value && allow_download_textures_24bit->value && !Com_ServerState())
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.jpg", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = TEXTURE_CNT+3;
			precache_tex = 0;
		}

		// confirm existance of .tga textures, try to download any that don't exist
		if (precache_check == TEXTURE_CNT+3) {
			// from qcommon/cmodel.c
			extern int32_t			numtexinfo;
			extern mapsurface_t	map_surfaces[];

			if (allow_download->value && allow_download_maps->value && allow_download_textures_24bit->value && !Com_ServerState())
			{
				while (precache_tex < numtexinfo)
				{
					char fn[MAX_OSPATH];

					Com_sprintf(fn, sizeof(fn), "textures/%s.tga", map_surfaces[precache_tex++].rname);
					if (!CL_CheckOrDownloadFile(fn))
						return; // started a download
				}
			}
			precache_check = TEXTURE_CNT+999;
		}
	}	// end new download code
//ZOID

	CL_RegisterSounds ();
	CL_PrepRefresh ();

	MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
	MSG_WriteString (&cls.netchan.message, va("begin %i\n", precache_spawncount) );
}