Beispiel #1
0
/*
================
CL_ParseConfigString
================
*/
void CL_ParseConfigString(void)
{
    int i;
    char * s;

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

    s = MSG_ReadString(&net_message);
    strcpy(cl.configstrings[i], s);

    // do something apropriate

    if (i >= CS_LIGHTS && i < CS_LIGHTS + MAX_LIGHTSTYLES)
    {
        CL_SetLightstyle(i - CS_LIGHTS);
    }
    else if (i == CS_CDTRACK)
    {
        if (cl.refresh_prepped)
        {
            CDAudio_Play(atoi(cl.configstrings[CS_CDTRACK]), true);
        }
    }
    else if (i >= CS_MODELS && i < CS_MODELS + MAX_MODELS)
    {
        if (cl.refresh_prepped)
        {
            cl.model_draw[i - CS_MODELS] = re.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_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_MODELS)
    {
        if (cl.refresh_prepped)
            cl.image_precache[i - CS_IMAGES] = re.RegisterPic(cl.configstrings[i]);
    }
    else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS + MAX_CLIENTS)
    {
        if (cl.refresh_prepped)
            CL_ParseClientinfo(i - CS_PLAYERSKINS);
    }
}
Beispiel #2
0
/*
 * Load or download any custom player skins and models
 */
void
CL_Skins_f(void)
{
	int i;

	for (i = 0; i < MAX_CLIENTS; i++)
	{
		if (!cl.configstrings[CS_PLAYERSKINS + i][0])
		{
			continue;
		}

		Com_Printf("client %i: %s\n", i, cl.configstrings[CS_PLAYERSKINS + i]);

		SCR_UpdateScreen();

		IN_Update();  /* pump message loop */

		CL_ParseClientinfo(i);
	}
}
Beispiel #3
0
void CL_FinishDownload (void)
{
#ifdef _DEBUG
	clientinfo_t *ci;
#endif

	int r;
	char	oldn[MAX_OSPATH];
	char	newn[MAX_OSPATH];

	fclose (cls.download);

	FS_FlushCache();

	// rename the temp file to it's final name
	CL_DownloadFileName(oldn, sizeof(oldn), cls.downloadtempname);
	CL_DownloadFileName(newn, sizeof(newn), cls.downloadname);

	r = rename (oldn, newn);
	if (r)
		Com_Printf ("failed to rename.\n", LOG_CLIENT);

#ifdef _DEBUG
	if (cls.serverProtocol == PROTOCOL_R1Q2 && (strstr(newn, "players"))) {
		for (r = 0; r < cl.maxclients; r++) {
			ci = &cl.clientinfo[r];
			if (ci->deferred)
				CL_ParseClientinfo (r);
		}
	}
#endif

	cls.failed_download = false;
	cls.downloadpending = false;
	cls.downloadname[0] = 0;
	cls.downloadposition = 0;
	cls.download = NULL;
	cls.downloadpercent = 0;
}
Beispiel #4
0
/*
================
CL_ParseConfigString
================
*/
void CL_ParseConfigString (void)
{
	size_t	length;
	int		i;
	char	*s;
	char	olds[MAX_QPATH];

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

	Q_strncpy (olds, cl.configstrings[i], sizeof(olds)-1);

	//Com_Printf ("cs: %i=%s\n", LOG_GENERAL, i, MakePrintable (s));

	//r1ch: only allow statusbar to overflow
	/*if (i >= CS_STATUSBAR && i < CS_AIRACCEL)
		strncpy (cl.configstrings[i], s, (sizeof(cl.configstrings[i]) * (CS_AIRACCEL - i))-1);
	else
		Q_strncpy (cl.configstrings[i], s, sizeof(cl.configstrings[i])-1);*/

	//r1: overflow may be desired by some mods in stats programs for example. who knows.
	length = strlen(s);

	if (length >= (sizeof(cl.configstrings[0]) * (MAX_CONFIGSTRINGS-i)) - 1)
		Com_Error (ERR_DROP, "CL_ParseConfigString: configstring %d exceeds available space", i);

	//r1: don't allow basic things to overflow
	if (i != CS_NAME && i < CS_GENERAL)
	{
		if (i >= CS_STATUSBAR && i < CS_AIRACCEL)
		{
			strncpy (cl.configstrings[i], s, (sizeof(cl.configstrings[i]) * (CS_AIRACCEL - i))-1);
		}
		else
		{
			if (length >= MAX_QPATH)
				Com_Printf ("WARNING: Configstring %d of length %d exceeds MAX_QPATH.\n", LOG_CLIENT|LOG_WARNING, i, (int)length);
			Q_strncpy (cl.configstrings[i], s, sizeof(cl.configstrings[i])-1);
		}
	}
	else
	{
		strcpy (cl.configstrings[i], s);
	}

	// do something apropriate
	if (i == CS_AIRACCEL)
	{
		pm_airaccelerate = (qboolean)atoi(cl.configstrings[CS_AIRACCEL]);
	}
	else if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES)
	{
		CL_SetLightstyle (i - CS_LIGHTS);
	}
#ifdef CD_AUDIO
	else if (i == CS_CDTRACK)
	{
		if (cl.refresh_prepped)
			CDAudio_Play (atoi(cl.configstrings[CS_CDTRACK]), true);
	}
#endif
	else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS)
	{
		if (cl.refresh_prepped)
		{
			cl.model_draw[i-CS_MODELS] = re.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;
		}

		//r1: load map whilst connecting to save a bit of time
		/*if (i == CS_MODELS + 1)
		{
			CM_LoadMap (cl.configstrings[CS_MODELS+1], true, &i);
			if (i && i != atoi(cl.configstrings[CS_MAPCHECKSUM]))
				Com_Error (ERR_DROP, "Local map version differs from server: 0x%.8x != 0x%.8x\n",
					i, atoi(cl.configstrings[CS_MAPCHECKSUM]));
		}*/
	}
	else if (i >= CS_SOUNDS && i < CS_SOUNDS+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_MODELS)
	{
		if (cl.refresh_prepped)
			re.RegisterPic (cl.configstrings[i]);
	}
	else if (i == CS_MAXCLIENTS)
	{
		if (!cl.attractloop)
			cl.maxclients = atoi(cl.configstrings[CS_MAXCLIENTS]);
	}
	else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS)
	{
		//r1: hack to avoid parsing non-skins from mods that overload CS_PLAYERSKINS
		//FIXME: how reliable is CS_MAXCLIENTS?
		i -= CS_PLAYERSKINS;
		if (i < cl.maxclients)
		{
			if (cl.refresh_prepped && strcmp(olds, s))
				CL_ParseClientinfo (i);
		}
		else
		{
			Com_DPrintf ("CL_ParseConfigString: Ignoring out-of-range playerskin %d (%s)\n", i, MakePrintable(s, 0));
		}
	}
}
Beispiel #5
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
}
Beispiel #6
0
void
CL_ParseConfigString(void)
{
    int i, length;
    char *s;
    char olds[MAX_QPATH];

    i = MSG_ReadShort(&net_message);

    if ((i < 0) || (i >= MAX_CONFIGSTRINGS))
    {
        Com_Error(ERR_DROP, "configstring > MAX_CONFIGSTRINGS");
    }

    s = MSG_ReadString(&net_message);

    Q_strlcpy(olds, cl.configstrings[i], sizeof(olds));

    length = strlen(s);
    if (length > sizeof(cl.configstrings) - sizeof(cl.configstrings[0])*i - 1)
    {
        Com_Error(ERR_DROP, "CL_ParseConfigString: oversize configstring");
    }

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

    /* do something apropriate */
    if ((i >= CS_LIGHTS) && (i < CS_LIGHTS + MAX_LIGHTSTYLES))
    {
        CL_SetLightstyle(i - CS_LIGHTS);
    }

    else if (i == CS_CDTRACK)
    {
        if (cl.refresh_prepped)
        {
#ifdef CDA
            CDAudio_Play((int)strtol(cl.configstrings[CS_CDTRACK],
                                     (char **)NULL, 10), true);
#endif

#ifdef OGG

            /* OGG/Vorbis */
            if ((int)strtol(cl.configstrings[CS_CDTRACK], (char **)NULL, 10) < 10)
            {
                char tmp[3] = "0";
                OGG_ParseCmd(strcat(tmp, cl.configstrings[CS_CDTRACK]));
            }
            else
            {
                OGG_ParseCmd(cl.configstrings[CS_CDTRACK]);
            }

#endif
        }
    }
    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_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_MODELS))
    {
        if (cl.refresh_prepped)
        {
            cl.image_precache[i - CS_IMAGES] = Draw_FindPic(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);
        }
    }
}
Beispiel #7
0
/*
================
CL_ParseConfigString
================
*/
void CL_ParseConfigString (sizebuf_t *msg)
{
	int		i, length;
	char	*s;
	char	olds[MAX_QPATH];

	i = MSG_ReadShort (msg);
	if ((unsigned)i >= MAX_CONFIGSTRINGS)
		Com_Error (ERR_DROP, "configstring > MAX_CONFIGSTRINGS");

	Q_strncpyz (olds, cl.configstrings[i], sizeof(olds));

	s = MSG_ReadString(msg);

	length = strlen(s);

	if (i != CS_NAME && i < CS_GENERAL)
	{
		if (i >= CS_STATUSBAR && i < CS_AIRACCEL)
		{
			Q_strncpyz(cl.configstrings[i], s, MAX_QPATH * (CS_AIRACCEL - i));
		}
		else
		{
			if (length >= MAX_QPATH)
				Com_Printf ("WARNING: Configstring %d of length %d exceeds MAX_QPATH.\n", i, length);
			Q_strncpyz(cl.configstrings[i], s, MAX_QPATH);
		}
	}
	else
	{
		Q_strncpyz(cl.configstrings[i], s, MAX_QPATH * (MAX_CONFIGSTRINGS - i));
	}

	// do something apropriate
	if(i == CS_AIRACCEL)
	{
		cl.pmp.airaccelerate = atoi(cl.configstrings[CS_AIRACCEL]) ? true : false;
	}
	else if (i >= CS_LIGHTS && i < CS_LIGHTS+MAX_LIGHTSTYLES)
	{
		CL_SetLightstyle (i - CS_LIGHTS);
	}
	else if (i == CS_CDTRACK)
	{
#ifdef CD_AUDIO
		if (cl.refresh_prepped)
			CDAudio_Play (atoi(cl.configstrings[CS_CDTRACK]), true);
#endif
	}
	else if (i >= CS_MODELS && i < CS_MODELS+MAX_MODELS)
	{
		if( i == CS_MODELS + 1 ) {
			if( length > 9 ) {
				Q_strncpyz( cls.mapname, s + 5, sizeof( cls.mapname ) ); // skip "maps/"
				cls.mapname[strlen( cls.mapname ) - 4] = 0; // cut off ".bsp"
			}

		}
		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_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_MODELS)
	{
		if (cl.refresh_prepped)
			cl.image_precache[i-CS_IMAGES] = Draw_FindPic (cl.configstrings[i]);
	}
	else if (i == CS_MAXCLIENTS)
	{
		cl.maxclients = atoi(cl.configstrings[CS_MAXCLIENTS]);
		clamp(cl.maxclients, 0, MAX_CLIENTS);
	}
	else if (i >= CS_PLAYERSKINS && i < CS_PLAYERSKINS+MAX_CLIENTS)
	{
		if (cl.refresh_prepped && strcmp(olds, s))
			CL_ParseClientinfo (i-CS_PLAYERSKINS);
	}
}
Beispiel #8
0
void V_InitRenderer()
{
	guard(V_InitRenderer);

	int		i;

	if (!cl.configstrings[CS_MODELS+1][0]) return;			// no map loaded
	SCR_SetLevelshot();

	// wait a small time to let server complete initialization
	// allow map to be changed before initializing renderer, when loading savegames,
	// saved at point of changing map; this situation is possible because:
	//   - server frame#1:
	//      - loading savegame, will create configstrings + may be insert command string "gamemap <newmap>"
	//      - send configstrings#1
	//   - server frame#2:
	//      - exec "gamemap" command from previous frame, change map etc.
	//      - send configstrings#2
	// in some circumstances, client will receive configstrings#1 after server frame#2 - this will load
	// client map#1 after loading server map#2 (out-of-sync client/server maps -- fatal error)
	static int startTime = 0;
	static int serverCount = 0;
	if (serverCount != cl.servercount)
	{
		serverCount = cl.servercount;
		startTime = cls.realtime;
		return;
	}
	if (cls.realtime < startTime + 300)
		return;

	CL_ClearEffects();		// can use shaders ...
	CL_ClearTEnts();		// temp entities linked to models, which are invalid after vid_restart

	// let the render dll load the map
	char mapname[MAX_QPATH];
	strcpy(mapname, cl.configstrings[CS_MODELS+1] + 5);	// skip "maps/"
	mapname[strlen(mapname)-4] = 0;		// cut off ".bsp"

	// compute total loading weight
	float totalWeight = W_MAP + W_TEXTURES + W_SKY;
	for (i = 1; i < MAX_MODELS && cl.configstrings[CS_MODELS+i][0]; i++) // models
		if (cl.configstrings[CS_MODELS+i][0] != '*')
			totalWeight += W_MODEL;
	for (i = 0; i < MAX_CLIENTS; i++)	// clients
		if (cl.configstrings[CS_PLAYERSKINS+i][0])
			totalWeight += W_CLIENT;

	// register models, pics, and skins
	float loadingFrac = 0;
	SCR_LoadingNotify(va("map: %s", mapname), 0);
	loadingFrac += W_MAP / totalWeight;
	RE_LoadNewWorld();

	// precache status bar pics
	SCR_TouchPics();

	CL_RegisterTEntModels();
	RegisterShaders();

	strcpy(cl_weaponmodels[0], "weapon.md2");	// default weapon model
	num_cl_weaponmodels = 1;

	for (i = 1; i < MAX_MODELS && cl.configstrings[CS_MODELS+i][0]; i++)
	{
		const char *name = cl.configstrings[CS_MODELS+i];
		if (name[0] != '*')
		{
			SCR_LoadingNotify(name, loadingFrac);
			loadingFrac += W_MODEL / totalWeight;
		}
		if (name[0] == '#')
		{
			// special player weapon model
			if (num_cl_weaponmodels < MAX_CLIENTWEAPONMODELS)
				strncpy(cl_weaponmodels[num_cl_weaponmodels++], cl.configstrings[CS_MODELS+i]+1,
					sizeof(cl_weaponmodels[0])-1);
		}
		else
		{
			const char *mdl = cl.configstrings[CS_MODELS + i];
			const char *ext = strrchr(name, '.');
			// load model, but do not reload BSP file:
			cl.model_draw[i] = (!ext || stricmp(ext, ".bsp")) ? RE_RegisterModel(mdl) : NULL;
			cl.model_clip[i] = (name[0] == '*') ? CM_InlineModel(mdl) : NULL;
		}
	}

	SCR_LoadingNotify("textures", loadingFrac);
	loadingFrac += W_TEXTURES / totalWeight;
	for (i = 1; i < MAX_IMAGES && cl.configstrings[CS_IMAGES+i][0]; i++)
		cl.image_precache[i] = RE_RegisterPic(va("pics/%s", cl.configstrings[CS_IMAGES+i]));

	for (i = 0; i < MAX_CLIENTS; i++)
	{
		if (!cl.configstrings[CS_PLAYERSKINS+i][0])
			continue;
		SCR_LoadingNotify(va("client %d: %s", i, cl.configstrings[CS_PLAYERSKINS+i]), loadingFrac);
		loadingFrac += W_CLIENT / totalWeight;
		CL_ParseClientinfo(i);
	}
	if (!cl.configstrings[CS_PLAYERSKINS+cl.playernum][0])
	{
		// in a singleplayer mode, server will not send clientinfo - generate it by
		// ourself for correct third-person view
//		Com_DPrintf("Fixing CI[playernum]\n");
		CL_UpdatePlayerClientInfo();
	}

	// setup sky
	SCR_LoadingNotify("sky", loadingFrac);
	float rotate = atof(cl.configstrings[CS_SKYROTATE]);
	CVec3 axis;
	sscanf(cl.configstrings[CS_SKYAXIS], "%f %f %f", &axis[0], &axis[1], &axis[2]);
	RE_SetSky(cl.configstrings[CS_SKY], rotate, axis);

	// the renderer can now free unneeded stuff
	RE_FinishLoadingWorld();

	Con_ClearNotify();
	SCR_EndLoadingPlaque(true);
	cl.rendererReady  = true;
	cl.forceViewFrame = true;

	// start the cd track
	CDAudio_Play(atoi(cl.configstrings[CS_CDTRACK]), true);

	unguard;
}