From 8b554980f64dffdba3e87209cdc5ab49c4741eca Mon Sep 17 00:00:00 2001
From: havoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Date: Fri, 3 Dec 2004 19:41:15 +0000
Subject: [PATCH] some renderer/client separation cleanup, migrated some things
 to r_refdef to eliminate renderer references to cl. fields

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4826 d7cf8633-e32d-0410-b094-e92efae38249
---
 cl_main.c     |  86 +++++++++++++++++--------------------------
 cl_screen.c   |  38 +++++++++++++++++++
 client.h      |  15 ++++++++
 gl_backend.c  |  50 -------------------------
 gl_models.c   |   2 +-
 gl_rmain.c    |  73 +++++++++---------------------------
 gl_rsurf.c    | 100 ++++++++++++++++++++++++--------------------------
 model_brush.c |   4 +-
 r_explosion.c |   2 +-
 r_light.c     |  20 +++++-----
 r_lightning.c |   4 +-
 r_shadow.c    |  38 +++++++++----------
 r_sky.c       |  12 +++---
 render.h      |   6 +--
 view.c        |  53 +++++++++++++++-----------
 15 files changed, 225 insertions(+), 278 deletions(-)

diff --git a/cl_main.c b/cl_main.c
index c90bec3a..c5caa797 100644
--- a/cl_main.c
+++ b/cl_main.c
@@ -893,6 +893,8 @@ void CL_RelinkWorld(void)
 	if (!r_fullbright.integer)
 		ent->render.flags |= RENDER_LIGHT;
 	VectorSet(ent->render.colormod, 1, 1, 1);
+	r_refdef.worldentity = &ent->render;
+	r_refdef.worldmodel = cl.worldmodel;
 }
 
 static void CL_RelinkStaticEntities(void)
@@ -1174,6 +1176,8 @@ int CL_ReadFromServer(void)
 {
 	CL_ReadDemoMessage();
 
+	r_refdef.time = cl.time;
+	r_refdef.extraupdate = !r_speeds.integer;
 	r_refdef.numentities = 0;
 	cl_num_entities = 0;
 	cl_num_brushmodel_entities = 0;
@@ -1268,37 +1272,39 @@ static void CL_Fog_f (void)
 	fog_blue = atof(Cmd_Argv(4));
 }
 
+/*
+====================
+CL_TimeRefresh_f
+
+For program optimization
+====================
+*/
+static void CL_TimeRefresh_f (void)
+{
+	int i;
+	float timestart, timedelta, oldangles[3];
+
+	r_refdef.extraupdate = false;
+	VectorCopy(cl.viewangles, oldangles);
+	VectorClear(cl.viewangles);
+
+	timestart = Sys_DoubleTime();
+	for (i = 0;i < 128;i++)
+	{
+		Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], 0, i / 128.0 * 360.0, 0, 1);
+		CL_UpdateScreen();
+	}
+	timedelta = Sys_DoubleTime() - timestart;
+
+	VectorCopy(oldangles, cl.viewangles);
+	Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta);
+}
+
 /*
 =================
 CL_Init
 =================
 */
-//VorteX: cvars for GAME_NETHERWORLD
-cvar_t __cl_playermodel = {CVAR_SAVE, "cl_playermodel", "ranger"}; 
-cvar_t cl_footsteps = {CVAR_SAVE, "cl_footsteps", "1"}; 
-cvar_t cl_weapon_ofs = {CVAR_SAVE, "cl_weapon_ofs", "0 0 0"}; 
-cvar_t cl_weapon_bstep = {CVAR_SAVE, "cl_weapon_bstep", "100 0 0"}; 
-cvar_t cl_weapon_bborder = {CVAR_SAVE, "cl_weapon_bborder", "2 0 0"};
-cvar_t cl_weapon_bphase = {CVAR_SAVE, "cl_weapon_bphase", "0 0 0"};
-cvar_t cl_weapon_bphasescale = {CVAR_SAVE, "cl_weapon_bphasescale", "1 1 1"};
-cvar_t cl_weapon_bphasescissor = {CVAR_SAVE, "cl_weapon_bphasescissor", "-1 -1 -1 1 1 1"};
-cvar_t cl_deathcam = {CVAR_SAVE, "cl_deathcam", "0"};
-cvar_t cl_askonresave = {CVAR_SAVE, "cl_askonresave", "1"};  //Asking on saving to full saveslot in savegame menu
-cvar_t sv_corpses_solid = {CVAR_SAVE, "sv_corpses_solid", "1"}; 
-cvar_t sv_corpses_removetime = {CVAR_SAVE, "sv_corpses_removetime", "0"}; 
-cvar_t sv_monsters_healthscale = {CVAR_SAVE, "sv_monsters_healthscale", "1"}; 
-cvar_t sv_monsters_damagescale = {CVAR_SAVE, "sv_monsters_damagescale", "1"}; 
-cvar_t sv_monsters_multiply = {CVAR_SAVE, "sv_monsters_multiply", "1"};
-cvar_t sv_monsters_randomize = {CVAR_SAVE, "sv_monsters_randomize", "0"};  
-cvar_t sv_monsters_multiply_radius = {CVAR_SAVE, "sv_monsters_multiply_radius", "5"}; 
-cvar_t sv_monsters_ai_skillmod = {CVAR_SAVE, "sv_monsters_ai_skillmod", "1"};
-cvar_t sv_monsters_ai_agrmod = {CVAR_SAVE, "sv_monsters_ai_agrmod", "1"};
-cvar_t sv_monsters_ai_dexmod = {CVAR_SAVE, "sv_monsters_ai_dexmod", "1"};
-cvar_t sv_monsters_deathmatch = {CVAR_SAVE, "sv_monsters_deathmatch", "0"}; 
-cvar_t sv_monsters_deathmatch_maxnum = {CVAR_SAVE, "sv_monsters_deathmatch_maxnum", "20"}; 
-cvar_t sv_monsters_deathmatch_spawntime = {CVAR_SAVE, "sv_monsters_deathmatch_spawntime", "5"}; 
-cvar_t sv_monsters_deathmatch_fragpermonster = {CVAR_SAVE, "sv_monsters_deathmatch_fragpermonster", "0"}; 
-
 void CL_Init (void)
 {
 	cl_entities_mempool = Mem_AllocPool("client entities", 0, NULL);
@@ -1369,33 +1375,7 @@ void CL_Init (void)
 
 	Cvar_RegisterVariable(&cl_prydoncursor);
 
-	if (gamemode == GAME_NETHERWORLD)
-	{
-		Cvar_RegisterVariable (&__cl_playermodel); 
-		Cvar_RegisterVariable (&cl_footsteps); 
-		Cvar_RegisterVariable (&cl_weapon_ofs); 
-		Cvar_RegisterVariable (&cl_weapon_bstep); 
-		Cvar_RegisterVariable (&cl_weapon_bborder);
-		Cvar_RegisterVariable (&cl_weapon_bphase);
-		Cvar_RegisterVariable (&cl_weapon_bphasescale);
-		Cvar_RegisterVariable (&cl_weapon_bphasescissor);
-		Cvar_RegisterVariable (&cl_deathcam);	 //Hack for q3-style death
-		Cvar_RegisterVariable (&cl_askonresave); //Every time ask if saving to "full" saveslot
-		//This must be server-side cvars, after complete finishing of subsystems whitch uses this, they must be moved to server-side
-		Cvar_RegisterVariable (&sv_monsters_healthscale); 
-		Cvar_RegisterVariable (&sv_monsters_damagescale); 
-		Cvar_RegisterVariable (&sv_monsters_randomize);
-		Cvar_RegisterVariable (&sv_monsters_multiply); 
-		Cvar_RegisterVariable (&sv_monsters_multiply_radius); 
-		Cvar_RegisterVariable (&sv_monsters_ai_skillmod); 
-		Cvar_RegisterVariable (&sv_monsters_ai_agrmod); 
-		Cvar_RegisterVariable (&sv_monsters_ai_dexmod); 
-		Cvar_RegisterVariable (&sv_monsters_deathmatch); //Keeping RPG mod
-		Cvar_RegisterVariable (&sv_monsters_deathmatch_maxnum); 
-		Cvar_RegisterVariable (&sv_monsters_deathmatch_spawntime); 
-		Cvar_RegisterVariable (&sv_monsters_deathmatch_fragpermonster); 
-		Cvar_RegisterVariable (&sv_corpses_solid); 
-	}
+	Cmd_AddCommand("timerefresh", CL_TimeRefresh_f);
 
 	CL_Parse_Init();
 	CL_Particles_Init();
diff --git a/cl_screen.c b/cl_screen.c
index f0481794..e00a463a 100644
--- a/cl_screen.c
+++ b/cl_screen.c
@@ -1206,6 +1206,44 @@ void CL_UpdateScreen(void)
 	if (!scr_initialized || !con_initialized || vid_hidden)
 		return;				// not initialized yet
 
+	// don't allow cheats in multiplayer
+	if (!cl.islocalgame && cl.worldmodel)
+	{
+		if (r_fullbright.integer != 0)
+			Cvar_Set ("r_fullbright", "0");
+		if (r_ambient.value != 0)
+			Cvar_Set ("r_ambient", "0");
+	}
+
+	// bound viewsize
+	if (scr_viewsize.value < 30)
+		Cvar_Set ("viewsize","30");
+	if (scr_viewsize.value > 120)
+		Cvar_Set ("viewsize","120");
+
+	// bound field of view
+	if (scr_fov.value < 1)
+		Cvar_Set ("fov","1");
+	if (scr_fov.value > 170)
+		Cvar_Set ("fov","170");
+
+	// intermission is always full screen
+	if (cl.intermission)
+		sb_lines = 0;
+	else
+	{
+		if (scr_viewsize.value >= 120)
+			sb_lines = 0;		// no status bar at all
+		else if (scr_viewsize.value >= 110)
+			sb_lines = 24;		// no inventory
+		else
+			sb_lines = 24+16+8;
+	}
+
+	r_refdef.colormask[0] = 1;
+	r_refdef.colormask[1] = 1;
+	r_refdef.colormask[2] = 1;
+
 	SCR_CaptureVideo();
 
 	if (cls.signon == SIGNONS)
diff --git a/client.h b/client.h
index b3272d1f..fd80cd82 100644
--- a/client.h
+++ b/client.h
@@ -835,10 +835,25 @@ typedef struct
 	// fullscreen color blend
 	float viewblend[4];
 
+	// whether to call S_ExtraUpdate during render to reduce sound chop
+	qboolean extraupdate;
+
+	// client gameworld time for rendering time based effects
+	double time;
+
+	// the world
+	entity_render_t *worldentity;
+
+	// same as worldentity->model
+	model_t *worldmodel;
+
+	// renderable entities (excluding world)
 	entity_render_t **entities;
 	int numentities;
 	int maxentities;
 
+	// 2D art drawing queue
+	// TODO: get rid of this
 	qbyte *drawqueue;
 	int drawqueuesize;
 	int maxdrawqueuesize;
diff --git a/gl_backend.c b/gl_backend.c
index 950dfc1e..a400d8b5 100644
--- a/gl_backend.c
+++ b/gl_backend.c
@@ -1430,56 +1430,6 @@ void SCR_UpdateScreen (void)
 	if (gl_combine.integer && (!gl_combine_extension || r_textureunits.integer < 2))
 		Cvar_SetValueQuick(&gl_combine, 0);
 
-	// don't allow cheats in multiplayer
-	if (!cl.islocalgame && cl.worldmodel)
-	{
-		if (r_fullbright.integer != 0)
-			Cvar_Set ("r_fullbright", "0");
-		if (r_ambient.value != 0)
-			Cvar_Set ("r_ambient", "0");
-	}
-
-	// bound viewsize
-	if (scr_viewsize.value < 30)
-		Cvar_Set ("viewsize","30");
-	if (scr_viewsize.value > 120)
-		Cvar_Set ("viewsize","120");
-
-	// bound field of view
-	if (scr_fov.value < 1)
-		Cvar_Set ("fov","1");
-	if (scr_fov.value > 170)
-		Cvar_Set ("fov","170");
-
-	// intermission is always full screen
-	if (cl.intermission)
-		sb_lines = 0;
-	else
-	{
-		if (scr_viewsize.value >= 120)
-			sb_lines = 0;		// no status bar at all
-		else if (scr_viewsize.value >= 110)
-			sb_lines = 24;		// no inventory
-		else
-			sb_lines = 24+16+8;
-	}
-
-	r_refdef.fovscale_x = 1;
-	r_refdef.fovscale_y = 1;
-	if (r_waterwarp.value > 0 && cl.worldmodel)
-	{
-		Mod_CheckLoaded(cl.worldmodel);
-		if (CL_PointSuperContents(r_vieworigin) & SUPERCONTENTS_LIQUIDSMASK)
-		{
-			r_refdef.fovscale_x = 1 - (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
-			r_refdef.fovscale_y = 1 - (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
-		}
-	}
-
-	r_refdef.colormask[0] = 1;
-	r_refdef.colormask[1] = 1;
-	r_refdef.colormask[2] = 1;
-
 	CHECKGLERROR
 	qglViewport(0, 0, vid.realwidth, vid.realheight);
 	qglDisable(GL_SCISSOR_TEST);
diff --git a/gl_models.c b/gl_models.c
index 1b2b134c..509a535b 100644
--- a/gl_models.c
+++ b/gl_models.c
@@ -17,7 +17,7 @@ aliasskin_t *R_FetchAliasSkin(const entity_render_t *ent, const aliasmesh_t *mes
 		if ((unsigned int)s >= (unsigned int)model->numskins)
 			s = 0;
 		if (model->skinscenes[s].framecount > 1)
-			s = model->skinscenes[s].firstframe + (int) (cl.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
+			s = model->skinscenes[s].firstframe + (int) (r_refdef.time * model->skinscenes[s].framerate) % model->skinscenes[s].framecount;
 		else
 			s = model->skinscenes[s].firstframe;
 		if (s >= mesh->num_skins)
diff --git a/gl_rmain.c b/gl_rmain.c
index 80ee9584..75e6ee6f 100644
--- a/gl_rmain.c
+++ b/gl_rmain.c
@@ -129,36 +129,6 @@ void R_FillColors(float *out, int verts, float r, float g, float b, float a)
 	}
 }
 
-/*
-====================
-R_TimeRefresh_f
-
-For program optimization
-====================
-*/
-qboolean intimerefresh = 0;
-static void R_TimeRefresh_f (void)
-{
-	int i;
-	float timestart, timedelta, oldangles[3];
-
-	intimerefresh = 1;
-	VectorCopy(cl.viewangles, oldangles);
-	VectorClear(cl.viewangles);
-
-	timestart = Sys_DoubleTime();
-	for (i = 0;i < 128;i++)
-	{
-		Matrix4x4_CreateFromQuakeEntity(&r_refdef.viewentitymatrix, r_vieworigin[0], r_vieworigin[1], r_vieworigin[2], 0, i / 128.0 * 360.0, 0, 1);
-		CL_UpdateScreen();
-	}
-	timedelta = Sys_DoubleTime() - timestart;
-
-	VectorCopy(oldangles, cl.viewangles);
-	intimerefresh = 0;
-	Con_Printf("%f seconds (%f fps)\n", timedelta, 128/timedelta);
-}
-
 vec3_t fogcolor;
 vec_t fogdensity;
 float fog_density, fog_red, fog_green, fog_blue;
@@ -241,12 +211,13 @@ void gl_main_shutdown(void)
 extern void CL_ParseEntityLump(char *entitystring);
 void gl_main_newmap(void)
 {
+	// FIXME: move this code to client
 	int l;
 	char *entities, entname[MAX_QPATH];
 	r_framecount = 1;
 	if (cl.worldmodel)
 	{
-		strcpy(entname, cl.worldmodel->name);
+		strlcpy(entname, cl.worldmodel->name, sizeof(entname));
 		l = strlen(entname) - 4;
 		if (l >= 0 && !strcmp(entname + l, ".bsp"))
 		{
@@ -268,7 +239,6 @@ void GL_Main_Init(void)
 	Matrix4x4_CreateIdentity(&r_identitymatrix);
 // FIXME: move this to client?
 	FOG_registercvars();
-	Cmd_AddCommand("timerefresh", R_TimeRefresh_f);
 	Cvar_RegisterVariable(&r_showtris);
 	Cvar_RegisterVariable(&r_drawentities);
 	Cvar_RegisterVariable(&r_drawviewmodel);
@@ -320,8 +290,8 @@ static float R_FarClip(vec3_t origin, vec3_t direction, vec_t startfarclip)
 	r_farclip_directionbit2 = r_farclip_direction[2] < 0;
 	r_farclip_meshfarclip = r_farclip_directiondist + startfarclip;
 
-	if (cl.worldmodel)
-		R_FarClip_Box(cl.worldmodel->normalmins, cl.worldmodel->normalmaxs);
+	if (r_refdef.worldmodel)
+		R_FarClip_Box(r_refdef.worldmodel->normalmins, r_refdef.worldmodel->normalmaxs);
 	for (i = 0;i < r_refdef.numentities;i++)
 		R_FarClip_Box(r_refdef.entities[i]->mins, r_refdef.entities[i]->maxs);
 	
@@ -439,10 +409,6 @@ static void R_MarkEntities (void)
 	int i;
 	entity_render_t *ent;
 
-	ent = &cl_entities[0].render;
-	Matrix4x4_CreateIdentity(&ent->matrix);
-	Matrix4x4_CreateIdentity(&ent->inversematrix);
-
 	if (!r_drawentities.integer)
 		return;
 
@@ -578,7 +544,7 @@ R_RenderView
 */
 void R_RenderView(void)
 {
-	if (!r_refdef.entities/* || !cl.worldmodel*/)
+	if (!r_refdef.entities/* || !r_refdef.worldmodel*/)
 		return; //Host_Error ("R_RenderView: NULL worldmodel");
 
 	r_view_width = bound(0, r_refdef.width, vid.realwidth);
@@ -627,10 +593,8 @@ void R_RenderView(void)
 extern void R_DrawLightningBeams (void);
 void R_RenderScene(void)
 {
-	entity_render_t *world;
-	
 	// don't let sound skip if going slow
-	if (!intimerefresh && !r_speeds.integer)
+	if (r_refdef.extraupdate)
 		S_ExtraUpdate ();
 
 	r_framecount++;
@@ -651,10 +615,9 @@ void R_RenderScene(void)
 
 	R_SkyStartFrame();
 
-	if (cl.worldmodel && cl.worldmodel->brush.FatPVS)
-		cl.worldmodel->brush.FatPVS(cl.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
-	world = &cl_entities[0].render;
-	R_WorldVisibility(world);
+	if (r_refdef.worldmodel && r_refdef.worldmodel->brush.FatPVS)
+		r_refdef.worldmodel->brush.FatPVS(r_refdef.worldmodel, r_vieworigin, 2, r_pvsbits, sizeof(r_pvsbits));
+	R_WorldVisibility();
 	R_TimeReport("worldvis");
 
 	R_MarkEntities();
@@ -663,13 +626,13 @@ void R_RenderScene(void)
 	R_Shadow_UpdateWorldLightSelection();
 
 	// don't let sound skip if going slow
-	if (!intimerefresh && !r_speeds.integer)
+	if (r_refdef.extraupdate)
 		S_ExtraUpdate ();
 
 	GL_ShowTrisColor(0.025, 0.025, 0, 1);
-	if (world->model && world->model->DrawSky)
+	if (r_refdef.worldmodel && r_refdef.worldmodel->DrawSky)
 	{
-		world->model->DrawSky(world);
+		r_refdef.worldmodel->DrawSky(r_refdef.worldentity);
 		R_TimeReport("worldsky");
 	}
 
@@ -677,14 +640,14 @@ void R_RenderScene(void)
 		R_TimeReport("bmodelsky");
 
 	GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
-	if (world->model && world->model->Draw)
+	if (r_refdef.worldmodel && r_refdef.worldmodel->Draw)
 	{
-		world->model->Draw(world);
+		r_refdef.worldmodel->Draw(r_refdef.worldentity);
 		R_TimeReport("world");
 	}
 
 	// don't let sound skip if going slow
-	if (!intimerefresh && !r_speeds.integer)
+	if (r_refdef.extraupdate)
 		S_ExtraUpdate ();
 
 	GL_ShowTrisColor(0, 0.015, 0, 1);
@@ -693,7 +656,7 @@ void R_RenderScene(void)
 	R_TimeReport("models");
 
 	// don't let sound skip if going slow
-	if (!intimerefresh && !r_speeds.integer)
+	if (r_refdef.extraupdate)
 		S_ExtraUpdate ();
 
 	GL_ShowTrisColor(0, 0, 0.033, 1);
@@ -701,7 +664,7 @@ void R_RenderScene(void)
 	R_TimeReport("rtlights");
 
 	// don't let sound skip if going slow
-	if (!intimerefresh && !r_speeds.integer)
+	if (r_refdef.extraupdate)
 		S_ExtraUpdate ();
 
 	GL_ShowTrisColor(0.1, 0, 0, 1);
@@ -736,7 +699,7 @@ void R_RenderScene(void)
 	GL_ShowTrisColor(0.05, 0.05, 0.05, 1);
 
 	// don't let sound skip if going slow
-	if (!intimerefresh && !r_speeds.integer)
+	if (r_refdef.extraupdate)
 		S_ExtraUpdate ();
 }
 
diff --git a/gl_rsurf.c b/gl_rsurf.c
index 720f5c71..32a34c0b 100644
--- a/gl_rsurf.c
+++ b/gl_rsurf.c
@@ -563,7 +563,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
 	entity_render_t *ent;
 	model_t *model;
 	vec3_t org;
-	if (cl.worldmodel == NULL || !cl.worldmodel->brushq1.nodes)
+	if (r_refdef.worldmodel == NULL || !r_refdef.worldmodel->brushq1.nodes)
 		return;
 	fcolor[0] = cr1;
 	fcolor[1] = cg1;
@@ -574,7 +574,7 @@ void R_Stain (const vec3_t origin, float radius, int cr1, int cg1, int cb1, int
 	fcolor[6] = cb2 - cb1;
 	fcolor[7] = (ca2 - ca1) * (1.0f / 64.0f);
 
-	R_StainNode(cl.worldmodel->brushq1.nodes + cl.worldmodel->brushq1.hulls[0].firstclipnode, cl.worldmodel, origin, radius, fcolor);
+	R_StainNode(r_refdef.worldmodel->brushq1.nodes + r_refdef.worldmodel->brushq1.hulls[0].firstclipnode, r_refdef.worldmodel, origin, radius, fcolor);
 
 	// look for embedded bmodels
 	for (n = 0;n < cl_num_brushmodel_entities;n++)
@@ -802,7 +802,7 @@ static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata
 
 	texture = surf->texinfo->texture;
 	if (texture->animated)
-		texture = texture->anim_frames[ent->frame != 0][(texture->anim_total[ent->frame != 0] >= 2) ? ((int) (cl.time * 5.0f) % texture->anim_total[ent->frame != 0]) : 0];
+		texture = texture->anim_frames[ent->frame != 0][(texture->anim_total[ent->frame != 0] >= 2) ? ((int) (r_refdef.time * 5.0f) % texture->anim_total[ent->frame != 0]) : 0];
 	currentalpha = ent->alpha;
 	if (surf->flags & SURF_WATERALPHA)
 		currentalpha *= r_wateralpha.value;
@@ -838,14 +838,14 @@ static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata
 		GL_Color(1, 1, 1, currentalpha);
 		memset(&m, 0, sizeof(m));
 		m.pointer_vertex = surf->mesh.data_vertex3f;
-		m.tex[0] = R_GetTexture(mod_shared_distorttexture[(int)(cl.time * 16)&63]);
+		m.tex[0] = R_GetTexture(mod_shared_distorttexture[(int)(r_refdef.time * 16)&63]);
 		m.tex[1] = R_GetTexture(texture->skin.base);
 		m.texcombinergb[0] = GL_REPLACE;
 		m.texcombinergb[1] = GL_REPLACE;
 		m.pointer_texcoord[0] = surf->mesh.data_texcoordtexture2f;
 		m.pointer_texcoord[1] = surf->mesh.data_texcoordtexture2f;
 		Matrix4x4_CreateFromQuakeEntity(&m.texmatrix[0], 0, 0, 0, 0, 0, 0, r_watershader.value);
-		Matrix4x4_CreateTranslate(&m.texmatrix[1], sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
+		Matrix4x4_CreateTranslate(&m.texmatrix[1], sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
 		R_Mesh_State(&m);
 
 		GL_ActiveTexture(0);
@@ -874,7 +874,7 @@ static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata
 		if (turb)
 		{
 			// scrolling in texture matrix
-			Matrix4x4_CreateTranslate(&m.texmatrix[0], sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
+			Matrix4x4_CreateTranslate(&m.texmatrix[0], sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
 		}
 		colorscale = 1;
 		if (gl_combine.integer)
@@ -909,7 +909,7 @@ static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata
 				if (turb)
 				{
 					// scrolling in texture matrix
-					Matrix4x4_CreateTranslate(&m.texmatrix[0], sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
+					Matrix4x4_CreateTranslate(&m.texmatrix[0], sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
 				}
 			}
 			R_Mesh_State(&m);
@@ -932,7 +932,7 @@ static void RSurfShader_Transparent_Callback(const void *calldata1, int calldata
 				if (turb)
 				{
 					// scrolling in texture matrix
-					Matrix4x4_CreateTranslate(&m.texmatrix[0], sin(cl.time) * 0.025 * r_waterscroll.value, sin(cl.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
+					Matrix4x4_CreateTranslate(&m.texmatrix[0], sin(r_refdef.time) * 0.025 * r_waterscroll.value, sin(r_refdef.time * 0.8f) * 0.025 * r_waterscroll.value, 0);
 				}
 			}
 			R_Mesh_State(&m);
@@ -1265,7 +1265,7 @@ void R_UpdateTextureInfo(entity_render_t *ent)
 		return;
 
 	alttextures = ent->frame != 0;
-	texframe = (int)(cl.time * 5.0f);
+	texframe = (int)(r_refdef.time * 5.0f);
 	for (i = 0;i < ent->model->brushq1.numtextures;i++)
 	{
 		t = ent->model->brushq1.textures + i;
@@ -1447,18 +1447,17 @@ static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
 	int i;
 	float *v;
 	rmeshstate_t m;
-	const entity_render_t *ent = calldata1;
-	const mportal_t *portal = ent->model->brushq1.portals + calldata2;
+	const mportal_t *portal = calldata1;
 	GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 	GL_DepthMask(false);
 	GL_DepthTest(true);
-	R_Mesh_Matrix(&ent->matrix);
+	R_Mesh_Matrix(&r_identitymatrix);
 
 	memset(&m, 0, sizeof(m));
 	m.pointer_vertex = varray_vertex3f;
 	R_Mesh_State(&m);
 
-	i = portal - ent->model->brushq1.portals;
+	i = calldata2;
 	GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f),
 			 ((i & 0x0038) >> 3) * (1.0f / 7.0f),
 			 ((i & 0x01C0) >> 6) * (1.0f / 7.0f),
@@ -1477,24 +1476,24 @@ static void R_DrawPortal_Callback(const void *calldata1, int calldata2)
 }
 
 // LordHavoc: this is just a nice debugging tool, very slow
-static void R_DrawPortals(entity_render_t *ent)
+static void R_DrawPortals(void)
 {
-	int i;
-	mportal_t *portal, *endportal;
-	float temp[3], center[3], f;
-	if (ent->model == NULL)
+	int i, portalnum;
+	mportal_t *portal;
+	float center[3], f;
+	model_t *model = r_refdef.worldmodel;
+	if (model == NULL)
 		return;
-	for (portal = ent->model->brushq1.portals, endportal = portal + ent->model->brushq1.numportals;portal < endportal;portal++)
+	for (portalnum = 0, portal = model->brushq1.portals;portalnum < model->brushq1.numportals;portalnum++, portal++)
 	{
 		if (portal->numpoints <= POLYGONELEMENTS_MAXPOINTS)
 		{
-			VectorClear(temp);
+			VectorClear(center);
 			for (i = 0;i < portal->numpoints;i++)
-				VectorAdd(temp, portal->points[i].position, temp);
+				VectorAdd(center, portal->points[i].position, center);
 			f = ixtable[portal->numpoints];
-			VectorScale(temp, f, temp);
-			Matrix4x4_Transform(&ent->matrix, temp, center);
-			R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, ent, portal - ent->model->brushq1.portals);
+			VectorScale(center, f, center);
+			R_MeshQueue_AddTransparent(center, R_DrawPortal_Callback, portal, portalnum);
 		}
 	}
 }
@@ -1540,21 +1539,19 @@ void R_PrepareBrushModel(entity_render_t *ent)
 	R_UpdateLightmapInfo(ent);
 }
 
-void R_SurfaceWorldNode (entity_render_t *ent)
+void R_SurfaceWorldNode (void)
 {
 	int i, *surfacevisframes, *surfacepvsframes, surfnum;
 	msurface_t *surf;
 	mleaf_t *leaf;
 	model_t *model;
-	vec3_t modelorg;
 
 	// equivilant to quake's RecursiveWorldNode but faster and more effective
-	model = ent->model;
+	model = r_refdef.worldmodel;
 	if (model == NULL)
 		return;
 	surfacevisframes = model->brushq1.surfacevisframes + model->firstmodelsurface;
 	surfacepvsframes = model->brushq1.surfacepvsframes + model->firstmodelsurface;
-	Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
 
 	for (leaf = model->brushq1.pvsleafchain;leaf;leaf = leaf->pvschain)
 	{
@@ -1570,7 +1567,7 @@ void R_SurfaceWorldNode (entity_render_t *ent)
 		surfnum = model->brushq1.pvssurflist[i];
 		surf = model->brushq1.surfaces + surfnum;
 #if WORLDNODECULLBACKFACES
-		if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+		if (PlaneDist(r_vieworigin, surf->plane) < surf->plane->dist)
 		{
 			if ((surf->flags & SURF_PLANEBACK) && !R_CullBox (surf->poly_mins, surf->poly_maxs))
 				surfacevisframes[surfnum] = r_framecount;
@@ -1587,7 +1584,7 @@ void R_SurfaceWorldNode (entity_render_t *ent)
 	}
 }
 
-static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
+static void R_PortalWorldNode(mleaf_t *viewleaf)
 {
 	int c, leafstackpos, *mark, *surfacevisframes;
 #if WORLDNODECULLBACKFACES
@@ -1596,17 +1593,16 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
 #endif
 	mleaf_t *leaf, *leafstack[8192];
 	mportal_t *p;
-	vec3_t modelorg;
 	msurface_t *surfaces;
-	if (ent->model == NULL)
+	model_t *model = r_refdef.worldmodel;
+	if (model == NULL)
 		return;
 	// LordHavoc: portal-passage worldnode with PVS;
 	// follows portals leading outward from viewleaf, does not venture
 	// offscreen or into leafs that are not visible, faster than Quake's
 	// RecursiveWorldNode
-	surfaces = ent->model->brushq1.surfaces;
-	surfacevisframes = ent->model->brushq1.surfacevisframes;
-	Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
+	surfaces = model->brushq1.surfaces;
+	surfacevisframes = model->brushq1.surfacevisframes;
 	viewleaf->worldnodeframe = r_framecount;
 	leafstack[0] = viewleaf;
 	leafstackpos = 1;
@@ -1625,7 +1621,7 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
 				if (surfacevisframes[n] != r_framecount)
 				{
 					surf = surfaces + n;
-					if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+					if (PlaneDist(r_vieworigin, surf->plane) < surf->plane->dist)
 					{
 						if ((surf->flags & SURF_PLANEBACK))
 							surfacevisframes[n] = r_framecount;
@@ -1646,7 +1642,7 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
 		{
 			// LordHavoc: this DotProduct hurts less than a cache miss
 			// (which is more likely to happen if backflowing through leafs)
-			if (DotProduct(modelorg, p->plane.normal) < (p->plane.dist + 1))
+			if (DotProduct(r_vieworigin, p->plane.normal) < (p->plane.dist + 1))
 			{
 				leaf = p->past;
 				if (leaf->worldnodeframe != r_framecount)
@@ -1661,13 +1657,13 @@ static void R_PortalWorldNode(entity_render_t *ent, mleaf_t *viewleaf)
 	}
 }
 
-void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf)
+void R_PVSUpdate (mleaf_t *viewleaf)
 {
 	int j, c, *surfacepvsframes, *mark;
 	mleaf_t *leaf;
 	model_t *model;
 
-	model = ent->model;
+	model = r_refdef.worldmodel;
 	if (model && (model->brushq1.pvsviewleaf != viewleaf || model->brushq1.pvsviewleafnovis != r_novis.integer))
 	{
 		model->brushq1.pvsframecount++;
@@ -1695,32 +1691,30 @@ void R_PVSUpdate (entity_render_t *ent, mleaf_t *viewleaf)
 	}
 }
 
-void R_WorldVisibility(entity_render_t *ent)
+void R_WorldVisibility(void)
 {
-	vec3_t modelorg;
 	mleaf_t *viewleaf;
 
-	Matrix4x4_Transform(&ent->inversematrix, r_vieworigin, modelorg);
-	viewleaf = (ent->model && ent->model->brushq1.PointInLeaf) ? ent->model->brushq1.PointInLeaf(ent->model, modelorg) : NULL;
-	R_PVSUpdate(ent, viewleaf);
+	viewleaf = (r_refdef.worldmodel && r_refdef.worldmodel->brushq1.PointInLeaf) ? r_refdef.worldmodel->brushq1.PointInLeaf(r_refdef.worldmodel, r_vieworigin) : NULL;
+	R_PVSUpdate(viewleaf);
 
 	if (!viewleaf)
 		return;
 
 	if (r_surfaceworldnode.integer || viewleaf->contents == CONTENTS_SOLID)
-		R_SurfaceWorldNode (ent);
+		R_SurfaceWorldNode();
 	else
-		R_PortalWorldNode (ent, viewleaf);
+		R_PortalWorldNode(viewleaf);
 
 	if (r_drawportals.integer)
-		R_DrawPortals(ent);
+		R_DrawPortals();
 }
 
 void R_Q1BSP_DrawSky(entity_render_t *ent)
 {
 	if (ent->model == NULL)
 		return;
-	if (ent != &cl_entities[0].render)
+	if (ent != r_refdef.worldentity)
 		R_PrepareBrushModel(ent);
 	R_PrepareSurfaces(ent);
 	R_DrawSurfaces(ent, SURF_DRAWSKY);
@@ -1731,7 +1725,7 @@ void R_Q1BSP_Draw(entity_render_t *ent)
 	if (ent->model == NULL)
 		return;
 	c_bmodels++;
-	if (ent != &cl_entities[0].render)
+	if (ent != r_refdef.worldentity)
 		R_PrepareBrushModel(ent);
 	R_PrepareSurfaces(ent);
 	R_UpdateTextureInfo(ent);
@@ -1884,7 +1878,7 @@ void R_Q1BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t
 				if (t->flags & SURF_LIGHTMAP && t->skin.fog == NULL)
 					Mod_ShadowMesh_AddMesh(r_shadow_mempool, r_shadow_compilingrtlight->static_meshchain_light, surface->texinfo->texture->skin.base, surface->texinfo->texture->skin.gloss, surface->texinfo->texture->skin.nmap, surface->mesh.data_vertex3f, surface->mesh.data_svector3f, surface->mesh.data_tvector3f, surface->mesh.data_normal3f, surface->mesh.data_texcoordtexture2f, surface->mesh.num_triangles, surface->mesh.data_element3i);
 			}
-			else if (ent != &cl_entities[0].render || surface->visframe == r_framecount)
+			else if (ent != r_refdef.worldentity || surface->visframe == r_framecount)
 			{
 				t = surface->texinfo->texture->currentframe;
 				// FIXME: transparent surfaces need to be lit later
@@ -2328,12 +2322,12 @@ void R_Q3BSP_DrawFaces(entity_render_t *ent, int skyfaces)
 		flags = Q3SURFACEFLAG_SKY;
 	else
 		flags = 0;
-	if (ent == &cl_entities[0].render)
+	if (ent == r_refdef.worldentity)
 	{
 		int j;
 		q3mleaf_t *leaf;
-		R_Surf_ClearSurfaceVisible(cl.worldmodel->brushq3.num_faces);
-		for (j = 0, leaf = cl.worldmodel->brushq3.data_leafs;j < cl.worldmodel->brushq3.num_leafs;j++, leaf++)
+		R_Surf_ClearSurfaceVisible(r_refdef.worldmodel->brushq3.num_faces);
+		for (j = 0, leaf = r_refdef.worldmodel->brushq3.data_leafs;j < r_refdef.worldmodel->brushq3.num_leafs;j++, leaf++)
 		{
 			if (CHECKPVSBIT(r_pvsbits, leaf->clusterindex) && !R_CullBox(leaf->mins, leaf->maxs))
 			{
diff --git a/model_brush.c b/model_brush.c
index 67de2935..21ea748c 100644
--- a/model_brush.c
+++ b/model_brush.c
@@ -788,7 +788,7 @@ loc0:
 			int i, ds, dt;
 			msurface_t *surf;
 
-			surf = cl.worldmodel->brushq1.surfaces + node->firstsurface;
+			surf = r_refdef.worldmodel->brushq1.surfaces + node->firstsurface;
 			for (i = 0;i < node->numsurfaces;i++, surf++)
 			{
 				if (!(surf->flags & SURF_LIGHTMAP) || !surf->samples)
@@ -869,7 +869,7 @@ middle sample (the one which was requested)
 
 void Mod_Q1BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
 {
-	Mod_Q1BSP_LightPoint_RecursiveBSPNode(ambientcolor, diffusecolor, diffusenormal, cl.worldmodel->brushq1.nodes + cl.worldmodel->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2], p[2] - 65536);
+	Mod_Q1BSP_LightPoint_RecursiveBSPNode(ambientcolor, diffusecolor, diffusenormal, model->brushq1.nodes + model->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2], p[2] - 65536);
 }
 
 static void Mod_Q1BSP_DecompressVis(const qbyte *in, const qbyte *inend, qbyte *out, qbyte *outend)
diff --git a/r_explosion.c b/r_explosion.c
index f1fe3ce2..a620177f 100644
--- a/r_explosion.c
+++ b/r_explosion.c
@@ -259,7 +259,7 @@ void R_DrawExplosions(void)
 	if (!r_drawexplosions.integer)
 		return;
 	for (i = 0;i < MAX_EXPLOSIONS;i++)
-		if (cl.time < explosion[i].endtime)
+		if (r_refdef.time < explosion[i].endtime)
 			R_MeshQueue_AddTransparent(explosion[i].origin, R_DrawExplosionCallback, &explosion[i], 0);
 }
 
diff --git a/r_light.c b/r_light.c
index e3f53cb0..0dc8bee0 100644
--- a/r_light.c
+++ b/r_light.c
@@ -288,24 +288,24 @@ void R_CompleteLightPoint(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffu
 	VectorClear(diffusecolor);
 	VectorClear(diffusenormal);
 
-	if (!r_fullbright.integer && cl.worldmodel && cl.worldmodel->brush.LightPoint)
+	if (!r_fullbright.integer && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
 	{
 		ambientcolor[0] = ambientcolor[1] = ambientcolor[2] = r_ambient.value * (2.0f / 128.0f);
-		cl.worldmodel->brush.LightPoint(cl.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
+		r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, p, ambientcolor, diffusecolor, diffusenormal);
 	}
 	else
 		VectorSet(ambientcolor, 1, 1, 1);
 
 	// FIXME: this .lights related stuff needs to be ported into the Mod_Q1BSP code
-	if (cl.worldmodel->brushq1.numlights)
+	if (r_refdef.worldmodel->brushq1.numlights)
 	{
 		int i;
 		vec3_t v;
 		float f;
 		mlight_t *sl;
-		for (i = 0;i < cl.worldmodel->brushq1.numlights;i++)
+		for (i = 0;i < r_refdef.worldmodel->brushq1.numlights;i++)
 		{
-			sl = cl.worldmodel->brushq1.lights + i;
+			sl = r_refdef.worldmodel->brushq1.lights + i;
 			if (d_lightstylevalue[sl->style] > 0)
 			{
 				VectorSubtract (p, sl->origin, v);
@@ -380,9 +380,9 @@ int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, co
 		maxnearlights = 0;
 	else
 	{
-		if (cl.worldmodel && cl.worldmodel->brush.LightPoint)
+		if (r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint)
 		{
-			cl.worldmodel->brush.LightPoint(cl.worldmodel, ent->origin, ambient4f, diffusecolor, tempdiffusenormal);
+			r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ambient4f, diffusecolor, tempdiffusenormal);
 			Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, diffusenormal);
 			VectorNormalize(diffusenormal);
 		}
@@ -397,7 +397,7 @@ int R_LightModel(float *ambient4f, float *diffusecolor, float *diffusenormal, co
 	nl = &nearlight[0];
 	for (i = 0;i < ent->numentlights;i++)
 	{
-		sl = cl.worldmodel->brushq1.lights + ent->entlights[i];
+		sl = r_refdef.worldmodel->brushq1.lights + ent->entlights[i];
 		stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f);
 		VectorSubtract (ent->origin, sl->origin, v);
 		f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale;
@@ -595,8 +595,8 @@ void R_UpdateEntLights(entity_render_t *ent)
 		ent->entlightstime = realtime + 0.1;
 		VectorCopy(ent->origin, ent->entlightsorigin);
 		ent->numentlights = 0;
-		if (cl.worldmodel)
-			for (i = 0, sl = cl.worldmodel->brushq1.lights;i < cl.worldmodel->brushq1.numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
+		if (r_refdef.worldmodel)
+			for (i = 0, sl = r_refdef.worldmodel->brushq1.lights;i < r_refdef.worldmodel->brushq1.numlights && ent->numentlights < MAXENTLIGHTS;i++, sl++)
 				if (CL_TraceLine(ent->origin, sl->origin, NULL, NULL, false, NULL, SUPERCONTENTS_SOLID) == 1)
 					ent->entlights[ent->numentlights++] = i;
 	}
diff --git a/r_lightning.c b/r_lightning.c
index e80216ee..74b397bb 100644
--- a/r_lightning.c
+++ b/r_lightning.c
@@ -260,7 +260,7 @@ void R_DrawLightningBeamCallback(const void *calldata1, int calldata2)
 	CrossProduct(beamdir, up, right);
 
 	// calculate T coordinate scrolling (start and end texcoord along the beam)
-	t1 = cl.time * -r_lightningbeam_scroll.value;// + beamrepeatscale * DotProduct(b->start, beamdir);
+	t1 = r_refdef.time * -r_lightningbeam_scroll.value;// + beamrepeatscale * DotProduct(b->start, beamdir);
 	t1 = t1 - (int) t1;
 	t2 = t1 + beamrepeatscale * length;
 
@@ -337,7 +337,7 @@ void R_DrawLightningBeams(void)
 	beamrepeatscale = 1.0f / r_lightningbeam_repeatdistance.value;
 	for (i = 0, b = cl_beams;i < cl_max_beams;i++, b++)
 	{
-		if (b->model && b->endtime >= cl.time && b->lightning)
+		if (b->model && b->endtime >= r_refdef.time && b->lightning)
 		{
 			VectorAdd(b->start, b->end, org);
 			VectorScale(org, 0.5f, org);
diff --git a/r_shadow.c b/r_shadow.c
index 70e4aab7..43d416e6 100644
--- a/r_shadow.c
+++ b/r_shadow.c
@@ -2372,16 +2372,16 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
 		VectorCopy(rtlight->cullmins, cullmins);
 		VectorCopy(rtlight->cullmaxs, cullmaxs);
 	}
-	else if (cl.worldmodel && cl.worldmodel->GetLightInfo)
+	else if (r_refdef.worldmodel && r_refdef.worldmodel->GetLightInfo)
 	{
 		// dynamic light, world available and can receive realtime lighting
 		// if the light box is offscreen, skip it right away
 		if (R_CullBox(cullmins, cullmaxs))
 			return;
 		// calculate lit surfaces and clusters
-		R_Shadow_EnlargeClusterBuffer(cl.worldmodel->brush.num_pvsclusters);
-		R_Shadow_EnlargeSurfaceBuffer(cl.worldmodel->nummodelsurfaces); 
-		cl.worldmodel->GetLightInfo(&cl_entities[0].render, rtlight->shadoworigin, rtlight->radius, cullmins, cullmaxs, r_shadow_buffer_clusterlist, r_shadow_buffer_clusterpvs, &numclusters, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces);
+		R_Shadow_EnlargeClusterBuffer(r_refdef.worldmodel->brush.num_pvsclusters);
+		R_Shadow_EnlargeSurfaceBuffer(r_refdef.worldmodel->nummodelsurfaces); 
+		r_refdef.worldmodel->GetLightInfo(&cl_entities[0].render, rtlight->shadoworigin, rtlight->radius, cullmins, cullmaxs, r_shadow_buffer_clusterlist, r_shadow_buffer_clusterpvs, &numclusters, r_shadow_buffer_surfacelist, r_shadow_buffer_surfacepvs, &numsurfaces);
 		clusterlist = r_shadow_buffer_clusterlist;
 		clusterpvs = r_shadow_buffer_clusterpvs;
 		surfacelist = r_shadow_buffer_surfacelist;
@@ -2461,7 +2461,7 @@ void R_DrawRTLight(rtlight_t *rtlight, int visiblevolumes)
 				{
 					if (!BoxesOverlap(ent->mins, ent->maxs, cullmins, cullmaxs))
 						continue;
-					if (cl.worldmodel != NULL && cl.worldmodel->brush.BoxTouchingPVS != NULL && !cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, clusterpvs, ent->mins, ent->maxs))
+					if (r_refdef.worldmodel != NULL && r_refdef.worldmodel->brush.BoxTouchingPVS != NULL && !r_refdef.worldmodel->brush.BoxTouchingPVS(r_refdef.worldmodel, clusterpvs, ent->mins, ent->maxs))
 						continue;
 				}
 				if (!(ent->flags & RENDER_SHADOW) || !ent->model || !ent->model->DrawShadowVolume)
@@ -2529,7 +2529,7 @@ void R_ShadowVolumeLighting(int visiblevolumes)
 	dlight_t *light;
 	rmeshstate_t m;
 
-	if (cl.worldmodel && strncmp(cl.worldmodel->name, r_shadow_mapname, sizeof(r_shadow_mapname)))
+	if (r_refdef.worldmodel && strncmp(r_refdef.worldmodel->name, r_shadow_mapname, sizeof(r_shadow_mapname)))
 		R_Shadow_EditLights_Reload_f();
 
 	if (visiblevolumes)
@@ -2820,12 +2820,12 @@ void R_Shadow_LoadWorldLights(void)
 	int n, a, style, shadow, flags;
 	char name[MAX_QPATH], cubemapname[MAX_QPATH], *lightsstring, *s, *t;
 	float origin[3], radius, color[3], angles[3], corona, coronasizescale, ambientscale, diffusescale, specularscale;
-	if (cl.worldmodel == NULL)
+	if (r_refdef.worldmodel == NULL)
 	{
 		Con_Print("No map loaded.\n");
 		return;
 	}
-	FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
+	FS_StripExtension (r_refdef.worldmodel->name, name, sizeof (name));
 	strlcat (name, ".rtlights", sizeof (name));
 	lightsstring = FS_LoadFile(name, tempmempool, false);
 	if (lightsstring)
@@ -2907,12 +2907,12 @@ void R_Shadow_SaveWorldLights(void)
 	char line[1024];
 	if (!r_shadow_worldlightchain)
 		return;
-	if (cl.worldmodel == NULL)
+	if (r_refdef.worldmodel == NULL)
 	{
 		Con_Print("No map loaded.\n");
 		return;
 	}
-	FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
+	FS_StripExtension (r_refdef.worldmodel->name, name, sizeof (name));
 	strlcat (name, ".rtlights", sizeof (name));
 	bufchars = bufmaxchars = 0;
 	buf = NULL;
@@ -2953,12 +2953,12 @@ void R_Shadow_LoadLightsFile(void)
 	int n, a, style;
 	char name[MAX_QPATH], *lightsstring, *s, *t;
 	float origin[3], radius, color[3], subtract, spotdir[3], spotcone, falloff, distbias;
-	if (cl.worldmodel == NULL)
+	if (r_refdef.worldmodel == NULL)
 	{
 		Con_Print("No map loaded.\n");
 		return;
 	}
-	FS_StripExtension (cl.worldmodel->name, name, sizeof (name));
+	FS_StripExtension (r_refdef.worldmodel->name, name, sizeof (name));
 	strlcat (name, ".lights", sizeof (name));
 	lightsstring = FS_LoadFile(name, tempmempool, false);
 	if (lightsstring)
@@ -3004,18 +3004,18 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
 	float origin[3], angles[3], radius, color[3], light[4], fadescale, lightscale, originhack[3], overridecolor[3], vec[4];
 	char key[256], value[1024];
 
-	if (cl.worldmodel == NULL)
+	if (r_refdef.worldmodel == NULL)
 	{
 		Con_Print("No map loaded.\n");
 		return;
 	}
 	// try to load a .ent file first
-	FS_StripExtension (cl.worldmodel->name, key, sizeof (key));
+	FS_StripExtension (r_refdef.worldmodel->name, key, sizeof (key));
 	strlcat (key, ".ent", sizeof (key));
 	data = entfiledata = FS_LoadFile(key, tempmempool, true);
 	// and if that is not found, fall back to the bsp file entity string
 	if (!data)
-		data = cl.worldmodel->brush.entities;
+		data = r_refdef.worldmodel->brush.entities;
 	if (!data)
 		return;
 	for (entnum = 0;COM_ParseToken(&data, false) && com_token[0] == '{';entnum++)
@@ -3155,7 +3155,7 @@ void R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(void)
 			}
 			else if (!strcmp("style", key))
 				style = atoi(value);
-			else if (cl.worldmodel->type == mod_brushq3)
+			else if (r_refdef.worldmodel->type == mod_brushq3)
 			{
 				if (!strcmp("scale", key))
 					lightscale = atof(value);
@@ -3254,9 +3254,9 @@ void R_Shadow_EditLights_Clear_f(void)
 
 void R_Shadow_EditLights_Reload_f(void)
 {
-	if (!cl.worldmodel)
+	if (!r_refdef.worldmodel)
 		return;
-	strlcpy(r_shadow_mapname, cl.worldmodel->name, sizeof(r_shadow_mapname));
+	strlcpy(r_shadow_mapname, r_refdef.worldmodel->name, sizeof(r_shadow_mapname));
 	R_Shadow_ClearWorldLights();
 	R_Shadow_LoadWorldLights();
 	if (r_shadow_worldlightchain == NULL)
@@ -3269,7 +3269,7 @@ void R_Shadow_EditLights_Reload_f(void)
 
 void R_Shadow_EditLights_Save_f(void)
 {
-	if (!cl.worldmodel)
+	if (!r_refdef.worldmodel)
 		return;
 	R_Shadow_SaveWorldLights();
 }
diff --git a/r_sky.c b/r_sky.c
index 5c0aca5f..b58ada98 100644
--- a/r_sky.c
+++ b/r_sky.c
@@ -60,7 +60,7 @@ void R_SkyStartFrame(void)
 	{
 		if (skyboxside[0] || skyboxside[1] || skyboxside[2] || skyboxside[3] || skyboxside[4] || skyboxside[5])
 			skyrenderbox = true;
-		else if (cl.worldmodel->brush.solidskytexture)
+		else if (r_refdef.worldmodel->brush.solidskytexture)
 			skyrendersphere = true;
 		// for depth-masked sky, render the sky on the first sky surface encountered
 		skyrendernow = true;
@@ -361,11 +361,11 @@ static void R_SkySphere(void)
 	// wrap the scroll values just to be extra kind to float accuracy
 
 	// scroll speed for upper layer
-	speedscale = cl.time*r_skyscroll1.value*8.0/128.0;
+	speedscale = r_refdef.time*r_skyscroll1.value*8.0/128.0;
 	speedscale -= (int)speedscale;
 	Matrix4x4_CreateTranslate(&scroll1matrix, speedscale, speedscale, 0);
 	// scroll speed for lower layer (transparent layer)
-	speedscale = cl.time*r_skyscroll2.value*8.0/128.0;
+	speedscale = r_refdef.time*r_skyscroll2.value*8.0/128.0;
 	speedscale -= (int)speedscale;
 	Matrix4x4_CreateTranslate(&scroll2matrix, speedscale, speedscale, 0);
 
@@ -375,13 +375,13 @@ static void R_SkySphere(void)
 	GL_DepthTest(false); // don't modify or read zbuffer
 	memset(&m, 0, sizeof(m));
 	m.pointer_vertex = skysphere_vertex3f;
-	m.tex[0] = R_GetTexture(cl.worldmodel->brush.solidskytexture);
+	m.tex[0] = R_GetTexture(r_refdef.worldmodel->brush.solidskytexture);
 	m.pointer_texcoord[0] = skysphere_texcoord2f;
 	m.texmatrix[0] = scroll1matrix;
 	if (r_textureunits.integer >= 2)
 	{
 		// one pass using GL_DECAL or GL_INTERPOLATE_ARB for alpha layer
-		m.tex[1] = R_GetTexture(cl.worldmodel->brush.alphaskytexture);
+		m.tex[1] = R_GetTexture(r_refdef.worldmodel->brush.alphaskytexture);
 		m.texcombinergb[1] = gl_combine.integer ? GL_INTERPOLATE_ARB : GL_DECAL;
 		m.pointer_texcoord[1] = skysphere_texcoord2f;
 		m.texmatrix[1] = scroll2matrix;
@@ -399,7 +399,7 @@ static void R_SkySphere(void)
 		GL_LockArrays(0, 0);
 
 		GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-		m.tex[0] = R_GetTexture(cl.worldmodel->brush.alphaskytexture);
+		m.tex[0] = R_GetTexture(r_refdef.worldmodel->brush.alphaskytexture);
 		m.texmatrix[0] = scroll2matrix;
 		R_Mesh_State(&m);
 		GL_LockArrays(0, skysphere_numverts);
diff --git a/render.h b/render.h
index 62347212..5a4d9787 100644
--- a/render.h
+++ b/render.h
@@ -52,7 +52,6 @@ extern void SHOWLMP_drawall(void);
 extern void SHOWLMP_clear(void);
 
 // render profiling stuff
-extern qboolean intimerefresh;
 extern char r_speeds_string[1024];
 
 // lighting stuff
@@ -133,8 +132,7 @@ void R_RenderView(void); // must call R_UpdateWorld and set r_refdef first
 
 void R_InitSky (qbyte *src, int bytesperpixel); // called at level load
 
-void R_WorldVisibility(entity_render_t *ent);
-void R_DrawWorld(entity_render_t *ent);
+void R_WorldVisibility();
 void R_DrawParticles(void);
 void R_DrawExplosions(void);
 
@@ -142,7 +140,7 @@ void R_DrawExplosions(void);
 #define gl_alpha_format 4
 
 int R_CullBox(const vec3_t mins, const vec3_t maxs);
-#define VIS_CullBox(mins,maxs) (R_CullBox((mins), (maxs)) || (cl.worldmodel && cl.worldmodel->brush.BoxTouchingPVS && !cl.worldmodel->brush.BoxTouchingPVS(cl.worldmodel, r_pvsbits, (mins), (maxs))))
+#define VIS_CullBox(mins,maxs) (R_CullBox((mins), (maxs)) || (r_refdef.worldmodel && r_refdef.worldmodel->brush.BoxTouchingPVS && !r_refdef.worldmodel->brush.BoxTouchingPVS(r_refdef.worldmodel, r_pvsbits, (mins), (maxs))))
 
 extern qboolean fogenabled;
 extern vec3_t fogcolor;
diff --git a/view.c b/view.c
index de0bf4d5..dc646ae7 100644
--- a/view.c
+++ b/view.c
@@ -308,7 +308,6 @@ V_CalcRefdef
 
 ==================
 */
-extern float timerefreshangle;
 void V_CalcRefdef (void)
 {
 	static float oldz;
@@ -449,35 +448,45 @@ void V_CalcViewBlend(void)
 	r_refdef.viewblend[1] = 0;
 	r_refdef.viewblend[2] = 0;
 	r_refdef.viewblend[3] = 0;
+	r_refdef.fovscale_x = cl.viewzoom;
+	r_refdef.fovscale_y = cl.viewzoom;
 	if (cls.state == ca_connected && cls.signon == SIGNONS && gl_polyblend.value > 0)
 	{
 		// set contents color
-		switch (CL_PointQ1Contents(r_vieworigin))
+		int supercontents;
+		vec3_t vieworigin;
+		Matrix4x4_OriginFromMatrix(&r_refdef.viewentitymatrix, vieworigin);
+		supercontents = CL_PointSuperContents(vieworigin);
+		if (supercontents & SUPERCONTENTS_LIQUIDSMASK)
+		{
+			r_refdef.fovscale_x *= 1 - (((sin(cl.time * 4.7) + 1) * 0.015) * r_waterwarp.value);
+			r_refdef.fovscale_y *= 1 - (((sin(cl.time * 3.0) + 1) * 0.015) * r_waterwarp.value);
+			if (supercontents & SUPERCONTENTS_LAVA)
+			{
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 255;
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80;
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 0;
+			}
+			else if (supercontents & SUPERCONTENTS_SLIME)
+			{
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 0;
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 25;
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 5;
+			}
+			else
+			{
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 130;
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80;
+				cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 50;
+			}
+			cl.cshifts[CSHIFT_CONTENTS].percent = 150 >> 1;
+		}
+		else
 		{
-		case CONTENTS_EMPTY:
-		case CONTENTS_SOLID:
 			cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 0;
 			cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 0;
 			cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 0;
 			cl.cshifts[CSHIFT_CONTENTS].percent = 0;
-			break;
-		case CONTENTS_LAVA:
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 255;
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80;
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 0;
-			cl.cshifts[CSHIFT_CONTENTS].percent = 150 >> 1;
-			break;
-		case CONTENTS_SLIME:
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 0;
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 25;
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 5;
-			cl.cshifts[CSHIFT_CONTENTS].percent = 150 >> 1;
-			break;
-		default:
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[0] = 130;
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[1] = 80;
-			cl.cshifts[CSHIFT_CONTENTS].destcolor[2] = 50;
-			cl.cshifts[CSHIFT_CONTENTS].percent = 128 >> 1;
 		}
 
 		if (gamemode != GAME_TRANSFUSION)
-- 
2.39.5