--- ../../q1source/WinQuake/gl_rmain.c	1999-12-21 15:53:24.000000000 +0200
+++ gl_rmain.c	2002-12-15 14:45:42.000000000 +0200
@@ -108,10 +108,13 @@ R_CullBox
 Returns true if the box is completely outside the frustom
 =================
 */
+extern cvar_t pan;      //aard
+extern cvar_t pfov;
+
 qboolean R_CullBox (vec3_t mins, vec3_t maxs)
 {
 	int		i;
-
+    if(pan.value==1.0 && pfov.value>180.0) return false; //aard
 	for (i=0 ; i<4 ; i++)
 		if (BoxOnPlaneSide (mins, maxs, &frustum[i]) == 2)
 			return true;
@@ -443,6 +446,8 @@ R_DrawAliasModel
 
 =================
 */
+extern cvar_t r_torches; //aard
+
 void R_DrawAliasModel (entity_t *e)
 {
 	int			i, j;
@@ -511,7 +516,10 @@ void R_DrawAliasModel (entity_t *e)
 	// HACK HACK HACK -- no fullbright colors, so make torches full light
 	if (!strcmp (clmodel->name, "progs/flame2.mdl")
 		|| !strcmp (clmodel->name, "progs/flame.mdl") )
-		ambientlight = shadelight = 256;
+    {
+		if(r_torches.value==0) return; //aard
+        ambientlight = shadelight = 256;
+    }
 
 	shadedots = r_avertexnormal_dots[((int)(e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
 	shadelight = shadelight / 200.0;
@@ -824,7 +832,10 @@ void R_SetupFrame (void)
 // build the transformation matrix for the given view angles
 	VectorCopy (r_refdef.vieworg, r_origin);
 
+    //aard: fix frustum for panyaw (hmm doesn't work)
+    //r_refdef.viewangles[YAW] -= r_refdef.panyaw;  //approximation, doesn't account for pitch
 	AngleVectors (r_refdef.viewangles, vpn, vright, vup);
+    //r_refdef.viewangles[YAW] += r_refdef.panyaw;
 
 // current viewleaf
 	r_oldviewleaf = r_viewleaf;
@@ -840,7 +851,7 @@ void R_SetupFrame (void)
 
 }
 
-
+/*
 void MYgluPerspective( GLdouble fovy, GLdouble aspect,
 		     GLdouble zNear, GLdouble zFar )
 {
@@ -854,6 +865,22 @@ void MYgluPerspective( GLdouble fovy, GL
 
    glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
 }
+*/
+
+//aard: calc projection based on fov_x is more accurate for panorama mode
+void MYgluPerspective( GLdouble fovx, GLdouble aspect, 
+		     GLdouble zNear, GLdouble zFar )
+{
+   GLdouble xmin, xmax, ymin, ymax;
+
+   xmax = zNear * tan( fovx * M_PI / 360.0 );
+   xmin = -xmax;
+
+   ymin = xmin / aspect;
+   ymax = xmax / aspect;
+
+   glFrustum( xmin, xmax, ymin, ymax, zNear, zFar );
+}
 
 
 /*
@@ -861,6 +888,7 @@ void MYgluPerspective( GLdouble fovy, GL
 R_SetupGL
 =============
 */
+
 void R_SetupGL (void)
 {
 	float	screenaspect;
@@ -901,7 +929,7 @@ void R_SetupGL (void)
 	glViewport (glx + x, gly + y2, w, h);
     screenaspect = (float)r_refdef.vrect.width/r_refdef.vrect.height;
 //	yfov = 2*atan((float)r_refdef.vrect.height/r_refdef.vrect.width)*180/M_PI;
-    MYgluPerspective (r_refdef.fov_y,  screenaspect,  4,  4096);
+    MYgluPerspective (r_refdef.fov_x,  screenaspect,  4,  4096);//aard
 
 	if (mirror)
 	{
@@ -919,6 +947,10 @@ void R_SetupGL (void)
 
     glRotatef (-90,  1, 0, 0);	    // put Z going up
     glRotatef (90,  0, 0, 1);	    // put Z going up
+    if(pan.value==1.0) //aard: doing this before all other makes mlook work correctly
+    {
+        glRotatef(-r_refdef.panyaw, 0, 0, 1);
+    };
     glRotatef (-r_refdef.viewangles[2],  1, 0, 0);
     glRotatef (-r_refdef.viewangles[0],  0, 1, 0);
     glRotatef (-r_refdef.viewangles[1],  0, 0, 1);
--- ../../q1source/WinQuake/gl_vidlinux.c	1999-12-21 18:42:04.000000000 +0200
+++ gl_vidlinux.c	2002-12-15 14:45:42.000000000 +0200
@@ -314,7 +314,7 @@ void GL_Init (void)
 
 	CheckMultiTextureExtensions ();
 
-	glClearColor (1,0,0,0);
+	glClearColor (1,0,0,0);     //aard
 	glCullFace(GL_FRONT);
 	glEnable(GL_TEXTURE_2D);
 
--- ../../q1source/WinQuake/gl_vidlinuxglx.c	1999-12-21 18:39:36.000000000 +0200
+++ gl_vidlinuxglx.c	2002-12-15 14:45:42.000000000 +0200
@@ -585,7 +585,7 @@ void GL_Init (void)
 
 	CheckMultiTextureExtensions ();
 
-	glClearColor (1,0,0,0);
+	glClearColor (1,0,0,0);     //aard
 	glCullFace(GL_FRONT);
 	glEnable(GL_TEXTURE_2D);
 
--- ../../q1source/WinQuake/gl_vidnt.c	1999-12-21 15:53:24.000000000 +0200
+++ gl_vidnt.c	2002-12-15 14:45:42.000000000 +0200
@@ -619,7 +619,7 @@ void GL_Init (void)
 	CheckTextureExtensions ();
 	CheckMultiTextureExtensions ();
 
-	glClearColor (1,0,0,0);
+	glClearColor (0,0,0,0);     //aard
 	glCullFace(GL_FRONT);
 	glEnable(GL_TEXTURE_2D);
 
--- ../../q1source/WinQuake/r_main.c	1999-12-21 15:53:26.000000000 +0200
+++ r_main.c	2002-12-15 14:45:42.000000000 +0200
@@ -355,11 +355,15 @@ Called every time the vid structure or r
 Guaranteed to be called before the first refresh
 ===============
 */
+extern cvar_t pan; //aard
+
 void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect)
 {
 	int		i;
 	float	res_scale;
 
+    if(pan.value==1.0) aspect = 1.0; //aard: to be sure
+
 	r_viewchanged = true;
 
 	R_SetVrect (pvrect, &r_refdef.vrect, lineadj);
--- ../../q1source/WinQuake/render.h	1999-12-21 15:54:20.000000000 +0200
+++ render.h	2002-12-15 14:45:42.000000000 +0200
@@ -98,6 +98,7 @@ typedef struct
 	float		fov_x, fov_y;
 
 	int			ambientlight;
+    float       panyaw; //aard: needed for modelview matrix setup
 } refdef_t;
 
 
--- ../../q1source/WinQuake/view.c	1999-12-21 15:53:26.000000000 +0200
+++ view.c	2002-12-15 14:45:42.000000000 +0200
@@ -34,6 +34,13 @@ when crossing a water boudnary.
 cvar_t		lcd_x = {"lcd_x","0"};
 cvar_t		lcd_yaw = {"lcd_yaw","0"};
 
+cvar_t	pan = {"pan","1", true};    //aard
+cvar_t	pfov = {"pfov","90", true};
+cvar_t	pslices = {"slices","13", true};
+cvar_t	r_torches = {"r_torches","0", true};
+cvar_t	pyscale = {"pyscale","120", true};
+cvar_t	autoscreenshot = {"autoscreenshot","0", false};
+
 cvar_t	scr_ofsx = {"scr_ofsx","0", false};
 cvar_t	scr_ofsy = {"scr_ofsy","0", false};
 cvar_t	scr_ofsz = {"scr_ofsz","0", false};
@@ -991,6 +998,7 @@ the entity origin, so any view position 
 ==================
 */
 extern vrect_t	scr_vrect;
+int animcount = 0;  //aard
 
 void V_RenderView (void)
 {
@@ -1015,7 +1023,6 @@ void V_RenderView (void)
 			V_CalcRefdef ();
 	}
 
-	R_PushDlights ();
 
 	if (lcd_x.value)
 	{
@@ -1024,6 +1031,8 @@ void V_RenderView (void)
 		//
 		int		i;
 
+	    R_PushDlights ();
+
 		vid.rowbytes <<= 1;
 		vid.aspect *= 0.5;
 
@@ -1048,10 +1057,50 @@ void V_RenderView (void)
 		vid.rowbytes >>= 1;
 		vid.aspect *= 2;
 	}
-	else
+	else if(pan.value==1.0) //aard: render screen in slices
 	{
+        float slices = pslices.value;
+        float wholefov = pfov.value;
+        float pys = pyscale.value;
+        refdef_t t = r_refdef;
+        int slw = t.vrect.width/slices;
+        int i;
+        if(scr_viewsize.value<100) Cvar_SetValue("viewsize", 100);
+        if((((int)slices)&1)==0) Cvar_SetValue("slices", ++slices);
+        if(slices<5) Cvar_SetValue("slices", slices = 5);
+        if(slices>51) Cvar_SetValue("slices", slices = 51);
+        if(wholefov<10)  Cvar_SetValue("pfov", wholefov = 10);
+        if(wholefov>1000) Cvar_SetValue("pfov", wholefov = 1000);
+        if(pys<100)  Cvar_SetValue("pyscale", wholefov = 100);
+        if(pys>200) Cvar_SetValue("pyscale", wholefov = 200);
+        correct:
+        r_refdef.vrect.width = slw;
+        r_refdef.fov_x = wholefov/slices+0.5;
+        r_refdef.vrect.height = (t.vrect.width/wholefov)*pys;
+        r_refdef.fov_y = 100;
+        if(r_refdef.vrect.height>t.vrect.height)
+        {
+            Cvar_SetValue("pfov", wholefov += 1);
+            goto correct;
+        };
+        r_refdef.vrect.y = (t.vrect.height-r_refdef.vrect.height)/2;
+	    r_refdef.horizontalFieldOfView = 2.0 * tan (r_refdef.fov_x/360*M_PI);
+        for(i = 0; i<slices; i++)
+        {
+            gl_clear.value = !i;
+            r_refdef.panyaw = -((i-slices/2+0.5)*(wholefov/slices));
+            r_refdef.vrect.x = i*slw+(t.vrect.width-slw*slices)/2;
+            R_PushDlights ();
+		    R_RenderView ();
+        };
+        r_refdef = t;
+        Sbar_Changed();
+	}
+    else
+    {
+    	R_PushDlights ();
 		R_RenderView ();
-	}
+    };
 
 #ifndef GLQUAKE
 	if (crosshair.value)
@@ -1059,6 +1108,46 @@ void V_RenderView (void)
 			scr_vrect.y + scr_vrect.height/2 + cl_crossy.value, '+');
 #endif
 		
+    //aard: adapted copy of screenshot code
+    if(cls.demoplayback && autoscreenshot.value==1.0)
+    {
+	    byte		*buffer;
+	    char		pcxname[MAX_OSPATH]; 
+	    int			i, c, temp;
+
+        if(animcount++)
+        {
+	        sprintf(pcxname, "ani%05d.tga", animcount-2);
+		        
+	        buffer = malloc(glwidth*glheight*3 + 18);
+	        memset (buffer, 0, 18);
+	        buffer[2] = 2;		// uncompressed type
+	        buffer[12] = glwidth&255;
+	        buffer[13] = glwidth>>8;
+	        buffer[14] = glheight&255;
+	        buffer[15] = glheight>>8;
+	        buffer[16] = 24;	// pixel size
+
+	        glReadPixels (glx, gly, glwidth, glheight, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); 
+
+	        // swap rgb to bgr
+	        c = 18+glwidth*glheight*3;
+	        for (i=18 ; i<c ; i+=3)
+	        {
+		        temp = buffer[i];
+		        buffer[i] = buffer[i+2];
+		        buffer[i+2] = temp;
+	        }
+
+	        COM_WriteFile (pcxname, buffer, glwidth*glheight*3 + 18 );
+
+	        free (buffer);
+        };
+    }
+    else
+    {
+        animcount = 0;
+    };
 }
 
 //============================================================================
@@ -1077,6 +1166,13 @@ void V_Init (void)
 	Cvar_RegisterVariable (&lcd_x);
 	Cvar_RegisterVariable (&lcd_yaw);
 
+	Cvar_RegisterVariable (&pan);   //aard
+	Cvar_RegisterVariable (&pfov);
+	Cvar_RegisterVariable (&pslices);
+	Cvar_RegisterVariable (&r_torches);
+	Cvar_RegisterVariable (&pyscale);
+	Cvar_RegisterVariable (&autoscreenshot);
+
 	Cvar_RegisterVariable (&v_centermove);
 	Cvar_RegisterVariable (&v_centerspeed);
 
