shithub: qk2

Download patch

ref: 0a3f54086a5d97c57bd6ffb1ca4a6296ed19b441
parent: fe87c990e0e84be637a8a743f2dd9d48ae6f5895
author: Konstantinn Bonnet <qu7uux@gmail.com>
date: Fri Mar 13 08:11:31 EDT 2015

shuffle code around more

diff: cannot open b/ref//null: file does not exist: 'b/ref//null' diff: cannot open a/ref_soft//null: file does not exist: 'a/ref_soft//null'
--- a/mkfile
+++ b/mkfile
@@ -5,7 +5,7 @@
 
 CLDIR=client
 SVDIR=server
-SRDIR=ref_soft
+SRDIR=ref
 CMDIR=qcommon
 P9DIR=plan9
 GMDIR=game
@@ -51,12 +51,12 @@
 	$SVDIR/sv_send.$O\
 	$SVDIR/sv_user.$O\
 	$SVDIR/sv_world.$O\
-	$P9DIR/cd_linux.$O\
-	$P9DIR/q_shlinux.$O\
+	$P9DIR/cd_9.$O\
+	$P9DIR/q_sh9.$O\
 	$P9DIR/vid_menu.$O\
 	$P9DIR/vid_so.$O\
-	$P9DIR/snd_linux.$O\
-	$P9DIR/sys_linux.$O\
+	$P9DIR/snd_9.$O\
+	$P9DIR/sys_9.$O\
 	$P9DIR/glob.$O\
 	$P9DIR/net_udp.$O\
 
@@ -260,9 +260,9 @@
 	$SRDIR/r_sprite.$O\
 	$SRDIR/r_surf.$O\
 	$GMDIR/q_shared.$O\
-	$P9DIR/q_shlinux.$O\
+	$P9DIR/q_sh9.$O\
 	$P9DIR/glob.$O\
-	$P9DIR/rw_x11.$O\
+	$P9DIR/rw_9.$O\
 
 SRHFILES=\
 	$SRDIR/adivtab.h\
--- /dev/null
+++ b/plan9/cd_9.c
@@ -1,0 +1,420 @@
+// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
+// rights reserved.
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include <linux/cdrom.h>
+
+#include "../client/client.h"
+
+static qboolean cdValid = false;
+static qboolean	playing = false;
+static qboolean	wasPlaying = false;
+static qboolean	initialized = false;
+static qboolean	enabled = true;
+static qboolean playLooping = false;
+static float	cdvolume;
+static byte 	remap[100];
+static byte		playTrack;
+static byte		maxTrack;
+
+static int cdfile = -1;
+
+//static char cd_dev[64] = "/dev/cdrom";
+
+cvar_t	*cd_volume;
+cvar_t *cd_nocd;
+cvar_t *cd_dev;
+
+void CDAudio_Pause(void);
+
+static void CDAudio_Eject(void)
+{
+	if (cdfile == -1 || !enabled)
+		return; // no cd init'd
+
+	if ( ioctl(cdfile, CDROMEJECT) == -1 ) 
+		Com_DPrintf("ioctl cdromeject failed\n");
+}
+
+
+static void CDAudio_CloseDoor(void)
+{
+	if (cdfile == -1 || !enabled)
+		return; // no cd init'd
+
+	if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) 
+		Com_DPrintf("ioctl cdromclosetray failed\n");
+}
+
+static int CDAudio_GetAudioDiskInfo(void)
+{
+	struct cdrom_tochdr tochdr;
+
+	cdValid = false;
+
+	if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) 
+    {
+      Com_DPrintf("ioctl cdromreadtochdr failed\n");
+	  return -1;
+    }
+
+	if (tochdr.cdth_trk0 < 1)
+	{
+		Com_DPrintf("CDAudio: no music tracks\n");
+		return -1;
+	}
+
+	cdValid = true;
+	maxTrack = tochdr.cdth_trk1;
+
+	return 0;
+}
+
+
+void CDAudio_Play(int track, qboolean looping)
+{
+	struct cdrom_tocentry entry;
+	struct cdrom_ti ti;
+
+	if (cdfile == -1 || !enabled)
+		return;
+	
+	if (!cdValid)
+	{
+		CDAudio_GetAudioDiskInfo();
+		if (!cdValid)
+			return;
+	}
+
+	track = remap[track];
+
+	if (track < 1 || track > maxTrack)
+	{
+		Com_DPrintf("CDAudio: Bad track number %u.\n", track);
+		return;
+	}
+
+	// don't try to play a non-audio track
+	entry.cdte_track = track;
+	entry.cdte_format = CDROM_MSF;
+    if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
+	{
+		Com_DPrintf("ioctl cdromreadtocentry failed\n");
+		return;
+	}
+	if (entry.cdte_ctrl == CDROM_DATA_TRACK)
+	{
+		Com_Printf("CDAudio: track %i is not audio\n", track);
+		return;
+	}
+
+	if (playing)
+	{
+		if (playTrack == track)
+			return;
+		CDAudio_Stop();
+	}
+
+	ti.cdti_trk0 = track;
+	ti.cdti_trk1 = track;
+	ti.cdti_ind0 = 1;
+	ti.cdti_ind1 = 99;
+
+	if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) 
+    {
+		Com_DPrintf("ioctl cdromplaytrkind failed\n");
+		return;
+    }
+
+	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
+		Com_DPrintf("ioctl cdromresume failed\n");
+
+	playLooping = looping;
+	playTrack = track;
+	playing = true;
+
+	if (cd_volume->value == 0.0)
+		CDAudio_Pause ();
+}
+
+
+void CDAudio_Stop(void)
+{
+	if (cdfile == -1 || !enabled)
+		return;
+	
+	if (!playing)
+		return;
+
+	if ( ioctl(cdfile, CDROMSTOP) == -1 )
+		Com_DPrintf("ioctl cdromstop failed (%d)\n", errno);
+
+	wasPlaying = false;
+	playing = false;
+}
+
+void CDAudio_Pause(void)
+{
+	if (cdfile == -1 || !enabled)
+		return;
+
+	if (!playing)
+		return;
+
+	if ( ioctl(cdfile, CDROMPAUSE) == -1 ) 
+		Com_DPrintf("ioctl cdrompause failed\n");
+
+	wasPlaying = playing;
+	playing = false;
+}
+
+
+void CDAudio_Resume(void)
+{
+	if (cdfile == -1 || !enabled)
+		return;
+	
+	if (!cdValid)
+		return;
+
+	if (!wasPlaying)
+		return;
+	
+	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
+		Com_DPrintf("ioctl cdromresume failed\n");
+	playing = true;
+}
+
+static void CD_f (void)
+{
+	char	*command;
+	int		ret;
+	int		n;
+
+	if (Cmd_Argc() < 2)
+		return;
+
+	command = Cmd_Argv (1);
+
+	if (Q_strcasecmp(command, "on") == 0)
+	{
+		enabled = true;
+		return;
+	}
+
+	if (Q_strcasecmp(command, "off") == 0)
+	{
+		if (playing)
+			CDAudio_Stop();
+		enabled = false;
+		return;
+	}
+
+	if (Q_strcasecmp(command, "reset") == 0)
+	{
+		enabled = true;
+		if (playing)
+			CDAudio_Stop();
+		for (n = 0; n < 100; n++)
+			remap[n] = n;
+		CDAudio_GetAudioDiskInfo();
+		return;
+	}
+
+	if (Q_strcasecmp(command, "remap") == 0)
+	{
+		ret = Cmd_Argc() - 2;
+		if (ret <= 0)
+		{
+			for (n = 1; n < 100; n++)
+				if (remap[n] != n)
+					Com_Printf("  %u -> %u\n", n, remap[n]);
+			return;
+		}
+		for (n = 1; n <= ret; n++)
+			remap[n] = atoi(Cmd_Argv (n+1));
+		return;
+	}
+
+	if (Q_strcasecmp(command, "close") == 0)
+	{
+		CDAudio_CloseDoor();
+		return;
+	}
+
+	if (!cdValid)
+	{
+		CDAudio_GetAudioDiskInfo();
+		if (!cdValid)
+		{
+			Com_Printf("No CD in player.\n");
+			return;
+		}
+	}
+
+	if (Q_strcasecmp(command, "play") == 0)
+	{
+		CDAudio_Play((byte)atoi(Cmd_Argv (2)), false);
+		return;
+	}
+
+	if (Q_strcasecmp(command, "loop") == 0)
+	{
+		CDAudio_Play((byte)atoi(Cmd_Argv (2)), true);
+		return;
+	}
+
+	if (Q_strcasecmp(command, "stop") == 0)
+	{
+		CDAudio_Stop();
+		return;
+	}
+
+	if (Q_strcasecmp(command, "pause") == 0)
+	{
+		CDAudio_Pause();
+		return;
+	}
+
+	if (Q_strcasecmp(command, "resume") == 0)
+	{
+		CDAudio_Resume();
+		return;
+	}
+
+	if (Q_strcasecmp(command, "eject") == 0)
+	{
+		if (playing)
+			CDAudio_Stop();
+		CDAudio_Eject();
+		cdValid = false;
+		return;
+	}
+
+	if (Q_strcasecmp(command, "info") == 0)
+	{
+		Com_Printf("%u tracks\n", maxTrack);
+		if (playing)
+			Com_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
+		else if (wasPlaying)
+			Com_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
+		Com_Printf("Volume is %f\n", cdvolume);
+		return;
+	}
+}
+
+void CDAudio_Update(void)
+{
+	struct cdrom_subchnl subchnl;
+	static time_t lastchk;
+
+	if (cdfile == -1 || !enabled)
+		return;
+
+	if (cd_volume && cd_volume->value != cdvolume)
+	{
+		if (cdvolume)
+		{
+			Cvar_SetValue ("cd_volume", 0.0);
+			cdvolume = cd_volume->value;
+			CDAudio_Pause ();
+		}
+		else
+		{
+			Cvar_SetValue ("cd_volume", 1.0);
+			cdvolume = cd_volume->value;
+			CDAudio_Resume ();
+		}
+	}
+
+	if (playing && lastchk < time(NULL)) {
+		lastchk = time(NULL) + 2; //two seconds between chks
+		subchnl.cdsc_format = CDROM_MSF;
+		if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
+			Com_DPrintf("ioctl cdromsubchnl failed\n");
+			playing = false;
+			return;
+		}
+		if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
+			subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
+			playing = false;
+			if (playLooping)
+				CDAudio_Play(playTrack, true);
+		}
+	}
+}
+
+int CDAudio_Init(void)
+{
+	int i;
+	cvar_t			*cv;
+	extern uid_t saved_euid;
+
+	cv = Cvar_Get ("nocdaudio", "0", CVAR_NOSET);
+	if (cv->value)
+		return -1;
+
+	cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE );
+	if ( cd_nocd->value)
+		return -1;
+
+	cd_volume = Cvar_Get ("cd_volume", "1", CVAR_ARCHIVE);
+
+	cd_dev = Cvar_Get("cd_dev", "/dev/cdrom", CVAR_ARCHIVE);
+
+	seteuid(saved_euid);
+
+	cdfile = open(cd_dev->string, O_RDONLY);
+
+	seteuid(getuid());
+
+	if (cdfile == -1) {
+		Com_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev->string, errno);
+		cdfile = -1;
+		return -1;
+	}
+
+	for (i = 0; i < 100; i++)
+		remap[i] = i;
+	initialized = true;
+	enabled = true;
+
+	if (CDAudio_GetAudioDiskInfo())
+	{
+		Com_Printf("CDAudio_Init: No CD in player.\n");
+		cdValid = false;
+	}
+
+	Cmd_AddCommand ("cd", CD_f);
+
+	Com_Printf("CD Audio Initialized\n");
+
+	return 0;
+}
+
+void CDAudio_Activate (qboolean active)
+{
+	if (active)
+		CDAudio_Resume ();
+	else
+		CDAudio_Pause ();
+}
+
+void CDAudio_Shutdown(void)
+{
+	if (!initialized)
+		return;
+	CDAudio_Stop();
+	close(cdfile);
+	cdfile = -1;
+}
--- a/plan9/cd_linux.c
+++ /dev/null
@@ -1,420 +1,0 @@
-// Quake is a trademark of Id Software, Inc., (c) 1996 Id Software, Inc. All
-// rights reserved.
-
-#include <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <string.h>
-#include <time.h>
-#include <errno.h>
-
-#include <linux/cdrom.h>
-
-#include "../client/client.h"
-
-static qboolean cdValid = false;
-static qboolean	playing = false;
-static qboolean	wasPlaying = false;
-static qboolean	initialized = false;
-static qboolean	enabled = true;
-static qboolean playLooping = false;
-static float	cdvolume;
-static byte 	remap[100];
-static byte		playTrack;
-static byte		maxTrack;
-
-static int cdfile = -1;
-
-//static char cd_dev[64] = "/dev/cdrom";
-
-cvar_t	*cd_volume;
-cvar_t *cd_nocd;
-cvar_t *cd_dev;
-
-void CDAudio_Pause(void);
-
-static void CDAudio_Eject(void)
-{
-	if (cdfile == -1 || !enabled)
-		return; // no cd init'd
-
-	if ( ioctl(cdfile, CDROMEJECT) == -1 ) 
-		Com_DPrintf("ioctl cdromeject failed\n");
-}
-
-
-static void CDAudio_CloseDoor(void)
-{
-	if (cdfile == -1 || !enabled)
-		return; // no cd init'd
-
-	if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) 
-		Com_DPrintf("ioctl cdromclosetray failed\n");
-}
-
-static int CDAudio_GetAudioDiskInfo(void)
-{
-	struct cdrom_tochdr tochdr;
-
-	cdValid = false;
-
-	if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) 
-    {
-      Com_DPrintf("ioctl cdromreadtochdr failed\n");
-	  return -1;
-    }
-
-	if (tochdr.cdth_trk0 < 1)
-	{
-		Com_DPrintf("CDAudio: no music tracks\n");
-		return -1;
-	}
-
-	cdValid = true;
-	maxTrack = tochdr.cdth_trk1;
-
-	return 0;
-}
-
-
-void CDAudio_Play(int track, qboolean looping)
-{
-	struct cdrom_tocentry entry;
-	struct cdrom_ti ti;
-
-	if (cdfile == -1 || !enabled)
-		return;
-	
-	if (!cdValid)
-	{
-		CDAudio_GetAudioDiskInfo();
-		if (!cdValid)
-			return;
-	}
-
-	track = remap[track];
-
-	if (track < 1 || track > maxTrack)
-	{
-		Com_DPrintf("CDAudio: Bad track number %u.\n", track);
-		return;
-	}
-
-	// don't try to play a non-audio track
-	entry.cdte_track = track;
-	entry.cdte_format = CDROM_MSF;
-    if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
-	{
-		Com_DPrintf("ioctl cdromreadtocentry failed\n");
-		return;
-	}
-	if (entry.cdte_ctrl == CDROM_DATA_TRACK)
-	{
-		Com_Printf("CDAudio: track %i is not audio\n", track);
-		return;
-	}
-
-	if (playing)
-	{
-		if (playTrack == track)
-			return;
-		CDAudio_Stop();
-	}
-
-	ti.cdti_trk0 = track;
-	ti.cdti_trk1 = track;
-	ti.cdti_ind0 = 1;
-	ti.cdti_ind1 = 99;
-
-	if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) 
-    {
-		Com_DPrintf("ioctl cdromplaytrkind failed\n");
-		return;
-    }
-
-	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
-		Com_DPrintf("ioctl cdromresume failed\n");
-
-	playLooping = looping;
-	playTrack = track;
-	playing = true;
-
-	if (cd_volume->value == 0.0)
-		CDAudio_Pause ();
-}
-
-
-void CDAudio_Stop(void)
-{
-	if (cdfile == -1 || !enabled)
-		return;
-	
-	if (!playing)
-		return;
-
-	if ( ioctl(cdfile, CDROMSTOP) == -1 )
-		Com_DPrintf("ioctl cdromstop failed (%d)\n", errno);
-
-	wasPlaying = false;
-	playing = false;
-}
-
-void CDAudio_Pause(void)
-{
-	if (cdfile == -1 || !enabled)
-		return;
-
-	if (!playing)
-		return;
-
-	if ( ioctl(cdfile, CDROMPAUSE) == -1 ) 
-		Com_DPrintf("ioctl cdrompause failed\n");
-
-	wasPlaying = playing;
-	playing = false;
-}
-
-
-void CDAudio_Resume(void)
-{
-	if (cdfile == -1 || !enabled)
-		return;
-	
-	if (!cdValid)
-		return;
-
-	if (!wasPlaying)
-		return;
-	
-	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
-		Com_DPrintf("ioctl cdromresume failed\n");
-	playing = true;
-}
-
-static void CD_f (void)
-{
-	char	*command;
-	int		ret;
-	int		n;
-
-	if (Cmd_Argc() < 2)
-		return;
-
-	command = Cmd_Argv (1);
-
-	if (Q_strcasecmp(command, "on") == 0)
-	{
-		enabled = true;
-		return;
-	}
-
-	if (Q_strcasecmp(command, "off") == 0)
-	{
-		if (playing)
-			CDAudio_Stop();
-		enabled = false;
-		return;
-	}
-
-	if (Q_strcasecmp(command, "reset") == 0)
-	{
-		enabled = true;
-		if (playing)
-			CDAudio_Stop();
-		for (n = 0; n < 100; n++)
-			remap[n] = n;
-		CDAudio_GetAudioDiskInfo();
-		return;
-	}
-
-	if (Q_strcasecmp(command, "remap") == 0)
-	{
-		ret = Cmd_Argc() - 2;
-		if (ret <= 0)
-		{
-			for (n = 1; n < 100; n++)
-				if (remap[n] != n)
-					Com_Printf("  %u -> %u\n", n, remap[n]);
-			return;
-		}
-		for (n = 1; n <= ret; n++)
-			remap[n] = atoi(Cmd_Argv (n+1));
-		return;
-	}
-
-	if (Q_strcasecmp(command, "close") == 0)
-	{
-		CDAudio_CloseDoor();
-		return;
-	}
-
-	if (!cdValid)
-	{
-		CDAudio_GetAudioDiskInfo();
-		if (!cdValid)
-		{
-			Com_Printf("No CD in player.\n");
-			return;
-		}
-	}
-
-	if (Q_strcasecmp(command, "play") == 0)
-	{
-		CDAudio_Play((byte)atoi(Cmd_Argv (2)), false);
-		return;
-	}
-
-	if (Q_strcasecmp(command, "loop") == 0)
-	{
-		CDAudio_Play((byte)atoi(Cmd_Argv (2)), true);
-		return;
-	}
-
-	if (Q_strcasecmp(command, "stop") == 0)
-	{
-		CDAudio_Stop();
-		return;
-	}
-
-	if (Q_strcasecmp(command, "pause") == 0)
-	{
-		CDAudio_Pause();
-		return;
-	}
-
-	if (Q_strcasecmp(command, "resume") == 0)
-	{
-		CDAudio_Resume();
-		return;
-	}
-
-	if (Q_strcasecmp(command, "eject") == 0)
-	{
-		if (playing)
-			CDAudio_Stop();
-		CDAudio_Eject();
-		cdValid = false;
-		return;
-	}
-
-	if (Q_strcasecmp(command, "info") == 0)
-	{
-		Com_Printf("%u tracks\n", maxTrack);
-		if (playing)
-			Com_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
-		else if (wasPlaying)
-			Com_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
-		Com_Printf("Volume is %f\n", cdvolume);
-		return;
-	}
-}
-
-void CDAudio_Update(void)
-{
-	struct cdrom_subchnl subchnl;
-	static time_t lastchk;
-
-	if (cdfile == -1 || !enabled)
-		return;
-
-	if (cd_volume && cd_volume->value != cdvolume)
-	{
-		if (cdvolume)
-		{
-			Cvar_SetValue ("cd_volume", 0.0);
-			cdvolume = cd_volume->value;
-			CDAudio_Pause ();
-		}
-		else
-		{
-			Cvar_SetValue ("cd_volume", 1.0);
-			cdvolume = cd_volume->value;
-			CDAudio_Resume ();
-		}
-	}
-
-	if (playing && lastchk < time(NULL)) {
-		lastchk = time(NULL) + 2; //two seconds between chks
-		subchnl.cdsc_format = CDROM_MSF;
-		if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
-			Com_DPrintf("ioctl cdromsubchnl failed\n");
-			playing = false;
-			return;
-		}
-		if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
-			subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
-			playing = false;
-			if (playLooping)
-				CDAudio_Play(playTrack, true);
-		}
-	}
-}
-
-int CDAudio_Init(void)
-{
-	int i;
-	cvar_t			*cv;
-	extern uid_t saved_euid;
-
-	cv = Cvar_Get ("nocdaudio", "0", CVAR_NOSET);
-	if (cv->value)
-		return -1;
-
-	cd_nocd = Cvar_Get ("cd_nocd", "0", CVAR_ARCHIVE );
-	if ( cd_nocd->value)
-		return -1;
-
-	cd_volume = Cvar_Get ("cd_volume", "1", CVAR_ARCHIVE);
-
-	cd_dev = Cvar_Get("cd_dev", "/dev/cdrom", CVAR_ARCHIVE);
-
-	seteuid(saved_euid);
-
-	cdfile = open(cd_dev->string, O_RDONLY);
-
-	seteuid(getuid());
-
-	if (cdfile == -1) {
-		Com_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev->string, errno);
-		cdfile = -1;
-		return -1;
-	}
-
-	for (i = 0; i < 100; i++)
-		remap[i] = i;
-	initialized = true;
-	enabled = true;
-
-	if (CDAudio_GetAudioDiskInfo())
-	{
-		Com_Printf("CDAudio_Init: No CD in player.\n");
-		cdValid = false;
-	}
-
-	Cmd_AddCommand ("cd", CD_f);
-
-	Com_Printf("CD Audio Initialized\n");
-
-	return 0;
-}
-
-void CDAudio_Activate (qboolean active)
-{
-	if (active)
-		CDAudio_Resume ();
-	else
-		CDAudio_Pause ();
-}
-
-void CDAudio_Shutdown(void)
-{
-	if (!initialized)
-		return;
-	CDAudio_Stop();
-	close(cdfile);
-	cdfile = -1;
-}
--- /dev/null
+++ b/plan9/in_9.c
@@ -1,0 +1,29 @@
+// in_null.c -- for systems without a mouse
+
+#include "../client/client.h"
+
+cvar_t	*in_mouse;
+cvar_t	*in_joystick;
+
+void IN_Init (void)
+{
+    in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
+    in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE);
+}
+
+void IN_Shutdown (void)
+{
+}
+
+void IN_Commands (void)
+{
+}
+
+void IN_Move (usercmd_t *cmd)
+{
+}
+
+void IN_Activate (qboolean active)
+{
+}
+
--- a/plan9/in_linux.c
+++ /dev/null
@@ -1,29 +1,0 @@
-// in_null.c -- for systems without a mouse
-
-#include "../client/client.h"
-
-cvar_t	*in_mouse;
-cvar_t	*in_joystick;
-
-void IN_Init (void)
-{
-    in_mouse = Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
-    in_joystick = Cvar_Get ("in_joystick", "0", CVAR_ARCHIVE);
-}
-
-void IN_Shutdown (void)
-{
-}
-
-void IN_Commands (void)
-{
-}
-
-void IN_Move (usercmd_t *cmd)
-{
-}
-
-void IN_Activate (qboolean active)
-{
-}
-
--- /dev/null
+++ b/plan9/q_sh9.c
@@ -1,0 +1,205 @@
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/time.h>
+
+#include "../linux/glob.h"
+
+#include "../qcommon/qcommon.h"
+
+//===============================================================================
+
+byte *membase;
+int maxhunksize;
+int curhunksize;
+
+void *Hunk_Begin (int maxsize)
+{
+	// reserve a huge chunk of memory, but don't commit any yet
+	maxhunksize = maxsize + sizeof(int);
+	curhunksize = 0;
+	membase = mmap(0, maxhunksize, PROT_READ|PROT_WRITE, 
+		MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+	if (membase == NULL || membase == (byte *)-1)
+		Sys_Error("unable to virtual allocate %d bytes", maxsize);
+
+	*((int *)membase) = curhunksize;
+
+	return membase + sizeof(int);
+}
+
+void *Hunk_Alloc (int size)
+{
+	byte *buf;
+
+	// round to cacheline
+	size = (size+31)&~31;
+	if (curhunksize + size > maxhunksize)
+		Sys_Error("Hunk_Alloc overflow");
+	buf = membase + sizeof(int) + curhunksize;
+	curhunksize += size;
+	return buf;
+}
+
+int Hunk_End (void)
+{
+	byte *n;
+
+	n = mremap(membase, maxhunksize, curhunksize + sizeof(int), 0);
+	if (n != membase)
+		Sys_Error("Hunk_End:  Could not remap virtual block (%d)", errno);
+	*((int *)membase) = curhunksize + sizeof(int);
+	
+	return curhunksize;
+}
+
+void Hunk_Free (void *base)
+{
+	byte *m;
+
+	if (base) {
+		m = ((byte *)base) - sizeof(int);
+		if (munmap(m, *((int *)m)))
+			Sys_Error("Hunk_Free: munmap failed (%d)", errno);
+	}
+}
+
+//===============================================================================
+
+
+/*
+================
+Sys_Milliseconds
+================
+*/
+int curtime;
+int Sys_Milliseconds (void)
+{
+	struct timeval tp;
+	struct timezone tzp;
+	static int		secbase;
+
+	gettimeofday(&tp, &tzp);
+	
+	if (!secbase)
+	{
+		secbase = tp.tv_sec;
+		return tp.tv_usec/1000;
+	}
+
+	curtime = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
+	
+	return curtime;
+}
+
+void Sys_Mkdir (char *path)
+{
+    mkdir (path, 0777);
+}
+
+char *strlwr (char *s)
+{
+	while (*s) {
+		*s = tolower(*s);
+		s++;
+	}
+}
+
+//============================================
+
+static	char	findbase[MAX_OSPATH];
+static	char	findpath[MAX_OSPATH];
+static	char	findpattern[MAX_OSPATH];
+static	DIR		*fdir;
+
+static qboolean CompareAttributes(char *path, char *name,
+	unsigned musthave, unsigned canthave )
+{
+	struct stat st;
+	char fn[MAX_OSPATH];
+
+// . and .. never match
+	if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
+		return false;
+
+	sprintf(fn, "%s/%s", path, name);
+	if (stat(fn, &st) == -1)
+		return false; // shouldn't happen
+
+	if ( ( st.st_mode & S_IFDIR ) && ( canthave & SFF_SUBDIR ) )
+		return false;
+
+	if ( ( musthave & SFF_SUBDIR ) && !( st.st_mode & S_IFDIR ) )
+		return false;
+
+	return true;
+}
+
+char *Sys_FindFirst (char *path, unsigned musthave, unsigned canhave)
+{
+	struct dirent *d;
+	char *p;
+
+	if (fdir)
+		Sys_Error ("Sys_BeginFind without close");
+
+//	COM_FilePath (path, findbase);
+	strcpy(findbase, path);
+
+	if ((p = strrchr(findbase, '/')) != NULL) {
+		*p = 0;
+		strcpy(findpattern, p + 1);
+	} else
+		strcpy(findpattern, "*");
+
+	if (strcmp(findpattern, "*.*") == 0)
+		strcpy(findpattern, "*");
+	
+	if ((fdir = opendir(findbase)) == NULL)
+		return NULL;
+	while ((d = readdir(fdir)) != NULL) {
+		if (!*findpattern || glob_match(findpattern, d->d_name)) {
+//			if (*findpattern)
+//				printf("%s matched %s\n", findpattern, d->d_name);
+			if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
+				sprintf (findpath, "%s/%s", findbase, d->d_name);
+				return findpath;
+			}
+		}
+	}
+	return NULL;
+}
+
+char *Sys_FindNext (unsigned musthave, unsigned canhave)
+{
+	struct dirent *d;
+
+	if (fdir == NULL)
+		return NULL;
+	while ((d = readdir(fdir)) != NULL) {
+		if (!*findpattern || glob_match(findpattern, d->d_name)) {
+//			if (*findpattern)
+//				printf("%s matched %s\n", findpattern, d->d_name);
+			if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
+				sprintf (findpath, "%s/%s", findbase, d->d_name);
+				return findpath;
+			}
+		}
+	}
+	return NULL;
+}
+
+void Sys_FindClose (void)
+{
+	if (fdir != NULL)
+		closedir(fdir);
+	fdir = NULL;
+}
+
+
+//============================================
+
--- a/plan9/q_shlinux.c
+++ /dev/null
@@ -1,205 +1,0 @@
-#include <sys/types.h>
-#include <errno.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-
-#include "../linux/glob.h"
-
-#include "../qcommon/qcommon.h"
-
-//===============================================================================
-
-byte *membase;
-int maxhunksize;
-int curhunksize;
-
-void *Hunk_Begin (int maxsize)
-{
-	// reserve a huge chunk of memory, but don't commit any yet
-	maxhunksize = maxsize + sizeof(int);
-	curhunksize = 0;
-	membase = mmap(0, maxhunksize, PROT_READ|PROT_WRITE, 
-		MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
-	if (membase == NULL || membase == (byte *)-1)
-		Sys_Error("unable to virtual allocate %d bytes", maxsize);
-
-	*((int *)membase) = curhunksize;
-
-	return membase + sizeof(int);
-}
-
-void *Hunk_Alloc (int size)
-{
-	byte *buf;
-
-	// round to cacheline
-	size = (size+31)&~31;
-	if (curhunksize + size > maxhunksize)
-		Sys_Error("Hunk_Alloc overflow");
-	buf = membase + sizeof(int) + curhunksize;
-	curhunksize += size;
-	return buf;
-}
-
-int Hunk_End (void)
-{
-	byte *n;
-
-	n = mremap(membase, maxhunksize, curhunksize + sizeof(int), 0);
-	if (n != membase)
-		Sys_Error("Hunk_End:  Could not remap virtual block (%d)", errno);
-	*((int *)membase) = curhunksize + sizeof(int);
-	
-	return curhunksize;
-}
-
-void Hunk_Free (void *base)
-{
-	byte *m;
-
-	if (base) {
-		m = ((byte *)base) - sizeof(int);
-		if (munmap(m, *((int *)m)))
-			Sys_Error("Hunk_Free: munmap failed (%d)", errno);
-	}
-}
-
-//===============================================================================
-
-
-/*
-================
-Sys_Milliseconds
-================
-*/
-int curtime;
-int Sys_Milliseconds (void)
-{
-	struct timeval tp;
-	struct timezone tzp;
-	static int		secbase;
-
-	gettimeofday(&tp, &tzp);
-	
-	if (!secbase)
-	{
-		secbase = tp.tv_sec;
-		return tp.tv_usec/1000;
-	}
-
-	curtime = (tp.tv_sec - secbase)*1000 + tp.tv_usec/1000;
-	
-	return curtime;
-}
-
-void Sys_Mkdir (char *path)
-{
-    mkdir (path, 0777);
-}
-
-char *strlwr (char *s)
-{
-	while (*s) {
-		*s = tolower(*s);
-		s++;
-	}
-}
-
-//============================================
-
-static	char	findbase[MAX_OSPATH];
-static	char	findpath[MAX_OSPATH];
-static	char	findpattern[MAX_OSPATH];
-static	DIR		*fdir;
-
-static qboolean CompareAttributes(char *path, char *name,
-	unsigned musthave, unsigned canthave )
-{
-	struct stat st;
-	char fn[MAX_OSPATH];
-
-// . and .. never match
-	if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
-		return false;
-
-	sprintf(fn, "%s/%s", path, name);
-	if (stat(fn, &st) == -1)
-		return false; // shouldn't happen
-
-	if ( ( st.st_mode & S_IFDIR ) && ( canthave & SFF_SUBDIR ) )
-		return false;
-
-	if ( ( musthave & SFF_SUBDIR ) && !( st.st_mode & S_IFDIR ) )
-		return false;
-
-	return true;
-}
-
-char *Sys_FindFirst (char *path, unsigned musthave, unsigned canhave)
-{
-	struct dirent *d;
-	char *p;
-
-	if (fdir)
-		Sys_Error ("Sys_BeginFind without close");
-
-//	COM_FilePath (path, findbase);
-	strcpy(findbase, path);
-
-	if ((p = strrchr(findbase, '/')) != NULL) {
-		*p = 0;
-		strcpy(findpattern, p + 1);
-	} else
-		strcpy(findpattern, "*");
-
-	if (strcmp(findpattern, "*.*") == 0)
-		strcpy(findpattern, "*");
-	
-	if ((fdir = opendir(findbase)) == NULL)
-		return NULL;
-	while ((d = readdir(fdir)) != NULL) {
-		if (!*findpattern || glob_match(findpattern, d->d_name)) {
-//			if (*findpattern)
-//				printf("%s matched %s\n", findpattern, d->d_name);
-			if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
-				sprintf (findpath, "%s/%s", findbase, d->d_name);
-				return findpath;
-			}
-		}
-	}
-	return NULL;
-}
-
-char *Sys_FindNext (unsigned musthave, unsigned canhave)
-{
-	struct dirent *d;
-
-	if (fdir == NULL)
-		return NULL;
-	while ((d = readdir(fdir)) != NULL) {
-		if (!*findpattern || glob_match(findpattern, d->d_name)) {
-//			if (*findpattern)
-//				printf("%s matched %s\n", findpattern, d->d_name);
-			if (CompareAttributes(findbase, d->d_name, musthave, canhave)) {
-				sprintf (findpath, "%s/%s", findbase, d->d_name);
-				return findpath;
-			}
-		}
-	}
-	return NULL;
-}
-
-void Sys_FindClose (void)
-{
-	if (fdir != NULL)
-		closedir(fdir);
-	fdir = NULL;
-}
-
-
-//============================================
-
--- /dev/null
+++ b/plan9/rw_9.c
@@ -1,0 +1,1093 @@
+/*
+** RW_X11.C
+**
+** This file contains ALL Linux specific stuff having to do with the
+** software refresh.  When a port is being made the following functions
+** must be implemented by the port:
+**
+** SWimp_EndFrame
+** SWimp_Init
+** SWimp_InitGraphics
+** SWimp_SetPalette
+** SWimp_Shutdown
+** SWimp_SwitchFullscreen
+*/
+
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/keysym.h>
+#include <X11/extensions/XShm.h>
+
+#include "../ref_soft/r_local.h"
+#include "../client/keys.h"
+#include "../linux/rw_linux.h"
+
+/*****************************************************************************/
+
+static qboolean			doShm;
+static Display			*x_disp;
+static Colormap			x_cmap;
+static Window			x_win;
+static GC				x_gc;
+static Visual			*x_vis;
+static XVisualInfo		*x_visinfo;
+//static XImage			*x_image;
+
+#define STD_EVENT_MASK (StructureNotifyMask | KeyPressMask \
+	     | KeyReleaseMask | ExposureMask | PointerMotionMask | \
+	     ButtonPressMask | ButtonReleaseMask)
+
+static int				x_shmeventtype;
+//static XShmSegmentInfo	x_shminfo;
+
+static qboolean			oktodraw = false;
+static qboolean			X11_active = false;
+
+int XShmQueryExtension(Display *);
+int XShmGetEventBase(Display *);
+
+int current_framebuffer;
+static XImage			*x_framebuffer[2] = { 0, 0 };
+static XShmSegmentInfo	x_shminfo[2];
+
+struct
+{
+	int key;
+	int down;
+} keyq[64];
+int keyq_head=0;
+int keyq_tail=0;
+
+int config_notify=0;
+int config_notify_width;
+int config_notify_height;
+						      
+typedef unsigned short PIXEL;
+
+// Console variables that we need to access from this module
+
+/*****************************************************************************/
+/* MOUSE                                                                     */
+/*****************************************************************************/
+
+// this is inside the renderer shared lib, so these are called from vid_so
+
+static qboolean        mouse_avail;
+static int     mouse_buttonstate;
+static int     mouse_oldbuttonstate;
+static int   mouse_x, mouse_y;
+static int	old_mouse_x, old_mouse_y;
+static int		mx, my;
+static float old_windowed_mouse;
+static int p_mouse_x, p_mouse_y;
+
+static cvar_t	*_windowed_mouse;
+static cvar_t	*m_filter;
+static cvar_t	*in_mouse;
+
+static qboolean	mlooking;
+
+// state struct passed in Init
+static in_state_t	*in_state;
+
+static cvar_t *sensitivity;
+static cvar_t *lookstrafe;
+static cvar_t *m_side;
+static cvar_t *m_yaw;
+static cvar_t *m_pitch;
+static cvar_t *m_forward;
+static cvar_t *freelook;
+
+static void Force_CenterView_f (void)
+{
+	in_state->viewangles[PITCH] = 0;
+}
+
+static void RW_IN_MLookDown (void) 
+{ 
+	mlooking = true; 
+}
+
+static void RW_IN_MLookUp (void) 
+{
+	mlooking = false;
+	in_state->IN_CenterView_fp ();
+}
+
+void RW_IN_Init(in_state_t *in_state_p)
+{
+	int mtype;
+	int i;
+
+	in_state = in_state_p;
+
+	// mouse variables
+	_windowed_mouse = ri.Cvar_Get ("_windowed_mouse", "0", CVAR_ARCHIVE);
+	m_filter = ri.Cvar_Get ("m_filter", "0", 0);
+    in_mouse = ri.Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
+	freelook = ri.Cvar_Get( "freelook", "0", 0 );
+	lookstrafe = ri.Cvar_Get ("lookstrafe", "0", 0);
+	sensitivity = ri.Cvar_Get ("sensitivity", "3", 0);
+	m_pitch = ri.Cvar_Get ("m_pitch", "0.022", 0);
+	m_yaw = ri.Cvar_Get ("m_yaw", "0.022", 0);
+	m_forward = ri.Cvar_Get ("m_forward", "1", 0);
+	m_side = ri.Cvar_Get ("m_side", "0.8", 0);
+
+	ri.Cmd_AddCommand ("+mlook", RW_IN_MLookDown);
+	ri.Cmd_AddCommand ("-mlook", RW_IN_MLookUp);
+
+	ri.Cmd_AddCommand ("force_centerview", Force_CenterView_f);
+
+	mouse_x = mouse_y = 0.0;
+	mouse_avail = true;
+}
+
+void RW_IN_Shutdown(void)
+{
+	mouse_avail = false;
+}
+
+/*
+===========
+IN_Commands
+===========
+*/
+void RW_IN_Commands (void)
+{
+	int i;
+   
+	if (!mouse_avail) 
+		return;
+   
+	for (i=0 ; i<3 ; i++) {
+		if ( (mouse_buttonstate & (1<<i)) && !(mouse_oldbuttonstate & (1<<i)) )
+			in_state->Key_Event_fp (K_MOUSE1 + i, true);
+
+		if ( !(mouse_buttonstate & (1<<i)) && (mouse_oldbuttonstate & (1<<i)) )
+			in_state->Key_Event_fp (K_MOUSE1 + i, false);
+	}
+	mouse_oldbuttonstate = mouse_buttonstate;
+}
+
+/*
+===========
+IN_Move
+===========
+*/
+void RW_IN_Move (usercmd_t *cmd)
+{
+	if (!mouse_avail)
+		return;
+   
+	if (m_filter->value)
+	{
+		mouse_x = (mx + old_mouse_x) * 0.5;
+		mouse_y = (my + old_mouse_y) * 0.5;
+	} else {
+		mouse_x = mx;
+		mouse_y = my;
+	}
+
+	old_mouse_x = mx;
+	old_mouse_y = my;
+
+	if (!mouse_x && !mouse_y)
+		return;
+
+	mouse_x *= sensitivity->value;
+	mouse_y *= sensitivity->value;
+
+// add mouse X/Y movement to cmd
+	if ( (*in_state->in_strafe_state & 1) || 
+		(lookstrafe->value && mlooking ))
+		cmd->sidemove += m_side->value * mouse_x;
+	else
+		in_state->viewangles[YAW] -= m_yaw->value * mouse_x;
+
+	if ( (mlooking || freelook->value) && 
+		!(*in_state->in_strafe_state & 1))
+	{
+		in_state->viewangles[PITCH] += m_pitch->value * mouse_y;
+	}
+	else
+	{
+		cmd->forwardmove -= m_forward->value * mouse_y;
+	}
+	mx = my = 0;
+}
+
+void RW_IN_Frame (void)
+{
+}
+
+void RW_IN_Activate(void)
+{
+}
+
+/*****************************************************************************/
+
+static PIXEL st2d_8to16table[256];
+static int shiftmask_fl=0;
+static long r_shift,g_shift,b_shift;
+static unsigned long r_mask,g_mask,b_mask;
+
+void shiftmask_init()
+{
+    unsigned int x;
+    r_mask=x_vis->red_mask;
+    g_mask=x_vis->green_mask;
+    b_mask=x_vis->blue_mask;
+    for(r_shift=-8,x=1;x<r_mask;x=x<<1)r_shift++;
+    for(g_shift=-8,x=1;x<g_mask;x=x<<1)g_shift++;
+    for(b_shift=-8,x=1;x<b_mask;x=x<<1)b_shift++;
+    shiftmask_fl=1;
+}
+
+PIXEL xlib_rgb(int r,int g,int b)
+{
+    PIXEL p;
+    if(shiftmask_fl==0) shiftmask_init();
+    p=0;
+
+    if(r_shift>0) {
+        p=(r<<(r_shift))&r_mask;
+    } else if(r_shift<0) {
+        p=(r>>(-r_shift))&r_mask;
+    } else p|=(r&r_mask);
+
+    if(g_shift>0) {
+        p|=(g<<(g_shift))&g_mask;
+    } else if(g_shift<0) {
+        p|=(g>>(-g_shift))&g_mask;
+    } else p|=(g&g_mask);
+
+    if(b_shift>0) {
+        p|=(b<<(b_shift))&b_mask;
+    } else if(b_shift<0) {
+        p|=(b>>(-b_shift))&b_mask;
+    } else p|=(b&b_mask);
+
+    return p;
+}
+
+void st2_fixup( XImage *framebuf, int x, int y, int width, int height)
+{
+	int xi,yi;
+	unsigned char *src;
+	PIXEL *dest;
+
+	if( (x<0)||(y<0) )return;
+
+	for (yi = y; yi < (y+height); yi++) {
+		src = &framebuf->data [yi * framebuf->bytes_per_line];
+		dest = (PIXEL*)src;
+		for(xi = (x+width-1); xi >= x; xi -= 8) {
+			dest[xi  ] = st2d_8to16table[src[xi  ]];
+			dest[xi-1] = st2d_8to16table[src[xi-1]];
+			dest[xi-2] = st2d_8to16table[src[xi-2]];
+			dest[xi-3] = st2d_8to16table[src[xi-3]];
+			dest[xi-4] = st2d_8to16table[src[xi-4]];
+			dest[xi-5] = st2d_8to16table[src[xi-5]];
+			dest[xi-6] = st2d_8to16table[src[xi-6]];
+			dest[xi-7] = st2d_8to16table[src[xi-7]];
+		}
+	}
+}
+
+// ========================================================================
+// makes a null cursor
+// ========================================================================
+
+static Cursor CreateNullCursor(Display *display, Window root)
+{
+    Pixmap cursormask; 
+    XGCValues xgc;
+    GC gc;
+    XColor dummycolour;
+    Cursor cursor;
+
+    cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
+    xgc.function = GXclear;
+    gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
+    XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
+    dummycolour.pixel = 0;
+    dummycolour.red = 0;
+    dummycolour.flags = 04;
+    cursor = XCreatePixmapCursor(display, cursormask, cursormask,
+          &dummycolour,&dummycolour, 0,0);
+    XFreePixmap(display,cursormask);
+    XFreeGC(display,gc);
+    return cursor;
+}
+
+void ResetFrameBuffer(void)
+{
+	int mem;
+	int pwidth;
+
+	if (x_framebuffer[0])
+	{
+		free(x_framebuffer[0]->data);
+		free(x_framebuffer[0]);
+	}
+
+// alloc an extra line in case we want to wrap, and allocate the z-buffer
+	pwidth = x_visinfo->depth / 8;
+	if (pwidth == 3) pwidth = 4;
+	mem = ((vid.width*pwidth+7)&~7) * vid.height;
+
+	x_framebuffer[0] = XCreateImage(	x_disp,
+		x_vis,
+		x_visinfo->depth,
+		ZPixmap,
+		0,
+		malloc(mem),
+		vid.width, vid.height,
+		32,
+		0);
+
+	if (!x_framebuffer[0])
+		Sys_Error("VID: XCreateImage failed\n");
+
+	vid.buffer = (byte*) (x_framebuffer[0]);
+}
+
+void ResetSharedFrameBuffers(void)
+{
+	int size;
+	int key;
+	int minsize = getpagesize();
+	int frm;
+
+	for (frm=0 ; frm<2 ; frm++)
+	{
+	// free up old frame buffer memory
+		if (x_framebuffer[frm])
+		{
+			XShmDetach(x_disp, &x_shminfo[frm]);
+			free(x_framebuffer[frm]);
+			shmdt(x_shminfo[frm].shmaddr);
+		}
+
+	// create the image
+		x_framebuffer[frm] = XShmCreateImage(	x_disp,
+						x_vis,
+						x_visinfo->depth,
+						ZPixmap,
+						0,
+						&x_shminfo[frm],
+						vid.width,
+						vid.height );
+
+	// grab shared memory
+
+		size = x_framebuffer[frm]->bytes_per_line
+			* x_framebuffer[frm]->height;
+		if (size < minsize)
+			Sys_Error("VID: Window must use at least %d bytes\n", minsize);
+
+		key = random();
+		x_shminfo[frm].shmid = shmget((key_t)key, size, IPC_CREAT|0777);
+		if (x_shminfo[frm].shmid==-1)
+			Sys_Error("VID: Could not get any shared memory\n");
+
+		// attach to the shared memory segment
+		x_shminfo[frm].shmaddr =
+			(void *) shmat(x_shminfo[frm].shmid, 0, 0);
+
+		ri.Con_Printf(PRINT_ALL, 
+			"MITSHM shared memory (id=%d, addr=0x%lx)\n", 
+			x_shminfo[frm].shmid,
+			(long) x_shminfo[frm].shmaddr);
+
+		x_framebuffer[frm]->data = x_shminfo[frm].shmaddr;
+
+	// get the X server to attach to it
+
+		if (!XShmAttach(x_disp, &x_shminfo[frm]))
+			Sys_Error("VID: XShmAttach() failed\n");
+		XSync(x_disp, 0);
+		shmctl(x_shminfo[frm].shmid, IPC_RMID, 0);
+	}
+
+}
+
+// ========================================================================
+// Tragic death handler
+// ========================================================================
+
+void TragicDeath(int signal_num)
+{
+	XAutoRepeatOn(x_disp);
+	XCloseDisplay(x_disp);
+	Sys_Error("This death brought to you by the number %d\n", signal_num);
+}
+
+int XLateKey(XKeyEvent *ev)
+{
+
+	int key;
+	char buf[64];
+	KeySym keysym;
+
+	key = 0;
+
+	XLookupString(ev, buf, sizeof buf, &keysym, 0);
+
+	switch(keysym)
+	{
+		case XK_KP_Page_Up:	 key = K_KP_PGUP; break;
+		case XK_Page_Up:	 key = K_PGUP; break;
+
+		case XK_KP_Page_Down: key = K_KP_PGDN; break;
+		case XK_Page_Down:	 key = K_PGDN; break;
+
+		case XK_KP_Home: key = K_KP_HOME; break;
+		case XK_Home:	 key = K_HOME; break;
+
+		case XK_KP_End:  key = K_KP_END; break;
+		case XK_End:	 key = K_END; break;
+
+		case XK_KP_Left: key = K_KP_LEFTARROW; break;
+		case XK_Left:	 key = K_LEFTARROW; break;
+
+		case XK_KP_Right: key = K_KP_RIGHTARROW; break;
+		case XK_Right:	key = K_RIGHTARROW;		break;
+
+		case XK_KP_Down: key = K_KP_DOWNARROW; break;
+		case XK_Down:	 key = K_DOWNARROW; break;
+
+		case XK_KP_Up:   key = K_KP_UPARROW; break;
+		case XK_Up:		 key = K_UPARROW;	 break;
+
+		case XK_Escape: key = K_ESCAPE;		break;
+
+		case XK_KP_Enter: key = K_KP_ENTER;	break;
+		case XK_Return: key = K_ENTER;		 break;
+
+		case XK_Tab:		key = K_TAB;			 break;
+
+		case XK_F1:		 key = K_F1;				break;
+
+		case XK_F2:		 key = K_F2;				break;
+
+		case XK_F3:		 key = K_F3;				break;
+
+		case XK_F4:		 key = K_F4;				break;
+
+		case XK_F5:		 key = K_F5;				break;
+
+		case XK_F6:		 key = K_F6;				break;
+
+		case XK_F7:		 key = K_F7;				break;
+
+		case XK_F8:		 key = K_F8;				break;
+
+		case XK_F9:		 key = K_F9;				break;
+
+		case XK_F10:		key = K_F10;			 break;
+
+		case XK_F11:		key = K_F11;			 break;
+
+		case XK_F12:		key = K_F12;			 break;
+
+		case XK_BackSpace: key = K_BACKSPACE; break;
+
+		case XK_KP_Delete: key = K_KP_DEL; break;
+		case XK_Delete: key = K_DEL; break;
+
+		case XK_Pause:	key = K_PAUSE;		 break;
+
+		case XK_Shift_L:
+		case XK_Shift_R:	key = K_SHIFT;		break;
+
+		case XK_Execute: 
+		case XK_Control_L: 
+		case XK_Control_R:	key = K_CTRL;		 break;
+
+		case XK_Alt_L:	
+		case XK_Meta_L: 
+		case XK_Alt_R:	
+		case XK_Meta_R: key = K_ALT;			break;
+
+		case XK_KP_Begin: key = K_KP_5;	break;
+
+		case XK_Insert:key = K_INS; break;
+		case XK_KP_Insert: key = K_KP_INS; break;
+
+		case XK_KP_Multiply: key = '*'; break;
+		case XK_KP_Add:  key = K_KP_PLUS; break;
+		case XK_KP_Subtract: key = K_KP_MINUS; break;
+		case XK_KP_Divide: key = K_KP_SLASH; break;
+
+#if 0
+		case 0x021: key = '1';break;/* [!] */
+		case 0x040: key = '2';break;/* [@] */
+		case 0x023: key = '3';break;/* [#] */
+		case 0x024: key = '4';break;/* [$] */
+		case 0x025: key = '5';break;/* [%] */
+		case 0x05e: key = '6';break;/* [^] */
+		case 0x026: key = '7';break;/* [&] */
+		case 0x02a: key = '8';break;/* [*] */
+		case 0x028: key = '9';;break;/* [(] */
+		case 0x029: key = '0';break;/* [)] */
+		case 0x05f: key = '-';break;/* [_] */
+		case 0x02b: key = '=';break;/* [+] */
+		case 0x07c: key = '\'';break;/* [|] */
+		case 0x07d: key = '[';break;/* [}] */
+		case 0x07b: key = ']';break;/* [{] */
+		case 0x022: key = '\'';break;/* ["] */
+		case 0x03a: key = ';';break;/* [:] */
+		case 0x03f: key = '/';break;/* [?] */
+		case 0x03e: key = '.';break;/* [>] */
+		case 0x03c: key = ',';break;/* [<] */
+#endif
+
+		default:
+			key = *(unsigned char*)buf;
+			if (key >= 'A' && key <= 'Z')
+				key = key - 'A' + 'a';
+			break;
+	} 
+
+	return key;
+}
+
+void GetEvent(void)
+{
+	XEvent x_event;
+	int b;
+   
+	XNextEvent(x_disp, &x_event);
+	switch(x_event.type) {
+	case KeyPress:
+		keyq[keyq_head].key = XLateKey(&x_event.xkey);
+		keyq[keyq_head].down = true;
+		keyq_head = (keyq_head + 1) & 63;
+		break;
+	case KeyRelease:
+		keyq[keyq_head].key = XLateKey(&x_event.xkey);
+		keyq[keyq_head].down = false;
+		keyq_head = (keyq_head + 1) & 63;
+		break;
+
+	case MotionNotify:
+		if (_windowed_mouse->value) {
+			mx += ((int)x_event.xmotion.x - (int)(vid.width/2));
+			my += ((int)x_event.xmotion.y - (int)(vid.height/2));
+
+			/* move the mouse to the window center again */
+			XSelectInput(x_disp,x_win, STD_EVENT_MASK & ~PointerMotionMask);
+			XWarpPointer(x_disp,None,x_win,0,0,0,0, 
+				(vid.width/2),(vid.height/2));
+			XSelectInput(x_disp,x_win, STD_EVENT_MASK);
+		} else {
+			mx = ((int)x_event.xmotion.x - (int)p_mouse_x);
+			my = ((int)x_event.xmotion.y - (int)p_mouse_y);
+			p_mouse_x=x_event.xmotion.x;
+			p_mouse_y=x_event.xmotion.y;
+		}
+		break;
+
+	case ButtonPress:
+		b=-1;
+		if (x_event.xbutton.button == 1)
+			b = 0;
+		else if (x_event.xbutton.button == 2)
+			b = 2;
+		else if (x_event.xbutton.button == 3)
+			b = 1;
+		if (b>=0)
+			mouse_buttonstate |= 1<<b;
+		break;
+
+	case ButtonRelease:
+		b=-1;
+		if (x_event.xbutton.button == 1)
+			b = 0;
+		else if (x_event.xbutton.button == 2)
+			b = 2;
+		else if (x_event.xbutton.button == 3)
+			b = 1;
+		if (b>=0)
+			mouse_buttonstate &= ~(1<<b);
+		break;
+	
+	case ConfigureNotify:
+		config_notify_width = x_event.xconfigure.width;
+		config_notify_height = x_event.xconfigure.height;
+		config_notify = 1;
+		break;
+
+	default:
+		if (doShm && x_event.type == x_shmeventtype)
+			oktodraw = true;
+	}
+   
+	if (old_windowed_mouse != _windowed_mouse->value) {
+		old_windowed_mouse = _windowed_mouse->value;
+
+		if (!_windowed_mouse->value) {
+			/* ungrab the pointer */
+			XUngrabPointer(x_disp,CurrentTime);
+		} else {
+			/* grab the pointer */
+			XGrabPointer(x_disp,x_win,True,0,GrabModeAsync,
+				GrabModeAsync,x_win,None,CurrentTime);
+		}
+	}
+}
+
+/*****************************************************************************/
+
+/*
+** SWimp_Init
+**
+** This routine is responsible for initializing the implementation
+** specific stuff in a software rendering subsystem.
+*/
+int SWimp_Init( void *hInstance, void *wndProc )
+{
+// open the display
+	x_disp = XOpenDisplay(0);
+	if (!x_disp)
+	{
+		if (getenv("DISPLAY"))
+			Sys_Error("VID: Could not open display [%s]\n",
+				getenv("DISPLAY"));
+		else
+			Sys_Error("VID: Could not open local display\n");
+	}
+
+// catch signals so i can turn on auto-repeat
+
+	{
+		struct sigaction sa;
+		sigaction(SIGINT, 0, &sa);
+		sa.sa_handler = TragicDeath;
+		sigaction(SIGINT, &sa, 0);
+		sigaction(SIGTERM, &sa, 0);
+	}
+
+	return true;
+}
+
+/*
+** SWimp_InitGraphics
+**
+** This initializes the software refresh's implementation specific
+** graphics subsystem.  In the case of Windows it creates DIB or
+** DDRAW surfaces.
+**
+** The necessary width and height parameters are grabbed from
+** vid.width and vid.height.
+*/
+static qboolean SWimp_InitGraphics( qboolean fullscreen )
+{
+	int pnum, i;
+	XVisualInfo template;
+	int num_visuals;
+	int template_mask;
+
+	srandom(getpid());
+
+	// free resources in use
+	SWimp_Shutdown ();
+
+	// let the sound and input subsystems know about the new window
+	ri.Vid_NewWindow (vid.width, vid.height);
+
+	XAutoRepeatOff(x_disp);
+
+// for debugging only
+	XSynchronize(x_disp, True);
+
+// check for command-line window size
+	template_mask = 0;
+
+#if 0
+// specify a visual id
+	if ((pnum=COM_CheckParm("-visualid")))
+	{
+		if (pnum >= com_argc-1)
+			Sys_Error("VID: -visualid <id#>\n");
+		template.visualid = Q_atoi(com_argv[pnum+1]);
+		template_mask = VisualIDMask;
+	}
+
+// If not specified, use default visual
+	else
+#endif
+	{
+		int screen;
+		screen = XDefaultScreen(x_disp);
+		template.visualid =
+			XVisualIDFromVisual(XDefaultVisual(x_disp, screen));
+		template_mask = VisualIDMask;
+	}
+
+// pick a visual- warn if more than one was available
+	x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals);
+	if (num_visuals > 1)
+	{
+		printf("Found more than one visual id at depth %d:\n", template.depth);
+		for (i=0 ; i<num_visuals ; i++)
+			printf("	-visualid %d\n", (int)(x_visinfo[i].visualid));
+	}
+	else if (num_visuals == 0)
+	{
+		if (template_mask == VisualIDMask)
+			Sys_Error("VID: Bad visual id %d\n", template.visualid);
+		else
+			Sys_Error("VID: No visuals at depth %d\n", template.depth);
+	}
+
+#if 0
+	if (verbose)
+	{
+		printf("Using visualid %d:\n", (int)(x_visinfo->visualid));
+		printf("	screen %d\n", x_visinfo->screen);
+		printf("	red_mask 0x%x\n", (int)(x_visinfo->red_mask));
+		printf("	green_mask 0x%x\n", (int)(x_visinfo->green_mask));
+		printf("	blue_mask 0x%x\n", (int)(x_visinfo->blue_mask));
+		printf("	colormap_size %d\n", x_visinfo->colormap_size);
+		printf("	bits_per_rgb %d\n", x_visinfo->bits_per_rgb);
+	}
+#endif
+
+	x_vis = x_visinfo->visual;
+
+// setup attributes for main window
+	{
+	   int attribmask = CWEventMask  | CWColormap | CWBorderPixel;
+	   XSetWindowAttributes attribs;
+	   Colormap tmpcmap;
+	   
+	   tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp,
+							 x_visinfo->screen), x_vis, AllocNone);
+	   
+	   attribs.event_mask = STD_EVENT_MASK;
+	   attribs.border_pixel = 0;
+	   attribs.colormap = tmpcmap;
+
+// create the main window
+		x_win = XCreateWindow(	x_disp,
+			XRootWindow(x_disp, x_visinfo->screen),
+			0, 0,	// x, y
+			vid.width, vid.height,
+			0, // borderwidth
+			x_visinfo->depth,
+			InputOutput,
+			x_vis,
+			attribmask,
+			&attribs );
+		XStoreName(x_disp, x_win, "Quake II");
+
+		if (x_visinfo->class != TrueColor)
+			XFreeColormap(x_disp, tmpcmap);
+	}
+
+	if (x_visinfo->depth == 8)
+	{
+	// create and upload the palette
+		if (x_visinfo->class == PseudoColor)
+		{
+			x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll);
+			XSetWindowColormap(x_disp, x_win, x_cmap);
+		}
+
+	}
+
+// inviso cursor
+	XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win));
+
+// create the GC
+	{
+		XGCValues xgcvalues;
+		int valuemask = GCGraphicsExposures;
+		xgcvalues.graphics_exposures = False;
+		x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues );
+	}
+
+// map the window
+	XMapWindow(x_disp, x_win);
+
+// wait for first exposure event
+	{
+		XEvent event;
+		do
+		{
+			XNextEvent(x_disp, &event);
+			if (event.type == Expose && !event.xexpose.count)
+				oktodraw = true;
+		} while (!oktodraw);
+	}
+// now safe to draw
+
+// even if MITSHM is available, make sure it's a local connection
+	if (XShmQueryExtension(x_disp))
+	{
+		char *displayname;
+		doShm = true;
+		displayname = (char *) getenv("DISPLAY");
+		if (displayname)
+		{
+			char *d = displayname;
+			while (*d && (*d != ':')) d++;
+			if (*d) *d = 0;
+			if (!(!strcasecmp(displayname, "unix") || !*displayname))
+				doShm = false;
+		}
+	}
+
+	if (doShm)
+	{
+		x_shmeventtype = XShmGetEventBase(x_disp) + ShmCompletion;
+		ResetSharedFrameBuffers();
+	}
+	else
+		ResetFrameBuffer();
+
+	current_framebuffer = 0;
+	vid.rowbytes = x_framebuffer[0]->bytes_per_line;
+	vid.buffer = x_framebuffer[0]->data;
+
+//	XSynchronize(x_disp, False);
+
+	X11_active = true;
+
+	return true;
+}
+
+/*
+** SWimp_EndFrame
+**
+** This does an implementation specific copy from the backbuffer to the
+** front buffer.  In the Win32 case it uses BitBlt or BltFast depending
+** on whether we're using DIB sections/GDI or DDRAW.
+*/
+void SWimp_EndFrame (void)
+{
+// if the window changes dimension, skip this frame
+#if 0
+	if (config_notify)
+	{
+		fprintf(stderr, "config notify\n");
+		config_notify = 0;
+		vid.width = config_notify_width & ~7;
+		vid.height = config_notify_height;
+		if (doShm)
+			ResetSharedFrameBuffers();
+		else
+			ResetFrameBuffer();
+		vid.rowbytes = x_framebuffer[0]->bytes_per_line;
+		vid.buffer = x_framebuffer[current_framebuffer]->data;
+		vid.recalc_refdef = 1;				// force a surface cache flush
+		Con_CheckResize();
+		Con_Clear_f();
+		return;
+	}
+#endif
+
+	if (doShm)
+	{
+
+		if (x_visinfo->depth != 8)
+			st2_fixup( x_framebuffer[current_framebuffer], 
+				0, 0, vid.width, vid.height);	
+		if (!XShmPutImage(x_disp, x_win, x_gc,
+			x_framebuffer[current_framebuffer], 0, 0,
+			0, 0, vid.width, vid.height, True))
+				Sys_Error("VID_Update: XShmPutImage failed\n");
+		oktodraw = false;
+		while (!oktodraw) 
+			GetEvent();
+		current_framebuffer = !current_framebuffer;
+		vid.buffer = x_framebuffer[current_framebuffer]->data;
+		XSync(x_disp, False);
+	}
+	else
+	{
+		if (x_visinfo->depth != 8)
+			st2_fixup( x_framebuffer[current_framebuffer], 
+				0, 0, vid.width, vid.height);
+		XPutImage(x_disp, x_win, x_gc, x_framebuffer[0],
+			0, 0, 0, 0, vid.width, vid.height);
+		XSync(x_disp, False);
+	}
+}
+
+/*
+** SWimp_SetMode
+*/
+rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
+{
+	rserr_t retval = rserr_ok;
+
+	ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode );
+
+	if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) )
+	{
+		ri.Con_Printf( PRINT_ALL, " invalid mode\n" );
+		return rserr_invalid_mode;
+	}
+
+	ri.Con_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight);
+
+	if ( !SWimp_InitGraphics( false ) ) {
+		// failed to set a valid mode in windowed mode
+		return rserr_invalid_mode;
+	}
+
+	R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
+
+	return retval;
+}
+
+/*
+** SWimp_SetPalette
+**
+** System specific palette setting routine.  A NULL palette means
+** to use the existing palette.  The palette is expected to be in
+** a padded 4-byte xRGB format.
+*/
+void SWimp_SetPalette( const unsigned char *palette )
+{
+	int i;
+	XColor colors[256];
+
+	if (!X11_active)
+		return;
+
+    if ( !palette )
+        palette = ( const unsigned char * ) sw_state.currentpalette;
+ 
+	for(i=0;i<256;i++)
+		st2d_8to16table[i]= xlib_rgb(palette[i*4],
+			palette[i*4+1],palette[i*4+2]);
+
+	if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8)
+	{
+		for (i=0 ; i<256 ; i++)
+		{
+			colors[i].pixel = i;
+			colors[i].flags = DoRed|DoGreen|DoBlue;
+			colors[i].red = palette[i*4] * 257;
+			colors[i].green = palette[i*4+1] * 257;
+			colors[i].blue = palette[i*4+2] * 257;
+		}
+		XStoreColors(x_disp, x_cmap, colors, 256);
+	}
+}
+
+/*
+** SWimp_Shutdown
+**
+** System specific graphics subsystem shutdown routine.  Destroys
+** DIBs or DDRAW surfaces as appropriate.
+*/
+void SWimp_Shutdown( void )
+{
+	int i;
+
+	if (!X11_active)
+		return;
+
+	if (doShm) {
+		for (i = 0; i < 2; i++)
+			if (x_framebuffer[i]) {
+				XShmDetach(x_disp, &x_shminfo[i]);
+				free(x_framebuffer[i]);
+				shmdt(x_shminfo[i].shmaddr);
+				x_framebuffer[i] = NULL;
+			}
+	} else if (x_framebuffer[0]) {
+		free(x_framebuffer[0]->data);
+		free(x_framebuffer[0]);
+		x_framebuffer[0] = NULL;
+	}
+
+	XDestroyWindow(	x_disp, x_win );
+
+	XAutoRepeatOn(x_disp);
+//	XCloseDisplay(x_disp);
+
+	X11_active = false;
+}
+
+/*
+** SWimp_AppActivate
+*/
+void SWimp_AppActivate( qboolean active )
+{
+}
+
+//===============================================================================
+
+/*
+================
+Sys_MakeCodeWriteable
+================
+*/
+void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
+{
+
+	int r;
+	unsigned long addr;
+	int psize = getpagesize();
+
+	addr = (startaddr & ~(psize-1)) - psize;
+
+//	fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
+//			addr, startaddr+length, length);
+
+	r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
+
+	if (r < 0)
+    		Sys_Error("Protection change failed\n");
+
+}
+
+/*****************************************************************************/
+/* KEYBOARD                                                                  */
+/*****************************************************************************/
+
+Key_Event_fp_t Key_Event_fp;
+
+void KBD_Init(Key_Event_fp_t fp)
+{
+	Key_Event_fp = fp;
+}
+
+void KBD_Update(void)
+{
+// get events from x server
+	if (x_disp)
+	{
+		while (XPending(x_disp)) 
+			GetEvent();
+		while (keyq_head != keyq_tail)
+		{
+			Key_Event_fp(keyq[keyq_tail].key, keyq[keyq_tail].down);
+			keyq_tail = (keyq_tail + 1) & 63;
+		}
+	}
+}
+
+void KBD_Close(void)
+{
+}
+
+
--- a/plan9/rw_x11.c
+++ /dev/null
@@ -1,1093 +1,0 @@
-/*
-** RW_X11.C
-**
-** This file contains ALL Linux specific stuff having to do with the
-** software refresh.  When a port is being made the following functions
-** must be implemented by the port:
-**
-** SWimp_EndFrame
-** SWimp_Init
-** SWimp_InitGraphics
-** SWimp_SetPalette
-** SWimp_Shutdown
-** SWimp_SwitchFullscreen
-*/
-
-#include <ctype.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/keysym.h>
-#include <X11/extensions/XShm.h>
-
-#include "../ref_soft/r_local.h"
-#include "../client/keys.h"
-#include "../linux/rw_linux.h"
-
-/*****************************************************************************/
-
-static qboolean			doShm;
-static Display			*x_disp;
-static Colormap			x_cmap;
-static Window			x_win;
-static GC				x_gc;
-static Visual			*x_vis;
-static XVisualInfo		*x_visinfo;
-//static XImage			*x_image;
-
-#define STD_EVENT_MASK (StructureNotifyMask | KeyPressMask \
-	     | KeyReleaseMask | ExposureMask | PointerMotionMask | \
-	     ButtonPressMask | ButtonReleaseMask)
-
-static int				x_shmeventtype;
-//static XShmSegmentInfo	x_shminfo;
-
-static qboolean			oktodraw = false;
-static qboolean			X11_active = false;
-
-int XShmQueryExtension(Display *);
-int XShmGetEventBase(Display *);
-
-int current_framebuffer;
-static XImage			*x_framebuffer[2] = { 0, 0 };
-static XShmSegmentInfo	x_shminfo[2];
-
-struct
-{
-	int key;
-	int down;
-} keyq[64];
-int keyq_head=0;
-int keyq_tail=0;
-
-int config_notify=0;
-int config_notify_width;
-int config_notify_height;
-						      
-typedef unsigned short PIXEL;
-
-// Console variables that we need to access from this module
-
-/*****************************************************************************/
-/* MOUSE                                                                     */
-/*****************************************************************************/
-
-// this is inside the renderer shared lib, so these are called from vid_so
-
-static qboolean        mouse_avail;
-static int     mouse_buttonstate;
-static int     mouse_oldbuttonstate;
-static int   mouse_x, mouse_y;
-static int	old_mouse_x, old_mouse_y;
-static int		mx, my;
-static float old_windowed_mouse;
-static int p_mouse_x, p_mouse_y;
-
-static cvar_t	*_windowed_mouse;
-static cvar_t	*m_filter;
-static cvar_t	*in_mouse;
-
-static qboolean	mlooking;
-
-// state struct passed in Init
-static in_state_t	*in_state;
-
-static cvar_t *sensitivity;
-static cvar_t *lookstrafe;
-static cvar_t *m_side;
-static cvar_t *m_yaw;
-static cvar_t *m_pitch;
-static cvar_t *m_forward;
-static cvar_t *freelook;
-
-static void Force_CenterView_f (void)
-{
-	in_state->viewangles[PITCH] = 0;
-}
-
-static void RW_IN_MLookDown (void) 
-{ 
-	mlooking = true; 
-}
-
-static void RW_IN_MLookUp (void) 
-{
-	mlooking = false;
-	in_state->IN_CenterView_fp ();
-}
-
-void RW_IN_Init(in_state_t *in_state_p)
-{
-	int mtype;
-	int i;
-
-	in_state = in_state_p;
-
-	// mouse variables
-	_windowed_mouse = ri.Cvar_Get ("_windowed_mouse", "0", CVAR_ARCHIVE);
-	m_filter = ri.Cvar_Get ("m_filter", "0", 0);
-    in_mouse = ri.Cvar_Get ("in_mouse", "1", CVAR_ARCHIVE);
-	freelook = ri.Cvar_Get( "freelook", "0", 0 );
-	lookstrafe = ri.Cvar_Get ("lookstrafe", "0", 0);
-	sensitivity = ri.Cvar_Get ("sensitivity", "3", 0);
-	m_pitch = ri.Cvar_Get ("m_pitch", "0.022", 0);
-	m_yaw = ri.Cvar_Get ("m_yaw", "0.022", 0);
-	m_forward = ri.Cvar_Get ("m_forward", "1", 0);
-	m_side = ri.Cvar_Get ("m_side", "0.8", 0);
-
-	ri.Cmd_AddCommand ("+mlook", RW_IN_MLookDown);
-	ri.Cmd_AddCommand ("-mlook", RW_IN_MLookUp);
-
-	ri.Cmd_AddCommand ("force_centerview", Force_CenterView_f);
-
-	mouse_x = mouse_y = 0.0;
-	mouse_avail = true;
-}
-
-void RW_IN_Shutdown(void)
-{
-	mouse_avail = false;
-}
-
-/*
-===========
-IN_Commands
-===========
-*/
-void RW_IN_Commands (void)
-{
-	int i;
-   
-	if (!mouse_avail) 
-		return;
-   
-	for (i=0 ; i<3 ; i++) {
-		if ( (mouse_buttonstate & (1<<i)) && !(mouse_oldbuttonstate & (1<<i)) )
-			in_state->Key_Event_fp (K_MOUSE1 + i, true);
-
-		if ( !(mouse_buttonstate & (1<<i)) && (mouse_oldbuttonstate & (1<<i)) )
-			in_state->Key_Event_fp (K_MOUSE1 + i, false);
-	}
-	mouse_oldbuttonstate = mouse_buttonstate;
-}
-
-/*
-===========
-IN_Move
-===========
-*/
-void RW_IN_Move (usercmd_t *cmd)
-{
-	if (!mouse_avail)
-		return;
-   
-	if (m_filter->value)
-	{
-		mouse_x = (mx + old_mouse_x) * 0.5;
-		mouse_y = (my + old_mouse_y) * 0.5;
-	} else {
-		mouse_x = mx;
-		mouse_y = my;
-	}
-
-	old_mouse_x = mx;
-	old_mouse_y = my;
-
-	if (!mouse_x && !mouse_y)
-		return;
-
-	mouse_x *= sensitivity->value;
-	mouse_y *= sensitivity->value;
-
-// add mouse X/Y movement to cmd
-	if ( (*in_state->in_strafe_state & 1) || 
-		(lookstrafe->value && mlooking ))
-		cmd->sidemove += m_side->value * mouse_x;
-	else
-		in_state->viewangles[YAW] -= m_yaw->value * mouse_x;
-
-	if ( (mlooking || freelook->value) && 
-		!(*in_state->in_strafe_state & 1))
-	{
-		in_state->viewangles[PITCH] += m_pitch->value * mouse_y;
-	}
-	else
-	{
-		cmd->forwardmove -= m_forward->value * mouse_y;
-	}
-	mx = my = 0;
-}
-
-void RW_IN_Frame (void)
-{
-}
-
-void RW_IN_Activate(void)
-{
-}
-
-/*****************************************************************************/
-
-static PIXEL st2d_8to16table[256];
-static int shiftmask_fl=0;
-static long r_shift,g_shift,b_shift;
-static unsigned long r_mask,g_mask,b_mask;
-
-void shiftmask_init()
-{
-    unsigned int x;
-    r_mask=x_vis->red_mask;
-    g_mask=x_vis->green_mask;
-    b_mask=x_vis->blue_mask;
-    for(r_shift=-8,x=1;x<r_mask;x=x<<1)r_shift++;
-    for(g_shift=-8,x=1;x<g_mask;x=x<<1)g_shift++;
-    for(b_shift=-8,x=1;x<b_mask;x=x<<1)b_shift++;
-    shiftmask_fl=1;
-}
-
-PIXEL xlib_rgb(int r,int g,int b)
-{
-    PIXEL p;
-    if(shiftmask_fl==0) shiftmask_init();
-    p=0;
-
-    if(r_shift>0) {
-        p=(r<<(r_shift))&r_mask;
-    } else if(r_shift<0) {
-        p=(r>>(-r_shift))&r_mask;
-    } else p|=(r&r_mask);
-
-    if(g_shift>0) {
-        p|=(g<<(g_shift))&g_mask;
-    } else if(g_shift<0) {
-        p|=(g>>(-g_shift))&g_mask;
-    } else p|=(g&g_mask);
-
-    if(b_shift>0) {
-        p|=(b<<(b_shift))&b_mask;
-    } else if(b_shift<0) {
-        p|=(b>>(-b_shift))&b_mask;
-    } else p|=(b&b_mask);
-
-    return p;
-}
-
-void st2_fixup( XImage *framebuf, int x, int y, int width, int height)
-{
-	int xi,yi;
-	unsigned char *src;
-	PIXEL *dest;
-
-	if( (x<0)||(y<0) )return;
-
-	for (yi = y; yi < (y+height); yi++) {
-		src = &framebuf->data [yi * framebuf->bytes_per_line];
-		dest = (PIXEL*)src;
-		for(xi = (x+width-1); xi >= x; xi -= 8) {
-			dest[xi  ] = st2d_8to16table[src[xi  ]];
-			dest[xi-1] = st2d_8to16table[src[xi-1]];
-			dest[xi-2] = st2d_8to16table[src[xi-2]];
-			dest[xi-3] = st2d_8to16table[src[xi-3]];
-			dest[xi-4] = st2d_8to16table[src[xi-4]];
-			dest[xi-5] = st2d_8to16table[src[xi-5]];
-			dest[xi-6] = st2d_8to16table[src[xi-6]];
-			dest[xi-7] = st2d_8to16table[src[xi-7]];
-		}
-	}
-}
-
-// ========================================================================
-// makes a null cursor
-// ========================================================================
-
-static Cursor CreateNullCursor(Display *display, Window root)
-{
-    Pixmap cursormask; 
-    XGCValues xgc;
-    GC gc;
-    XColor dummycolour;
-    Cursor cursor;
-
-    cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
-    xgc.function = GXclear;
-    gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
-    XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
-    dummycolour.pixel = 0;
-    dummycolour.red = 0;
-    dummycolour.flags = 04;
-    cursor = XCreatePixmapCursor(display, cursormask, cursormask,
-          &dummycolour,&dummycolour, 0,0);
-    XFreePixmap(display,cursormask);
-    XFreeGC(display,gc);
-    return cursor;
-}
-
-void ResetFrameBuffer(void)
-{
-	int mem;
-	int pwidth;
-
-	if (x_framebuffer[0])
-	{
-		free(x_framebuffer[0]->data);
-		free(x_framebuffer[0]);
-	}
-
-// alloc an extra line in case we want to wrap, and allocate the z-buffer
-	pwidth = x_visinfo->depth / 8;
-	if (pwidth == 3) pwidth = 4;
-	mem = ((vid.width*pwidth+7)&~7) * vid.height;
-
-	x_framebuffer[0] = XCreateImage(	x_disp,
-		x_vis,
-		x_visinfo->depth,
-		ZPixmap,
-		0,
-		malloc(mem),
-		vid.width, vid.height,
-		32,
-		0);
-
-	if (!x_framebuffer[0])
-		Sys_Error("VID: XCreateImage failed\n");
-
-	vid.buffer = (byte*) (x_framebuffer[0]);
-}
-
-void ResetSharedFrameBuffers(void)
-{
-	int size;
-	int key;
-	int minsize = getpagesize();
-	int frm;
-
-	for (frm=0 ; frm<2 ; frm++)
-	{
-	// free up old frame buffer memory
-		if (x_framebuffer[frm])
-		{
-			XShmDetach(x_disp, &x_shminfo[frm]);
-			free(x_framebuffer[frm]);
-			shmdt(x_shminfo[frm].shmaddr);
-		}
-
-	// create the image
-		x_framebuffer[frm] = XShmCreateImage(	x_disp,
-						x_vis,
-						x_visinfo->depth,
-						ZPixmap,
-						0,
-						&x_shminfo[frm],
-						vid.width,
-						vid.height );
-
-	// grab shared memory
-
-		size = x_framebuffer[frm]->bytes_per_line
-			* x_framebuffer[frm]->height;
-		if (size < minsize)
-			Sys_Error("VID: Window must use at least %d bytes\n", minsize);
-
-		key = random();
-		x_shminfo[frm].shmid = shmget((key_t)key, size, IPC_CREAT|0777);
-		if (x_shminfo[frm].shmid==-1)
-			Sys_Error("VID: Could not get any shared memory\n");
-
-		// attach to the shared memory segment
-		x_shminfo[frm].shmaddr =
-			(void *) shmat(x_shminfo[frm].shmid, 0, 0);
-
-		ri.Con_Printf(PRINT_ALL, 
-			"MITSHM shared memory (id=%d, addr=0x%lx)\n", 
-			x_shminfo[frm].shmid,
-			(long) x_shminfo[frm].shmaddr);
-
-		x_framebuffer[frm]->data = x_shminfo[frm].shmaddr;
-
-	// get the X server to attach to it
-
-		if (!XShmAttach(x_disp, &x_shminfo[frm]))
-			Sys_Error("VID: XShmAttach() failed\n");
-		XSync(x_disp, 0);
-		shmctl(x_shminfo[frm].shmid, IPC_RMID, 0);
-	}
-
-}
-
-// ========================================================================
-// Tragic death handler
-// ========================================================================
-
-void TragicDeath(int signal_num)
-{
-	XAutoRepeatOn(x_disp);
-	XCloseDisplay(x_disp);
-	Sys_Error("This death brought to you by the number %d\n", signal_num);
-}
-
-int XLateKey(XKeyEvent *ev)
-{
-
-	int key;
-	char buf[64];
-	KeySym keysym;
-
-	key = 0;
-
-	XLookupString(ev, buf, sizeof buf, &keysym, 0);
-
-	switch(keysym)
-	{
-		case XK_KP_Page_Up:	 key = K_KP_PGUP; break;
-		case XK_Page_Up:	 key = K_PGUP; break;
-
-		case XK_KP_Page_Down: key = K_KP_PGDN; break;
-		case XK_Page_Down:	 key = K_PGDN; break;
-
-		case XK_KP_Home: key = K_KP_HOME; break;
-		case XK_Home:	 key = K_HOME; break;
-
-		case XK_KP_End:  key = K_KP_END; break;
-		case XK_End:	 key = K_END; break;
-
-		case XK_KP_Left: key = K_KP_LEFTARROW; break;
-		case XK_Left:	 key = K_LEFTARROW; break;
-
-		case XK_KP_Right: key = K_KP_RIGHTARROW; break;
-		case XK_Right:	key = K_RIGHTARROW;		break;
-
-		case XK_KP_Down: key = K_KP_DOWNARROW; break;
-		case XK_Down:	 key = K_DOWNARROW; break;
-
-		case XK_KP_Up:   key = K_KP_UPARROW; break;
-		case XK_Up:		 key = K_UPARROW;	 break;
-
-		case XK_Escape: key = K_ESCAPE;		break;
-
-		case XK_KP_Enter: key = K_KP_ENTER;	break;
-		case XK_Return: key = K_ENTER;		 break;
-
-		case XK_Tab:		key = K_TAB;			 break;
-
-		case XK_F1:		 key = K_F1;				break;
-
-		case XK_F2:		 key = K_F2;				break;
-
-		case XK_F3:		 key = K_F3;				break;
-
-		case XK_F4:		 key = K_F4;				break;
-
-		case XK_F5:		 key = K_F5;				break;
-
-		case XK_F6:		 key = K_F6;				break;
-
-		case XK_F7:		 key = K_F7;				break;
-
-		case XK_F8:		 key = K_F8;				break;
-
-		case XK_F9:		 key = K_F9;				break;
-
-		case XK_F10:		key = K_F10;			 break;
-
-		case XK_F11:		key = K_F11;			 break;
-
-		case XK_F12:		key = K_F12;			 break;
-
-		case XK_BackSpace: key = K_BACKSPACE; break;
-
-		case XK_KP_Delete: key = K_KP_DEL; break;
-		case XK_Delete: key = K_DEL; break;
-
-		case XK_Pause:	key = K_PAUSE;		 break;
-
-		case XK_Shift_L:
-		case XK_Shift_R:	key = K_SHIFT;		break;
-
-		case XK_Execute: 
-		case XK_Control_L: 
-		case XK_Control_R:	key = K_CTRL;		 break;
-
-		case XK_Alt_L:	
-		case XK_Meta_L: 
-		case XK_Alt_R:	
-		case XK_Meta_R: key = K_ALT;			break;
-
-		case XK_KP_Begin: key = K_KP_5;	break;
-
-		case XK_Insert:key = K_INS; break;
-		case XK_KP_Insert: key = K_KP_INS; break;
-
-		case XK_KP_Multiply: key = '*'; break;
-		case XK_KP_Add:  key = K_KP_PLUS; break;
-		case XK_KP_Subtract: key = K_KP_MINUS; break;
-		case XK_KP_Divide: key = K_KP_SLASH; break;
-
-#if 0
-		case 0x021: key = '1';break;/* [!] */
-		case 0x040: key = '2';break;/* [@] */
-		case 0x023: key = '3';break;/* [#] */
-		case 0x024: key = '4';break;/* [$] */
-		case 0x025: key = '5';break;/* [%] */
-		case 0x05e: key = '6';break;/* [^] */
-		case 0x026: key = '7';break;/* [&] */
-		case 0x02a: key = '8';break;/* [*] */
-		case 0x028: key = '9';;break;/* [(] */
-		case 0x029: key = '0';break;/* [)] */
-		case 0x05f: key = '-';break;/* [_] */
-		case 0x02b: key = '=';break;/* [+] */
-		case 0x07c: key = '\'';break;/* [|] */
-		case 0x07d: key = '[';break;/* [}] */
-		case 0x07b: key = ']';break;/* [{] */
-		case 0x022: key = '\'';break;/* ["] */
-		case 0x03a: key = ';';break;/* [:] */
-		case 0x03f: key = '/';break;/* [?] */
-		case 0x03e: key = '.';break;/* [>] */
-		case 0x03c: key = ',';break;/* [<] */
-#endif
-
-		default:
-			key = *(unsigned char*)buf;
-			if (key >= 'A' && key <= 'Z')
-				key = key - 'A' + 'a';
-			break;
-	} 
-
-	return key;
-}
-
-void GetEvent(void)
-{
-	XEvent x_event;
-	int b;
-   
-	XNextEvent(x_disp, &x_event);
-	switch(x_event.type) {
-	case KeyPress:
-		keyq[keyq_head].key = XLateKey(&x_event.xkey);
-		keyq[keyq_head].down = true;
-		keyq_head = (keyq_head + 1) & 63;
-		break;
-	case KeyRelease:
-		keyq[keyq_head].key = XLateKey(&x_event.xkey);
-		keyq[keyq_head].down = false;
-		keyq_head = (keyq_head + 1) & 63;
-		break;
-
-	case MotionNotify:
-		if (_windowed_mouse->value) {
-			mx += ((int)x_event.xmotion.x - (int)(vid.width/2));
-			my += ((int)x_event.xmotion.y - (int)(vid.height/2));
-
-			/* move the mouse to the window center again */
-			XSelectInput(x_disp,x_win, STD_EVENT_MASK & ~PointerMotionMask);
-			XWarpPointer(x_disp,None,x_win,0,0,0,0, 
-				(vid.width/2),(vid.height/2));
-			XSelectInput(x_disp,x_win, STD_EVENT_MASK);
-		} else {
-			mx = ((int)x_event.xmotion.x - (int)p_mouse_x);
-			my = ((int)x_event.xmotion.y - (int)p_mouse_y);
-			p_mouse_x=x_event.xmotion.x;
-			p_mouse_y=x_event.xmotion.y;
-		}
-		break;
-
-	case ButtonPress:
-		b=-1;
-		if (x_event.xbutton.button == 1)
-			b = 0;
-		else if (x_event.xbutton.button == 2)
-			b = 2;
-		else if (x_event.xbutton.button == 3)
-			b = 1;
-		if (b>=0)
-			mouse_buttonstate |= 1<<b;
-		break;
-
-	case ButtonRelease:
-		b=-1;
-		if (x_event.xbutton.button == 1)
-			b = 0;
-		else if (x_event.xbutton.button == 2)
-			b = 2;
-		else if (x_event.xbutton.button == 3)
-			b = 1;
-		if (b>=0)
-			mouse_buttonstate &= ~(1<<b);
-		break;
-	
-	case ConfigureNotify:
-		config_notify_width = x_event.xconfigure.width;
-		config_notify_height = x_event.xconfigure.height;
-		config_notify = 1;
-		break;
-
-	default:
-		if (doShm && x_event.type == x_shmeventtype)
-			oktodraw = true;
-	}
-   
-	if (old_windowed_mouse != _windowed_mouse->value) {
-		old_windowed_mouse = _windowed_mouse->value;
-
-		if (!_windowed_mouse->value) {
-			/* ungrab the pointer */
-			XUngrabPointer(x_disp,CurrentTime);
-		} else {
-			/* grab the pointer */
-			XGrabPointer(x_disp,x_win,True,0,GrabModeAsync,
-				GrabModeAsync,x_win,None,CurrentTime);
-		}
-	}
-}
-
-/*****************************************************************************/
-
-/*
-** SWimp_Init
-**
-** This routine is responsible for initializing the implementation
-** specific stuff in a software rendering subsystem.
-*/
-int SWimp_Init( void *hInstance, void *wndProc )
-{
-// open the display
-	x_disp = XOpenDisplay(0);
-	if (!x_disp)
-	{
-		if (getenv("DISPLAY"))
-			Sys_Error("VID: Could not open display [%s]\n",
-				getenv("DISPLAY"));
-		else
-			Sys_Error("VID: Could not open local display\n");
-	}
-
-// catch signals so i can turn on auto-repeat
-
-	{
-		struct sigaction sa;
-		sigaction(SIGINT, 0, &sa);
-		sa.sa_handler = TragicDeath;
-		sigaction(SIGINT, &sa, 0);
-		sigaction(SIGTERM, &sa, 0);
-	}
-
-	return true;
-}
-
-/*
-** SWimp_InitGraphics
-**
-** This initializes the software refresh's implementation specific
-** graphics subsystem.  In the case of Windows it creates DIB or
-** DDRAW surfaces.
-**
-** The necessary width and height parameters are grabbed from
-** vid.width and vid.height.
-*/
-static qboolean SWimp_InitGraphics( qboolean fullscreen )
-{
-	int pnum, i;
-	XVisualInfo template;
-	int num_visuals;
-	int template_mask;
-
-	srandom(getpid());
-
-	// free resources in use
-	SWimp_Shutdown ();
-
-	// let the sound and input subsystems know about the new window
-	ri.Vid_NewWindow (vid.width, vid.height);
-
-	XAutoRepeatOff(x_disp);
-
-// for debugging only
-	XSynchronize(x_disp, True);
-
-// check for command-line window size
-	template_mask = 0;
-
-#if 0
-// specify a visual id
-	if ((pnum=COM_CheckParm("-visualid")))
-	{
-		if (pnum >= com_argc-1)
-			Sys_Error("VID: -visualid <id#>\n");
-		template.visualid = Q_atoi(com_argv[pnum+1]);
-		template_mask = VisualIDMask;
-	}
-
-// If not specified, use default visual
-	else
-#endif
-	{
-		int screen;
-		screen = XDefaultScreen(x_disp);
-		template.visualid =
-			XVisualIDFromVisual(XDefaultVisual(x_disp, screen));
-		template_mask = VisualIDMask;
-	}
-
-// pick a visual- warn if more than one was available
-	x_visinfo = XGetVisualInfo(x_disp, template_mask, &template, &num_visuals);
-	if (num_visuals > 1)
-	{
-		printf("Found more than one visual id at depth %d:\n", template.depth);
-		for (i=0 ; i<num_visuals ; i++)
-			printf("	-visualid %d\n", (int)(x_visinfo[i].visualid));
-	}
-	else if (num_visuals == 0)
-	{
-		if (template_mask == VisualIDMask)
-			Sys_Error("VID: Bad visual id %d\n", template.visualid);
-		else
-			Sys_Error("VID: No visuals at depth %d\n", template.depth);
-	}
-
-#if 0
-	if (verbose)
-	{
-		printf("Using visualid %d:\n", (int)(x_visinfo->visualid));
-		printf("	screen %d\n", x_visinfo->screen);
-		printf("	red_mask 0x%x\n", (int)(x_visinfo->red_mask));
-		printf("	green_mask 0x%x\n", (int)(x_visinfo->green_mask));
-		printf("	blue_mask 0x%x\n", (int)(x_visinfo->blue_mask));
-		printf("	colormap_size %d\n", x_visinfo->colormap_size);
-		printf("	bits_per_rgb %d\n", x_visinfo->bits_per_rgb);
-	}
-#endif
-
-	x_vis = x_visinfo->visual;
-
-// setup attributes for main window
-	{
-	   int attribmask = CWEventMask  | CWColormap | CWBorderPixel;
-	   XSetWindowAttributes attribs;
-	   Colormap tmpcmap;
-	   
-	   tmpcmap = XCreateColormap(x_disp, XRootWindow(x_disp,
-							 x_visinfo->screen), x_vis, AllocNone);
-	   
-	   attribs.event_mask = STD_EVENT_MASK;
-	   attribs.border_pixel = 0;
-	   attribs.colormap = tmpcmap;
-
-// create the main window
-		x_win = XCreateWindow(	x_disp,
-			XRootWindow(x_disp, x_visinfo->screen),
-			0, 0,	// x, y
-			vid.width, vid.height,
-			0, // borderwidth
-			x_visinfo->depth,
-			InputOutput,
-			x_vis,
-			attribmask,
-			&attribs );
-		XStoreName(x_disp, x_win, "Quake II");
-
-		if (x_visinfo->class != TrueColor)
-			XFreeColormap(x_disp, tmpcmap);
-	}
-
-	if (x_visinfo->depth == 8)
-	{
-	// create and upload the palette
-		if (x_visinfo->class == PseudoColor)
-		{
-			x_cmap = XCreateColormap(x_disp, x_win, x_vis, AllocAll);
-			XSetWindowColormap(x_disp, x_win, x_cmap);
-		}
-
-	}
-
-// inviso cursor
-	XDefineCursor(x_disp, x_win, CreateNullCursor(x_disp, x_win));
-
-// create the GC
-	{
-		XGCValues xgcvalues;
-		int valuemask = GCGraphicsExposures;
-		xgcvalues.graphics_exposures = False;
-		x_gc = XCreateGC(x_disp, x_win, valuemask, &xgcvalues );
-	}
-
-// map the window
-	XMapWindow(x_disp, x_win);
-
-// wait for first exposure event
-	{
-		XEvent event;
-		do
-		{
-			XNextEvent(x_disp, &event);
-			if (event.type == Expose && !event.xexpose.count)
-				oktodraw = true;
-		} while (!oktodraw);
-	}
-// now safe to draw
-
-// even if MITSHM is available, make sure it's a local connection
-	if (XShmQueryExtension(x_disp))
-	{
-		char *displayname;
-		doShm = true;
-		displayname = (char *) getenv("DISPLAY");
-		if (displayname)
-		{
-			char *d = displayname;
-			while (*d && (*d != ':')) d++;
-			if (*d) *d = 0;
-			if (!(!strcasecmp(displayname, "unix") || !*displayname))
-				doShm = false;
-		}
-	}
-
-	if (doShm)
-	{
-		x_shmeventtype = XShmGetEventBase(x_disp) + ShmCompletion;
-		ResetSharedFrameBuffers();
-	}
-	else
-		ResetFrameBuffer();
-
-	current_framebuffer = 0;
-	vid.rowbytes = x_framebuffer[0]->bytes_per_line;
-	vid.buffer = x_framebuffer[0]->data;
-
-//	XSynchronize(x_disp, False);
-
-	X11_active = true;
-
-	return true;
-}
-
-/*
-** SWimp_EndFrame
-**
-** This does an implementation specific copy from the backbuffer to the
-** front buffer.  In the Win32 case it uses BitBlt or BltFast depending
-** on whether we're using DIB sections/GDI or DDRAW.
-*/
-void SWimp_EndFrame (void)
-{
-// if the window changes dimension, skip this frame
-#if 0
-	if (config_notify)
-	{
-		fprintf(stderr, "config notify\n");
-		config_notify = 0;
-		vid.width = config_notify_width & ~7;
-		vid.height = config_notify_height;
-		if (doShm)
-			ResetSharedFrameBuffers();
-		else
-			ResetFrameBuffer();
-		vid.rowbytes = x_framebuffer[0]->bytes_per_line;
-		vid.buffer = x_framebuffer[current_framebuffer]->data;
-		vid.recalc_refdef = 1;				// force a surface cache flush
-		Con_CheckResize();
-		Con_Clear_f();
-		return;
-	}
-#endif
-
-	if (doShm)
-	{
-
-		if (x_visinfo->depth != 8)
-			st2_fixup( x_framebuffer[current_framebuffer], 
-				0, 0, vid.width, vid.height);	
-		if (!XShmPutImage(x_disp, x_win, x_gc,
-			x_framebuffer[current_framebuffer], 0, 0,
-			0, 0, vid.width, vid.height, True))
-				Sys_Error("VID_Update: XShmPutImage failed\n");
-		oktodraw = false;
-		while (!oktodraw) 
-			GetEvent();
-		current_framebuffer = !current_framebuffer;
-		vid.buffer = x_framebuffer[current_framebuffer]->data;
-		XSync(x_disp, False);
-	}
-	else
-	{
-		if (x_visinfo->depth != 8)
-			st2_fixup( x_framebuffer[current_framebuffer], 
-				0, 0, vid.width, vid.height);
-		XPutImage(x_disp, x_win, x_gc, x_framebuffer[0],
-			0, 0, 0, 0, vid.width, vid.height);
-		XSync(x_disp, False);
-	}
-}
-
-/*
-** SWimp_SetMode
-*/
-rserr_t SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen )
-{
-	rserr_t retval = rserr_ok;
-
-	ri.Con_Printf (PRINT_ALL, "setting mode %d:", mode );
-
-	if ( !ri.Vid_GetModeInfo( pwidth, pheight, mode ) )
-	{
-		ri.Con_Printf( PRINT_ALL, " invalid mode\n" );
-		return rserr_invalid_mode;
-	}
-
-	ri.Con_Printf( PRINT_ALL, " %d %d\n", *pwidth, *pheight);
-
-	if ( !SWimp_InitGraphics( false ) ) {
-		// failed to set a valid mode in windowed mode
-		return rserr_invalid_mode;
-	}
-
-	R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
-
-	return retval;
-}
-
-/*
-** SWimp_SetPalette
-**
-** System specific palette setting routine.  A NULL palette means
-** to use the existing palette.  The palette is expected to be in
-** a padded 4-byte xRGB format.
-*/
-void SWimp_SetPalette( const unsigned char *palette )
-{
-	int i;
-	XColor colors[256];
-
-	if (!X11_active)
-		return;
-
-    if ( !palette )
-        palette = ( const unsigned char * ) sw_state.currentpalette;
- 
-	for(i=0;i<256;i++)
-		st2d_8to16table[i]= xlib_rgb(palette[i*4],
-			palette[i*4+1],palette[i*4+2]);
-
-	if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8)
-	{
-		for (i=0 ; i<256 ; i++)
-		{
-			colors[i].pixel = i;
-			colors[i].flags = DoRed|DoGreen|DoBlue;
-			colors[i].red = palette[i*4] * 257;
-			colors[i].green = palette[i*4+1] * 257;
-			colors[i].blue = palette[i*4+2] * 257;
-		}
-		XStoreColors(x_disp, x_cmap, colors, 256);
-	}
-}
-
-/*
-** SWimp_Shutdown
-**
-** System specific graphics subsystem shutdown routine.  Destroys
-** DIBs or DDRAW surfaces as appropriate.
-*/
-void SWimp_Shutdown( void )
-{
-	int i;
-
-	if (!X11_active)
-		return;
-
-	if (doShm) {
-		for (i = 0; i < 2; i++)
-			if (x_framebuffer[i]) {
-				XShmDetach(x_disp, &x_shminfo[i]);
-				free(x_framebuffer[i]);
-				shmdt(x_shminfo[i].shmaddr);
-				x_framebuffer[i] = NULL;
-			}
-	} else if (x_framebuffer[0]) {
-		free(x_framebuffer[0]->data);
-		free(x_framebuffer[0]);
-		x_framebuffer[0] = NULL;
-	}
-
-	XDestroyWindow(	x_disp, x_win );
-
-	XAutoRepeatOn(x_disp);
-//	XCloseDisplay(x_disp);
-
-	X11_active = false;
-}
-
-/*
-** SWimp_AppActivate
-*/
-void SWimp_AppActivate( qboolean active )
-{
-}
-
-//===============================================================================
-
-/*
-================
-Sys_MakeCodeWriteable
-================
-*/
-void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
-{
-
-	int r;
-	unsigned long addr;
-	int psize = getpagesize();
-
-	addr = (startaddr & ~(psize-1)) - psize;
-
-//	fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
-//			addr, startaddr+length, length);
-
-	r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
-
-	if (r < 0)
-    		Sys_Error("Protection change failed\n");
-
-}
-
-/*****************************************************************************/
-/* KEYBOARD                                                                  */
-/*****************************************************************************/
-
-Key_Event_fp_t Key_Event_fp;
-
-void KBD_Init(Key_Event_fp_t fp)
-{
-	Key_Event_fp = fp;
-}
-
-void KBD_Update(void)
-{
-// get events from x server
-	if (x_disp)
-	{
-		while (XPending(x_disp)) 
-			GetEvent();
-		while (keyq_head != keyq_tail)
-		{
-			Key_Event_fp(keyq[keyq_tail].key, keyq[keyq_tail].down);
-			keyq_tail = (keyq_tail + 1) & 63;
-		}
-	}
-}
-
-void KBD_Close(void)
-{
-}
-
-
--- /dev/null
+++ b/plan9/snd_9.c
@@ -1,0 +1,266 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <sys/shm.h>
+#include <sys/wait.h>
+#include <linux/soundcard.h>
+#include <stdio.h>
+
+#include "../client/client.h"
+#include "../client/snd_loc.h"
+
+int audio_fd;
+int snd_inited;
+
+cvar_t *sndbits;
+cvar_t *sndspeed;
+cvar_t *sndchannels;
+cvar_t *snddevice;
+
+static int tryrates[] = { 11025, 22051, 44100, 8000 };
+
+qboolean SNDDMA_Init(void)
+{
+
+	int rc;
+    int fmt;
+	int tmp;
+    int i;
+    char *s;
+	struct audio_buf_info info;
+	int caps;
+	extern uid_t saved_euid;
+
+	if (snd_inited)
+		return;
+
+	if (!snddevice) {
+		sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
+		sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
+		sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
+		snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
+	}
+
+// open /dev/dsp, confirm capability to mmap, and get size of dma buffer
+
+	if (!audio_fd) {
+		seteuid(saved_euid);
+
+		audio_fd = open(snddevice->string, O_RDWR);
+
+		seteuid(getuid());
+
+		if (audio_fd < 0)
+		{
+			perror(snddevice->string);
+			Com_Printf("Could not open %s\n", snddevice->string);
+			return 0;
+		}
+	}
+
+    rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
+    if (rc < 0)
+	{
+		perror(snddevice->string);
+		Com_Printf("Could not reset %s\n", snddevice->string);
+		close(audio_fd);
+		return 0;
+	}
+
+	if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
+	{
+		perror(snddevice->string);
+        Com_Printf("Sound driver too old\n");
+		close(audio_fd);
+		return 0;
+	}
+
+	if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
+	{
+		Com_Printf("Sorry but your soundcard can't do this\n");
+		close(audio_fd);
+		return 0;
+	}
+
+    if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
+    {   
+        perror("GETOSPACE");
+		Com_Printf("Um, can't do GETOSPACE?\n");
+		close(audio_fd);
+		return 0;
+    }
+    
+// set sample bits & speed
+
+    dma.samplebits = (int)sndbits->value;
+	if (dma.samplebits != 16 && dma.samplebits != 8)
+    {
+        ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
+        if (fmt & AFMT_S16_LE) dma.samplebits = 16;
+        else if (fmt & AFMT_U8) dma.samplebits = 8;
+    }
+
+	dma.speed = (int)sndspeed->value;
+	if (!dma.speed) {
+        for (i=0 ; i<sizeof(tryrates)/4 ; i++)
+            if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
+        dma.speed = tryrates[i];
+    }
+
+	dma.channels = (int)sndchannels->value;
+	if (dma.channels < 1 || dma.channels > 2)
+		dma.channels = 2;
+	
+	dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
+	dma.submission_chunk = 1;
+
+// memory map the dma buffer
+
+	if (!dma.buffer)
+		dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
+			* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
+	if (!dma.buffer)
+	{
+		perror(snddevice->string);
+		Com_Printf("Could not mmap %s\n", snddevice->string);
+		close(audio_fd);
+		return 0;
+	}
+
+	tmp = 0;
+	if (dma.channels == 2)
+		tmp = 1;
+    rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
+    if (rc < 0)
+    {
+		perror(snddevice->string);
+        Com_Printf("Could not set %s to stereo=%d", snddevice->string, dma.channels);
+		close(audio_fd);
+        return 0;
+    }
+	if (tmp)
+		dma.channels = 2;
+	else
+		dma.channels = 1;
+
+    rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
+    if (rc < 0)
+    {
+		perror(snddevice->string);
+        Com_Printf("Could not set %s speed to %d", snddevice->string, dma.speed);
+		close(audio_fd);
+        return 0;
+    }
+
+    if (dma.samplebits == 16)
+    {
+        rc = AFMT_S16_LE;
+        rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
+        if (rc < 0)
+		{
+			perror(snddevice->string);
+			Com_Printf("Could not support 16-bit data.  Try 8-bit.\n");
+			close(audio_fd);
+			return 0;
+		}
+    }
+    else if (dma.samplebits == 8)
+    {
+        rc = AFMT_U8;
+        rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
+        if (rc < 0)
+		{
+			perror(snddevice->string);
+			Com_Printf("Could not support 8-bit data.\n");
+			close(audio_fd);
+			return 0;
+		}
+    }
+	else
+	{
+		perror(snddevice->string);
+		Com_Printf("%d-bit sound not supported.", dma.samplebits);
+		close(audio_fd);
+		return 0;
+	}
+
+// toggle the trigger & start her up
+
+    tmp = 0;
+    rc  = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
+	if (rc < 0)
+	{
+		perror(snddevice->string);
+		Com_Printf("Could not toggle.\n");
+		close(audio_fd);
+		return 0;
+	}
+    tmp = PCM_ENABLE_OUTPUT;
+    rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
+	if (rc < 0)
+	{
+		perror(snddevice->string);
+		Com_Printf("Could not toggle.\n");
+		close(audio_fd);
+		return 0;
+	}
+
+	dma.samplepos = 0;
+
+	snd_inited = 1;
+	return 1;
+
+}
+
+int SNDDMA_GetDMAPos(void)
+{
+
+	struct count_info count;
+
+	if (!snd_inited) return 0;
+
+	if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
+	{
+		perror(snddevice->string);
+		Com_Printf("Uh, sound dead.\n");
+		close(audio_fd);
+		snd_inited = 0;
+		return 0;
+	}
+//	dma.samplepos = (count.bytes / (dma.samplebits / 8)) & (dma.samples-1);
+//	fprintf(stderr, "%d    \r", count.ptr);
+	dma.samplepos = count.ptr / (dma.samplebits / 8);
+
+	return dma.samplepos;
+
+}
+
+void SNDDMA_Shutdown(void)
+{
+#if 0
+	if (snd_inited)
+	{
+		close(audio_fd);
+		snd_inited = 0;
+	}
+#endif
+}
+
+/*
+==============
+SNDDMA_Submit
+
+Send sound to device if buffer isn't really the dma buffer
+===============
+*/
+void SNDDMA_Submit(void)
+{
+}
+
+void SNDDMA_BeginPainting (void)
+{
+}
+
--- a/plan9/snd_linux.c
+++ /dev/null
@@ -1,266 +1,0 @@
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <sys/shm.h>
-#include <sys/wait.h>
-#include <linux/soundcard.h>
-#include <stdio.h>
-
-#include "../client/client.h"
-#include "../client/snd_loc.h"
-
-int audio_fd;
-int snd_inited;
-
-cvar_t *sndbits;
-cvar_t *sndspeed;
-cvar_t *sndchannels;
-cvar_t *snddevice;
-
-static int tryrates[] = { 11025, 22051, 44100, 8000 };
-
-qboolean SNDDMA_Init(void)
-{
-
-	int rc;
-    int fmt;
-	int tmp;
-    int i;
-    char *s;
-	struct audio_buf_info info;
-	int caps;
-	extern uid_t saved_euid;
-
-	if (snd_inited)
-		return;
-
-	if (!snddevice) {
-		sndbits = Cvar_Get("sndbits", "16", CVAR_ARCHIVE);
-		sndspeed = Cvar_Get("sndspeed", "0", CVAR_ARCHIVE);
-		sndchannels = Cvar_Get("sndchannels", "2", CVAR_ARCHIVE);
-		snddevice = Cvar_Get("snddevice", "/dev/dsp", CVAR_ARCHIVE);
-	}
-
-// open /dev/dsp, confirm capability to mmap, and get size of dma buffer
-
-	if (!audio_fd) {
-		seteuid(saved_euid);
-
-		audio_fd = open(snddevice->string, O_RDWR);
-
-		seteuid(getuid());
-
-		if (audio_fd < 0)
-		{
-			perror(snddevice->string);
-			Com_Printf("Could not open %s\n", snddevice->string);
-			return 0;
-		}
-	}
-
-    rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
-    if (rc < 0)
-	{
-		perror(snddevice->string);
-		Com_Printf("Could not reset %s\n", snddevice->string);
-		close(audio_fd);
-		return 0;
-	}
-
-	if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
-	{
-		perror(snddevice->string);
-        Com_Printf("Sound driver too old\n");
-		close(audio_fd);
-		return 0;
-	}
-
-	if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
-	{
-		Com_Printf("Sorry but your soundcard can't do this\n");
-		close(audio_fd);
-		return 0;
-	}
-
-    if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info)==-1)
-    {   
-        perror("GETOSPACE");
-		Com_Printf("Um, can't do GETOSPACE?\n");
-		close(audio_fd);
-		return 0;
-    }
-    
-// set sample bits & speed
-
-    dma.samplebits = (int)sndbits->value;
-	if (dma.samplebits != 16 && dma.samplebits != 8)
-    {
-        ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
-        if (fmt & AFMT_S16_LE) dma.samplebits = 16;
-        else if (fmt & AFMT_U8) dma.samplebits = 8;
-    }
-
-	dma.speed = (int)sndspeed->value;
-	if (!dma.speed) {
-        for (i=0 ; i<sizeof(tryrates)/4 ; i++)
-            if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
-        dma.speed = tryrates[i];
-    }
-
-	dma.channels = (int)sndchannels->value;
-	if (dma.channels < 1 || dma.channels > 2)
-		dma.channels = 2;
-	
-	dma.samples = info.fragstotal * info.fragsize / (dma.samplebits/8);
-	dma.submission_chunk = 1;
-
-// memory map the dma buffer
-
-	if (!dma.buffer)
-		dma.buffer = (unsigned char *) mmap(NULL, info.fragstotal
-			* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
-	if (!dma.buffer)
-	{
-		perror(snddevice->string);
-		Com_Printf("Could not mmap %s\n", snddevice->string);
-		close(audio_fd);
-		return 0;
-	}
-
-	tmp = 0;
-	if (dma.channels == 2)
-		tmp = 1;
-    rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
-    if (rc < 0)
-    {
-		perror(snddevice->string);
-        Com_Printf("Could not set %s to stereo=%d", snddevice->string, dma.channels);
-		close(audio_fd);
-        return 0;
-    }
-	if (tmp)
-		dma.channels = 2;
-	else
-		dma.channels = 1;
-
-    rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &dma.speed);
-    if (rc < 0)
-    {
-		perror(snddevice->string);
-        Com_Printf("Could not set %s speed to %d", snddevice->string, dma.speed);
-		close(audio_fd);
-        return 0;
-    }
-
-    if (dma.samplebits == 16)
-    {
-        rc = AFMT_S16_LE;
-        rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
-        if (rc < 0)
-		{
-			perror(snddevice->string);
-			Com_Printf("Could not support 16-bit data.  Try 8-bit.\n");
-			close(audio_fd);
-			return 0;
-		}
-    }
-    else if (dma.samplebits == 8)
-    {
-        rc = AFMT_U8;
-        rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
-        if (rc < 0)
-		{
-			perror(snddevice->string);
-			Com_Printf("Could not support 8-bit data.\n");
-			close(audio_fd);
-			return 0;
-		}
-    }
-	else
-	{
-		perror(snddevice->string);
-		Com_Printf("%d-bit sound not supported.", dma.samplebits);
-		close(audio_fd);
-		return 0;
-	}
-
-// toggle the trigger & start her up
-
-    tmp = 0;
-    rc  = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
-	if (rc < 0)
-	{
-		perror(snddevice->string);
-		Com_Printf("Could not toggle.\n");
-		close(audio_fd);
-		return 0;
-	}
-    tmp = PCM_ENABLE_OUTPUT;
-    rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
-	if (rc < 0)
-	{
-		perror(snddevice->string);
-		Com_Printf("Could not toggle.\n");
-		close(audio_fd);
-		return 0;
-	}
-
-	dma.samplepos = 0;
-
-	snd_inited = 1;
-	return 1;
-
-}
-
-int SNDDMA_GetDMAPos(void)
-{
-
-	struct count_info count;
-
-	if (!snd_inited) return 0;
-
-	if (ioctl(audio_fd, SNDCTL_DSP_GETOPTR, &count)==-1)
-	{
-		perror(snddevice->string);
-		Com_Printf("Uh, sound dead.\n");
-		close(audio_fd);
-		snd_inited = 0;
-		return 0;
-	}
-//	dma.samplepos = (count.bytes / (dma.samplebits / 8)) & (dma.samples-1);
-//	fprintf(stderr, "%d    \r", count.ptr);
-	dma.samplepos = count.ptr / (dma.samplebits / 8);
-
-	return dma.samplepos;
-
-}
-
-void SNDDMA_Shutdown(void)
-{
-#if 0
-	if (snd_inited)
-	{
-		close(audio_fd);
-		snd_inited = 0;
-	}
-#endif
-}
-
-/*
-==============
-SNDDMA_Submit
-
-Send sound to device if buffer isn't really the dma buffer
-===============
-*/
-void SNDDMA_Submit(void)
-{
-}
-
-void SNDDMA_BeginPainting (void)
-{
-}
-
--- /dev/null
+++ b/plan9/sys_9.c
@@ -1,0 +1,381 @@
+#include <unistd.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <mntent.h>
+
+#include <dlfcn.h>
+
+#include "../qcommon/qcommon.h"
+
+#include "../linux/rw_linux.h"
+
+cvar_t *nostdout;
+
+unsigned	sys_frame_time;
+
+uid_t saved_euid;
+qboolean stdin_active = true;
+
+// =======================================================================
+// General routines
+// =======================================================================
+
+void Sys_ConsoleOutput (char *string)
+{
+	if (nostdout && nostdout->value)
+		return;
+
+	fputs(string, stdout);
+}
+
+void Sys_Printf (char *fmt, ...)
+{
+	va_list		argptr;
+	char		text[1024];
+	unsigned char		*p;
+
+	va_start (argptr,fmt);
+	vsprintf (text,fmt,argptr);
+	va_end (argptr);
+
+	if (strlen(text) > sizeof(text))
+		Sys_Error("memory overwrite in Sys_Printf");
+
+    if (nostdout && nostdout->value)
+        return;
+
+	for (p = (unsigned char *)text; *p; p++) {
+		*p &= 0x7f;
+		if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
+			printf("[%02x]", *p);
+		else
+			putc(*p, stdout);
+	}
+}
+
+void Sys_Quit (void)
+{
+	CL_Shutdown ();
+	Qcommon_Shutdown ();
+    fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
+	_exit(0);
+}
+
+void Sys_Init(void)
+{
+#if id386
+//	Sys_SetFPCW();
+#endif
+}
+
+void Sys_Error (char *error, ...)
+{ 
+    va_list     argptr;
+    char        string[1024];
+
+// change stdin to non blocking
+    fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
+
+	CL_Shutdown ();
+	Qcommon_Shutdown ();
+    
+    va_start (argptr,error);
+    vsprintf (string,error,argptr);
+    va_end (argptr);
+	fprintf(stderr, "Error: %s\n", string);
+
+	_exit (1);
+
+} 
+
+void Sys_Warn (char *warning, ...)
+{ 
+    va_list     argptr;
+    char        string[1024];
+    
+    va_start (argptr,warning);
+    vsprintf (string,warning,argptr);
+    va_end (argptr);
+	fprintf(stderr, "Warning: %s", string);
+} 
+
+/*
+============
+Sys_FileTime
+
+returns -1 if not present
+============
+*/
+int	Sys_FileTime (char *path)
+{
+	struct	stat	buf;
+	
+	if (stat (path,&buf) == -1)
+		return -1;
+	
+	return buf.st_mtime;
+}
+
+void floating_point_exception_handler(int whatever)
+{
+//	Sys_Warn("floating point exception\n");
+	signal(SIGFPE, floating_point_exception_handler);
+}
+
+char *Sys_ConsoleInput(void)
+{
+    static char text[256];
+    int     len;
+	fd_set	fdset;
+    struct timeval timeout;
+
+	if (!dedicated || !dedicated->value)
+		return NULL;
+
+	if (!stdin_active)
+		return NULL;
+
+	FD_ZERO(&fdset);
+	FD_SET(0, &fdset); // stdin
+	timeout.tv_sec = 0;
+	timeout.tv_usec = 0;
+	if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
+		return NULL;
+
+	len = read (0, text, sizeof(text));
+	if (len == 0) { // eof!
+		stdin_active = false;
+		return NULL;
+	}
+
+	if (len < 1)
+		return NULL;
+	text[len-1] = 0;    // rip off the /n and terminate
+
+	return text;
+}
+
+/*****************************************************************************/
+
+static void *game_library;
+
+/*
+=================
+Sys_UnloadGame
+=================
+*/
+void Sys_UnloadGame (void)
+{
+	if (game_library) 
+		dlclose (game_library);
+	game_library = NULL;
+}
+
+/*
+=================
+Sys_GetGameAPI
+
+Loads the game dll
+=================
+*/
+void *Sys_GetGameAPI (void *parms)
+{
+	void	*(*GetGameAPI) (void *);
+
+	char	name[MAX_OSPATH];
+	char	curpath[MAX_OSPATH];
+	char	*path;
+#ifdef __i386__
+	const char *gamename = "gamei386.so";
+#elif defined __alpha__
+	const char *gamename = "gameaxp.so";
+#else
+#error Unknown arch
+#endif
+
+	setreuid(getuid(), getuid());
+	setegid(getgid());
+
+	if (game_library)
+		Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
+
+	getcwd(curpath, sizeof(curpath));
+
+	Com_Printf("------- Loading %s -------", gamename);
+
+	// now run through the search paths
+	path = NULL;
+	while (1)
+	{
+		path = FS_NextPath (path);
+		if (!path)
+			return NULL;		// couldn't find one anywhere
+		sprintf (name, "%s/%s/%s", curpath, path, gamename);
+		game_library = dlopen (name, RTLD_NOW );
+		if (game_library)
+		{
+			Com_DPrintf ("LoadLibrary (%s)\n",name);
+			break;
+		}
+		else
+			printf("dlerror: %s\n", dlerror());
+	}
+
+	GetGameAPI = (void *)dlsym (game_library, "GetGameAPI");
+	if (!GetGameAPI)
+	{
+		Sys_UnloadGame ();		
+		return NULL;
+	}
+
+	return GetGameAPI (parms);
+}
+
+/*****************************************************************************/
+
+void Sys_AppActivate (void)
+{
+}
+
+void Sys_SendKeyEvents (void)
+{
+#ifndef DEDICATED_ONLY
+	if (KBD_Update_fp)
+		KBD_Update_fp();
+#endif
+
+	// grab frame time 
+	sys_frame_time = Sys_Milliseconds();
+}
+
+/*****************************************************************************/
+
+char *Sys_GetClipboardData(void)
+{
+	return NULL;
+}
+
+int main (int argc, char **argv)
+{
+	int 	time, oldtime, newtime;
+
+	// go back to real user for config loads
+	saved_euid = geteuid();
+	seteuid(getuid());
+
+	Qcommon_Init(argc, argv);
+
+	fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
+
+	nostdout = Cvar_Get("nostdout", "0", 0);
+	if (!nostdout->value) {
+		fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
+//		printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION);
+	}
+
+    oldtime = Sys_Milliseconds ();
+    while (1)
+    {
+// find time spent rendering last frame
+		do {
+			newtime = Sys_Milliseconds ();
+			time = newtime - oldtime;
+		} while (time < 1);
+        Qcommon_Frame (time);
+		oldtime = newtime;
+    }
+
+}
+
+void Sys_CopyProtect(void)
+{
+	FILE *mnt;
+	struct mntent *ent;
+	char path[MAX_OSPATH];
+	struct stat st;
+	qboolean found_cd = false;
+
+	static qboolean checked = false;
+
+	if (checked)
+		return;
+
+	if ((mnt = setmntent("/etc/mtab", "r")) == NULL)
+		Com_Error(ERR_FATAL, "Can't read mount table to determine mounted cd location.");
+
+	while ((ent = getmntent(mnt)) != NULL) {
+		if (strcmp(ent->mnt_type, "iso9660") == 0) {
+			// found a cd file system
+			found_cd = true;
+			sprintf(path, "%s/%s", ent->mnt_dir, "install/data/quake2.exe");
+			if (stat(path, &st) == 0) {
+				// found it
+				checked = true;
+				endmntent(mnt);
+				return;
+			}
+			sprintf(path, "%s/%s", ent->mnt_dir, "Install/Data/quake2.exe");
+			if (stat(path, &st) == 0) {
+				// found it
+				checked = true;
+				endmntent(mnt);
+				return;
+			}
+			sprintf(path, "%s/%s", ent->mnt_dir, "quake2.exe");
+			if (stat(path, &st) == 0) {
+				// found it
+				checked = true;
+				endmntent(mnt);
+				return;
+			}
+		}
+	}
+	endmntent(mnt);
+
+	if (found_cd)
+		Com_Error (ERR_FATAL, "Could not find a Quake2 CD in your CD drive.");
+	Com_Error (ERR_FATAL, "Unable to find a mounted iso9660 file system.\n"
+		"You must mount the Quake2 CD in a cdrom drive in order to play.");
+}
+
+#if 0
+/*
+================
+Sys_MakeCodeWriteable
+================
+*/
+void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
+{
+
+	int r;
+	unsigned long addr;
+	int psize = getpagesize();
+
+	addr = (startaddr & ~(psize-1)) - psize;
+
+//	fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
+//			addr, startaddr+length, length);
+
+	r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
+
+	if (r < 0)
+    		Sys_Error("Protection change failed\n");
+
+}
+
+#endif
--- a/plan9/sys_linux.c
+++ /dev/null
@@ -1,381 +1,0 @@
-#include <unistd.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-#include <sys/stat.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/wait.h>
-#include <sys/mman.h>
-#include <errno.h>
-#include <mntent.h>
-
-#include <dlfcn.h>
-
-#include "../qcommon/qcommon.h"
-
-#include "../linux/rw_linux.h"
-
-cvar_t *nostdout;
-
-unsigned	sys_frame_time;
-
-uid_t saved_euid;
-qboolean stdin_active = true;
-
-// =======================================================================
-// General routines
-// =======================================================================
-
-void Sys_ConsoleOutput (char *string)
-{
-	if (nostdout && nostdout->value)
-		return;
-
-	fputs(string, stdout);
-}
-
-void Sys_Printf (char *fmt, ...)
-{
-	va_list		argptr;
-	char		text[1024];
-	unsigned char		*p;
-
-	va_start (argptr,fmt);
-	vsprintf (text,fmt,argptr);
-	va_end (argptr);
-
-	if (strlen(text) > sizeof(text))
-		Sys_Error("memory overwrite in Sys_Printf");
-
-    if (nostdout && nostdout->value)
-        return;
-
-	for (p = (unsigned char *)text; *p; p++) {
-		*p &= 0x7f;
-		if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
-			printf("[%02x]", *p);
-		else
-			putc(*p, stdout);
-	}
-}
-
-void Sys_Quit (void)
-{
-	CL_Shutdown ();
-	Qcommon_Shutdown ();
-    fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
-	_exit(0);
-}
-
-void Sys_Init(void)
-{
-#if id386
-//	Sys_SetFPCW();
-#endif
-}
-
-void Sys_Error (char *error, ...)
-{ 
-    va_list     argptr;
-    char        string[1024];
-
-// change stdin to non blocking
-    fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
-
-	CL_Shutdown ();
-	Qcommon_Shutdown ();
-    
-    va_start (argptr,error);
-    vsprintf (string,error,argptr);
-    va_end (argptr);
-	fprintf(stderr, "Error: %s\n", string);
-
-	_exit (1);
-
-} 
-
-void Sys_Warn (char *warning, ...)
-{ 
-    va_list     argptr;
-    char        string[1024];
-    
-    va_start (argptr,warning);
-    vsprintf (string,warning,argptr);
-    va_end (argptr);
-	fprintf(stderr, "Warning: %s", string);
-} 
-
-/*
-============
-Sys_FileTime
-
-returns -1 if not present
-============
-*/
-int	Sys_FileTime (char *path)
-{
-	struct	stat	buf;
-	
-	if (stat (path,&buf) == -1)
-		return -1;
-	
-	return buf.st_mtime;
-}
-
-void floating_point_exception_handler(int whatever)
-{
-//	Sys_Warn("floating point exception\n");
-	signal(SIGFPE, floating_point_exception_handler);
-}
-
-char *Sys_ConsoleInput(void)
-{
-    static char text[256];
-    int     len;
-	fd_set	fdset;
-    struct timeval timeout;
-
-	if (!dedicated || !dedicated->value)
-		return NULL;
-
-	if (!stdin_active)
-		return NULL;
-
-	FD_ZERO(&fdset);
-	FD_SET(0, &fdset); // stdin
-	timeout.tv_sec = 0;
-	timeout.tv_usec = 0;
-	if (select (1, &fdset, NULL, NULL, &timeout) == -1 || !FD_ISSET(0, &fdset))
-		return NULL;
-
-	len = read (0, text, sizeof(text));
-	if (len == 0) { // eof!
-		stdin_active = false;
-		return NULL;
-	}
-
-	if (len < 1)
-		return NULL;
-	text[len-1] = 0;    // rip off the /n and terminate
-
-	return text;
-}
-
-/*****************************************************************************/
-
-static void *game_library;
-
-/*
-=================
-Sys_UnloadGame
-=================
-*/
-void Sys_UnloadGame (void)
-{
-	if (game_library) 
-		dlclose (game_library);
-	game_library = NULL;
-}
-
-/*
-=================
-Sys_GetGameAPI
-
-Loads the game dll
-=================
-*/
-void *Sys_GetGameAPI (void *parms)
-{
-	void	*(*GetGameAPI) (void *);
-
-	char	name[MAX_OSPATH];
-	char	curpath[MAX_OSPATH];
-	char	*path;
-#ifdef __i386__
-	const char *gamename = "gamei386.so";
-#elif defined __alpha__
-	const char *gamename = "gameaxp.so";
-#else
-#error Unknown arch
-#endif
-
-	setreuid(getuid(), getuid());
-	setegid(getgid());
-
-	if (game_library)
-		Com_Error (ERR_FATAL, "Sys_GetGameAPI without Sys_UnloadingGame");
-
-	getcwd(curpath, sizeof(curpath));
-
-	Com_Printf("------- Loading %s -------", gamename);
-
-	// now run through the search paths
-	path = NULL;
-	while (1)
-	{
-		path = FS_NextPath (path);
-		if (!path)
-			return NULL;		// couldn't find one anywhere
-		sprintf (name, "%s/%s/%s", curpath, path, gamename);
-		game_library = dlopen (name, RTLD_NOW );
-		if (game_library)
-		{
-			Com_DPrintf ("LoadLibrary (%s)\n",name);
-			break;
-		}
-		else
-			printf("dlerror: %s\n", dlerror());
-	}
-
-	GetGameAPI = (void *)dlsym (game_library, "GetGameAPI");
-	if (!GetGameAPI)
-	{
-		Sys_UnloadGame ();		
-		return NULL;
-	}
-
-	return GetGameAPI (parms);
-}
-
-/*****************************************************************************/
-
-void Sys_AppActivate (void)
-{
-}
-
-void Sys_SendKeyEvents (void)
-{
-#ifndef DEDICATED_ONLY
-	if (KBD_Update_fp)
-		KBD_Update_fp();
-#endif
-
-	// grab frame time 
-	sys_frame_time = Sys_Milliseconds();
-}
-
-/*****************************************************************************/
-
-char *Sys_GetClipboardData(void)
-{
-	return NULL;
-}
-
-int main (int argc, char **argv)
-{
-	int 	time, oldtime, newtime;
-
-	// go back to real user for config loads
-	saved_euid = geteuid();
-	seteuid(getuid());
-
-	Qcommon_Init(argc, argv);
-
-	fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
-
-	nostdout = Cvar_Get("nostdout", "0", 0);
-	if (!nostdout->value) {
-		fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
-//		printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION);
-	}
-
-    oldtime = Sys_Milliseconds ();
-    while (1)
-    {
-// find time spent rendering last frame
-		do {
-			newtime = Sys_Milliseconds ();
-			time = newtime - oldtime;
-		} while (time < 1);
-        Qcommon_Frame (time);
-		oldtime = newtime;
-    }
-
-}
-
-void Sys_CopyProtect(void)
-{
-	FILE *mnt;
-	struct mntent *ent;
-	char path[MAX_OSPATH];
-	struct stat st;
-	qboolean found_cd = false;
-
-	static qboolean checked = false;
-
-	if (checked)
-		return;
-
-	if ((mnt = setmntent("/etc/mtab", "r")) == NULL)
-		Com_Error(ERR_FATAL, "Can't read mount table to determine mounted cd location.");
-
-	while ((ent = getmntent(mnt)) != NULL) {
-		if (strcmp(ent->mnt_type, "iso9660") == 0) {
-			// found a cd file system
-			found_cd = true;
-			sprintf(path, "%s/%s", ent->mnt_dir, "install/data/quake2.exe");
-			if (stat(path, &st) == 0) {
-				// found it
-				checked = true;
-				endmntent(mnt);
-				return;
-			}
-			sprintf(path, "%s/%s", ent->mnt_dir, "Install/Data/quake2.exe");
-			if (stat(path, &st) == 0) {
-				// found it
-				checked = true;
-				endmntent(mnt);
-				return;
-			}
-			sprintf(path, "%s/%s", ent->mnt_dir, "quake2.exe");
-			if (stat(path, &st) == 0) {
-				// found it
-				checked = true;
-				endmntent(mnt);
-				return;
-			}
-		}
-	}
-	endmntent(mnt);
-
-	if (found_cd)
-		Com_Error (ERR_FATAL, "Could not find a Quake2 CD in your CD drive.");
-	Com_Error (ERR_FATAL, "Unable to find a mounted iso9660 file system.\n"
-		"You must mount the Quake2 CD in a cdrom drive in order to play.");
-}
-
-#if 0
-/*
-================
-Sys_MakeCodeWriteable
-================
-*/
-void Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length)
-{
-
-	int r;
-	unsigned long addr;
-	int psize = getpagesize();
-
-	addr = (startaddr & ~(psize-1)) - psize;
-
-//	fprintf(stderr, "writable code %lx(%lx)-%lx, length=%lx\n", startaddr,
-//			addr, startaddr+length, length);
-
-	r = mprotect((char*)addr, length + startaddr - addr + psize, 7);
-
-	if (r < 0)
-    		Sys_Error("Protection change failed\n");
-
-}
-
-#endif
--- /dev/null
+++ b/ref/adivtab.h
@@ -1,0 +1,1077 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// table of quotients and remainders for [-15...16] / [-15...16]
+
+// numerator = -15
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{1, -4},
+{1, -5},
+{1, -6},
+{1, -7},
+{2, -1},
+{2, -3},
+{3, 0},
+{3, -3},
+{5, 0},
+{7, -1},
+{15, 0},
+{0, 0},
+{-15, 0},
+{-8, 1},
+{-5, 0},
+{-4, 1},
+{-3, 0},
+{-3, 3},
+{-3, 6},
+{-2, 1},
+{-2, 3},
+{-2, 5},
+{-2, 7},
+{-2, 9},
+{-2, 11},
+{-2, 13},
+{-1, 0},
+{-1, 1},
+// numerator = -14
+{0, -14},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{1, -4},
+{1, -5},
+{1, -6},
+{2, 0},
+{2, -2},
+{2, -4},
+{3, -2},
+{4, -2},
+{7, 0},
+{14, 0},
+{0, 0},
+{-14, 0},
+{-7, 0},
+{-5, 1},
+{-4, 2},
+{-3, 1},
+{-3, 4},
+{-2, 0},
+{-2, 2},
+{-2, 4},
+{-2, 6},
+{-2, 8},
+{-2, 10},
+{-2, 12},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+// numerator = -13
+{0, -13},
+{0, -13},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{1, -4},
+{1, -5},
+{1, -6},
+{2, -1},
+{2, -3},
+{3, -1},
+{4, -1},
+{6, -1},
+{13, 0},
+{0, 0},
+{-13, 0},
+{-7, 1},
+{-5, 2},
+{-4, 3},
+{-3, 2},
+{-3, 5},
+{-2, 1},
+{-2, 3},
+{-2, 5},
+{-2, 7},
+{-2, 9},
+{-2, 11},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+// numerator = -12
+{0, -12},
+{0, -12},
+{0, -12},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{1, -4},
+{1, -5},
+{2, 0},
+{2, -2},
+{3, 0},
+{4, 0},
+{6, 0},
+{12, 0},
+{0, 0},
+{-12, 0},
+{-6, 0},
+{-4, 0},
+{-3, 0},
+{-3, 3},
+{-2, 0},
+{-2, 2},
+{-2, 4},
+{-2, 6},
+{-2, 8},
+{-2, 10},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+// numerator = -11
+{0, -11},
+{0, -11},
+{0, -11},
+{0, -11},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{1, -4},
+{1, -5},
+{2, -1},
+{2, -3},
+{3, -2},
+{5, -1},
+{11, 0},
+{0, 0},
+{-11, 0},
+{-6, 1},
+{-4, 1},
+{-3, 1},
+{-3, 4},
+{-2, 1},
+{-2, 3},
+{-2, 5},
+{-2, 7},
+{-2, 9},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+// numerator = -10
+{0, -10},
+{0, -10},
+{0, -10},
+{0, -10},
+{0, -10},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{1, -4},
+{2, 0},
+{2, -2},
+{3, -1},
+{5, 0},
+{10, 0},
+{0, 0},
+{-10, 0},
+{-5, 0},
+{-4, 2},
+{-3, 2},
+{-2, 0},
+{-2, 2},
+{-2, 4},
+{-2, 6},
+{-2, 8},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+// numerator = -9
+{0, -9},
+{0, -9},
+{0, -9},
+{0, -9},
+{0, -9},
+{0, -9},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{1, -4},
+{2, -1},
+{3, 0},
+{4, -1},
+{9, 0},
+{0, 0},
+{-9, 0},
+{-5, 1},
+{-3, 0},
+{-3, 3},
+{-2, 1},
+{-2, 3},
+{-2, 5},
+{-2, 7},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+// numerator = -8
+{0, -8},
+{0, -8},
+{0, -8},
+{0, -8},
+{0, -8},
+{0, -8},
+{0, -8},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{2, 0},
+{2, -2},
+{4, 0},
+{8, 0},
+{0, 0},
+{-8, 0},
+{-4, 0},
+{-3, 1},
+{-2, 0},
+{-2, 2},
+{-2, 4},
+{-2, 6},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+// numerator = -7
+{0, -7},
+{0, -7},
+{0, -7},
+{0, -7},
+{0, -7},
+{0, -7},
+{0, -7},
+{0, -7},
+{1, 0},
+{1, -1},
+{1, -2},
+{1, -3},
+{2, -1},
+{3, -1},
+{7, 0},
+{0, 0},
+{-7, 0},
+{-4, 1},
+{-3, 2},
+{-2, 1},
+{-2, 3},
+{-2, 5},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+{-1, 9},
+// numerator = -6
+{0, -6},
+{0, -6},
+{0, -6},
+{0, -6},
+{0, -6},
+{0, -6},
+{0, -6},
+{0, -6},
+{0, -6},
+{1, 0},
+{1, -1},
+{1, -2},
+{2, 0},
+{3, 0},
+{6, 0},
+{0, 0},
+{-6, 0},
+{-3, 0},
+{-2, 0},
+{-2, 2},
+{-2, 4},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+{-1, 9},
+{-1, 10},
+// numerator = -5
+{0, -5},
+{0, -5},
+{0, -5},
+{0, -5},
+{0, -5},
+{0, -5},
+{0, -5},
+{0, -5},
+{0, -5},
+{0, -5},
+{1, 0},
+{1, -1},
+{1, -2},
+{2, -1},
+{5, 0},
+{0, 0},
+{-5, 0},
+{-3, 1},
+{-2, 1},
+{-2, 3},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+{-1, 9},
+{-1, 10},
+{-1, 11},
+// numerator = -4
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{0, -4},
+{1, 0},
+{1, -1},
+{2, 0},
+{4, 0},
+{0, 0},
+{-4, 0},
+{-2, 0},
+{-2, 2},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+{-1, 9},
+{-1, 10},
+{-1, 11},
+{-1, 12},
+// numerator = -3
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{0, -3},
+{1, 0},
+{1, -1},
+{3, 0},
+{0, 0},
+{-3, 0},
+{-2, 1},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+{-1, 9},
+{-1, 10},
+{-1, 11},
+{-1, 12},
+{-1, 13},
+// numerator = -2
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{0, -2},
+{1, 0},
+{2, 0},
+{0, 0},
+{-2, 0},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+{-1, 9},
+{-1, 10},
+{-1, 11},
+{-1, 12},
+{-1, 13},
+{-1, 14},
+// numerator = -1
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{0, -1},
+{1, 0},
+{0, 0},
+{-1, 0},
+{-1, 1},
+{-1, 2},
+{-1, 3},
+{-1, 4},
+{-1, 5},
+{-1, 6},
+{-1, 7},
+{-1, 8},
+{-1, 9},
+{-1, 10},
+{-1, 11},
+{-1, 12},
+{-1, 13},
+{-1, 14},
+{-1, 15},
+// numerator = 0
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+{0, 0},
+// numerator = 1
+{-1, -14},
+{-1, -13},
+{-1, -12},
+{-1, -11},
+{-1, -10},
+{-1, -9},
+{-1, -8},
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{0, 0},
+{1, 0},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+{0, 1},
+// numerator = 2
+{-1, -13},
+{-1, -12},
+{-1, -11},
+{-1, -10},
+{-1, -9},
+{-1, -8},
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, 0},
+{0, 0},
+{2, 0},
+{1, 0},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+{0, 2},
+// numerator = 3
+{-1, -12},
+{-1, -11},
+{-1, -10},
+{-1, -9},
+{-1, -8},
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -1},
+{-3, 0},
+{0, 0},
+{3, 0},
+{1, 1},
+{1, 0},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+{0, 3},
+// numerator = 4
+{-1, -11},
+{-1, -10},
+{-1, -9},
+{-1, -8},
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -2},
+{-2, 0},
+{-4, 0},
+{0, 0},
+{4, 0},
+{2, 0},
+{1, 1},
+{1, 0},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+{0, 4},
+// numerator = 5
+{-1, -10},
+{-1, -9},
+{-1, -8},
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -3},
+{-2, -1},
+{-3, -1},
+{-5, 0},
+{0, 0},
+{5, 0},
+{2, 1},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+{0, 5},
+// numerator = 6
+{-1, -9},
+{-1, -8},
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -4},
+{-2, -2},
+{-2, 0},
+{-3, 0},
+{-6, 0},
+{0, 0},
+{6, 0},
+{3, 0},
+{2, 0},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 6},
+{0, 6},
+{0, 6},
+{0, 6},
+{0, 6},
+{0, 6},
+{0, 6},
+{0, 6},
+{0, 6},
+{0, 6},
+// numerator = 7
+{-1, -8},
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -5},
+{-2, -3},
+{-2, -1},
+{-3, -2},
+{-4, -1},
+{-7, 0},
+{0, 0},
+{7, 0},
+{3, 1},
+{2, 1},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 7},
+{0, 7},
+{0, 7},
+{0, 7},
+{0, 7},
+{0, 7},
+{0, 7},
+{0, 7},
+{0, 7},
+// numerator = 8
+{-1, -7},
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -6},
+{-2, -4},
+{-2, -2},
+{-2, 0},
+{-3, -1},
+{-4, 0},
+{-8, 0},
+{0, 0},
+{8, 0},
+{4, 0},
+{2, 2},
+{2, 0},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 8},
+{0, 8},
+{0, 8},
+{0, 8},
+{0, 8},
+{0, 8},
+{0, 8},
+{0, 8},
+// numerator = 9
+{-1, -6},
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -7},
+{-2, -5},
+{-2, -3},
+{-2, -1},
+{-3, -3},
+{-3, 0},
+{-5, -1},
+{-9, 0},
+{0, 0},
+{9, 0},
+{4, 1},
+{3, 0},
+{2, 1},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 9},
+{0, 9},
+{0, 9},
+{0, 9},
+{0, 9},
+{0, 9},
+{0, 9},
+// numerator = 10
+{-1, -5},
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -8},
+{-2, -6},
+{-2, -4},
+{-2, -2},
+{-2, 0},
+{-3, -2},
+{-4, -2},
+{-5, 0},
+{-10, 0},
+{0, 0},
+{10, 0},
+{5, 0},
+{3, 1},
+{2, 2},
+{2, 0},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 10},
+{0, 10},
+{0, 10},
+{0, 10},
+{0, 10},
+{0, 10},
+// numerator = 11
+{-1, -4},
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -9},
+{-2, -7},
+{-2, -5},
+{-2, -3},
+{-2, -1},
+{-3, -4},
+{-3, -1},
+{-4, -1},
+{-6, -1},
+{-11, 0},
+{0, 0},
+{11, 0},
+{5, 1},
+{3, 2},
+{2, 3},
+{2, 1},
+{1, 5},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 11},
+{0, 11},
+{0, 11},
+{0, 11},
+{0, 11},
+// numerator = 12
+{-1, -3},
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -10},
+{-2, -8},
+{-2, -6},
+{-2, -4},
+{-2, -2},
+{-2, 0},
+{-3, -3},
+{-3, 0},
+{-4, 0},
+{-6, 0},
+{-12, 0},
+{0, 0},
+{12, 0},
+{6, 0},
+{4, 0},
+{3, 0},
+{2, 2},
+{2, 0},
+{1, 5},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 12},
+{0, 12},
+{0, 12},
+{0, 12},
+// numerator = 13
+{-1, -2},
+{-1, -1},
+{-1, 0},
+{-2, -11},
+{-2, -9},
+{-2, -7},
+{-2, -5},
+{-2, -3},
+{-2, -1},
+{-3, -5},
+{-3, -2},
+{-4, -3},
+{-5, -2},
+{-7, -1},
+{-13, 0},
+{0, 0},
+{13, 0},
+{6, 1},
+{4, 1},
+{3, 1},
+{2, 3},
+{2, 1},
+{1, 6},
+{1, 5},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 13},
+{0, 13},
+{0, 13},
+// numerator = 14
+{-1, -1},
+{-1, 0},
+{-2, -12},
+{-2, -10},
+{-2, -8},
+{-2, -6},
+{-2, -4},
+{-2, -2},
+{-2, 0},
+{-3, -4},
+{-3, -1},
+{-4, -2},
+{-5, -1},
+{-7, 0},
+{-14, 0},
+{0, 0},
+{14, 0},
+{7, 0},
+{4, 2},
+{3, 2},
+{2, 4},
+{2, 2},
+{2, 0},
+{1, 6},
+{1, 5},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 14},
+{0, 14},
+// numerator = 15
+{-1, 0},
+{-2, -13},
+{-2, -11},
+{-2, -9},
+{-2, -7},
+{-2, -5},
+{-2, -3},
+{-2, -1},
+{-3, -6},
+{-3, -3},
+{-3, 0},
+{-4, -1},
+{-5, 0},
+{-8, -1},
+{-15, 0},
+{0, 0},
+{15, 0},
+{7, 1},
+{5, 0},
+{3, 3},
+{3, 0},
+{2, 3},
+{2, 1},
+{1, 7},
+{1, 6},
+{1, 5},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
+{0, 15},
+// numerator = 16
+{-2, -14},
+{-2, -12},
+{-2, -10},
+{-2, -8},
+{-2, -6},
+{-2, -4},
+{-2, -2},
+{-2, 0},
+{-3, -5},
+{-3, -2},
+{-4, -4},
+{-4, 0},
+{-6, -2},
+{-8, 0},
+{-16, 0},
+{0, 0},
+{16, 0},
+{8, 0},
+{5, 1},
+{4, 0},
+{3, 1},
+{2, 4},
+{2, 2},
+{2, 0},
+{1, 7},
+{1, 6},
+{1, 5},
+{1, 4},
+{1, 3},
+{1, 2},
+{1, 1},
+{1, 0},
--- /dev/null
+++ b/ref/r_aclip.c
@@ -1,0 +1,323 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_aclip.c: clip routines for drawing Alias models directly to the screen
+
+#include "r_local.h"
+
+static finalvert_t		fv[2][8];
+
+void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv);
+void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
+	finalvert_t *out);
+void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
+	finalvert_t *out);
+void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
+	finalvert_t *out);
+void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
+	finalvert_t *out);
+
+
+/*
+================
+R_Alias_clip_z
+
+pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
+================
+*/
+void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
+{
+	float		scale;
+
+	scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) /
+			(pfv1->xyz[2] - pfv0->xyz[2]);
+
+	out->xyz[0] = pfv0->xyz[0] + (pfv1->xyz[0] - pfv0->xyz[0]) * scale;
+	out->xyz[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale;
+	out->xyz[2] = ALIAS_Z_CLIP_PLANE;
+
+	out->s =	pfv0->s + (pfv1->s - pfv0->s) * scale;
+	out->t =	pfv0->t + (pfv1->t - pfv0->t) * scale;
+	out->l =	pfv0->l + (pfv1->l - pfv0->l) * scale;
+
+	R_AliasProjectAndClipTestFinalVert (out);
+}
+
+
+#if	!id386
+
+void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
+{
+	float		scale;
+
+	if (pfv0->v >= pfv1->v )
+	{
+		scale = (float)(r_refdef.aliasvrect.x - pfv0->u) /
+				(pfv1->u - pfv0->u);
+		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
+		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
+		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
+		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
+		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
+		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
+	}
+	else
+	{
+		scale = (float)(r_refdef.aliasvrect.x - pfv1->u) /
+				(pfv0->u - pfv1->u);
+		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
+		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
+		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
+		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
+		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
+		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
+	}
+}
+
+
+void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
+{
+	float		scale;
+
+	if ( pfv0->v >= pfv1->v )
+	{
+		scale = (float)(r_refdef.aliasvrectright - pfv0->u ) /
+				(pfv1->u - pfv0->u );
+		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
+		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
+		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
+		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
+		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
+		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
+	}
+	else
+	{
+		scale = (float)(r_refdef.aliasvrectright - pfv1->u ) /
+				(pfv0->u - pfv1->u );
+		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
+		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
+		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
+		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
+		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
+		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
+	}
+}
+
+
+void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
+{
+	float		scale;
+
+	if (pfv0->v >= pfv1->v)
+	{
+		scale = (float)(r_refdef.aliasvrect.y - pfv0->v) /
+				(pfv1->v - pfv0->v);
+		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
+		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
+		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
+		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
+		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
+		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
+	}
+	else
+	{
+		scale = (float)(r_refdef.aliasvrect.y - pfv1->v) /
+				(pfv0->v - pfv1->v);
+		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
+		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
+		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
+		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
+		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
+		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
+	}
+}
+
+
+void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
+	finalvert_t *out)
+{
+	float		scale;
+
+	if (pfv0->v >= pfv1->v)
+	{
+		scale = (float)(r_refdef.aliasvrectbottom - pfv0->v) /
+				(pfv1->v - pfv0->v);
+
+		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
+		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
+		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
+		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
+		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
+		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
+	}
+	else
+	{
+		scale = (float)(r_refdef.aliasvrectbottom - pfv1->v) /
+				(pfv0->v - pfv1->v);
+
+		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
+		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
+		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
+		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
+		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
+		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
+	}
+}
+
+#endif
+
+
+int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
+	void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
+{
+	int			i,j,k;
+	int			flags, oldflags;
+	
+	j = count-1;
+	k = 0;
+	for (i=0 ; i<count ; j = i, i++)
+	{
+		oldflags = in[j].flags & flag;
+		flags = in[i].flags & flag;
+
+		if (flags && oldflags)
+			continue;
+		if (oldflags ^ flags)
+		{
+			clip (&in[j], &in[i], &out[k]);
+			out[k].flags = 0;
+			if (out[k].u < r_refdef.aliasvrect.x)
+				out[k].flags |= ALIAS_LEFT_CLIP;
+			if (out[k].v < r_refdef.aliasvrect.y)
+				out[k].flags |= ALIAS_TOP_CLIP;
+			if (out[k].u > r_refdef.aliasvrectright)
+				out[k].flags |= ALIAS_RIGHT_CLIP;
+			if (out[k].v > r_refdef.aliasvrectbottom)
+				out[k].flags |= ALIAS_BOTTOM_CLIP;	
+			k++;
+		}
+		if (!flags)
+		{
+			out[k] = in[i];
+			k++;
+		}
+	}
+	
+	return k;
+}
+
+
+/*
+================
+R_AliasClipTriangle
+================
+*/
+void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2)
+{
+	int				i, k, pingpong;
+	unsigned		clipflags;
+
+// copy vertexes and fix seam texture coordinates
+	fv[0][0] = *index0;
+	fv[0][1] = *index1;
+	fv[0][2] = *index2;
+
+// clip
+	clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
+
+	if (clipflags & ALIAS_Z_CLIP)
+	{
+		k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
+		if (k == 0)
+			return;
+
+		pingpong = 1;
+		clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
+	}
+	else
+	{
+		pingpong = 0;
+		k = 3;
+	}
+
+	if (clipflags & ALIAS_LEFT_CLIP)
+	{
+		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
+							ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
+		if (k == 0)
+			return;
+
+		pingpong ^= 1;
+	}
+
+	if (clipflags & ALIAS_RIGHT_CLIP)
+	{
+		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
+							ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
+		if (k == 0)
+			return;
+
+		pingpong ^= 1;
+	}
+
+	if (clipflags & ALIAS_BOTTOM_CLIP)
+	{
+		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
+							ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
+		if (k == 0)
+			return;
+
+		pingpong ^= 1;
+	}
+
+	if (clipflags & ALIAS_TOP_CLIP)
+	{
+		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
+							ALIAS_TOP_CLIP, k, R_Alias_clip_top);
+		if (k == 0)
+			return;
+
+		pingpong ^= 1;
+	}
+
+	for (i=0 ; i<k ; i++)
+	{
+		if (fv[pingpong][i].u < r_refdef.aliasvrect.x)
+			fv[pingpong][i].u = r_refdef.aliasvrect.x;
+		else if (fv[pingpong][i].u > r_refdef.aliasvrectright)
+			fv[pingpong][i].u = r_refdef.aliasvrectright;
+
+		if (fv[pingpong][i].v < r_refdef.aliasvrect.y)
+			fv[pingpong][i].v = r_refdef.aliasvrect.y;
+		else if (fv[pingpong][i].v > r_refdef.aliasvrectbottom)
+			fv[pingpong][i].v = r_refdef.aliasvrectbottom;
+
+		fv[pingpong][i].flags = 0;
+	}
+
+// draw triangles
+	for (i=1 ; i<k-1 ; i++)
+	{
+		aliastriangleparms.a = &fv[pingpong][0];
+		aliastriangleparms.b = &fv[pingpong][i];
+		aliastriangleparms.c = &fv[pingpong][i+1];
+		R_DrawTriangle();
+	}
+}
+
--- /dev/null
+++ b/ref/r_alias.c
@@ -1,0 +1,1198 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_alias.c: routines for setting up to draw alias models
+
+/*
+** use a real variable to control lerping
+*/
+#include "r_local.h"
+
+#define LIGHT_MIN	5		// lowest light value we'll allow, to avoid the
+							//  need for inner-loop light clamping
+
+//PGM
+extern byte iractive;
+//PGM
+
+int				r_amodels_drawn;
+
+affinetridesc_t	r_affinetridesc;
+
+vec3_t			r_plightvec;
+vec3_t          r_lerped[1024];
+vec3_t          r_lerp_frontv, r_lerp_backv, r_lerp_move;
+
+int				r_ambientlight;
+int				r_aliasblendcolor;
+float			r_shadelight;
+
+
+daliasframe_t	*r_thisframe, *r_lastframe;
+dmdl_t			*s_pmdl;
+
+float	aliastransform[3][4];
+float   aliasworldtransform[3][4];
+float   aliasoldworldtransform[3][4];
+
+static float	s_ziscale;
+static vec3_t	s_alias_forward, s_alias_right, s_alias_up;
+
+
+#define NUMVERTEXNORMALS	162
+
+float	r_avertexnormals[NUMVERTEXNORMALS][3] = {
+#include "../anorms.h"
+};
+
+
+void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp );
+void R_AliasSetUpTransform (void);
+void R_AliasTransformVector (vec3_t in, vec3_t out, float m[3][4] );
+void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv);
+
+void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv );
+
+void R_AliasLerpFrames( dmdl_t *paliashdr, float backlerp );
+
+/*
+================
+R_AliasCheckBBox
+================
+*/
+typedef struct {
+	int	index0;
+	int	index1;
+} aedge_t;
+
+static aedge_t	aedges[12] = {
+{0, 1}, {1, 2}, {2, 3}, {3, 0},
+{4, 5}, {5, 6}, {6, 7}, {7, 4},
+{0, 5}, {1, 4}, {2, 7}, {3, 6}
+};
+
+#define BBOX_TRIVIAL_ACCEPT 0
+#define BBOX_MUST_CLIP_XY   1
+#define BBOX_MUST_CLIP_Z    2
+#define BBOX_TRIVIAL_REJECT 8
+
+/*
+** R_AliasCheckFrameBBox
+**
+** Checks a specific alias frame bounding box
+*/
+unsigned long R_AliasCheckFrameBBox( daliasframe_t *frame, float worldxf[3][4] )
+{
+	unsigned long aggregate_and_clipcode = ~0U, 
+		          aggregate_or_clipcode = 0;
+	int           i;
+	vec3_t        mins, maxs;
+	vec3_t        transformed_min, transformed_max;
+	qboolean      zclipped = false, zfullyclipped = true;
+	float         minz = 9999.0F;
+
+	/*
+	** get the exact frame bounding box
+	*/
+	for (i=0 ; i<3 ; i++)
+	{
+		mins[i] = frame->translate[i];
+		maxs[i] = mins[i] + frame->scale[i]*255;
+	}
+
+	/*
+	** transform the min and max values into view space
+	*/
+	R_AliasTransformVector( mins, transformed_min, aliastransform );
+	R_AliasTransformVector( maxs, transformed_max, aliastransform );
+
+	if ( transformed_min[2] >= ALIAS_Z_CLIP_PLANE )
+		zfullyclipped = false;
+	if ( transformed_max[2] >= ALIAS_Z_CLIP_PLANE )
+		zfullyclipped = false;
+
+	if ( zfullyclipped )
+	{
+		return BBOX_TRIVIAL_REJECT;
+	}
+	if ( zclipped )
+	{
+		return ( BBOX_MUST_CLIP_XY | BBOX_MUST_CLIP_Z );
+	}
+
+	/*
+	** build a transformed bounding box from the given min and max
+	*/
+	for ( i = 0; i < 8; i++ )
+	{
+		int      j;
+		vec3_t   tmp, transformed;
+		unsigned long clipcode = 0;
+
+		if ( i & 1 )
+			tmp[0] = mins[0];
+		else
+			tmp[0] = maxs[0];
+
+		if ( i & 2 )
+			tmp[1] = mins[1];
+		else
+			tmp[1] = maxs[1];
+
+		if ( i & 4 )
+			tmp[2] = mins[2];
+		else
+			tmp[2] = maxs[2];
+
+		R_AliasTransformVector( tmp, transformed, worldxf );
+
+		for ( j = 0; j < 4; j++ )
+		{
+			float dp = DotProduct( transformed, view_clipplanes[j].normal );
+
+			if ( ( dp - view_clipplanes[j].dist ) < 0.0F )
+				clipcode |= 1 << j;
+		}
+
+		aggregate_and_clipcode &= clipcode;
+		aggregate_or_clipcode  |= clipcode;
+	}
+
+	if ( aggregate_and_clipcode )
+	{
+		return BBOX_TRIVIAL_REJECT;
+	}
+	if ( !aggregate_or_clipcode )
+	{
+		return BBOX_TRIVIAL_ACCEPT;
+	}
+
+	return BBOX_MUST_CLIP_XY;
+}
+
+qboolean R_AliasCheckBBox (void)
+{
+	unsigned long ccodes[2] = { 0, 0 };
+
+	ccodes[0] = R_AliasCheckFrameBBox( r_thisframe, aliasworldtransform );
+
+	/*
+	** non-lerping model
+	*/
+	if ( currententity->backlerp == 0 )
+	{
+		if ( ccodes[0] == BBOX_TRIVIAL_ACCEPT )
+			return BBOX_TRIVIAL_ACCEPT;
+		else if ( ccodes[0] & BBOX_TRIVIAL_REJECT )
+			return BBOX_TRIVIAL_REJECT;
+		else
+			return ( ccodes[0] & ~BBOX_TRIVIAL_REJECT );
+	}
+
+	ccodes[1] = R_AliasCheckFrameBBox( r_lastframe, aliasoldworldtransform );
+
+	if ( ( ccodes[0] | ccodes[1] ) == BBOX_TRIVIAL_ACCEPT )
+		return BBOX_TRIVIAL_ACCEPT;
+	else if ( ( ccodes[0] & ccodes[1] ) & BBOX_TRIVIAL_REJECT )
+		return BBOX_TRIVIAL_REJECT;
+	else
+		return ( ccodes[0] | ccodes[1] ) & ~BBOX_TRIVIAL_REJECT;
+}
+
+
+/*
+================
+R_AliasTransformVector
+================
+*/
+void R_AliasTransformVector(vec3_t in, vec3_t out, float xf[3][4] )
+{
+	out[0] = DotProduct(in, xf[0]) + xf[0][3];
+	out[1] = DotProduct(in, xf[1]) + xf[1][3];
+	out[2] = DotProduct(in, xf[2]) + xf[2][3];
+}
+
+
+/*
+================
+R_AliasPreparePoints
+
+General clipped case
+================
+*/
+typedef struct
+{
+	int          num_points;
+	dtrivertx_t *last_verts;   // verts from the last frame
+	dtrivertx_t *this_verts;   // verts from this frame
+	finalvert_t *dest_verts;   // destination for transformed verts
+} aliasbatchedtransformdata_t;
+
+aliasbatchedtransformdata_t aliasbatchedtransformdata;
+
+void R_AliasPreparePoints (void)
+{
+	int			i;
+	dstvert_t	*pstverts;
+	dtriangle_t	*ptri;
+	finalvert_t	*pfv[3];
+	finalvert_t	finalverts[MAXALIASVERTS +
+						((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 3];
+	finalvert_t	*pfinalverts;
+
+//PGM
+	iractive = (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE);
+//	iractive = 0;
+//	if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
+//		iractive = 1;
+//PGM
+
+	// put work vertexes on stack, cache aligned
+	pfinalverts = (finalvert_t *)
+			(((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
+
+	aliasbatchedtransformdata.num_points = s_pmdl->num_xyz;
+	aliasbatchedtransformdata.last_verts = r_lastframe->verts;
+	aliasbatchedtransformdata.this_verts = r_thisframe->verts;
+	aliasbatchedtransformdata.dest_verts = pfinalverts;
+
+	R_AliasTransformFinalVerts( aliasbatchedtransformdata.num_points,
+		                        aliasbatchedtransformdata.dest_verts,
+								aliasbatchedtransformdata.last_verts,
+								aliasbatchedtransformdata.this_verts );
+
+// clip and draw all triangles
+//
+	pstverts = (dstvert_t *)((byte *)s_pmdl + s_pmdl->ofs_st);
+	ptri = (dtriangle_t *)((byte *)s_pmdl + s_pmdl->ofs_tris);
+
+	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
+	{
+		for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++)
+		{
+			pfv[0] = &pfinalverts[ptri->index_xyz[0]];
+			pfv[1] = &pfinalverts[ptri->index_xyz[1]];
+			pfv[2] = &pfinalverts[ptri->index_xyz[2]];
+
+			if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags )
+				continue;		// completely clipped
+
+			// insert s/t coordinates
+			pfv[0]->s = pstverts[ptri->index_st[0]].s << 16;
+			pfv[0]->t = pstverts[ptri->index_st[0]].t << 16;
+
+			pfv[1]->s = pstverts[ptri->index_st[1]].s << 16;
+			pfv[1]->t = pstverts[ptri->index_st[1]].t << 16;
+
+			pfv[2]->s = pstverts[ptri->index_st[2]].s << 16;
+			pfv[2]->t = pstverts[ptri->index_st[2]].t << 16;
+
+			if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) )
+			{	// totally unclipped
+				aliastriangleparms.a = pfv[2];
+				aliastriangleparms.b = pfv[1];
+				aliastriangleparms.c = pfv[0];
+
+				R_DrawTriangle();
+			}
+			else
+			{
+				R_AliasClipTriangle (pfv[2], pfv[1], pfv[0]);
+			}
+		}
+	}
+	else
+	{
+		for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++)
+		{
+			pfv[0] = &pfinalverts[ptri->index_xyz[0]];
+			pfv[1] = &pfinalverts[ptri->index_xyz[1]];
+			pfv[2] = &pfinalverts[ptri->index_xyz[2]];
+
+			if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags )
+				continue;		// completely clipped
+
+			// insert s/t coordinates
+			pfv[0]->s = pstverts[ptri->index_st[0]].s << 16;
+			pfv[0]->t = pstverts[ptri->index_st[0]].t << 16;
+
+			pfv[1]->s = pstverts[ptri->index_st[1]].s << 16;
+			pfv[1]->t = pstverts[ptri->index_st[1]].t << 16;
+
+			pfv[2]->s = pstverts[ptri->index_st[2]].s << 16;
+			pfv[2]->t = pstverts[ptri->index_st[2]].t << 16;
+
+			if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) )
+			{	// totally unclipped
+				aliastriangleparms.a = pfv[0];
+				aliastriangleparms.b = pfv[1];
+				aliastriangleparms.c = pfv[2];
+
+				R_DrawTriangle();
+			}
+			else		
+			{	// partially clipped
+				R_AliasClipTriangle (pfv[0], pfv[1], pfv[2]);
+			}
+		}
+	}
+}
+
+
+/*
+================
+R_AliasSetUpTransform
+================
+*/
+void R_AliasSetUpTransform (void)
+{
+	int				i;
+	static float	viewmatrix[3][4];
+	vec3_t			angles;
+
+// TODO: should really be stored with the entity instead of being reconstructed
+// TODO: should use a look-up table
+// TODO: could cache lazily, stored in the entity
+// 
+	angles[ROLL] = currententity->angles[ROLL];
+	angles[PITCH] = currententity->angles[PITCH];
+	angles[YAW] = currententity->angles[YAW];
+	AngleVectors( angles, s_alias_forward, s_alias_right, s_alias_up );
+
+// TODO: can do this with simple matrix rearrangement
+
+	memset( aliasworldtransform, 0, sizeof( aliasworldtransform ) );
+	memset( aliasoldworldtransform, 0, sizeof( aliasworldtransform ) );
+
+	for (i=0 ; i<3 ; i++)
+	{
+		aliasoldworldtransform[i][0] = aliasworldtransform[i][0] =  s_alias_forward[i];
+		aliasoldworldtransform[i][0] = aliasworldtransform[i][1] = -s_alias_right[i];
+		aliasoldworldtransform[i][0] = aliasworldtransform[i][2] =  s_alias_up[i];
+	}
+
+	aliasworldtransform[0][3] = currententity->origin[0]-r_origin[0];
+	aliasworldtransform[1][3] = currententity->origin[1]-r_origin[1];
+	aliasworldtransform[2][3] = currententity->origin[2]-r_origin[2];
+
+	aliasoldworldtransform[0][3] = currententity->oldorigin[0]-r_origin[0];
+	aliasoldworldtransform[1][3] = currententity->oldorigin[1]-r_origin[1];
+	aliasoldworldtransform[2][3] = currententity->oldorigin[2]-r_origin[2];
+
+// FIXME: can do more efficiently than full concatenation
+//	memcpy( rotationmatrix, t2matrix, sizeof( rotationmatrix ) );
+
+//	R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix);
+
+// TODO: should be global, set when vright, etc., set
+	VectorCopy (vright, viewmatrix[0]);
+	VectorCopy (vup, viewmatrix[1]);
+	VectorInverse (viewmatrix[1]);
+	VectorCopy (vpn, viewmatrix[2]);
+
+	viewmatrix[0][3] = 0;
+	viewmatrix[1][3] = 0;
+	viewmatrix[2][3] = 0;
+
+//	memcpy( aliasworldtransform, rotationmatrix, sizeof( aliastransform ) );
+
+	R_ConcatTransforms (viewmatrix, aliasworldtransform, aliastransform);
+
+	aliasworldtransform[0][3] = currententity->origin[0];
+	aliasworldtransform[1][3] = currententity->origin[1];
+	aliasworldtransform[2][3] = currententity->origin[2];
+
+	aliasoldworldtransform[0][3] = currententity->oldorigin[0];
+	aliasoldworldtransform[1][3] = currententity->oldorigin[1];
+	aliasoldworldtransform[2][3] = currententity->oldorigin[2];
+}
+
+
+/*
+================
+R_AliasTransformFinalVerts
+================
+*/
+#if id386 && !defined __linux__
+void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv )
+{
+	float  lightcos;
+	float	lerped_vert[3];
+	int    byte_to_dword_ptr_var;
+	int    tmpint;
+
+	float  one = 1.0F;
+	float  zi;
+
+	static float  FALIAS_Z_CLIP_PLANE = ALIAS_Z_CLIP_PLANE;
+	static float  PS_SCALE = POWERSUIT_SCALE;
+
+	__asm mov ecx, numpoints
+
+	/*
+	lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0];
+	lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1];
+	lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2];
+	*/
+top_of_loop:
+
+	__asm mov esi, oldv
+	__asm mov edi, newv
+
+	__asm xor ebx, ebx
+
+	__asm mov bl, byte ptr [esi+DTRIVERTX_V0]
+	__asm mov byte_to_dword_ptr_var, ebx
+	__asm fild dword ptr byte_to_dword_ptr_var      
+	__asm fmul dword ptr [r_lerp_backv+0]                  ; oldv[0]*rlb[0]
+
+	__asm mov bl, byte ptr [esi+DTRIVERTX_V1]
+	__asm mov byte_to_dword_ptr_var, ebx
+	__asm fild dword ptr byte_to_dword_ptr_var
+	__asm fmul dword ptr [r_lerp_backv+4]                  ; oldv[1]*rlb[1] | oldv[0]*rlb[0]
+
+	__asm mov bl, byte ptr [esi+DTRIVERTX_V2]
+	__asm mov byte_to_dword_ptr_var, ebx
+	__asm fild dword ptr byte_to_dword_ptr_var
+	__asm fmul dword ptr [r_lerp_backv+8]                  ; oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
+
+	__asm mov bl, byte ptr [edi+DTRIVERTX_V0]
+	__asm mov byte_to_dword_ptr_var, ebx
+	__asm fild dword ptr byte_to_dword_ptr_var      
+	__asm fmul dword ptr [r_lerp_frontv+0]                 ; newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
+
+	__asm mov bl, byte ptr [edi+DTRIVERTX_V1]
+	__asm mov byte_to_dword_ptr_var, ebx
+	__asm fild dword ptr byte_to_dword_ptr_var
+	__asm fmul dword ptr [r_lerp_frontv+4]                 ; newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
+
+	__asm mov bl, byte ptr [edi+DTRIVERTX_V2]
+	__asm mov byte_to_dword_ptr_var, ebx
+	__asm fild dword ptr byte_to_dword_ptr_var
+	__asm fmul dword ptr [r_lerp_frontv+8]                 ; newv[2]*rlf[2] | newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
+
+	__asm fxch st(5)                     ; oldv[0]*rlb[0] | newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | newv[2]*rlf[2]
+	__asm faddp st(2), st                ; newv[1]*rlf[1] | oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | newv[2]*rlf[2]
+	__asm faddp st(3), st                ; oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] + newv[1]*rlf[1] | newv[2]*rlf[2]
+	__asm fxch st(1)                     ; oldv[2]*rlb[2] | oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[1]*rlb[1] + newv[1]*rlf[1] | newv[2]*rlf[2]
+	__asm faddp st(3), st                ; oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[1]*rlb[1] + newv[1]*rlf[1] | oldv[2]*rlb[2] + newv[2]*rlf[2]
+	__asm fadd dword ptr [r_lerp_move+0] ; lv0 | oldv[1]*rlb[1] + newv[1]*rlf[1] | oldv[2]*rlb[2] + newv[2]*rlf[2]
+	__asm fxch st(1)                     ; oldv[1]*rlb[1] + newv[1]*rlf[1] | lv0 | oldv[2]*rlb[2] + newv[2]*rlf[2]
+	__asm fadd dword ptr [r_lerp_move+4] ; lv1 | lv0 | oldv[2]*rlb[2] + newv[2]*rlf[2]
+	__asm fxch st(2)                     ; oldv[2]*rlb[2] + newv[2]*rlf[2] | lv0 | lv1
+	__asm fadd dword ptr [r_lerp_move+8] ; lv2 | lv0 | lv1
+	__asm fxch st(1)                     ; lv0 | lv2 | lv1
+	__asm fstp dword ptr [lerped_vert+0] ; lv2 | lv1
+	__asm fstp dword ptr [lerped_vert+8] ; lv2
+	__asm fstp dword ptr [lerped_vert+4] ; (empty)
+
+	__asm mov  eax, currententity
+	__asm mov  eax, dword ptr [eax+ENTITY_FLAGS]
+	__asm mov  ebx, RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM
+	__asm and  eax, ebx
+	__asm jz   not_powersuit
+
+	/*
+	**    lerped_vert[0] += lightnormal[0] * POWERSUIT_SCALE
+	**    lerped_vert[1] += lightnormal[1] * POWERSUIT_SCALE
+	**    lerped_vert[2] += lightnormal[2] * POWERSUIT_SCALE
+	*/
+
+	__asm xor ebx, ebx
+	__asm mov bl,  byte ptr [edi+DTRIVERTX_LNI]
+	__asm mov eax, 12
+	__asm mul ebx
+	__asm lea eax, [r_avertexnormals+eax]
+
+	__asm fld  dword ptr [eax+0]				; n[0]
+	__asm fmul PS_SCALE							; n[0] * PS
+	__asm fld  dword ptr [eax+4]				; n[1] | n[0] * PS
+	__asm fmul PS_SCALE							; n[1] * PS | n[0] * PS
+	__asm fld  dword ptr [eax+8]				; n[2] | n[1] * PS | n[0] * PS
+	__asm fmul PS_SCALE							; n[2] * PS | n[1] * PS | n[0] * PS
+	__asm fld  dword ptr [lerped_vert+0]		; lv0 | n[2] * PS | n[1] * PS | n[0] * PS
+	__asm faddp st(3), st						; n[2] * PS | n[1] * PS | n[0] * PS + lv0
+	__asm fld  dword ptr [lerped_vert+4]		; lv1 | n[2] * PS | n[1] * PS | n[0] * PS + lv0
+	__asm faddp st(2), st						; n[2] * PS | n[1] * PS + lv1 | n[0] * PS + lv0
+	__asm fadd dword ptr [lerped_vert+8]		; n[2] * PS + lv2 | n[1] * PS + lv1 | n[0] * PS + lv0
+	__asm fxch st(2)							; LV0 | LV1 | LV2
+	__asm fstp dword ptr [lerped_vert+0]		; LV1 | LV2
+	__asm fstp dword ptr [lerped_vert+4]		; LV2
+	__asm fstp dword ptr [lerped_vert+8]		; (empty)
+
+not_powersuit:
+
+	/*
+	fv->flags = 0;
+
+	fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3];
+	fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3];
+	fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3];
+	*/
+	__asm mov  eax, fv
+	__asm mov  dword ptr [eax+FINALVERT_FLAGS], 0
+
+	__asm fld  dword ptr [lerped_vert+0]           ; lv0
+	__asm fmul dword ptr [aliastransform+0]        ; lv0*at[0][0]
+	__asm fld  dword ptr [lerped_vert+4]           ; lv1 | lv0*at[0][0]
+	__asm fmul dword ptr [aliastransform+4]        ; lv1*at[0][1] | lv0*at[0][0]
+	__asm fld  dword ptr [lerped_vert+8]           ; lv2 | lv1*at[0][1] | lv0*at[0][0]
+	__asm fmul dword ptr [aliastransform+8]        ; lv2*at[0][2] | lv1*at[0][1] | lv0*at[0][0]
+	__asm fxch st(2)                               ; lv0*at[0][0] | lv1*at[0][1] | lv2*at[0][2]
+	__asm faddp st(1), st                          ; lv0*at[0][0] + lv1*at[0][1] | lv2*at[0][2]
+	__asm faddp st(1), st                          ; lv0*at[0][0] + lv1*at[0][1] + lv2*at[0][2]
+	__asm fadd  dword ptr [aliastransform+12]      ; FV.X
+
+	__asm fld  dword ptr [lerped_vert+0]           ; lv0
+	__asm fmul dword ptr [aliastransform+16]       ; lv0*at[1][0]
+	__asm fld  dword ptr [lerped_vert+4]           ; lv1 | lv0*at[1][0]
+	__asm fmul dword ptr [aliastransform+20]       ; lv1*at[1][1] | lv0*at[1][0]
+	__asm fld  dword ptr [lerped_vert+8]           ; lv2 | lv1*at[1][1] | lv0*at[1][0]
+	__asm fmul dword ptr [aliastransform+24]       ; lv2*at[1][2] | lv1*at[1][1] | lv0*at[1][0]
+	__asm fxch st(2)                               ; lv0*at[1][0] | lv1*at[1][1] | lv2*at[1][2]
+	__asm faddp st(1), st                          ; lv0*at[1][0] + lv1*at[1][1] | lv2*at[1][2]
+	__asm faddp st(1), st                          ; lv0*at[1][0] + lv1*at[1][1] + lv2*at[1][2]
+	__asm fadd dword ptr [aliastransform+28]       ; FV.Y | FV.X
+	__asm fxch st(1)                               ; FV.X | FV.Y
+	__asm fstp  dword ptr [eax+FINALVERT_X]        ; FV.Y
+	
+	__asm fld  dword ptr [lerped_vert+0]           ; lv0
+	__asm fmul dword ptr [aliastransform+32]       ; lv0*at[2][0]
+	__asm fld  dword ptr [lerped_vert+4]           ; lv1 | lv0*at[2][0]
+	__asm fmul dword ptr [aliastransform+36]       ; lv1*at[2][1] | lv0*at[2][0]
+	__asm fld  dword ptr [lerped_vert+8]           ; lv2 | lv1*at[2][1] | lv0*at[2][0]
+	__asm fmul dword ptr [aliastransform+40]       ; lv2*at[2][2] | lv1*at[2][1] | lv0*at[2][0]
+	__asm fxch st(2)                               ; lv0*at[2][0] | lv1*at[2][1] | lv2*at[2][2]
+	__asm faddp st(1), st                          ; lv0*at[2][0] + lv1*at[2][1] | lv2*at[2][2]
+	__asm faddp st(1), st                          ; lv0*at[2][0] + lv1*at[2][1] + lv2*at[2][2]
+	__asm fadd dword ptr [aliastransform+44]       ; FV.Z | FV.Y
+	__asm fxch st(1)                               ; FV.Y | FV.Z
+	__asm fstp dword ptr [eax+FINALVERT_Y]         ; FV.Z
+	__asm fstp dword ptr [eax+FINALVERT_Z]         ; (empty)
+
+	/*
+	**  lighting
+	**
+	**  plightnormal = r_avertexnormals[newv->lightnormalindex];
+	**	lightcos = DotProduct (plightnormal, r_plightvec);
+	**	temp = r_ambientlight;
+	*/
+	__asm xor ebx, ebx
+	__asm mov bl,  byte ptr [edi+DTRIVERTX_LNI]
+	__asm mov eax, 12
+	__asm mul ebx
+	__asm lea eax, [r_avertexnormals+eax]
+	__asm lea ebx, r_plightvec
+
+	__asm fld  dword ptr [eax+0]
+	__asm fmul dword ptr [ebx+0]
+	__asm fld  dword ptr [eax+4]
+	__asm fmul dword ptr [ebx+4]
+	__asm fld  dword ptr [eax+8]
+	__asm fmul dword ptr [ebx+8]
+	__asm fxch st(2)
+	__asm faddp st(1), st
+	__asm faddp st(1), st
+	__asm fstp dword ptr lightcos
+	__asm mov eax, lightcos
+	__asm mov ebx, r_ambientlight
+
+	/*
+	if (lightcos < 0)
+	{
+		temp += (int)(r_shadelight * lightcos);
+
+		// clamp; because we limited the minimum ambient and shading light, we
+		// don't have to clamp low light, just bright
+		if (temp < 0)
+			temp = 0;
+	}
+
+	fv->v[4] = temp;
+	*/
+	__asm or  eax, eax
+	__asm jns store_fv4
+
+	__asm fld   dword ptr r_shadelight
+	__asm fmul  dword ptr lightcos
+	__asm fistp dword ptr tmpint
+	__asm add   ebx, tmpint
+
+	__asm or    ebx, ebx
+	__asm jns   store_fv4
+	__asm mov   ebx, 0
+
+store_fv4:
+	__asm mov edi, fv
+	__asm mov dword ptr [edi+FINALVERT_V4], ebx
+
+	__asm mov edx, dword ptr [edi+FINALVERT_FLAGS]
+
+	/*
+	** do clip testing and projection here
+	*/
+	/*
+	if ( dest_vert->xyz[2] < ALIAS_Z_CLIP_PLANE )
+	{
+		dest_vert->flags |= ALIAS_Z_CLIP;
+	}
+	else
+	{
+		R_AliasProjectAndClipTestFinalVert( dest_vert );
+	}
+	*/
+	__asm mov eax, dword ptr [edi+FINALVERT_Z]
+	__asm and eax, eax
+	__asm js  alias_z_clip
+	__asm cmp eax, FALIAS_Z_CLIP_PLANE
+	__asm jl  alias_z_clip
+
+	/*
+	This is the code to R_AliasProjectAndClipTestFinalVert
+
+	float	zi;
+	float	x, y, z;
+
+	x = fv->xyz[0];
+	y = fv->xyz[1];
+	z = fv->xyz[2];
+	zi = 1.0 / z;
+
+	fv->v[5] = zi * s_ziscale;
+
+	fv->v[0] = (x * aliasxscale * zi) + aliasxcenter;
+	fv->v[1] = (y * aliasyscale * zi) + aliasycenter;
+	*/
+	__asm fld   one                             ; 1
+	__asm fdiv  dword ptr [edi+FINALVERT_Z]     ; zi
+
+	__asm mov   eax, dword ptr [edi+32]
+	__asm mov   eax, dword ptr [edi+64]
+
+	__asm fst   zi                              ; zi
+	__asm fmul  s_ziscale                       ; fv5
+	__asm fld   dword ptr [edi+FINALVERT_X]     ; x | fv5
+	__asm fmul  aliasxscale                     ; x * aliasxscale | fv5
+	__asm fld   dword ptr [edi+FINALVERT_Y]     ; y | x * aliasxscale | fv5
+	__asm fmul  aliasyscale                     ; y * aliasyscale | x * aliasxscale | fv5
+	__asm fxch  st(1)                           ; x * aliasxscale | y * aliasyscale | fv5
+	__asm fmul  zi                              ; x * asx * zi | y * asy | fv5
+	__asm fadd  aliasxcenter                    ; fv0 | y * asy | fv5
+	__asm fxch  st(1)                           ; y * asy | fv0 | fv5
+	__asm fmul  zi                              ; y * asy * zi | fv0 | fv5
+	__asm fadd  aliasycenter                    ; fv1 | fv0 | fv5
+	__asm fxch  st(2)                           ; fv5 | fv0 | fv1
+	__asm fistp dword ptr [edi+FINALVERT_V5]    ; fv0 | fv1
+	__asm fistp dword ptr [edi+FINALVERT_V0]    ; fv1
+	__asm fistp dword ptr [edi+FINALVERT_V1]    ; (empty)
+
+	/*
+	if (fv->v[0] < r_refdef.aliasvrect.x)
+		fv->flags |= ALIAS_LEFT_CLIP;
+	if (fv->v[1] < r_refdef.aliasvrect.y)
+		fv->flags |= ALIAS_TOP_CLIP;
+	if (fv->v[0] > r_refdef.aliasvrectright)
+		fv->flags |= ALIAS_RIGHT_CLIP;
+	if (fv->v[1] > r_refdef.aliasvrectbottom)
+		fv->flags |= ALIAS_BOTTOM_CLIP;
+	*/
+	__asm mov eax, dword ptr [edi+FINALVERT_V0]
+	__asm mov ebx, dword ptr [edi+FINALVERT_V1]
+
+	__asm cmp eax, r_refdef.aliasvrect.x
+	__asm jge ct_alias_top
+	__asm or  edx, ALIAS_LEFT_CLIP
+ct_alias_top:
+	__asm cmp ebx, r_refdef.aliasvrect.y
+	__asm jge ct_alias_right
+	__asm or edx, ALIAS_TOP_CLIP
+ct_alias_right:
+	__asm cmp eax, r_refdef.aliasvrectright
+	__asm jle ct_alias_bottom
+	__asm or edx, ALIAS_RIGHT_CLIP
+ct_alias_bottom:
+	__asm cmp ebx, r_refdef.aliasvrectbottom
+	__asm jle end_of_loop
+	__asm or  edx, ALIAS_BOTTOM_CLIP
+
+	__asm jmp end_of_loop
+
+alias_z_clip:
+	__asm or  edx, ALIAS_Z_CLIP
+
+end_of_loop:
+
+	__asm mov dword ptr [edi+FINALVERT_FLAGS], edx
+	__asm add oldv, DTRIVERTX_SIZE
+	__asm add newv, DTRIVERTX_SIZE
+	__asm add fv, FINALVERT_SIZE
+
+	__asm dec ecx
+	__asm jnz top_of_loop
+}
+#else
+void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv )
+{
+	int i;
+
+	for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ )
+	{
+		int		temp;
+		float	lightcos, *plightnormal;
+		vec3_t  lerped_vert;
+
+		lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0];
+		lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1];
+		lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2];
+
+		plightnormal = r_avertexnormals[newv->lightnormalindex];
+
+		// PMM - added double damage shell
+		if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
+		{
+			lerped_vert[0] += plightnormal[0] * POWERSUIT_SCALE;
+			lerped_vert[1] += plightnormal[1] * POWERSUIT_SCALE;
+			lerped_vert[2] += plightnormal[2] * POWERSUIT_SCALE;
+		}
+
+		fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3];
+		fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3];
+		fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3];
+
+		fv->flags = 0;
+
+		// lighting
+		lightcos = DotProduct (plightnormal, r_plightvec);
+		temp = r_ambientlight;
+
+		if (lightcos < 0)
+		{
+			temp += (int)(r_shadelight * lightcos);
+
+			// clamp; because we limited the minimum ambient and shading light, we
+			// don't have to clamp low light, just bright
+			if (temp < 0)
+				temp = 0;
+		}
+
+		fv->l = temp;
+
+		if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE )
+		{
+			fv->flags |= ALIAS_Z_CLIP;
+		}
+		else
+		{
+			R_AliasProjectAndClipTestFinalVert( fv );
+		}
+	}
+}
+
+#endif
+
+/*
+================
+R_AliasProjectAndClipTestFinalVert
+================
+*/
+void R_AliasProjectAndClipTestFinalVert( finalvert_t *fv )
+{
+	float	zi;
+	float	x, y, z;
+
+	// project points
+	x = fv->xyz[0];
+	y = fv->xyz[1];
+	z = fv->xyz[2];
+	zi = 1.0 / z;
+
+	fv->zi = zi * s_ziscale;
+
+	fv->u = (x * aliasxscale * zi) + aliasxcenter;
+	fv->v = (y * aliasyscale * zi) + aliasycenter;
+
+	if (fv->u < r_refdef.aliasvrect.x)
+		fv->flags |= ALIAS_LEFT_CLIP;
+	if (fv->v < r_refdef.aliasvrect.y)
+		fv->flags |= ALIAS_TOP_CLIP;
+	if (fv->u > r_refdef.aliasvrectright)
+		fv->flags |= ALIAS_RIGHT_CLIP;
+	if (fv->v > r_refdef.aliasvrectbottom)
+		fv->flags |= ALIAS_BOTTOM_CLIP;	
+}
+
+/*
+===============
+R_AliasSetupSkin
+===============
+*/
+static qboolean R_AliasSetupSkin (void)
+{
+	int				skinnum;
+	image_t			*pskindesc;
+
+	if (currententity->skin)
+		pskindesc = currententity->skin;
+	else
+	{
+		skinnum = currententity->skinnum;
+		if ((skinnum >= s_pmdl->num_skins) || (skinnum < 0))
+		{
+			ri.Con_Printf (PRINT_ALL, "R_AliasSetupSkin %s: no such skin # %d\n", 
+				currentmodel->name, skinnum);
+			skinnum = 0;
+		}
+
+		pskindesc = currentmodel->skins[skinnum];
+	}
+
+	if ( !pskindesc )
+		return false;
+
+	r_affinetridesc.pskin = pskindesc->pixels[0];
+	r_affinetridesc.skinwidth = pskindesc->width;
+	r_affinetridesc.skinheight = pskindesc->height;
+
+	R_PolysetUpdateTables ();		// FIXME: precalc edge lookups
+
+	return true;
+}
+
+
+/*
+================
+R_AliasSetupLighting
+
+  FIXME: put lighting into tables
+================
+*/
+void R_AliasSetupLighting (void)
+{
+	alight_t		lighting;
+	float			lightvec[3] = {-1, 0, 0};
+	vec3_t			light;
+	int				i, j;
+
+	// all components of light should be identical in software
+	if ( currententity->flags & RF_FULLBRIGHT )
+	{
+		for (i=0 ; i<3 ; i++)
+			light[i] = 1.0;
+	}
+	else
+	{
+		R_LightPoint (currententity->origin, light);
+	}
+
+	// save off light value for server to look at (BIG HACK!)
+	if ( currententity->flags & RF_WEAPONMODEL )
+		r_lightlevel->value = 150.0 * light[0];
+
+
+	if ( currententity->flags & RF_MINLIGHT )
+	{
+		for (i=0 ; i<3 ; i++)
+			if (light[i] < 0.1)
+				light[i] = 0.1;
+	}
+
+	if ( currententity->flags & RF_GLOW )
+	{	// bonus items will pulse with time
+		float	scale;
+		float	min;
+
+		scale = 0.1 * sin(r_newrefdef.time*7);
+		for (i=0 ; i<3 ; i++)
+		{
+			min = light[i] * 0.8;
+			light[i] += scale;
+			if (light[i] < min)
+				light[i] = min;
+		}
+	}
+
+	j = (light[0] + light[1] + light[2])*0.3333*255;
+
+	lighting.ambientlight = j;
+	lighting.shadelight = j;
+
+	lighting.plightvec = lightvec;
+
+// clamp lighting so it doesn't overbright as much
+	if (lighting.ambientlight > 128)
+		lighting.ambientlight = 128;
+	if (lighting.ambientlight + lighting.shadelight > 192)
+		lighting.shadelight = 192 - lighting.ambientlight;
+
+// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
+// to clamp off the bottom
+	r_ambientlight = lighting.ambientlight;
+
+	if (r_ambientlight < LIGHT_MIN)
+		r_ambientlight = LIGHT_MIN;
+
+	r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
+
+	if (r_ambientlight < LIGHT_MIN)
+		r_ambientlight = LIGHT_MIN;
+
+	r_shadelight = lighting.shadelight;
+
+	if (r_shadelight < 0)
+		r_shadelight = 0;
+
+	r_shadelight *= VID_GRADES;
+
+// rotate the lighting vector into the model's frame of reference
+	r_plightvec[0] =  DotProduct( lighting.plightvec, s_alias_forward );
+	r_plightvec[1] = -DotProduct( lighting.plightvec, s_alias_right );
+	r_plightvec[2] =  DotProduct( lighting.plightvec, s_alias_up );
+}
+
+
+/*
+=================
+R_AliasSetupFrames
+
+=================
+*/
+void R_AliasSetupFrames( dmdl_t *pmdl )
+{
+	int thisframe = currententity->frame;
+	int lastframe = currententity->oldframe;
+
+	if ( ( thisframe >= pmdl->num_frames ) || ( thisframe < 0 ) )
+	{
+		ri.Con_Printf (PRINT_ALL, "R_AliasSetupFrames %s: no such thisframe %d\n", 
+			currentmodel->name, thisframe);
+		thisframe = 0;
+	}
+	if ( ( lastframe >= pmdl->num_frames ) || ( lastframe < 0 ) )
+	{
+		ri.Con_Printf (PRINT_ALL, "R_AliasSetupFrames %s: no such lastframe %d\n", 
+			currentmodel->name, lastframe);
+		lastframe = 0;
+	}
+
+	r_thisframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames 
+		+ thisframe * pmdl->framesize);
+
+	r_lastframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames 
+		+ lastframe * pmdl->framesize);
+}
+
+/*
+** R_AliasSetUpLerpData
+**
+** Precomputes lerp coefficients used for the whole frame.
+*/
+void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp )
+{
+	float	frontlerp;
+	vec3_t	translation, vectors[3];
+	int		i;
+
+	frontlerp = 1.0F - backlerp;
+
+	/*
+	** convert entity's angles into discrete vectors for R, U, and F
+	*/
+	AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
+
+	/*
+	** translation is the vector from last position to this position
+	*/
+	VectorSubtract (currententity->oldorigin, currententity->origin, translation);
+
+	/*
+	** move should be the delta back to the previous frame * backlerp
+	*/
+	r_lerp_move[0] =  DotProduct(translation, vectors[0]);	// forward
+	r_lerp_move[1] = -DotProduct(translation, vectors[1]);	// left
+	r_lerp_move[2] =  DotProduct(translation, vectors[2]);	// up
+
+	VectorAdd( r_lerp_move, r_lastframe->translate, r_lerp_move );
+
+	for (i=0 ; i<3 ; i++)
+	{
+		r_lerp_move[i] = backlerp*r_lerp_move[i] + frontlerp * r_thisframe->translate[i];
+	}
+
+	for (i=0 ; i<3 ; i++)
+	{
+		r_lerp_frontv[i] = frontlerp * r_thisframe->scale[i];
+		r_lerp_backv[i]  = backlerp  * r_lastframe->scale[i];
+	}
+}
+
+/*
+================
+R_AliasDrawModel
+================
+*/
+void R_AliasDrawModel (void)
+{
+	extern void	(*d_pdrawspans)(void *);
+	extern void R_PolysetDrawSpans8_Opaque( void * );
+	extern void R_PolysetDrawSpans8_33( void * );
+	extern void R_PolysetDrawSpans8_66( void * );
+	extern void R_PolysetDrawSpansConstant8_33( void * );
+	extern void R_PolysetDrawSpansConstant8_66( void * );
+
+	s_pmdl = (dmdl_t *)currentmodel->extradata;
+
+	if ( r_lerpmodels->value == 0 )
+		currententity->backlerp = 0;
+
+	if ( currententity->flags & RF_WEAPONMODEL )
+	{
+		if ( r_lefthand->value == 1.0F )
+			aliasxscale = -aliasxscale;
+		else if ( r_lefthand->value == 2.0F )
+			return;
+	}
+
+	/*
+	** we have to set our frame pointers and transformations before
+	** doing any real work
+	*/
+	R_AliasSetupFrames( s_pmdl );
+	R_AliasSetUpTransform();
+
+	// see if the bounding box lets us trivially reject, also sets
+	// trivial accept status
+	if ( R_AliasCheckBBox() == BBOX_TRIVIAL_REJECT )
+	{
+		if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
+		{
+			aliasxscale = -aliasxscale;
+		}
+		return;
+	}
+
+	// set up the skin and verify it exists
+	if ( !R_AliasSetupSkin () )
+	{
+		ri.Con_Printf( PRINT_ALL, "R_AliasDrawModel %s: NULL skin found\n",
+			currentmodel->name);
+		return;
+	}
+
+	r_amodels_drawn++;
+	R_AliasSetupLighting ();
+
+	/*
+	** select the proper span routine based on translucency
+	*/
+	// PMM - added double damage shell
+	// PMM - reordered to handle blending
+	if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
+	{
+		int		color;
+
+		// PMM - added double
+		color = currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM);
+		// PMM - reordered, old code first
+/*
+		if ( color == RF_SHELL_RED )
+			r_aliasblendcolor = SHELL_RED_COLOR;
+		else if ( color == RF_SHELL_GREEN )
+			r_aliasblendcolor = SHELL_GREEN_COLOR;
+		else if ( color == RF_SHELL_BLUE )
+			r_aliasblendcolor = SHELL_BLUE_COLOR;
+		else if ( color == (RF_SHELL_RED | RF_SHELL_GREEN) )
+			r_aliasblendcolor = SHELL_RG_COLOR;
+		else if ( color == (RF_SHELL_RED | RF_SHELL_BLUE) )
+			r_aliasblendcolor = SHELL_RB_COLOR;
+		else if ( color == (RF_SHELL_BLUE | RF_SHELL_GREEN) )
+			r_aliasblendcolor = SHELL_BG_COLOR;
+		// PMM - added this .. it's yellowish
+		else if ( color == (RF_SHELL_DOUBLE) )
+			r_aliasblendcolor = SHELL_DOUBLE_COLOR;
+		else if ( color == (RF_SHELL_HALF_DAM) )
+			r_aliasblendcolor = SHELL_HALF_DAM_COLOR;
+		// pmm
+		else
+			r_aliasblendcolor = SHELL_WHITE_COLOR;
+*/
+		if ( color & RF_SHELL_RED )
+		{
+			if ( ( color & RF_SHELL_BLUE) && ( color & RF_SHELL_GREEN) )
+				r_aliasblendcolor = SHELL_WHITE_COLOR;
+			else if ( color & (RF_SHELL_BLUE | RF_SHELL_DOUBLE))
+				r_aliasblendcolor = SHELL_RB_COLOR;
+			else
+				r_aliasblendcolor = SHELL_RED_COLOR;
+		}
+		else if ( color & RF_SHELL_BLUE)
+		{
+			if ( color & RF_SHELL_DOUBLE )
+				r_aliasblendcolor = SHELL_CYAN_COLOR;
+			else
+				r_aliasblendcolor = SHELL_BLUE_COLOR;
+		}
+		else if ( color & (RF_SHELL_DOUBLE) )
+			r_aliasblendcolor = SHELL_DOUBLE_COLOR;
+		else if ( color & (RF_SHELL_HALF_DAM) )
+			r_aliasblendcolor = SHELL_HALF_DAM_COLOR;
+		else if ( color & RF_SHELL_GREEN )
+			r_aliasblendcolor = SHELL_GREEN_COLOR;
+		else
+			r_aliasblendcolor = SHELL_WHITE_COLOR;
+
+
+		if ( currententity->alpha > 0.33 )
+			d_pdrawspans = R_PolysetDrawSpansConstant8_66;
+		else
+			d_pdrawspans = R_PolysetDrawSpansConstant8_33;
+	}
+	else if ( currententity->flags & RF_TRANSLUCENT )
+	{
+		if ( currententity->alpha > 0.66 )
+			d_pdrawspans = R_PolysetDrawSpans8_Opaque;
+		else if ( currententity->alpha > 0.33 )
+			d_pdrawspans = R_PolysetDrawSpans8_66;
+		else
+			d_pdrawspans = R_PolysetDrawSpans8_33;
+	}
+	else
+	{
+		d_pdrawspans = R_PolysetDrawSpans8_Opaque;
+	}
+
+	/*
+	** compute this_frame and old_frame addresses
+	*/
+	R_AliasSetUpLerpData( s_pmdl, currententity->backlerp );
+
+	if (currententity->flags & RF_DEPTHHACK)
+		s_ziscale = (float)0x8000 * (float)0x10000 * 3.0;
+	else
+		s_ziscale = (float)0x8000 * (float)0x10000;
+
+	R_AliasPreparePoints ();
+
+	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
+	{
+		aliasxscale = -aliasxscale;
+	}
+}
+
+
+
--- /dev/null
+++ b/ref/r_bsp.c
@@ -1,0 +1,637 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_bsp.c
+
+#include "r_local.h"
+
+//
+// current entity info
+//
+qboolean		insubmodel;
+entity_t		*currententity;
+vec3_t			modelorg;		// modelorg is the viewpoint reletive to
+								// the currently rendering entity
+vec3_t			r_entorigin;	// the currently rendering entity in world
+								// coordinates
+
+float			entity_rotation[3][3];
+
+int				r_currentbkey;
+
+typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t;
+
+#define MAX_BMODEL_VERTS	500			// 6K
+#define MAX_BMODEL_EDGES	1000		// 12K
+
+static mvertex_t	*pbverts;
+static bedge_t		*pbedges;
+static int			numbverts, numbedges;
+
+static mvertex_t	*pfrontenter, *pfrontexit;
+
+static qboolean		makeclippededge;
+
+
+//===========================================================================
+
+/*
+================
+R_EntityRotate
+================
+*/
+void R_EntityRotate (vec3_t vec)
+{
+	vec3_t	tvec;
+
+	VectorCopy (vec, tvec);
+	vec[0] = DotProduct (entity_rotation[0], tvec);
+	vec[1] = DotProduct (entity_rotation[1], tvec);
+	vec[2] = DotProduct (entity_rotation[2], tvec);
+}
+
+
+/*
+================
+R_RotateBmodel
+================
+*/
+void R_RotateBmodel (void)
+{
+	float	angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3];
+
+// TODO: should use a look-up table
+// TODO: should really be stored with the entity instead of being reconstructed
+// TODO: could cache lazily, stored in the entity
+// TODO: share work with R_SetUpAliasTransform
+
+// yaw
+	angle = currententity->angles[YAW];		
+	angle = angle * M_PI*2 / 360;
+	s = sin(angle);
+	c = cos(angle);
+
+	temp1[0][0] = c;
+	temp1[0][1] = s;
+	temp1[0][2] = 0;
+	temp1[1][0] = -s;
+	temp1[1][1] = c;
+	temp1[1][2] = 0;
+	temp1[2][0] = 0;
+	temp1[2][1] = 0;
+	temp1[2][2] = 1;
+
+
+// pitch
+	angle = currententity->angles[PITCH];		
+	angle = angle * M_PI*2 / 360;
+	s = sin(angle);
+	c = cos(angle);
+
+	temp2[0][0] = c;
+	temp2[0][1] = 0;
+	temp2[0][2] = -s;
+	temp2[1][0] = 0;
+	temp2[1][1] = 1;
+	temp2[1][2] = 0;
+	temp2[2][0] = s;
+	temp2[2][1] = 0;
+	temp2[2][2] = c;
+
+	R_ConcatRotations (temp2, temp1, temp3);
+
+// roll
+	angle = currententity->angles[ROLL];		
+	angle = angle * M_PI*2 / 360;
+	s = sin(angle);
+	c = cos(angle);
+
+	temp1[0][0] = 1;
+	temp1[0][1] = 0;
+	temp1[0][2] = 0;
+	temp1[1][0] = 0;
+	temp1[1][1] = c;
+	temp1[1][2] = s;
+	temp1[2][0] = 0;
+	temp1[2][1] = -s;
+	temp1[2][2] = c;
+
+	R_ConcatRotations (temp1, temp3, entity_rotation);
+
+//
+// rotate modelorg and the transformation matrix
+//
+	R_EntityRotate (modelorg);
+	R_EntityRotate (vpn);
+	R_EntityRotate (vright);
+	R_EntityRotate (vup);
+
+	R_TransformFrustum ();
+}
+
+
+/*
+================
+R_RecursiveClipBPoly
+
+Clip a bmodel poly down the world bsp tree
+================
+*/
+void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf)
+{
+	bedge_t		*psideedges[2], *pnextedge, *ptedge;
+	int			i, side, lastside;
+	float		dist, frac, lastdist;
+	mplane_t	*splitplane, tplane;
+	mvertex_t	*pvert, *plastvert, *ptvert;
+	mnode_t		*pn;
+	int			area;
+
+	psideedges[0] = psideedges[1] = NULL;
+
+	makeclippededge = false;
+
+// transform the BSP plane into model space
+// FIXME: cache these?
+	splitplane = pnode->plane;
+	tplane.dist = splitplane->dist -
+			DotProduct(r_entorigin, splitplane->normal);
+	tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal);
+	tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal);
+	tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal);
+
+// clip edges to BSP plane
+	for ( ; pedges ; pedges = pnextedge)
+	{
+		pnextedge = pedges->pnext;
+
+	// set the status for the last point as the previous point
+	// FIXME: cache this stuff somehow?
+		plastvert = pedges->v[0];
+		lastdist = DotProduct (plastvert->position, tplane.normal) -
+				   tplane.dist;
+
+		if (lastdist > 0)
+			lastside = 0;
+		else
+			lastside = 1;
+
+		pvert = pedges->v[1];
+
+		dist = DotProduct (pvert->position, tplane.normal) - tplane.dist;
+
+		if (dist > 0)
+			side = 0;
+		else
+			side = 1;
+
+		if (side != lastside)
+		{
+		// clipped
+			if (numbverts >= MAX_BMODEL_VERTS)
+				return;
+
+		// generate the clipped vertex
+			frac = lastdist / (lastdist - dist);
+			ptvert = &pbverts[numbverts++];
+			ptvert->position[0] = plastvert->position[0] +
+					frac * (pvert->position[0] -
+					plastvert->position[0]);
+			ptvert->position[1] = plastvert->position[1] +
+					frac * (pvert->position[1] -
+					plastvert->position[1]);
+			ptvert->position[2] = plastvert->position[2] +
+					frac * (pvert->position[2] -
+					plastvert->position[2]);
+
+		// split into two edges, one on each side, and remember entering
+		// and exiting points
+		// FIXME: share the clip edge by having a winding direction flag?
+			if (numbedges >= (MAX_BMODEL_EDGES - 1))
+			{
+				ri.Con_Printf (PRINT_ALL,"Out of edges for bmodel\n");
+				return;
+			}
+
+			ptedge = &pbedges[numbedges];
+			ptedge->pnext = psideedges[lastside];
+			psideedges[lastside] = ptedge;
+			ptedge->v[0] = plastvert;
+			ptedge->v[1] = ptvert;
+
+			ptedge = &pbedges[numbedges + 1];
+			ptedge->pnext = psideedges[side];
+			psideedges[side] = ptedge;
+			ptedge->v[0] = ptvert;
+			ptedge->v[1] = pvert;
+
+			numbedges += 2;
+
+			if (side == 0)
+			{
+			// entering for front, exiting for back
+				pfrontenter = ptvert;
+				makeclippededge = true;
+			}
+			else
+			{
+				pfrontexit = ptvert;
+				makeclippededge = true;
+			}
+		}
+		else
+		{
+		// add the edge to the appropriate side
+			pedges->pnext = psideedges[side];
+			psideedges[side] = pedges;
+		}
+	}
+
+// if anything was clipped, reconstitute and add the edges along the clip
+// plane to both sides (but in opposite directions)
+	if (makeclippededge)
+	{
+		if (numbedges >= (MAX_BMODEL_EDGES - 2))
+		{
+			ri.Con_Printf (PRINT_ALL,"Out of edges for bmodel\n");
+			return;
+		}
+
+		ptedge = &pbedges[numbedges];
+		ptedge->pnext = psideedges[0];
+		psideedges[0] = ptedge;
+		ptedge->v[0] = pfrontexit;
+		ptedge->v[1] = pfrontenter;
+
+		ptedge = &pbedges[numbedges + 1];
+		ptedge->pnext = psideedges[1];
+		psideedges[1] = ptedge;
+		ptedge->v[0] = pfrontenter;
+		ptedge->v[1] = pfrontexit;
+
+		numbedges += 2;
+	}
+
+// draw or recurse further
+	for (i=0 ; i<2 ; i++)
+	{
+		if (psideedges[i])
+		{
+		// draw if we've reached a non-solid leaf, done if all that's left is a
+		// solid leaf, and continue down the tree if it's not a leaf
+			pn = pnode->children[i];
+
+		// we're done with this branch if the node or leaf isn't in the PVS
+			if (pn->visframe == r_visframecount)
+			{
+				if (pn->contents != CONTENTS_NODE)
+				{
+					if (pn->contents != CONTENTS_SOLID)
+					{
+						if (r_newrefdef.areabits)
+						{
+							area = ((mleaf_t *)pn)->area;
+							if (! (r_newrefdef.areabits[area>>3] & (1<<(area&7)) ) )
+								continue;		// not visible
+						}
+
+						r_currentbkey = ((mleaf_t *)pn)->key;
+						R_RenderBmodelFace (psideedges[i], psurf);
+					}
+				}
+				else
+				{
+					R_RecursiveClipBPoly (psideedges[i], pnode->children[i],
+									  psurf);
+				}
+			}
+		}
+	}
+}
+
+
+/*
+================
+R_DrawSolidClippedSubmodelPolygons
+
+Bmodel crosses multiple leafs
+================
+*/
+void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode)
+{
+	int			i, j, lindex;
+	vec_t		dot;
+	msurface_t	*psurf;
+	int			numsurfaces;
+	mplane_t	*pplane;
+	mvertex_t	bverts[MAX_BMODEL_VERTS];
+	bedge_t		bedges[MAX_BMODEL_EDGES], *pbedge;
+	medge_t		*pedge, *pedges;
+
+// FIXME: use bounding-box-based frustum clipping info?
+
+	psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
+	numsurfaces = pmodel->nummodelsurfaces;
+	pedges = pmodel->edges;
+
+	for (i=0 ; i<numsurfaces ; i++, psurf++)
+	{
+	// find which side of the node we are on
+		pplane = psurf->plane;
+
+		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
+
+	// draw the polygon
+		if (( !(psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
+			((psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
+			continue;
+
+	// FIXME: use bounding-box-based frustum clipping info?
+
+	// copy the edges to bedges, flipping if necessary so always
+	// clockwise winding
+	// FIXME: if edges and vertices get caches, these assignments must move
+	// outside the loop, and overflow checking must be done here
+		pbverts = bverts;
+		pbedges = bedges;
+		numbverts = numbedges = 0;
+		pbedge = &bedges[numbedges];
+		numbedges += psurf->numedges;
+
+		for (j=0 ; j<psurf->numedges ; j++)
+		{
+		   lindex = pmodel->surfedges[psurf->firstedge+j];
+
+			if (lindex > 0)
+			{
+				pedge = &pedges[lindex];
+				pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
+				pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
+			}
+			else
+			{
+				lindex = -lindex;
+				pedge = &pedges[lindex];
+				pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
+				pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
+			}
+
+			pbedge[j].pnext = &pbedge[j+1];
+		}
+
+		pbedge[j-1].pnext = NULL;	// mark end of edges
+
+		if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) )
+			R_RecursiveClipBPoly (pbedge, topnode, psurf);
+		else
+			R_RenderBmodelFace( pbedge, psurf );
+	}
+}
+
+
+/*
+================
+R_DrawSubmodelPolygons
+
+All in one leaf
+================
+*/
+void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode)
+{
+	int			i;
+	vec_t		dot;
+	msurface_t	*psurf;
+	int			numsurfaces;
+	mplane_t	*pplane;
+
+// FIXME: use bounding-box-based frustum clipping info?
+
+	psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
+	numsurfaces = pmodel->nummodelsurfaces;
+
+	for (i=0 ; i<numsurfaces ; i++, psurf++)
+	{
+	// find which side of the node we are on
+		pplane = psurf->plane;
+
+		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
+
+	// draw the polygon
+		if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
+			(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
+		{
+			r_currentkey = ((mleaf_t *)topnode)->key;
+
+		// FIXME: use bounding-box-based frustum clipping info?
+			R_RenderFace (psurf, clipflags);
+		}
+	}
+}
+
+
+int c_drawnode;
+
+/*
+================
+R_RecursiveWorldNode
+================
+*/
+void R_RecursiveWorldNode (mnode_t *node, int clipflags)
+{
+	int			i, c, side, *pindex;
+	vec3_t		acceptpt, rejectpt;
+	mplane_t	*plane;
+	msurface_t	*surf, **mark;
+	float		d, dot;
+	mleaf_t		*pleaf;
+
+	if (node->contents == CONTENTS_SOLID)
+		return;		// solid
+
+	if (node->visframe != r_visframecount)
+		return;
+
+// cull the clipping planes if not trivial accept
+// FIXME: the compiler is doing a lousy job of optimizing here; it could be
+//  twice as fast in ASM
+	if (clipflags)
+	{
+		for (i=0 ; i<4 ; i++)
+		{
+			if (! (clipflags & (1<<i)) )
+				continue;	// don't need to clip against it
+
+		// generate accept and reject points
+		// FIXME: do with fast look-ups or integer tests based on the sign bit
+		// of the floating point values
+
+			pindex = pfrustum_indexes[i];
+
+			rejectpt[0] = (float)node->minmaxs[pindex[0]];
+			rejectpt[1] = (float)node->minmaxs[pindex[1]];
+			rejectpt[2] = (float)node->minmaxs[pindex[2]];
+			
+			d = DotProduct (rejectpt, view_clipplanes[i].normal);
+			d -= view_clipplanes[i].dist;
+			if (d <= 0)
+				return;
+			acceptpt[0] = (float)node->minmaxs[pindex[3+0]];
+			acceptpt[1] = (float)node->minmaxs[pindex[3+1]];
+			acceptpt[2] = (float)node->minmaxs[pindex[3+2]];
+
+			d = DotProduct (acceptpt, view_clipplanes[i].normal);
+			d -= view_clipplanes[i].dist;
+
+			if (d >= 0)
+				clipflags &= ~(1<<i);	// node is entirely on screen
+		}
+	}
+
+c_drawnode++;
+
+// if a leaf node, draw stuff
+	if (node->contents != -1)
+	{
+		pleaf = (mleaf_t *)node;
+
+		// check for door connected areas
+		if (r_newrefdef.areabits)
+		{
+			if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
+				return;		// not visible
+		}
+
+		mark = pleaf->firstmarksurface;
+		c = pleaf->nummarksurfaces;
+
+		if (c)
+		{
+			do
+			{
+				(*mark)->visframe = r_framecount;
+				mark++;
+			} while (--c);
+		}
+
+		pleaf->key = r_currentkey;
+		r_currentkey++;		// all bmodels in a leaf share the same key
+	}
+	else
+	{
+	// node is just a decision point, so go down the apropriate sides
+
+	// find which side of the node we are on
+		plane = node->plane;
+
+		switch (plane->type)
+		{
+		case PLANE_X:
+			dot = modelorg[0] - plane->dist;
+			break;
+		case PLANE_Y:
+			dot = modelorg[1] - plane->dist;
+			break;
+		case PLANE_Z:
+			dot = modelorg[2] - plane->dist;
+			break;
+		default:
+			dot = DotProduct (modelorg, plane->normal) - plane->dist;
+			break;
+		}
+	
+		if (dot >= 0)
+			side = 0;
+		else
+			side = 1;
+
+	// recurse down the children, front side first
+		R_RecursiveWorldNode (node->children[side], clipflags);
+
+	// draw stuff
+		c = node->numsurfaces;
+
+		if (c)
+		{
+			surf = r_worldmodel->surfaces + node->firstsurface;
+
+			if (dot < -BACKFACE_EPSILON)
+			{
+				do
+				{
+					if ((surf->flags & SURF_PLANEBACK) &&
+						(surf->visframe == r_framecount))
+					{
+						R_RenderFace (surf, clipflags);
+					}
+
+					surf++;
+				} while (--c);
+			}
+			else if (dot > BACKFACE_EPSILON)
+			{
+				do
+				{
+					if (!(surf->flags & SURF_PLANEBACK) &&
+						(surf->visframe == r_framecount))
+					{
+						R_RenderFace (surf, clipflags);
+					}
+
+					surf++;
+				} while (--c);
+			}
+
+		// all surfaces on the same node share the same sequence number
+			r_currentkey++;
+		}
+
+	// recurse down the back side
+		R_RecursiveWorldNode (node->children[!side], clipflags);
+	}
+}
+
+
+
+/*
+================
+R_RenderWorld
+================
+*/
+void R_RenderWorld (void)
+{
+
+	if (!r_drawworld->value)
+		return;
+	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
+		return;
+
+	c_drawnode=0;
+
+	// auto cycle the world frame for texture animation
+	r_worldentity.frame = (int)(r_newrefdef.time*2);
+	currententity = &r_worldentity;
+
+	VectorCopy (r_origin, modelorg);
+	currentmodel = r_worldmodel;
+	r_pcurrentvertbase = currentmodel->vertexes;
+
+	R_RecursiveWorldNode (currentmodel->nodes, 15);
+}
+
+
--- /dev/null
+++ b/ref/r_draw.c
@@ -1,0 +1,445 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+// draw.c
+
+#include "r_local.h"
+
+
+image_t		*draw_chars;				// 8*8 graphic characters
+
+//=============================================================================
+
+/*
+================
+Draw_FindPic
+================
+*/
+image_t *Draw_FindPic (char *name)
+{
+	image_t	*image;
+	char	fullname[MAX_QPATH];
+
+	if (name[0] != '/' && name[0] != '\\')
+	{
+		Com_sprintf (fullname, sizeof(fullname), "pics/%s.pcx", name);
+		image = R_FindImage (fullname, it_pic);
+	}
+	else
+		image = R_FindImage (name+1, it_pic);
+
+	return image;
+}
+
+
+
+/*
+===============
+Draw_InitLocal
+===============
+*/
+void Draw_InitLocal (void)
+{
+	draw_chars = Draw_FindPic ("conchars");
+}
+
+
+
+/*
+================
+Draw_Char
+
+Draws one 8*8 graphics character
+It can be clipped to the top of the screen to allow the console to be
+smoothly scrolled off.
+================
+*/
+void Draw_Char (int x, int y, int num)
+{
+	byte			*dest;
+	byte			*source;
+	int				drawline;	
+	int				row, col;
+
+	num &= 255;
+
+	if (num == 32 || num == 32+128)
+		return;
+
+	if (y <= -8)
+		return;			// totally off screen
+
+//	if ( ( y + 8 ) >= vid.height )
+	if ( ( y + 8 ) > vid.height )		// PGM - status text was missing in sw...
+		return;
+
+#ifdef PARANOID
+	if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
+		ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: (%i, %i)", x, y);
+	if (num < 0 || num > 255)
+		ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: char %i", num);
+#endif
+
+	row = num>>4;
+	col = num&15;
+	source = draw_chars->pixels[0] + (row<<10) + (col<<3);
+
+	if (y < 0)
+	{	// clipped
+		drawline = 8 + y;
+		source -= 128*y;
+		y = 0;
+	}
+	else
+		drawline = 8;
+
+
+	dest = vid.buffer + y*vid.rowbytes + x;
+
+	while (drawline--)
+	{
+		if (source[0] != TRANSPARENT_COLOR)
+			dest[0] = source[0];
+		if (source[1] != TRANSPARENT_COLOR)
+			dest[1] = source[1];
+		if (source[2] != TRANSPARENT_COLOR)
+			dest[2] = source[2];
+		if (source[3] != TRANSPARENT_COLOR)
+			dest[3] = source[3];
+		if (source[4] != TRANSPARENT_COLOR)
+			dest[4] = source[4];
+		if (source[5] != TRANSPARENT_COLOR)
+			dest[5] = source[5];
+		if (source[6] != TRANSPARENT_COLOR)
+			dest[6] = source[6];
+		if (source[7] != TRANSPARENT_COLOR)
+			dest[7] = source[7];
+		source += 128;
+		dest += vid.rowbytes;
+	}
+}
+
+/*
+=============
+Draw_GetPicSize
+=============
+*/
+void Draw_GetPicSize (int *w, int *h, char *pic)
+{
+	image_t *gl;
+
+	gl = Draw_FindPic (pic);
+	if (!gl)
+	{
+		*w = *h = -1;
+		return;
+	}
+	*w = gl->width;
+	*h = gl->height;
+}
+
+/*
+=============
+Draw_StretchPicImplementation
+=============
+*/
+void Draw_StretchPicImplementation (int x, int y, int w, int h, image_t	*pic)
+{
+	byte			*dest, *source;
+	int				v, u, sv;
+	int				height;
+	int				f, fstep;
+	int				skip;
+
+	if ((x < 0) ||
+		(x + w > vid.width) ||
+		(y + h > vid.height))
+	{
+		ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
+	}
+
+	height = h;
+	if (y < 0)
+	{
+		skip = -y;
+		height += y;
+		y = 0;
+	}
+	else
+		skip = 0;
+
+	dest = vid.buffer + y * vid.rowbytes + x;
+
+	for (v=0 ; v<height ; v++, dest += vid.rowbytes)
+	{
+		sv = (skip + v)*pic->height/h;
+		source = pic->pixels[0] + sv*pic->width;
+		if (w == pic->width)
+			memcpy (dest, source, w);
+		else
+		{
+			f = 0;
+			fstep = pic->width*0x10000/w;
+			for (u=0 ; u<w ; u+=4)
+			{
+				dest[u] = source[f>>16];
+				f += fstep;
+				dest[u+1] = source[f>>16];
+				f += fstep;
+				dest[u+2] = source[f>>16];
+				f += fstep;
+				dest[u+3] = source[f>>16];
+				f += fstep;
+			}
+		}
+	}
+}
+
+/*
+=============
+Draw_StretchPic
+=============
+*/
+void Draw_StretchPic (int x, int y, int w, int h, char *name)
+{
+	image_t	*pic;
+
+	pic = Draw_FindPic (name);
+	if (!pic)
+	{
+		ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
+		return;
+	}
+	Draw_StretchPicImplementation (x, y, w, h, pic);
+}
+
+/*
+=============
+Draw_StretchRaw
+=============
+*/
+void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data)
+{
+	image_t	pic;
+
+	pic.pixels[0] = data;
+	pic.width = cols;
+	pic.height = rows;
+	Draw_StretchPicImplementation (x, y, w, h, &pic);
+}
+
+/*
+=============
+Draw_Pic
+=============
+*/
+void Draw_Pic (int x, int y, char *name)
+{
+	image_t			*pic;
+	byte			*dest, *source;
+	int				v, u;
+	int				tbyte;
+	int				height;
+
+	pic = Draw_FindPic (name);
+	if (!pic)
+	{
+		ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
+		return;
+	}
+
+	if ((x < 0) ||
+		(x + pic->width > vid.width) ||
+		(y + pic->height > vid.height))
+		return;	//	ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
+
+	height = pic->height;
+	source = pic->pixels[0];
+	if (y < 0)
+	{
+		height += y;
+		source += pic->width*-y;
+		y = 0;
+	}
+
+	dest = vid.buffer + y * vid.rowbytes + x;
+
+	if (!pic->transparent)
+	{
+		for (v=0 ; v<height ; v++)
+		{
+			memcpy (dest, source, pic->width);
+			dest += vid.rowbytes;
+			source += pic->width;
+		}
+	}
+	else
+	{
+		if (pic->width & 7)
+		{	// general
+			for (v=0 ; v<height ; v++)
+			{
+				for (u=0 ; u<pic->width ; u++)
+					if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
+						dest[u] = tbyte;
+
+				dest += vid.rowbytes;
+				source += pic->width;
+			}
+		}
+		else
+		{	// unwound
+			for (v=0 ; v<height ; v++)
+			{
+				for (u=0 ; u<pic->width ; u+=8)
+				{
+					if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
+						dest[u] = tbyte;
+					if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
+						dest[u+1] = tbyte;
+					if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
+						dest[u+2] = tbyte;
+					if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
+						dest[u+3] = tbyte;
+					if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
+						dest[u+4] = tbyte;
+					if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
+						dest[u+5] = tbyte;
+					if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
+						dest[u+6] = tbyte;
+					if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
+						dest[u+7] = tbyte;
+				}
+				dest += vid.rowbytes;
+				source += pic->width;
+			}
+		}
+	}
+}
+
+/*
+=============
+Draw_TileClear
+
+This repeats a 64*64 tile graphic to fill the screen around a sized down
+refresh window.
+=============
+*/
+void Draw_TileClear (int x, int y, int w, int h, char *name)
+{
+	int			i, j;
+	byte		*psrc;
+	byte		*pdest;
+	image_t		*pic;
+	int			x2;
+
+	if (x < 0)
+	{
+		w += x;
+		x = 0;
+	}
+	if (y < 0)
+	{
+		h += y;
+		y = 0;
+	}
+	if (x + w > vid.width)
+		w = vid.width - x;
+	if (y + h > vid.height)
+		h = vid.height - y;
+	if (w <= 0 || h <= 0)
+		return;
+
+	pic = Draw_FindPic (name);
+	if (!pic)
+	{
+		ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
+		return;
+	}
+	x2 = x + w;
+	pdest = vid.buffer + y*vid.rowbytes;
+	for (i=0 ; i<h ; i++, pdest += vid.rowbytes)
+	{
+		psrc = pic->pixels[0] + pic->width * ((i+y)&63);
+		for (j=x ; j<x2 ; j++)
+			pdest[j] = psrc[j&63];
+	}
+}
+
+
+/*
+=============
+Draw_Fill
+
+Fills a box of pixels with a single color
+=============
+*/
+void Draw_Fill (int x, int y, int w, int h, int c)
+{
+	byte			*dest;
+	int				u, v;
+
+	if (x+w > vid.width)
+		w = vid.width - x;
+	if (y+h > vid.height)
+		h = vid.height - y;
+	if (x < 0)
+	{
+		w += x;
+		x = 0;
+	}
+	if (y < 0)
+	{
+		h += y;
+		y = 0;
+	}
+	if (w < 0 || h < 0)
+		return;
+	dest = vid.buffer + y*vid.rowbytes + x;
+	for (v=0 ; v<h ; v++, dest += vid.rowbytes)
+		for (u=0 ; u<w ; u++)
+			dest[u] = c;
+}
+//=============================================================================
+
+/*
+================
+Draw_FadeScreen
+
+================
+*/
+void Draw_FadeScreen (void)
+{
+	int			x,y;
+	byte		*pbuf;
+	int	t;
+
+	for (y=0 ; y<vid.height ; y++)
+	{
+		pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
+		t = (y & 1) << 1;
+
+		for (x=0 ; x<vid.width ; x++)
+		{
+			if ((x & 3) != t)
+				pbuf[x] = 0;
+		}
+	}
+}
--- /dev/null
+++ b/ref/r_edge.c
@@ -1,0 +1,1125 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_edge.c
+
+#include "r_local.h"
+
+#ifndef id386
+void R_SurfacePatch (void)
+{
+}
+
+void R_EdgeCodeStart (void)
+{
+}
+
+void R_EdgeCodeEnd (void)
+{
+}
+#endif
+
+
+#if 0
+the complex cases add new polys on most lines, so dont optimize for keeping them the same
+have multiple free span lists to try to get better coherence?
+low depth complexity -- 1 to 3 or so
+
+have a sentinal at both ends?
+#endif
+
+
+edge_t	*auxedges;
+edge_t	*r_edges, *edge_p, *edge_max;
+
+surf_t	*surfaces, *surface_p, *surf_max;
+
+// surfaces are generated in back to front order by the bsp, so if a surf
+// pointer is greater than another one, it should be drawn in front
+// surfaces[1] is the background, and is used as the active surface stack
+
+edge_t	*newedges[MAXHEIGHT];
+edge_t	*removeedges[MAXHEIGHT];
+
+espan_t	*span_p, *max_span_p;
+
+int		r_currentkey;
+
+int	current_iv;
+
+int	edge_head_u_shift20, edge_tail_u_shift20;
+
+static void (*pdrawfunc)(void);
+
+edge_t	edge_head;
+edge_t	edge_tail;
+edge_t	edge_aftertail;
+edge_t	edge_sentinel;
+
+float	fv;
+
+static int	miplevel;
+
+float		scale_for_mip;
+int			ubasestep, errorterm, erroradjustup, erroradjustdown;
+
+// FIXME: should go away
+extern void			R_RotateBmodel (void);
+extern void			R_TransformFrustum (void);
+
+
+
+void R_GenerateSpans (void);
+void R_GenerateSpansBackward (void);
+
+void R_LeadingEdge (edge_t *edge);
+void R_LeadingEdgeBackwards (edge_t *edge);
+void R_TrailingEdge (surf_t *surf, edge_t *edge);
+
+
+/*
+===============================================================================
+
+EDGE SCANNING
+
+===============================================================================
+*/
+
+/*
+==============
+R_BeginEdgeFrame
+==============
+*/
+void R_BeginEdgeFrame (void)
+{
+	int		v;
+
+	edge_p = r_edges;
+	edge_max = &r_edges[r_numallocatededges];
+
+	surface_p = &surfaces[2];	// background is surface 1,
+								//  surface 0 is a dummy
+	surfaces[1].spans = NULL;	// no background spans yet
+	surfaces[1].flags = SURF_DRAWBACKGROUND;
+
+// put the background behind everything in the world
+	if (sw_draworder->value)
+	{
+		pdrawfunc = R_GenerateSpansBackward;
+		surfaces[1].key = 0;
+		r_currentkey = 1;
+	}
+	else
+	{
+		pdrawfunc = R_GenerateSpans;
+		surfaces[1].key = 0x7FFfFFFF;
+		r_currentkey = 0;
+	}
+
+// FIXME: set with memset
+	for (v=r_refdef.vrect.y ; v<r_refdef.vrectbottom ; v++)
+	{
+		newedges[v] = removeedges[v] = NULL;
+	}
+}
+
+
+#if	!id386
+
+/*
+==============
+R_InsertNewEdges
+
+Adds the edges in the linked list edgestoadd, adding them to the edges in the
+linked list edgelist.  edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]).  edgelist is assumed to be sorted on u, with a
+sentinel at the end (actually, this is the active edge table starting at
+edge_head.next).
+==============
+*/
+void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
+{
+	edge_t	*next_edge;
+
+	do
+	{
+		next_edge = edgestoadd->next;
+edgesearch:
+		if (edgelist->u >= edgestoadd->u)
+			goto addedge;
+		edgelist=edgelist->next;
+		if (edgelist->u >= edgestoadd->u)
+			goto addedge;
+		edgelist=edgelist->next;
+		if (edgelist->u >= edgestoadd->u)
+			goto addedge;
+		edgelist=edgelist->next;
+		if (edgelist->u >= edgestoadd->u)
+			goto addedge;
+		edgelist=edgelist->next;
+		goto edgesearch;
+
+	// insert edgestoadd before edgelist
+addedge:
+		edgestoadd->next = edgelist;
+		edgestoadd->prev = edgelist->prev;
+		edgelist->prev->next = edgestoadd;
+		edgelist->prev = edgestoadd;
+	} while ((edgestoadd = next_edge) != NULL);
+}
+
+#endif	// !id386
+	
+
+#if	!id386
+
+/*
+==============
+R_RemoveEdges
+==============
+*/
+void R_RemoveEdges (edge_t *pedge)
+{
+
+	do
+	{
+		pedge->next->prev = pedge->prev;
+		pedge->prev->next = pedge->next;
+	} while ((pedge = pedge->nextremove) != NULL);
+}
+
+#endif	// !id386
+
+
+#if	!id386
+
+/*
+==============
+R_StepActiveU
+==============
+*/
+void R_StepActiveU (edge_t *pedge)
+{
+	edge_t		*pnext_edge, *pwedge;
+
+	while (1)
+	{
+nextedge:
+		pedge->u += pedge->u_step;
+		if (pedge->u < pedge->prev->u)
+			goto pushback;
+		pedge = pedge->next;
+			
+		pedge->u += pedge->u_step;
+		if (pedge->u < pedge->prev->u)
+			goto pushback;
+		pedge = pedge->next;
+			
+		pedge->u += pedge->u_step;
+		if (pedge->u < pedge->prev->u)
+			goto pushback;
+		pedge = pedge->next;
+			
+		pedge->u += pedge->u_step;
+		if (pedge->u < pedge->prev->u)
+			goto pushback;
+		pedge = pedge->next;
+			
+		goto nextedge;		
+		
+pushback:
+		if (pedge == &edge_aftertail)
+			return;
+			
+	// push it back to keep it sorted		
+		pnext_edge = pedge->next;
+
+	// pull the edge out of the edge list
+		pedge->next->prev = pedge->prev;
+		pedge->prev->next = pedge->next;
+
+	// find out where the edge goes in the edge list
+		pwedge = pedge->prev->prev;
+
+		while (pwedge->u > pedge->u)
+		{
+			pwedge = pwedge->prev;
+		}
+
+	// put the edge back into the edge list
+		pedge->next = pwedge->next;
+		pedge->prev = pwedge;
+		pedge->next->prev = pedge;
+		pwedge->next = pedge;
+
+		pedge = pnext_edge;
+		if (pedge == &edge_tail)
+			return;
+	}
+}
+
+#endif	// !id386
+
+
+/*
+==============
+R_CleanupSpan
+==============
+*/
+void R_CleanupSpan (void)
+{
+	surf_t	*surf;
+	int		iu;
+	espan_t	*span;
+
+// now that we've reached the right edge of the screen, we're done with any
+// unfinished surfaces, so emit a span for whatever's on top
+	surf = surfaces[1].next;
+	iu = edge_tail_u_shift20;
+	if (iu > surf->last_u)
+	{
+		span = span_p++;
+		span->u = surf->last_u;
+		span->count = iu - span->u;
+		span->v = current_iv;
+		span->pnext = surf->spans;
+		surf->spans = span;
+	}
+
+// reset spanstate for all surfaces in the surface stack
+	do
+	{
+		surf->spanstate = 0;
+		surf = surf->next;
+	} while (surf != &surfaces[1]);
+}
+
+
+/*
+==============
+R_LeadingEdgeBackwards
+==============
+*/
+void R_LeadingEdgeBackwards (edge_t *edge)
+{
+	espan_t			*span;
+	surf_t			*surf, *surf2;
+	int				iu;
+
+// it's adding a new surface in, so find the correct place
+	surf = &surfaces[edge->surfs[1]];
+
+// don't start a span if this is an inverted span, with the end
+// edge preceding the start edge (that is, we've already seen the
+// end edge)
+	if (++surf->spanstate == 1)
+	{
+		surf2 = surfaces[1].next;
+
+		if (surf->key > surf2->key)
+			goto newtop;
+
+	// if it's two surfaces on the same plane, the one that's already
+	// active is in front, so keep going unless it's a bmodel
+		if (surf->insubmodel && (surf->key == surf2->key))
+		{
+		// must be two bmodels in the same leaf; don't care, because they'll
+		// never be farthest anyway
+			goto newtop;
+		}
+
+continue_search:
+
+		do
+		{
+			surf2 = surf2->next;
+		} while (surf->key < surf2->key);
+
+		if (surf->key == surf2->key)
+		{
+		// if it's two surfaces on the same plane, the one that's already
+		// active is in front, so keep going unless it's a bmodel
+			if (!surf->insubmodel)
+				goto continue_search;
+
+		// must be two bmodels in the same leaf; don't care which is really
+		// in front, because they'll never be farthest anyway
+		}
+
+		goto gotposition;
+
+newtop:
+	// emit a span (obscures current top)
+		iu = edge->u >> 20;
+
+		if (iu > surf2->last_u)
+		{
+			span = span_p++;
+			span->u = surf2->last_u;
+			span->count = iu - span->u;
+			span->v = current_iv;
+			span->pnext = surf2->spans;
+			surf2->spans = span;
+		}
+
+		// set last_u on the new span
+		surf->last_u = iu;
+				
+gotposition:
+	// insert before surf2
+		surf->next = surf2;
+		surf->prev = surf2->prev;
+		surf2->prev->next = surf;
+		surf2->prev = surf;
+	}
+}
+
+
+/*
+==============
+R_TrailingEdge
+==============
+*/
+void R_TrailingEdge (surf_t *surf, edge_t *edge)
+{
+	espan_t			*span;
+	int				iu;
+
+// don't generate a span if this is an inverted span, with the end
+// edge preceding the start edge (that is, we haven't seen the
+// start edge yet)
+	if (--surf->spanstate == 0)
+	{
+		if (surf == surfaces[1].next)
+		{
+		// emit a span (current top going away)
+			iu = edge->u >> 20;
+			if (iu > surf->last_u)
+			{
+				span = span_p++;
+				span->u = surf->last_u;
+				span->count = iu - span->u;
+				span->v = current_iv;
+				span->pnext = surf->spans;
+				surf->spans = span;
+			}
+
+		// set last_u on the surface below
+			surf->next->last_u = iu;
+		}
+
+		surf->prev->next = surf->next;
+		surf->next->prev = surf->prev;
+	}
+}
+
+
+#if	!id386
+
+/*
+==============
+R_LeadingEdge
+==============
+*/
+void R_LeadingEdge (edge_t *edge)
+{
+	espan_t			*span;
+	surf_t			*surf, *surf2;
+	int				iu;
+	float			fu, newzi, testzi, newzitop, newzibottom;
+
+	if (edge->surfs[1])
+	{
+	// it's adding a new surface in, so find the correct place
+		surf = &surfaces[edge->surfs[1]];
+
+	// don't start a span if this is an inverted span, with the end
+	// edge preceding the start edge (that is, we've already seen the
+	// end edge)
+		if (++surf->spanstate == 1)
+		{
+			surf2 = surfaces[1].next;
+
+			if (surf->key < surf2->key)
+				goto newtop;
+
+		// if it's two surfaces on the same plane, the one that's already
+		// active is in front, so keep going unless it's a bmodel
+			if (surf->insubmodel && (surf->key == surf2->key))
+			{
+			// must be two bmodels in the same leaf; sort on 1/z
+				fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
+				newzi = surf->d_ziorigin + fv*surf->d_zistepv +
+						fu*surf->d_zistepu;
+				newzibottom = newzi * 0.99;
+
+				testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
+						fu*surf2->d_zistepu;
+
+				if (newzibottom >= testzi)
+				{
+					goto newtop;
+				}
+
+				newzitop = newzi * 1.01;
+				if (newzitop >= testzi)
+				{
+					if (surf->d_zistepu >= surf2->d_zistepu)
+					{
+						goto newtop;
+					}
+				}
+			}
+
+continue_search:
+
+			do
+			{
+				surf2 = surf2->next;
+			} while (surf->key > surf2->key);
+
+			if (surf->key == surf2->key)
+			{
+			// if it's two surfaces on the same plane, the one that's already
+			// active is in front, so keep going unless it's a bmodel
+				if (!surf->insubmodel)
+					goto continue_search;
+
+			// must be two bmodels in the same leaf; sort on 1/z
+				fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
+				newzi = surf->d_ziorigin + fv*surf->d_zistepv +
+						fu*surf->d_zistepu;
+				newzibottom = newzi * 0.99;
+
+				testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
+						fu*surf2->d_zistepu;
+
+				if (newzibottom >= testzi)
+				{
+					goto gotposition;
+				}
+
+				newzitop = newzi * 1.01;
+				if (newzitop >= testzi)
+				{
+					if (surf->d_zistepu >= surf2->d_zistepu)
+					{
+						goto gotposition;
+					}
+				}
+
+				goto continue_search;
+			}
+
+			goto gotposition;
+
+newtop:
+		// emit a span (obscures current top)
+			iu = edge->u >> 20;
+
+			if (iu > surf2->last_u)
+			{
+				span = span_p++;
+				span->u = surf2->last_u;
+				span->count = iu - span->u;
+				span->v = current_iv;
+				span->pnext = surf2->spans;
+				surf2->spans = span;
+			}
+
+			// set last_u on the new span
+			surf->last_u = iu;
+				
+gotposition:
+		// insert before surf2
+			surf->next = surf2;
+			surf->prev = surf2->prev;
+			surf2->prev->next = surf;
+			surf2->prev = surf;
+		}
+	}
+}
+
+
+/*
+==============
+R_GenerateSpans
+==============
+*/
+void R_GenerateSpans (void)
+{
+	edge_t			*edge;
+	surf_t			*surf;
+
+// clear active surfaces to just the background surface
+	surfaces[1].next = surfaces[1].prev = &surfaces[1];
+	surfaces[1].last_u = edge_head_u_shift20;
+
+// generate spans
+	for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
+	{			
+		if (edge->surfs[0])
+		{
+		// it has a left surface, so a surface is going away for this span
+			surf = &surfaces[edge->surfs[0]];
+
+			R_TrailingEdge (surf, edge);
+
+			if (!edge->surfs[1])
+				continue;
+		}
+
+		R_LeadingEdge (edge);
+	}
+
+	R_CleanupSpan ();
+}
+
+#endif	// !id386
+
+
+/*
+==============
+R_GenerateSpansBackward
+==============
+*/
+void R_GenerateSpansBackward (void)
+{
+	edge_t			*edge;
+
+// clear active surfaces to just the background surface
+	surfaces[1].next = surfaces[1].prev = &surfaces[1];
+	surfaces[1].last_u = edge_head_u_shift20;
+
+// generate spans
+	for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
+	{			
+		if (edge->surfs[0])
+			R_TrailingEdge (&surfaces[edge->surfs[0]], edge);
+
+		if (edge->surfs[1])
+			R_LeadingEdgeBackwards (edge);
+	}
+
+	R_CleanupSpan ();
+}
+
+
+/*
+==============
+R_ScanEdges
+
+Input: 
+newedges[] array
+	this has links to edges, which have links to surfaces
+
+Output:
+Each surface has a linked list of its visible spans
+==============
+*/
+void R_ScanEdges (void)
+{
+	int		iv, bottom;
+	byte	basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE];
+	espan_t	*basespan_p;
+	surf_t	*s;
+
+	basespan_p = (espan_t *)
+			((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
+	max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
+
+	span_p = basespan_p;
+
+// clear active edges to just the background edges around the whole screen
+// FIXME: most of this only needs to be set up once
+	edge_head.u = r_refdef.vrect.x << 20;
+	edge_head_u_shift20 = edge_head.u >> 20;
+	edge_head.u_step = 0;
+	edge_head.prev = NULL;
+	edge_head.next = &edge_tail;
+	edge_head.surfs[0] = 0;
+	edge_head.surfs[1] = 1;
+	
+	edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF;
+	edge_tail_u_shift20 = edge_tail.u >> 20;
+	edge_tail.u_step = 0;
+	edge_tail.prev = &edge_head;
+	edge_tail.next = &edge_aftertail;
+	edge_tail.surfs[0] = 1;
+	edge_tail.surfs[1] = 0;
+	
+	edge_aftertail.u = -1;		// force a move
+	edge_aftertail.u_step = 0;
+	edge_aftertail.next = &edge_sentinel;
+	edge_aftertail.prev = &edge_tail;
+
+// FIXME: do we need this now that we clamp x in r_draw.c?
+	edge_sentinel.u = 2000 << 24;		// make sure nothing sorts past this
+	edge_sentinel.prev = &edge_aftertail;
+
+//	
+// process all scan lines
+//
+	bottom = r_refdef.vrectbottom - 1;
+
+	for (iv=r_refdef.vrect.y ; iv<bottom ; iv++)
+	{
+		current_iv = iv;
+		fv = (float)iv;
+
+	// mark that the head (background start) span is pre-included
+		surfaces[1].spanstate = 1;
+
+		if (newedges[iv])
+		{
+			R_InsertNewEdges (newedges[iv], edge_head.next);
+		}
+
+		(*pdrawfunc) ();
+
+	// flush the span list if we can't be sure we have enough spans left for
+	// the next scan
+		if (span_p > max_span_p)
+		{
+			D_DrawSurfaces ();
+
+		// clear the surface span pointers
+			for (s = &surfaces[1] ; s<surface_p ; s++)
+				s->spans = NULL;
+
+			span_p = basespan_p;
+		}
+
+		if (removeedges[iv])
+			R_RemoveEdges (removeedges[iv]);
+
+		if (edge_head.next != &edge_tail)
+			R_StepActiveU (edge_head.next);
+	}
+
+// do the last scan (no need to step or sort or remove on the last scan)
+
+	current_iv = iv;
+	fv = (float)iv;
+
+// mark that the head (background start) span is pre-included
+	surfaces[1].spanstate = 1;
+
+	if (newedges[iv])
+		R_InsertNewEdges (newedges[iv], edge_head.next);
+
+	(*pdrawfunc) ();
+
+// draw whatever's left in the span list
+	D_DrawSurfaces ();
+}
+
+
+/*
+=========================================================================
+
+SURFACE FILLING
+
+=========================================================================
+*/
+
+msurface_t		*pface;
+surfcache_t		*pcurrentcache;
+vec3_t			transformed_modelorg;
+vec3_t			world_transformed_modelorg;
+vec3_t			local_modelorg;
+
+/*
+=============
+D_MipLevelForScale
+=============
+*/
+int D_MipLevelForScale (float scale)
+{
+	int		lmiplevel;
+
+	if (scale >= d_scalemip[0] )
+		lmiplevel = 0;
+	else if (scale >= d_scalemip[1] )
+		lmiplevel = 1;
+	else if (scale >= d_scalemip[2] )
+		lmiplevel = 2;
+	else
+		lmiplevel = 3;
+
+	if (lmiplevel < d_minmip)
+		lmiplevel = d_minmip;
+
+	return lmiplevel;
+}
+
+
+/*
+==============
+D_FlatFillSurface
+
+Simple single color fill with no texture mapping
+==============
+*/
+void D_FlatFillSurface (surf_t *surf, int color)
+{
+	espan_t	*span;
+	byte	*pdest;
+	int		u, u2;
+	
+	for (span=surf->spans ; span ; span=span->pnext)
+	{
+		pdest = (byte *)d_viewbuffer + r_screenwidth*span->v;
+		u = span->u;
+		u2 = span->u + span->count - 1;
+		for ( ; u <= u2 ; u++)
+			pdest[u] = color;
+	}
+}
+
+
+/*
+==============
+D_CalcGradients
+==============
+*/
+void D_CalcGradients (msurface_t *pface)
+{
+	mplane_t	*pplane;
+	float		mipscale;
+	vec3_t		p_temp1;
+	vec3_t		p_saxis, p_taxis;
+	float		t;
+
+	pplane = pface->plane;
+
+	mipscale = 1.0 / (float)(1 << miplevel);
+
+	TransformVector (pface->texinfo->vecs[0], p_saxis);
+	TransformVector (pface->texinfo->vecs[1], p_taxis);
+
+	t = xscaleinv * mipscale;
+	d_sdivzstepu = p_saxis[0] * t;
+	d_tdivzstepu = p_taxis[0] * t;
+
+	t = yscaleinv * mipscale;
+	d_sdivzstepv = -p_saxis[1] * t;
+	d_tdivzstepv = -p_taxis[1] * t;
+
+	d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
+			ycenter * d_sdivzstepv;
+	d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
+			ycenter * d_tdivzstepv;
+
+	VectorScale (transformed_modelorg, mipscale, p_temp1);
+
+	t = 0x10000*mipscale;
+	sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
+			((pface->texturemins[0] << 16) >> miplevel)
+			+ pface->texinfo->vecs[0][3]*t;
+	tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
+			((pface->texturemins[1] << 16) >> miplevel)
+			+ pface->texinfo->vecs[1][3]*t;
+
+	// PGM - changing flow speed for non-warping textures.
+	if (pface->texinfo->flags & SURF_FLOWING)
+	{
+		if(pface->texinfo->flags & SURF_WARP)
+			sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.25) - (int)(r_newrefdef.time * 0.25) ));
+		else
+			sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.77) - (int)(r_newrefdef.time * 0.77) ));
+	}
+	// PGM
+
+//
+// -1 (-epsilon) so we never wander off the edge of the texture
+//
+	bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
+	bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
+}
+
+
+/*
+==============
+D_BackgroundSurf
+
+The grey background filler seen when there is a hole in the map
+==============
+*/
+void D_BackgroundSurf (surf_t *s)
+{
+// set up a gradient for the background surface that places it
+// effectively at infinity distance from the viewpoint
+	d_zistepu = 0;
+	d_zistepv = 0;
+	d_ziorigin = -0.9;
+
+	D_FlatFillSurface (s, (int)sw_clearcolor->value & 0xFF);
+	D_DrawZSpans (s->spans);
+}
+
+/*
+=================
+D_TurbulentSurf
+=================
+*/
+void D_TurbulentSurf (surf_t *s)
+{
+	d_zistepu = s->d_zistepu;
+	d_zistepv = s->d_zistepv;
+	d_ziorigin = s->d_ziorigin;
+
+	pface = s->msurf;
+	miplevel = 0;
+	cacheblock = pface->texinfo->image->pixels[0];
+	cachewidth = 64;
+
+	if (s->insubmodel)
+	{
+	// FIXME: we don't want to do all this for every polygon!
+	// TODO: store once at start of frame
+		currententity = s->entity;	//FIXME: make this passed in to
+									// R_RotateBmodel ()
+		VectorSubtract (r_origin, currententity->origin,
+				local_modelorg);
+		TransformVector (local_modelorg, transformed_modelorg);
+
+		R_RotateBmodel ();	// FIXME: don't mess with the frustum,
+							// make entity passed in
+	}
+
+	D_CalcGradients (pface);
+
+//============
+//PGM
+	// textures that aren't warping are just flowing. Use NonTurbulent8 instead
+	if(!(pface->texinfo->flags & SURF_WARP))
+		NonTurbulent8 (s->spans);
+	else
+		Turbulent8 (s->spans);
+//PGM
+//============
+
+	D_DrawZSpans (s->spans);
+
+	if (s->insubmodel)
+	{
+	//
+	// restore the old drawing state
+	// FIXME: we don't want to do this every time!
+	// TODO: speed up
+	//
+		currententity = NULL;	// &r_worldentity;
+		VectorCopy (world_transformed_modelorg,
+					transformed_modelorg);
+		VectorCopy (base_vpn, vpn);
+		VectorCopy (base_vup, vup);
+		VectorCopy (base_vright, vright);
+		R_TransformFrustum ();
+	}
+}
+
+/*
+==============
+D_SkySurf
+==============
+*/
+void D_SkySurf (surf_t *s)
+{
+	pface = s->msurf;
+	miplevel = 0;
+	if (!pface->texinfo->image)
+		return;
+	cacheblock = pface->texinfo->image->pixels[0];
+	cachewidth = 256;
+
+	d_zistepu = s->d_zistepu;
+	d_zistepv = s->d_zistepv;
+	d_ziorigin = s->d_ziorigin;
+
+	D_CalcGradients (pface);
+
+	D_DrawSpans16 (s->spans);
+
+// set up a gradient for the background surface that places it
+// effectively at infinity distance from the viewpoint
+	d_zistepu = 0;
+	d_zistepv = 0;
+	d_ziorigin = -0.9;
+
+	D_DrawZSpans (s->spans);
+}
+
+/*
+==============
+D_SolidSurf
+
+Normal surface cached, texture mapped surface
+==============
+*/
+void D_SolidSurf (surf_t *s)
+{
+	d_zistepu = s->d_zistepu;
+	d_zistepv = s->d_zistepv;
+	d_ziorigin = s->d_ziorigin;
+
+	if (s->insubmodel)
+	{
+	// FIXME: we don't want to do all this for every polygon!
+	// TODO: store once at start of frame
+		currententity = s->entity;	//FIXME: make this passed in to
+									// R_RotateBmodel ()
+		VectorSubtract (r_origin, currententity->origin, local_modelorg);
+		TransformVector (local_modelorg, transformed_modelorg);
+
+		R_RotateBmodel ();	// FIXME: don't mess with the frustum,
+							// make entity passed in
+	}
+	else
+		currententity = &r_worldentity;
+
+	pface = s->msurf;
+#if 1
+	miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
+#else
+	{
+		float dot;
+		float normal[3];
+
+		if ( s->insubmodel )
+		{
+			VectorCopy( pface->plane->normal, normal );
+//			TransformVector( pface->plane->normal, normal);
+			dot = DotProduct( normal, vpn );
+		}
+		else
+		{
+			VectorCopy( pface->plane->normal, normal );
+			dot = DotProduct( normal, vpn );
+		}
+
+		if ( pface->flags & SURF_PLANEBACK )
+			dot = -dot;
+
+		if ( dot > 0 )
+			printf( "blah" );
+
+		miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
+	}
+#endif
+
+// FIXME: make this passed in to D_CacheSurface
+	pcurrentcache = D_CacheSurface (pface, miplevel);
+
+	cacheblock = (pixel_t *)pcurrentcache->data;
+	cachewidth = pcurrentcache->width;
+
+	D_CalcGradients (pface);
+
+	D_DrawSpans16 (s->spans);
+
+	D_DrawZSpans (s->spans);
+
+	if (s->insubmodel)
+	{
+	//
+	// restore the old drawing state
+	// FIXME: we don't want to do this every time!
+	// TODO: speed up
+	//
+		VectorCopy (world_transformed_modelorg,
+					transformed_modelorg);
+		VectorCopy (base_vpn, vpn);
+		VectorCopy (base_vup, vup);
+		VectorCopy (base_vright, vright);
+		R_TransformFrustum ();
+		currententity = NULL;	//&r_worldentity;
+	}
+}
+
+/*
+=============
+D_DrawflatSurfaces
+
+To allow developers to see the polygon carving of the world
+=============
+*/
+void D_DrawflatSurfaces (void)
+{
+	surf_t			*s;
+
+	for (s = &surfaces[1] ; s<surface_p ; s++)
+	{
+		if (!s->spans)
+			continue;
+
+		d_zistepu = s->d_zistepu;
+		d_zistepv = s->d_zistepv;
+		d_ziorigin = s->d_ziorigin;
+
+		// make a stable color for each surface by taking the low
+		// bits of the msurface pointer
+		D_FlatFillSurface (s, (int)s->msurf & 0xFF);
+		D_DrawZSpans (s->spans);
+	}
+}
+
+/*
+==============
+D_DrawSurfaces
+
+Rasterize all the span lists.  Guaranteed zero overdraw.
+May be called more than once a frame if the surf list overflows (higher res)
+==============
+*/
+void D_DrawSurfaces (void)
+{
+	surf_t			*s;
+
+//	currententity = NULL;	//&r_worldentity;
+	VectorSubtract (r_origin, vec3_origin, modelorg);
+	TransformVector (modelorg, transformed_modelorg);
+	VectorCopy (transformed_modelorg, world_transformed_modelorg);
+
+	if (!sw_drawflat->value)
+	{
+		for (s = &surfaces[1] ; s<surface_p ; s++)
+		{
+			if (!s->spans)
+				continue;
+
+			r_drawnpolycount++;
+
+			if (! (s->flags & (SURF_DRAWSKYBOX|SURF_DRAWBACKGROUND|SURF_DRAWTURB) ) )
+				D_SolidSurf (s);
+			else if (s->flags & SURF_DRAWSKYBOX)
+				D_SkySurf (s);
+			else if (s->flags & SURF_DRAWBACKGROUND)
+				D_BackgroundSurf (s);
+			else if (s->flags & SURF_DRAWTURB)
+				D_TurbulentSurf (s);
+		}
+	}
+	else
+		D_DrawflatSurfaces ();
+
+	currententity = NULL;	//&r_worldentity;
+	VectorSubtract (r_origin, vec3_origin, modelorg);
+	R_TransformFrustum ();
+}
+
--- /dev/null
+++ b/ref/r_image.c
@@ -1,0 +1,617 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#include "r_local.h"
+
+
+#define	MAX_RIMAGES	1024
+image_t		r_images[MAX_RIMAGES];
+int			numr_images;
+
+
+/*
+===============
+R_ImageList_f
+===============
+*/
+void	R_ImageList_f (void)
+{
+	int		i;
+	image_t	*image;
+	int		texels;
+
+	ri.Con_Printf (PRINT_ALL, "------------------\n");
+	texels = 0;
+
+	for (i=0, image=r_images ; i<numr_images ; i++, image++)
+	{
+		if (image->registration_sequence <= 0)
+			continue;
+		texels += image->width*image->height;
+		switch (image->type)
+		{
+		case it_skin:
+			ri.Con_Printf (PRINT_ALL, "M");
+			break;
+		case it_sprite:
+			ri.Con_Printf (PRINT_ALL, "S");
+			break;
+		case it_wall:
+			ri.Con_Printf (PRINT_ALL, "W");
+			break;
+		case it_pic:
+			ri.Con_Printf (PRINT_ALL, "P");
+			break;
+		default:
+			ri.Con_Printf (PRINT_ALL, " ");
+			break;
+		}
+
+		ri.Con_Printf (PRINT_ALL,  " %3i %3i : %s\n",
+			image->width, image->height, image->name);
+	}
+	ri.Con_Printf (PRINT_ALL, "Total texel count: %i\n", texels);
+}
+
+
+/*
+=================================================================
+
+PCX LOADING
+
+=================================================================
+*/
+
+/*
+==============
+LoadPCX
+==============
+*/
+void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
+{
+	byte	*raw;
+	pcx_t	*pcx;
+	int		x, y;
+	int		len;
+	int		dataByte, runLength;
+	byte	*out, *pix;
+
+	*pic = NULL;
+
+	//
+	// load the file
+	//
+	len = ri.FS_LoadFile (filename, (void **)&raw);
+	if (!raw)
+	{
+		ri.Con_Printf (PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
+		return;
+	}
+
+	//
+	// parse the PCX file
+	//
+	pcx = (pcx_t *)raw;
+
+    pcx->xmin = LittleShort(pcx->xmin);
+    pcx->ymin = LittleShort(pcx->ymin);
+    pcx->xmax = LittleShort(pcx->xmax);
+    pcx->ymax = LittleShort(pcx->ymax);
+    pcx->hres = LittleShort(pcx->hres);
+    pcx->vres = LittleShort(pcx->vres);
+    pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
+    pcx->palette_type = LittleShort(pcx->palette_type);
+
+	raw = &pcx->data;
+
+	if (pcx->manufacturer != 0x0a
+		|| pcx->version != 5
+		|| pcx->encoding != 1
+		|| pcx->bits_per_pixel != 8
+		|| pcx->xmax >= 640
+		|| pcx->ymax >= 480)
+	{
+		ri.Con_Printf (PRINT_ALL, "Bad pcx file %s\n", filename);
+		return;
+	}
+
+	out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
+
+	*pic = out;
+
+	pix = out;
+
+	if (palette)
+	{
+		*palette = malloc(768);
+		memcpy (*palette, (byte *)pcx + len - 768, 768);
+	}
+
+	if (width)
+		*width = pcx->xmax+1;
+	if (height)
+		*height = pcx->ymax+1;
+
+	for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
+	{
+		for (x=0 ; x<=pcx->xmax ; )
+		{
+			dataByte = *raw++;
+
+			if((dataByte & 0xC0) == 0xC0)
+			{
+				runLength = dataByte & 0x3F;
+				dataByte = *raw++;
+			}
+			else
+				runLength = 1;
+
+			while(runLength-- > 0)
+				pix[x++] = dataByte;
+		}
+
+	}
+
+	if ( raw - (byte *)pcx > len)
+	{
+		ri.Con_Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename);
+		free (*pic);
+		*pic = NULL;
+	}
+
+	ri.FS_FreeFile (pcx);
+}
+
+/*
+=========================================================
+
+TARGA LOADING
+
+=========================================================
+*/
+
+typedef struct _TargaHeader {
+	unsigned char 	id_length, colormap_type, image_type;
+	unsigned short	colormap_index, colormap_length;
+	unsigned char	colormap_size;
+	unsigned short	x_origin, y_origin, width, height;
+	unsigned char	pixel_size, attributes;
+} TargaHeader;
+
+
+/*
+=============
+LoadTGA
+=============
+*/
+void LoadTGA (char *name, byte **pic, int *width, int *height)
+{
+	int		columns, rows, numPixels;
+	byte	*pixbuf;
+	int		row, column;
+	byte	*buf_p;
+	byte	*buffer;
+	int		length;
+	TargaHeader		targa_header;
+	byte			*targa_rgba;
+
+	*pic = NULL;
+
+	//
+	// load the file
+	//
+	length = ri.FS_LoadFile (name, (void **)&buffer);
+	if (!buffer)
+	{
+		ri.Con_Printf (PRINT_DEVELOPER, "Bad tga file %s\n", name);
+		return;
+	}
+
+	buf_p = buffer;
+
+	targa_header.id_length = *buf_p++;
+	targa_header.colormap_type = *buf_p++;
+	targa_header.image_type = *buf_p++;
+	
+	targa_header.colormap_index = LittleShort ( *((short *)buf_p) );
+	buf_p+=2;
+	targa_header.colormap_length = LittleShort ( *((short *)buf_p) );
+	buf_p+=2;
+	targa_header.colormap_size = *buf_p++;
+	targa_header.x_origin = LittleShort ( *((short *)buf_p) );
+	buf_p+=2;
+	targa_header.y_origin = LittleShort ( *((short *)buf_p) );
+	buf_p+=2;
+	targa_header.width = LittleShort ( *((short *)buf_p) );
+	buf_p+=2;
+	targa_header.height = LittleShort ( *((short *)buf_p) );
+	buf_p+=2;
+	targa_header.pixel_size = *buf_p++;
+	targa_header.attributes = *buf_p++;
+
+	if (targa_header.image_type!=2 
+		&& targa_header.image_type!=10) 
+		ri.Sys_Error (ERR_DROP, "LoadTGA: Only type 2 and 10 targa RGB images supported\n");
+
+	if (targa_header.colormap_type !=0 
+		|| (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
+		ri.Sys_Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
+
+	columns = targa_header.width;
+	rows = targa_header.height;
+	numPixels = columns * rows;
+
+	if (width)
+		*width = columns;
+	if (height)
+		*height = rows;
+
+	targa_rgba = malloc (numPixels*4);
+	*pic = targa_rgba;
+
+	if (targa_header.id_length != 0)
+		buf_p += targa_header.id_length;  // skip TARGA image comment
+	
+	if (targa_header.image_type==2) {  // Uncompressed, RGB images
+		for(row=rows-1; row>=0; row--) {
+			pixbuf = targa_rgba + row*columns*4;
+			for(column=0; column<columns; column++) {
+				unsigned char red,green,blue,alphabyte;
+				switch (targa_header.pixel_size) {
+					case 24:
+							
+							blue = *buf_p++;
+							green = *buf_p++;
+							red = *buf_p++;
+							*pixbuf++ = red;
+							*pixbuf++ = green;
+							*pixbuf++ = blue;
+							*pixbuf++ = 255;
+							break;
+					case 32:
+							blue = *buf_p++;
+							green = *buf_p++;
+							red = *buf_p++;
+							alphabyte = *buf_p++;
+							*pixbuf++ = red;
+							*pixbuf++ = green;
+							*pixbuf++ = blue;
+							*pixbuf++ = alphabyte;
+							break;
+				}
+			}
+		}
+	}
+	else if (targa_header.image_type==10) {   // Runlength encoded RGB images
+		unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
+		for(row=rows-1; row>=0; row--) {
+			pixbuf = targa_rgba + row*columns*4;
+			for(column=0; column<columns; ) {
+				packetHeader= *buf_p++;
+				packetSize = 1 + (packetHeader & 0x7f);
+				if (packetHeader & 0x80) {        // run-length packet
+					switch (targa_header.pixel_size) {
+						case 24:
+								blue = *buf_p++;
+								green = *buf_p++;
+								red = *buf_p++;
+								alphabyte = 255;
+								break;
+						case 32:
+								blue = *buf_p++;
+								green = *buf_p++;
+								red = *buf_p++;
+								alphabyte = *buf_p++;
+								break;
+					}
+	
+					for(j=0;j<packetSize;j++) {
+						*pixbuf++=red;
+						*pixbuf++=green;
+						*pixbuf++=blue;
+						*pixbuf++=alphabyte;
+						column++;
+						if (column==columns) { // run spans across rows
+							column=0;
+							if (row>0)
+								row--;
+							else
+								goto breakOut;
+							pixbuf = targa_rgba + row*columns*4;
+						}
+					}
+				}
+				else {                            // non run-length packet
+					for(j=0;j<packetSize;j++) {
+						switch (targa_header.pixel_size) {
+							case 24:
+									blue = *buf_p++;
+									green = *buf_p++;
+									red = *buf_p++;
+									*pixbuf++ = red;
+									*pixbuf++ = green;
+									*pixbuf++ = blue;
+									*pixbuf++ = 255;
+									break;
+							case 32:
+									blue = *buf_p++;
+									green = *buf_p++;
+									red = *buf_p++;
+									alphabyte = *buf_p++;
+									*pixbuf++ = red;
+									*pixbuf++ = green;
+									*pixbuf++ = blue;
+									*pixbuf++ = alphabyte;
+									break;
+						}
+						column++;
+						if (column==columns) { // pixel packet run spans across rows
+							column=0;
+							if (row>0)
+								row--;
+							else
+								goto breakOut;
+							pixbuf = targa_rgba + row*columns*4;
+						}						
+					}
+				}
+			}
+			breakOut:;
+		}
+	}
+
+	ri.FS_FreeFile (buffer);
+}
+
+
+//=======================================================
+
+image_t *R_FindFreeImage (void)
+{
+	image_t		*image;
+	int			i;
+
+	// find a free image_t
+	for (i=0, image=r_images ; i<numr_images ; i++,image++)
+	{
+		if (!image->registration_sequence)
+			break;
+	}
+	if (i == numr_images)
+	{
+		if (numr_images == MAX_RIMAGES)
+			ri.Sys_Error (ERR_DROP, "MAX_RIMAGES");
+		numr_images++;
+	}
+	image = &r_images[i];
+
+	return image;
+}
+
+/*
+================
+GL_LoadPic
+
+================
+*/
+image_t *GL_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type)
+{
+	image_t		*image;
+	int			i, c, b;
+
+	image = R_FindFreeImage ();
+	if (strlen(name) >= sizeof(image->name))
+		ri.Sys_Error (ERR_DROP, "Draw_LoadPic: \"%s\" is too long", name);
+	strcpy (image->name, name);
+	image->registration_sequence = registration_sequence;
+
+	image->width = width;
+	image->height = height;
+	image->type = type;
+
+	c = width*height;
+	image->pixels[0] = malloc (c);
+	image->transparent = false;
+	for (i=0 ; i<c ; i++)
+	{
+		b = pic[i];
+		if (b == 255)
+			image->transparent = true;
+		image->pixels[0][i] = b;
+	}
+
+	return image;
+}
+
+/*
+================
+R_LoadWal
+================
+*/
+image_t *R_LoadWal (char *name)
+{
+	miptex_t	*mt;
+	int			ofs;
+	image_t		*image;
+	int			size;
+
+	ri.FS_LoadFile (name, (void **)&mt);
+	if (!mt)
+	{
+		ri.Con_Printf (PRINT_ALL, "R_LoadWal: can't load %s\n", name);
+		return r_notexture_mip;
+	}
+
+	image = R_FindFreeImage ();
+	strcpy (image->name, name);
+	image->width = LittleLong (mt->width);
+	image->height = LittleLong (mt->height);
+	image->type = it_wall;
+	image->registration_sequence = registration_sequence;
+
+	size = image->width*image->height * (256+64+16+4)/256;
+	image->pixels[0] = malloc (size);
+	image->pixels[1] = image->pixels[0] + image->width*image->height;
+	image->pixels[2] = image->pixels[1] + image->width*image->height/4;
+	image->pixels[3] = image->pixels[2] + image->width*image->height/16;
+
+	ofs = LittleLong (mt->offsets[0]);
+	memcpy ( image->pixels[0], (byte *)mt + ofs, size);
+
+	ri.FS_FreeFile ((void *)mt);
+
+	return image;
+}
+
+
+/*
+===============
+R_FindImage
+
+Finds or loads the given image
+===============
+*/
+image_t	*R_FindImage (char *name, imagetype_t type)
+{
+	image_t	*image;
+	int		i, len;
+	byte	*pic, *palette;
+	int		width, height;
+
+	if (!name)
+		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: NULL name");
+	len = strlen(name);
+	if (len<5)
+		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: bad name: %s", name);
+
+	// look for it
+	for (i=0, image=r_images ; i<numr_images ; i++,image++)
+	{
+		if (!strcmp(name, image->name))
+		{
+			image->registration_sequence = registration_sequence;
+			return image;
+		}
+	}
+
+	//
+	// load the pic from disk
+	//
+	pic = NULL;
+	palette = NULL;
+	if (!strcmp(name+len-4, ".pcx"))
+	{
+		LoadPCX (name, &pic, &palette, &width, &height);
+		if (!pic)
+			return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s", name);
+		image = GL_LoadPic (name, pic, width, height, type);
+	}
+	else if (!strcmp(name+len-4, ".wal"))
+	{
+		image = R_LoadWal (name);
+	}
+	else if (!strcmp(name+len-4, ".tga"))
+		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s in software renderer", name);
+	else
+		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: bad extension on: %s", name);
+
+	if (pic)
+		free(pic);
+	if (palette)
+		free(palette);
+
+	return image;
+}
+
+
+
+/*
+===============
+R_RegisterSkin
+===============
+*/
+struct image_s *R_RegisterSkin (char *name)
+{
+	return R_FindImage (name, it_skin);
+}
+
+
+/*
+================
+R_FreeUnusedImages
+
+Any image that was not touched on this registration sequence
+will be freed.
+================
+*/
+void R_FreeUnusedImages (void)
+{
+	int		i;
+	image_t	*image;
+
+	for (i=0, image=r_images ; i<numr_images ; i++, image++)
+	{
+		if (image->registration_sequence == registration_sequence)
+		{
+			Com_PageInMemory ((byte *)image->pixels[0], image->width*image->height);
+			continue;		// used this sequence
+		}
+		if (!image->registration_sequence)
+			continue;		// free texture
+		if (image->type == it_pic)
+			continue;		// don't free pics
+		// free it
+		free (image->pixels[0]);	// the other mip levels just follow
+		memset (image, 0, sizeof(*image));
+	}
+}
+
+
+
+/*
+===============
+R_InitImages
+===============
+*/
+void	R_InitImages (void)
+{
+	registration_sequence = 1;
+}
+
+/*
+===============
+R_ShutdownImages
+===============
+*/
+void	R_ShutdownImages (void)
+{
+	int		i;
+	image_t	*image;
+
+	for (i=0, image=r_images ; i<numr_images ; i++, image++)
+	{
+		if (!image->registration_sequence)
+			continue;		// free texture
+		// free it
+		free (image->pixels[0]);	// the other mip levels just follow
+		memset (image, 0, sizeof(*image));
+	}
+}
+
--- /dev/null
+++ b/ref/r_light.c
@@ -1,0 +1,442 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_light.c
+
+#include "r_local.h"
+
+int	r_dlightframecount;
+
+
+/*
+=============================================================================
+
+DYNAMIC LIGHTS
+
+=============================================================================
+*/
+
+/*
+=============
+R_MarkLights
+=============
+*/
+void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
+{
+	mplane_t	*splitplane;
+	float		dist;
+	msurface_t	*surf;
+	int			i;
+	
+	if (node->contents != -1)
+		return;
+
+	splitplane = node->plane;
+	dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
+	
+//=====
+//PGM
+	i=light->intensity;
+	if(i<0)
+		i=-i;
+//PGM
+//=====
+
+	if (dist > i)	// PGM (dist > light->intensity)
+	{
+		R_MarkLights (light, bit, node->children[0]);
+		return;
+	}
+	if (dist < -i)	// PGM (dist < -light->intensity)
+	{
+		R_MarkLights (light, bit, node->children[1]);
+		return;
+	}
+		
+// mark the polygons
+	surf = r_worldmodel->surfaces + node->firstsurface;
+	for (i=0 ; i<node->numsurfaces ; i++, surf++)
+	{
+		if (surf->dlightframe != r_dlightframecount)
+		{
+			surf->dlightbits = 0;
+			surf->dlightframe = r_dlightframecount;
+		}
+		surf->dlightbits |= bit;
+	}
+
+	R_MarkLights (light, bit, node->children[0]);
+	R_MarkLights (light, bit, node->children[1]);
+}
+
+
+/*
+=============
+R_PushDlights
+=============
+*/
+void R_PushDlights (model_t *model)
+{
+	int		i;
+	dlight_t	*l;
+
+	r_dlightframecount = r_framecount;
+	for (i=0, l = r_newrefdef.dlights ; i<r_newrefdef.num_dlights ; i++, l++)
+	{
+		R_MarkLights ( l, 1<<i, 
+			model->nodes + model->firstnode);
+	}
+}
+
+
+/*
+=============================================================================
+
+LIGHT SAMPLING
+
+=============================================================================
+*/
+
+vec3_t	pointcolor;
+mplane_t		*lightplane;		// used as shadow plane
+vec3_t			lightspot;
+
+int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
+{
+	float		front, back, frac;
+	int			side;
+	mplane_t	*plane;
+	vec3_t		mid;
+	msurface_t	*surf;
+	int			s, t, ds, dt;
+	int			i;
+	mtexinfo_t	*tex;
+	byte		*lightmap;
+	float		*scales;
+	int			maps;
+	float		samp;
+	int			r;
+
+	if (node->contents != -1)
+		return -1;		// didn't hit anything
+	
+// calculate mid point
+
+// FIXME: optimize for axial
+	plane = node->plane;
+	front = DotProduct (start, plane->normal) - plane->dist;
+	back = DotProduct (end, plane->normal) - plane->dist;
+	side = front < 0;
+	
+	if ( (back < 0) == side)
+		return RecursiveLightPoint (node->children[side], start, end);
+	
+	frac = front / (front-back);
+	mid[0] = start[0] + (end[0] - start[0])*frac;
+	mid[1] = start[1] + (end[1] - start[1])*frac;
+	mid[2] = start[2] + (end[2] - start[2])*frac;
+	if (plane->type < 3)	// axial planes
+		mid[plane->type] = plane->dist;
+
+// go down front side	
+	r = RecursiveLightPoint (node->children[side], start, mid);
+	if (r >= 0)
+		return r;		// hit something
+		
+	if ( (back < 0) == side )
+		return -1;		// didn't hit anuthing
+		
+// check for impact on this node
+	VectorCopy (mid, lightspot);
+	lightplane = plane;
+
+	surf = r_worldmodel->surfaces + node->firstsurface;
+	for (i=0 ; i<node->numsurfaces ; i++, surf++)
+	{
+		if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY)) 
+			continue;	// no lightmaps
+
+		tex = surf->texinfo;
+		
+		s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
+		t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];
+		if (s < surf->texturemins[0] ||
+		t < surf->texturemins[1])
+			continue;
+		
+		ds = s - surf->texturemins[0];
+		dt = t - surf->texturemins[1];
+		
+		if ( ds > surf->extents[0] || dt > surf->extents[1] )
+			continue;
+
+		if (!surf->samples)
+			return 0;
+
+		ds >>= 4;
+		dt >>= 4;
+
+		lightmap = surf->samples;
+		VectorCopy (vec3_origin, pointcolor);
+		if (lightmap)
+		{
+			lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
+
+			for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
+					maps++)
+			{
+				samp = *lightmap * /* 0.5 * */ (1.0/255);	// adjust for gl scale
+				scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb;
+				VectorMA (pointcolor, samp, scales, pointcolor);
+				lightmap += ((surf->extents[0]>>4)+1) *
+						((surf->extents[1]>>4)+1);
+			}
+		}
+		
+		return 1;
+	}
+
+// go down back side
+	return RecursiveLightPoint (node->children[!side], mid, end);
+}
+
+/*
+===============
+R_LightPoint
+===============
+*/
+void R_LightPoint (vec3_t p, vec3_t color)
+{
+	vec3_t		end;
+	float		r;
+	int			lnum;
+	dlight_t	*dl;
+	float		light;
+	vec3_t		dist;
+	float		add;
+	
+	if (!r_worldmodel->lightdata)
+	{
+		color[0] = color[1] = color[2] = 1.0;
+		return;
+	}
+	
+	end[0] = p[0];
+	end[1] = p[1];
+	end[2] = p[2] - 2048;
+	
+	r = RecursiveLightPoint (r_worldmodel->nodes, p, end);
+	
+	if (r == -1)
+	{
+		VectorCopy (vec3_origin, color);
+	}
+	else
+	{
+		VectorCopy (pointcolor, color);
+	}
+
+	//
+	// add dynamic lights
+	//
+	light = 0;
+	for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
+	{
+		dl = &r_newrefdef.dlights[lnum];
+		VectorSubtract (currententity->origin,
+						dl->origin,
+						dist);
+		add = dl->intensity - VectorLength(dist);
+		add *= (1.0/256);
+		if (add > 0)
+		{
+			VectorMA (color, add, dl->color, color);
+		}
+	}
+}
+
+//===================================================================
+
+
+unsigned		blocklights[1024];	// allow some very large lightmaps
+
+/*
+===============
+R_AddDynamicLights
+===============
+*/
+void R_AddDynamicLights (void)
+{
+	msurface_t *surf;
+	int			lnum;
+	int			sd, td;
+	float		dist, rad, minlight;
+	vec3_t		impact, local;
+	int			s, t;
+	int			i;
+	int			smax, tmax;
+	mtexinfo_t	*tex;
+	dlight_t	*dl;
+	int			negativeLight;	//PGM
+
+	surf = r_drawsurf.surf;
+	smax = (surf->extents[0]>>4)+1;
+	tmax = (surf->extents[1]>>4)+1;
+	tex = surf->texinfo;
+
+	for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
+	{
+		if ( !(surf->dlightbits & (1<<lnum) ) )
+			continue;		// not lit by this light
+
+		dl = &r_newrefdef.dlights[lnum];
+		rad = dl->intensity;
+
+//=====
+//PGM
+		negativeLight = 0;
+		if(rad < 0)
+		{
+			negativeLight = 1;
+			rad = -rad;
+		}
+//PGM
+//=====
+
+		dist = DotProduct (dl->origin, surf->plane->normal) -
+				surf->plane->dist;
+		rad -= fabs(dist);
+		minlight = 32;		// dl->minlight;
+		if (rad < minlight)
+			continue;
+		minlight = rad - minlight;
+
+		for (i=0 ; i<3 ; i++)
+		{
+			impact[i] = dl->origin[i] -
+					surf->plane->normal[i]*dist;
+		}
+
+		local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
+		local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
+
+		local[0] -= surf->texturemins[0];
+		local[1] -= surf->texturemins[1];
+		
+		for (t = 0 ; t<tmax ; t++)
+		{
+			td = local[1] - t*16;
+			if (td < 0)
+				td = -td;
+			for (s=0 ; s<smax ; s++)
+			{
+				sd = local[0] - s*16;
+				if (sd < 0)
+					sd = -sd;
+				if (sd > td)
+					dist = sd + (td>>1);
+				else
+					dist = td + (sd>>1);
+//====
+//PGM
+				if(!negativeLight)
+				{
+					if (dist < minlight)
+						blocklights[t*smax + s] += (rad - dist)*256;
+				}
+				else
+				{
+					if (dist < minlight)
+						blocklights[t*smax + s] -= (rad - dist)*256;
+					if(blocklights[t*smax + s] < minlight)
+						blocklights[t*smax + s] = minlight;
+				}
+//PGM
+//====
+			}
+		}
+	}
+}
+
+/*
+===============
+R_BuildLightMap
+
+Combine and scale multiple lightmaps into the 8.8 format in blocklights
+===============
+*/
+void R_BuildLightMap (void)
+{
+	int			smax, tmax;
+	int			t;
+	int			i, size;
+	byte		*lightmap;
+	unsigned	scale;
+	int			maps;
+	msurface_t	*surf;
+
+	surf = r_drawsurf.surf;
+
+	smax = (surf->extents[0]>>4)+1;
+	tmax = (surf->extents[1]>>4)+1;
+	size = smax*tmax;
+
+	if (r_fullbright->value || !r_worldmodel->lightdata)
+	{
+		for (i=0 ; i<size ; i++)
+			blocklights[i] = 0;
+		return;
+	}
+
+// clear to no light
+	for (i=0 ; i<size ; i++)
+		blocklights[i] = 0;
+
+
+// add all the lightmaps
+	lightmap = surf->samples;
+	if (lightmap)
+		for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
+			 maps++)
+		{
+			scale = r_drawsurf.lightadj[maps];	// 8.8 fraction		
+			for (i=0 ; i<size ; i++)
+				blocklights[i] += lightmap[i] * scale;
+			lightmap += size;	// skip to next lightmap
+		}
+
+// add all the dynamic lights
+	if (surf->dlightframe == r_framecount)
+		R_AddDynamicLights ();
+
+// bound, invert, and shift
+	for (i=0 ; i<size ; i++)
+	{
+		t = (int)blocklights[i];
+		if (t < 0)
+			t = 0;
+		t = (255*256 - t) >> (8 - VID_CBITS);
+
+		if (t < (1 << 6))
+			t = (1 << 6);
+
+		blocklights[i] = t;
+	}
+}
+
--- /dev/null
+++ b/ref/r_local.h
@@ -1,0 +1,849 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+  
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <stdarg.h>
+
+#include "../client/ref.h"
+
+#define REF_VERSION     "SOFT 0.01"
+
+// up / down
+#define PITCH   0
+
+// left / right
+#define YAW             1
+
+// fall over
+#define ROLL    2
+
+
+/*
+
+  skins will be outline flood filled and mip mapped
+  pics and sprites with alpha will be outline flood filled
+  pic won't be mip mapped
+
+  model skin
+  sprite frame
+  wall texture
+  pic
+
+*/
+
+typedef enum 
+{
+	it_skin,
+	it_sprite,
+	it_wall,
+	it_pic,
+	it_sky
+} imagetype_t;
+
+typedef struct image_s
+{
+	char    name[MAX_QPATH];        // game path, including extension
+	imagetype_t     type;
+	int             width, height;
+	qboolean        transparent;    // true if any 255 pixels in image
+	int             registration_sequence;  // 0 = free
+	byte		*pixels[4];				// mip levels
+} image_t;
+
+
+//===================================================================
+
+typedef unsigned char pixel_t;
+
+typedef struct vrect_s
+{
+	int                             x,y,width,height;
+	struct vrect_s  *pnext;
+} vrect_t;
+
+typedef struct
+{
+	pixel_t                 *buffer;                // invisible buffer
+	pixel_t                 *colormap;              // 256 * VID_GRADES size
+	pixel_t                 *alphamap;              // 256 * 256 translucency map
+	int                             rowbytes;               // may be > width if displayed in a window
+									// can be negative for stupid dibs
+	int						width;          
+	int						height;
+} viddef_t;
+
+typedef enum
+{
+	rserr_ok,
+
+	rserr_invalid_fullscreen,
+	rserr_invalid_mode,
+
+	rserr_unknown
+} rserr_t;
+
+extern viddef_t vid;
+
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+typedef struct
+{
+	vrect_t         vrect;                          // subwindow in video for refresh
+									// FIXME: not need vrect next field here?
+	vrect_t         aliasvrect;                     // scaled Alias version
+	int                     vrectright, vrectbottom;        // right & bottom screen coords
+	int                     aliasvrectright, aliasvrectbottom;      // scaled Alias versions
+	float           vrectrightedge;                 // rightmost right edge we care about,
+										//  for use in edge list
+	float           fvrectx, fvrecty;               // for floating-point compares
+	float           fvrectx_adj, fvrecty_adj; // left and top edges, for clamping
+	int                     vrect_x_adj_shift20;    // (vrect.x + 0.5 - epsilon) << 20
+	int                     vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20
+	float           fvrectright_adj, fvrectbottom_adj;
+										// right and bottom edges, for clamping
+	float           fvrectright;                    // rightmost edge, for Alias clamping
+	float           fvrectbottom;                   // bottommost edge, for Alias clamping
+	float           horizontalFieldOfView;  // at Z = 1.0, this many X is visible 
+										// 2.0 = 90 degrees
+	float           xOrigin;                        // should probably always be 0.5
+	float           yOrigin;                        // between be around 0.3 to 0.5
+
+	vec3_t          vieworg;
+	vec3_t          viewangles;
+	
+	int                     ambientlight;
+} oldrefdef_t;
+
+extern oldrefdef_t      r_refdef;
+
+#include "r_model.h"
+
+#define CACHE_SIZE      32
+
+/*
+====================================================
+
+  CONSTANTS
+
+====================================================
+*/
+
+#define VID_CBITS       6
+#define VID_GRADES      (1 << VID_CBITS)
+
+
+// r_shared.h: general refresh-related stuff shared between the refresh and the
+// driver
+
+
+#define MAXVERTS        64              // max points in a surface polygon
+#define MAXWORKINGVERTS (MAXVERTS+4)    // max points in an intermediate
+										//  polygon (while processing)
+// !!! if this is changed, it must be changed in d_ifacea.h too !!!
+#define MAXHEIGHT       1200
+#define MAXWIDTH        1600
+
+#define INFINITE_DISTANCE       0x10000         // distance that's always guaranteed to
+										//  be farther away than anything in
+										//  the scene
+
+
+// d_iface.h: interface header file for rasterization driver modules
+
+#define WARP_WIDTH              320
+#define WARP_HEIGHT             240
+
+#define MAX_LBM_HEIGHT  480
+
+
+#define PARTICLE_Z_CLIP 8.0
+
+// !!! must be kept the same as in quakeasm.h !!!
+#define TRANSPARENT_COLOR       0xFF
+
+
+// !!! if this is changed, it must be changed in d_ifacea.h too !!!
+#define TURB_TEX_SIZE   64              // base turbulent texture size
+
+// !!! if this is changed, it must be changed in d_ifacea.h too !!!
+#define CYCLE                   128             // turbulent cycle size
+
+#define SCANBUFFERPAD           0x1000
+
+#define DS_SPAN_LIST_END        -128
+
+#define NUMSTACKEDGES           2000
+#define MINEDGES                        NUMSTACKEDGES
+#define NUMSTACKSURFACES        1000
+#define MINSURFACES                     NUMSTACKSURFACES
+#define MAXSPANS                        3000
+
+// flags in finalvert_t.flags
+#define ALIAS_LEFT_CLIP                         0x0001
+#define ALIAS_TOP_CLIP                          0x0002
+#define ALIAS_RIGHT_CLIP                        0x0004
+#define ALIAS_BOTTOM_CLIP                       0x0008
+#define ALIAS_Z_CLIP                            0x0010
+#define ALIAS_XY_CLIP_MASK                      0x000F
+
+#define SURFCACHE_SIZE_AT_320X240    1024*768
+
+#define BMODEL_FULLY_CLIPPED    0x10 // value returned by R_BmodelCheckBBox ()
+									 //  if bbox is trivially rejected
+
+#define XCENTERING      (1.0 / 2.0)
+#define YCENTERING      (1.0 / 2.0)
+
+#define CLIP_EPSILON            0.001
+
+#define BACKFACE_EPSILON        0.01
+
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+#define NEAR_CLIP       0.01
+
+
+#define MAXALIASVERTS           2000    // TODO: tune this
+#define ALIAS_Z_CLIP_PLANE      4
+
+// turbulence stuff
+
+#define AMP             8*0x10000
+#define AMP2    3
+#define SPEED   20
+
+
+/*
+====================================================
+
+TYPES
+
+====================================================
+*/
+
+typedef struct
+{
+	float   u, v;
+	float   s, t;
+	float   zi;
+} emitpoint_t;
+
+/*
+** if you change this structure be sure to change the #defines
+** listed after it!
+*/
+#define SMALL_FINALVERT 0
+
+#if SMALL_FINALVERT
+
+typedef struct finalvert_s {
+	short           u, v, s, t;
+	int             l;
+	int             zi;
+	int             flags;
+	float   xyz[3];         // eye space
+} finalvert_t;
+
+#define FINALVERT_V0     0
+#define FINALVERT_V1     2
+#define FINALVERT_V2     4
+#define FINALVERT_V3     6
+#define FINALVERT_V4     8
+#define FINALVERT_V5    12
+#define FINALVERT_FLAGS 16
+#define FINALVERT_X     20
+#define FINALVERT_Y     24
+#define FINALVERT_Z     28
+#define FINALVERT_SIZE  32
+
+#else
+
+typedef struct finalvert_s {
+	int             u, v, s, t;
+	int             l;
+	int             zi;
+	int             flags;
+	float   xyz[3];         // eye space
+} finalvert_t;
+
+#define FINALVERT_V0     0
+#define FINALVERT_V1     4
+#define FINALVERT_V2     8
+#define FINALVERT_V3    12
+#define FINALVERT_V4    16
+#define FINALVERT_V5    20
+#define FINALVERT_FLAGS 24
+#define FINALVERT_X     28
+#define FINALVERT_Y     32
+#define FINALVERT_Z     36
+#define FINALVERT_SIZE  40
+
+#endif
+
+typedef struct
+{
+	void                            *pskin;
+	int                                     pskindesc;
+	int                                     skinwidth;
+	int                                     skinheight;
+	dtriangle_t                     *ptriangles;
+	finalvert_t                     *pfinalverts;
+	int                                     numtriangles;
+	int                                     drawtype;
+	int                                     seamfixupX16;
+	qboolean                        do_vis_thresh;
+	int                                     vis_thresh;
+} affinetridesc_t;
+
+typedef struct
+{
+	byte            *surfdat;       // destination for generated surface
+	int                     rowbytes;       // destination logical width in bytes
+	msurface_t      *surf;          // description for surface to generate
+	fixed8_t        lightadj[MAXLIGHTMAPS];
+							// adjust for lightmap levels for dynamic lighting
+	image_t			*image;
+	int                     surfmip;        // mipmapped ratio of surface texels / world pixels
+	int                     surfwidth;      // in mipmapped texels
+	int                     surfheight;     // in mipmapped texels
+} drawsurf_t;
+
+
+
+typedef struct {
+	int                     ambientlight;
+	int                     shadelight;
+	float           *plightvec;
+} alight_t;
+
+// clipped bmodel edges
+
+typedef struct bedge_s
+{
+	mvertex_t               *v[2];
+	struct bedge_s  *pnext;
+} bedge_t;
+
+
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+typedef struct clipplane_s
+{
+	vec3_t          normal;
+	float           dist;
+	struct          clipplane_s     *next;
+	byte            leftedge;
+	byte            rightedge;
+	byte            reserved[2];
+} clipplane_t;
+
+
+typedef struct surfcache_s
+{
+	struct surfcache_s      *next;
+	struct surfcache_s      **owner;                // NULL is an empty chunk of memory
+	int                                     lightadj[MAXLIGHTMAPS]; // checked for strobe flush
+	int                                     dlight;
+	int                                     size;           // including header
+	unsigned                        width;
+	unsigned                        height;         // DEBUG only needed for debug
+	float                           mipscale;
+	image_t							*image;
+	byte                            data[4];        // width*height elements
+} surfcache_t;
+
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+typedef struct espan_s
+{
+	int                             u, v, count;
+	struct espan_s  *pnext;
+} espan_t;
+
+// used by the polygon drawer (R_POLY.C) and sprite setup code (R_SPRITE.C)
+typedef struct
+{
+	int                     nump;
+	emitpoint_t     *pverts;
+	byte            *pixels;                        // image
+	int                     pixel_width;            // image width
+	int         pixel_height;       // image height
+	vec3_t          vup, vright, vpn;       // in worldspace, for plane eq
+	float       dist;
+	float       s_offset, t_offset;
+	float       viewer_position[3];
+	void       (*drawspanlet)( void );
+	int         stipple_parity;
+} polydesc_t;
+
+// FIXME: compress, make a union if that will help
+// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte
+typedef struct surf_s
+{
+	struct surf_s   *next;                  // active surface stack in r_edge.c
+	struct surf_s   *prev;                  // used in r_edge.c for active surf stack
+	struct espan_s  *spans;                 // pointer to linked list of spans to draw
+	int                     key;                            // sorting key (BSP order)
+	int                     last_u;                         // set during tracing
+	int                     spanstate;                      // 0 = not in span
+									// 1 = in span
+									// -1 = in inverted span (end before
+									//  start)
+	int                     flags;                          // currentface flags
+	msurface_t      *msurf;
+	entity_t        *entity;
+	float           nearzi;                         // nearest 1/z on surface, for mipmapping
+	qboolean        insubmodel;
+	float           d_ziorigin, d_zistepu, d_zistepv;
+
+	int                     pad[2];                         // to 64 bytes
+} surf_t;
+
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+typedef struct edge_s
+{
+	fixed16_t               u;
+	fixed16_t               u_step;
+	struct edge_s   *prev, *next;
+	unsigned short  surfs[2];
+	struct edge_s   *nextremove;
+	float                   nearzi;
+	medge_t                 *owner;
+} edge_t;
+
+
+/*
+====================================================
+
+VARS
+
+====================================================
+*/
+
+extern int              d_spanpixcount;
+extern int              r_framecount;           // sequence # of current frame since Quake
+									//  started
+extern float    r_aliasuvscale;         // scale-up factor for screen u and v
+									//  on Alias vertices passed to driver
+extern qboolean r_dowarp;
+
+extern affinetridesc_t  r_affinetridesc;
+
+extern vec3_t   r_pright, r_pup, r_ppn;
+
+void D_DrawSurfaces (void);
+void R_DrawParticle( void );
+void D_ViewChanged (void);
+void D_WarpScreen (void);
+void R_PolysetUpdateTables (void);
+
+extern void *acolormap; // FIXME: should go away
+
+//=======================================================================//
+
+// callbacks to Quake
+
+extern drawsurf_t       r_drawsurf;
+
+void R_DrawSurface (void);
+
+extern int              c_surf;
+
+extern byte             r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
+
+
+
+
+extern float    scale_for_mip;
+
+extern qboolean         d_roverwrapped;
+extern surfcache_t      *sc_rover;
+extern surfcache_t      *d_initial_rover;
+
+extern float    d_sdivzstepu, d_tdivzstepu, d_zistepu;
+extern float    d_sdivzstepv, d_tdivzstepv, d_zistepv;
+extern float    d_sdivzorigin, d_tdivzorigin, d_ziorigin;
+
+extern  fixed16_t       sadjust, tadjust;
+extern  fixed16_t       bbextents, bbextentt;
+
+
+void D_DrawSpans16 (espan_t *pspans);
+void D_DrawZSpans (espan_t *pspans);
+void Turbulent8 (espan_t *pspan);
+void NonTurbulent8 (espan_t *pspan);	//PGM
+
+surfcache_t     *D_CacheSurface (msurface_t *surface, int miplevel);
+
+extern int      d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
+
+extern int      d_pix_min, d_pix_max, d_pix_shift;
+
+extern pixel_t  *d_viewbuffer;
+extern short *d_pzbuffer;
+extern unsigned int d_zrowbytes, d_zwidth;
+extern short    *zspantable[MAXHEIGHT];
+extern int      d_scantable[MAXHEIGHT];
+
+extern int              d_minmip;
+extern float    d_scalemip[3];
+
+//===================================================================
+
+extern int              cachewidth;
+extern pixel_t  *cacheblock;
+extern int              r_screenwidth;
+
+extern int              r_drawnpolycount;
+
+extern int      sintable[1280];
+extern int      intsintable[1280];
+extern int		blanktable[1280];		// PGM
+
+extern  vec3_t  vup, base_vup;
+extern  vec3_t  vpn, base_vpn;
+extern  vec3_t  vright, base_vright;
+
+extern  surf_t  *surfaces, *surface_p, *surf_max;
+
+// surfaces are generated in back to front order by the bsp, so if a surf
+// pointer is greater than another one, it should be drawn in front
+// surfaces[1] is the background, and is used as the active surface stack.
+// surfaces[0] is a dummy, because index 0 is used to indicate no surface
+//  attached to an edge_t
+
+//===================================================================
+
+extern vec3_t   sxformaxis[4];  // s axis transformed into viewspace
+extern vec3_t   txformaxis[4];  // t axis transformed into viewspac
+
+extern  float   xcenter, ycenter;
+extern  float   xscale, yscale;
+extern  float   xscaleinv, yscaleinv;
+extern  float   xscaleshrink, yscaleshrink;
+
+extern void TransformVector (vec3_t in, vec3_t out);
+extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
+	fixed8_t endvertu, fixed8_t endvertv);
+
+extern int      ubasestep, errorterm, erroradjustup, erroradjustdown;
+
+//===========================================================================
+
+extern cvar_t   *sw_aliasstats;
+extern cvar_t   *sw_clearcolor;
+extern cvar_t   *sw_drawflat;
+extern cvar_t   *sw_draworder;
+extern cvar_t   *sw_maxedges;
+extern cvar_t   *sw_maxsurfs;
+extern cvar_t   *sw_mipcap;
+extern cvar_t   *sw_mipscale;
+extern cvar_t   *sw_mode;
+extern cvar_t   *sw_reportsurfout;
+extern cvar_t   *sw_reportedgeout;
+extern cvar_t   *sw_stipplealpha;
+extern cvar_t   *sw_surfcacheoverride;
+extern cvar_t   *sw_waterwarp;
+
+extern cvar_t   *r_fullbright;
+extern cvar_t	*r_lefthand;
+extern cvar_t   *r_drawentities;
+extern cvar_t   *r_drawworld;
+extern cvar_t   *r_dspeeds;
+extern cvar_t   *r_lerpmodels;
+
+extern cvar_t   *r_speeds;
+
+extern cvar_t   *r_lightlevel;  //FIXME HACK
+
+extern cvar_t	*vid_fullscreen;
+extern	cvar_t	*vid_gamma;
+
+
+extern  clipplane_t     view_clipplanes[4];
+extern int              *pfrustum_indexes[4];
+
+
+//=============================================================================
+
+void R_RenderWorld (void);
+
+//=============================================================================
+
+extern  mplane_t        screenedge[4];
+
+extern  vec3_t  r_origin;
+
+extern	entity_t	r_worldentity;
+extern  model_t         *currentmodel;
+extern  entity_t                *currententity;
+extern  vec3_t  modelorg;
+extern  vec3_t  r_entorigin;
+
+extern  float   verticalFieldOfView;
+extern  float   xOrigin, yOrigin;
+
+extern  int             r_visframecount;
+
+extern msurface_t *r_alpha_surfaces;
+
+//=============================================================================
+
+void R_ClearPolyList (void);
+void R_DrawPolyList (void);
+
+//
+// current entity info
+//
+extern  qboolean                insubmodel;
+
+void R_DrawAlphaSurfaces( void );
+
+void R_DrawSprite (void);
+void R_DrawBeam( entity_t *e );
+
+void R_RenderFace (msurface_t *fa, int clipflags);
+void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf);
+void R_TransformPlane (mplane_t *p, float *normal, float *dist);
+void R_TransformFrustum (void);
+void R_DrawSurfaceBlock16 (void);
+void R_DrawSurfaceBlock8 (void);
+
+#if     id386
+
+void R_DrawSurfaceBlock8_mip0 (void);
+void R_DrawSurfaceBlock8_mip1 (void);
+void R_DrawSurfaceBlock8_mip2 (void);
+void R_DrawSurfaceBlock8_mip3 (void);
+
+#endif
+
+void R_GenSkyTile (void *pdest);
+void R_GenSkyTile16 (void *pdest);
+void R_Surf8Patch (void);
+void R_Surf16Patch (void);
+void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode);
+void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode);
+
+void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel);
+surf_t *R_GetSurf (void);
+void R_AliasDrawModel (void);
+void R_BeginEdgeFrame (void);
+void R_ScanEdges (void);
+void D_DrawSurfaces (void);
+void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist);
+void R_StepActiveU (edge_t *pedge);
+void R_RemoveEdges (edge_t *pedge);
+void R_PushDlights (model_t *model);
+
+extern void R_Surf8Start (void);
+extern void R_Surf8End (void);
+extern void R_Surf16Start (void);
+extern void R_Surf16End (void);
+extern void R_EdgeCodeStart (void);
+extern void R_EdgeCodeEnd (void);
+
+extern void R_RotateBmodel (void);
+
+extern int      c_faceclip;
+extern int      r_polycount;
+extern int      r_wholepolycount;
+
+extern int                      ubasestep, errorterm, erroradjustup, erroradjustdown;
+
+extern fixed16_t        sadjust, tadjust;
+extern fixed16_t        bbextents, bbextentt;
+
+extern mvertex_t        *r_ptverts, *r_ptvertsmax;
+
+extern float                    entity_rotation[3][3];
+
+extern int              r_currentkey;
+extern int              r_currentbkey;
+
+void    R_InitTurb (void);
+
+void R_DrawParticles (void);
+void R_SurfacePatch (void);
+
+extern int              r_amodels_drawn;
+extern edge_t   *auxedges;
+extern int              r_numallocatededges;
+extern edge_t   *r_edges, *edge_p, *edge_max;
+
+extern  edge_t  *newedges[MAXHEIGHT];
+extern  edge_t  *removeedges[MAXHEIGHT];
+
+// FIXME: make stack vars when debugging done
+extern  edge_t  edge_head;
+extern  edge_t  edge_tail;
+extern  edge_t  edge_aftertail;
+
+extern	int	r_aliasblendcolor;
+
+extern float    aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
+
+extern int              r_outofsurfaces;
+extern int              r_outofedges;
+
+extern mvertex_t        *r_pcurrentvertbase;
+extern int                      r_maxvalidedgeoffset;
+
+typedef struct
+{
+	finalvert_t *a, *b, *c;
+} aliastriangleparms_t;
+
+extern aliastriangleparms_t aliastriangleparms;
+
+void R_DrawTriangle( void );
+//void R_DrawTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2);
+void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2);
+
+
+extern float    r_time1;
+extern float	da_time1, da_time2;
+extern float	dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
+extern float	se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2;
+extern int              r_frustum_indexes[4*6];
+extern int              r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
+extern qboolean r_surfsonstack;
+
+extern	mleaf_t		*r_viewleaf;
+extern	int			r_viewcluster, r_oldviewcluster;
+
+extern int              r_clipflags;
+extern int              r_dlightframecount;
+extern qboolean r_fov_greater_than_90;
+
+extern  image_t         *r_notexture_mip;
+extern  model_t         *r_worldmodel;
+
+void R_PrintAliasStats (void);
+void R_PrintTimes (void);
+void R_PrintDSpeeds (void);
+void R_AnimateLight (void);
+void R_LightPoint (vec3_t p, vec3_t color);
+void R_SetupFrame (void);
+void R_cshift_f (void);
+void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
+void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
+void R_SplitEntityOnNode2 (mnode_t *node);
+
+extern  refdef_t        r_newrefdef;
+
+extern  surfcache_t     *sc_rover, *sc_base;
+
+extern  void            *colormap;
+
+//====================================================================
+
+float R_DLightPoint (vec3_t p);
+
+void R_NewMap (void);
+void R_Register (void);
+void R_UnRegister (void);
+void Draw_InitLocal (void);
+qboolean R_Init( void *hInstance, void *wndProc );
+void R_Shutdown (void);
+void R_InitCaches (void);
+void D_FlushCaches (void);
+
+void	R_ScreenShot_f( void );
+void    R_BeginRegistration (char *map);
+struct model_s  *R_RegisterModel (char *name);
+void    R_EndRegistration (void);
+
+void    R_RenderFrame (refdef_t *fd);
+
+struct image_s  *Draw_FindPic (char *name);
+
+void    Draw_GetPicSize (int *w, int *h, char *name);
+void    Draw_Pic (int x, int y, char *name);
+void    Draw_StretchPic (int x, int y, int w, int h, char *name);
+void    Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data);
+void    Draw_Char (int x, int y, int c);
+void    Draw_TileClear (int x, int y, int w, int h, char *name);
+void    Draw_Fill (int x, int y, int w, int h, int c);
+void    Draw_FadeScreen (void);
+
+void    Draw_GetPalette (void);
+
+void	 R_BeginFrame( float camera_separation );
+
+void	R_CinematicSetPalette( const unsigned char *palette );
+
+extern unsigned d_8to24table[256]; // base
+
+void    Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length);
+void    Sys_SetFPCW (void);
+
+void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height);
+
+void    R_InitImages (void);
+void	R_ShutdownImages (void);
+image_t *R_FindImage (char *name, imagetype_t type);
+void    R_FreeUnusedImages (void);
+
+void	R_GammaCorrectAndSetPalette( const unsigned char *pal );
+
+extern mtexinfo_t  *sky_texinfo[6];
+
+void R_InitSkyBox (void);
+
+typedef struct swstate_s
+{
+	qboolean fullscreen;
+	int      prev_mode;				// last valid SW mode
+
+	byte		gammatable[256];
+	byte		currentpalette[1024];
+
+} swstate_t;
+
+void R_IMFlatShadedQuad( vec3_t a, vec3_t b, vec3_t c, vec3_t d, int color, float alpha );
+
+extern swstate_t sw_state;
+
+/*
+====================================================================
+
+IMPORTED FUNCTIONS
+
+====================================================================
+*/
+
+extern  refimport_t     ri;
+
+/*
+====================================================================
+
+IMPLEMENTATION FUNCTIONS
+
+====================================================================
+*/
+
+void		SWimp_BeginFrame( float camera_separation );
+void		SWimp_EndFrame (void);
+int			SWimp_Init( void *hInstance, void *wndProc );
+void		SWimp_SetPalette( const unsigned char *palette);
+void		SWimp_Shutdown( void );
+rserr_t		SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen );
+void		SWimp_AppActivate( qboolean active );
+
--- /dev/null
+++ b/ref/r_main.c
@@ -1,0 +1,1422 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_main.c
+
+#include "r_local.h"
+
+viddef_t	vid;
+refimport_t	ri;
+
+unsigned	d_8to24table[256];
+
+entity_t	r_worldentity;
+
+char		skyname[MAX_QPATH];
+float		skyrotate;
+vec3_t		skyaxis;
+image_t		*sky_images[6];
+
+refdef_t	r_newrefdef;
+model_t		*currentmodel;
+
+model_t		*r_worldmodel;
+
+byte		r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
+
+swstate_t sw_state;
+
+void		*colormap;
+vec3_t		viewlightvec;
+alight_t	r_viewlighting = {128, 192, viewlightvec};
+float		r_time1;
+int			r_numallocatededges;
+float		r_aliasuvscale = 1.0;
+int			r_outofsurfaces;
+int			r_outofedges;
+
+qboolean	r_dowarp;
+
+mvertex_t	*r_pcurrentvertbase;
+
+int			c_surf;
+int			r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
+qboolean	r_surfsonstack;
+int			r_clipflags;
+
+//
+// view origin
+//
+vec3_t	vup, base_vup;
+vec3_t	vpn, base_vpn;
+vec3_t	vright, base_vright;
+vec3_t	r_origin;
+
+//
+// screen size info
+//
+oldrefdef_t	r_refdef;
+float		xcenter, ycenter;
+float		xscale, yscale;
+float		xscaleinv, yscaleinv;
+float		xscaleshrink, yscaleshrink;
+float		aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
+
+int		r_screenwidth;
+
+float	verticalFieldOfView;
+float	xOrigin, yOrigin;
+
+mplane_t	screenedge[4];
+
+//
+// refresh flags
+//
+int		r_framecount = 1;	// so frame counts initialized to 0 don't match
+int		r_visframecount;
+int		d_spanpixcount;
+int		r_polycount;
+int		r_drawnpolycount;
+int		r_wholepolycount;
+
+int			*pfrustum_indexes[4];
+int			r_frustum_indexes[4*6];
+
+mleaf_t		*r_viewleaf;
+int			r_viewcluster, r_oldviewcluster;
+
+image_t  	*r_notexture_mip;
+
+float	da_time1, da_time2, dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
+float	se_time1, se_time2, de_time1, de_time2;
+
+void R_MarkLeaves (void);
+
+cvar_t	*r_lefthand;
+cvar_t	*sw_aliasstats;
+cvar_t	*sw_allow_modex;
+cvar_t	*sw_clearcolor;
+cvar_t	*sw_drawflat;
+cvar_t	*sw_draworder;
+cvar_t	*sw_maxedges;
+cvar_t	*sw_maxsurfs;
+cvar_t  *sw_mode;
+cvar_t	*sw_reportedgeout;
+cvar_t	*sw_reportsurfout;
+cvar_t  *sw_stipplealpha;
+cvar_t	*sw_surfcacheoverride;
+cvar_t	*sw_waterwarp;
+
+cvar_t	*r_drawworld;
+cvar_t	*r_drawentities;
+cvar_t	*r_dspeeds;
+cvar_t	*r_fullbright;
+cvar_t  *r_lerpmodels;
+cvar_t  *r_novis;
+
+cvar_t	*r_speeds;
+cvar_t	*r_lightlevel;	//FIXME HACK
+
+cvar_t	*vid_fullscreen;
+cvar_t	*vid_gamma;
+
+//PGM
+cvar_t	*sw_lockpvs;
+//PGM
+
+#define	STRINGER(x) "x"
+
+
+#if	!id386
+
+// r_vars.c
+
+// all global and static refresh variables are collected in a contiguous block
+// to avoid cache conflicts.
+
+//-------------------------------------------------------
+// global refresh variables
+//-------------------------------------------------------
+
+// FIXME: make into one big structure, like cl or sv
+// FIXME: do separately for refresh engine and driver
+
+
+// d_vars.c
+
+// all global and static refresh variables are collected in a contiguous block
+// to avoid cache conflicts.
+
+//-------------------------------------------------------
+// global refresh variables
+//-------------------------------------------------------
+
+// FIXME: make into one big structure, like cl or sv
+// FIXME: do separately for refresh engine and driver
+
+float	d_sdivzstepu, d_tdivzstepu, d_zistepu;
+float	d_sdivzstepv, d_tdivzstepv, d_zistepv;
+float	d_sdivzorigin, d_tdivzorigin, d_ziorigin;
+
+fixed16_t	sadjust, tadjust, bbextents, bbextentt;
+
+pixel_t			*cacheblock;
+int				cachewidth;
+pixel_t			*d_viewbuffer;
+short			*d_pzbuffer;
+unsigned int	d_zrowbytes;
+unsigned int	d_zwidth;
+
+
+#endif	// !id386
+
+byte	r_notexture_buffer[1024];
+
+/*
+==================
+R_InitTextures
+==================
+*/
+void	R_InitTextures (void)
+{
+	int		x,y, m;
+	byte	*dest;
+	
+// create a simple checkerboard texture for the default
+	r_notexture_mip = (image_t *)&r_notexture_buffer;
+	
+	r_notexture_mip->width = r_notexture_mip->height = 16;
+	r_notexture_mip->pixels[0] = &r_notexture_buffer[sizeof(image_t)];
+	r_notexture_mip->pixels[1] = r_notexture_mip->pixels[0] + 16*16;
+	r_notexture_mip->pixels[2] = r_notexture_mip->pixels[1] + 8*8;
+	r_notexture_mip->pixels[3] = r_notexture_mip->pixels[2] + 4*4;
+	
+	for (m=0 ; m<4 ; m++)
+	{
+		dest = r_notexture_mip->pixels[m];
+		for (y=0 ; y< (16>>m) ; y++)
+			for (x=0 ; x< (16>>m) ; x++)
+			{
+				if (  (y< (8>>m) ) ^ (x< (8>>m) ) )
+
+					*dest++ = 0;
+				else
+					*dest++ = 0xff;
+			}
+	}	
+}
+
+
+/*
+================
+R_InitTurb
+================
+*/
+void R_InitTurb (void)
+{
+	int		i;
+	
+	for (i=0 ; i<1280 ; i++)
+	{
+		sintable[i] = AMP + sin(i*3.14159*2/CYCLE)*AMP;
+		intsintable[i] = AMP2 + sin(i*3.14159*2/CYCLE)*AMP2;	// AMP2, not 20
+		blanktable[i] = 0;			//PGM
+	}
+}
+
+void R_ImageList_f( void );
+
+void R_Register (void)
+{
+	sw_aliasstats = ri.Cvar_Get ("sw_polymodelstats", "0", 0);
+	sw_allow_modex = ri.Cvar_Get( "sw_allow_modex", "1", CVAR_ARCHIVE );
+	sw_clearcolor = ri.Cvar_Get ("sw_clearcolor", "2", 0);
+	sw_drawflat = ri.Cvar_Get ("sw_drawflat", "0", 0);
+	sw_draworder = ri.Cvar_Get ("sw_draworder", "0", 0);
+	sw_maxedges = ri.Cvar_Get ("sw_maxedges", STRINGER(MAXSTACKSURFACES), 0);
+	sw_maxsurfs = ri.Cvar_Get ("sw_maxsurfs", "0", 0);
+	sw_mipcap = ri.Cvar_Get ("sw_mipcap", "0", 0);
+	sw_mipscale = ri.Cvar_Get ("sw_mipscale", "1", 0);
+	sw_reportedgeout = ri.Cvar_Get ("sw_reportedgeout", "0", 0);
+	sw_reportsurfout = ri.Cvar_Get ("sw_reportsurfout", "0", 0);
+	sw_stipplealpha = ri.Cvar_Get( "sw_stipplealpha", "0", CVAR_ARCHIVE );
+	sw_surfcacheoverride = ri.Cvar_Get ("sw_surfcacheoverride", "0", 0);
+	sw_waterwarp = ri.Cvar_Get ("sw_waterwarp", "1", 0);
+	sw_mode = ri.Cvar_Get( "sw_mode", "0", CVAR_ARCHIVE );
+
+	r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
+	r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
+	r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
+	r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
+	r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
+	r_dspeeds = ri.Cvar_Get ("r_dspeeds", "0", 0);
+	r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
+	r_lerpmodels = ri.Cvar_Get( "r_lerpmodels", "1", 0 );
+	r_novis = ri.Cvar_Get( "r_novis", "0", 0 );
+
+	vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
+	vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
+
+	ri.Cmd_AddCommand ("modellist", Mod_Modellist_f);
+	ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
+	ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
+
+	sw_mode->modified = true; // force us to do mode specific stuff later
+	vid_gamma->modified = true; // force us to rebuild the gamma table later
+
+//PGM
+	sw_lockpvs = ri.Cvar_Get ("sw_lockpvs", "0", 0);
+//PGM
+}
+
+void R_UnRegister (void)
+{
+	ri.Cmd_RemoveCommand( "screenshot" );
+	ri.Cmd_RemoveCommand ("modellist");
+	ri.Cmd_RemoveCommand( "imagelist" );
+}
+
+/*
+===============
+R_Init
+===============
+*/
+qboolean R_Init( void *hInstance, void *wndProc )
+{
+	R_InitImages ();
+	Mod_Init ();
+	Draw_InitLocal ();
+	R_InitTextures ();
+
+	R_InitTurb ();
+
+	view_clipplanes[0].leftedge = true;
+	view_clipplanes[1].rightedge = true;
+	view_clipplanes[1].leftedge = view_clipplanes[2].leftedge =
+			view_clipplanes[3].leftedge = false;
+	view_clipplanes[0].rightedge = view_clipplanes[2].rightedge =
+			view_clipplanes[3].rightedge = false;
+
+	r_refdef.xOrigin = XCENTERING;
+	r_refdef.yOrigin = YCENTERING;
+
+// TODO: collect 386-specific code in one place
+#if	id386
+	Sys_MakeCodeWriteable ((long)R_EdgeCodeStart,
+					     (long)R_EdgeCodeEnd - (long)R_EdgeCodeStart);
+	Sys_SetFPCW ();		// get bit masks for FPCW	(FIXME: is this id386?)
+#endif	// id386
+
+	r_aliasuvscale = 1.0;
+
+	R_Register ();
+	Draw_GetPalette ();
+	SWimp_Init( hInstance, wndProc );
+
+	// create the window
+	R_BeginFrame( 0 );
+
+	ri.Con_Printf (PRINT_ALL, "ref_soft version: "REF_VERSION"\n");
+
+	return true;
+}
+
+/*
+===============
+R_Shutdown
+===============
+*/
+void R_Shutdown (void)
+{
+	// free z buffer
+	if (d_pzbuffer)
+	{
+		free (d_pzbuffer);
+		d_pzbuffer = NULL;
+	}
+	// free surface cache
+	if (sc_base)
+	{
+		D_FlushCaches ();
+		free (sc_base);
+		sc_base = NULL;
+	}
+
+	// free colormap
+	if (vid.colormap)
+	{
+		free (vid.colormap);
+		vid.colormap = NULL;
+	}
+	R_UnRegister ();
+	Mod_FreeAll ();
+	R_ShutdownImages ();
+
+	SWimp_Shutdown();
+}
+
+/*
+===============
+R_NewMap
+===============
+*/
+void R_NewMap (void)
+{
+	r_viewcluster = -1;
+
+	r_cnumsurfs = sw_maxsurfs->value;
+
+	if (r_cnumsurfs <= MINSURFACES)
+		r_cnumsurfs = MINSURFACES;
+
+	if (r_cnumsurfs > NUMSTACKSURFACES)
+	{
+		surfaces = malloc (r_cnumsurfs * sizeof(surf_t));
+		surface_p = surfaces;
+		surf_max = &surfaces[r_cnumsurfs];
+		r_surfsonstack = false;
+	// surface 0 doesn't really exist; it's just a dummy because index 0
+	// is used to indicate no edge attached to surface
+		surfaces--;
+		R_SurfacePatch ();
+	}
+	else
+	{
+		r_surfsonstack = true;
+	}
+
+	r_maxedgesseen = 0;
+	r_maxsurfsseen = 0;
+
+	r_numallocatededges = sw_maxedges->value;
+
+	if (r_numallocatededges < MINEDGES)
+		r_numallocatededges = MINEDGES;
+
+	if (r_numallocatededges <= NUMSTACKEDGES)
+	{
+		auxedges = NULL;
+	}
+	else
+	{
+		auxedges = malloc (r_numallocatededges * sizeof(edge_t));
+	}
+}
+
+
+/*
+===============
+R_MarkLeaves
+
+Mark the leaves and nodes that are in the PVS for the current
+cluster
+===============
+*/
+void R_MarkLeaves (void)
+{
+	byte	*vis;
+	mnode_t	*node;
+	int		i;
+	mleaf_t	*leaf;
+	int		cluster;
+
+	if (r_oldviewcluster == r_viewcluster && !r_novis->value && r_viewcluster != -1)
+		return;
+	
+	// development aid to let you run around and see exactly where
+	// the pvs ends
+	if (sw_lockpvs->value)
+		return;
+
+	r_visframecount++;
+	r_oldviewcluster = r_viewcluster;
+
+	if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
+	{
+		// mark everything
+		for (i=0 ; i<r_worldmodel->numleafs ; i++)
+			r_worldmodel->leafs[i].visframe = r_visframecount;
+		for (i=0 ; i<r_worldmodel->numnodes ; i++)
+			r_worldmodel->nodes[i].visframe = r_visframecount;
+		return;
+	}
+
+	vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
+	
+	for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
+	{
+		cluster = leaf->cluster;
+		if (cluster == -1)
+			continue;
+		if (vis[cluster>>3] & (1<<(cluster&7)))
+		{
+			node = (mnode_t *)leaf;
+			do
+			{
+				if (node->visframe == r_visframecount)
+					break;
+				node->visframe = r_visframecount;
+				node = node->parent;
+			} while (node);
+		}
+	}
+
+#if 0
+	for (i=0 ; i<r_worldmodel->vis->numclusters ; i++)
+	{
+		if (vis[i>>3] & (1<<(i&7)))
+		{
+			node = (mnode_t *)&r_worldmodel->leafs[i];	// FIXME: cluster
+			do
+			{
+				if (node->visframe == r_visframecount)
+					break;
+				node->visframe = r_visframecount;
+				node = node->parent;
+			} while (node);
+		}
+	}
+#endif
+}
+
+/*
+** R_DrawNullModel
+**
+** IMPLEMENT THIS!
+*/
+void R_DrawNullModel( void )
+{
+}
+
+/*
+=============
+R_DrawEntitiesOnList
+=============
+*/
+void R_DrawEntitiesOnList (void)
+{
+	int			i;
+	qboolean	translucent_entities = false;
+
+	if (!r_drawentities->value)
+		return;
+
+	// all bmodels have already been drawn by the edge list
+	for (i=0 ; i<r_newrefdef.num_entities ; i++)
+	{
+		currententity = &r_newrefdef.entities[i];
+
+		if ( currententity->flags & RF_TRANSLUCENT )
+		{
+			translucent_entities = true;
+			continue;
+		}
+
+		if ( currententity->flags & RF_BEAM )
+		{
+			modelorg[0] = -r_origin[0];
+			modelorg[1] = -r_origin[1];
+			modelorg[2] = -r_origin[2];
+			VectorCopy( vec3_origin, r_entorigin );
+			R_DrawBeam( currententity );
+		}
+		else
+		{
+			currentmodel = currententity->model;
+			if (!currentmodel)
+			{
+				R_DrawNullModel();
+				continue;
+			}
+			VectorCopy (currententity->origin, r_entorigin);
+			VectorSubtract (r_origin, r_entorigin, modelorg);
+
+			switch (currentmodel->type)
+			{
+			case mod_sprite:
+				R_DrawSprite ();
+				break;
+
+			case mod_alias:
+				R_AliasDrawModel ();
+				break;
+
+			default:
+				break;
+			}
+		}
+	}
+
+	if ( !translucent_entities )
+		return;
+
+	for (i=0 ; i<r_newrefdef.num_entities ; i++)
+	{
+		currententity = &r_newrefdef.entities[i];
+
+		if ( !( currententity->flags & RF_TRANSLUCENT ) )
+			continue;
+
+		if ( currententity->flags & RF_BEAM )
+		{
+			modelorg[0] = -r_origin[0];
+			modelorg[1] = -r_origin[1];
+			modelorg[2] = -r_origin[2];
+			VectorCopy( vec3_origin, r_entorigin );
+			R_DrawBeam( currententity );
+		}
+		else
+		{
+			currentmodel = currententity->model;
+			if (!currentmodel)
+			{
+				R_DrawNullModel();
+				continue;
+			}
+			VectorCopy (currententity->origin, r_entorigin);
+			VectorSubtract (r_origin, r_entorigin, modelorg);
+
+			switch (currentmodel->type)
+			{
+			case mod_sprite:
+				R_DrawSprite ();
+				break;
+
+			case mod_alias:
+				R_AliasDrawModel ();
+				break;
+
+			default:
+				break;
+			}
+		}
+	}
+}
+
+
+/*
+=============
+R_BmodelCheckBBox
+=============
+*/
+int R_BmodelCheckBBox (float *minmaxs)
+{
+	int			i, *pindex, clipflags;
+	vec3_t		acceptpt, rejectpt;
+	float		d;
+
+	clipflags = 0;
+
+	for (i=0 ; i<4 ; i++)
+	{
+	// generate accept and reject points
+	// FIXME: do with fast look-ups or integer tests based on the sign bit
+	// of the floating point values
+
+		pindex = pfrustum_indexes[i];
+
+		rejectpt[0] = minmaxs[pindex[0]];
+		rejectpt[1] = minmaxs[pindex[1]];
+		rejectpt[2] = minmaxs[pindex[2]];
+		
+		d = DotProduct (rejectpt, view_clipplanes[i].normal);
+		d -= view_clipplanes[i].dist;
+
+		if (d <= 0)
+			return BMODEL_FULLY_CLIPPED;
+
+		acceptpt[0] = minmaxs[pindex[3+0]];
+		acceptpt[1] = minmaxs[pindex[3+1]];
+		acceptpt[2] = minmaxs[pindex[3+2]];
+
+		d = DotProduct (acceptpt, view_clipplanes[i].normal);
+		d -= view_clipplanes[i].dist;
+
+		if (d <= 0)
+			clipflags |= (1<<i);
+	}
+
+	return clipflags;
+}
+
+
+/*
+===================
+R_FindTopnode
+
+Find the first node that splits the given box
+===================
+*/
+mnode_t *R_FindTopnode (vec3_t mins, vec3_t maxs)
+{
+	mplane_t	*splitplane;
+	int			sides;
+	mnode_t *node;
+
+	node = r_worldmodel->nodes;
+
+	while (1)
+	{
+		if (node->visframe != r_visframecount)
+			return NULL;		// not visible at all
+		
+		if (node->contents != CONTENTS_NODE)
+		{
+			if (node->contents != CONTENTS_SOLID)
+				return	node; // we've reached a non-solid leaf, so it's
+							//  visible and not BSP clipped
+			return NULL;	// in solid, so not visible
+		}
+		
+		splitplane = node->plane;
+		sides = BOX_ON_PLANE_SIDE(mins, maxs, (cplane_t *)splitplane);
+		
+		if (sides == 3)
+			return node;	// this is the splitter
+		
+	// not split yet; recurse down the contacted side
+		if (sides & 1)
+			node = node->children[0];
+		else
+			node = node->children[1];
+	}
+}
+
+
+/*
+=============
+RotatedBBox
+
+Returns an axially aligned box that contains the input box at the given rotation
+=============
+*/
+void RotatedBBox (vec3_t mins, vec3_t maxs, vec3_t angles, vec3_t tmins, vec3_t tmaxs)
+{
+	vec3_t	tmp, v;
+	int		i, j;
+	vec3_t	forward, right, up;
+
+	if (!angles[0] && !angles[1] && !angles[2])
+	{
+		VectorCopy (mins, tmins);
+		VectorCopy (maxs, tmaxs);
+		return;
+	}
+
+	for (i=0 ; i<3 ; i++)
+	{
+		tmins[i] = 99999;
+		tmaxs[i] = -99999;
+	}
+
+	AngleVectors (angles, forward, right, up);
+
+	for ( i = 0; i < 8; i++ )
+	{
+		if ( i & 1 )
+			tmp[0] = mins[0];
+		else
+			tmp[0] = maxs[0];
+
+		if ( i & 2 )
+			tmp[1] = mins[1];
+		else
+			tmp[1] = maxs[1];
+
+		if ( i & 4 )
+			tmp[2] = mins[2];
+		else
+			tmp[2] = maxs[2];
+
+
+		VectorScale (forward, tmp[0], v);
+		VectorMA (v, -tmp[1], right, v);
+		VectorMA (v, tmp[2], up, v);
+
+		for (j=0 ; j<3 ; j++)
+		{
+			if (v[j] < tmins[j])
+				tmins[j] = v[j];
+			if (v[j] > tmaxs[j])
+				tmaxs[j] = v[j];
+		}
+	}
+}
+
+/*
+=============
+R_DrawBEntitiesOnList
+=============
+*/
+void R_DrawBEntitiesOnList (void)
+{
+	int			i, clipflags;
+	vec3_t		oldorigin;
+	vec3_t		mins, maxs;
+	float		minmaxs[6];
+	mnode_t		*topnode;
+
+	if (!r_drawentities->value)
+		return;
+
+	VectorCopy (modelorg, oldorigin);
+	insubmodel = true;
+	r_dlightframecount = r_framecount;
+
+	for (i=0 ; i<r_newrefdef.num_entities ; i++)
+	{
+		currententity = &r_newrefdef.entities[i];
+		currentmodel = currententity->model;
+		if (!currentmodel)
+			continue;
+		if (currentmodel->nummodelsurfaces == 0)
+			continue;	// clip brush only
+		if ( currententity->flags & RF_BEAM )
+			continue;
+		if (currentmodel->type != mod_brush)
+			continue;
+	// see if the bounding box lets us trivially reject, also sets
+	// trivial accept status
+		RotatedBBox (currentmodel->mins, currentmodel->maxs,
+			currententity->angles, mins, maxs);
+		VectorAdd (mins, currententity->origin, minmaxs);
+		VectorAdd (maxs, currententity->origin, (minmaxs+3));
+
+		clipflags = R_BmodelCheckBBox (minmaxs);
+		if (clipflags == BMODEL_FULLY_CLIPPED)
+			continue;	// off the edge of the screen
+
+		topnode = R_FindTopnode (minmaxs, minmaxs+3);
+		if (!topnode)
+			continue;	// no part in a visible leaf
+
+		VectorCopy (currententity->origin, r_entorigin);
+		VectorSubtract (r_origin, r_entorigin, modelorg);
+
+		r_pcurrentvertbase = currentmodel->vertexes;
+
+	// FIXME: stop transforming twice
+		R_RotateBmodel ();
+
+	// calculate dynamic lighting for bmodel
+		R_PushDlights (currentmodel);
+
+		if (topnode->contents == CONTENTS_NODE)
+		{
+		// not a leaf; has to be clipped to the world BSP
+			r_clipflags = clipflags;
+			R_DrawSolidClippedSubmodelPolygons (currentmodel, topnode);
+		}
+		else
+		{
+		// falls entirely in one leaf, so we just put all the
+		// edges in the edge list and let 1/z sorting handle
+		// drawing order
+			R_DrawSubmodelPolygons (currentmodel, clipflags, topnode);
+		}
+
+	// put back world rotation and frustum clipping		
+	// FIXME: R_RotateBmodel should just work off base_vxx
+		VectorCopy (base_vpn, vpn);
+		VectorCopy (base_vup, vup);
+		VectorCopy (base_vright, vright);
+		VectorCopy (oldorigin, modelorg);
+		R_TransformFrustum ();
+	}
+
+	insubmodel = false;
+}
+
+
+/*
+================
+R_EdgeDrawing
+================
+*/
+void R_EdgeDrawing (void)
+{
+	edge_t	ledges[NUMSTACKEDGES +
+				((CACHE_SIZE - 1) / sizeof(edge_t)) + 1];
+	surf_t	lsurfs[NUMSTACKSURFACES +
+				((CACHE_SIZE - 1) / sizeof(surf_t)) + 1];
+
+	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
+		return;
+
+	if (auxedges)
+	{
+		r_edges = auxedges;
+	}
+	else
+	{
+		r_edges =  (edge_t *)
+				(((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
+	}
+
+	if (r_surfsonstack)
+	{
+		surfaces =  (surf_t *)
+				(((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
+		surf_max = &surfaces[r_cnumsurfs];
+	// surface 0 doesn't really exist; it's just a dummy because index 0
+	// is used to indicate no edge attached to surface
+		surfaces--;
+		R_SurfacePatch ();
+	}
+
+	R_BeginEdgeFrame ();
+
+	if (r_dspeeds->value)
+	{
+		rw_time1 = Sys_Milliseconds ();
+	}
+
+	R_RenderWorld ();
+
+	if (r_dspeeds->value)
+	{
+		rw_time2 = Sys_Milliseconds ();
+		db_time1 = rw_time2;
+	}
+
+	R_DrawBEntitiesOnList ();
+
+	if (r_dspeeds->value)
+	{
+		db_time2 = Sys_Milliseconds ();
+		se_time1 = db_time2;
+	}
+
+	R_ScanEdges ();
+}
+
+//=======================================================================
+
+
+/*
+=============
+R_CalcPalette
+
+=============
+*/
+void R_CalcPalette (void)
+{
+	static qboolean modified;
+	byte	palette[256][4], *in, *out;
+	int		i, j;
+	float	alpha, one_minus_alpha;
+	vec3_t	premult;
+	int		v;
+
+	alpha = r_newrefdef.blend[3];
+	if (alpha <= 0)
+	{
+		if (modified)
+		{	// set back to default
+			modified = false;
+			R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
+			return;
+		}
+		return;
+	}
+
+	modified = true;
+	if (alpha > 1)
+		alpha = 1;
+
+	premult[0] = r_newrefdef.blend[0]*alpha*255;
+	premult[1] = r_newrefdef.blend[1]*alpha*255;
+	premult[2] = r_newrefdef.blend[2]*alpha*255;
+
+	one_minus_alpha = (1.0 - alpha);
+
+	in = (byte *)d_8to24table;
+	out = palette[0];
+	for (i=0 ; i<256 ; i++, in+=4, out+=4)
+	{
+		for (j=0 ; j<3 ; j++)
+		{
+			v = premult[j] + one_minus_alpha * in[j];
+			if (v > 255)
+				v = 255;
+			out[j] = v;
+		}
+		out[3] = 255;
+	}
+
+	R_GammaCorrectAndSetPalette( ( const unsigned char * ) palette[0] );
+//	SWimp_SetPalette( palette[0] );
+}
+
+//=======================================================================
+
+void R_SetLightLevel (void)
+{
+	vec3_t		light;
+
+	if ((r_newrefdef.rdflags & RDF_NOWORLDMODEL) || (!r_drawentities->value) || (!currententity))
+	{
+		r_lightlevel->value = 150.0;
+		return;
+	}
+
+	// save off light value for server to look at (BIG HACK!)
+	R_LightPoint (r_newrefdef.vieworg, light);
+	r_lightlevel->value = 150.0 * light[0];
+}
+
+
+/*
+@@@@@@@@@@@@@@@@
+R_RenderFrame
+
+@@@@@@@@@@@@@@@@
+*/
+void R_RenderFrame (refdef_t *fd)
+{
+	r_newrefdef = *fd;
+
+	if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
+		ri.Sys_Error (ERR_FATAL,"R_RenderView: NULL worldmodel");
+
+	VectorCopy (fd->vieworg, r_refdef.vieworg);
+	VectorCopy (fd->viewangles, r_refdef.viewangles);
+
+	if (r_speeds->value || r_dspeeds->value)
+		r_time1 = Sys_Milliseconds ();
+
+	R_SetupFrame ();
+
+	R_MarkLeaves ();	// done here so we know if we're in water
+
+	R_PushDlights (r_worldmodel);
+
+	R_EdgeDrawing ();
+
+	if (r_dspeeds->value)
+	{
+		se_time2 = Sys_Milliseconds ();
+		de_time1 = se_time2;
+	}
+
+	R_DrawEntitiesOnList ();
+
+	if (r_dspeeds->value)
+	{
+		de_time2 = Sys_Milliseconds ();
+		dp_time1 = Sys_Milliseconds ();
+	}
+
+	R_DrawParticles ();
+
+	if (r_dspeeds->value)
+		dp_time2 = Sys_Milliseconds ();
+
+	R_DrawAlphaSurfaces();
+
+	R_SetLightLevel ();
+
+	if (r_dowarp)
+		D_WarpScreen ();
+
+	if (r_dspeeds->value)
+		da_time1 = Sys_Milliseconds ();
+
+	if (r_dspeeds->value)
+		da_time2 = Sys_Milliseconds ();
+
+	R_CalcPalette ();
+
+	if (sw_aliasstats->value)
+		R_PrintAliasStats ();
+		
+	if (r_speeds->value)
+		R_PrintTimes ();
+
+	if (r_dspeeds->value)
+		R_PrintDSpeeds ();
+
+	if (sw_reportsurfout->value && r_outofsurfaces)
+		ri.Con_Printf (PRINT_ALL,"Short %d surfaces\n", r_outofsurfaces);
+
+	if (sw_reportedgeout->value && r_outofedges)
+		ri.Con_Printf (PRINT_ALL,"Short roughly %d edges\n", r_outofedges * 2 / 3);
+}
+
+/*
+** R_InitGraphics
+*/
+void R_InitGraphics( int width, int height )
+{
+	vid.width  = width;
+	vid.height = height;
+
+	// free z buffer
+	if ( d_pzbuffer )
+	{
+		free( d_pzbuffer );
+		d_pzbuffer = NULL;
+	}
+
+	// free surface cache
+	if ( sc_base )
+	{
+		D_FlushCaches ();
+		free( sc_base );
+		sc_base = NULL;
+	}
+
+	d_pzbuffer = malloc(vid.width*vid.height*2);
+
+	R_InitCaches ();
+
+	R_GammaCorrectAndSetPalette( ( const unsigned char *) d_8to24table );
+}
+
+/*
+** R_BeginFrame
+*/
+void R_BeginFrame( float camera_separation )
+{
+	extern void Draw_BuildGammaTable( void );
+
+	/*
+	** rebuild the gamma correction palette if necessary
+	*/
+	if ( vid_gamma->modified )
+	{
+		Draw_BuildGammaTable();
+		R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
+
+		vid_gamma->modified = false;
+	}
+
+	while ( sw_mode->modified || vid_fullscreen->modified )
+	{
+		rserr_t err;
+
+		/*
+		** if this returns rserr_invalid_fullscreen then it set the mode but not as a
+		** fullscreen mode, e.g. 320x200 on a system that doesn't support that res
+		*/
+		if ( ( err = SWimp_SetMode( &vid.width, &vid.height, sw_mode->value, vid_fullscreen->value ) ) == rserr_ok )
+		{
+			R_InitGraphics( vid.width, vid.height );
+
+			sw_state.prev_mode = sw_mode->value;
+			vid_fullscreen->modified = false;
+			sw_mode->modified = false;
+		}
+		else
+		{
+			if ( err == rserr_invalid_mode )
+			{
+				ri.Cvar_SetValue( "sw_mode", sw_state.prev_mode );
+				ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - could not set mode\n" );
+			}
+			else if ( err == rserr_invalid_fullscreen )
+			{
+				R_InitGraphics( vid.width, vid.height );
+
+				ri.Cvar_SetValue( "vid_fullscreen", 0);
+				ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - fullscreen unavailable in this mode\n" );
+				sw_state.prev_mode = sw_mode->value;
+//				vid_fullscreen->modified = false;
+//				sw_mode->modified = false;
+			}
+			else
+			{
+				ri.Sys_Error( ERR_FATAL, "ref_soft::R_BeginFrame() - catastrophic mode change failure\n" );
+			}
+		}
+	}
+}
+
+/*
+** R_GammaCorrectAndSetPalette
+*/
+void R_GammaCorrectAndSetPalette( const unsigned char *palette )
+{
+	int i;
+
+	for ( i = 0; i < 256; i++ )
+	{
+		sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+0]];
+		sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]];
+		sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+2]];
+	}
+
+	SWimp_SetPalette( sw_state.currentpalette );
+}
+
+/*
+** R_CinematicSetPalette
+*/
+void R_CinematicSetPalette( const unsigned char *palette )
+{
+	byte palette32[1024];
+	int		i, j, w;
+	int		*d;
+
+	// clear screen to black to avoid any palette flash
+	w = abs(vid.rowbytes)>>2;	// stupid negative pitch win32 stuff...
+	for (i=0 ; i<vid.height ; i++, d+=w)
+	{
+		d = (int *)(vid.buffer + i*vid.rowbytes);
+		for (j=0 ; j<w ; j++)
+			d[j] = 0;
+	}
+	// flush it to the screen
+	SWimp_EndFrame ();
+
+	if ( palette )
+	{
+		for ( i = 0; i < 256; i++ )
+		{
+			palette32[i*4+0] = palette[i*3+0];
+			palette32[i*4+1] = palette[i*3+1];
+			palette32[i*4+2] = palette[i*3+2];
+			palette32[i*4+3] = 0xFF;
+		}
+
+		R_GammaCorrectAndSetPalette( palette32 );
+	}
+	else
+	{
+		R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
+	}
+}
+
+/*
+================
+Draw_BuildGammaTable
+================
+*/
+void Draw_BuildGammaTable (void)
+{
+	int		i, inf;
+	float	g;
+
+	g = vid_gamma->value;
+
+	if (g == 1.0)
+	{
+		for (i=0 ; i<256 ; i++)
+			sw_state.gammatable[i] = i;
+		return;
+	}
+	
+	for (i=0 ; i<256 ; i++)
+	{
+		inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
+		if (inf < 0)
+			inf = 0;
+		if (inf > 255)
+			inf = 255;
+		sw_state.gammatable[i] = inf;
+	}
+}
+
+/*
+** R_DrawBeam
+*/
+void R_DrawBeam( entity_t *e )
+{
+#define NUM_BEAM_SEGS 6
+
+	int	i;
+
+	vec3_t perpvec;
+	vec3_t direction, normalized_direction;
+	vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
+	vec3_t oldorigin, origin;
+
+	oldorigin[0] = e->oldorigin[0];
+	oldorigin[1] = e->oldorigin[1];
+	oldorigin[2] = e->oldorigin[2];
+
+	origin[0] = e->origin[0];
+	origin[1] = e->origin[1];
+	origin[2] = e->origin[2];
+
+	normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
+	normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
+	normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
+
+	if ( VectorNormalize( normalized_direction ) == 0 )
+		return;
+
+	PerpendicularVector( perpvec, normalized_direction );
+	VectorScale( perpvec, e->frame / 2, perpvec );
+
+	for ( i = 0; i < NUM_BEAM_SEGS; i++ )
+	{
+		RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
+		VectorAdd( start_points[i], origin, start_points[i] );
+		VectorAdd( start_points[i], direction, end_points[i] );
+	}
+
+	for ( i = 0; i < NUM_BEAM_SEGS; i++ )
+	{
+		R_IMFlatShadedQuad( start_points[i],
+		                    end_points[i],
+							end_points[(i+1)%NUM_BEAM_SEGS],
+							start_points[(i+1)%NUM_BEAM_SEGS],
+							e->skinnum & 0xFF,
+							e->alpha );
+	}
+}
+
+
+//===================================================================
+
+/*
+============
+R_SetSky
+============
+*/
+// 3dstudio environment map names
+char	*suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
+int	r_skysideimage[6] = {5, 2, 4, 1, 0, 3};
+extern	mtexinfo_t		r_skytexinfo[6];
+void R_SetSky (char *name, float rotate, vec3_t axis)
+{
+	int		i;
+	char	pathname[MAX_QPATH];
+
+	strncpy (skyname, name, sizeof(skyname)-1);
+	skyrotate = rotate;
+	VectorCopy (axis, skyaxis);
+
+	for (i=0 ; i<6 ; i++)
+	{
+		Com_sprintf (pathname, sizeof(pathname), "env/%s%s.pcx", skyname, suf[r_skysideimage[i]]);
+		r_skytexinfo[i].image = R_FindImage (pathname, it_sky);
+	}
+}
+
+
+/*
+===============
+Draw_GetPalette
+===============
+*/
+void Draw_GetPalette (void)
+{
+	byte	*pal, *out;
+	int		i;
+	int		r, g, b;
+
+	// get the palette and colormap
+	LoadPCX ("pics/colormap.pcx", &vid.colormap, &pal, NULL, NULL);
+	if (!vid.colormap)
+		ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
+	vid.alphamap = vid.colormap + 64*256;
+
+	out = (byte *)d_8to24table;
+	for (i=0 ; i<256 ; i++, out+=4)
+	{
+		r = pal[i*3+0];
+		g = pal[i*3+1];
+		b = pal[i*3+2];
+
+        out[0] = r;
+        out[1] = g;
+        out[2] = b;
+	}
+
+	free (pal);
+}
+
+struct image_s *R_RegisterSkin (char *name);
+
+/*
+@@@@@@@@@@@@@@@@@@@@@
+GetRefAPI
+
+@@@@@@@@@@@@@@@@@@@@@
+*/
+refexport_t GetRefAPI (refimport_t rimp)
+{
+	refexport_t	re;
+
+	ri = rimp;
+
+	re.api_version = API_VERSION;
+
+	re.BeginRegistration = R_BeginRegistration;
+    re.RegisterModel = R_RegisterModel;
+    re.RegisterSkin = R_RegisterSkin;
+	re.RegisterPic = Draw_FindPic;
+	re.SetSky = R_SetSky;
+	re.EndRegistration = R_EndRegistration;
+
+	re.RenderFrame = R_RenderFrame;
+
+	re.DrawGetPicSize = Draw_GetPicSize;
+	re.DrawPic = Draw_Pic;
+	re.DrawStretchPic = Draw_StretchPic;
+	re.DrawChar = Draw_Char;
+	re.DrawTileClear = Draw_TileClear;
+	re.DrawFill = Draw_Fill;
+	re.DrawFadeScreen= Draw_FadeScreen;
+
+	re.DrawStretchRaw = Draw_StretchRaw;
+
+	re.Init = R_Init;
+	re.Shutdown = R_Shutdown;
+
+	re.CinematicSetPalette = R_CinematicSetPalette;
+	re.BeginFrame = R_BeginFrame;
+	re.EndFrame = SWimp_EndFrame;
+
+	re.AppActivate = SWimp_AppActivate;
+
+	Swap_Init ();
+
+	return re;
+}
+
+#ifndef REF_HARD_LINKED
+// this is only here so the functions in q_shared.c and q_shwin.c can link
+void Sys_Error (char *error, ...)
+{
+	va_list		argptr;
+	char		text[1024];
+
+	va_start (argptr, error);
+	vsprintf (text, error, argptr);
+	va_end (argptr);
+
+	ri.Sys_Error (ERR_FATAL, "%s", text);
+}
+
+void Com_Printf (char *fmt, ...)
+{
+	va_list		argptr;
+	char		text[1024];
+
+	va_start (argptr, fmt);
+	vsprintf (text, fmt, argptr);
+	va_end (argptr);
+
+	ri.Con_Printf (PRINT_ALL, "%s", text);
+}
+
+#endif
--- /dev/null
+++ b/ref/r_misc.c
@@ -1,0 +1,670 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_misc.c
+
+#include "r_local.h"
+
+#define NUM_MIPS	4
+
+cvar_t	*sw_mipcap;
+cvar_t	*sw_mipscale;
+
+surfcache_t		*d_initial_rover;
+qboolean		d_roverwrapped;
+int				d_minmip;
+float			d_scalemip[NUM_MIPS-1];
+
+static float	basemip[NUM_MIPS-1] = {1.0, 0.5*0.8, 0.25*0.8};
+
+extern int			d_aflatcolor;
+
+int	d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
+
+int	d_pix_min, d_pix_max, d_pix_shift;
+
+int		d_scantable[MAXHEIGHT];
+short	*zspantable[MAXHEIGHT]; 
+
+/*
+================
+D_Patch
+================
+*/
+void D_Patch (void)
+{
+#if id386
+	extern void D_Aff8Patch( void );
+	static qboolean protectset8 = false;
+	extern void D_PolysetAff8Start( void );
+
+	if (!protectset8)
+	{
+		Sys_MakeCodeWriteable ((int)D_PolysetAff8Start,
+						     (int)D_Aff8Patch - (int)D_PolysetAff8Start);
+		Sys_MakeCodeWriteable ((long)R_Surf8Start,
+						 (long)R_Surf8End - (long)R_Surf8Start);
+		protectset8 = true;
+	}
+	colormap = vid.colormap;
+
+	R_Surf8Patch ();
+	D_Aff8Patch();
+#endif
+}
+/*
+================
+D_ViewChanged
+================
+*/
+unsigned char *alias_colormap;
+
+void D_ViewChanged (void)
+{
+	int		i;
+
+	scale_for_mip = xscale;
+	if (yscale > xscale)
+		scale_for_mip = yscale;
+
+	d_zrowbytes = vid.width * 2;
+	d_zwidth = vid.width;
+
+	d_pix_min = r_refdef.vrect.width / 320;
+	if (d_pix_min < 1)
+		d_pix_min = 1;
+
+	d_pix_max = (int)((float)r_refdef.vrect.width / (320.0 / 4.0) + 0.5);
+	d_pix_shift = 8 - (int)((float)r_refdef.vrect.width / 320.0 + 0.5);
+	if (d_pix_max < 1)
+		d_pix_max = 1;
+
+	d_vrectx = r_refdef.vrect.x;
+	d_vrecty = r_refdef.vrect.y;
+	d_vrectright_particle = r_refdef.vrectright - d_pix_max;
+	d_vrectbottom_particle =
+			r_refdef.vrectbottom - d_pix_max;
+
+	for (i=0 ; i<vid.height; i++)
+	{
+		d_scantable[i] = i*r_screenwidth;
+		zspantable[i] = d_pzbuffer + i*d_zwidth;
+	}
+
+	/*
+	** clear Z-buffer and color-buffers if we're doing the gallery
+	*/
+	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
+	{
+		memset( d_pzbuffer, 0xff, vid.width * vid.height * sizeof( d_pzbuffer[0] ) );
+		Draw_Fill( r_newrefdef.x, r_newrefdef.y, r_newrefdef.width, r_newrefdef.height,( int ) sw_clearcolor->value & 0xff );
+	}
+
+	alias_colormap = vid.colormap;
+
+	D_Patch ();
+}
+
+
+
+/*
+=============
+R_PrintTimes
+=============
+*/
+void R_PrintTimes (void)
+{
+	int		r_time2;
+	int		ms;
+
+	r_time2 = Sys_Milliseconds ();
+
+	ms = r_time2 - r_time1;
+	
+	ri.Con_Printf (PRINT_ALL,"%5i ms %3i/%3i/%3i poly %3i surf\n",
+				ms, c_faceclip, r_polycount, r_drawnpolycount, c_surf);
+	c_surf = 0;
+}
+
+
+/*
+=============
+R_PrintDSpeeds
+=============
+*/
+void R_PrintDSpeeds (void)
+{
+	int	ms, dp_time, r_time2, rw_time, db_time, se_time, de_time, da_time;
+
+	r_time2 = Sys_Milliseconds ();
+
+	da_time = (da_time2 - da_time1);
+	dp_time = (dp_time2 - dp_time1);
+	rw_time = (rw_time2 - rw_time1);
+	db_time = (db_time2 - db_time1);
+	se_time = (se_time2 - se_time1);
+	de_time = (de_time2 - de_time1);
+	ms = (r_time2 - r_time1);
+
+	ri.Con_Printf (PRINT_ALL,"%3i %2ip %2iw %2ib %2is %2ie %2ia\n",
+				ms, dp_time, rw_time, db_time, se_time, de_time, da_time);
+}
+
+
+/*
+=============
+R_PrintAliasStats
+=============
+*/
+void R_PrintAliasStats (void)
+{
+	ri.Con_Printf (PRINT_ALL,"%3i polygon model drawn\n", r_amodels_drawn);
+}
+
+
+
+/*
+===================
+R_TransformFrustum
+===================
+*/
+void R_TransformFrustum (void)
+{
+	int		i;
+	vec3_t	v, v2;
+	
+	for (i=0 ; i<4 ; i++)
+	{
+		v[0] = screenedge[i].normal[2];
+		v[1] = -screenedge[i].normal[0];
+		v[2] = screenedge[i].normal[1];
+
+		v2[0] = v[1]*vright[0] + v[2]*vup[0] + v[0]*vpn[0];
+		v2[1] = v[1]*vright[1] + v[2]*vup[1] + v[0]*vpn[1];
+		v2[2] = v[1]*vright[2] + v[2]*vup[2] + v[0]*vpn[2];
+
+		VectorCopy (v2, view_clipplanes[i].normal);
+
+		view_clipplanes[i].dist = DotProduct (modelorg, v2);
+	}
+}
+
+
+#if !(defined __linux__ && defined __i386__)
+#if !id386
+
+/*
+================
+TransformVector
+================
+*/
+void TransformVector (vec3_t in, vec3_t out)
+{
+	out[0] = DotProduct(in,vright);
+	out[1] = DotProduct(in,vup);
+	out[2] = DotProduct(in,vpn);		
+}
+
+#else
+
+__declspec( naked ) void TransformVector( vec3_t vin, vec3_t vout )
+{
+	__asm mov eax, dword ptr [esp+4]
+	__asm mov edx, dword ptr [esp+8]
+
+	__asm fld  dword ptr [eax+0]
+	__asm fmul dword ptr [vright+0]
+	__asm fld  dword ptr [eax+0]
+	__asm fmul dword ptr [vup+0]
+	__asm fld  dword ptr [eax+0]
+	__asm fmul dword ptr [vpn+0]
+
+	__asm fld  dword ptr [eax+4]
+	__asm fmul dword ptr [vright+4]
+	__asm fld  dword ptr [eax+4]
+	__asm fmul dword ptr [vup+4]
+	__asm fld  dword ptr [eax+4]
+	__asm fmul dword ptr [vpn+4]
+
+	__asm fxch st(2)
+
+	__asm faddp st(5), st(0)
+	__asm faddp st(3), st(0)
+	__asm faddp st(1), st(0)
+
+	__asm fld  dword ptr [eax+8]
+	__asm fmul dword ptr [vright+8]
+	__asm fld  dword ptr [eax+8]
+	__asm fmul dword ptr [vup+8]
+	__asm fld  dword ptr [eax+8]
+	__asm fmul dword ptr [vpn+8]
+
+	__asm fxch st(2)
+
+	__asm faddp st(5), st(0)
+	__asm faddp st(3), st(0)
+	__asm faddp st(1), st(0)
+
+	__asm fstp dword ptr [edx+8]
+	__asm fstp dword ptr [edx+4]
+	__asm fstp dword ptr [edx+0]
+
+	__asm ret
+}
+
+#endif
+#endif
+
+
+/*
+================
+R_TransformPlane
+================
+*/
+void R_TransformPlane (mplane_t *p, float *normal, float *dist)
+{
+	float	d;
+	
+	d = DotProduct (r_origin, p->normal);
+	*dist = p->dist - d;
+// TODO: when we have rotating entities, this will need to use the view matrix
+	TransformVector (p->normal, normal);
+}
+
+
+/*
+===============
+R_SetUpFrustumIndexes
+===============
+*/
+void R_SetUpFrustumIndexes (void)
+{
+	int		i, j, *pindex;
+
+	pindex = r_frustum_indexes;
+
+	for (i=0 ; i<4 ; i++)
+	{
+		for (j=0 ; j<3 ; j++)
+		{
+			if (view_clipplanes[i].normal[j] < 0)
+			{
+				pindex[j] = j;
+				pindex[j+3] = j+3;
+			}
+			else
+			{
+				pindex[j] = j+3;
+				pindex[j+3] = j;
+			}
+		}
+
+	// FIXME: do just once at start
+		pfrustum_indexes[i] = pindex;
+		pindex += 6;
+	}
+}
+
+/*
+===============
+R_ViewChanged
+
+Called every time the vid structure or r_refdef changes.
+Guaranteed to be called before the first refresh
+===============
+*/
+void R_ViewChanged (vrect_t *vr)
+{
+	int		i;
+
+	r_refdef.vrect = *vr;
+
+	r_refdef.horizontalFieldOfView = 2*tan((float)r_newrefdef.fov_x/360*M_PI);;
+	verticalFieldOfView = 2*tan((float)r_newrefdef.fov_y/360*M_PI);
+
+	r_refdef.fvrectx = (float)r_refdef.vrect.x;
+	r_refdef.fvrectx_adj = (float)r_refdef.vrect.x - 0.5;
+	r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x<<20) + (1<<19) - 1;
+	r_refdef.fvrecty = (float)r_refdef.vrect.y;
+	r_refdef.fvrecty_adj = (float)r_refdef.vrect.y - 0.5;
+	r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width;
+	r_refdef.vrectright_adj_shift20 = (r_refdef.vrectright<<20) + (1<<19) - 1;
+	r_refdef.fvrectright = (float)r_refdef.vrectright;
+	r_refdef.fvrectright_adj = (float)r_refdef.vrectright - 0.5;
+	r_refdef.vrectrightedge = (float)r_refdef.vrectright - 0.99;
+	r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height;
+	r_refdef.fvrectbottom = (float)r_refdef.vrectbottom;
+	r_refdef.fvrectbottom_adj = (float)r_refdef.vrectbottom - 0.5;
+
+	r_refdef.aliasvrect.x = (int)(r_refdef.vrect.x * r_aliasuvscale);
+	r_refdef.aliasvrect.y = (int)(r_refdef.vrect.y * r_aliasuvscale);
+	r_refdef.aliasvrect.width = (int)(r_refdef.vrect.width * r_aliasuvscale);
+	r_refdef.aliasvrect.height = (int)(r_refdef.vrect.height * r_aliasuvscale);
+	r_refdef.aliasvrectright = r_refdef.aliasvrect.x +
+			r_refdef.aliasvrect.width;
+	r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y +
+			r_refdef.aliasvrect.height;
+
+	xOrigin = r_refdef.xOrigin;
+	yOrigin = r_refdef.yOrigin;
+	
+// values for perspective projection
+// if math were exact, the values would range from 0.5 to to range+0.5
+// hopefully they wll be in the 0.000001 to range+.999999 and truncate
+// the polygon rasterization will never render in the first row or column
+// but will definately render in the [range] row and column, so adjust the
+// buffer origin to get an exact edge to edge fill
+	xcenter = ((float)r_refdef.vrect.width * XCENTERING) +
+			r_refdef.vrect.x - 0.5;
+	aliasxcenter = xcenter * r_aliasuvscale;
+	ycenter = ((float)r_refdef.vrect.height * YCENTERING) +
+			r_refdef.vrect.y - 0.5;
+	aliasycenter = ycenter * r_aliasuvscale;
+
+	xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView;
+	aliasxscale = xscale * r_aliasuvscale;
+	xscaleinv = 1.0 / xscale;
+
+	yscale = xscale;
+	aliasyscale = yscale * r_aliasuvscale;
+	yscaleinv = 1.0 / yscale;
+	xscaleshrink = (r_refdef.vrect.width-6)/r_refdef.horizontalFieldOfView;
+	yscaleshrink = xscaleshrink;
+
+// left side clip
+	screenedge[0].normal[0] = -1.0 / (xOrigin*r_refdef.horizontalFieldOfView);
+	screenedge[0].normal[1] = 0;
+	screenedge[0].normal[2] = 1;
+	screenedge[0].type = PLANE_ANYZ;
+	
+// right side clip
+	screenedge[1].normal[0] =
+			1.0 / ((1.0-xOrigin)*r_refdef.horizontalFieldOfView);
+	screenedge[1].normal[1] = 0;
+	screenedge[1].normal[2] = 1;
+	screenedge[1].type = PLANE_ANYZ;
+	
+// top side clip
+	screenedge[2].normal[0] = 0;
+	screenedge[2].normal[1] = -1.0 / (yOrigin*verticalFieldOfView);
+	screenedge[2].normal[2] = 1;
+	screenedge[2].type = PLANE_ANYZ;
+	
+// bottom side clip
+	screenedge[3].normal[0] = 0;
+	screenedge[3].normal[1] = 1.0 / ((1.0-yOrigin)*verticalFieldOfView);
+	screenedge[3].normal[2] = 1;	
+	screenedge[3].type = PLANE_ANYZ;
+	
+	for (i=0 ; i<4 ; i++)
+		VectorNormalize (screenedge[i].normal);
+
+	D_ViewChanged ();
+}
+
+
+/*
+===============
+R_SetupFrame
+===============
+*/
+void R_SetupFrame (void)
+{
+	int			i;
+	vrect_t		vrect;
+
+	if (r_fullbright->modified)
+	{
+		r_fullbright->modified = false;
+		D_FlushCaches ();	// so all lighting changes
+	}
+	
+	r_framecount++;
+
+
+// build the transformation matrix for the given view angles
+	VectorCopy (r_refdef.vieworg, modelorg);
+	VectorCopy (r_refdef.vieworg, r_origin);
+
+	AngleVectors (r_refdef.viewangles, vpn, vright, vup);
+
+// current viewleaf
+	if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
+	{
+		r_viewleaf = Mod_PointInLeaf (r_origin, r_worldmodel);
+		r_viewcluster = r_viewleaf->cluster;
+	}
+
+	if (sw_waterwarp->value && (r_newrefdef.rdflags & RDF_UNDERWATER) )
+		r_dowarp = true;
+	else
+		r_dowarp = false;
+
+	if (r_dowarp)
+	{	// warp into off screen buffer
+		vrect.x = 0;
+		vrect.y = 0;
+		vrect.width = r_newrefdef.width < WARP_WIDTH ? r_newrefdef.width : WARP_WIDTH;
+		vrect.height = r_newrefdef.height < WARP_HEIGHT ? r_newrefdef.height : WARP_HEIGHT;
+
+		d_viewbuffer = r_warpbuffer;
+		r_screenwidth = WARP_WIDTH;
+	}
+	else
+	{
+		vrect.x = r_newrefdef.x;
+		vrect.y = r_newrefdef.y;
+		vrect.width = r_newrefdef.width;
+		vrect.height = r_newrefdef.height;
+
+		d_viewbuffer = (void *)vid.buffer;
+		r_screenwidth = vid.rowbytes;
+	}
+	
+	R_ViewChanged (&vrect);
+
+// start off with just the four screen edge clip planes
+	R_TransformFrustum ();
+	R_SetUpFrustumIndexes ();
+
+// save base values
+	VectorCopy (vpn, base_vpn);
+	VectorCopy (vright, base_vright);
+	VectorCopy (vup, base_vup);
+
+// clear frame counts
+	c_faceclip = 0;
+	d_spanpixcount = 0;
+	r_polycount = 0;
+	r_drawnpolycount = 0;
+	r_wholepolycount = 0;
+	r_amodels_drawn = 0;
+	r_outofsurfaces = 0;
+	r_outofedges = 0;
+
+// d_setup
+	d_roverwrapped = false;
+	d_initial_rover = sc_rover;
+
+	d_minmip = sw_mipcap->value;
+	if (d_minmip > 3)
+		d_minmip = 3;
+	else if (d_minmip < 0)
+		d_minmip = 0;
+
+	for (i=0 ; i<(NUM_MIPS-1) ; i++)
+		d_scalemip[i] = basemip[i] * sw_mipscale->value;
+
+	d_aflatcolor = 0;
+}
+
+
+#if	!id386
+
+/*
+================
+R_SurfacePatch
+================
+*/
+void R_SurfacePatch (void)
+{
+	// we only patch code on Intel
+}
+
+#endif	// !id386
+
+
+/* 
+============================================================================== 
+ 
+						SCREEN SHOTS 
+ 
+============================================================================== 
+*/ 
+
+
+/* 
+============== 
+WritePCXfile 
+============== 
+*/ 
+void WritePCXfile (char *filename, byte *data, int width, int height,
+	int rowbytes, byte *palette) 
+{
+	int			i, j, length;
+	pcx_t		*pcx;
+	byte		*pack;
+	FILE		*f;
+
+	pcx = (pcx_t *)malloc (width*height*2+1000);
+	if (!pcx)
+		return;
+
+	pcx->manufacturer = 0x0a;	// PCX id
+	pcx->version = 5;			// 256 color
+ 	pcx->encoding = 1;		// uncompressed
+	pcx->bits_per_pixel = 8;		// 256 color
+	pcx->xmin = 0;
+	pcx->ymin = 0;
+	pcx->xmax = LittleShort((short)(width-1));
+	pcx->ymax = LittleShort((short)(height-1));
+	pcx->hres = LittleShort((short)width);
+	pcx->vres = LittleShort((short)height);
+	memset (pcx->palette,0,sizeof(pcx->palette));
+	pcx->color_planes = 1;		// chunky image
+	pcx->bytes_per_line = LittleShort((short)width);
+	pcx->palette_type = LittleShort(2);		// not a grey scale
+	memset (pcx->filler,0,sizeof(pcx->filler));
+
+// pack the image
+	pack = &pcx->data;
+	
+	for (i=0 ; i<height ; i++)
+	{
+		for (j=0 ; j<width ; j++)
+		{
+			if ( (*data & 0xc0) != 0xc0)
+				*pack++ = *data++;
+			else
+			{
+				*pack++ = 0xc1;
+				*pack++ = *data++;
+			}
+		}
+
+		data += rowbytes - width;
+	}
+			
+// write the palette
+	*pack++ = 0x0c;	// palette ID byte
+	for (i=0 ; i<768 ; i++)
+		*pack++ = *palette++;
+		
+// write output file 
+	length = pack - (byte *)pcx;
+	f = fopen (filename, "wb");
+	if (!f)
+		ri.Con_Printf (PRINT_ALL, "Failed to open to %s\n", filename);
+	else
+	{
+		fwrite ((void *)pcx, 1, length, f);
+		fclose (f);
+	}
+
+	free (pcx);
+} 
+ 
+
+
+/* 
+================== 
+R_ScreenShot_f
+================== 
+*/  
+void R_ScreenShot_f (void) 
+{ 
+	int			i; 
+	char		pcxname[80]; 
+	char		checkname[MAX_OSPATH];
+	FILE		*f;
+	byte		palette[768];
+
+	// create the scrnshots directory if it doesn't exist
+	Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir());
+	Sys_Mkdir (checkname);
+
+// 
+// find a file name to save it to 
+// 
+	strcpy(pcxname,"quake00.pcx");
+		
+	for (i=0 ; i<=99 ; i++) 
+	{ 
+		pcxname[5] = i/10 + '0'; 
+		pcxname[6] = i%10 + '0'; 
+		Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), pcxname);
+		f = fopen (checkname, "r");
+		if (!f)
+			break;	// file doesn't exist
+		fclose (f);
+	} 
+	if (i==100) 
+	{
+		ri.Con_Printf (PRINT_ALL, "R_ScreenShot_f: Couldn't create a PCX"); 
+		return;
+	}
+
+	// turn the current 32 bit palette into a 24 bit palette
+	for (i=0 ; i<256 ; i++)
+	{
+		palette[i*3+0] = sw_state.currentpalette[i*4+0];
+		palette[i*3+1] = sw_state.currentpalette[i*4+1];
+		palette[i*3+2] = sw_state.currentpalette[i*4+2];
+	}
+
+// 
+// save the pcx file 
+// 
+
+	WritePCXfile (checkname, vid.buffer, vid.width, vid.height, vid.rowbytes,
+				  palette);
+
+	ri.Con_Printf (PRINT_ALL, "Wrote %s\n", checkname);
+} 
+
--- /dev/null
+++ b/ref/r_model.c
@@ -1,0 +1,1241 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// models.c -- model loading and caching
+
+// models are the only shared resource between a client and server running
+// on the same machine.
+
+#include "r_local.h"
+
+model_t	*loadmodel;
+char	loadname[32];	// for hunk tags
+
+void Mod_LoadSpriteModel (model_t *mod, void *buffer);
+void Mod_LoadBrushModel (model_t *mod, void *buffer);
+void Mod_LoadAliasModel (model_t *mod, void *buffer);
+model_t *Mod_LoadModel (model_t *mod, qboolean crash);
+
+byte	mod_novis[MAX_MAP_LEAFS/8];
+
+#define	MAX_MOD_KNOWN	256
+model_t	mod_known[MAX_MOD_KNOWN];
+int		mod_numknown;
+
+// the inline * models from the current map are kept seperate
+model_t	mod_inline[MAX_MOD_KNOWN];
+
+int		registration_sequence;
+int		modfilelen;
+
+//===============================================================================
+
+
+/*
+================
+Mod_Modellist_f
+================
+*/
+void Mod_Modellist_f (void)
+{
+	int		i;
+	model_t	*mod;
+	int		total;
+
+	total = 0;
+	ri.Con_Printf (PRINT_ALL,"Loaded models:\n");
+	for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
+	{
+		if (!mod->name[0])
+			continue;
+		ri.Con_Printf (PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);
+		total += mod->extradatasize;
+	}
+	ri.Con_Printf (PRINT_ALL, "Total resident: %i\n", total);
+}
+
+/*
+===============
+Mod_Init
+===============
+*/
+void Mod_Init (void)
+{
+	memset (mod_novis, 0xff, sizeof(mod_novis));
+}
+
+/*
+==================
+Mod_ForName
+
+Loads in a model for the given name
+==================
+*/
+model_t *Mod_ForName (char *name, qboolean crash)
+{
+	model_t	*mod;
+	unsigned *buf;
+	int		i;
+	
+	if (!name[0])
+		ri.Sys_Error (ERR_DROP,"Mod_ForName: NULL name");
+
+	//
+	// inline models are grabbed only from worldmodel
+	//
+	if (name[0] == '*')
+	{
+		i = atoi(name+1);
+		if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
+			ri.Sys_Error (ERR_DROP, "bad inline model number");
+		return &mod_inline[i];
+	}
+
+	//
+	// search the currently loaded models
+	//
+	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
+		if (!strcmp (mod->name, name) )
+			return mod;
+			
+	//
+	// find a free model slot spot
+	//
+	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
+	{
+		if (!mod->name[0])
+			break;	// free spot
+	}
+	if (i == mod_numknown)
+	{
+		if (mod_numknown == MAX_MOD_KNOWN)
+			ri.Sys_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
+		mod_numknown++;
+	}
+	strcpy (mod->name, name);
+	
+	//
+	// load the file
+	//
+	modfilelen = ri.FS_LoadFile (mod->name, (void **)&buf);
+	if (!buf)
+	{
+		if (crash)
+			ri.Sys_Error (ERR_DROP,"Mod_NumForName: %s not found", mod->name);
+		memset (mod->name, 0, sizeof(mod->name));
+		return NULL;
+	}
+	
+	loadmodel = mod;
+
+	//
+	// fill it in
+	//
+
+	// call the apropriate loader
+	
+	switch (LittleLong(*(unsigned *)buf))
+	{
+	case IDALIASHEADER:
+		loadmodel->extradata = Hunk_Begin (0x200000);
+		Mod_LoadAliasModel (mod, buf);
+		break;
+		
+	case IDSPRITEHEADER:
+		loadmodel->extradata = Hunk_Begin (0x10000);
+		Mod_LoadSpriteModel (mod, buf);
+		break;
+	
+	case IDBSPHEADER:
+		loadmodel->extradata = Hunk_Begin (0x1000000);
+		Mod_LoadBrushModel (mod, buf);
+		break;
+
+	default:
+		ri.Sys_Error (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name);
+		break;
+	}
+
+	loadmodel->extradatasize = Hunk_End ();
+
+	ri.FS_FreeFile (buf);
+
+	return mod;
+}
+
+
+/*
+===============
+Mod_PointInLeaf
+===============
+*/
+mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
+{
+	mnode_t		*node;
+	float		d;
+	mplane_t	*plane;
+	
+	if (!model || !model->nodes)
+		ri.Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model");
+
+	node = model->nodes;
+	while (1)
+	{
+		if (node->contents != -1)
+			return (mleaf_t *)node;
+		plane = node->plane;
+		d = DotProduct (p,plane->normal) - plane->dist;
+		if (d > 0)
+			node = node->children[0];
+		else
+			node = node->children[1];
+	}
+	
+	return NULL;	// never reached
+}
+
+
+/*
+===================
+Mod_DecompressVis
+===================
+*/
+byte *Mod_DecompressVis (byte *in, model_t *model)
+{
+	static byte	decompressed[MAX_MAP_LEAFS/8];
+	int		c;
+	byte	*out;
+	int		row;
+
+	row = (model->vis->numclusters+7)>>3;	
+	out = decompressed;
+
+#if 0
+	memcpy (out, in, row);
+#else
+	if (!in)
+	{	// no vis info, so make all visible
+		while (row)
+		{
+			*out++ = 0xff;
+			row--;
+		}
+		return decompressed;		
+	}
+
+	do
+	{
+		if (*in)
+		{
+			*out++ = *in++;
+			continue;
+		}
+	
+		c = in[1];
+		in += 2;
+		while (c)
+		{
+			*out++ = 0;
+			c--;
+		}
+	} while (out - decompressed < row);
+#endif
+	
+	return decompressed;
+}
+
+/*
+==============
+Mod_ClusterPVS
+==============
+*/
+byte *Mod_ClusterPVS (int cluster, model_t *model)
+{
+	if (cluster == -1 || !model->vis)
+		return mod_novis;
+	return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS],
+		model);
+}
+
+/*
+===============================================================================
+
+					BRUSHMODEL LOADING
+
+===============================================================================
+*/
+
+byte	*mod_base;
+
+
+/*
+=================
+Mod_LoadLighting
+
+Converts the 24 bit lighting down to 8 bit
+by taking the brightest component
+=================
+*/
+void Mod_LoadLighting (lump_t *l)
+{
+	int		i, size;
+	byte	*in;
+
+	if (!l->filelen)
+	{
+		loadmodel->lightdata = NULL;
+		return;
+	}
+	size = l->filelen/3;
+	loadmodel->lightdata = Hunk_Alloc (size);
+	in = (void *)(mod_base + l->fileofs);
+	for (i=0 ; i<size ; i++, in+=3)
+	{
+		if (in[0] > in[1] && in[0] > in[2])
+			loadmodel->lightdata[i] = in[0];
+		else if (in[1] > in[0] && in[1] > in[2])
+			loadmodel->lightdata[i] = in[1];
+		else
+			loadmodel->lightdata[i] = in[2];
+	}
+}
+
+
+int		r_leaftovis[MAX_MAP_LEAFS];
+int		r_vistoleaf[MAX_MAP_LEAFS];
+int		r_numvisleafs;
+
+void	R_NumberLeafs (mnode_t *node)
+{
+	mleaf_t	*leaf;
+	int		leafnum;
+
+	if (node->contents != -1)
+	{
+		leaf = (mleaf_t *)node;
+		leafnum = leaf - loadmodel->leafs;
+		if (leaf->contents & CONTENTS_SOLID)
+			return;
+		r_leaftovis[leafnum] = r_numvisleafs;
+		r_vistoleaf[r_numvisleafs] = leafnum;
+		r_numvisleafs++;
+		return;
+	}
+
+	R_NumberLeafs (node->children[0]);
+	R_NumberLeafs (node->children[1]);
+}
+
+
+/*
+=================
+Mod_LoadVisibility
+=================
+*/
+void Mod_LoadVisibility (lump_t *l)
+{
+	int		i;
+
+	if (!l->filelen)
+	{
+		loadmodel->vis = NULL;
+		return;
+	}
+	loadmodel->vis = Hunk_Alloc ( l->filelen);	
+	memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen);
+
+	loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters);
+	for (i=0 ; i<loadmodel->vis->numclusters ; i++)
+	{
+		loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]);
+		loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]);
+	}
+}
+
+
+/*
+=================
+Mod_LoadVertexes
+=================
+*/
+void Mod_LoadVertexes (lump_t *l)
+{
+	dvertex_t	*in;
+	mvertex_t	*out;
+	int			i, count;
+
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( (count+8)*sizeof(*out));		// extra for skybox
+
+	loadmodel->vertexes = out;
+	loadmodel->numvertexes = count;
+
+	for ( i=0 ; i<count ; i++, in++, out++)
+	{
+		out->position[0] = LittleFloat (in->point[0]);
+		out->position[1] = LittleFloat (in->point[1]);
+		out->position[2] = LittleFloat (in->point[2]);
+	}
+}
+
+/*
+=================
+Mod_LoadSubmodels
+=================
+*/
+void Mod_LoadSubmodels (lump_t *l)
+{
+	dmodel_t	*in;
+	dmodel_t	*out;
+	int			i, j, count;
+
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( count*sizeof(*out));	
+
+	loadmodel->submodels = out;
+	loadmodel->numsubmodels = count;
+
+	for ( i=0 ; i<count ; i++, in++, out++)
+	{
+		for (j=0 ; j<3 ; j++)
+		{	// spread the mins / maxs by a pixel
+			out->mins[j] = LittleFloat (in->mins[j]) - 1;
+			out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
+			out->origin[j] = LittleFloat (in->origin[j]);
+		}
+		out->headnode = LittleLong (in->headnode);
+		out->firstface = LittleLong (in->firstface);
+		out->numfaces = LittleLong (in->numfaces);
+	}
+}
+
+/*
+=================
+Mod_LoadEdges
+=================
+*/
+void Mod_LoadEdges (lump_t *l)
+{
+	dedge_t *in;
+	medge_t *out;
+	int 	i, count;
+
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( (count + 13) * sizeof(*out));	// extra for skybox
+
+	loadmodel->edges = out;
+	loadmodel->numedges = count;
+
+	for ( i=0 ; i<count ; i++, in++, out++)
+	{
+		out->v[0] = (unsigned short)LittleShort(in->v[0]);
+		out->v[1] = (unsigned short)LittleShort(in->v[1]);
+	}
+}
+
+/*
+=================
+Mod_LoadTexinfo
+=================
+*/
+void Mod_LoadTexinfo (lump_t *l)
+{
+	texinfo_t *in;
+	mtexinfo_t *out, *step;
+	int 	i, j, count;
+	float	len1, len2;
+	char	name[MAX_QPATH];
+	int		next;
+
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( (count+6)*sizeof(*out));	// extra for skybox
+
+	loadmodel->texinfo = out;
+	loadmodel->numtexinfo = count;
+
+	for ( i=0 ; i<count ; i++, in++, out++)
+	{
+		for (j=0 ; j<8 ; j++)
+			out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
+		len1 = VectorLength (out->vecs[0]);
+		len2 = VectorLength (out->vecs[1]);
+		len1 = (len1 + len2)/2;
+		if (len1 < 0.32)
+			out->mipadjust = 4;
+		else if (len1 < 0.49)
+			out->mipadjust = 3;
+		else if (len1 < 0.99)
+			out->mipadjust = 2;
+		else
+			out->mipadjust = 1;
+#if 0
+		if (len1 + len2 < 0.001)
+			out->mipadjust = 1;		// don't crash
+		else
+			out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
+#endif
+
+		out->flags = LittleLong (in->flags);
+
+		next = LittleLong (in->nexttexinfo);
+		if (next > 0)
+			out->next = loadmodel->texinfo + next;
+
+		Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);
+		out->image = R_FindImage (name, it_wall);
+		if (!out->image)
+		{
+			out->image = r_notexture_mip; // texture not found
+			out->flags = 0;
+		}
+	}
+
+	// count animation frames
+	for (i=0 ; i<count ; i++)
+	{
+		out = &loadmodel->texinfo[i];
+		out->numframes = 1;
+		for (step = out->next ; step && step != out ; step=step->next)
+			out->numframes++;
+	}
+}
+
+/*
+================
+CalcSurfaceExtents
+
+Fills in s->texturemins[] and s->extents[]
+================
+*/
+void CalcSurfaceExtents (msurface_t *s)
+{
+	float	mins[2], maxs[2], val;
+	int		i,j, e;
+	mvertex_t	*v;
+	mtexinfo_t	*tex;
+	int		bmins[2], bmaxs[2];
+
+	mins[0] = mins[1] = 999999;
+	maxs[0] = maxs[1] = -99999;
+
+	tex = s->texinfo;
+	
+	for (i=0 ; i<s->numedges ; i++)
+	{
+		e = loadmodel->surfedges[s->firstedge+i];
+		if (e >= 0)
+			v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
+		else
+			v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
+		
+		for (j=0 ; j<2 ; j++)
+		{
+			val = v->position[0] * tex->vecs[j][0] + 
+				v->position[1] * tex->vecs[j][1] +
+				v->position[2] * tex->vecs[j][2] +
+				tex->vecs[j][3];
+			if (val < mins[j])
+				mins[j] = val;
+			if (val > maxs[j])
+				maxs[j] = val;
+		}
+	}
+
+	for (i=0 ; i<2 ; i++)
+	{	
+		bmins[i] = floor(mins[i]/16);
+		bmaxs[i] = ceil(maxs[i]/16);
+
+		s->texturemins[i] = bmins[i] * 16;
+		s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
+		if (s->extents[i] < 16)
+			s->extents[i] = 16;	// take at least one cache block
+		if ( !(tex->flags & (SURF_WARP|SURF_SKY)) && s->extents[i] > 256)
+			ri.Sys_Error (ERR_DROP,"Bad surface extents");
+	}
+}
+
+
+/*
+=================
+Mod_LoadFaces
+=================
+*/
+void Mod_LoadFaces (lump_t *l)
+{
+	dface_t		*in;
+	msurface_t 	*out;
+	int			i, count, surfnum;
+	int			planenum, side;
+
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( (count+6)*sizeof(*out));	// extra for skybox
+
+	loadmodel->surfaces = out;
+	loadmodel->numsurfaces = count;
+
+	for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
+	{
+		out->firstedge = LittleLong(in->firstedge);
+		out->numedges = LittleShort(in->numedges);		
+		if (out->numedges < 3)
+			ri.Sys_Error (ERR_DROP,"Surface with %s edges", out->numedges);
+		out->flags = 0;
+
+		planenum = LittleShort(in->planenum);
+		side = LittleShort(in->side);
+		if (side)
+			out->flags |= SURF_PLANEBACK;			
+
+		out->plane = loadmodel->planes + planenum;
+
+		out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
+
+		CalcSurfaceExtents (out);
+				
+	// lighting info is converted from 24 bit on disk to 8 bit
+
+		for (i=0 ; i<MAXLIGHTMAPS ; i++)
+			out->styles[i] = in->styles[i];
+		i = LittleLong(in->lightofs);
+		if (i == -1)
+			out->samples = NULL;
+		else
+			out->samples = loadmodel->lightdata + i/3;
+		
+	// set the drawing flags flag
+		
+		if (!out->texinfo->image)
+			continue;
+		if (out->texinfo->flags & SURF_SKY)
+		{
+			out->flags |= SURF_DRAWSKY;
+			continue;
+		}
+		
+		if (out->texinfo->flags & SURF_WARP)
+		{
+			out->flags |= SURF_DRAWTURB;
+			for (i=0 ; i<2 ; i++)
+			{
+				out->extents[i] = 16384;
+				out->texturemins[i] = -8192;
+			}
+			continue;
+		}
+//==============
+//PGM
+		// this marks flowing surfaces as turbulent, but with the new
+		// SURF_FLOW flag.
+		if (out->texinfo->flags & SURF_FLOWING)
+		{
+			out->flags |= SURF_DRAWTURB | SURF_FLOW;
+			for (i=0 ; i<2 ; i++)
+			{
+				out->extents[i] = 16384;
+				out->texturemins[i] = -8192;
+			}
+			continue;
+		}
+//PGM
+//==============
+	}
+}
+
+
+/*
+=================
+Mod_SetParent
+=================
+*/
+void Mod_SetParent (mnode_t *node, mnode_t *parent)
+{
+	node->parent = parent;
+	if (node->contents != -1)
+		return;
+	Mod_SetParent (node->children[0], node);
+	Mod_SetParent (node->children[1], node);
+}
+
+/*
+=================
+Mod_LoadNodes
+=================
+*/
+void Mod_LoadNodes (lump_t *l)
+{
+	int			i, j, count, p;
+	dnode_t		*in;
+	mnode_t 	*out;
+
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( count*sizeof(*out));	
+
+	loadmodel->nodes = out;
+	loadmodel->numnodes = count;
+
+	for ( i=0 ; i<count ; i++, in++, out++)
+	{
+		for (j=0 ; j<3 ; j++)
+		{
+			out->minmaxs[j] = LittleShort (in->mins[j]);
+			out->minmaxs[3+j] = LittleShort (in->maxs[j]);
+		}
+	
+		p = LittleLong(in->planenum);
+		out->plane = loadmodel->planes + p;
+
+		out->firstsurface = LittleShort (in->firstface);
+		out->numsurfaces = LittleShort (in->numfaces);
+		out->contents = CONTENTS_NODE;	// differentiate from leafs
+		
+		for (j=0 ; j<2 ; j++)
+		{
+			p = LittleLong (in->children[j]);
+			if (p >= 0)
+				out->children[j] = loadmodel->nodes + p;
+			else
+				out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
+		}
+	}
+	
+	Mod_SetParent (loadmodel->nodes, NULL);	// sets nodes and leafs
+}
+
+/*
+=================
+Mod_LoadLeafs
+=================
+*/
+void Mod_LoadLeafs (lump_t *l)
+{
+	dleaf_t 	*in;
+	mleaf_t 	*out;
+	int			i, j, count;
+
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( count*sizeof(*out));
+
+	loadmodel->leafs = out;
+	loadmodel->numleafs = count;
+
+	for ( i=0 ; i<count ; i++, in++, out++)
+	{
+		for (j=0 ; j<3 ; j++)
+		{
+			out->minmaxs[j] = LittleShort (in->mins[j]);
+			out->minmaxs[3+j] = LittleShort (in->maxs[j]);
+		}
+
+		out->contents = LittleLong(in->contents);
+		out->cluster = LittleShort(in->cluster);
+		out->area = LittleShort(in->area);
+
+		out->firstmarksurface = loadmodel->marksurfaces +
+			LittleShort(in->firstleafface);
+		out->nummarksurfaces = LittleShort(in->numleaffaces);
+	}	
+}
+
+
+/*
+=================
+Mod_LoadMarksurfaces
+=================
+*/
+void Mod_LoadMarksurfaces (lump_t *l)
+{	
+	int		i, j, count;
+	short		*in;
+	msurface_t **out;
+	
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( count*sizeof(*out));	
+
+	loadmodel->marksurfaces = out;
+	loadmodel->nummarksurfaces = count;
+
+	for ( i=0 ; i<count ; i++)
+	{
+		j = LittleShort(in[i]);
+		if (j >= loadmodel->numsurfaces)
+			ri.Sys_Error (ERR_DROP,"Mod_ParseMarksurfaces: bad surface number");
+		out[i] = loadmodel->surfaces + j;
+	}
+}
+
+/*
+=================
+Mod_LoadSurfedges
+=================
+*/
+void Mod_LoadSurfedges (lump_t *l)
+{	
+	int		i, count;
+	int		*in, *out;
+	
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( (count+24)*sizeof(*out));	// extra for skybox
+
+	loadmodel->surfedges = out;
+	loadmodel->numsurfedges = count;
+
+	for ( i=0 ; i<count ; i++)
+		out[i] = LittleLong (in[i]);
+}
+
+/*
+=================
+Mod_LoadPlanes
+=================
+*/
+void Mod_LoadPlanes (lump_t *l)
+{
+	int			i, j;
+	mplane_t	*out;
+	dplane_t 	*in;
+	int			count;
+	int			bits;
+	
+	in = (void *)(mod_base + l->fileofs);
+	if (l->filelen % sizeof(*in))
+		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
+	count = l->filelen / sizeof(*in);
+	out = Hunk_Alloc ( (count+6)*sizeof(*out));		// extra for skybox
+	
+	loadmodel->planes = out;
+	loadmodel->numplanes = count;
+
+	for ( i=0 ; i<count ; i++, in++, out++)
+	{
+		bits = 0;
+		for (j=0 ; j<3 ; j++)
+		{
+			out->normal[j] = LittleFloat (in->normal[j]);
+			if (out->normal[j] < 0)
+				bits |= 1<<j;
+		}
+
+		out->dist = LittleFloat (in->dist);
+		out->type = LittleLong (in->type);
+		out->signbits = bits;
+	}
+}
+
+
+/*
+=================
+Mod_LoadBrushModel
+=================
+*/
+void Mod_LoadBrushModel (model_t *mod, void *buffer)
+{
+	int			i;
+	dheader_t	*header;
+	dmodel_t 	*bm;
+	
+	loadmodel->type = mod_brush;
+	if (loadmodel != mod_known)
+		ri.Sys_Error (ERR_DROP, "Loaded a brush model after the world");
+	
+	header = (dheader_t *)buffer;
+
+	i = LittleLong (header->version);
+	if (i != BSPVERSION)
+		ri.Sys_Error (ERR_DROP,"Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
+
+// swap all the lumps
+	mod_base = (byte *)header;
+
+	for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
+		((int *)header)[i] = LittleLong ( ((int *)header)[i]);
+
+// load into heap
+	
+	Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
+	Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
+	Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
+	Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
+	Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
+	Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
+	Mod_LoadFaces (&header->lumps[LUMP_FACES]);
+	Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]);
+	Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
+	Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
+	Mod_LoadNodes (&header->lumps[LUMP_NODES]);
+	Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
+	r_numvisleafs = 0;
+	R_NumberLeafs (loadmodel->nodes);
+	
+//
+// set up the submodels
+//
+	for (i=0 ; i<mod->numsubmodels ; i++)
+	{
+		model_t	*starmod;
+
+		bm = &mod->submodels[i];
+		starmod = &mod_inline[i];
+
+		*starmod = *loadmodel;
+		
+		starmod->firstmodelsurface = bm->firstface;
+		starmod->nummodelsurfaces = bm->numfaces;
+		starmod->firstnode = bm->headnode;
+		if (starmod->firstnode >= loadmodel->numnodes)
+			ri.Sys_Error (ERR_DROP, "Inline model %i has bad firstnode", i);
+
+		VectorCopy (bm->maxs, starmod->maxs);
+		VectorCopy (bm->mins, starmod->mins);
+	
+		if (i == 0)
+			*loadmodel = *starmod;
+	}
+
+	R_InitSkyBox ();
+}
+
+/*
+==============================================================================
+
+ALIAS MODELS
+
+==============================================================================
+*/
+
+/*
+=================
+Mod_LoadAliasModel
+=================
+*/
+void Mod_LoadAliasModel (model_t *mod, void *buffer)
+{
+	int					i, j;
+	dmdl_t				*pinmodel, *pheader;
+	dstvert_t			*pinst, *poutst;
+	dtriangle_t			*pintri, *pouttri;
+	daliasframe_t		*pinframe, *poutframe;
+	int					*pincmd, *poutcmd;
+	int					version;
+
+	pinmodel = (dmdl_t *)buffer;
+
+	version = LittleLong (pinmodel->version);
+	if (version != ALIAS_VERSION)
+		ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
+				 mod->name, version, ALIAS_VERSION);
+
+	pheader = Hunk_Alloc (LittleLong(pinmodel->ofs_end));
+	
+	// byte swap the header fields and sanity check
+	for (i=0 ; i<sizeof(dmdl_t)/4 ; i++)
+		((int *)pheader)[i] = LittleLong (((int *)buffer)[i]);
+
+	if (pheader->skinheight > MAX_LBM_HEIGHT)
+		ri.Sys_Error (ERR_DROP, "model %s has a skin taller than %d", mod->name,
+				   MAX_LBM_HEIGHT);
+
+	if (pheader->num_xyz <= 0)
+		ri.Sys_Error (ERR_DROP, "model %s has no vertices", mod->name);
+
+	if (pheader->num_xyz > MAX_VERTS)
+		ri.Sys_Error (ERR_DROP, "model %s has too many vertices", mod->name);
+
+	if (pheader->num_st <= 0)
+		ri.Sys_Error (ERR_DROP, "model %s has no st vertices", mod->name);
+
+	if (pheader->num_tris <= 0)
+		ri.Sys_Error (ERR_DROP, "model %s has no triangles", mod->name);
+
+	if (pheader->num_frames <= 0)
+		ri.Sys_Error (ERR_DROP, "model %s has no frames", mod->name);
+
+//
+// load base s and t vertices (not used in gl version)
+//
+	pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st);
+	poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
+
+	for (i=0 ; i<pheader->num_st ; i++)
+	{
+		poutst[i].s = LittleShort (pinst[i].s);
+		poutst[i].t = LittleShort (pinst[i].t);
+	}
+
+//
+// load triangle lists
+//
+	pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris);
+	pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
+
+	for (i=0 ; i<pheader->num_tris ; i++)
+	{
+		for (j=0 ; j<3 ; j++)
+		{
+			pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
+			pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
+		}
+	}
+
+//
+// load the frames
+//
+	for (i=0 ; i<pheader->num_frames ; i++)
+	{
+		pinframe = (daliasframe_t *) ((byte *)pinmodel 
+			+ pheader->ofs_frames + i * pheader->framesize);
+		poutframe = (daliasframe_t *) ((byte *)pheader 
+			+ pheader->ofs_frames + i * pheader->framesize);
+
+		memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
+		for (j=0 ; j<3 ; j++)
+		{
+			poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
+			poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
+		}
+		// verts are all 8 bit, so no swapping needed
+		memcpy (poutframe->verts, pinframe->verts, 
+			pheader->num_xyz*sizeof(dtrivertx_t));
+
+	}
+
+	mod->type = mod_alias;
+
+	//
+	// load the glcmds
+	//
+	pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds);
+	poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds);
+	for (i=0 ; i<pheader->num_glcmds ; i++)
+		poutcmd[i] = LittleLong (pincmd[i]);
+
+
+	// register all skins
+	memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins,
+		pheader->num_skins*MAX_SKINNAME);
+	for (i=0 ; i<pheader->num_skins ; i++)
+	{
+		mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
+	}
+}
+
+/*
+==============================================================================
+
+SPRITE MODELS
+
+==============================================================================
+*/
+
+/*
+=================
+Mod_LoadSpriteModel
+=================
+*/
+void Mod_LoadSpriteModel (model_t *mod, void *buffer)
+{
+	dsprite_t	*sprin, *sprout;
+	int			i;
+
+	sprin = (dsprite_t *)buffer;
+	sprout = Hunk_Alloc (modfilelen);
+
+	sprout->ident = LittleLong (sprin->ident);
+	sprout->version = LittleLong (sprin->version);
+	sprout->numframes = LittleLong (sprin->numframes);
+
+	if (sprout->version != SPRITE_VERSION)
+		ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
+				 mod->name, sprout->version, SPRITE_VERSION);
+
+	if (sprout->numframes > MAX_MD2SKINS)
+		ri.Sys_Error (ERR_DROP, "%s has too many frames (%i > %i)",
+				 mod->name, sprout->numframes, MAX_MD2SKINS);
+
+	// byte swap everything
+	for (i=0 ; i<sprout->numframes ; i++)
+	{
+		sprout->frames[i].width = LittleLong (sprin->frames[i].width);
+		sprout->frames[i].height = LittleLong (sprin->frames[i].height);
+		sprout->frames[i].origin_x = LittleLong (sprin->frames[i].origin_x);
+		sprout->frames[i].origin_y = LittleLong (sprin->frames[i].origin_y);
+		memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME);
+		mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite);
+	}
+
+	mod->type = mod_sprite;
+}
+
+//=============================================================================
+
+/*
+@@@@@@@@@@@@@@@@@@@@@
+R_BeginRegistration
+
+Specifies the model that will be used as the world
+@@@@@@@@@@@@@@@@@@@@@
+*/
+void R_BeginRegistration (char *model)
+{
+	char	fullname[MAX_QPATH];
+	cvar_t	*flushmap;
+
+	registration_sequence++;
+	r_oldviewcluster = -1;		// force markleafs
+	Com_sprintf (fullname, sizeof(fullname), "maps/%s.bsp", model);
+
+	D_FlushCaches ();
+	// explicitly free the old map if different
+	// this guarantees that mod_known[0] is the world map
+	flushmap = ri.Cvar_Get ("flushmap", "0", 0);
+	if ( strcmp(mod_known[0].name, fullname) || flushmap->value)
+		Mod_Free (&mod_known[0]);
+	r_worldmodel = R_RegisterModel (fullname);
+	R_NewMap ();
+}
+
+
+/*
+@@@@@@@@@@@@@@@@@@@@@
+R_RegisterModel
+
+@@@@@@@@@@@@@@@@@@@@@
+*/
+struct model_s *R_RegisterModel (char *name)
+{
+	model_t	*mod;
+	int		i;
+	dsprite_t	*sprout;
+	dmdl_t		*pheader;
+
+	mod = Mod_ForName (name, false);
+	if (mod)
+	{
+		mod->registration_sequence = registration_sequence;
+
+		// register any images used by the models
+		if (mod->type == mod_sprite)
+		{
+			sprout = (dsprite_t *)mod->extradata;
+			for (i=0 ; i<sprout->numframes ; i++)
+				mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite);
+		}
+		else if (mod->type == mod_alias)
+		{
+			pheader = (dmdl_t *)mod->extradata;
+			for (i=0 ; i<pheader->num_skins ; i++)
+				mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
+//PGM
+			mod->numframes = pheader->num_frames;
+//PGM
+		}
+		else if (mod->type == mod_brush)
+		{
+			for (i=0 ; i<mod->numtexinfo ; i++)
+				mod->texinfo[i].image->registration_sequence = registration_sequence;
+		}
+	}
+	return mod;
+}
+
+/*
+@@@@@@@@@@@@@@@@@@@@@
+R_EndRegistration
+
+@@@@@@@@@@@@@@@@@@@@@
+*/
+void R_EndRegistration (void)
+{
+	int		i;
+	model_t	*mod;
+
+	for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
+	{
+		if (!mod->name[0])
+			continue;
+		if (mod->registration_sequence != registration_sequence)
+		{	// don't need this model
+			Hunk_Free (mod->extradata);
+			memset (mod, 0, sizeof(*mod));
+		}
+		else
+		{	// make sure it is paged in
+			Com_PageInMemory (mod->extradata, mod->extradatasize);
+		}
+	}
+
+	R_FreeUnusedImages ();
+}
+
+
+//=============================================================================
+
+/*
+================
+Mod_Free
+================
+*/
+void Mod_Free (model_t *mod)
+{
+	Hunk_Free (mod->extradata);
+	memset (mod, 0, sizeof(*mod));
+}
+
+/*
+================
+Mod_FreeAll
+================
+*/
+void Mod_FreeAll (void)
+{
+	int		i;
+
+	for (i=0 ; i<mod_numknown ; i++)
+	{
+		if (mod_known[i].extradatasize)
+			Mod_Free (&mod_known[i]);
+	}
+}
--- /dev/null
+++ b/ref/r_model.h
@@ -1,0 +1,256 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+#ifndef __MODEL__
+#define __MODEL__
+
+/*
+
+d*_t structures are on-disk representations
+m*_t structures are in-memory
+
+*/
+
+
+/*
+==============================================================================
+
+BRUSH MODELS
+
+==============================================================================
+*/
+
+
+//
+// in memory representation
+//
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+typedef struct
+{
+	vec3_t		position;
+} mvertex_t;
+
+#define	SIDE_FRONT	0
+#define	SIDE_BACK	1
+#define	SIDE_ON		2
+
+
+// plane_t structure
+// !!! if this is changed, it must be changed in asm_i386.h too !!!
+typedef struct mplane_s
+{
+	vec3_t	normal;
+	float	dist;
+	byte	type;			// for texture axis selection and fast side tests
+	byte	signbits;		// signx + signy<<1 + signz<<1
+	byte	pad[2];
+} mplane_t;
+
+
+// FIXME: differentiate from texinfo SURF_ flags
+#define	SURF_PLANEBACK		2
+#define	SURF_DRAWSKY		4			// sky brush face
+#define SURF_DRAWTURB		0x10
+#define SURF_DRAWBACKGROUND	0x40
+#define SURF_DRAWSKYBOX		0x80		// sky box
+
+#define SURF_FLOW			0x100		//PGM
+
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+typedef struct
+{
+	unsigned short	v[2];
+	unsigned int	cachededgeoffset;
+} medge_t;
+
+typedef struct mtexinfo_s
+{
+	float		vecs[2][4];
+	float		mipadjust;
+	image_t		*image;
+	int			flags;
+	int			numframes;
+	struct mtexinfo_s	*next;		// animation chain
+} mtexinfo_t;
+
+typedef struct msurface_s
+{
+	int			visframe;		// should be drawn when node is crossed
+
+	int			dlightframe;
+	int			dlightbits;
+
+	mplane_t	*plane;
+	int			flags;
+
+	int			firstedge;	// look up in model->surfedges[], negative numbers
+	int			numedges;	// are backwards edges
+	
+// surface generation data
+	struct surfcache_s	*cachespots[MIPLEVELS];
+
+	short		texturemins[2];
+	short		extents[2];
+
+	mtexinfo_t	*texinfo;
+	
+// lighting info
+	byte		styles[MAXLIGHTMAPS];
+	byte		*samples;		// [numstyles*surfsize]
+
+	struct msurface_s *nextalphasurface;
+} msurface_t;
+
+
+#define	CONTENTS_NODE	-1
+typedef struct mnode_s
+{
+// common with leaf
+	int			contents;		// CONTENTS_NODE, to differentiate from leafs
+	int			visframe;		// node needs to be traversed if current
+	
+	short		minmaxs[6];		// for bounding box culling
+
+	struct mnode_s	*parent;
+
+// node specific
+	mplane_t	*plane;
+	struct mnode_s	*children[2];	
+
+	unsigned short		firstsurface;
+	unsigned short		numsurfaces;
+} mnode_t;
+
+
+
+typedef struct mleaf_s
+{
+// common with node
+	int			contents;		// wil be something other than CONTENTS_NODE
+	int			visframe;		// node needs to be traversed if current
+
+	short		minmaxs[6];		// for bounding box culling
+
+	struct mnode_s	*parent;
+
+// leaf specific
+	int			cluster;
+	int			area;
+
+	msurface_t	**firstmarksurface;
+	int			nummarksurfaces;
+	int			key;			// BSP sequence number for leaf's contents
+} mleaf_t;
+
+
+//===================================================================
+
+//
+// Whole model
+//
+
+typedef enum {mod_bad, mod_brush, mod_sprite, mod_alias } modtype_t;
+
+typedef struct model_s
+{
+	char		name[MAX_QPATH];
+
+	int			registration_sequence;
+
+	modtype_t	type;
+	int			numframes;
+	
+	int			flags;
+
+//
+// volume occupied by the model graphics
+//		
+	vec3_t		mins, maxs;
+
+//
+// solid volume for clipping (sent from server)
+//
+	qboolean	clipbox;
+	vec3_t		clipmins, clipmaxs;
+
+//
+// brush model
+//
+	int			firstmodelsurface, nummodelsurfaces;
+
+	int			numsubmodels;
+	dmodel_t	*submodels;
+
+	int			numplanes;
+	mplane_t	*planes;
+
+	int			numleafs;		// number of visible leafs, not counting 0
+	mleaf_t		*leafs;
+
+	int			numvertexes;
+	mvertex_t	*vertexes;
+
+	int			numedges;
+	medge_t		*edges;
+
+	int			numnodes;
+	int			firstnode;
+	mnode_t		*nodes;
+
+	int			numtexinfo;
+	mtexinfo_t	*texinfo;
+
+	int			numsurfaces;
+	msurface_t	*surfaces;
+
+	int			numsurfedges;
+	int			*surfedges;
+
+	int			nummarksurfaces;
+	msurface_t	**marksurfaces;
+
+	dvis_t		*vis;
+
+	byte		*lightdata;
+
+	// for alias models and sprites
+	image_t		*skins[MAX_MD2SKINS];
+	void		*extradata;
+	int			extradatasize;
+} model_t;
+
+//============================================================================
+
+void	Mod_Init (void);
+void	Mod_ClearAll (void);
+model_t *Mod_ForName (char *name, qboolean crash);
+void	*Mod_Extradata (model_t *mod);	// handles caching
+void	Mod_TouchModel (char *name);
+
+mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
+byte	*Mod_ClusterPVS (int cluster, model_t *model);
+
+void Mod_Modellist_f (void);
+void Mod_FreeAll (void);
+void Mod_Free (model_t *mod);
+
+extern	int		registration_sequence;
+
+#endif	// __MODEL__
--- /dev/null
+++ b/ref/r_part.c
@@ -1,0 +1,638 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include "r_local.h"
+
+vec3_t r_pright, r_pup, r_ppn;
+
+#define PARTICLE_33     0
+#define PARTICLE_66     1
+#define PARTICLE_OPAQUE 2
+
+typedef struct
+{
+	particle_t *particle;
+	int         level;
+	int         color;
+} partparms_t;
+
+static partparms_t partparms;
+
+#if id386 && !defined __linux__
+
+static unsigned s_prefetch_address;
+
+/*
+** BlendParticleXX
+**
+** Inputs:
+** EAX = color
+** EDI = pdest
+**
+** Scratch:
+** EBX = scratch (dstcolor)
+** EBP = scratch
+**
+** Outputs:
+** none
+*/
+__declspec(naked) void BlendParticle33( void )
+{
+	//	return vid.alphamap[color + dstcolor*256];
+	__asm mov ebp, vid.alphamap
+	__asm xor ebx, ebx
+
+	__asm mov bl,  byte ptr [edi]
+	__asm shl ebx, 8
+
+	__asm add ebp, ebx
+	__asm add ebp, eax
+
+	__asm mov al,  byte ptr [ebp]
+
+	__asm mov byte ptr [edi], al
+
+	__asm ret
+}
+
+__declspec(naked) void BlendParticle66( void )
+{
+	//	return vid.alphamap[pcolor*256 + dstcolor];
+	__asm mov ebp, vid.alphamap
+	__asm xor ebx, ebx
+
+	__asm shl eax,  8
+	__asm mov bl,   byte ptr [edi]
+
+	__asm add ebp, ebx
+	__asm add ebp, eax
+
+	__asm mov al,  byte ptr [ebp]
+
+	__asm mov byte ptr [edi], al
+
+	__asm ret
+}
+
+__declspec(naked) void BlendParticle100( void )
+{
+	__asm mov byte ptr [edi], al
+	__asm ret
+}
+
+/*
+** R_DrawParticle (asm version)
+**
+** Since we use __declspec( naked ) we don't have a stack frame
+** that we can use.  Since I want to reserve EBP anyway, I tossed
+** all the important variables into statics.  This routine isn't
+** meant to be re-entrant, so this shouldn't cause any problems
+** other than a slightly higher global memory footprint.
+**
+*/
+__declspec(naked) void R_DrawParticle( void )
+{
+	static vec3_t	local, transformed;
+	static float	zi;
+	static int      u, v, tmp;
+	static short    izi;
+	static int      ebpsave;
+
+	static byte (*blendfunc)(void);
+
+	/*
+	** must be memvars since x86 can't load constants
+	** directly.  I guess I could use fld1, but that
+	** actually costs one more clock than fld [one]!
+	*/
+	static float    particle_z_clip    = PARTICLE_Z_CLIP;
+	static float    one                = 1.0F;
+	static float    point_five         = 0.5F;
+	static float    eight_thousand_hex = 0x8000;
+
+	/*
+	** save trashed variables
+	*/
+	__asm mov  ebpsave, ebp
+	__asm push esi
+	__asm push edi
+
+	/*
+	** transform the particle
+	*/
+	// VectorSubtract (pparticle->origin, r_origin, local);
+	__asm mov  esi, partparms.particle
+	__asm fld  dword ptr [esi+0]          ; p_o.x
+	__asm fsub dword ptr [r_origin+0]     ; p_o.x-r_o.x
+	__asm fld  dword ptr [esi+4]          ; p_o.y | p_o.x-r_o.x
+	__asm fsub dword ptr [r_origin+4]     ; p_o.y-r_o.y | p_o.x-r_o.x
+	__asm fld  dword ptr [esi+8]          ; p_o.z | p_o.y-r_o.y | p_o.x-r_o.x
+	__asm fsub dword ptr [r_origin+8]     ; p_o.z-r_o.z | p_o.y-r_o.y | p_o.x-r_o.x
+	__asm fxch st(2)                      ; p_o.x-r_o.x | p_o.y-r_o.y | p_o.z-r_o.z
+	__asm fstp dword ptr [local+0]        ; p_o.y-r_o.y | p_o.z-r_o.z
+	__asm fstp dword ptr [local+4]        ; p_o.z-r_o.z
+	__asm fstp dword ptr [local+8]        ; (empty)
+
+	// transformed[0] = DotProduct(local, r_pright);
+	// transformed[1] = DotProduct(local, r_pup);
+	// transformed[2] = DotProduct(local, r_ppn);
+	__asm fld  dword ptr [local+0]        ; l.x
+	__asm fmul dword ptr [r_pright+0]     ; l.x*pr.x
+	__asm fld  dword ptr [local+4]        ; l.y | l.x*pr.x
+	__asm fmul dword ptr [r_pright+4]     ; l.y*pr.y | l.x*pr.x
+	__asm fld  dword ptr [local+8]        ; l.z | l.y*pr.y | l.x*pr.x
+	__asm fmul dword ptr [r_pright+8]     ; l.z*pr.z | l.y*pr.y | l.x*pr.x
+	__asm fxch st(2)                      ; l.x*pr.x | l.y*pr.y | l.z*pr.z
+	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y | l.z*pr.z
+	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y + l.z*pr.z
+	__asm fstp  dword ptr [transformed+0] ; (empty)
+
+	__asm fld  dword ptr [local+0]        ; l.x
+	__asm fmul dword ptr [r_pup+0]        ; l.x*pr.x
+	__asm fld  dword ptr [local+4]        ; l.y | l.x*pr.x
+	__asm fmul dword ptr [r_pup+4]        ; l.y*pr.y | l.x*pr.x
+	__asm fld  dword ptr [local+8]        ; l.z | l.y*pr.y | l.x*pr.x
+	__asm fmul dword ptr [r_pup+8]        ; l.z*pr.z | l.y*pr.y | l.x*pr.x
+	__asm fxch st(2)                      ; l.x*pr.x | l.y*pr.y | l.z*pr.z
+	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y | l.z*pr.z
+	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y + l.z*pr.z
+	__asm fstp  dword ptr [transformed+4] ; (empty)
+
+	__asm fld  dword ptr [local+0]        ; l.x
+	__asm fmul dword ptr [r_ppn+0]        ; l.x*pr.x
+	__asm fld  dword ptr [local+4]        ; l.y | l.x*pr.x
+	__asm fmul dword ptr [r_ppn+4]        ; l.y*pr.y | l.x*pr.x
+	__asm fld  dword ptr [local+8]        ; l.z | l.y*pr.y | l.x*pr.x
+	__asm fmul dword ptr [r_ppn+8]        ; l.z*pr.z | l.y*pr.y | l.x*pr.x
+	__asm fxch st(2)                      ; l.x*pr.x | l.y*pr.y | l.z*pr.z
+	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y | l.z*pr.z
+	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y + l.z*pr.z
+	__asm fstp  dword ptr [transformed+8] ; (empty)
+
+	/*
+	** make sure that the transformed particle is not in front of
+	** the particle Z clip plane.  We can do the comparison in 
+	** integer space since we know the sign of one of the inputs
+	** and can figure out the sign of the other easily enough.
+	*/
+	//	if (transformed[2] < PARTICLE_Z_CLIP)
+	//		return;
+
+	__asm mov  eax, dword ptr [transformed+8]
+	__asm and  eax, eax
+	__asm js   end
+	__asm cmp  eax, particle_z_clip
+	__asm jl   end
+
+	/*
+	** project the point by initiating the 1/z calc
+	*/
+	//	zi = 1.0 / transformed[2];
+	__asm fld   one
+	__asm fdiv  dword ptr [transformed+8]
+
+	/*
+	** bind the blend function pointer to the appropriate blender
+	** while we're dividing
+	*/
+	//if ( level == PARTICLE_33 )
+	//	blendparticle = BlendParticle33;
+	//else if ( level == PARTICLE_66 )
+	//	blendparticle = BlendParticle66;
+	//else 
+	//	blendparticle = BlendParticle100;
+
+	__asm cmp partparms.level, PARTICLE_66
+	__asm je  blendfunc_66
+	__asm jl  blendfunc_33
+	__asm lea ebx, BlendParticle100
+	__asm jmp done_selecting_blend_func
+blendfunc_33:
+	__asm lea ebx, BlendParticle33
+	__asm jmp done_selecting_blend_func
+blendfunc_66:
+	__asm lea ebx, BlendParticle66
+done_selecting_blend_func:
+	__asm mov blendfunc, ebx
+
+	// prefetch the next particle
+	__asm mov ebp, s_prefetch_address
+	__asm mov ebp, [ebp]
+
+	// finish the above divide
+	__asm fstp  zi
+
+	// u = (int)(xcenter + zi * transformed[0] + 0.5);
+	// v = (int)(ycenter - zi * transformed[1] + 0.5);
+	__asm fld   zi                           ; zi
+	__asm fmul  dword ptr [transformed+0]    ; zi * transformed[0]
+	__asm fld   zi                           ; zi | zi * transformed[0]
+	__asm fmul  dword ptr [transformed+4]    ; zi * transformed[1] | zi * transformed[0]
+	__asm fxch  st(1)                        ; zi * transformed[0] | zi * transformed[1]
+	__asm fadd  xcenter                      ; xcenter + zi * transformed[0] | zi * transformed[1]
+	__asm fxch  st(1)                        ; zi * transformed[1] | xcenter + zi * transformed[0]
+	__asm fld   ycenter                      ; ycenter | zi * transformed[1] | xcenter + zi * transformed[0]
+    __asm fsubrp st(1), st(0)                ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0]
+  	__asm fxch  st(1)                        ; xcenter + zi * transformed[0] | ycenter + zi * transformed[1]
+  	__asm fadd  point_five                   ; xcenter + zi * transformed[0] + 0.5 | ycenter - zi * transformed[1]
+  	__asm fxch  st(1)                        ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0] + 0.5 
+  	__asm fadd  point_five                   ; ycenter - zi * transformed[1] + 0.5 | xcenter + zi * transformed[0] + 0.5 
+  	__asm fxch  st(1)                        ; u | v
+  	__asm fistp dword ptr [u]                ; v
+  	__asm fistp dword ptr [v]                ; (empty)
+
+	/*
+	** clip out the particle
+	*/
+
+	//	if ((v > d_vrectbottom_particle) || 
+	//		(u > d_vrectright_particle) ||
+	//		(v < d_vrecty) ||
+	//		(u < d_vrectx))
+	//	{
+	//		return;
+	//	}
+
+	__asm mov ebx, u
+	__asm mov ecx, v
+	__asm cmp ecx, d_vrectbottom_particle
+	__asm jg  end
+	__asm cmp ecx, d_vrecty
+	__asm jl  end
+	__asm cmp ebx, d_vrectright_particle
+	__asm jg  end
+	__asm cmp ebx, d_vrectx
+	__asm jl  end
+
+	/*
+	** compute addresses of zbuffer, framebuffer, and 
+	** compute the Z-buffer reference value.
+	**
+	** EBX      = U
+	** ECX      = V
+	**
+	** Outputs:
+	** ESI = Z-buffer address
+	** EDI = framebuffer address
+	*/
+	// ESI = d_pzbuffer + (d_zwidth * v) + u;
+	__asm mov esi, d_pzbuffer             ; esi = d_pzbuffer
+	__asm mov eax, d_zwidth               ; eax = d_zwidth
+	__asm mul ecx                         ; eax = d_zwidth*v
+	__asm add eax, ebx                    ; eax = d_zwidth*v+u
+	__asm shl eax, 1                      ; eax = 2*(d_zwidth*v+u)
+	__asm add esi, eax                    ; esi = ( short * ) ( d_pzbuffer + ( d_zwidth * v ) + u )
+
+	// initiate
+	// izi = (int)(zi * 0x8000);
+	__asm fld  zi
+	__asm fmul eight_thousand_hex
+
+	// EDI = pdest = d_viewbuffer + d_scantable[v] + u;
+	__asm lea edi, [d_scantable+ecx*4]
+	__asm mov edi, [edi]
+	__asm add edi, d_viewbuffer
+	__asm add edi, ebx
+
+	// complete
+	// izi = (int)(zi * 0x8000);
+	__asm fistp tmp
+	__asm mov   eax, tmp
+	__asm mov   izi, ax
+
+	/*
+	** determine the screen area covered by the particle,
+	** which also means clamping to a min and max
+	*/
+	//	pix = izi >> d_pix_shift;
+	__asm xor edx, edx
+	__asm mov dx, izi
+	__asm mov ecx, d_pix_shift
+	__asm shr dx, cl
+
+	//	if (pix < d_pix_min)
+	//		pix = d_pix_min;
+	__asm cmp edx, d_pix_min
+	__asm jge check_pix_max
+	__asm mov edx, d_pix_min
+	__asm jmp skip_pix_clamp
+
+	//	else if (pix > d_pix_max)
+	//		pix = d_pix_max;
+check_pix_max:
+	__asm cmp edx, d_pix_max
+	__asm jle skip_pix_clamp
+	__asm mov edx, d_pix_max
+
+skip_pix_clamp:
+
+	/*
+	** render the appropriate pixels
+	**
+	** ECX = count (used for inner loop)
+	** EDX = count (used for outer loop)
+	** ESI = zbuffer
+	** EDI = framebuffer
+	*/
+	__asm mov ecx, edx
+
+	__asm cmp ecx, 1
+	__asm ja  over
+
+over:
+
+	/*
+	** at this point:
+	**
+	** ECX = count
+	*/
+	__asm push ecx
+	__asm push edi
+	__asm push esi
+
+top_of_pix_vert_loop:
+
+top_of_pix_horiz_loop:
+
+	//	for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
+	//	{
+	//		for (i=0 ; i<pix ; i++)
+	//		{
+	//			if (pz[i] <= izi)
+	//			{
+	//				pdest[i] = blendparticle( color, pdest[i] );
+	//			}
+	//		}
+	//	}
+	__asm xor   eax, eax
+
+	__asm mov   ax, word ptr [esi]
+
+	__asm cmp   ax, izi
+	__asm jg    end_of_horiz_loop
+
+#if ENABLE_ZWRITES_FOR_PARTICLES
+  	__asm mov   bp, izi
+  	__asm mov   word ptr [esi], bp
+#endif
+
+	__asm mov   eax, partparms.color
+
+	__asm call  [blendfunc]
+
+	__asm add   edi, 1
+	__asm add   esi, 2
+
+end_of_horiz_loop:
+
+	__asm dec   ecx
+	__asm jnz   top_of_pix_horiz_loop
+
+	__asm pop   esi
+	__asm pop   edi
+
+	__asm mov   ebp, d_zwidth
+	__asm shl   ebp, 1
+
+	__asm add   esi, ebp
+	__asm add   edi, [r_screenwidth]
+
+	__asm pop   ecx
+	__asm push  ecx
+
+	__asm push  edi
+	__asm push  esi
+
+	__asm dec   edx
+	__asm jnz   top_of_pix_vert_loop
+
+	__asm pop   ecx
+	__asm pop   ecx
+	__asm pop   ecx
+
+end:
+	__asm pop edi
+	__asm pop esi
+	__asm mov ebp, ebpsave
+	__asm ret
+}
+
+#else
+
+static byte BlendParticle33( int pcolor, int dstcolor )
+{
+	return vid.alphamap[pcolor + dstcolor*256];
+}
+
+static byte BlendParticle66( int pcolor, int dstcolor )
+{
+	return vid.alphamap[pcolor*256+dstcolor];
+}
+
+static byte BlendParticle100( int pcolor, int dstcolor )
+{
+	dstcolor = dstcolor;
+	return pcolor;
+}
+
+/*
+** R_DrawParticle
+**
+** Yes, this is amazingly slow, but it's the C reference
+** implementation and should be both robust and vaguely
+** understandable.  The only time this path should be
+** executed is if we're debugging on x86 or if we're
+** recompiling and deploying on a non-x86 platform.
+**
+** To minimize error and improve readability I went the 
+** function pointer route.  This exacts some overhead, but
+** it pays off in clean and easy to understand code.
+*/
+void R_DrawParticle( void )
+{
+	particle_t *pparticle = partparms.particle;
+	int         level     = partparms.level;
+	vec3_t	local, transformed;
+	float	zi;
+	byte	*pdest;
+	short	*pz;
+	int      color = pparticle->color;
+	int		i, izi, pix, count, u, v;
+	byte  (*blendparticle)( int, int );
+
+	/*
+	** transform the particle
+	*/
+	VectorSubtract (pparticle->origin, r_origin, local);
+
+	transformed[0] = DotProduct(local, r_pright);
+	transformed[1] = DotProduct(local, r_pup);
+	transformed[2] = DotProduct(local, r_ppn);		
+
+	if (transformed[2] < PARTICLE_Z_CLIP)
+		return;
+
+	/*
+	** bind the blend function pointer to the appropriate blender
+	*/
+	if ( level == PARTICLE_33 )
+		blendparticle = BlendParticle33;
+	else if ( level == PARTICLE_66 )
+		blendparticle = BlendParticle66;
+	else 
+		blendparticle = BlendParticle100;
+
+	/*
+	** project the point
+	*/
+	// FIXME: preadjust xcenter and ycenter
+	zi = 1.0 / transformed[2];
+	u = (int)(xcenter + zi * transformed[0] + 0.5);
+	v = (int)(ycenter - zi * transformed[1] + 0.5);
+
+	if ((v > d_vrectbottom_particle) || 
+		(u > d_vrectright_particle) ||
+		(v < d_vrecty) ||
+		(u < d_vrectx))
+	{
+		return;
+	}
+
+	/*
+	** compute addresses of zbuffer, framebuffer, and 
+	** compute the Z-buffer reference value.
+	*/
+	pz = d_pzbuffer + (d_zwidth * v) + u;
+	pdest = d_viewbuffer + d_scantable[v] + u;
+	izi = (int)(zi * 0x8000);
+
+	/*
+	** determine the screen area covered by the particle,
+	** which also means clamping to a min and max
+	*/
+	pix = izi >> d_pix_shift;
+	if (pix < d_pix_min)
+		pix = d_pix_min;
+	else if (pix > d_pix_max)
+		pix = d_pix_max;
+
+	/*
+	** render the appropriate pixels
+	*/
+	count = pix;
+
+    switch (level) {
+    case PARTICLE_33 :
+        for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
+        {
+//FIXME--do it in blocks of 8?
+            for (i=0 ; i<pix ; i++)
+            {
+                if (pz[i] <= izi)
+                {
+                    pz[i]    = izi;
+                    pdest[i] = vid.alphamap[color + ((int)pdest[i]<<8)];
+                }
+            }
+        }
+        break;
+
+    case PARTICLE_66 :
+        for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
+        {
+            for (i=0 ; i<pix ; i++)
+            {
+                if (pz[i] <= izi)
+                {
+                    pz[i]    = izi;
+                    pdest[i] = vid.alphamap[(color<<8) + (int)pdest[i]];
+                }
+            }
+        }
+        break;
+
+    default:  //100
+        for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
+        {
+            for (i=0 ; i<pix ; i++)
+            {
+                if (pz[i] <= izi)
+                {
+                    pz[i]    = izi;
+                    pdest[i] = color;
+                }
+            }
+        }
+        break;
+    }
+}
+
+#endif	// !id386
+
+/*
+** R_DrawParticles
+**
+** Responsible for drawing all of the particles in the particle list
+** throughout the world.  Doesn't care if we're using the C path or
+** if we're using the asm path, it simply assigns a function pointer
+** and goes.
+*/
+void R_DrawParticles (void)
+{
+	particle_t *p;
+	int         i;
+	extern unsigned long fpu_sp24_cw, fpu_chop_cw;
+
+	VectorScale( vright, xscaleshrink, r_pright );
+	VectorScale( vup, yscaleshrink, r_pup );
+	VectorCopy( vpn, r_ppn );
+
+#if id386 && !defined __linux__
+	__asm fldcw word ptr [fpu_sp24_cw]
+#endif
+
+	for (p=r_newrefdef.particles, i=0 ; i<r_newrefdef.num_particles ; i++,p++)
+	{
+
+		if ( p->alpha > 0.66 )
+			partparms.level = PARTICLE_OPAQUE;
+		else if ( p->alpha > 0.33 )
+			partparms.level = PARTICLE_66;
+		else
+			partparms.level = PARTICLE_33;
+
+		partparms.particle = p;
+		partparms.color    = p->color;
+
+#if id386 && !defined __linux__
+		if ( i < r_newrefdef.num_particles-1 )
+			s_prefetch_address = ( unsigned int ) ( p + 1 );
+		else
+			s_prefetch_address = ( unsigned int ) r_newrefdef.particles;
+#endif
+
+		R_DrawParticle();
+	}
+
+#if id386 && !defined __linux__
+	__asm fldcw word ptr [fpu_chop_cw]
+#endif
+
+}
+
--- /dev/null
+++ b/ref/r_poly.c
@@ -1,0 +1,1244 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+#include <assert.h>
+#include "r_local.h"
+
+#define AFFINE_SPANLET_SIZE      16
+#define AFFINE_SPANLET_SIZE_BITS 4
+
+typedef struct
+{
+	byte     *pbase, *pdest;
+	short	 *pz;
+	fixed16_t s, t;
+	fixed16_t sstep, tstep;
+	int       izi, izistep, izistep_times_2;
+	int       spancount;
+	unsigned  u, v;
+} spanletvars_t;
+
+spanletvars_t s_spanletvars;
+
+static int r_polyblendcolor;
+
+static espan_t	*s_polygon_spans;
+
+polydesc_t	r_polydesc;
+
+msurface_t *r_alpha_surfaces;
+
+extern int *r_turb_turb;
+
+static int		clip_current;
+vec5_t	r_clip_verts[2][MAXWORKINGVERTS+2];
+
+static int		s_minindex, s_maxindex;
+
+static void R_DrawPoly( qboolean iswater );
+
+/*
+** R_DrawSpanletOpaque
+*/
+void R_DrawSpanletOpaque( void )
+{
+	unsigned btemp;
+
+	do
+	{
+		unsigned ts, tt;
+
+		ts = s_spanletvars.s >> 16;
+		tt = s_spanletvars.t >> 16;
+
+		btemp = *(s_spanletvars.pbase + (ts) + (tt) * cachewidth);
+		if (btemp != 255)
+		{
+			if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
+			{
+				*s_spanletvars.pz    = s_spanletvars.izi >> 16;
+				*s_spanletvars.pdest = btemp;
+			}
+		}
+
+		s_spanletvars.izi += s_spanletvars.izistep;
+		s_spanletvars.pdest++;
+		s_spanletvars.pz++;
+		s_spanletvars.s += s_spanletvars.sstep;
+		s_spanletvars.t += s_spanletvars.tstep;
+	} while (--s_spanletvars.spancount > 0);
+}
+
+/*
+** R_DrawSpanletTurbulentStipple33
+*/
+void R_DrawSpanletTurbulentStipple33( void )
+{
+	unsigned btemp;
+	int	     sturb, tturb;
+	byte    *pdest = s_spanletvars.pdest;
+	short   *pz    = s_spanletvars.pz;
+	int      izi   = s_spanletvars.izi;
+	
+	if ( s_spanletvars.v & 1 )
+	{
+		s_spanletvars.pdest += s_spanletvars.spancount;
+		s_spanletvars.pz    += s_spanletvars.spancount;
+
+		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
+			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
+		else
+			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
+		
+		if ( s_spanletvars.u & 1 )
+		{
+			izi += s_spanletvars.izistep;
+			s_spanletvars.s   += s_spanletvars.sstep;
+			s_spanletvars.t   += s_spanletvars.tstep;
+
+			pdest++;
+			pz++;
+			s_spanletvars.spancount--;
+		}
+
+		s_spanletvars.sstep   *= 2;
+		s_spanletvars.tstep   *= 2;
+
+		while ( s_spanletvars.spancount > 0 )
+		{
+			sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
+			tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
+			
+			btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
+			
+			if ( *pz <= ( izi >> 16 ) )
+				*pdest = btemp;
+			
+			izi               += s_spanletvars.izistep_times_2;
+			s_spanletvars.s   += s_spanletvars.sstep;
+			s_spanletvars.t   += s_spanletvars.tstep;
+			
+			pdest += 2;
+			pz    += 2;
+			
+			s_spanletvars.spancount -= 2;
+		}
+	}
+}
+
+/*
+** R_DrawSpanletTurbulentStipple66
+*/
+void R_DrawSpanletTurbulentStipple66( void )
+{
+	unsigned btemp;
+	int	     sturb, tturb;
+	byte    *pdest = s_spanletvars.pdest;
+	short   *pz    = s_spanletvars.pz;
+	int      izi   = s_spanletvars.izi;
+	
+	if ( !( s_spanletvars.v & 1 ) )
+	{
+		s_spanletvars.pdest += s_spanletvars.spancount;
+		s_spanletvars.pz    += s_spanletvars.spancount;
+
+		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
+			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
+		else
+			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
+		
+		if ( s_spanletvars.u & 1 )
+		{
+			izi += s_spanletvars.izistep;
+			s_spanletvars.s   += s_spanletvars.sstep;
+			s_spanletvars.t   += s_spanletvars.tstep;
+
+			pdest++;
+			pz++;
+			s_spanletvars.spancount--;
+		}
+
+		s_spanletvars.sstep   *= 2;
+		s_spanletvars.tstep   *= 2;
+
+		while ( s_spanletvars.spancount > 0 )
+		{
+			sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
+			tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
+			
+			btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
+			
+			if ( *pz <= ( izi >> 16 ) )
+				*pdest = btemp;
+			
+			izi               += s_spanletvars.izistep_times_2;
+			s_spanletvars.s   += s_spanletvars.sstep;
+			s_spanletvars.t   += s_spanletvars.tstep;
+			
+			pdest += 2;
+			pz    += 2;
+			
+			s_spanletvars.spancount -= 2;
+		}
+	}
+	else
+	{
+		s_spanletvars.pdest += s_spanletvars.spancount;
+		s_spanletvars.pz    += s_spanletvars.spancount;
+
+		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
+			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
+		else
+			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
+		
+		while ( s_spanletvars.spancount > 0 )
+		{
+			sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
+			tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
+			
+			btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
+			
+			if ( *pz <= ( izi >> 16 ) )
+				*pdest = btemp;
+			
+			izi               += s_spanletvars.izistep;
+			s_spanletvars.s   += s_spanletvars.sstep;
+			s_spanletvars.t   += s_spanletvars.tstep;
+			
+			pdest++;
+			pz++;
+			
+			s_spanletvars.spancount--;
+		}
+	}
+}
+
+/*
+** R_DrawSpanletTurbulentBlended
+*/
+void R_DrawSpanletTurbulentBlended66( void )
+{
+	unsigned btemp;
+	int	     sturb, tturb;
+
+	do
+	{
+		sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
+		tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
+
+		btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
+
+		if ( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) )
+			*s_spanletvars.pdest = vid.alphamap[btemp*256+*s_spanletvars.pdest];
+
+		s_spanletvars.izi += s_spanletvars.izistep;
+		s_spanletvars.pdest++;
+		s_spanletvars.pz++;
+		s_spanletvars.s += s_spanletvars.sstep;
+		s_spanletvars.t += s_spanletvars.tstep;
+
+	} while ( --s_spanletvars.spancount > 0 );
+}
+
+void R_DrawSpanletTurbulentBlended33( void )
+{
+	unsigned btemp;
+	int	     sturb, tturb;
+
+	do
+	{
+		sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
+		tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
+
+		btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
+
+		if ( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) )
+			*s_spanletvars.pdest = vid.alphamap[btemp+*s_spanletvars.pdest*256];
+
+		s_spanletvars.izi += s_spanletvars.izistep;
+		s_spanletvars.pdest++;
+		s_spanletvars.pz++;
+		s_spanletvars.s += s_spanletvars.sstep;
+		s_spanletvars.t += s_spanletvars.tstep;
+
+	} while ( --s_spanletvars.spancount > 0 );
+}
+
+/*
+** R_DrawSpanlet33
+*/
+void R_DrawSpanlet33( void )
+{
+	unsigned btemp;
+
+	do
+	{
+		unsigned ts, tt;
+
+		ts = s_spanletvars.s >> 16;
+		tt = s_spanletvars.t >> 16;
+
+		btemp = *(s_spanletvars.pbase + (ts) + (tt) * cachewidth);
+
+		if ( btemp != 255 )
+		{
+			if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
+			{
+				*s_spanletvars.pdest = vid.alphamap[btemp+*s_spanletvars.pdest*256];
+			}
+		}
+
+		s_spanletvars.izi += s_spanletvars.izistep;
+		s_spanletvars.pdest++;
+		s_spanletvars.pz++;
+		s_spanletvars.s += s_spanletvars.sstep;
+		s_spanletvars.t += s_spanletvars.tstep;
+	} while (--s_spanletvars.spancount > 0);
+}
+
+void R_DrawSpanletConstant33( void )
+{
+	do
+	{
+		if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
+		{
+			*s_spanletvars.pdest = vid.alphamap[r_polyblendcolor+*s_spanletvars.pdest*256];
+		}
+
+		s_spanletvars.izi += s_spanletvars.izistep;
+		s_spanletvars.pdest++;
+		s_spanletvars.pz++;
+	} while (--s_spanletvars.spancount > 0);
+}
+
+/*
+** R_DrawSpanlet66
+*/
+void R_DrawSpanlet66( void )
+{
+	unsigned btemp;
+
+	do
+	{
+		unsigned ts, tt;
+
+		ts = s_spanletvars.s >> 16;
+		tt = s_spanletvars.t >> 16;
+
+		btemp = *(s_spanletvars.pbase + (ts) + (tt) * cachewidth);
+
+		if ( btemp != 255 )
+		{
+			if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
+			{
+				*s_spanletvars.pdest = vid.alphamap[btemp*256+*s_spanletvars.pdest];
+			}
+		}
+
+		s_spanletvars.izi += s_spanletvars.izistep;
+		s_spanletvars.pdest++;
+		s_spanletvars.pz++;
+		s_spanletvars.s += s_spanletvars.sstep;
+		s_spanletvars.t += s_spanletvars.tstep;
+	} while (--s_spanletvars.spancount > 0);
+}
+
+/*
+** R_DrawSpanlet33Stipple
+*/
+void R_DrawSpanlet33Stipple( void )
+{
+	unsigned btemp;
+	byte    *pdest = s_spanletvars.pdest;
+	short   *pz    = s_spanletvars.pz;
+	int      izi   = s_spanletvars.izi;
+	
+	if ( r_polydesc.stipple_parity ^ ( s_spanletvars.v & 1 ) )
+	{
+		s_spanletvars.pdest += s_spanletvars.spancount;
+		s_spanletvars.pz    += s_spanletvars.spancount;
+
+		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
+			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
+		else
+			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
+		
+		if ( r_polydesc.stipple_parity ^ ( s_spanletvars.u & 1 ) )
+		{
+			izi += s_spanletvars.izistep;
+			s_spanletvars.s   += s_spanletvars.sstep;
+			s_spanletvars.t   += s_spanletvars.tstep;
+
+			pdest++;
+			pz++;
+			s_spanletvars.spancount--;
+		}
+
+		s_spanletvars.sstep *= 2;
+		s_spanletvars.tstep *= 2;
+
+		while ( s_spanletvars.spancount > 0 )
+		{
+			unsigned s = s_spanletvars.s >> 16;
+			unsigned t = s_spanletvars.t >> 16;
+
+			btemp = *( s_spanletvars.pbase + ( s ) + ( t * cachewidth ) );
+			
+			if ( btemp != 255 )
+			{
+				if ( *pz <= ( izi >> 16 ) )
+					*pdest = btemp;
+			}
+			
+			izi               += s_spanletvars.izistep_times_2;
+			s_spanletvars.s   += s_spanletvars.sstep;
+			s_spanletvars.t   += s_spanletvars.tstep;
+			
+			pdest += 2;
+			pz    += 2;
+			
+			s_spanletvars.spancount -= 2;
+		}
+	}
+}
+
+/*
+** R_DrawSpanlet66Stipple
+*/
+void R_DrawSpanlet66Stipple( void )
+{
+	unsigned btemp;
+	byte    *pdest = s_spanletvars.pdest;
+	short   *pz    = s_spanletvars.pz;
+	int      izi   = s_spanletvars.izi;
+
+	s_spanletvars.pdest += s_spanletvars.spancount;
+	s_spanletvars.pz    += s_spanletvars.spancount;
+
+	if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
+		s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
+	else
+		s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
+
+	if ( r_polydesc.stipple_parity ^ ( s_spanletvars.v & 1 ) )
+	{
+		if ( r_polydesc.stipple_parity ^ ( s_spanletvars.u & 1 ) )
+		{
+			izi += s_spanletvars.izistep;
+			s_spanletvars.s += s_spanletvars.sstep;
+			s_spanletvars.t += s_spanletvars.tstep;
+
+			pdest++;
+			pz++;
+			s_spanletvars.spancount--;
+		}
+
+		s_spanletvars.sstep *= 2;
+		s_spanletvars.tstep *= 2;
+
+		while ( s_spanletvars.spancount > 0 )
+		{
+			unsigned s = s_spanletvars.s >> 16;
+			unsigned t = s_spanletvars.t >> 16;
+			
+			btemp = *( s_spanletvars.pbase + ( s ) + ( t * cachewidth ) );
+
+			if ( btemp != 255 )
+			{
+				if ( *pz <= ( izi >> 16 ) )
+					*pdest = btemp;
+			}
+			
+			izi             += s_spanletvars.izistep_times_2;
+			s_spanletvars.s += s_spanletvars.sstep;
+			s_spanletvars.t += s_spanletvars.tstep;
+			
+			pdest += 2;
+			pz    += 2;
+			
+			s_spanletvars.spancount -= 2;
+		}
+	}
+	else
+	{
+		while ( s_spanletvars.spancount > 0 )
+		{
+			unsigned s = s_spanletvars.s >> 16;
+			unsigned t = s_spanletvars.t >> 16;
+			
+			btemp = *( s_spanletvars.pbase + ( s ) + ( t * cachewidth ) );
+			
+			if ( btemp != 255 )
+			{
+				if ( *pz <= ( izi >> 16 ) )
+					*pdest = btemp;
+			}
+			
+			izi             += s_spanletvars.izistep;
+			s_spanletvars.s += s_spanletvars.sstep;
+			s_spanletvars.t += s_spanletvars.tstep;
+			
+			pdest++;
+			pz++;
+			
+			s_spanletvars.spancount--;
+		}
+	}
+}
+
+/*
+** R_ClipPolyFace
+**
+** Clips the winding at clip_verts[clip_current] and changes clip_current
+** Throws out the back side
+*/
+int R_ClipPolyFace (int nump, clipplane_t *pclipplane)
+{
+	int		i, outcount;
+	float	dists[MAXWORKINGVERTS+3];
+	float	frac, clipdist, *pclipnormal;
+	float	*in, *instep, *outstep, *vert2;
+
+	clipdist = pclipplane->dist;
+	pclipnormal = pclipplane->normal;
+	
+// calc dists
+	if (clip_current)
+	{
+		in = r_clip_verts[1][0];
+		outstep = r_clip_verts[0][0];
+		clip_current = 0;
+	}
+	else
+	{
+		in = r_clip_verts[0][0];
+		outstep = r_clip_verts[1][0];
+		clip_current = 1;
+	}
+	
+	instep = in;
+	for (i=0 ; i<nump ; i++, instep += sizeof (vec5_t) / sizeof (float))
+	{
+		dists[i] = DotProduct (instep, pclipnormal) - clipdist;
+	}
+	
+// handle wraparound case
+	dists[nump] = dists[0];
+	memcpy (instep, in, sizeof (vec5_t));
+
+
+// clip the winding
+	instep = in;
+	outcount = 0;
+
+	for (i=0 ; i<nump ; i++, instep += sizeof (vec5_t) / sizeof (float))
+	{
+		if (dists[i] >= 0)
+		{
+			memcpy (outstep, instep, sizeof (vec5_t));
+			outstep += sizeof (vec5_t) / sizeof (float);
+			outcount++;
+		}
+
+		if (dists[i] == 0 || dists[i+1] == 0)
+			continue;
+
+		if ( (dists[i] > 0) == (dists[i+1] > 0) )
+			continue;
+			
+	// split it into a new vertex
+		frac = dists[i] / (dists[i] - dists[i+1]);
+			
+		vert2 = instep + sizeof (vec5_t) / sizeof (float);
+		
+		outstep[0] = instep[0] + frac*(vert2[0] - instep[0]);
+		outstep[1] = instep[1] + frac*(vert2[1] - instep[1]);
+		outstep[2] = instep[2] + frac*(vert2[2] - instep[2]);
+		outstep[3] = instep[3] + frac*(vert2[3] - instep[3]);
+		outstep[4] = instep[4] + frac*(vert2[4] - instep[4]);
+
+		outstep += sizeof (vec5_t) / sizeof (float);
+		outcount++;
+	}	
+	
+	return outcount;
+}
+
+/*
+** R_PolygonDrawSpans
+*/
+void R_PolygonDrawSpans(espan_t *pspan, qboolean iswater )
+{
+	int			count;
+	fixed16_t	snext, tnext;
+	float		sdivz, tdivz, zi, z, du, dv, spancountminus1;
+	float		sdivzspanletstepu, tdivzspanletstepu, zispanletstepu;
+
+	s_spanletvars.pbase = cacheblock;
+
+	if ( iswater )
+		r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
+
+	sdivzspanletstepu = d_sdivzstepu * AFFINE_SPANLET_SIZE;
+	tdivzspanletstepu = d_tdivzstepu * AFFINE_SPANLET_SIZE;
+	zispanletstepu = d_zistepu * AFFINE_SPANLET_SIZE;
+
+// we count on FP exceptions being turned off to avoid range problems
+	s_spanletvars.izistep = (int)(d_zistepu * 0x8000 * 0x10000);
+	s_spanletvars.izistep_times_2 = s_spanletvars.izistep * 2;
+
+	s_spanletvars.pz = 0;
+
+	do
+	{
+		s_spanletvars.pdest   = (byte *)d_viewbuffer + ( d_scantable[pspan->v] /*r_screenwidth * pspan->v*/) + pspan->u;
+		s_spanletvars.pz      = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
+		s_spanletvars.u       = pspan->u;
+		s_spanletvars.v       = pspan->v;
+
+		count = pspan->count;
+
+		if (count <= 0)
+			goto NextSpan;
+
+	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
+		du = (float)pspan->u;
+		dv = (float)pspan->v;
+
+		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
+		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
+
+		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
+		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+	// we count on FP exceptions being turned off to avoid range problems
+		s_spanletvars.izi = (int)(zi * 0x8000 * 0x10000);
+
+		s_spanletvars.s = (int)(sdivz * z) + sadjust;
+		s_spanletvars.t = (int)(tdivz * z) + tadjust;
+
+		if ( !iswater )
+		{
+			if (s_spanletvars.s > bbextents)
+				s_spanletvars.s = bbextents;
+			else if (s_spanletvars.s < 0)
+				s_spanletvars.s = 0;
+
+			if (s_spanletvars.t > bbextentt)
+				s_spanletvars.t = bbextentt;
+			else if (s_spanletvars.t < 0)
+				s_spanletvars.t = 0;
+		}
+
+		do
+		{
+		// calculate s and t at the far end of the span
+			if (count >= AFFINE_SPANLET_SIZE )
+				s_spanletvars.spancount = AFFINE_SPANLET_SIZE;
+			else
+				s_spanletvars.spancount = count;
+
+			count -= s_spanletvars.spancount;
+
+			if (count)
+			{
+			// calculate s/z, t/z, zi->fixed s and t at far end of span,
+			// calculate s and t steps across span by shifting
+				sdivz += sdivzspanletstepu;
+				tdivz += tdivzspanletstepu;
+				zi += zispanletstepu;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+
+				snext = (int)(sdivz * z) + sadjust;
+				tnext = (int)(tdivz * z) + tadjust;
+
+				if ( !iswater )
+				{
+					if (snext > bbextents)
+						snext = bbextents;
+					else if (snext < AFFINE_SPANLET_SIZE)
+						snext = AFFINE_SPANLET_SIZE;	// prevent round-off error on <0 steps from
+									//  from causing overstepping & running off the
+									//  edge of the texture
+
+					if (tnext > bbextentt)
+						tnext = bbextentt;
+					else if (tnext < AFFINE_SPANLET_SIZE)
+						tnext = AFFINE_SPANLET_SIZE;	// guard against round-off error on <0 steps
+				}
+
+				s_spanletvars.sstep = (snext - s_spanletvars.s) >> AFFINE_SPANLET_SIZE_BITS;
+				s_spanletvars.tstep = (tnext - s_spanletvars.t) >> AFFINE_SPANLET_SIZE_BITS;
+			}
+			else
+			{
+			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
+			// can't step off polygon), clamp, calculate s and t steps across
+			// span by division, biasing steps low so we don't run off the
+			// texture
+				spancountminus1 = (float)(s_spanletvars.spancount - 1);
+				sdivz += d_sdivzstepu * spancountminus1;
+				tdivz += d_tdivzstepu * spancountminus1;
+				zi += d_zistepu * spancountminus1;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+				snext = (int)(sdivz * z) + sadjust;
+				tnext = (int)(tdivz * z) + tadjust;
+
+				if ( !iswater )
+				{
+					if (snext > bbextents)
+						snext = bbextents;
+					else if (snext < AFFINE_SPANLET_SIZE)
+						snext = AFFINE_SPANLET_SIZE;	// prevent round-off error on <0 steps from
+									//  from causing overstepping & running off the
+									//  edge of the texture
+
+					if (tnext > bbextentt)
+						tnext = bbextentt;
+					else if (tnext < AFFINE_SPANLET_SIZE)
+						tnext = AFFINE_SPANLET_SIZE;	// guard against round-off error on <0 steps
+				}
+
+				if (s_spanletvars.spancount > 1)
+				{
+					s_spanletvars.sstep = (snext - s_spanletvars.s) / (s_spanletvars.spancount - 1);
+					s_spanletvars.tstep = (tnext - s_spanletvars.t) / (s_spanletvars.spancount - 1);
+				}
+			}
+
+			if ( iswater )
+			{
+				s_spanletvars.s = s_spanletvars.s & ((CYCLE<<16)-1);
+				s_spanletvars.t = s_spanletvars.t & ((CYCLE<<16)-1);
+			}
+
+			r_polydesc.drawspanlet();
+
+			s_spanletvars.s = snext;
+			s_spanletvars.t = tnext;
+
+		} while (count > 0);
+
+NextSpan:
+		pspan++;
+
+	} while (pspan->count != DS_SPAN_LIST_END);
+}
+
+/*
+**
+** R_PolygonScanLeftEdge
+**
+** Goes through the polygon and scans the left edge, filling in 
+** screen coordinate data for the spans
+*/
+void R_PolygonScanLeftEdge (void)
+{
+	int			i, v, itop, ibottom, lmaxindex;
+	emitpoint_t	*pvert, *pnext;
+	espan_t		*pspan;
+	float		du, dv, vtop, vbottom, slope;
+	fixed16_t	u, u_step;
+
+	pspan = s_polygon_spans;
+	i = s_minindex;
+	if (i == 0)
+		i = r_polydesc.nump;
+
+	lmaxindex = s_maxindex;
+	if (lmaxindex == 0)
+		lmaxindex = r_polydesc.nump;
+
+	vtop = ceil (r_polydesc.pverts[i].v);
+
+	do
+	{
+		pvert = &r_polydesc.pverts[i];
+		pnext = pvert - 1;
+
+		vbottom = ceil (pnext->v);
+
+		if (vtop < vbottom)
+		{
+			du = pnext->u - pvert->u;
+			dv = pnext->v - pvert->v;
+
+			slope = du / dv;
+			u_step = (int)(slope * 0x10000);
+		// adjust u to ceil the integer portion
+			u = (int)((pvert->u + (slope * (vtop - pvert->v))) * 0x10000) +
+					(0x10000 - 1);
+			itop = (int)vtop;
+			ibottom = (int)vbottom;
+
+			for (v=itop ; v<ibottom ; v++)
+			{
+				pspan->u = u >> 16;
+				pspan->v = v;
+				u += u_step;
+				pspan++;
+			}
+		}
+
+		vtop = vbottom;
+
+		i--;
+		if (i == 0)
+			i = r_polydesc.nump;
+
+	} while (i != lmaxindex);
+}
+
+/*
+** R_PolygonScanRightEdge
+**
+** Goes through the polygon and scans the right edge, filling in
+** count values.
+*/
+void R_PolygonScanRightEdge (void)
+{
+	int			i, v, itop, ibottom;
+	emitpoint_t	*pvert, *pnext;
+	espan_t		*pspan;
+	float		du, dv, vtop, vbottom, slope, uvert, unext, vvert, vnext;
+	fixed16_t	u, u_step;
+
+	pspan = s_polygon_spans;
+	i = s_minindex;
+
+	vvert = r_polydesc.pverts[i].v;
+	if (vvert < r_refdef.fvrecty_adj)
+		vvert = r_refdef.fvrecty_adj;
+	if (vvert > r_refdef.fvrectbottom_adj)
+		vvert = r_refdef.fvrectbottom_adj;
+
+	vtop = ceil (vvert);
+
+	do
+	{
+		pvert = &r_polydesc.pverts[i];
+		pnext = pvert + 1;
+
+		vnext = pnext->v;
+		if (vnext < r_refdef.fvrecty_adj)
+			vnext = r_refdef.fvrecty_adj;
+		if (vnext > r_refdef.fvrectbottom_adj)
+			vnext = r_refdef.fvrectbottom_adj;
+
+		vbottom = ceil (vnext);
+
+		if (vtop < vbottom)
+		{
+			uvert = pvert->u;
+			if (uvert < r_refdef.fvrectx_adj)
+				uvert = r_refdef.fvrectx_adj;
+			if (uvert > r_refdef.fvrectright_adj)
+				uvert = r_refdef.fvrectright_adj;
+
+			unext = pnext->u;
+			if (unext < r_refdef.fvrectx_adj)
+				unext = r_refdef.fvrectx_adj;
+			if (unext > r_refdef.fvrectright_adj)
+				unext = r_refdef.fvrectright_adj;
+
+			du = unext - uvert;
+			dv = vnext - vvert;
+			slope = du / dv;
+			u_step = (int)(slope * 0x10000);
+		// adjust u to ceil the integer portion
+			u = (int)((uvert + (slope * (vtop - vvert))) * 0x10000) +
+					(0x10000 - 1);
+			itop = (int)vtop;
+			ibottom = (int)vbottom;
+
+			for (v=itop ; v<ibottom ; v++)
+			{
+				pspan->count = (u >> 16) - pspan->u;
+				u += u_step;
+				pspan++;
+			}
+		}
+
+		vtop = vbottom;
+		vvert = vnext;
+
+		i++;
+		if (i == r_polydesc.nump)
+			i = 0;
+
+	} while (i != s_maxindex);
+
+	pspan->count = DS_SPAN_LIST_END;	// mark the end of the span list 
+}
+
+/*
+** R_ClipAndDrawPoly
+*/
+void R_ClipAndDrawPoly( float alpha, qboolean isturbulent, qboolean textured )
+{
+	emitpoint_t	outverts[MAXWORKINGVERTS+3], *pout;
+	float		*pv;
+	int			i, nump;
+	float		scale;
+	vec3_t		transformed, local;
+
+	if ( !textured )
+	{
+		r_polydesc.drawspanlet = R_DrawSpanletConstant33;
+	}
+	else
+	{
+
+		/*
+		** choose the correct spanlet routine based on alpha
+		*/
+		if ( alpha == 1 )
+		{
+			// isturbulent is ignored because we know that turbulent surfaces
+			// can't be opaque
+			r_polydesc.drawspanlet = R_DrawSpanletOpaque;
+		}
+		else
+		{
+			if ( sw_stipplealpha->value )
+			{
+				if ( isturbulent )
+				{
+					if ( alpha > 0.33 )
+						r_polydesc.drawspanlet = R_DrawSpanletTurbulentStipple66;
+					else 
+						r_polydesc.drawspanlet = R_DrawSpanletTurbulentStipple33;
+				}
+				else
+				{
+					if ( alpha > 0.33 )
+						r_polydesc.drawspanlet = R_DrawSpanlet66Stipple;
+					else 
+						r_polydesc.drawspanlet = R_DrawSpanlet33Stipple;
+				}
+			}
+			else
+			{
+				if ( isturbulent )
+				{
+					if ( alpha > 0.33 )
+						r_polydesc.drawspanlet = R_DrawSpanletTurbulentBlended66;
+					else
+						r_polydesc.drawspanlet = R_DrawSpanletTurbulentBlended33;
+				}
+				else
+				{
+					if ( alpha > 0.33 )
+						r_polydesc.drawspanlet = R_DrawSpanlet66;
+					else 
+						r_polydesc.drawspanlet = R_DrawSpanlet33;
+				}
+			}
+		}
+	}
+
+	// clip to the frustum in worldspace
+	nump = r_polydesc.nump;
+	clip_current = 0;
+
+	for (i=0 ; i<4 ; i++)
+	{
+		nump = R_ClipPolyFace (nump, &view_clipplanes[i]);
+		if (nump < 3)
+			return;
+		if (nump > MAXWORKINGVERTS)
+			ri.Sys_Error(ERR_DROP, "R_ClipAndDrawPoly: too many points: %d", nump );
+	}
+
+// transform vertices into viewspace and project
+	pv = &r_clip_verts[clip_current][0][0];
+
+	for (i=0 ; i<nump ; i++)
+	{
+		VectorSubtract (pv, r_origin, local);
+		TransformVector (local, transformed);
+
+		if (transformed[2] < NEAR_CLIP)
+			transformed[2] = NEAR_CLIP;
+
+		pout = &outverts[i];
+		pout->zi = 1.0 / transformed[2];
+
+		pout->s = pv[3];
+		pout->t = pv[4];
+		
+		scale = xscale * pout->zi;
+		pout->u = (xcenter + scale * transformed[0]);
+
+		scale = yscale * pout->zi;
+		pout->v = (ycenter - scale * transformed[1]);
+
+		pv += sizeof (vec5_t) / sizeof (pv);
+	}
+
+// draw it
+	r_polydesc.nump = nump;
+	r_polydesc.pverts = outverts;
+
+	R_DrawPoly( isturbulent );
+}
+
+/*
+** R_BuildPolygonFromSurface
+*/
+void R_BuildPolygonFromSurface(msurface_t *fa)
+{
+	int			i, lindex, lnumverts;
+	medge_t		*pedges, *r_pedge;
+	int			vertpage;
+	float		*vec;
+	vec5_t     *pverts;
+	float       tmins[2] = { 0, 0 };
+
+	r_polydesc.nump = 0;
+
+	// reconstruct the polygon
+	pedges = currentmodel->edges;
+	lnumverts = fa->numedges;
+	vertpage = 0;
+
+	pverts = r_clip_verts[0];
+
+	for (i=0 ; i<lnumverts ; i++)
+	{
+		lindex = currentmodel->surfedges[fa->firstedge + i];
+
+		if (lindex > 0)
+		{
+			r_pedge = &pedges[lindex];
+			vec = currentmodel->vertexes[r_pedge->v[0]].position;
+		}
+		else
+		{
+			r_pedge = &pedges[-lindex];
+			vec = currentmodel->vertexes[r_pedge->v[1]].position;
+		}
+
+		VectorCopy (vec, pverts[i] );
+	}
+
+	VectorCopy( fa->texinfo->vecs[0], r_polydesc.vright );
+	VectorCopy( fa->texinfo->vecs[1], r_polydesc.vup );
+	VectorCopy( fa->plane->normal, r_polydesc.vpn );
+	VectorCopy( r_origin, r_polydesc.viewer_position );
+
+	if ( fa->flags & SURF_PLANEBACK )
+	{
+		VectorSubtract( vec3_origin, r_polydesc.vpn, r_polydesc.vpn );
+	}
+
+	if ( fa->texinfo->flags & SURF_WARP )
+	{
+		r_polydesc.pixels       = fa->texinfo->image->pixels[0];
+		r_polydesc.pixel_width  = fa->texinfo->image->width;
+		r_polydesc.pixel_height = fa->texinfo->image->height;
+	}
+	else
+	{
+		surfcache_t *scache;
+
+		scache = D_CacheSurface( fa, 0 );
+
+		r_polydesc.pixels       = scache->data;
+		r_polydesc.pixel_width  = scache->width;
+		r_polydesc.pixel_height = scache->height;
+
+		tmins[0] = fa->texturemins[0];
+		tmins[1] = fa->texturemins[1];
+	}
+
+	r_polydesc.dist = DotProduct( r_polydesc.vpn, pverts[0] );
+
+	r_polydesc.s_offset = fa->texinfo->vecs[0][3] - tmins[0];
+	r_polydesc.t_offset = fa->texinfo->vecs[1][3] - tmins[1];
+
+	// scrolling texture addition
+	if (fa->texinfo->flags & SURF_FLOWING)
+	{
+		r_polydesc.s_offset += -128 * ( (r_newrefdef.time*0.25) - (int)(r_newrefdef.time*0.25) );
+	}
+
+	r_polydesc.nump = lnumverts;
+}
+
+/*
+** R_PolygonCalculateGradients
+*/
+void R_PolygonCalculateGradients (void)
+{
+	vec3_t		p_normal, p_saxis, p_taxis;
+	float		distinv;
+
+	TransformVector (r_polydesc.vpn, p_normal);
+	TransformVector (r_polydesc.vright, p_saxis);
+	TransformVector (r_polydesc.vup, p_taxis);
+
+	distinv = 1.0 / (-(DotProduct (r_polydesc.viewer_position, r_polydesc.vpn)) + r_polydesc.dist );
+
+	d_sdivzstepu  =  p_saxis[0] * xscaleinv;
+	d_sdivzstepv  = -p_saxis[1] * yscaleinv;
+	d_sdivzorigin =  p_saxis[2] - xcenter * d_sdivzstepu - ycenter * d_sdivzstepv;
+
+	d_tdivzstepu  =  p_taxis[0] * xscaleinv;
+	d_tdivzstepv  = -p_taxis[1] * yscaleinv;
+	d_tdivzorigin =  p_taxis[2] - xcenter * d_tdivzstepu - ycenter * d_tdivzstepv;
+
+	d_zistepu =   p_normal[0] * xscaleinv * distinv;
+	d_zistepv =  -p_normal[1] * yscaleinv * distinv;
+	d_ziorigin =  p_normal[2] * distinv - xcenter * d_zistepu - ycenter * d_zistepv;
+
+	sadjust = (fixed16_t) ( ( DotProduct( r_polydesc.viewer_position, r_polydesc.vright) + r_polydesc.s_offset ) * 0x10000 );
+	tadjust = (fixed16_t) ( ( DotProduct( r_polydesc.viewer_position, r_polydesc.vup   ) + r_polydesc.t_offset ) * 0x10000 );
+
+// -1 (-epsilon) so we never wander off the edge of the texture
+	bbextents = (r_polydesc.pixel_width << 16) - 1;
+	bbextentt = (r_polydesc.pixel_height << 16) - 1;
+}
+
+/*
+** R_DrawPoly
+**
+** Polygon drawing function.  Uses the polygon described in r_polydesc
+** to calculate edges and gradients, then renders the resultant spans.
+**
+** This should NOT be called externally since it doesn't do clipping!
+*/
+static void R_DrawPoly( qboolean iswater )
+{
+	int			i, nump;
+	float		ymin, ymax;
+	emitpoint_t	*pverts;
+	espan_t	spans[MAXHEIGHT+1];
+
+	s_polygon_spans = spans;
+
+// find the top and bottom vertices, and make sure there's at least one scan to
+// draw
+	ymin = 999999.9;
+	ymax = -999999.9;
+	pverts = r_polydesc.pverts;
+
+	for (i=0 ; i<r_polydesc.nump ; i++)
+	{
+		if (pverts->v < ymin)
+		{
+			ymin = pverts->v;
+			s_minindex = i;
+		}
+
+		if (pverts->v > ymax)
+		{
+			ymax = pverts->v;
+			s_maxindex = i;
+		}
+
+		pverts++;
+	}
+
+	ymin = ceil (ymin);
+	ymax = ceil (ymax);
+
+	if (ymin >= ymax)
+		return;		// doesn't cross any scans at all
+
+	cachewidth = r_polydesc.pixel_width;
+	cacheblock = r_polydesc.pixels;
+
+// copy the first vertex to the last vertex, so we don't have to deal with
+// wrapping
+	nump = r_polydesc.nump;
+	pverts = r_polydesc.pverts;
+	pverts[nump] = pverts[0];
+
+	R_PolygonCalculateGradients ();
+	R_PolygonScanLeftEdge ();
+	R_PolygonScanRightEdge ();
+
+	R_PolygonDrawSpans( s_polygon_spans, iswater );
+}
+
+/*
+** R_DrawAlphaSurfaces
+*/
+void R_DrawAlphaSurfaces( void )
+{
+	msurface_t *s = r_alpha_surfaces;
+
+	currentmodel = r_worldmodel;
+
+	modelorg[0] = -r_origin[0];
+	modelorg[1] = -r_origin[1];
+	modelorg[2] = -r_origin[2];
+
+	while ( s )
+	{
+		R_BuildPolygonFromSurface( s );
+
+		if (s->texinfo->flags & SURF_TRANS66)
+			R_ClipAndDrawPoly( 0.60f, ( s->texinfo->flags & SURF_WARP) != 0, true );
+		else
+			R_ClipAndDrawPoly( 0.30f, ( s->texinfo->flags & SURF_WARP) != 0, true );
+
+		s = s->nextalphasurface;
+	}
+	
+	r_alpha_surfaces = NULL;
+}
+
+/*
+** R_IMFlatShadedQuad
+*/
+void R_IMFlatShadedQuad( vec3_t a, vec3_t b, vec3_t c, vec3_t d, int color, float alpha )
+{
+	vec3_t s0, s1;
+
+	r_polydesc.nump = 4;
+	VectorCopy( r_origin, r_polydesc.viewer_position );
+
+	VectorCopy( a, r_clip_verts[0][0] );
+	VectorCopy( b, r_clip_verts[0][1] );
+	VectorCopy( c, r_clip_verts[0][2] );
+	VectorCopy( d, r_clip_verts[0][3] );
+
+	r_clip_verts[0][0][3] = 0;
+	r_clip_verts[0][1][3] = 0;
+	r_clip_verts[0][2][3] = 0;
+	r_clip_verts[0][3][3] = 0;
+
+	r_clip_verts[0][0][4] = 0;
+	r_clip_verts[0][1][4] = 0;
+	r_clip_verts[0][2][4] = 0;
+	r_clip_verts[0][3][4] = 0;
+
+	VectorSubtract( d, c, s0 );
+	VectorSubtract( c, b, s1 );
+	CrossProduct( s0, s1, r_polydesc.vpn );
+	VectorNormalize( r_polydesc.vpn );
+
+	r_polydesc.dist = DotProduct( r_polydesc.vpn, r_clip_verts[0][0] );
+
+	r_polyblendcolor = color;
+
+	R_ClipAndDrawPoly( alpha, false, false );
+}
+
--- /dev/null
+++ b/ref/r_polyse.c
@@ -1,0 +1,1539 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// d_polyset.c: routines for drawing sets of polygons sharing the same
+// texture (used for Alias models)
+
+#include "r_local.h"
+
+int	rand1k[] = {
+#include "rand1k.h"
+};
+
+#define MASK_1K	0x3FF
+
+int		rand1k_index = 0;
+
+// TODO: put in span spilling to shrink list size
+// !!! if this is changed, it must be changed in d_polysa.s too !!!
+#define DPS_MAXSPANS			MAXHEIGHT+1	
+									// 1 extra for spanpackage that marks end
+
+// !!! if this is changed, it must be changed in asm_draw.h too !!!
+typedef struct {
+	void			*pdest;
+	short			*pz;
+	int				count;
+	byte			*ptex;
+	int				sfrac, tfrac, light, zi;
+} spanpackage_t;
+
+typedef struct {
+	int		isflattop;
+	int		numleftedges;
+	int		*pleftedgevert0;
+	int		*pleftedgevert1;
+	int		*pleftedgevert2;
+	int		numrightedges;
+	int		*prightedgevert0;
+	int		*prightedgevert1;
+	int		*prightedgevert2;
+} edgetable;
+
+aliastriangleparms_t aliastriangleparms;
+
+int	r_p0[6], r_p1[6], r_p2[6];
+
+byte		*d_pcolormap;
+
+int			d_aflatcolor;
+int			d_xdenom;
+
+edgetable	*pedgetable;
+
+edgetable	edgetables[12] = {
+	{0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
+	{0, 2, r_p1, r_p0, r_p2,   1, r_p1, r_p2, NULL},
+	{1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
+	{0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
+	{0, 2, r_p0, r_p2, r_p1,   1, r_p0, r_p1, NULL},
+	{0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
+	{0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
+	{0, 2, r_p2, r_p1, r_p0,   1, r_p2, r_p0, NULL},
+	{0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
+	{1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
+	{1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
+	{0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
+};
+
+// FIXME: some of these can become statics
+int				a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
+int				r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
+int				r_zistepx, r_zistepy;
+int				d_aspancount, d_countextrastep;
+
+spanpackage_t			*a_spans;
+spanpackage_t			*d_pedgespanpackage;
+static int				ystart;
+byte					*d_pdest, *d_ptex;
+short					*d_pz;
+int						d_sfrac, d_tfrac, d_light, d_zi;
+int						d_ptexextrastep, d_sfracextrastep;
+int						d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
+int						d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
+int						d_sfracbasestep, d_tfracbasestep;
+int						d_ziextrastep, d_zibasestep;
+int						d_pzextrastep, d_pzbasestep;
+
+typedef struct {
+	int		quotient;
+	int		remainder;
+} adivtab_t;
+
+static adivtab_t	adivtab[32*32] = {
+#include "adivtab.h"
+};
+
+byte	*skintable[MAX_LBM_HEIGHT];
+int		skinwidth;
+byte	*skinstart;
+
+void	(*d_pdrawspans)(spanpackage_t *pspanpackage);
+
+void R_PolysetDrawSpans8_33 (spanpackage_t *pspanpackage);
+void R_PolysetDrawSpans8_66 (spanpackage_t *pspanpackage);
+void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage);
+
+void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage);
+void R_PolysetCalcGradients (int skinwidth);
+void R_DrawNonSubdiv (void);
+void R_PolysetSetEdgeTable (void);
+void R_RasterizeAliasPolySmooth (void);
+void R_PolysetScanLeftEdge(int height);
+void R_PolysetScanLeftEdge_C(int height);
+
+// ======================
+// PGM
+// 64 65 66 67 68 69 70 71   72 73 74 75 76 77 78 79
+byte iractive = 0;
+byte irtable[256] = { 79, 78, 77, 76, 75, 74, 73, 72,		// black/white
+					  71, 70, 69, 68, 67, 66, 65, 64,
+					  64, 65, 66, 67, 68, 69, 70, 71,		// dark taupe
+					  72, 73, 74, 75, 76, 77, 78, 79,
+
+					  64, 65, 66, 67, 68, 69, 70, 71,		// slate grey
+					  72, 73, 74, 75, 76, 77, 78, 79,
+					  208, 208, 208, 208, 208, 208, 208, 208,	// unused?'
+					  64, 66, 68, 70, 72, 74, 76, 78,		// dark yellow
+					  
+					  64, 65, 66, 67, 68, 69, 70, 71,		// dark red
+					  72, 73, 74, 75, 76, 77, 78, 79,
+					  64, 65, 66, 67, 68, 69, 70, 71,		// grey/tan
+					  72, 73, 74, 75, 76, 77, 78, 79,
+
+					  64, 66, 68, 70, 72, 74, 76, 78,		// chocolate
+					  68, 67, 66, 65, 64, 65, 66, 67,		// mauve / teal
+					  68, 69, 70, 71, 72, 73, 74, 75,
+					  76, 76, 77, 77, 78, 78, 79, 79,		
+
+					  64, 65, 66, 67, 68, 69, 70, 71,		// more mauve
+					  72, 73, 74, 75, 76, 77, 78, 79,
+					  64, 65, 66, 67, 68, 69, 70, 71,		// olive
+					  72, 73, 74, 75, 76, 77, 78, 79,
+
+					  64, 65, 66, 67, 68, 69, 70, 71,		// maroon
+					  72, 73, 74, 75, 76, 77, 78, 79,
+					  64, 65, 66, 67, 68, 69, 70, 71,		// sky blue
+					  72, 73, 74, 75, 76, 77, 78, 79,
+					  
+					  64, 65, 66, 67, 68, 69, 70, 71,		// olive again
+					  72, 73, 74, 75, 76, 77, 78, 79,
+					  64, 65, 66, 67, 68, 69, 70, 71,		// nuclear green
+					  64, 65, 66, 67, 68, 69, 70, 71,		// bright yellow
+
+					  64, 65, 66, 67, 68, 69, 70, 71,		// fire colors
+					  72, 73, 74, 75, 76, 77, 78, 79,
+					  208, 208, 64, 64, 70, 71, 72, 64,		// mishmash1
+					  66, 68, 70, 64, 65, 66, 67, 68};		// mishmash2
+// PGM
+// ======================
+
+/*
+================
+R_PolysetUpdateTables
+================
+*/
+void R_PolysetUpdateTables (void)
+{
+	int		i;
+	byte	*s;
+	
+	if (r_affinetridesc.skinwidth != skinwidth ||
+		r_affinetridesc.pskin != skinstart)
+	{
+		skinwidth = r_affinetridesc.skinwidth;
+		skinstart = r_affinetridesc.pskin;
+		s = skinstart;
+		for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)
+			skintable[i] = s;
+	}
+}
+
+
+/*
+================
+R_DrawTriangle
+================
+*/
+void R_DrawTriangle( void )
+{
+	spanpackage_t spans[DPS_MAXSPANS];
+
+	int dv1_ab, dv0_ac;
+	int dv0_ab, dv1_ac;
+
+	/*
+	d_xdenom = ( aliastriangleparms.a->v[1] - aliastriangleparms.b->v[1] ) * ( aliastriangleparms.a->v[0] - aliastriangleparms.c->v[0] ) -
+			   ( aliastriangleparms.a->v[0] - aliastriangleparms.b->v[0] ) * ( aliastriangleparms.a->v[1] - aliastriangleparms.c->v[1] );
+	*/
+
+	dv0_ab = aliastriangleparms.a->u - aliastriangleparms.b->u;
+	dv1_ab = aliastriangleparms.a->v - aliastriangleparms.b->v;
+
+	if ( !( dv0_ab | dv1_ab ) )
+		return;
+
+	dv0_ac = aliastriangleparms.a->u - aliastriangleparms.c->u;
+	dv1_ac = aliastriangleparms.a->v - aliastriangleparms.c->v;
+
+	if ( !( dv0_ac | dv1_ac ) )
+		return;
+
+	d_xdenom = ( dv0_ac * dv1_ab ) - ( dv0_ab * dv1_ac );
+
+	if ( d_xdenom < 0 )
+	{
+		a_spans = spans;
+
+		r_p0[0] = aliastriangleparms.a->u;		// u
+		r_p0[1] = aliastriangleparms.a->v;		// v
+		r_p0[2] = aliastriangleparms.a->s;		// s
+		r_p0[3] = aliastriangleparms.a->t;		// t
+		r_p0[4] = aliastriangleparms.a->l;		// light
+		r_p0[5] = aliastriangleparms.a->zi;		// iz
+
+		r_p1[0] = aliastriangleparms.b->u;
+		r_p1[1] = aliastriangleparms.b->v;
+		r_p1[2] = aliastriangleparms.b->s;
+		r_p1[3] = aliastriangleparms.b->t;
+		r_p1[4] = aliastriangleparms.b->l;
+		r_p1[5] = aliastriangleparms.b->zi;
+
+		r_p2[0] = aliastriangleparms.c->u;
+		r_p2[1] = aliastriangleparms.c->v;
+		r_p2[2] = aliastriangleparms.c->s;
+		r_p2[3] = aliastriangleparms.c->t;
+		r_p2[4] = aliastriangleparms.c->l;
+		r_p2[5] = aliastriangleparms.c->zi;
+
+		R_PolysetSetEdgeTable ();
+		R_RasterizeAliasPolySmooth ();
+	}
+}
+
+
+/*
+===================
+R_PolysetScanLeftEdge_C
+====================
+*/
+void R_PolysetScanLeftEdge_C(int height)
+{
+	do
+	{
+		d_pedgespanpackage->pdest = d_pdest;
+		d_pedgespanpackage->pz = d_pz;
+		d_pedgespanpackage->count = d_aspancount;
+		d_pedgespanpackage->ptex = d_ptex;
+
+		d_pedgespanpackage->sfrac = d_sfrac;
+		d_pedgespanpackage->tfrac = d_tfrac;
+
+	// FIXME: need to clamp l, s, t, at both ends?
+		d_pedgespanpackage->light = d_light;
+		d_pedgespanpackage->zi = d_zi;
+
+		d_pedgespanpackage++;
+
+		errorterm += erroradjustup;
+		if (errorterm >= 0)
+		{
+			d_pdest += d_pdestextrastep;
+			d_pz += d_pzextrastep;
+			d_aspancount += d_countextrastep;
+			d_ptex += d_ptexextrastep;
+			d_sfrac += d_sfracextrastep;
+			d_ptex += d_sfrac >> 16;
+
+			d_sfrac &= 0xFFFF;
+			d_tfrac += d_tfracextrastep;
+			if (d_tfrac & 0x10000)
+			{
+				d_ptex += r_affinetridesc.skinwidth;
+				d_tfrac &= 0xFFFF;
+			}
+			d_light += d_lightextrastep;
+			d_zi += d_ziextrastep;
+			errorterm -= erroradjustdown;
+		}
+		else
+		{
+			d_pdest += d_pdestbasestep;
+			d_pz += d_pzbasestep;
+			d_aspancount += ubasestep;
+			d_ptex += d_ptexbasestep;
+			d_sfrac += d_sfracbasestep;
+			d_ptex += d_sfrac >> 16;
+			d_sfrac &= 0xFFFF;
+			d_tfrac += d_tfracbasestep;
+			if (d_tfrac & 0x10000)
+			{
+				d_ptex += r_affinetridesc.skinwidth;
+				d_tfrac &= 0xFFFF;
+			}
+			d_light += d_lightbasestep;
+			d_zi += d_zibasestep;
+		}
+	} while (--height);
+}
+
+/*
+===================
+FloorDivMod
+
+Returns mathematically correct (floor-based) quotient and remainder for
+numer and denom, both of which should contain no fractional part. The
+quotient must fit in 32 bits.
+FIXME: GET RID OF THIS! (FloorDivMod)
+====================
+*/
+void FloorDivMod (float numer, float denom, int *quotient,
+		int *rem)
+{
+	int		q, r;
+	float	x;
+
+	if (numer >= 0.0)
+	{
+
+		x = floor(numer / denom);
+		q = (int)x;
+		r = (int)floor(numer - (x * denom));
+	}
+	else
+	{
+	//
+	// perform operations with positive values, and fix mod to make floor-based
+	//
+		x = floor(-numer / denom);
+		q = -(int)x;
+		r = (int)floor(-numer - (x * denom));
+		if (r != 0)
+		{
+			q--;
+			r = (int)denom - r;
+		}
+	}
+
+	*quotient = q;
+	*rem = r;
+}
+
+
+/*
+===================
+R_PolysetSetUpForLineScan
+====================
+*/
+void R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
+		fixed8_t endvertu, fixed8_t endvertv)
+{
+	float		dm, dn;
+	int			tm, tn;
+	adivtab_t	*ptemp;
+
+// TODO: implement x86 version
+
+	errorterm = -1;
+
+	tm = endvertu - startvertu;
+	tn = endvertv - startvertv;
+
+	if (((tm <= 16) && (tm >= -15)) &&
+		((tn <= 16) && (tn >= -15)))
+	{
+		ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
+		ubasestep = ptemp->quotient;
+		erroradjustup = ptemp->remainder;
+		erroradjustdown = tn;
+	}
+	else
+	{
+		dm = tm;
+		dn = tn;
+
+		FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
+
+		erroradjustdown = dn;
+	}
+}
+
+
+
+/*
+================
+R_PolysetCalcGradients
+================
+*/
+#if id386 && !defined __linux__
+void R_PolysetCalcGradients( int skinwidth )
+{
+	static float xstepdenominv, ystepdenominv, t0, t1;
+	static float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
+	static float one = 1.0F, negative_one = -1.0F;
+	static unsigned long t0_int, t1_int;
+
+	extern unsigned long fpu_sp24_ceil_cw, fpu_ceil_cw, fpu_chop_cw;
+
+	/*
+	p00_minus_p20 = r_p0[0] - r_p2[0];
+	p01_minus_p21 = r_p0[1] - r_p2[1];
+	p10_minus_p20 = r_p1[0] - r_p2[0];
+	p11_minus_p21 = r_p1[1] - r_p2[1];
+	*/
+
+	__asm mov eax, dword ptr [r_p0+0]
+	__asm mov ebx, dword ptr [r_p0+4]
+	__asm sub eax, dword ptr [r_p2+0]
+	__asm sub ebx, dword ptr [r_p2+4]
+	__asm mov p00_minus_p20, eax
+	__asm mov p01_minus_p21, ebx
+	__asm fild dword ptr p00_minus_p20
+	__asm fild dword ptr p01_minus_p21
+	__asm mov eax, dword ptr [r_p1+0]
+	__asm mov ebx, dword ptr [r_p1+4]
+	__asm sub eax, dword ptr [r_p2+0]
+	__asm sub ebx, dword ptr [r_p2+4]
+	__asm fstp p01_minus_p21
+	__asm fstp p00_minus_p20
+	__asm mov p10_minus_p20, eax
+	__asm mov p11_minus_p21, ebx
+	__asm fild dword ptr p10_minus_p20
+	__asm fild dword ptr p11_minus_p21
+	__asm fstp p11_minus_p21
+	__asm fstp p10_minus_p20
+
+	/*
+	xstepdenominv = 1.0 / (float)d_xdenom;
+
+	ystepdenominv = -xstepdenominv;
+	*/
+
+	/*
+	** put FPU in single precision ceil mode
+	*/
+	__asm fldcw word ptr [fpu_sp24_ceil_cw]
+//	__asm fldcw word ptr [fpu_ceil_cw]
+
+	__asm fild  dword ptr d_xdenom    ; d_xdenom
+	__asm fdivr one                   ; 1 / d_xdenom
+	__asm fst   xstepdenominv         ; 
+	__asm fmul  negative_one          ; -( 1 / d_xdenom )
+
+// ceil () for light so positive steps are exaggerated, negative steps
+// diminished,  pushing us away from underflow toward overflow. Underflow is
+// very visible, overflow is very unlikely, because of ambient lighting
+	/*
+	t0 = r_p0[4] - r_p2[4];
+	t1 = r_p1[4] - r_p2[4];
+	r_lstepx = (int)
+			ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
+	r_lstepy = (int)
+			ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
+	*/
+	__asm mov   eax, dword ptr [r_p0+16]
+	__asm mov   ebx, dword ptr [r_p1+16]
+	__asm sub   eax, dword ptr [r_p2+16]
+	__asm sub   ebx, dword ptr [r_p2+16]
+
+	__asm fstp  ystepdenominv       ; (empty)
+
+	__asm mov   t0_int, eax
+	__asm mov   t1_int, ebx
+	__asm fild  t0_int              ; t0
+	__asm fild  t1_int              ; t1 | t0
+	__asm fxch  st(1)               ; t0 | t1
+	__asm fstp  t0                  ; t1
+	__asm fst   t1                  ; t1
+	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
+	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
+	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fsubrp st(1), st          ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fxch  st(1)
+	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
+	__asm fxch  st(1)               ; r_lstepx | r_lstepy
+	__asm fistp dword ptr [r_lstepx]
+	__asm fistp dword ptr [r_lstepy]
+
+	/*
+	** put FPU back into extended precision chop mode
+	*/
+	__asm fldcw word ptr [fpu_chop_cw]
+
+	/*
+	t0 = r_p0[2] - r_p2[2];
+	t1 = r_p1[2] - r_p2[2];
+	r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
+			xstepdenominv);
+	r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
+			ystepdenominv);
+	*/
+	__asm mov eax, dword ptr [r_p0+8]
+	__asm mov ebx, dword ptr [r_p1+8]
+	__asm sub eax, dword ptr [r_p2+8]
+	__asm sub ebx, dword ptr [r_p2+8]
+	__asm mov   t0_int, eax
+	__asm mov   t1_int, ebx
+	__asm fild  t0_int              ; t0
+	__asm fild  t1_int              ; t1 | t0
+	__asm fxch  st(1)               ; t0 | t1
+	__asm fstp  t0                  ; t1
+	__asm fst   t1                  ; (empty)
+
+	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
+	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
+	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fxch  st(1)
+	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
+	__asm fxch  st(1)               ; r_lstepx | r_lstepy
+	__asm fistp dword ptr [r_sstepx]
+	__asm fistp dword ptr [r_sstepy]
+
+	/*
+	t0 = r_p0[3] - r_p2[3];
+	t1 = r_p1[3] - r_p2[3];
+	r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
+			xstepdenominv);
+	r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
+			ystepdenominv);
+	*/
+	__asm mov eax, dword ptr [r_p0+12]
+	__asm mov ebx, dword ptr [r_p1+12]
+	__asm sub eax, dword ptr [r_p2+12]
+	__asm sub ebx, dword ptr [r_p2+12]
+
+	__asm mov   t0_int, eax
+	__asm mov   t1_int, ebx
+	__asm fild  t0_int              ; t0
+	__asm fild  t1_int              ; t1 | t0
+	__asm fxch  st(1)               ; t0 | t1
+	__asm fstp  t0                  ; t1
+	__asm fst   t1                  ; (empty)
+
+	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
+	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
+	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fxch  st(1)
+	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
+	__asm fxch  st(1)               ; r_lstepx | r_lstepy
+	__asm fistp dword ptr [r_tstepx]
+	__asm fistp dword ptr [r_tstepy]
+
+	/*
+	t0 = r_p0[5] - r_p2[5];
+	t1 = r_p1[5] - r_p2[5];
+	r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
+			xstepdenominv);
+	r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
+			ystepdenominv);
+	*/
+	__asm mov eax, dword ptr [r_p0+20]
+	__asm mov ebx, dword ptr [r_p1+20]
+	__asm sub eax, dword ptr [r_p2+20]
+	__asm sub ebx, dword ptr [r_p2+20]
+
+	__asm mov   t0_int, eax
+	__asm mov   t1_int, ebx
+	__asm fild  t0_int              ; t0
+	__asm fild  t1_int              ; t1 | t0
+	__asm fxch  st(1)               ; t0 | t1
+	__asm fstp  t0                  ; t1
+	__asm fst   t1                  ; (empty)
+
+	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
+	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
+	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
+	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
+	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
+	__asm fxch  st(1)
+	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
+	__asm fxch  st(1)               ; r_lstepx | r_lstepy
+	__asm fistp dword ptr [r_zistepx]
+	__asm fistp dword ptr [r_zistepy]
+
+	/*
+#if	id386ALIAS
+	a_sstepxfrac = r_sstepx << 16;
+	a_tstepxfrac = r_tstepx << 16;
+#else
+	a_sstepxfrac = r_sstepx & 0xFFFF;
+	a_tstepxfrac = r_tstepx & 0xFFFF;
+#endif
+	*/
+	__asm mov eax, d_pdrawspans
+	__asm cmp eax, offset R_PolysetDrawSpans8_Opaque
+	__asm mov eax, r_sstepx
+	__asm mov ebx, r_tstepx
+	__asm jne translucent
+//#if id386ALIAS
+	__asm shl eax, 16
+	__asm shl ebx, 16
+	__asm jmp done_with_steps
+//#else
+translucent:
+	__asm and eax, 0ffffh
+	__asm and ebx, 0ffffh
+//#endif
+done_with_steps:
+	__asm mov a_sstepxfrac, eax
+	__asm mov a_tstepxfrac, ebx
+
+	/*
+	a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
+	*/
+	__asm mov ebx, r_tstepx
+	__asm mov ecx, r_sstepx
+	__asm sar ebx, 16
+	__asm mov eax, skinwidth
+	__asm mul ebx
+	__asm sar ecx, 16
+	__asm add eax, ecx
+	__asm mov a_ststepxwhole, eax
+}
+#else
+void R_PolysetCalcGradients (int skinwidth)
+{
+	float	xstepdenominv, ystepdenominv, t0, t1;
+	float	p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
+
+	p00_minus_p20 = r_p0[0] - r_p2[0];
+	p01_minus_p21 = r_p0[1] - r_p2[1];
+	p10_minus_p20 = r_p1[0] - r_p2[0];
+	p11_minus_p21 = r_p1[1] - r_p2[1];
+
+	xstepdenominv = 1.0 / (float)d_xdenom;
+
+	ystepdenominv = -xstepdenominv;
+
+// ceil () for light so positive steps are exaggerated, negative steps
+// diminished,  pushing us away from underflow toward overflow. Underflow is
+// very visible, overflow is very unlikely, because of ambient lighting
+	t0 = r_p0[4] - r_p2[4];
+	t1 = r_p1[4] - r_p2[4];
+	r_lstepx = (int)
+			ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
+	r_lstepy = (int)
+			ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
+
+	t0 = r_p0[2] - r_p2[2];
+	t1 = r_p1[2] - r_p2[2];
+	r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
+			xstepdenominv);
+	r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
+			ystepdenominv);
+
+	t0 = r_p0[3] - r_p2[3];
+	t1 = r_p1[3] - r_p2[3];
+	r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
+			xstepdenominv);
+	r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
+			ystepdenominv);
+
+	t0 = r_p0[5] - r_p2[5];
+	t1 = r_p1[5] - r_p2[5];
+	r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
+			xstepdenominv);
+	r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
+			ystepdenominv);
+
+//#if	id386ALIAS
+#if id386
+	if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+	{
+		a_sstepxfrac = r_sstepx << 16;
+		a_tstepxfrac = r_tstepx << 16;
+	}
+	else
+#endif
+	{
+//#else
+		a_sstepxfrac = r_sstepx & 0xFFFF;
+		a_tstepxfrac = r_tstepx & 0xFFFF;
+	}
+//#endif
+
+	a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
+}
+#endif
+
+/*
+================
+R_PolysetDrawThreshSpans8
+
+Random fizzle fade rasterizer
+================
+*/
+void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage)
+{
+	int		lcount;
+	byte	*lpdest;
+	byte	*lptex;
+	int		lsfrac, ltfrac;
+	int		llight;
+	int		lzi;
+	short	*lpz;
+
+	do
+	{
+		lcount = d_aspancount - pspanpackage->count;
+
+		errorterm += erroradjustup;
+		if (errorterm >= 0)
+		{
+			d_aspancount += d_countextrastep;
+			errorterm -= erroradjustdown;
+		}
+		else
+		{
+			d_aspancount += ubasestep;
+		}
+
+		if (lcount)
+		{
+			lpdest = pspanpackage->pdest;
+			lptex = pspanpackage->ptex;
+			lpz = pspanpackage->pz;
+			lsfrac = pspanpackage->sfrac;
+			ltfrac = pspanpackage->tfrac;
+			llight = pspanpackage->light;
+			lzi = pspanpackage->zi;
+
+			do
+			{
+				if ((lzi >> 16) >= *lpz)
+				{
+					rand1k_index = (rand1k_index + 1) & MASK_1K;
+
+					if (rand1k[rand1k_index] <= r_affinetridesc.vis_thresh)
+					{
+						*lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
+						*lpz = lzi >> 16;
+					}
+				}
+
+				lpdest++;
+				lzi += r_zistepx;
+				lpz++;
+				llight += r_lstepx;
+				lptex += a_ststepxwhole;
+				lsfrac += a_sstepxfrac;
+				lptex += lsfrac >> 16;
+				lsfrac &= 0xFFFF;
+				ltfrac += a_tstepxfrac;
+				if (ltfrac & 0x10000)
+				{
+					lptex += r_affinetridesc.skinwidth;
+					ltfrac &= 0xFFFF;
+				}
+			} while (--lcount);
+		}
+
+		pspanpackage++;
+	} while (pspanpackage->count != -999999);
+}
+
+
+/*
+================
+R_PolysetDrawSpans8
+================
+*/
+void R_PolysetDrawSpans8_33( spanpackage_t *pspanpackage)
+{
+	int		lcount;
+	byte	*lpdest;
+	byte	*lptex;
+	int		lsfrac, ltfrac;
+	int		llight;
+	int		lzi;
+	short	*lpz;
+
+	do
+	{
+		lcount = d_aspancount - pspanpackage->count;
+
+		errorterm += erroradjustup;
+		if (errorterm >= 0)
+		{
+			d_aspancount += d_countextrastep;
+			errorterm -= erroradjustdown;
+		}
+		else
+		{
+			d_aspancount += ubasestep;
+		}
+
+		if (lcount)
+		{
+			lpdest = pspanpackage->pdest;
+			lptex = pspanpackage->ptex;
+			lpz = pspanpackage->pz;
+			lsfrac = pspanpackage->sfrac;
+			ltfrac = pspanpackage->tfrac;
+			llight = pspanpackage->light;
+			lzi = pspanpackage->zi;
+
+			do
+			{
+				if ((lzi >> 16) >= *lpz)
+				{
+					int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
+
+					*lpdest = vid.alphamap[temp+ *lpdest*256];
+				}
+				lpdest++;
+				lzi += r_zistepx;
+				lpz++;
+				llight += r_lstepx;
+				lptex += a_ststepxwhole;
+				lsfrac += a_sstepxfrac;
+				lptex += lsfrac >> 16;
+				lsfrac &= 0xFFFF;
+				ltfrac += a_tstepxfrac;
+				if (ltfrac & 0x10000)
+				{
+					lptex += r_affinetridesc.skinwidth;
+					ltfrac &= 0xFFFF;
+				}
+			} while (--lcount);
+		}
+
+		pspanpackage++;
+	} while (pspanpackage->count != -999999);
+}
+
+void R_PolysetDrawSpansConstant8_33( spanpackage_t *pspanpackage)
+{
+	int		lcount;
+	byte	*lpdest;
+	int		lzi;
+	short	*lpz;
+
+	do
+	{
+		lcount = d_aspancount - pspanpackage->count;
+
+		errorterm += erroradjustup;
+		if (errorterm >= 0)
+		{
+			d_aspancount += d_countextrastep;
+			errorterm -= erroradjustdown;
+		}
+		else
+		{
+			d_aspancount += ubasestep;
+		}
+
+		if (lcount)
+		{
+			lpdest = pspanpackage->pdest;
+			lpz = pspanpackage->pz;
+			lzi = pspanpackage->zi;
+
+			do
+			{
+				if ((lzi >> 16) >= *lpz)
+				{
+					*lpdest = vid.alphamap[r_aliasblendcolor + *lpdest*256];
+				}
+				lpdest++;
+				lzi += r_zistepx;
+				lpz++;
+			} while (--lcount);
+		}
+
+		pspanpackage++;
+	} while (pspanpackage->count != -999999);
+}
+
+void R_PolysetDrawSpans8_66(spanpackage_t *pspanpackage)
+{
+	int		lcount;
+	byte	*lpdest;
+	byte	*lptex;
+	int		lsfrac, ltfrac;
+	int		llight;
+	int		lzi;
+	short	*lpz;
+
+	do
+	{
+		lcount = d_aspancount - pspanpackage->count;
+
+		errorterm += erroradjustup;
+		if (errorterm >= 0)
+		{
+			d_aspancount += d_countextrastep;
+			errorterm -= erroradjustdown;
+		}
+		else
+		{
+			d_aspancount += ubasestep;
+		}
+
+		if (lcount)
+		{
+			lpdest = pspanpackage->pdest;
+			lptex = pspanpackage->ptex;
+			lpz = pspanpackage->pz;
+			lsfrac = pspanpackage->sfrac;
+			ltfrac = pspanpackage->tfrac;
+			llight = pspanpackage->light;
+			lzi = pspanpackage->zi;
+
+			do
+			{
+				if ((lzi >> 16) >= *lpz)
+				{
+					int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
+
+					*lpdest = vid.alphamap[temp*256 + *lpdest];
+					*lpz = lzi >> 16;
+				}
+				lpdest++;
+				lzi += r_zistepx;
+				lpz++;
+				llight += r_lstepx;
+				lptex += a_ststepxwhole;
+				lsfrac += a_sstepxfrac;
+				lptex += lsfrac >> 16;
+				lsfrac &= 0xFFFF;
+				ltfrac += a_tstepxfrac;
+				if (ltfrac & 0x10000)
+				{
+					lptex += r_affinetridesc.skinwidth;
+					ltfrac &= 0xFFFF;
+				}
+			} while (--lcount);
+		}
+
+		pspanpackage++;
+	} while (pspanpackage->count != -999999);
+}
+
+void R_PolysetDrawSpansConstant8_66( spanpackage_t *pspanpackage)
+{
+	int		lcount;
+	byte	*lpdest;
+	int		lzi;
+	short	*lpz;
+
+	do
+	{
+		lcount = d_aspancount - pspanpackage->count;
+
+		errorterm += erroradjustup;
+		if (errorterm >= 0)
+		{
+			d_aspancount += d_countextrastep;
+			errorterm -= erroradjustdown;
+		}
+		else
+		{
+			d_aspancount += ubasestep;
+		}
+
+		if (lcount)
+		{
+			lpdest = pspanpackage->pdest;
+			lpz = pspanpackage->pz;
+			lzi = pspanpackage->zi;
+
+			do
+			{
+				if ((lzi >> 16) >= *lpz)
+				{
+					*lpdest = vid.alphamap[r_aliasblendcolor*256 + *lpdest];
+				}
+				lpdest++;
+				lzi += r_zistepx;
+				lpz++;
+			} while (--lcount);
+		}
+
+		pspanpackage++;
+	} while (pspanpackage->count != -999999);
+}
+
+#if !id386
+void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage)
+{
+	int		lcount;
+
+	do
+	{
+		lcount = d_aspancount - pspanpackage->count;
+
+		errorterm += erroradjustup;
+		if (errorterm >= 0)
+		{
+			d_aspancount += d_countextrastep;
+			errorterm -= erroradjustdown;
+		}
+		else
+		{
+			d_aspancount += ubasestep;
+		}
+
+		if (lcount)
+		{
+			int		lsfrac, ltfrac;
+			byte	*lpdest;
+			byte	*lptex;
+			int		llight;
+			int		lzi;
+			short	*lpz;
+
+			lpdest = pspanpackage->pdest;
+			lptex = pspanpackage->ptex;
+			lpz = pspanpackage->pz;
+			lsfrac = pspanpackage->sfrac;
+			ltfrac = pspanpackage->tfrac;
+			llight = pspanpackage->light;
+			lzi = pspanpackage->zi;
+
+			do
+			{
+				if ((lzi >> 16) >= *lpz)
+				{
+//PGM
+					if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
+						*lpdest = ((byte *)vid.colormap)[irtable[*lptex]];
+					else
+					*lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
+//PGM
+					*lpz = lzi >> 16;
+				}
+				lpdest++;
+				lzi += r_zistepx;
+				lpz++;
+				llight += r_lstepx;
+				lptex += a_ststepxwhole;
+				lsfrac += a_sstepxfrac;
+				lptex += lsfrac >> 16;
+				lsfrac &= 0xFFFF;
+				ltfrac += a_tstepxfrac;
+				if (ltfrac & 0x10000)
+				{
+					lptex += r_affinetridesc.skinwidth;
+					ltfrac &= 0xFFFF;
+				}
+			} while (--lcount);
+		}
+
+		pspanpackage++;
+	} while (pspanpackage->count != -999999);
+}
+#endif
+
+
+/*
+================
+R_PolysetFillSpans8
+================
+*/
+void R_PolysetFillSpans8 (spanpackage_t *pspanpackage)
+{
+	int				color;
+
+// FIXME: do z buffering
+
+	color = d_aflatcolor++;
+
+	while (1)
+	{
+		int		lcount;
+		byte	*lpdest;
+
+		lcount = pspanpackage->count;
+
+		if (lcount == -1)
+			return;
+
+		if (lcount)
+		{
+			lpdest = pspanpackage->pdest;
+
+			do
+			{
+				*lpdest++ = color;
+			} while (--lcount);
+		}
+
+		pspanpackage++;
+	}
+}
+
+/*
+================
+R_RasterizeAliasPolySmooth
+================
+*/
+void R_RasterizeAliasPolySmooth (void)
+{
+	int				initialleftheight, initialrightheight;
+	int				*plefttop, *prighttop, *pleftbottom, *prightbottom;
+	int				working_lstepx, originalcount;
+
+	plefttop = pedgetable->pleftedgevert0;
+	prighttop = pedgetable->prightedgevert0;
+
+	pleftbottom = pedgetable->pleftedgevert1;
+	prightbottom = pedgetable->prightedgevert1;
+
+	initialleftheight = pleftbottom[1] - plefttop[1];
+	initialrightheight = prightbottom[1] - prighttop[1];
+
+//
+// set the s, t, and light gradients, which are consistent across the triangle
+// because being a triangle, things are affine
+//
+	R_PolysetCalcGradients (r_affinetridesc.skinwidth);
+//
+// rasterize the polygon
+//
+
+//
+// scan out the top (and possibly only) part of the left edge
+//
+	d_pedgespanpackage = a_spans;
+
+	ystart = plefttop[1];
+	d_aspancount = plefttop[0] - prighttop[0];
+
+	d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
+			(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
+//#if	id386ALIAS
+#if id386
+	if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+	{
+		d_sfrac = (plefttop[2] & 0xFFFF) << 16;
+		d_tfrac = (plefttop[3] & 0xFFFF) << 16;
+	}
+//#else
+	else
+#endif
+	{
+		d_sfrac = plefttop[2] & 0xFFFF;
+		d_tfrac = plefttop[3] & 0xFFFF;
+	}
+//#endif
+	d_light = plefttop[4];
+	d_zi = plefttop[5];
+
+	d_pdest = (byte *)d_viewbuffer +
+			ystart * r_screenwidth + plefttop[0];
+	d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
+
+	if (initialleftheight == 1)
+	{
+		d_pedgespanpackage->pdest = d_pdest;
+		d_pedgespanpackage->pz = d_pz;
+		d_pedgespanpackage->count = d_aspancount;
+		d_pedgespanpackage->ptex = d_ptex;
+
+		d_pedgespanpackage->sfrac = d_sfrac;
+		d_pedgespanpackage->tfrac = d_tfrac;
+
+	// FIXME: need to clamp l, s, t, at both ends?
+		d_pedgespanpackage->light = d_light;
+		d_pedgespanpackage->zi = d_zi;
+
+		d_pedgespanpackage++;
+	}
+	else
+	{
+		R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
+							  pleftbottom[0], pleftbottom[1]);
+
+//#if	id386ALIAS
+#if id386
+		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+		{
+			d_pzbasestep = (d_zwidth + ubasestep) << 1;
+			d_pzextrastep = d_pzbasestep + 2;
+		}
+//#else
+		else
+#endif
+		{
+			d_pzbasestep = d_zwidth + ubasestep;
+			d_pzextrastep = d_pzbasestep + 1;
+		}
+//#endif
+
+		d_pdestbasestep = r_screenwidth + ubasestep;
+		d_pdestextrastep = d_pdestbasestep + 1;
+
+	// TODO: can reuse partial expressions here
+
+	// for negative steps in x along left edge, bias toward overflow rather than
+	// underflow (sort of turning the floor () we did in the gradient calcs into
+	// ceil (), but plus a little bit)
+		if (ubasestep < 0)
+			working_lstepx = r_lstepx - 1;
+		else
+			working_lstepx = r_lstepx;
+
+		d_countextrastep = ubasestep + 1;
+		d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
+				((r_tstepy + r_tstepx * ubasestep) >> 16) *
+				r_affinetridesc.skinwidth;
+//#if	id386ALIAS
+#if id386
+		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+		{
+			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
+			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
+		}
+		else
+#endif
+		{
+//#else
+			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
+			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
+		}
+//#endif
+		d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
+		d_zibasestep = r_zistepy + r_zistepx * ubasestep;
+
+		d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
+				((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
+				r_affinetridesc.skinwidth;
+//#if	id386ALIAS
+#if id386
+		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+		{
+			d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
+			d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
+		}
+		else
+#endif
+		{
+//#else
+			d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
+			d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
+		}
+//#endif
+		d_lightextrastep = d_lightbasestep + working_lstepx;
+		d_ziextrastep = d_zibasestep + r_zistepx;
+
+#if id386
+		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+		{
+			R_PolysetScanLeftEdge (initialleftheight);
+		}
+		else
+#endif
+		{
+			R_PolysetScanLeftEdge_C(initialleftheight);
+		}
+	}
+
+//
+// scan out the bottom part of the left edge, if it exists
+//
+	if (pedgetable->numleftedges == 2)
+	{
+		int		height;
+
+		plefttop = pleftbottom;
+		pleftbottom = pedgetable->pleftedgevert2;
+
+		height = pleftbottom[1] - plefttop[1];
+
+// TODO: make this a function; modularize this function in general
+
+		ystart = plefttop[1];
+		d_aspancount = plefttop[0] - prighttop[0];
+		d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
+				(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
+		d_sfrac = 0;
+		d_tfrac = 0;
+		d_light = plefttop[4];
+		d_zi = plefttop[5];
+
+		d_pdest = (byte *)d_viewbuffer + ystart * r_screenwidth + plefttop[0];
+		d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
+
+		if (height == 1)
+		{
+			d_pedgespanpackage->pdest = d_pdest;
+			d_pedgespanpackage->pz = d_pz;
+			d_pedgespanpackage->count = d_aspancount;
+			d_pedgespanpackage->ptex = d_ptex;
+
+			d_pedgespanpackage->sfrac = d_sfrac;
+			d_pedgespanpackage->tfrac = d_tfrac;
+
+		// FIXME: need to clamp l, s, t, at both ends?
+			d_pedgespanpackage->light = d_light;
+			d_pedgespanpackage->zi = d_zi;
+
+			d_pedgespanpackage++;
+		}
+		else
+		{
+			R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
+								  pleftbottom[0], pleftbottom[1]);
+
+			d_pdestbasestep = r_screenwidth + ubasestep;
+			d_pdestextrastep = d_pdestbasestep + 1;
+
+//#if	id386ALIAS
+#if id386
+			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+			{
+				d_pzbasestep = (d_zwidth + ubasestep) << 1;
+				d_pzextrastep = d_pzbasestep + 2;
+			}
+//#else
+			else
+#endif
+			{
+				d_pzbasestep = d_zwidth + ubasestep;
+				d_pzextrastep = d_pzbasestep + 1;
+			}
+//#endif
+
+			if (ubasestep < 0)
+				working_lstepx = r_lstepx - 1;
+			else
+				working_lstepx = r_lstepx;
+
+			d_countextrastep = ubasestep + 1;
+			d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
+					((r_tstepy + r_tstepx * ubasestep) >> 16) *
+					r_affinetridesc.skinwidth;
+//#if	id386ALIAS
+#if id386
+			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+			{
+				d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
+				d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
+			}
+//#else
+			else
+#endif
+			{
+				d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
+				d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
+			}
+//#endif
+			d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
+			d_zibasestep = r_zistepy + r_zistepx * ubasestep;
+
+			d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
+					((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
+					r_affinetridesc.skinwidth;
+//#if	id386ALIAS
+#if id386
+			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+			{
+				d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
+				d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
+			}
+			else
+#endif
+//#endif
+			{
+				d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
+				d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
+			}
+//#endif
+			d_lightextrastep = d_lightbasestep + working_lstepx;
+			d_ziextrastep = d_zibasestep + r_zistepx;
+
+#if id386
+			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
+			{
+				R_PolysetScanLeftEdge (height);
+			}
+			else
+#endif
+			{
+				R_PolysetScanLeftEdge_C(height);
+			}
+		}
+	}
+
+// scan out the top (and possibly only) part of the right edge, updating the
+// count field
+	d_pedgespanpackage = a_spans;
+
+	R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
+						  prightbottom[0], prightbottom[1]);
+	d_aspancount = 0;
+	d_countextrastep = ubasestep + 1;
+	originalcount = a_spans[initialrightheight].count;
+	a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
+	(*d_pdrawspans) (a_spans);
+
+// scan out the bottom part of the right edge, if it exists
+	if (pedgetable->numrightedges == 2)
+	{
+		int				height;
+		spanpackage_t	*pstart;
+
+		pstart = a_spans + initialrightheight;
+		pstart->count = originalcount;
+
+		d_aspancount = prightbottom[0] - prighttop[0];
+
+		prighttop = prightbottom;
+		prightbottom = pedgetable->prightedgevert2;
+
+		height = prightbottom[1] - prighttop[1];
+
+		R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
+							  prightbottom[0], prightbottom[1]);
+
+		d_countextrastep = ubasestep + 1;
+		a_spans[initialrightheight + height].count = -999999;
+											// mark end of the spanpackages
+		(*d_pdrawspans) (pstart);
+	}
+}
+
+
+/*
+================
+R_PolysetSetEdgeTable
+================
+*/
+void R_PolysetSetEdgeTable (void)
+{
+	int			edgetableindex;
+
+	edgetableindex = 0;	// assume the vertices are already in
+						//  top to bottom order
+
+//
+// determine which edges are right & left, and the order in which
+// to rasterize them
+//
+	if (r_p0[1] >= r_p1[1])
+	{
+		if (r_p0[1] == r_p1[1])
+		{
+			if (r_p0[1] < r_p2[1])
+				pedgetable = &edgetables[2];
+			else
+				pedgetable = &edgetables[5];
+
+			return;
+		}
+		else
+		{
+			edgetableindex = 1;
+		}
+	}
+
+	if (r_p0[1] == r_p2[1])
+	{
+		if (edgetableindex)
+			pedgetable = &edgetables[8];
+		else
+			pedgetable = &edgetables[9];
+
+		return;
+	}
+	else if (r_p1[1] == r_p2[1])
+	{
+		if (edgetableindex)
+			pedgetable = &edgetables[10];
+		else
+			pedgetable = &edgetables[11];
+
+		return;
+	}
+
+	if (r_p0[1] > r_p2[1])
+		edgetableindex += 2;
+
+	if (r_p1[1] > r_p2[1])
+		edgetableindex += 4;
+
+	pedgetable = &edgetables[edgetableindex];
+}
+
+
--- /dev/null
+++ b/ref/r_rast.c
@@ -1,0 +1,852 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_rast.c
+
+#include <assert.h>
+
+#include "r_local.h"
+
+#define MAXLEFTCLIPEDGES		100
+
+// !!! if these are changed, they must be changed in asm_draw.h too !!!
+#define FULLY_CLIPPED_CACHED	0x80000000
+#define FRAMECOUNT_MASK			0x7FFFFFFF
+
+unsigned int	cacheoffset;
+
+int			c_faceclip;					// number of faces clipped
+
+
+clipplane_t	*entity_clipplanes;
+clipplane_t	view_clipplanes[4];
+clipplane_t	world_clipplanes[16];
+
+medge_t			*r_pedge;
+
+qboolean		r_leftclipped, r_rightclipped;
+static qboolean	makeleftedge, makerightedge;
+qboolean		r_nearzionly;
+
+int		sintable[1280];
+int		intsintable[1280];
+int		blanktable[1280];		// PGM
+
+mvertex_t	r_leftenter, r_leftexit;
+mvertex_t	r_rightenter, r_rightexit;
+
+typedef struct
+{
+	float	u,v;
+	int		ceilv;
+} evert_t;
+
+int				r_emitted;
+float			r_nearzi;
+float			r_u1, r_v1, r_lzi1;
+int				r_ceilv1;
+
+qboolean		r_lastvertvalid;
+int				r_skyframe;
+
+msurface_t		*r_skyfaces;
+mplane_t		r_skyplanes[6];
+mtexinfo_t		r_skytexinfo[6];
+mvertex_t		*r_skyverts;
+medge_t			*r_skyedges;
+int				*r_skysurfedges;
+
+// I just copied this data from a box map...
+int skybox_planes[12] = {2,-128, 0,-128, 2,128, 1,128, 0,128, 1,-128};
+
+int box_surfedges[24] = { 1,2,3,4,  -1,5,6,7,  8,9,-6,10,  -2,-7,-9,11,
+  12,-3,-11,-8,  -12,-10,-5,-4};
+int box_edges[24] = { 1,2, 2,3, 3,4, 4,1, 1,5, 5,6, 6,2, 7,8, 8,6, 5,7, 8,3, 7,4};
+
+int	box_faces[6] = {0,0,2,2,2,0};
+
+vec3_t	box_vecs[6][2] = {
+	{	{0,-1,0}, {-1,0,0} },
+	{ {0,1,0}, {0,0,-1} },
+	{	{0,-1,0}, {1,0,0} },
+	{ {1,0,0}, {0,0,-1} },
+	{ {0,-1,0}, {0,0,-1} },
+	{ {-1,0,0}, {0,0,-1} }
+};
+
+float	box_verts[8][3] = {
+	{-1,-1,-1},
+	{-1,1,-1},
+	{1,1,-1},
+	{1,-1,-1},
+	{-1,-1,1},
+	{-1,1,1},
+	{1,-1,1},
+	{1,1,1}
+};
+
+// down, west, up, north, east, south
+// {"rt", "bk", "lf", "ft", "up", "dn"};
+
+/*
+================
+R_InitSkyBox
+
+================
+*/
+void R_InitSkyBox (void)
+{
+	int		i;
+	extern model_t *loadmodel;
+
+	r_skyfaces = loadmodel->surfaces + loadmodel->numsurfaces;
+	loadmodel->numsurfaces += 6;
+	r_skyverts = loadmodel->vertexes + loadmodel->numvertexes;
+	loadmodel->numvertexes += 8;
+	r_skyedges = loadmodel->edges + loadmodel->numedges;
+	loadmodel->numedges += 12;
+	r_skysurfedges = loadmodel->surfedges + loadmodel->numsurfedges;
+	loadmodel->numsurfedges += 24;
+	if (loadmodel->numsurfaces > MAX_MAP_FACES
+		|| loadmodel->numvertexes > MAX_MAP_VERTS
+		|| loadmodel->numedges > MAX_MAP_EDGES)
+		ri.Sys_Error (ERR_DROP, "InitSkyBox: map overflow");
+
+	memset (r_skyfaces, 0, 6*sizeof(*r_skyfaces));
+	for (i=0 ; i<6 ; i++)
+	{
+		r_skyplanes[i].normal[skybox_planes[i*2]] = 1;
+		r_skyplanes[i].dist = skybox_planes[i*2+1];
+
+		VectorCopy (box_vecs[i][0], r_skytexinfo[i].vecs[0]);
+		VectorCopy (box_vecs[i][1], r_skytexinfo[i].vecs[1]);
+
+		r_skyfaces[i].plane = &r_skyplanes[i];
+		r_skyfaces[i].numedges = 4;
+		r_skyfaces[i].flags = box_faces[i] | SURF_DRAWSKYBOX;
+		r_skyfaces[i].firstedge = loadmodel->numsurfedges-24+i*4;
+		r_skyfaces[i].texinfo = &r_skytexinfo[i];
+		r_skyfaces[i].texturemins[0] = -128;
+		r_skyfaces[i].texturemins[1] = -128;
+		r_skyfaces[i].extents[0] = 256;
+		r_skyfaces[i].extents[1] = 256;
+	}
+
+	for (i=0 ; i<24 ; i++)
+		if (box_surfedges[i] > 0)
+			r_skysurfedges[i] = loadmodel->numedges-13 + box_surfedges[i];
+		else
+			r_skysurfedges[i] = - (loadmodel->numedges-13 + -box_surfedges[i]);
+
+	for(i=0 ; i<12 ; i++)
+	{
+		r_skyedges[i].v[0] = loadmodel->numvertexes-9+box_edges[i*2+0];
+		r_skyedges[i].v[1] = loadmodel->numvertexes-9+box_edges[i*2+1];
+		r_skyedges[i].cachededgeoffset = 0;
+	}
+}
+
+/*
+================
+R_EmitSkyBox
+================
+*/
+void R_EmitSkyBox (void)
+{
+	int		i, j;
+	int		oldkey;
+
+	if (insubmodel)
+		return;		// submodels should never have skies
+	if (r_skyframe == r_framecount)
+		return;		// already set this frame
+
+	r_skyframe = r_framecount;
+
+	// set the eight fake vertexes
+	for (i=0 ; i<8 ; i++)
+		for (j=0 ; j<3 ; j++)
+			r_skyverts[i].position[j] = r_origin[j] + box_verts[i][j]*128;
+
+	// set the six fake planes
+	for (i=0 ; i<6 ; i++)
+		if (skybox_planes[i*2+1] > 0)
+			r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]+128;
+		else
+			r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]-128;
+
+	// fix texture offseets
+	for (i=0 ; i<6 ; i++)
+	{
+		r_skytexinfo[i].vecs[0][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[0]);
+		r_skytexinfo[i].vecs[1][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[1]);
+	}
+
+	// emit the six faces
+	oldkey = r_currentkey;
+	r_currentkey = 0x7ffffff0;
+ 	for (i=0 ; i<6 ; i++)
+	{
+		R_RenderFace (r_skyfaces + i, 15);
+	}
+	r_currentkey = oldkey;		// bsp sorting order
+}
+
+
+#if	!id386
+
+/*
+================
+R_EmitEdge
+================
+*/
+void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
+{
+	edge_t	*edge, *pcheck;
+	int		u_check;
+	float	u, u_step;
+	vec3_t	local, transformed;
+	float	*world;
+	int		v, v2, ceilv0;
+	float	scale, lzi0, u0, v0;
+	int		side;
+
+	if (r_lastvertvalid)
+	{
+		u0 = r_u1;
+		v0 = r_v1;
+		lzi0 = r_lzi1;
+		ceilv0 = r_ceilv1;
+	}
+	else
+	{
+		world = &pv0->position[0];
+	
+	// transform and project
+		VectorSubtract (world, modelorg, local);
+		TransformVector (local, transformed);
+	
+		if (transformed[2] < NEAR_CLIP)
+			transformed[2] = NEAR_CLIP;
+	
+		lzi0 = 1.0 / transformed[2];
+	
+	// FIXME: build x/yscale into transform?
+		scale = xscale * lzi0;
+		u0 = (xcenter + scale*transformed[0]);
+		if (u0 < r_refdef.fvrectx_adj)
+			u0 = r_refdef.fvrectx_adj;
+		if (u0 > r_refdef.fvrectright_adj)
+			u0 = r_refdef.fvrectright_adj;
+	
+		scale = yscale * lzi0;
+		v0 = (ycenter - scale*transformed[1]);
+		if (v0 < r_refdef.fvrecty_adj)
+			v0 = r_refdef.fvrecty_adj;
+		if (v0 > r_refdef.fvrectbottom_adj)
+			v0 = r_refdef.fvrectbottom_adj;
+	
+		ceilv0 = (int) ceil(v0);
+	}
+
+	world = &pv1->position[0];
+
+// transform and project
+	VectorSubtract (world, modelorg, local);
+	TransformVector (local, transformed);
+
+	if (transformed[2] < NEAR_CLIP)
+		transformed[2] = NEAR_CLIP;
+
+	r_lzi1 = 1.0 / transformed[2];
+
+	scale = xscale * r_lzi1;
+	r_u1 = (xcenter + scale*transformed[0]);
+	if (r_u1 < r_refdef.fvrectx_adj)
+		r_u1 = r_refdef.fvrectx_adj;
+	if (r_u1 > r_refdef.fvrectright_adj)
+		r_u1 = r_refdef.fvrectright_adj;
+
+	scale = yscale * r_lzi1;
+	r_v1 = (ycenter - scale*transformed[1]);
+	if (r_v1 < r_refdef.fvrecty_adj)
+		r_v1 = r_refdef.fvrecty_adj;
+	if (r_v1 > r_refdef.fvrectbottom_adj)
+		r_v1 = r_refdef.fvrectbottom_adj;
+
+	if (r_lzi1 > lzi0)
+		lzi0 = r_lzi1;
+
+	if (lzi0 > r_nearzi)	// for mipmap finding
+		r_nearzi = lzi0;
+
+// for right edges, all we want is the effect on 1/z
+	if (r_nearzionly)
+		return;
+
+	r_emitted = 1;
+
+	r_ceilv1 = (int) ceil(r_v1);
+
+
+// create the edge
+	if (ceilv0 == r_ceilv1)
+	{
+	// we cache unclipped horizontal edges as fully clipped
+		if (cacheoffset != 0x7FFFFFFF)
+		{
+			cacheoffset = FULLY_CLIPPED_CACHED |
+					(r_framecount & FRAMECOUNT_MASK);
+		}
+
+		return;		// horizontal edge
+	}
+
+	side = ceilv0 > r_ceilv1;
+
+	edge = edge_p++;
+
+	edge->owner = r_pedge;
+
+	edge->nearzi = lzi0;
+
+	if (side == 0)
+	{
+	// trailing edge (go from p1 to p2)
+		v = ceilv0;
+		v2 = r_ceilv1 - 1;
+
+		edge->surfs[0] = surface_p - surfaces;
+		edge->surfs[1] = 0;
+
+		u_step = ((r_u1 - u0) / (r_v1 - v0));
+		u = u0 + ((float)v - v0) * u_step;
+	}
+	else
+	{
+	// leading edge (go from p2 to p1)
+		v2 = ceilv0 - 1;
+		v = r_ceilv1;
+
+		edge->surfs[0] = 0;
+		edge->surfs[1] = surface_p - surfaces;
+
+		u_step = ((u0 - r_u1) / (v0 - r_v1));
+		u = r_u1 + ((float)v - r_v1) * u_step;
+	}
+
+	edge->u_step = u_step*0x100000;
+	edge->u = u*0x100000 + 0xFFFFF;
+
+// we need to do this to avoid stepping off the edges if a very nearly
+// horizontal edge is less than epsilon above a scan, and numeric error causes
+// it to incorrectly extend to the scan, and the extension of the line goes off
+// the edge of the screen
+// FIXME: is this actually needed?
+	if (edge->u < r_refdef.vrect_x_adj_shift20)
+		edge->u = r_refdef.vrect_x_adj_shift20;
+	if (edge->u > r_refdef.vrectright_adj_shift20)
+		edge->u = r_refdef.vrectright_adj_shift20;
+
+//
+// sort the edge in normally
+//
+	u_check = edge->u;
+	if (edge->surfs[0])
+		u_check++;	// sort trailers after leaders
+
+	if (!newedges[v] || newedges[v]->u >= u_check)
+	{
+		edge->next = newedges[v];
+		newedges[v] = edge;
+	}
+	else
+	{
+		pcheck = newedges[v];
+		while (pcheck->next && pcheck->next->u < u_check)
+			pcheck = pcheck->next;
+		edge->next = pcheck->next;
+		pcheck->next = edge;
+	}
+
+	edge->nextremove = removeedges[v2];
+	removeedges[v2] = edge;
+}
+
+
+/*
+================
+R_ClipEdge
+================
+*/
+void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
+{
+	float		d0, d1, f;
+	mvertex_t	clipvert;
+
+	if (clip)
+	{
+		do
+		{
+			d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
+			d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
+
+			if (d0 >= 0)
+			{
+			// point 0 is unclipped
+				if (d1 >= 0)
+				{
+				// both points are unclipped
+					continue;
+				}
+
+			// only point 1 is clipped
+
+			// we don't cache clipped edges
+				cacheoffset = 0x7FFFFFFF;
+
+				f = d0 / (d0 - d1);
+				clipvert.position[0] = pv0->position[0] +
+						f * (pv1->position[0] - pv0->position[0]);
+				clipvert.position[1] = pv0->position[1] +
+						f * (pv1->position[1] - pv0->position[1]);
+				clipvert.position[2] = pv0->position[2] +
+						f * (pv1->position[2] - pv0->position[2]);
+
+				if (clip->leftedge)
+				{
+					r_leftclipped = true;
+					r_leftexit = clipvert;
+				}
+				else if (clip->rightedge)
+				{
+					r_rightclipped = true;
+					r_rightexit = clipvert;
+				}
+
+				R_ClipEdge (pv0, &clipvert, clip->next);
+				return;
+			}
+			else
+			{
+			// point 0 is clipped
+				if (d1 < 0)
+				{
+				// both points are clipped
+				// we do cache fully clipped edges
+					if (!r_leftclipped)
+						cacheoffset = FULLY_CLIPPED_CACHED |
+								(r_framecount & FRAMECOUNT_MASK);
+					return;
+				}
+
+			// only point 0 is clipped
+				r_lastvertvalid = false;
+
+			// we don't cache partially clipped edges
+				cacheoffset = 0x7FFFFFFF;
+
+				f = d0 / (d0 - d1);
+				clipvert.position[0] = pv0->position[0] +
+						f * (pv1->position[0] - pv0->position[0]);
+				clipvert.position[1] = pv0->position[1] +
+						f * (pv1->position[1] - pv0->position[1]);
+				clipvert.position[2] = pv0->position[2] +
+						f * (pv1->position[2] - pv0->position[2]);
+
+				if (clip->leftedge)
+				{
+					r_leftclipped = true;
+					r_leftenter = clipvert;
+				}
+				else if (clip->rightedge)
+				{
+					r_rightclipped = true;
+					r_rightenter = clipvert;
+				}
+
+				R_ClipEdge (&clipvert, pv1, clip->next);
+				return;
+			}
+		} while ((clip = clip->next) != NULL);
+	}
+
+// add the edge
+	R_EmitEdge (pv0, pv1);
+}
+
+#endif	// !id386
+
+
+/*
+================
+R_EmitCachedEdge
+================
+*/
+void R_EmitCachedEdge (void)
+{
+	edge_t		*pedge_t;
+
+	pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset);
+
+	if (!pedge_t->surfs[0])
+		pedge_t->surfs[0] = surface_p - surfaces;
+	else
+		pedge_t->surfs[1] = surface_p - surfaces;
+
+	if (pedge_t->nearzi > r_nearzi)	// for mipmap finding
+		r_nearzi = pedge_t->nearzi;
+
+	r_emitted = 1;
+}
+
+
+/*
+================
+R_RenderFace
+================
+*/
+void R_RenderFace (msurface_t *fa, int clipflags)
+{
+	int			i, lindex;
+	unsigned	mask;
+	mplane_t	*pplane;
+	float		distinv;
+	vec3_t		p_normal;
+	medge_t		*pedges, tedge;
+	clipplane_t	*pclip;
+
+	// translucent surfaces are not drawn by the edge renderer
+	if (fa->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
+	{
+		fa->nextalphasurface = r_alpha_surfaces;
+		r_alpha_surfaces = fa;
+		return;
+	}
+
+	// sky surfaces encountered in the world will cause the
+	// environment box surfaces to be emited
+	if ( fa->texinfo->flags & SURF_SKY )
+	{
+		R_EmitSkyBox ();	
+		return;
+	}
+
+// skip out if no more surfs
+	if ((surface_p) >= surf_max)
+	{
+		r_outofsurfaces++;
+		return;
+	}
+
+// ditto if not enough edges left, or switch to auxedges if possible
+	if ((edge_p + fa->numedges + 4) >= edge_max)
+	{
+		r_outofedges += fa->numedges;
+		return;
+	}
+
+	c_faceclip++;
+
+// set up clip planes
+	pclip = NULL;
+
+	for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
+	{
+		if (clipflags & mask)
+		{
+			view_clipplanes[i].next = pclip;
+			pclip = &view_clipplanes[i];
+		}
+	}
+
+// push the edges through
+	r_emitted = 0;
+	r_nearzi = 0;
+	r_nearzionly = false;
+	makeleftedge = makerightedge = false;
+	pedges = currentmodel->edges;
+	r_lastvertvalid = false;
+
+	for (i=0 ; i<fa->numedges ; i++)
+	{
+		lindex = currentmodel->surfedges[fa->firstedge + i];
+
+		if (lindex > 0)
+		{
+			r_pedge = &pedges[lindex];
+
+		// if the edge is cached, we can just reuse the edge
+			if (!insubmodel)
+			{
+				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
+				{
+					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
+						r_framecount)
+					{
+						r_lastvertvalid = false;
+						continue;
+					}
+				}
+				else
+				{
+					if ((((unsigned long)edge_p - (unsigned long)r_edges) >
+						 r_pedge->cachededgeoffset) &&
+						(((edge_t *)((unsigned long)r_edges +
+						 r_pedge->cachededgeoffset))->owner == r_pedge))
+					{
+						R_EmitCachedEdge ();
+						r_lastvertvalid = false;
+						continue;
+					}
+				}
+			}
+
+		// assume it's cacheable
+			cacheoffset = (byte *)edge_p - (byte *)r_edges;
+			r_leftclipped = r_rightclipped = false;
+			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
+						&r_pcurrentvertbase[r_pedge->v[1]],
+						pclip);
+			r_pedge->cachededgeoffset = cacheoffset;
+
+			if (r_leftclipped)
+				makeleftedge = true;
+			if (r_rightclipped)
+				makerightedge = true;
+			r_lastvertvalid = true;
+		}
+		else
+		{
+			lindex = -lindex;
+			r_pedge = &pedges[lindex];
+		// if the edge is cached, we can just reuse the edge
+			if (!insubmodel)
+			{
+				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
+				{
+					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
+						r_framecount)
+					{
+						r_lastvertvalid = false;
+						continue;
+					}
+				}
+				else
+				{
+				// it's cached if the cached edge is valid and is owned
+				// by this medge_t
+					if ((((unsigned long)edge_p - (unsigned long)r_edges) >
+						 r_pedge->cachededgeoffset) &&
+						(((edge_t *)((unsigned long)r_edges +
+						 r_pedge->cachededgeoffset))->owner == r_pedge))
+					{
+						R_EmitCachedEdge ();
+						r_lastvertvalid = false;
+						continue;
+					}
+				}
+			}
+
+		// assume it's cacheable
+			cacheoffset = (byte *)edge_p - (byte *)r_edges;
+			r_leftclipped = r_rightclipped = false;
+			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]],
+						&r_pcurrentvertbase[r_pedge->v[0]],
+						pclip);
+			r_pedge->cachededgeoffset = cacheoffset;
+
+			if (r_leftclipped)
+				makeleftedge = true;
+			if (r_rightclipped)
+				makerightedge = true;
+			r_lastvertvalid = true;
+		}
+	}
+
+// if there was a clip off the left edge, add that edge too
+// FIXME: faster to do in screen space?
+// FIXME: share clipped edges?
+	if (makeleftedge)
+	{
+		r_pedge = &tedge;
+		r_lastvertvalid = false;
+		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
+	}
+
+// if there was a clip off the right edge, get the right r_nearzi
+	if (makerightedge)
+	{
+		r_pedge = &tedge;
+		r_lastvertvalid = false;
+		r_nearzionly = true;
+		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
+	}
+
+// if no edges made it out, return without posting the surface
+	if (!r_emitted)
+		return;
+
+	r_polycount++;
+
+	surface_p->msurf = fa;
+	surface_p->nearzi = r_nearzi;
+	surface_p->flags = fa->flags;
+	surface_p->insubmodel = insubmodel;
+	surface_p->spanstate = 0;
+	surface_p->entity = currententity;
+	surface_p->key = r_currentkey++;
+	surface_p->spans = NULL;
+
+	pplane = fa->plane;
+// FIXME: cache this?
+	TransformVector (pplane->normal, p_normal);
+// FIXME: cache this?
+	distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
+
+	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
+	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
+	surface_p->d_ziorigin = p_normal[2] * distinv -
+			xcenter * surface_p->d_zistepu -
+			ycenter * surface_p->d_zistepv;
+
+	surface_p++;
+}
+
+
+/*
+================
+R_RenderBmodelFace
+================
+*/
+void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
+{
+	int			i;
+	unsigned	mask;
+	mplane_t	*pplane;
+	float		distinv;
+	vec3_t		p_normal;
+	medge_t		tedge;
+	clipplane_t	*pclip;
+
+	if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
+	{
+		psurf->nextalphasurface = r_alpha_surfaces;
+		r_alpha_surfaces = psurf;
+		return;
+	}
+
+// skip out if no more surfs
+	if (surface_p >= surf_max)
+	{
+		r_outofsurfaces++;
+		return;
+	}
+
+// ditto if not enough edges left, or switch to auxedges if possible
+	if ((edge_p + psurf->numedges + 4) >= edge_max)
+	{
+		r_outofedges += psurf->numedges;
+		return;
+	}
+
+	c_faceclip++;
+
+// this is a dummy to give the caching mechanism someplace to write to
+	r_pedge = &tedge;
+
+// set up clip planes
+	pclip = NULL;
+
+	for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
+	{
+		if (r_clipflags & mask)
+		{
+			view_clipplanes[i].next = pclip;
+			pclip = &view_clipplanes[i];
+		}
+	}
+
+// push the edges through
+	r_emitted = 0;
+	r_nearzi = 0;
+	r_nearzionly = false;
+	makeleftedge = makerightedge = false;
+// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching
+// can be used?
+	r_lastvertvalid = false;
+
+	for ( ; pedges ; pedges = pedges->pnext)
+	{
+		r_leftclipped = r_rightclipped = false;
+		R_ClipEdge (pedges->v[0], pedges->v[1], pclip);
+
+		if (r_leftclipped)
+			makeleftedge = true;
+		if (r_rightclipped)
+			makerightedge = true;
+	}
+
+// if there was a clip off the left edge, add that edge too
+// FIXME: faster to do in screen space?
+// FIXME: share clipped edges?
+	if (makeleftedge)
+	{
+		r_pedge = &tedge;
+		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
+	}
+
+// if there was a clip off the right edge, get the right r_nearzi
+	if (makerightedge)
+	{
+		r_pedge = &tedge;
+		r_nearzionly = true;
+		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
+	}
+
+// if no edges made it out, return without posting the surface
+	if (!r_emitted)
+		return;
+
+	r_polycount++;
+
+	surface_p->msurf = psurf;
+	surface_p->nearzi = r_nearzi;
+	surface_p->flags = psurf->flags;
+	surface_p->insubmodel = true;
+	surface_p->spanstate = 0;
+	surface_p->entity = currententity;
+	surface_p->key = r_currentbkey;
+	surface_p->spans = NULL;
+
+	pplane = psurf->plane;
+// FIXME: cache this?
+	TransformVector (pplane->normal, p_normal);
+// FIXME: cache this?
+	distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
+
+	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
+	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
+	surface_p->d_ziorigin = p_normal[2] * distinv -
+			xcenter * surface_p->d_zistepu -
+			ycenter * surface_p->d_zistepv;
+
+	surface_p++;
+}
+
--- /dev/null
+++ b/ref/r_scan.c
@@ -1,0 +1,591 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// d_scan.c
+//
+// Portable C scan-level rasterization code, all pixel depths.
+
+#include "r_local.h"
+
+unsigned char	*r_turb_pbase, *r_turb_pdest;
+fixed16_t		r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
+int				*r_turb_turb;
+int				r_turb_spancount;
+
+void D_DrawTurbulent8Span (void);
+
+
+/*
+=============
+D_WarpScreen
+
+this performs a slight compression of the screen at the same time as
+the sine warp, to keep the edges from wrapping
+=============
+*/
+void D_WarpScreen (void)
+{
+	int		w, h;
+	int		u,v, u2, v2;
+	byte	*dest;
+	int		*turb;
+	int		*col;
+	byte	**row;
+
+	static int	cached_width, cached_height;
+	static byte	*rowptr[1200+AMP2*2];
+	static int	column[1600+AMP2*2];
+
+	//
+	// these are constant over resolutions, and can be saved
+	//
+	w = r_newrefdef.width;
+	h = r_newrefdef.height;
+	if (w != cached_width || h != cached_height)
+	{
+		cached_width = w;
+		cached_height = h;
+		for (v=0 ; v<h+AMP2*2 ; v++)
+		{
+			v2 = (int)((float)v/(h + AMP2 * 2) * r_refdef.vrect.height);
+			rowptr[v] = r_warpbuffer + (WARP_WIDTH * v2);
+		}
+
+		for (u=0 ; u<w+AMP2*2 ; u++)
+		{
+			u2 = (int)((float)u/(w + AMP2 * 2) * r_refdef.vrect.width);
+			column[u] = u2;
+		}
+	}
+
+	turb = intsintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
+	dest = vid.buffer + r_newrefdef.y * vid.rowbytes + r_newrefdef.x;
+
+	for (v=0 ; v<h ; v++, dest += vid.rowbytes)
+	{
+		col = &column[turb[v]];
+		row = &rowptr[v];
+		for (u=0 ; u<w ; u+=4)
+		{
+			dest[u+0] = row[turb[u+0]][col[u+0]];
+			dest[u+1] = row[turb[u+1]][col[u+1]];
+			dest[u+2] = row[turb[u+2]][col[u+2]];
+			dest[u+3] = row[turb[u+3]][col[u+3]];
+		}
+	}
+}
+
+
+#if	!id386
+
+/*
+=============
+D_DrawTurbulent8Span
+=============
+*/
+void D_DrawTurbulent8Span (void)
+{
+	int		sturb, tturb;
+
+	do
+	{
+		sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
+		tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
+		*r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
+		r_turb_s += r_turb_sstep;
+		r_turb_t += r_turb_tstep;
+	} while (--r_turb_spancount > 0);
+}
+
+#endif	// !id386
+
+
+/*
+=============
+Turbulent8
+=============
+*/
+void Turbulent8 (espan_t *pspan)
+{
+	int				count;
+	fixed16_t		snext, tnext;
+	float			sdivz, tdivz, zi, z, du, dv, spancountminus1;
+	float			sdivz16stepu, tdivz16stepu, zi16stepu;
+	
+	r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
+
+	r_turb_sstep = 0;	// keep compiler happy
+	r_turb_tstep = 0;	// ditto
+
+	r_turb_pbase = (unsigned char *)cacheblock;
+
+	sdivz16stepu = d_sdivzstepu * 16;
+	tdivz16stepu = d_tdivzstepu * 16;
+	zi16stepu = d_zistepu * 16;
+
+	do
+	{
+		r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
+				(r_screenwidth * pspan->v) + pspan->u);
+
+		count = pspan->count;
+
+	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
+		du = (float)pspan->u;
+		dv = (float)pspan->v;
+
+		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
+		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
+		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
+		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+
+		r_turb_s = (int)(sdivz * z) + sadjust;
+		if (r_turb_s > bbextents)
+			r_turb_s = bbextents;
+		else if (r_turb_s < 0)
+			r_turb_s = 0;
+
+		r_turb_t = (int)(tdivz * z) + tadjust;
+		if (r_turb_t > bbextentt)
+			r_turb_t = bbextentt;
+		else if (r_turb_t < 0)
+			r_turb_t = 0;
+
+		do
+		{
+		// calculate s and t at the far end of the span
+			if (count >= 16)
+				r_turb_spancount = 16;
+			else
+				r_turb_spancount = count;
+
+			count -= r_turb_spancount;
+
+			if (count)
+			{
+			// calculate s/z, t/z, zi->fixed s and t at far end of span,
+			// calculate s and t steps across span by shifting
+				sdivz += sdivz16stepu;
+				tdivz += tdivz16stepu;
+				zi += zi16stepu;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+
+				snext = (int)(sdivz * z) + sadjust;
+				if (snext > bbextents)
+					snext = bbextents;
+				else if (snext < 16)
+					snext = 16;	// prevent round-off error on <0 steps from
+								//  from causing overstepping & running off the
+								//  edge of the texture
+
+				tnext = (int)(tdivz * z) + tadjust;
+				if (tnext > bbextentt)
+					tnext = bbextentt;
+				else if (tnext < 16)
+					tnext = 16;	// guard against round-off error on <0 steps
+
+				r_turb_sstep = (snext - r_turb_s) >> 4;
+				r_turb_tstep = (tnext - r_turb_t) >> 4;
+			}
+			else
+			{
+			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
+			// can't step off polygon), clamp, calculate s and t steps across
+			// span by division, biasing steps low so we don't run off the
+			// texture
+				spancountminus1 = (float)(r_turb_spancount - 1);
+				sdivz += d_sdivzstepu * spancountminus1;
+				tdivz += d_tdivzstepu * spancountminus1;
+				zi += d_zistepu * spancountminus1;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+				snext = (int)(sdivz * z) + sadjust;
+				if (snext > bbextents)
+					snext = bbextents;
+				else if (snext < 16)
+					snext = 16;	// prevent round-off error on <0 steps from
+								//  from causing overstepping & running off the
+								//  edge of the texture
+
+				tnext = (int)(tdivz * z) + tadjust;
+				if (tnext > bbextentt)
+					tnext = bbextentt;
+				else if (tnext < 16)
+					tnext = 16;	// guard against round-off error on <0 steps
+
+				if (r_turb_spancount > 1)
+				{
+					r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
+					r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
+				}
+			}
+
+			r_turb_s = r_turb_s & ((CYCLE<<16)-1);
+			r_turb_t = r_turb_t & ((CYCLE<<16)-1);
+
+			D_DrawTurbulent8Span ();
+
+			r_turb_s = snext;
+			r_turb_t = tnext;
+
+		} while (count > 0);
+
+	} while ((pspan = pspan->pnext) != NULL);
+}
+
+//====================
+//PGM
+/*
+=============
+NonTurbulent8 - this is for drawing scrolling textures. they're warping water textures
+	but the turbulence is automatically 0.
+=============
+*/
+void NonTurbulent8 (espan_t *pspan)
+{
+	int				count;
+	fixed16_t		snext, tnext;
+	float			sdivz, tdivz, zi, z, du, dv, spancountminus1;
+	float			sdivz16stepu, tdivz16stepu, zi16stepu;
+	
+//	r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
+	r_turb_turb = blanktable;
+
+	r_turb_sstep = 0;	// keep compiler happy
+	r_turb_tstep = 0;	// ditto
+
+	r_turb_pbase = (unsigned char *)cacheblock;
+
+	sdivz16stepu = d_sdivzstepu * 16;
+	tdivz16stepu = d_tdivzstepu * 16;
+	zi16stepu = d_zistepu * 16;
+
+	do
+	{
+		r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
+				(r_screenwidth * pspan->v) + pspan->u);
+
+		count = pspan->count;
+
+	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
+		du = (float)pspan->u;
+		dv = (float)pspan->v;
+
+		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
+		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
+		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
+		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+
+		r_turb_s = (int)(sdivz * z) + sadjust;
+		if (r_turb_s > bbextents)
+			r_turb_s = bbextents;
+		else if (r_turb_s < 0)
+			r_turb_s = 0;
+
+		r_turb_t = (int)(tdivz * z) + tadjust;
+		if (r_turb_t > bbextentt)
+			r_turb_t = bbextentt;
+		else if (r_turb_t < 0)
+			r_turb_t = 0;
+
+		do
+		{
+		// calculate s and t at the far end of the span
+			if (count >= 16)
+				r_turb_spancount = 16;
+			else
+				r_turb_spancount = count;
+
+			count -= r_turb_spancount;
+
+			if (count)
+			{
+			// calculate s/z, t/z, zi->fixed s and t at far end of span,
+			// calculate s and t steps across span by shifting
+				sdivz += sdivz16stepu;
+				tdivz += tdivz16stepu;
+				zi += zi16stepu;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+
+				snext = (int)(sdivz * z) + sadjust;
+				if (snext > bbextents)
+					snext = bbextents;
+				else if (snext < 16)
+					snext = 16;	// prevent round-off error on <0 steps from
+								//  from causing overstepping & running off the
+								//  edge of the texture
+
+				tnext = (int)(tdivz * z) + tadjust;
+				if (tnext > bbextentt)
+					tnext = bbextentt;
+				else if (tnext < 16)
+					tnext = 16;	// guard against round-off error on <0 steps
+
+				r_turb_sstep = (snext - r_turb_s) >> 4;
+				r_turb_tstep = (tnext - r_turb_t) >> 4;
+			}
+			else
+			{
+			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
+			// can't step off polygon), clamp, calculate s and t steps across
+			// span by division, biasing steps low so we don't run off the
+			// texture
+				spancountminus1 = (float)(r_turb_spancount - 1);
+				sdivz += d_sdivzstepu * spancountminus1;
+				tdivz += d_tdivzstepu * spancountminus1;
+				zi += d_zistepu * spancountminus1;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+				snext = (int)(sdivz * z) + sadjust;
+				if (snext > bbextents)
+					snext = bbextents;
+				else if (snext < 16)
+					snext = 16;	// prevent round-off error on <0 steps from
+								//  from causing overstepping & running off the
+								//  edge of the texture
+
+				tnext = (int)(tdivz * z) + tadjust;
+				if (tnext > bbextentt)
+					tnext = bbextentt;
+				else if (tnext < 16)
+					tnext = 16;	// guard against round-off error on <0 steps
+
+				if (r_turb_spancount > 1)
+				{
+					r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
+					r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
+				}
+			}
+
+			r_turb_s = r_turb_s & ((CYCLE<<16)-1);
+			r_turb_t = r_turb_t & ((CYCLE<<16)-1);
+
+			D_DrawTurbulent8Span ();
+
+			r_turb_s = snext;
+			r_turb_t = tnext;
+
+		} while (count > 0);
+
+	} while ((pspan = pspan->pnext) != NULL);
+}
+//PGM
+//====================
+
+
+#if	!id386
+
+/*
+=============
+D_DrawSpans16
+
+  FIXME: actually make this subdivide by 16 instead of 8!!!
+=============
+*/
+void D_DrawSpans16 (espan_t *pspan)
+{
+	int				count, spancount;
+	unsigned char	*pbase, *pdest;
+	fixed16_t		s, t, snext, tnext, sstep, tstep;
+	float			sdivz, tdivz, zi, z, du, dv, spancountminus1;
+	float			sdivz8stepu, tdivz8stepu, zi8stepu;
+
+	sstep = 0;	// keep compiler happy
+	tstep = 0;	// ditto
+
+	pbase = (unsigned char *)cacheblock;
+
+	sdivz8stepu = d_sdivzstepu * 8;
+	tdivz8stepu = d_tdivzstepu * 8;
+	zi8stepu = d_zistepu * 8;
+
+	do
+	{
+		pdest = (unsigned char *)((byte *)d_viewbuffer +
+				(r_screenwidth * pspan->v) + pspan->u);
+
+		count = pspan->count;
+
+	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
+		du = (float)pspan->u;
+		dv = (float)pspan->v;
+
+		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
+		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
+		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
+		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+
+		s = (int)(sdivz * z) + sadjust;
+		if (s > bbextents)
+			s = bbextents;
+		else if (s < 0)
+			s = 0;
+
+		t = (int)(tdivz * z) + tadjust;
+		if (t > bbextentt)
+			t = bbextentt;
+		else if (t < 0)
+			t = 0;
+
+		do
+		{
+		// calculate s and t at the far end of the span
+			if (count >= 8)
+				spancount = 8;
+			else
+				spancount = count;
+
+			count -= spancount;
+
+			if (count)
+			{
+			// calculate s/z, t/z, zi->fixed s and t at far end of span,
+			// calculate s and t steps across span by shifting
+				sdivz += sdivz8stepu;
+				tdivz += tdivz8stepu;
+				zi += zi8stepu;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+
+				snext = (int)(sdivz * z) + sadjust;
+				if (snext > bbextents)
+					snext = bbextents;
+				else if (snext < 8)
+					snext = 8;	// prevent round-off error on <0 steps from
+								//  from causing overstepping & running off the
+								//  edge of the texture
+
+				tnext = (int)(tdivz * z) + tadjust;
+				if (tnext > bbextentt)
+					tnext = bbextentt;
+				else if (tnext < 8)
+					tnext = 8;	// guard against round-off error on <0 steps
+
+				sstep = (snext - s) >> 3;
+				tstep = (tnext - t) >> 3;
+			}
+			else
+			{
+			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
+			// can't step off polygon), clamp, calculate s and t steps across
+			// span by division, biasing steps low so we don't run off the
+			// texture
+				spancountminus1 = (float)(spancount - 1);
+				sdivz += d_sdivzstepu * spancountminus1;
+				tdivz += d_tdivzstepu * spancountminus1;
+				zi += d_zistepu * spancountminus1;
+				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
+				snext = (int)(sdivz * z) + sadjust;
+				if (snext > bbextents)
+					snext = bbextents;
+				else if (snext < 8)
+					snext = 8;	// prevent round-off error on <0 steps from
+								//  from causing overstepping & running off the
+								//  edge of the texture
+
+				tnext = (int)(tdivz * z) + tadjust;
+				if (tnext > bbextentt)
+					tnext = bbextentt;
+				else if (tnext < 8)
+					tnext = 8;	// guard against round-off error on <0 steps
+
+				if (spancount > 1)
+				{
+					sstep = (snext - s) / (spancount - 1);
+					tstep = (tnext - t) / (spancount - 1);
+				}
+			}
+
+			do
+			{
+				*pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
+				s += sstep;
+				t += tstep;
+			} while (--spancount > 0);
+
+			s = snext;
+			t = tnext;
+
+		} while (count > 0);
+
+	} while ((pspan = pspan->pnext) != NULL);
+}
+
+#endif
+
+
+#if	!id386
+
+/*
+=============
+D_DrawZSpans
+=============
+*/
+void D_DrawZSpans (espan_t *pspan)
+{
+	int				count, doublecount, izistep;
+	int				izi;
+	short			*pdest;
+	unsigned		ltemp;
+	float			zi;
+	float			du, dv;
+
+// FIXME: check for clamping/range problems
+// we count on FP exceptions being turned off to avoid range problems
+	izistep = (int)(d_zistepu * 0x8000 * 0x10000);
+
+	do
+	{
+		pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
+
+		count = pspan->count;
+
+	// calculate the initial 1/z
+		du = (float)pspan->u;
+		dv = (float)pspan->v;
+
+		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
+	// we count on FP exceptions being turned off to avoid range problems
+		izi = (int)(zi * 0x8000 * 0x10000);
+
+		if ((long)pdest & 0x02)
+		{
+			*pdest++ = (short)(izi >> 16);
+			izi += izistep;
+			count--;
+		}
+
+		if ((doublecount = count >> 1) > 0)
+		{
+			do
+			{
+				ltemp = izi >> 16;
+				izi += izistep;
+				ltemp |= izi & 0xFFFF0000;
+				izi += izistep;
+				*(int *)pdest = ltemp;
+				pdest += 2;
+			} while (--doublecount > 0);
+		}
+
+		if (count & 1)
+			*pdest = (short)(izi >> 16);
+
+	} while ((pspan = pspan->pnext) != NULL);
+}
+
+#endif
+
--- /dev/null
+++ b/ref/r_sprite.c
@@ -1,0 +1,123 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_sprite.c
+#include "r_local.h"
+
+extern polydesc_t r_polydesc;
+
+void R_BuildPolygonFromSurface(msurface_t *fa);
+void R_PolygonCalculateGradients (void);
+
+extern void R_PolyChooseSpanletRoutine( float alpha, qboolean isturbulent );
+
+extern vec5_t r_clip_verts[2][MAXWORKINGVERTS+2];
+
+extern void	R_ClipAndDrawPoly( float alpha, qboolean isturbulent, qboolean textured );
+
+/*
+** R_DrawSprite
+**
+** Draw currententity / currentmodel as a single texture
+** mapped polygon
+*/
+void R_DrawSprite (void)
+{
+	vec5_t		*pverts;
+	vec3_t		left, up, right, down;
+	dsprite_t	*s_psprite;
+	dsprframe_t	*s_psprframe;
+
+
+	s_psprite = (dsprite_t *)currentmodel->extradata;
+#if 0
+	if (currententity->frame >= s_psprite->numframes
+		|| currententity->frame < 0)
+	{
+		ri.Con_Printf (PRINT_ALL, "No such sprite frame %i\n", 
+			currententity->frame);
+		currententity->frame = 0;
+	}
+#endif
+	currententity->frame %= s_psprite->numframes;
+
+	s_psprframe = &s_psprite->frames[currententity->frame];
+
+	r_polydesc.pixels       = currentmodel->skins[currententity->frame]->pixels[0];
+	r_polydesc.pixel_width  = s_psprframe->width;
+	r_polydesc.pixel_height = s_psprframe->height;
+	r_polydesc.dist         = 0;
+
+	// generate the sprite's axes, completely parallel to the viewplane.
+	VectorCopy (vup, r_polydesc.vup);
+	VectorCopy (vright, r_polydesc.vright);
+	VectorCopy (vpn, r_polydesc.vpn);
+
+// build the sprite poster in worldspace
+	VectorScale (r_polydesc.vright, 
+		s_psprframe->width - s_psprframe->origin_x, right);
+	VectorScale (r_polydesc.vup, 
+		s_psprframe->height - s_psprframe->origin_y, up);
+	VectorScale (r_polydesc.vright,
+		-s_psprframe->origin_x, left);
+	VectorScale (r_polydesc.vup,
+		-s_psprframe->origin_y, down);
+
+	// invert UP vector for sprites
+	VectorInverse( r_polydesc.vup );
+
+	pverts = r_clip_verts[0];
+
+	pverts[0][0] = r_entorigin[0] + up[0] + left[0];
+	pverts[0][1] = r_entorigin[1] + up[1] + left[1];
+	pverts[0][2] = r_entorigin[2] + up[2] + left[2];
+	pverts[0][3] = 0;
+	pverts[0][4] = 0;
+
+	pverts[1][0] = r_entorigin[0] + up[0] + right[0];
+	pverts[1][1] = r_entorigin[1] + up[1] + right[1];
+	pverts[1][2] = r_entorigin[2] + up[2] + right[2];
+	pverts[1][3] = s_psprframe->width;
+	pverts[1][4] = 0;
+
+	pverts[2][0] = r_entorigin[0] + down[0] + right[0];
+	pverts[2][1] = r_entorigin[1] + down[1] + right[1];
+	pverts[2][2] = r_entorigin[2] + down[2] + right[2];
+	pverts[2][3] = s_psprframe->width;
+	pverts[2][4] = s_psprframe->height;
+
+	pverts[3][0] = r_entorigin[0] + down[0] + left[0];
+	pverts[3][1] = r_entorigin[1] + down[1] + left[1];
+	pverts[3][2] = r_entorigin[2] + down[2] + left[2];
+	pverts[3][3] = 0;
+	pverts[3][4] = s_psprframe->height;
+
+	r_polydesc.nump = 4;
+	r_polydesc.s_offset = ( r_polydesc.pixel_width  >> 1);
+	r_polydesc.t_offset = ( r_polydesc.pixel_height >> 1);
+	VectorCopy( modelorg, r_polydesc.viewer_position );
+
+	r_polydesc.stipple_parity = 1;
+	if ( currententity->flags & RF_TRANSLUCENT )
+		R_ClipAndDrawPoly ( currententity->alpha, false, true );
+	else
+		R_ClipAndDrawPoly ( 1.0F, false, true );
+	r_polydesc.stipple_parity = 0;
+}
+
--- /dev/null
+++ b/ref/r_surf.c
@@ -1,0 +1,651 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// r_surf.c: surface-related refresh code
+
+#include "r_local.h"
+
+drawsurf_t	r_drawsurf;
+
+int				lightleft, sourcesstep, blocksize, sourcetstep;
+int				lightdelta, lightdeltastep;
+int				lightright, lightleftstep, lightrightstep, blockdivshift;
+unsigned		blockdivmask;
+void			*prowdestbase;
+unsigned char	*pbasesource;
+int				surfrowbytes;	// used by ASM files
+unsigned		*r_lightptr;
+int				r_stepback;
+int				r_lightwidth;
+int				r_numhblocks, r_numvblocks;
+unsigned char	*r_source, *r_sourcemax;
+
+void R_DrawSurfaceBlock8_mip0 (void);
+void R_DrawSurfaceBlock8_mip1 (void);
+void R_DrawSurfaceBlock8_mip2 (void);
+void R_DrawSurfaceBlock8_mip3 (void);
+
+static void	(*surfmiptable[4])(void) = {
+	R_DrawSurfaceBlock8_mip0,
+	R_DrawSurfaceBlock8_mip1,
+	R_DrawSurfaceBlock8_mip2,
+	R_DrawSurfaceBlock8_mip3
+};
+
+void R_BuildLightMap (void);
+extern	unsigned		blocklights[1024];	// allow some very large lightmaps
+
+float           surfscale;
+qboolean        r_cache_thrash;         // set if surface cache is thrashing
+
+int         sc_size;
+surfcache_t	*sc_rover, *sc_base;
+
+/*
+===============
+R_TextureAnimation
+
+Returns the proper texture for a given time and base texture
+===============
+*/
+image_t *R_TextureAnimation (mtexinfo_t *tex)
+{
+	int		c;
+
+	if (!tex->next)
+		return tex->image;
+
+	c = currententity->frame % tex->numframes;
+	while (c)
+	{
+		tex = tex->next;
+		c--;
+	}
+
+	return tex->image;
+}
+
+
+/*
+===============
+R_DrawSurface
+===============
+*/
+void R_DrawSurface (void)
+{
+	unsigned char	*basetptr;
+	int				smax, tmax, twidth;
+	int				u;
+	int				soffset, basetoffset, texwidth;
+	int				horzblockstep;
+	unsigned char	*pcolumndest;
+	void			(*pblockdrawer)(void);
+	image_t			*mt;
+
+	surfrowbytes = r_drawsurf.rowbytes;
+
+	mt = r_drawsurf.image;
+	
+	r_source = mt->pixels[r_drawsurf.surfmip];
+	
+// the fractional light values should range from 0 to (VID_GRADES - 1) << 16
+// from a source range of 0 - 255
+	
+	texwidth = mt->width >> r_drawsurf.surfmip;
+
+	blocksize = 16 >> r_drawsurf.surfmip;
+	blockdivshift = 4 - r_drawsurf.surfmip;
+	blockdivmask = (1 << blockdivshift) - 1;
+	
+	r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
+
+	r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
+	r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
+
+//==============================
+
+	pblockdrawer = surfmiptable[r_drawsurf.surfmip];
+// TODO: only needs to be set when there is a display settings change
+	horzblockstep = blocksize;
+
+	smax = mt->width >> r_drawsurf.surfmip;
+	twidth = texwidth;
+	tmax = mt->height >> r_drawsurf.surfmip;
+	sourcetstep = texwidth;
+	r_stepback = tmax * twidth;
+
+	r_sourcemax = r_source + (tmax * smax);
+
+	soffset = r_drawsurf.surf->texturemins[0];
+	basetoffset = r_drawsurf.surf->texturemins[1];
+
+// << 16 components are to guarantee positive values for %
+	soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
+	basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) 
+		+ (tmax << 16)) % tmax) * twidth)];
+
+	pcolumndest = r_drawsurf.surfdat;
+
+	for (u=0 ; u<r_numhblocks; u++)
+	{
+		r_lightptr = blocklights + u;
+
+		prowdestbase = pcolumndest;
+
+		pbasesource = basetptr + soffset;
+
+		(*pblockdrawer)();
+
+		soffset = soffset + blocksize;
+		if (soffset >= smax)
+			soffset = 0;
+
+		pcolumndest += horzblockstep;
+	}
+}
+
+
+//=============================================================================
+
+#if	!id386
+
+/*
+================
+R_DrawSurfaceBlock8_mip0
+================
+*/
+void R_DrawSurfaceBlock8_mip0 (void)
+{
+	int				v, i, b, lightstep, lighttemp, light;
+	unsigned char	pix, *psource, *prowdest;
+
+	psource = pbasesource;
+	prowdest = prowdestbase;
+
+	for (v=0 ; v<r_numvblocks ; v++)
+	{
+	// FIXME: make these locals?
+	// FIXME: use delta rather than both right and left, like ASM?
+		lightleft = r_lightptr[0];
+		lightright = r_lightptr[1];
+		r_lightptr += r_lightwidth;
+		lightleftstep = (r_lightptr[0] - lightleft) >> 4;
+		lightrightstep = (r_lightptr[1] - lightright) >> 4;
+
+		for (i=0 ; i<16 ; i++)
+		{
+			lighttemp = lightleft - lightright;
+			lightstep = lighttemp >> 4;
+
+			light = lightright;
+
+			for (b=15; b>=0; b--)
+			{
+				pix = psource[b];
+				prowdest[b] = ((unsigned char *)vid.colormap)
+						[(light & 0xFF00) + pix];
+				light += lightstep;
+			}
+	
+			psource += sourcetstep;
+			lightright += lightrightstep;
+			lightleft += lightleftstep;
+			prowdest += surfrowbytes;
+		}
+
+		if (psource >= r_sourcemax)
+			psource -= r_stepback;
+	}
+}
+
+
+/*
+================
+R_DrawSurfaceBlock8_mip1
+================
+*/
+void R_DrawSurfaceBlock8_mip1 (void)
+{
+	int				v, i, b, lightstep, lighttemp, light;
+	unsigned char	pix, *psource, *prowdest;
+
+	psource = pbasesource;
+	prowdest = prowdestbase;
+
+	for (v=0 ; v<r_numvblocks ; v++)
+	{
+	// FIXME: make these locals?
+	// FIXME: use delta rather than both right and left, like ASM?
+		lightleft = r_lightptr[0];
+		lightright = r_lightptr[1];
+		r_lightptr += r_lightwidth;
+		lightleftstep = (r_lightptr[0] - lightleft) >> 3;
+		lightrightstep = (r_lightptr[1] - lightright) >> 3;
+
+		for (i=0 ; i<8 ; i++)
+		{
+			lighttemp = lightleft - lightright;
+			lightstep = lighttemp >> 3;
+
+			light = lightright;
+
+			for (b=7; b>=0; b--)
+			{
+				pix = psource[b];
+				prowdest[b] = ((unsigned char *)vid.colormap)
+						[(light & 0xFF00) + pix];
+				light += lightstep;
+			}
+	
+			psource += sourcetstep;
+			lightright += lightrightstep;
+			lightleft += lightleftstep;
+			prowdest += surfrowbytes;
+		}
+
+		if (psource >= r_sourcemax)
+			psource -= r_stepback;
+	}
+}
+
+
+/*
+================
+R_DrawSurfaceBlock8_mip2
+================
+*/
+void R_DrawSurfaceBlock8_mip2 (void)
+{
+	int				v, i, b, lightstep, lighttemp, light;
+	unsigned char	pix, *psource, *prowdest;
+
+	psource = pbasesource;
+	prowdest = prowdestbase;
+
+	for (v=0 ; v<r_numvblocks ; v++)
+	{
+	// FIXME: make these locals?
+	// FIXME: use delta rather than both right and left, like ASM?
+		lightleft = r_lightptr[0];
+		lightright = r_lightptr[1];
+		r_lightptr += r_lightwidth;
+		lightleftstep = (r_lightptr[0] - lightleft) >> 2;
+		lightrightstep = (r_lightptr[1] - lightright) >> 2;
+
+		for (i=0 ; i<4 ; i++)
+		{
+			lighttemp = lightleft - lightright;
+			lightstep = lighttemp >> 2;
+
+			light = lightright;
+
+			for (b=3; b>=0; b--)
+			{
+				pix = psource[b];
+				prowdest[b] = ((unsigned char *)vid.colormap)
+						[(light & 0xFF00) + pix];
+				light += lightstep;
+			}
+	
+			psource += sourcetstep;
+			lightright += lightrightstep;
+			lightleft += lightleftstep;
+			prowdest += surfrowbytes;
+		}
+
+		if (psource >= r_sourcemax)
+			psource -= r_stepback;
+	}
+}
+
+
+/*
+================
+R_DrawSurfaceBlock8_mip3
+================
+*/
+void R_DrawSurfaceBlock8_mip3 (void)
+{
+	int				v, i, b, lightstep, lighttemp, light;
+	unsigned char	pix, *psource, *prowdest;
+
+	psource = pbasesource;
+	prowdest = prowdestbase;
+
+	for (v=0 ; v<r_numvblocks ; v++)
+	{
+	// FIXME: make these locals?
+	// FIXME: use delta rather than both right and left, like ASM?
+		lightleft = r_lightptr[0];
+		lightright = r_lightptr[1];
+		r_lightptr += r_lightwidth;
+		lightleftstep = (r_lightptr[0] - lightleft) >> 1;
+		lightrightstep = (r_lightptr[1] - lightright) >> 1;
+
+		for (i=0 ; i<2 ; i++)
+		{
+			lighttemp = lightleft - lightright;
+			lightstep = lighttemp >> 1;
+
+			light = lightright;
+
+			for (b=1; b>=0; b--)
+			{
+				pix = psource[b];
+				prowdest[b] = ((unsigned char *)vid.colormap)
+						[(light & 0xFF00) + pix];
+				light += lightstep;
+			}
+	
+			psource += sourcetstep;
+			lightright += lightrightstep;
+			lightleft += lightleftstep;
+			prowdest += surfrowbytes;
+		}
+
+		if (psource >= r_sourcemax)
+			psource -= r_stepback;
+	}
+}
+
+#endif
+
+
+//============================================================================
+
+
+/*
+================
+R_InitCaches
+
+================
+*/
+void R_InitCaches (void)
+{
+	int		size;
+	int		pix;
+
+	// calculate size to allocate
+	if (sw_surfcacheoverride->value)
+	{
+		size = sw_surfcacheoverride->value;
+	}
+	else
+	{
+		size = SURFCACHE_SIZE_AT_320X240;
+
+		pix = vid.width*vid.height;
+		if (pix > 64000)
+			size += (pix-64000)*3;
+	}		
+
+	// round up to page size
+	size = (size + 8191) & ~8191;
+
+	ri.Con_Printf (PRINT_ALL,"%ik surface cache\n", size/1024);
+
+	sc_size = size;
+	sc_base = (surfcache_t *)malloc(size);
+	sc_rover = sc_base;
+	
+	sc_base->next = NULL;
+	sc_base->owner = NULL;
+	sc_base->size = sc_size;
+}
+
+
+/*
+==================
+D_FlushCaches
+==================
+*/
+void D_FlushCaches (void)
+{
+	surfcache_t     *c;
+	
+	if (!sc_base)
+		return;
+
+	for (c = sc_base ; c ; c = c->next)
+	{
+		if (c->owner)
+			*c->owner = NULL;
+	}
+	
+	sc_rover = sc_base;
+	sc_base->next = NULL;
+	sc_base->owner = NULL;
+	sc_base->size = sc_size;
+}
+
+/*
+=================
+D_SCAlloc
+=================
+*/
+surfcache_t     *D_SCAlloc (int width, int size)
+{
+	surfcache_t             *new;
+	qboolean                wrapped_this_time;
+
+	if ((width < 0) || (width > 256))
+		ri.Sys_Error (ERR_FATAL,"D_SCAlloc: bad cache width %d\n", width);
+
+	if ((size <= 0) || (size > 0x10000))
+		ri.Sys_Error (ERR_FATAL,"D_SCAlloc: bad cache size %d\n", size);
+	
+	size = (int)&((surfcache_t *)0)->data[size];
+	size = (size + 3) & ~3;
+	if (size > sc_size)
+		ri.Sys_Error (ERR_FATAL,"D_SCAlloc: %i > cache size of %i",size, sc_size);
+
+// if there is not size bytes after the rover, reset to the start
+	wrapped_this_time = false;
+
+	if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size)
+	{
+		if (sc_rover)
+		{
+			wrapped_this_time = true;
+		}
+		sc_rover = sc_base;
+	}
+		
+// colect and free surfcache_t blocks until the rover block is large enough
+	new = sc_rover;
+	if (sc_rover->owner)
+		*sc_rover->owner = NULL;
+	
+	while (new->size < size)
+	{
+	// free another
+		sc_rover = sc_rover->next;
+		if (!sc_rover)
+			ri.Sys_Error (ERR_FATAL,"D_SCAlloc: hit the end of memory");
+		if (sc_rover->owner)
+			*sc_rover->owner = NULL;
+			
+		new->size += sc_rover->size;
+		new->next = sc_rover->next;
+	}
+
+// create a fragment out of any leftovers
+	if (new->size - size > 256)
+	{
+		sc_rover = (surfcache_t *)( (byte *)new + size);
+		sc_rover->size = new->size - size;
+		sc_rover->next = new->next;
+		sc_rover->width = 0;
+		sc_rover->owner = NULL;
+		new->next = sc_rover;
+		new->size = size;
+	}
+	else
+		sc_rover = new->next;
+	
+	new->width = width;
+// DEBUG
+	if (width > 0)
+		new->height = (size - sizeof(*new) + sizeof(new->data)) / width;
+
+	new->owner = NULL;              // should be set properly after return
+
+	if (d_roverwrapped)
+	{
+		if (wrapped_this_time || (sc_rover >= d_initial_rover))
+			r_cache_thrash = true;
+	}
+	else if (wrapped_this_time)
+	{       
+		d_roverwrapped = true;
+	}
+
+	return new;
+}
+
+
+/*
+=================
+D_SCDump
+=================
+*/
+void D_SCDump (void)
+{
+	surfcache_t             *test;
+
+	for (test = sc_base ; test ; test = test->next)
+	{
+		if (test == sc_rover)
+			ri.Con_Printf (PRINT_ALL,"ROVER:\n");
+		ri.Con_Printf (PRINT_ALL,"%p : %i bytes     %i width\n",test, test->size, test->width);
+	}
+}
+
+//=============================================================================
+
+// if the num is not a power of 2, assume it will not repeat
+
+int     MaskForNum (int num)
+{
+	if (num==128)
+		return 127;
+	if (num==64)
+		return 63;
+	if (num==32)
+		return 31;
+	if (num==16)
+		return 15;
+	return 255;
+}
+
+int D_log2 (int num)
+{
+	int     c;
+	
+	c = 0;
+	
+	while (num>>=1)
+		c++;
+	return c;
+}
+
+//=============================================================================
+
+/*
+================
+D_CacheSurface
+================
+*/
+surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel)
+{
+	surfcache_t     *cache;
+
+//
+// if the surface is animating or flashing, flush the cache
+//
+	r_drawsurf.image = R_TextureAnimation (surface->texinfo);
+	r_drawsurf.lightadj[0] = r_newrefdef.lightstyles[surface->styles[0]].white*128;
+	r_drawsurf.lightadj[1] = r_newrefdef.lightstyles[surface->styles[1]].white*128;
+	r_drawsurf.lightadj[2] = r_newrefdef.lightstyles[surface->styles[2]].white*128;
+	r_drawsurf.lightadj[3] = r_newrefdef.lightstyles[surface->styles[3]].white*128;
+	
+//
+// see if the cache holds apropriate data
+//
+	cache = surface->cachespots[miplevel];
+
+	if (cache && !cache->dlight && surface->dlightframe != r_framecount
+			&& cache->image == r_drawsurf.image
+			&& cache->lightadj[0] == r_drawsurf.lightadj[0]
+			&& cache->lightadj[1] == r_drawsurf.lightadj[1]
+			&& cache->lightadj[2] == r_drawsurf.lightadj[2]
+			&& cache->lightadj[3] == r_drawsurf.lightadj[3] )
+		return cache;
+
+//
+// determine shape of surface
+//
+	surfscale = 1.0 / (1<<miplevel);
+	r_drawsurf.surfmip = miplevel;
+	r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
+	r_drawsurf.rowbytes = r_drawsurf.surfwidth;
+	r_drawsurf.surfheight = surface->extents[1] >> miplevel;
+	
+//
+// allocate memory if needed
+//
+	if (!cache)     // if a texture just animated, don't reallocate it
+	{
+		cache = D_SCAlloc (r_drawsurf.surfwidth,
+						   r_drawsurf.surfwidth * r_drawsurf.surfheight);
+		surface->cachespots[miplevel] = cache;
+		cache->owner = &surface->cachespots[miplevel];
+		cache->mipscale = surfscale;
+	}
+	
+	if (surface->dlightframe == r_framecount)
+		cache->dlight = 1;
+	else
+		cache->dlight = 0;
+
+	r_drawsurf.surfdat = (pixel_t *)cache->data;
+	
+	cache->image = r_drawsurf.image;
+	cache->lightadj[0] = r_drawsurf.lightadj[0];
+	cache->lightadj[1] = r_drawsurf.lightadj[1];
+	cache->lightadj[2] = r_drawsurf.lightadj[2];
+	cache->lightadj[3] = r_drawsurf.lightadj[3];
+
+//
+// draw and light the surface texture
+//
+	r_drawsurf.surf = surface;
+
+	c_surf++;
+
+	// calculate the lightings
+	R_BuildLightMap ();
+	
+	// rasterize the surface into the cache
+	R_DrawSurface ();
+
+	return cache;
+}
+
+
--- /dev/null
+++ b/ref/rand1k.h
@@ -1,0 +1,123 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+// 1K random numbers in the range 0-255
+0, 144, 49, 207, 149, 122, 89, 229, 210, 191,
+44, 219, 181, 131, 77, 3, 23, 93, 37, 42,
+253, 114, 30, 1, 2, 96, 136, 146, 154, 155,
+42, 169, 115, 90, 14, 155, 200, 205, 133, 77,
+224, 186, 244, 236, 138, 36, 118, 60, 220, 53,
+199, 215, 255, 255, 156, 100, 68, 76, 215, 6,
+96, 23, 173, 14, 2, 235, 70, 69, 150, 176,
+214, 185, 124, 52, 190, 119, 117, 242, 190, 27,
+153, 98, 188, 155, 146, 92, 38, 57, 108, 205,
+132, 253, 192, 88, 43, 168, 125, 16, 179, 129,
+37, 243, 36, 231, 177, 77, 109, 18, 247, 174,
+39, 224, 210, 149, 48, 45, 209, 121, 39, 129,
+187, 103, 71, 145, 174, 193, 184, 121, 31, 94,
+213, 8, 132, 169, 109, 26, 243, 235, 140, 88,
+120, 95, 216, 81, 116, 69, 251, 76, 189, 145,
+50, 194, 214, 101, 128, 227, 7, 254, 146, 12,
+136, 49, 215, 160, 168, 50, 215, 31, 28, 190,
+80, 240, 73, 86, 35, 187, 213, 181, 153, 191,
+64, 36, 0, 15, 206, 218, 53, 29, 141, 3,
+29, 116, 192, 175, 139, 18, 111, 51, 178, 74,
+111, 59, 147, 136, 160, 41, 129, 246, 178, 236,
+48, 86, 45, 254, 117, 255, 24, 160, 24, 112,
+238, 12, 229, 74, 58, 196, 105, 51, 160, 154,
+115, 119, 153, 162, 218, 212, 159, 184, 144, 96,
+47, 188, 142, 231, 62, 48, 154, 178, 149, 89,
+126, 20, 189, 156, 158, 176, 205, 38, 147, 222,
+233, 157, 186, 11, 170, 249, 80, 145, 78, 44,
+27, 222, 217, 190, 39, 83, 20, 19, 164, 209,
+139, 114, 104, 76, 119, 128, 39, 82, 188, 80,
+211, 245, 223, 185, 76, 241, 32, 16, 200, 134,
+156, 244, 18, 224, 167, 82, 26, 129, 58, 74,
+235, 141, 169, 29, 126, 97, 127, 203, 130, 97,
+176, 136, 155, 101, 1, 181, 25, 159, 220, 125,
+191, 127, 97, 201, 141, 91, 244, 161, 45, 95,
+33, 190, 243, 156, 7, 84, 14, 163, 33, 216,
+221, 152, 184, 218, 3, 32, 181, 157, 55, 16,
+43, 159, 87, 81, 94, 169, 205, 206, 134, 156,
+204, 230, 37, 161, 103, 64, 34, 218, 16, 109,
+146, 77, 140, 57, 79, 28, 206, 34, 72, 201,
+229, 202, 190, 157, 92, 219, 58, 221, 58, 63,
+138, 252, 13, 20, 134, 109, 24, 66, 228, 59,
+37, 32, 238, 20, 12, 15, 86, 234, 102, 110,
+242, 214, 136, 215, 177, 101, 66, 1, 134, 244,
+102, 61, 149, 65, 175, 241, 111, 227, 1, 240,
+153, 201, 147, 36, 56, 98, 1, 106, 21, 168,
+218, 16, 207, 169, 177, 205, 135, 175, 36, 176,
+186, 199, 7, 222, 164, 180, 21, 141, 242, 15,
+70, 37, 251, 158, 74, 236, 94, 177, 55, 39,
+61, 133, 230, 27, 231, 113, 20, 200, 43, 249,
+198, 222, 53, 116, 0, 192, 29, 103, 79, 254,
+9, 64, 48, 63, 39, 158, 226, 240, 50, 199,
+165, 168, 232, 116, 235, 170, 38, 162, 145, 108,
+241, 138, 148, 137, 65, 101, 89, 9, 203, 50,
+17, 99, 151, 18, 50, 39, 164, 116, 154, 178,
+112, 175, 101, 213, 151, 51, 243, 224, 100, 252,
+47, 229, 147, 113, 160, 181, 12, 73, 66, 104,
+229, 181, 186, 229, 100, 101, 231, 79, 99, 146,
+90, 187, 190, 188, 189, 35, 51, 69, 174, 233,
+94, 132, 28, 232, 51, 132, 167, 112, 176, 23,
+20, 19, 7, 90, 78, 178, 36, 101, 17, 172,
+185, 50, 177, 157, 167, 139, 25, 139, 12, 249,
+118, 248, 186, 135, 174, 177, 95, 99, 12, 207,
+43, 15, 79, 200, 54, 82, 124, 2, 112, 130,
+155, 194, 102, 89, 215, 241, 159, 255, 13, 144,
+221, 99, 78, 72, 6, 156, 100, 4, 7, 116,
+219, 239, 102, 186, 156, 206, 224, 149, 152, 20,
+203, 118, 151, 150, 145, 208, 172, 87, 2, 68,
+87, 59, 197, 95, 222, 29, 185, 161, 228, 46,
+137, 230, 199, 247, 50, 230, 204, 244, 217, 227,
+160, 47, 157, 67, 64, 187, 201, 43, 182, 123,
+20, 206, 218, 31, 78, 146, 121, 195, 49, 186,
+254, 3, 165, 177, 44, 18, 70, 173, 214, 142,
+95, 199, 59, 163, 59, 52, 248, 72, 5, 196,
+38, 12, 2, 89, 164, 87, 106, 106, 23, 139,
+179, 86, 168, 224, 137, 145, 13, 119, 66, 109,
+221, 124, 22, 144, 181, 199, 221, 217, 75, 221,
+165, 191, 212, 195, 223, 232, 233, 133, 112, 27,
+90, 210, 109, 43, 0, 168, 198, 16, 22, 98,
+175, 206, 39, 36, 12, 88, 4, 250, 165, 13,
+234, 163, 110, 5, 62, 100, 167, 200, 5, 211,
+35, 162, 140, 251, 118, 54, 76, 200, 87, 123,
+155, 26, 252, 193, 38, 116, 182, 255, 198, 164,
+159, 242, 176, 74, 145, 74, 140, 182, 63, 139,
+126, 243, 171, 195, 159, 114, 204, 190, 253, 52,
+161, 232, 151, 235, 129, 125, 115, 227, 240, 46,
+64, 51, 187, 240, 160, 10, 164, 8, 142, 139,
+114, 15, 254, 32, 153, 12, 44, 169, 85, 80,
+167, 105, 109, 56, 173, 42, 127, 129, 205, 111,
+1, 86, 96, 32, 211, 187, 228, 164, 166, 131,
+187, 188, 245, 119, 92, 28, 231, 210, 116, 27,
+222, 194, 10, 106, 239, 17, 42, 54, 29, 151,
+30, 158, 148, 176, 187, 234, 171, 76, 207, 96,
+255, 197, 52, 43, 99, 46, 148, 50, 245, 48,
+97, 77, 30, 50, 11, 197, 194, 225, 0, 114,
+109, 205, 118, 126, 191, 61, 143, 23, 236, 228,
+219, 15, 125, 161, 191, 193, 65, 232, 202, 51,
+141, 13, 133, 202, 180, 6, 187, 141, 234, 224,
+204, 78, 101, 123, 13, 166, 0, 196, 193, 56,
+39, 14, 171, 8, 88, 178, 204, 111, 251, 162,
+75, 122, 223, 20, 25, 36, 36, 235, 79, 95,
+208, 11, 208, 61, 229, 65, 68, 53, 58, 216,
+223, 227, 216, 155, 10, 44, 47, 91, 115, 47,
+228, 159, 139, 233
--- a/ref_soft/adivtab.h
+++ /dev/null
@@ -1,1077 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// table of quotients and remainders for [-15...16] / [-15...16]
-
-// numerator = -15
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{1, -4},
-{1, -5},
-{1, -6},
-{1, -7},
-{2, -1},
-{2, -3},
-{3, 0},
-{3, -3},
-{5, 0},
-{7, -1},
-{15, 0},
-{0, 0},
-{-15, 0},
-{-8, 1},
-{-5, 0},
-{-4, 1},
-{-3, 0},
-{-3, 3},
-{-3, 6},
-{-2, 1},
-{-2, 3},
-{-2, 5},
-{-2, 7},
-{-2, 9},
-{-2, 11},
-{-2, 13},
-{-1, 0},
-{-1, 1},
-// numerator = -14
-{0, -14},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{1, -4},
-{1, -5},
-{1, -6},
-{2, 0},
-{2, -2},
-{2, -4},
-{3, -2},
-{4, -2},
-{7, 0},
-{14, 0},
-{0, 0},
-{-14, 0},
-{-7, 0},
-{-5, 1},
-{-4, 2},
-{-3, 1},
-{-3, 4},
-{-2, 0},
-{-2, 2},
-{-2, 4},
-{-2, 6},
-{-2, 8},
-{-2, 10},
-{-2, 12},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-// numerator = -13
-{0, -13},
-{0, -13},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{1, -4},
-{1, -5},
-{1, -6},
-{2, -1},
-{2, -3},
-{3, -1},
-{4, -1},
-{6, -1},
-{13, 0},
-{0, 0},
-{-13, 0},
-{-7, 1},
-{-5, 2},
-{-4, 3},
-{-3, 2},
-{-3, 5},
-{-2, 1},
-{-2, 3},
-{-2, 5},
-{-2, 7},
-{-2, 9},
-{-2, 11},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-// numerator = -12
-{0, -12},
-{0, -12},
-{0, -12},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{1, -4},
-{1, -5},
-{2, 0},
-{2, -2},
-{3, 0},
-{4, 0},
-{6, 0},
-{12, 0},
-{0, 0},
-{-12, 0},
-{-6, 0},
-{-4, 0},
-{-3, 0},
-{-3, 3},
-{-2, 0},
-{-2, 2},
-{-2, 4},
-{-2, 6},
-{-2, 8},
-{-2, 10},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-// numerator = -11
-{0, -11},
-{0, -11},
-{0, -11},
-{0, -11},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{1, -4},
-{1, -5},
-{2, -1},
-{2, -3},
-{3, -2},
-{5, -1},
-{11, 0},
-{0, 0},
-{-11, 0},
-{-6, 1},
-{-4, 1},
-{-3, 1},
-{-3, 4},
-{-2, 1},
-{-2, 3},
-{-2, 5},
-{-2, 7},
-{-2, 9},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-// numerator = -10
-{0, -10},
-{0, -10},
-{0, -10},
-{0, -10},
-{0, -10},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{1, -4},
-{2, 0},
-{2, -2},
-{3, -1},
-{5, 0},
-{10, 0},
-{0, 0},
-{-10, 0},
-{-5, 0},
-{-4, 2},
-{-3, 2},
-{-2, 0},
-{-2, 2},
-{-2, 4},
-{-2, 6},
-{-2, 8},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-// numerator = -9
-{0, -9},
-{0, -9},
-{0, -9},
-{0, -9},
-{0, -9},
-{0, -9},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{1, -4},
-{2, -1},
-{3, 0},
-{4, -1},
-{9, 0},
-{0, 0},
-{-9, 0},
-{-5, 1},
-{-3, 0},
-{-3, 3},
-{-2, 1},
-{-2, 3},
-{-2, 5},
-{-2, 7},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-// numerator = -8
-{0, -8},
-{0, -8},
-{0, -8},
-{0, -8},
-{0, -8},
-{0, -8},
-{0, -8},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{2, 0},
-{2, -2},
-{4, 0},
-{8, 0},
-{0, 0},
-{-8, 0},
-{-4, 0},
-{-3, 1},
-{-2, 0},
-{-2, 2},
-{-2, 4},
-{-2, 6},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-// numerator = -7
-{0, -7},
-{0, -7},
-{0, -7},
-{0, -7},
-{0, -7},
-{0, -7},
-{0, -7},
-{0, -7},
-{1, 0},
-{1, -1},
-{1, -2},
-{1, -3},
-{2, -1},
-{3, -1},
-{7, 0},
-{0, 0},
-{-7, 0},
-{-4, 1},
-{-3, 2},
-{-2, 1},
-{-2, 3},
-{-2, 5},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-{-1, 9},
-// numerator = -6
-{0, -6},
-{0, -6},
-{0, -6},
-{0, -6},
-{0, -6},
-{0, -6},
-{0, -6},
-{0, -6},
-{0, -6},
-{1, 0},
-{1, -1},
-{1, -2},
-{2, 0},
-{3, 0},
-{6, 0},
-{0, 0},
-{-6, 0},
-{-3, 0},
-{-2, 0},
-{-2, 2},
-{-2, 4},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-{-1, 9},
-{-1, 10},
-// numerator = -5
-{0, -5},
-{0, -5},
-{0, -5},
-{0, -5},
-{0, -5},
-{0, -5},
-{0, -5},
-{0, -5},
-{0, -5},
-{0, -5},
-{1, 0},
-{1, -1},
-{1, -2},
-{2, -1},
-{5, 0},
-{0, 0},
-{-5, 0},
-{-3, 1},
-{-2, 1},
-{-2, 3},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-{-1, 9},
-{-1, 10},
-{-1, 11},
-// numerator = -4
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{0, -4},
-{1, 0},
-{1, -1},
-{2, 0},
-{4, 0},
-{0, 0},
-{-4, 0},
-{-2, 0},
-{-2, 2},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-{-1, 9},
-{-1, 10},
-{-1, 11},
-{-1, 12},
-// numerator = -3
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{0, -3},
-{1, 0},
-{1, -1},
-{3, 0},
-{0, 0},
-{-3, 0},
-{-2, 1},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-{-1, 9},
-{-1, 10},
-{-1, 11},
-{-1, 12},
-{-1, 13},
-// numerator = -2
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{0, -2},
-{1, 0},
-{2, 0},
-{0, 0},
-{-2, 0},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-{-1, 9},
-{-1, 10},
-{-1, 11},
-{-1, 12},
-{-1, 13},
-{-1, 14},
-// numerator = -1
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{0, -1},
-{1, 0},
-{0, 0},
-{-1, 0},
-{-1, 1},
-{-1, 2},
-{-1, 3},
-{-1, 4},
-{-1, 5},
-{-1, 6},
-{-1, 7},
-{-1, 8},
-{-1, 9},
-{-1, 10},
-{-1, 11},
-{-1, 12},
-{-1, 13},
-{-1, 14},
-{-1, 15},
-// numerator = 0
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-{0, 0},
-// numerator = 1
-{-1, -14},
-{-1, -13},
-{-1, -12},
-{-1, -11},
-{-1, -10},
-{-1, -9},
-{-1, -8},
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{0, 0},
-{1, 0},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-{0, 1},
-// numerator = 2
-{-1, -13},
-{-1, -12},
-{-1, -11},
-{-1, -10},
-{-1, -9},
-{-1, -8},
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, 0},
-{0, 0},
-{2, 0},
-{1, 0},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-{0, 2},
-// numerator = 3
-{-1, -12},
-{-1, -11},
-{-1, -10},
-{-1, -9},
-{-1, -8},
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -1},
-{-3, 0},
-{0, 0},
-{3, 0},
-{1, 1},
-{1, 0},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-{0, 3},
-// numerator = 4
-{-1, -11},
-{-1, -10},
-{-1, -9},
-{-1, -8},
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -2},
-{-2, 0},
-{-4, 0},
-{0, 0},
-{4, 0},
-{2, 0},
-{1, 1},
-{1, 0},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-{0, 4},
-// numerator = 5
-{-1, -10},
-{-1, -9},
-{-1, -8},
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -3},
-{-2, -1},
-{-3, -1},
-{-5, 0},
-{0, 0},
-{5, 0},
-{2, 1},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-{0, 5},
-// numerator = 6
-{-1, -9},
-{-1, -8},
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -4},
-{-2, -2},
-{-2, 0},
-{-3, 0},
-{-6, 0},
-{0, 0},
-{6, 0},
-{3, 0},
-{2, 0},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 6},
-{0, 6},
-{0, 6},
-{0, 6},
-{0, 6},
-{0, 6},
-{0, 6},
-{0, 6},
-{0, 6},
-{0, 6},
-// numerator = 7
-{-1, -8},
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -5},
-{-2, -3},
-{-2, -1},
-{-3, -2},
-{-4, -1},
-{-7, 0},
-{0, 0},
-{7, 0},
-{3, 1},
-{2, 1},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 7},
-{0, 7},
-{0, 7},
-{0, 7},
-{0, 7},
-{0, 7},
-{0, 7},
-{0, 7},
-{0, 7},
-// numerator = 8
-{-1, -7},
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -6},
-{-2, -4},
-{-2, -2},
-{-2, 0},
-{-3, -1},
-{-4, 0},
-{-8, 0},
-{0, 0},
-{8, 0},
-{4, 0},
-{2, 2},
-{2, 0},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 8},
-{0, 8},
-{0, 8},
-{0, 8},
-{0, 8},
-{0, 8},
-{0, 8},
-{0, 8},
-// numerator = 9
-{-1, -6},
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -7},
-{-2, -5},
-{-2, -3},
-{-2, -1},
-{-3, -3},
-{-3, 0},
-{-5, -1},
-{-9, 0},
-{0, 0},
-{9, 0},
-{4, 1},
-{3, 0},
-{2, 1},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 9},
-{0, 9},
-{0, 9},
-{0, 9},
-{0, 9},
-{0, 9},
-{0, 9},
-// numerator = 10
-{-1, -5},
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -8},
-{-2, -6},
-{-2, -4},
-{-2, -2},
-{-2, 0},
-{-3, -2},
-{-4, -2},
-{-5, 0},
-{-10, 0},
-{0, 0},
-{10, 0},
-{5, 0},
-{3, 1},
-{2, 2},
-{2, 0},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 10},
-{0, 10},
-{0, 10},
-{0, 10},
-{0, 10},
-{0, 10},
-// numerator = 11
-{-1, -4},
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -9},
-{-2, -7},
-{-2, -5},
-{-2, -3},
-{-2, -1},
-{-3, -4},
-{-3, -1},
-{-4, -1},
-{-6, -1},
-{-11, 0},
-{0, 0},
-{11, 0},
-{5, 1},
-{3, 2},
-{2, 3},
-{2, 1},
-{1, 5},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 11},
-{0, 11},
-{0, 11},
-{0, 11},
-{0, 11},
-// numerator = 12
-{-1, -3},
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -10},
-{-2, -8},
-{-2, -6},
-{-2, -4},
-{-2, -2},
-{-2, 0},
-{-3, -3},
-{-3, 0},
-{-4, 0},
-{-6, 0},
-{-12, 0},
-{0, 0},
-{12, 0},
-{6, 0},
-{4, 0},
-{3, 0},
-{2, 2},
-{2, 0},
-{1, 5},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 12},
-{0, 12},
-{0, 12},
-{0, 12},
-// numerator = 13
-{-1, -2},
-{-1, -1},
-{-1, 0},
-{-2, -11},
-{-2, -9},
-{-2, -7},
-{-2, -5},
-{-2, -3},
-{-2, -1},
-{-3, -5},
-{-3, -2},
-{-4, -3},
-{-5, -2},
-{-7, -1},
-{-13, 0},
-{0, 0},
-{13, 0},
-{6, 1},
-{4, 1},
-{3, 1},
-{2, 3},
-{2, 1},
-{1, 6},
-{1, 5},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 13},
-{0, 13},
-{0, 13},
-// numerator = 14
-{-1, -1},
-{-1, 0},
-{-2, -12},
-{-2, -10},
-{-2, -8},
-{-2, -6},
-{-2, -4},
-{-2, -2},
-{-2, 0},
-{-3, -4},
-{-3, -1},
-{-4, -2},
-{-5, -1},
-{-7, 0},
-{-14, 0},
-{0, 0},
-{14, 0},
-{7, 0},
-{4, 2},
-{3, 2},
-{2, 4},
-{2, 2},
-{2, 0},
-{1, 6},
-{1, 5},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 14},
-{0, 14},
-// numerator = 15
-{-1, 0},
-{-2, -13},
-{-2, -11},
-{-2, -9},
-{-2, -7},
-{-2, -5},
-{-2, -3},
-{-2, -1},
-{-3, -6},
-{-3, -3},
-{-3, 0},
-{-4, -1},
-{-5, 0},
-{-8, -1},
-{-15, 0},
-{0, 0},
-{15, 0},
-{7, 1},
-{5, 0},
-{3, 3},
-{3, 0},
-{2, 3},
-{2, 1},
-{1, 7},
-{1, 6},
-{1, 5},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
-{0, 15},
-// numerator = 16
-{-2, -14},
-{-2, -12},
-{-2, -10},
-{-2, -8},
-{-2, -6},
-{-2, -4},
-{-2, -2},
-{-2, 0},
-{-3, -5},
-{-3, -2},
-{-4, -4},
-{-4, 0},
-{-6, -2},
-{-8, 0},
-{-16, 0},
-{0, 0},
-{16, 0},
-{8, 0},
-{5, 1},
-{4, 0},
-{3, 1},
-{2, 4},
-{2, 2},
-{2, 0},
-{1, 7},
-{1, 6},
-{1, 5},
-{1, 4},
-{1, 3},
-{1, 2},
-{1, 1},
-{1, 0},
--- a/ref_soft/r_aclip.c
+++ /dev/null
@@ -1,323 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_aclip.c: clip routines for drawing Alias models directly to the screen
-
-#include "r_local.h"
-
-static finalvert_t		fv[2][8];
-
-void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv);
-void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1,
-	finalvert_t *out);
-void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
-	finalvert_t *out);
-void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1,
-	finalvert_t *out);
-void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1,
-	finalvert_t *out);
-
-
-/*
-================
-R_Alias_clip_z
-
-pfv0 is the unclipped vertex, pfv1 is the z-clipped vertex
-================
-*/
-void R_Alias_clip_z (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
-{
-	float		scale;
-
-	scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) /
-			(pfv1->xyz[2] - pfv0->xyz[2]);
-
-	out->xyz[0] = pfv0->xyz[0] + (pfv1->xyz[0] - pfv0->xyz[0]) * scale;
-	out->xyz[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale;
-	out->xyz[2] = ALIAS_Z_CLIP_PLANE;
-
-	out->s =	pfv0->s + (pfv1->s - pfv0->s) * scale;
-	out->t =	pfv0->t + (pfv1->t - pfv0->t) * scale;
-	out->l =	pfv0->l + (pfv1->l - pfv0->l) * scale;
-
-	R_AliasProjectAndClipTestFinalVert (out);
-}
-
-
-#if	!id386
-
-void R_Alias_clip_left (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
-{
-	float		scale;
-
-	if (pfv0->v >= pfv1->v )
-	{
-		scale = (float)(r_refdef.aliasvrect.x - pfv0->u) /
-				(pfv1->u - pfv0->u);
-		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
-		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
-		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
-		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
-		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
-		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
-	}
-	else
-	{
-		scale = (float)(r_refdef.aliasvrect.x - pfv1->u) /
-				(pfv0->u - pfv1->u);
-		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
-		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
-		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
-		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
-		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
-		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
-	}
-}
-
-
-void R_Alias_clip_right (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
-{
-	float		scale;
-
-	if ( pfv0->v >= pfv1->v )
-	{
-		scale = (float)(r_refdef.aliasvrectright - pfv0->u ) /
-				(pfv1->u - pfv0->u );
-		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
-		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
-		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
-		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
-		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
-		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
-	}
-	else
-	{
-		scale = (float)(r_refdef.aliasvrectright - pfv1->u ) /
-				(pfv0->u - pfv1->u );
-		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
-		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
-		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
-		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
-		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
-		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
-	}
-}
-
-
-void R_Alias_clip_top (finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out)
-{
-	float		scale;
-
-	if (pfv0->v >= pfv1->v)
-	{
-		scale = (float)(r_refdef.aliasvrect.y - pfv0->v) /
-				(pfv1->v - pfv0->v);
-		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
-		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
-		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
-		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
-		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
-		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
-	}
-	else
-	{
-		scale = (float)(r_refdef.aliasvrect.y - pfv1->v) /
-				(pfv0->v - pfv1->v);
-		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
-		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
-		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
-		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
-		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
-		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
-	}
-}
-
-
-void R_Alias_clip_bottom (finalvert_t *pfv0, finalvert_t *pfv1,
-	finalvert_t *out)
-{
-	float		scale;
-
-	if (pfv0->v >= pfv1->v)
-	{
-		scale = (float)(r_refdef.aliasvrectbottom - pfv0->v) /
-				(pfv1->v - pfv0->v);
-
-		out->u  = pfv0->u  + ( pfv1->u  - pfv0->u ) * scale + 0.5;
-		out->v  = pfv0->v  + ( pfv1->v  - pfv0->v ) * scale + 0.5;
-		out->s  = pfv0->s  + ( pfv1->s  - pfv0->s ) * scale + 0.5;
-		out->t  = pfv0->t  + ( pfv1->t  - pfv0->t ) * scale + 0.5;
-		out->l  = pfv0->l  + ( pfv1->l  - pfv0->l ) * scale + 0.5;
-		out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5;
-	}
-	else
-	{
-		scale = (float)(r_refdef.aliasvrectbottom - pfv1->v) /
-				(pfv0->v - pfv1->v);
-
-		out->u  = pfv1->u  + ( pfv0->u  - pfv1->u ) * scale + 0.5;
-		out->v  = pfv1->v  + ( pfv0->v  - pfv1->v ) * scale + 0.5;
-		out->s  = pfv1->s  + ( pfv0->s  - pfv1->s ) * scale + 0.5;
-		out->t  = pfv1->t  + ( pfv0->t  - pfv1->t ) * scale + 0.5;
-		out->l  = pfv1->l  + ( pfv0->l  - pfv1->l ) * scale + 0.5;
-		out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5;
-	}
-}
-
-#endif
-
-
-int R_AliasClip (finalvert_t *in, finalvert_t *out, int flag, int count,
-	void(*clip)(finalvert_t *pfv0, finalvert_t *pfv1, finalvert_t *out) )
-{
-	int			i,j,k;
-	int			flags, oldflags;
-	
-	j = count-1;
-	k = 0;
-	for (i=0 ; i<count ; j = i, i++)
-	{
-		oldflags = in[j].flags & flag;
-		flags = in[i].flags & flag;
-
-		if (flags && oldflags)
-			continue;
-		if (oldflags ^ flags)
-		{
-			clip (&in[j], &in[i], &out[k]);
-			out[k].flags = 0;
-			if (out[k].u < r_refdef.aliasvrect.x)
-				out[k].flags |= ALIAS_LEFT_CLIP;
-			if (out[k].v < r_refdef.aliasvrect.y)
-				out[k].flags |= ALIAS_TOP_CLIP;
-			if (out[k].u > r_refdef.aliasvrectright)
-				out[k].flags |= ALIAS_RIGHT_CLIP;
-			if (out[k].v > r_refdef.aliasvrectbottom)
-				out[k].flags |= ALIAS_BOTTOM_CLIP;	
-			k++;
-		}
-		if (!flags)
-		{
-			out[k] = in[i];
-			k++;
-		}
-	}
-	
-	return k;
-}
-
-
-/*
-================
-R_AliasClipTriangle
-================
-*/
-void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2)
-{
-	int				i, k, pingpong;
-	unsigned		clipflags;
-
-// copy vertexes and fix seam texture coordinates
-	fv[0][0] = *index0;
-	fv[0][1] = *index1;
-	fv[0][2] = *index2;
-
-// clip
-	clipflags = fv[0][0].flags | fv[0][1].flags | fv[0][2].flags;
-
-	if (clipflags & ALIAS_Z_CLIP)
-	{
-		k = R_AliasClip (fv[0], fv[1], ALIAS_Z_CLIP, 3, R_Alias_clip_z);
-		if (k == 0)
-			return;
-
-		pingpong = 1;
-		clipflags = fv[1][0].flags | fv[1][1].flags | fv[1][2].flags;
-	}
-	else
-	{
-		pingpong = 0;
-		k = 3;
-	}
-
-	if (clipflags & ALIAS_LEFT_CLIP)
-	{
-		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
-							ALIAS_LEFT_CLIP, k, R_Alias_clip_left);
-		if (k == 0)
-			return;
-
-		pingpong ^= 1;
-	}
-
-	if (clipflags & ALIAS_RIGHT_CLIP)
-	{
-		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
-							ALIAS_RIGHT_CLIP, k, R_Alias_clip_right);
-		if (k == 0)
-			return;
-
-		pingpong ^= 1;
-	}
-
-	if (clipflags & ALIAS_BOTTOM_CLIP)
-	{
-		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
-							ALIAS_BOTTOM_CLIP, k, R_Alias_clip_bottom);
-		if (k == 0)
-			return;
-
-		pingpong ^= 1;
-	}
-
-	if (clipflags & ALIAS_TOP_CLIP)
-	{
-		k = R_AliasClip (fv[pingpong], fv[pingpong ^ 1],
-							ALIAS_TOP_CLIP, k, R_Alias_clip_top);
-		if (k == 0)
-			return;
-
-		pingpong ^= 1;
-	}
-
-	for (i=0 ; i<k ; i++)
-	{
-		if (fv[pingpong][i].u < r_refdef.aliasvrect.x)
-			fv[pingpong][i].u = r_refdef.aliasvrect.x;
-		else if (fv[pingpong][i].u > r_refdef.aliasvrectright)
-			fv[pingpong][i].u = r_refdef.aliasvrectright;
-
-		if (fv[pingpong][i].v < r_refdef.aliasvrect.y)
-			fv[pingpong][i].v = r_refdef.aliasvrect.y;
-		else if (fv[pingpong][i].v > r_refdef.aliasvrectbottom)
-			fv[pingpong][i].v = r_refdef.aliasvrectbottom;
-
-		fv[pingpong][i].flags = 0;
-	}
-
-// draw triangles
-	for (i=1 ; i<k-1 ; i++)
-	{
-		aliastriangleparms.a = &fv[pingpong][0];
-		aliastriangleparms.b = &fv[pingpong][i];
-		aliastriangleparms.c = &fv[pingpong][i+1];
-		R_DrawTriangle();
-	}
-}
-
--- a/ref_soft/r_alias.c
+++ /dev/null
@@ -1,1198 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_alias.c: routines for setting up to draw alias models
-
-/*
-** use a real variable to control lerping
-*/
-#include "r_local.h"
-
-#define LIGHT_MIN	5		// lowest light value we'll allow, to avoid the
-							//  need for inner-loop light clamping
-
-//PGM
-extern byte iractive;
-//PGM
-
-int				r_amodels_drawn;
-
-affinetridesc_t	r_affinetridesc;
-
-vec3_t			r_plightvec;
-vec3_t          r_lerped[1024];
-vec3_t          r_lerp_frontv, r_lerp_backv, r_lerp_move;
-
-int				r_ambientlight;
-int				r_aliasblendcolor;
-float			r_shadelight;
-
-
-daliasframe_t	*r_thisframe, *r_lastframe;
-dmdl_t			*s_pmdl;
-
-float	aliastransform[3][4];
-float   aliasworldtransform[3][4];
-float   aliasoldworldtransform[3][4];
-
-static float	s_ziscale;
-static vec3_t	s_alias_forward, s_alias_right, s_alias_up;
-
-
-#define NUMVERTEXNORMALS	162
-
-float	r_avertexnormals[NUMVERTEXNORMALS][3] = {
-#include "../anorms.h"
-};
-
-
-void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp );
-void R_AliasSetUpTransform (void);
-void R_AliasTransformVector (vec3_t in, vec3_t out, float m[3][4] );
-void R_AliasProjectAndClipTestFinalVert (finalvert_t *fv);
-
-void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv );
-
-void R_AliasLerpFrames( dmdl_t *paliashdr, float backlerp );
-
-/*
-================
-R_AliasCheckBBox
-================
-*/
-typedef struct {
-	int	index0;
-	int	index1;
-} aedge_t;
-
-static aedge_t	aedges[12] = {
-{0, 1}, {1, 2}, {2, 3}, {3, 0},
-{4, 5}, {5, 6}, {6, 7}, {7, 4},
-{0, 5}, {1, 4}, {2, 7}, {3, 6}
-};
-
-#define BBOX_TRIVIAL_ACCEPT 0
-#define BBOX_MUST_CLIP_XY   1
-#define BBOX_MUST_CLIP_Z    2
-#define BBOX_TRIVIAL_REJECT 8
-
-/*
-** R_AliasCheckFrameBBox
-**
-** Checks a specific alias frame bounding box
-*/
-unsigned long R_AliasCheckFrameBBox( daliasframe_t *frame, float worldxf[3][4] )
-{
-	unsigned long aggregate_and_clipcode = ~0U, 
-		          aggregate_or_clipcode = 0;
-	int           i;
-	vec3_t        mins, maxs;
-	vec3_t        transformed_min, transformed_max;
-	qboolean      zclipped = false, zfullyclipped = true;
-	float         minz = 9999.0F;
-
-	/*
-	** get the exact frame bounding box
-	*/
-	for (i=0 ; i<3 ; i++)
-	{
-		mins[i] = frame->translate[i];
-		maxs[i] = mins[i] + frame->scale[i]*255;
-	}
-
-	/*
-	** transform the min and max values into view space
-	*/
-	R_AliasTransformVector( mins, transformed_min, aliastransform );
-	R_AliasTransformVector( maxs, transformed_max, aliastransform );
-
-	if ( transformed_min[2] >= ALIAS_Z_CLIP_PLANE )
-		zfullyclipped = false;
-	if ( transformed_max[2] >= ALIAS_Z_CLIP_PLANE )
-		zfullyclipped = false;
-
-	if ( zfullyclipped )
-	{
-		return BBOX_TRIVIAL_REJECT;
-	}
-	if ( zclipped )
-	{
-		return ( BBOX_MUST_CLIP_XY | BBOX_MUST_CLIP_Z );
-	}
-
-	/*
-	** build a transformed bounding box from the given min and max
-	*/
-	for ( i = 0; i < 8; i++ )
-	{
-		int      j;
-		vec3_t   tmp, transformed;
-		unsigned long clipcode = 0;
-
-		if ( i & 1 )
-			tmp[0] = mins[0];
-		else
-			tmp[0] = maxs[0];
-
-		if ( i & 2 )
-			tmp[1] = mins[1];
-		else
-			tmp[1] = maxs[1];
-
-		if ( i & 4 )
-			tmp[2] = mins[2];
-		else
-			tmp[2] = maxs[2];
-
-		R_AliasTransformVector( tmp, transformed, worldxf );
-
-		for ( j = 0; j < 4; j++ )
-		{
-			float dp = DotProduct( transformed, view_clipplanes[j].normal );
-
-			if ( ( dp - view_clipplanes[j].dist ) < 0.0F )
-				clipcode |= 1 << j;
-		}
-
-		aggregate_and_clipcode &= clipcode;
-		aggregate_or_clipcode  |= clipcode;
-	}
-
-	if ( aggregate_and_clipcode )
-	{
-		return BBOX_TRIVIAL_REJECT;
-	}
-	if ( !aggregate_or_clipcode )
-	{
-		return BBOX_TRIVIAL_ACCEPT;
-	}
-
-	return BBOX_MUST_CLIP_XY;
-}
-
-qboolean R_AliasCheckBBox (void)
-{
-	unsigned long ccodes[2] = { 0, 0 };
-
-	ccodes[0] = R_AliasCheckFrameBBox( r_thisframe, aliasworldtransform );
-
-	/*
-	** non-lerping model
-	*/
-	if ( currententity->backlerp == 0 )
-	{
-		if ( ccodes[0] == BBOX_TRIVIAL_ACCEPT )
-			return BBOX_TRIVIAL_ACCEPT;
-		else if ( ccodes[0] & BBOX_TRIVIAL_REJECT )
-			return BBOX_TRIVIAL_REJECT;
-		else
-			return ( ccodes[0] & ~BBOX_TRIVIAL_REJECT );
-	}
-
-	ccodes[1] = R_AliasCheckFrameBBox( r_lastframe, aliasoldworldtransform );
-
-	if ( ( ccodes[0] | ccodes[1] ) == BBOX_TRIVIAL_ACCEPT )
-		return BBOX_TRIVIAL_ACCEPT;
-	else if ( ( ccodes[0] & ccodes[1] ) & BBOX_TRIVIAL_REJECT )
-		return BBOX_TRIVIAL_REJECT;
-	else
-		return ( ccodes[0] | ccodes[1] ) & ~BBOX_TRIVIAL_REJECT;
-}
-
-
-/*
-================
-R_AliasTransformVector
-================
-*/
-void R_AliasTransformVector(vec3_t in, vec3_t out, float xf[3][4] )
-{
-	out[0] = DotProduct(in, xf[0]) + xf[0][3];
-	out[1] = DotProduct(in, xf[1]) + xf[1][3];
-	out[2] = DotProduct(in, xf[2]) + xf[2][3];
-}
-
-
-/*
-================
-R_AliasPreparePoints
-
-General clipped case
-================
-*/
-typedef struct
-{
-	int          num_points;
-	dtrivertx_t *last_verts;   // verts from the last frame
-	dtrivertx_t *this_verts;   // verts from this frame
-	finalvert_t *dest_verts;   // destination for transformed verts
-} aliasbatchedtransformdata_t;
-
-aliasbatchedtransformdata_t aliasbatchedtransformdata;
-
-void R_AliasPreparePoints (void)
-{
-	int			i;
-	dstvert_t	*pstverts;
-	dtriangle_t	*ptri;
-	finalvert_t	*pfv[3];
-	finalvert_t	finalverts[MAXALIASVERTS +
-						((CACHE_SIZE - 1) / sizeof(finalvert_t)) + 3];
-	finalvert_t	*pfinalverts;
-
-//PGM
-	iractive = (r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE);
-//	iractive = 0;
-//	if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
-//		iractive = 1;
-//PGM
-
-	// put work vertexes on stack, cache aligned
-	pfinalverts = (finalvert_t *)
-			(((long)&finalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
-
-	aliasbatchedtransformdata.num_points = s_pmdl->num_xyz;
-	aliasbatchedtransformdata.last_verts = r_lastframe->verts;
-	aliasbatchedtransformdata.this_verts = r_thisframe->verts;
-	aliasbatchedtransformdata.dest_verts = pfinalverts;
-
-	R_AliasTransformFinalVerts( aliasbatchedtransformdata.num_points,
-		                        aliasbatchedtransformdata.dest_verts,
-								aliasbatchedtransformdata.last_verts,
-								aliasbatchedtransformdata.this_verts );
-
-// clip and draw all triangles
-//
-	pstverts = (dstvert_t *)((byte *)s_pmdl + s_pmdl->ofs_st);
-	ptri = (dtriangle_t *)((byte *)s_pmdl + s_pmdl->ofs_tris);
-
-	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
-	{
-		for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++)
-		{
-			pfv[0] = &pfinalverts[ptri->index_xyz[0]];
-			pfv[1] = &pfinalverts[ptri->index_xyz[1]];
-			pfv[2] = &pfinalverts[ptri->index_xyz[2]];
-
-			if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags )
-				continue;		// completely clipped
-
-			// insert s/t coordinates
-			pfv[0]->s = pstverts[ptri->index_st[0]].s << 16;
-			pfv[0]->t = pstverts[ptri->index_st[0]].t << 16;
-
-			pfv[1]->s = pstverts[ptri->index_st[1]].s << 16;
-			pfv[1]->t = pstverts[ptri->index_st[1]].t << 16;
-
-			pfv[2]->s = pstverts[ptri->index_st[2]].s << 16;
-			pfv[2]->t = pstverts[ptri->index_st[2]].t << 16;
-
-			if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) )
-			{	// totally unclipped
-				aliastriangleparms.a = pfv[2];
-				aliastriangleparms.b = pfv[1];
-				aliastriangleparms.c = pfv[0];
-
-				R_DrawTriangle();
-			}
-			else
-			{
-				R_AliasClipTriangle (pfv[2], pfv[1], pfv[0]);
-			}
-		}
-	}
-	else
-	{
-		for (i=0 ; i<s_pmdl->num_tris ; i++, ptri++)
-		{
-			pfv[0] = &pfinalverts[ptri->index_xyz[0]];
-			pfv[1] = &pfinalverts[ptri->index_xyz[1]];
-			pfv[2] = &pfinalverts[ptri->index_xyz[2]];
-
-			if ( pfv[0]->flags & pfv[1]->flags & pfv[2]->flags )
-				continue;		// completely clipped
-
-			// insert s/t coordinates
-			pfv[0]->s = pstverts[ptri->index_st[0]].s << 16;
-			pfv[0]->t = pstverts[ptri->index_st[0]].t << 16;
-
-			pfv[1]->s = pstverts[ptri->index_st[1]].s << 16;
-			pfv[1]->t = pstverts[ptri->index_st[1]].t << 16;
-
-			pfv[2]->s = pstverts[ptri->index_st[2]].s << 16;
-			pfv[2]->t = pstverts[ptri->index_st[2]].t << 16;
-
-			if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) )
-			{	// totally unclipped
-				aliastriangleparms.a = pfv[0];
-				aliastriangleparms.b = pfv[1];
-				aliastriangleparms.c = pfv[2];
-
-				R_DrawTriangle();
-			}
-			else		
-			{	// partially clipped
-				R_AliasClipTriangle (pfv[0], pfv[1], pfv[2]);
-			}
-		}
-	}
-}
-
-
-/*
-================
-R_AliasSetUpTransform
-================
-*/
-void R_AliasSetUpTransform (void)
-{
-	int				i;
-	static float	viewmatrix[3][4];
-	vec3_t			angles;
-
-// TODO: should really be stored with the entity instead of being reconstructed
-// TODO: should use a look-up table
-// TODO: could cache lazily, stored in the entity
-// 
-	angles[ROLL] = currententity->angles[ROLL];
-	angles[PITCH] = currententity->angles[PITCH];
-	angles[YAW] = currententity->angles[YAW];
-	AngleVectors( angles, s_alias_forward, s_alias_right, s_alias_up );
-
-// TODO: can do this with simple matrix rearrangement
-
-	memset( aliasworldtransform, 0, sizeof( aliasworldtransform ) );
-	memset( aliasoldworldtransform, 0, sizeof( aliasworldtransform ) );
-
-	for (i=0 ; i<3 ; i++)
-	{
-		aliasoldworldtransform[i][0] = aliasworldtransform[i][0] =  s_alias_forward[i];
-		aliasoldworldtransform[i][0] = aliasworldtransform[i][1] = -s_alias_right[i];
-		aliasoldworldtransform[i][0] = aliasworldtransform[i][2] =  s_alias_up[i];
-	}
-
-	aliasworldtransform[0][3] = currententity->origin[0]-r_origin[0];
-	aliasworldtransform[1][3] = currententity->origin[1]-r_origin[1];
-	aliasworldtransform[2][3] = currententity->origin[2]-r_origin[2];
-
-	aliasoldworldtransform[0][3] = currententity->oldorigin[0]-r_origin[0];
-	aliasoldworldtransform[1][3] = currententity->oldorigin[1]-r_origin[1];
-	aliasoldworldtransform[2][3] = currententity->oldorigin[2]-r_origin[2];
-
-// FIXME: can do more efficiently than full concatenation
-//	memcpy( rotationmatrix, t2matrix, sizeof( rotationmatrix ) );
-
-//	R_ConcatTransforms (t2matrix, tmatrix, rotationmatrix);
-
-// TODO: should be global, set when vright, etc., set
-	VectorCopy (vright, viewmatrix[0]);
-	VectorCopy (vup, viewmatrix[1]);
-	VectorInverse (viewmatrix[1]);
-	VectorCopy (vpn, viewmatrix[2]);
-
-	viewmatrix[0][3] = 0;
-	viewmatrix[1][3] = 0;
-	viewmatrix[2][3] = 0;
-
-//	memcpy( aliasworldtransform, rotationmatrix, sizeof( aliastransform ) );
-
-	R_ConcatTransforms (viewmatrix, aliasworldtransform, aliastransform);
-
-	aliasworldtransform[0][3] = currententity->origin[0];
-	aliasworldtransform[1][3] = currententity->origin[1];
-	aliasworldtransform[2][3] = currententity->origin[2];
-
-	aliasoldworldtransform[0][3] = currententity->oldorigin[0];
-	aliasoldworldtransform[1][3] = currententity->oldorigin[1];
-	aliasoldworldtransform[2][3] = currententity->oldorigin[2];
-}
-
-
-/*
-================
-R_AliasTransformFinalVerts
-================
-*/
-#if id386 && !defined __linux__
-void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv )
-{
-	float  lightcos;
-	float	lerped_vert[3];
-	int    byte_to_dword_ptr_var;
-	int    tmpint;
-
-	float  one = 1.0F;
-	float  zi;
-
-	static float  FALIAS_Z_CLIP_PLANE = ALIAS_Z_CLIP_PLANE;
-	static float  PS_SCALE = POWERSUIT_SCALE;
-
-	__asm mov ecx, numpoints
-
-	/*
-	lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0];
-	lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1];
-	lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2];
-	*/
-top_of_loop:
-
-	__asm mov esi, oldv
-	__asm mov edi, newv
-
-	__asm xor ebx, ebx
-
-	__asm mov bl, byte ptr [esi+DTRIVERTX_V0]
-	__asm mov byte_to_dword_ptr_var, ebx
-	__asm fild dword ptr byte_to_dword_ptr_var      
-	__asm fmul dword ptr [r_lerp_backv+0]                  ; oldv[0]*rlb[0]
-
-	__asm mov bl, byte ptr [esi+DTRIVERTX_V1]
-	__asm mov byte_to_dword_ptr_var, ebx
-	__asm fild dword ptr byte_to_dword_ptr_var
-	__asm fmul dword ptr [r_lerp_backv+4]                  ; oldv[1]*rlb[1] | oldv[0]*rlb[0]
-
-	__asm mov bl, byte ptr [esi+DTRIVERTX_V2]
-	__asm mov byte_to_dword_ptr_var, ebx
-	__asm fild dword ptr byte_to_dword_ptr_var
-	__asm fmul dword ptr [r_lerp_backv+8]                  ; oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
-
-	__asm mov bl, byte ptr [edi+DTRIVERTX_V0]
-	__asm mov byte_to_dword_ptr_var, ebx
-	__asm fild dword ptr byte_to_dword_ptr_var      
-	__asm fmul dword ptr [r_lerp_frontv+0]                 ; newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
-
-	__asm mov bl, byte ptr [edi+DTRIVERTX_V1]
-	__asm mov byte_to_dword_ptr_var, ebx
-	__asm fild dword ptr byte_to_dword_ptr_var
-	__asm fmul dword ptr [r_lerp_frontv+4]                 ; newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
-
-	__asm mov bl, byte ptr [edi+DTRIVERTX_V2]
-	__asm mov byte_to_dword_ptr_var, ebx
-	__asm fild dword ptr byte_to_dword_ptr_var
-	__asm fmul dword ptr [r_lerp_frontv+8]                 ; newv[2]*rlf[2] | newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | oldv[0]*rlb[0]
-
-	__asm fxch st(5)                     ; oldv[0]*rlb[0] | newv[1]*rlf[1] | newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | newv[2]*rlf[2]
-	__asm faddp st(2), st                ; newv[1]*rlf[1] | oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] | newv[2]*rlf[2]
-	__asm faddp st(3), st                ; oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[2]*rlb[2] | oldv[1]*rlb[1] + newv[1]*rlf[1] | newv[2]*rlf[2]
-	__asm fxch st(1)                     ; oldv[2]*rlb[2] | oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[1]*rlb[1] + newv[1]*rlf[1] | newv[2]*rlf[2]
-	__asm faddp st(3), st                ; oldv[0]*rlb[0] + newv[0]*rlf[0] | oldv[1]*rlb[1] + newv[1]*rlf[1] | oldv[2]*rlb[2] + newv[2]*rlf[2]
-	__asm fadd dword ptr [r_lerp_move+0] ; lv0 | oldv[1]*rlb[1] + newv[1]*rlf[1] | oldv[2]*rlb[2] + newv[2]*rlf[2]
-	__asm fxch st(1)                     ; oldv[1]*rlb[1] + newv[1]*rlf[1] | lv0 | oldv[2]*rlb[2] + newv[2]*rlf[2]
-	__asm fadd dword ptr [r_lerp_move+4] ; lv1 | lv0 | oldv[2]*rlb[2] + newv[2]*rlf[2]
-	__asm fxch st(2)                     ; oldv[2]*rlb[2] + newv[2]*rlf[2] | lv0 | lv1
-	__asm fadd dword ptr [r_lerp_move+8] ; lv2 | lv0 | lv1
-	__asm fxch st(1)                     ; lv0 | lv2 | lv1
-	__asm fstp dword ptr [lerped_vert+0] ; lv2 | lv1
-	__asm fstp dword ptr [lerped_vert+8] ; lv2
-	__asm fstp dword ptr [lerped_vert+4] ; (empty)
-
-	__asm mov  eax, currententity
-	__asm mov  eax, dword ptr [eax+ENTITY_FLAGS]
-	__asm mov  ebx, RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM
-	__asm and  eax, ebx
-	__asm jz   not_powersuit
-
-	/*
-	**    lerped_vert[0] += lightnormal[0] * POWERSUIT_SCALE
-	**    lerped_vert[1] += lightnormal[1] * POWERSUIT_SCALE
-	**    lerped_vert[2] += lightnormal[2] * POWERSUIT_SCALE
-	*/
-
-	__asm xor ebx, ebx
-	__asm mov bl,  byte ptr [edi+DTRIVERTX_LNI]
-	__asm mov eax, 12
-	__asm mul ebx
-	__asm lea eax, [r_avertexnormals+eax]
-
-	__asm fld  dword ptr [eax+0]				; n[0]
-	__asm fmul PS_SCALE							; n[0] * PS
-	__asm fld  dword ptr [eax+4]				; n[1] | n[0] * PS
-	__asm fmul PS_SCALE							; n[1] * PS | n[0] * PS
-	__asm fld  dword ptr [eax+8]				; n[2] | n[1] * PS | n[0] * PS
-	__asm fmul PS_SCALE							; n[2] * PS | n[1] * PS | n[0] * PS
-	__asm fld  dword ptr [lerped_vert+0]		; lv0 | n[2] * PS | n[1] * PS | n[0] * PS
-	__asm faddp st(3), st						; n[2] * PS | n[1] * PS | n[0] * PS + lv0
-	__asm fld  dword ptr [lerped_vert+4]		; lv1 | n[2] * PS | n[1] * PS | n[0] * PS + lv0
-	__asm faddp st(2), st						; n[2] * PS | n[1] * PS + lv1 | n[0] * PS + lv0
-	__asm fadd dword ptr [lerped_vert+8]		; n[2] * PS + lv2 | n[1] * PS + lv1 | n[0] * PS + lv0
-	__asm fxch st(2)							; LV0 | LV1 | LV2
-	__asm fstp dword ptr [lerped_vert+0]		; LV1 | LV2
-	__asm fstp dword ptr [lerped_vert+4]		; LV2
-	__asm fstp dword ptr [lerped_vert+8]		; (empty)
-
-not_powersuit:
-
-	/*
-	fv->flags = 0;
-
-	fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3];
-	fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3];
-	fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3];
-	*/
-	__asm mov  eax, fv
-	__asm mov  dword ptr [eax+FINALVERT_FLAGS], 0
-
-	__asm fld  dword ptr [lerped_vert+0]           ; lv0
-	__asm fmul dword ptr [aliastransform+0]        ; lv0*at[0][0]
-	__asm fld  dword ptr [lerped_vert+4]           ; lv1 | lv0*at[0][0]
-	__asm fmul dword ptr [aliastransform+4]        ; lv1*at[0][1] | lv0*at[0][0]
-	__asm fld  dword ptr [lerped_vert+8]           ; lv2 | lv1*at[0][1] | lv0*at[0][0]
-	__asm fmul dword ptr [aliastransform+8]        ; lv2*at[0][2] | lv1*at[0][1] | lv0*at[0][0]
-	__asm fxch st(2)                               ; lv0*at[0][0] | lv1*at[0][1] | lv2*at[0][2]
-	__asm faddp st(1), st                          ; lv0*at[0][0] + lv1*at[0][1] | lv2*at[0][2]
-	__asm faddp st(1), st                          ; lv0*at[0][0] + lv1*at[0][1] + lv2*at[0][2]
-	__asm fadd  dword ptr [aliastransform+12]      ; FV.X
-
-	__asm fld  dword ptr [lerped_vert+0]           ; lv0
-	__asm fmul dword ptr [aliastransform+16]       ; lv0*at[1][0]
-	__asm fld  dword ptr [lerped_vert+4]           ; lv1 | lv0*at[1][0]
-	__asm fmul dword ptr [aliastransform+20]       ; lv1*at[1][1] | lv0*at[1][0]
-	__asm fld  dword ptr [lerped_vert+8]           ; lv2 | lv1*at[1][1] | lv0*at[1][0]
-	__asm fmul dword ptr [aliastransform+24]       ; lv2*at[1][2] | lv1*at[1][1] | lv0*at[1][0]
-	__asm fxch st(2)                               ; lv0*at[1][0] | lv1*at[1][1] | lv2*at[1][2]
-	__asm faddp st(1), st                          ; lv0*at[1][0] + lv1*at[1][1] | lv2*at[1][2]
-	__asm faddp st(1), st                          ; lv0*at[1][0] + lv1*at[1][1] + lv2*at[1][2]
-	__asm fadd dword ptr [aliastransform+28]       ; FV.Y | FV.X
-	__asm fxch st(1)                               ; FV.X | FV.Y
-	__asm fstp  dword ptr [eax+FINALVERT_X]        ; FV.Y
-	
-	__asm fld  dword ptr [lerped_vert+0]           ; lv0
-	__asm fmul dword ptr [aliastransform+32]       ; lv0*at[2][0]
-	__asm fld  dword ptr [lerped_vert+4]           ; lv1 | lv0*at[2][0]
-	__asm fmul dword ptr [aliastransform+36]       ; lv1*at[2][1] | lv0*at[2][0]
-	__asm fld  dword ptr [lerped_vert+8]           ; lv2 | lv1*at[2][1] | lv0*at[2][0]
-	__asm fmul dword ptr [aliastransform+40]       ; lv2*at[2][2] | lv1*at[2][1] | lv0*at[2][0]
-	__asm fxch st(2)                               ; lv0*at[2][0] | lv1*at[2][1] | lv2*at[2][2]
-	__asm faddp st(1), st                          ; lv0*at[2][0] + lv1*at[2][1] | lv2*at[2][2]
-	__asm faddp st(1), st                          ; lv0*at[2][0] + lv1*at[2][1] + lv2*at[2][2]
-	__asm fadd dword ptr [aliastransform+44]       ; FV.Z | FV.Y
-	__asm fxch st(1)                               ; FV.Y | FV.Z
-	__asm fstp dword ptr [eax+FINALVERT_Y]         ; FV.Z
-	__asm fstp dword ptr [eax+FINALVERT_Z]         ; (empty)
-
-	/*
-	**  lighting
-	**
-	**  plightnormal = r_avertexnormals[newv->lightnormalindex];
-	**	lightcos = DotProduct (plightnormal, r_plightvec);
-	**	temp = r_ambientlight;
-	*/
-	__asm xor ebx, ebx
-	__asm mov bl,  byte ptr [edi+DTRIVERTX_LNI]
-	__asm mov eax, 12
-	__asm mul ebx
-	__asm lea eax, [r_avertexnormals+eax]
-	__asm lea ebx, r_plightvec
-
-	__asm fld  dword ptr [eax+0]
-	__asm fmul dword ptr [ebx+0]
-	__asm fld  dword ptr [eax+4]
-	__asm fmul dword ptr [ebx+4]
-	__asm fld  dword ptr [eax+8]
-	__asm fmul dword ptr [ebx+8]
-	__asm fxch st(2)
-	__asm faddp st(1), st
-	__asm faddp st(1), st
-	__asm fstp dword ptr lightcos
-	__asm mov eax, lightcos
-	__asm mov ebx, r_ambientlight
-
-	/*
-	if (lightcos < 0)
-	{
-		temp += (int)(r_shadelight * lightcos);
-
-		// clamp; because we limited the minimum ambient and shading light, we
-		// don't have to clamp low light, just bright
-		if (temp < 0)
-			temp = 0;
-	}
-
-	fv->v[4] = temp;
-	*/
-	__asm or  eax, eax
-	__asm jns store_fv4
-
-	__asm fld   dword ptr r_shadelight
-	__asm fmul  dword ptr lightcos
-	__asm fistp dword ptr tmpint
-	__asm add   ebx, tmpint
-
-	__asm or    ebx, ebx
-	__asm jns   store_fv4
-	__asm mov   ebx, 0
-
-store_fv4:
-	__asm mov edi, fv
-	__asm mov dword ptr [edi+FINALVERT_V4], ebx
-
-	__asm mov edx, dword ptr [edi+FINALVERT_FLAGS]
-
-	/*
-	** do clip testing and projection here
-	*/
-	/*
-	if ( dest_vert->xyz[2] < ALIAS_Z_CLIP_PLANE )
-	{
-		dest_vert->flags |= ALIAS_Z_CLIP;
-	}
-	else
-	{
-		R_AliasProjectAndClipTestFinalVert( dest_vert );
-	}
-	*/
-	__asm mov eax, dword ptr [edi+FINALVERT_Z]
-	__asm and eax, eax
-	__asm js  alias_z_clip
-	__asm cmp eax, FALIAS_Z_CLIP_PLANE
-	__asm jl  alias_z_clip
-
-	/*
-	This is the code to R_AliasProjectAndClipTestFinalVert
-
-	float	zi;
-	float	x, y, z;
-
-	x = fv->xyz[0];
-	y = fv->xyz[1];
-	z = fv->xyz[2];
-	zi = 1.0 / z;
-
-	fv->v[5] = zi * s_ziscale;
-
-	fv->v[0] = (x * aliasxscale * zi) + aliasxcenter;
-	fv->v[1] = (y * aliasyscale * zi) + aliasycenter;
-	*/
-	__asm fld   one                             ; 1
-	__asm fdiv  dword ptr [edi+FINALVERT_Z]     ; zi
-
-	__asm mov   eax, dword ptr [edi+32]
-	__asm mov   eax, dword ptr [edi+64]
-
-	__asm fst   zi                              ; zi
-	__asm fmul  s_ziscale                       ; fv5
-	__asm fld   dword ptr [edi+FINALVERT_X]     ; x | fv5
-	__asm fmul  aliasxscale                     ; x * aliasxscale | fv5
-	__asm fld   dword ptr [edi+FINALVERT_Y]     ; y | x * aliasxscale | fv5
-	__asm fmul  aliasyscale                     ; y * aliasyscale | x * aliasxscale | fv5
-	__asm fxch  st(1)                           ; x * aliasxscale | y * aliasyscale | fv5
-	__asm fmul  zi                              ; x * asx * zi | y * asy | fv5
-	__asm fadd  aliasxcenter                    ; fv0 | y * asy | fv5
-	__asm fxch  st(1)                           ; y * asy | fv0 | fv5
-	__asm fmul  zi                              ; y * asy * zi | fv0 | fv5
-	__asm fadd  aliasycenter                    ; fv1 | fv0 | fv5
-	__asm fxch  st(2)                           ; fv5 | fv0 | fv1
-	__asm fistp dword ptr [edi+FINALVERT_V5]    ; fv0 | fv1
-	__asm fistp dword ptr [edi+FINALVERT_V0]    ; fv1
-	__asm fistp dword ptr [edi+FINALVERT_V1]    ; (empty)
-
-	/*
-	if (fv->v[0] < r_refdef.aliasvrect.x)
-		fv->flags |= ALIAS_LEFT_CLIP;
-	if (fv->v[1] < r_refdef.aliasvrect.y)
-		fv->flags |= ALIAS_TOP_CLIP;
-	if (fv->v[0] > r_refdef.aliasvrectright)
-		fv->flags |= ALIAS_RIGHT_CLIP;
-	if (fv->v[1] > r_refdef.aliasvrectbottom)
-		fv->flags |= ALIAS_BOTTOM_CLIP;
-	*/
-	__asm mov eax, dword ptr [edi+FINALVERT_V0]
-	__asm mov ebx, dword ptr [edi+FINALVERT_V1]
-
-	__asm cmp eax, r_refdef.aliasvrect.x
-	__asm jge ct_alias_top
-	__asm or  edx, ALIAS_LEFT_CLIP
-ct_alias_top:
-	__asm cmp ebx, r_refdef.aliasvrect.y
-	__asm jge ct_alias_right
-	__asm or edx, ALIAS_TOP_CLIP
-ct_alias_right:
-	__asm cmp eax, r_refdef.aliasvrectright
-	__asm jle ct_alias_bottom
-	__asm or edx, ALIAS_RIGHT_CLIP
-ct_alias_bottom:
-	__asm cmp ebx, r_refdef.aliasvrectbottom
-	__asm jle end_of_loop
-	__asm or  edx, ALIAS_BOTTOM_CLIP
-
-	__asm jmp end_of_loop
-
-alias_z_clip:
-	__asm or  edx, ALIAS_Z_CLIP
-
-end_of_loop:
-
-	__asm mov dword ptr [edi+FINALVERT_FLAGS], edx
-	__asm add oldv, DTRIVERTX_SIZE
-	__asm add newv, DTRIVERTX_SIZE
-	__asm add fv, FINALVERT_SIZE
-
-	__asm dec ecx
-	__asm jnz top_of_loop
-}
-#else
-void R_AliasTransformFinalVerts( int numpoints, finalvert_t *fv, dtrivertx_t *oldv, dtrivertx_t *newv )
-{
-	int i;
-
-	for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ )
-	{
-		int		temp;
-		float	lightcos, *plightnormal;
-		vec3_t  lerped_vert;
-
-		lerped_vert[0] = r_lerp_move[0] + oldv->v[0]*r_lerp_backv[0] + newv->v[0]*r_lerp_frontv[0];
-		lerped_vert[1] = r_lerp_move[1] + oldv->v[1]*r_lerp_backv[1] + newv->v[1]*r_lerp_frontv[1];
-		lerped_vert[2] = r_lerp_move[2] + oldv->v[2]*r_lerp_backv[2] + newv->v[2]*r_lerp_frontv[2];
-
-		plightnormal = r_avertexnormals[newv->lightnormalindex];
-
-		// PMM - added double damage shell
-		if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
-		{
-			lerped_vert[0] += plightnormal[0] * POWERSUIT_SCALE;
-			lerped_vert[1] += plightnormal[1] * POWERSUIT_SCALE;
-			lerped_vert[2] += plightnormal[2] * POWERSUIT_SCALE;
-		}
-
-		fv->xyz[0] = DotProduct(lerped_vert, aliastransform[0]) + aliastransform[0][3];
-		fv->xyz[1] = DotProduct(lerped_vert, aliastransform[1]) + aliastransform[1][3];
-		fv->xyz[2] = DotProduct(lerped_vert, aliastransform[2]) + aliastransform[2][3];
-
-		fv->flags = 0;
-
-		// lighting
-		lightcos = DotProduct (plightnormal, r_plightvec);
-		temp = r_ambientlight;
-
-		if (lightcos < 0)
-		{
-			temp += (int)(r_shadelight * lightcos);
-
-			// clamp; because we limited the minimum ambient and shading light, we
-			// don't have to clamp low light, just bright
-			if (temp < 0)
-				temp = 0;
-		}
-
-		fv->l = temp;
-
-		if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE )
-		{
-			fv->flags |= ALIAS_Z_CLIP;
-		}
-		else
-		{
-			R_AliasProjectAndClipTestFinalVert( fv );
-		}
-	}
-}
-
-#endif
-
-/*
-================
-R_AliasProjectAndClipTestFinalVert
-================
-*/
-void R_AliasProjectAndClipTestFinalVert( finalvert_t *fv )
-{
-	float	zi;
-	float	x, y, z;
-
-	// project points
-	x = fv->xyz[0];
-	y = fv->xyz[1];
-	z = fv->xyz[2];
-	zi = 1.0 / z;
-
-	fv->zi = zi * s_ziscale;
-
-	fv->u = (x * aliasxscale * zi) + aliasxcenter;
-	fv->v = (y * aliasyscale * zi) + aliasycenter;
-
-	if (fv->u < r_refdef.aliasvrect.x)
-		fv->flags |= ALIAS_LEFT_CLIP;
-	if (fv->v < r_refdef.aliasvrect.y)
-		fv->flags |= ALIAS_TOP_CLIP;
-	if (fv->u > r_refdef.aliasvrectright)
-		fv->flags |= ALIAS_RIGHT_CLIP;
-	if (fv->v > r_refdef.aliasvrectbottom)
-		fv->flags |= ALIAS_BOTTOM_CLIP;	
-}
-
-/*
-===============
-R_AliasSetupSkin
-===============
-*/
-static qboolean R_AliasSetupSkin (void)
-{
-	int				skinnum;
-	image_t			*pskindesc;
-
-	if (currententity->skin)
-		pskindesc = currententity->skin;
-	else
-	{
-		skinnum = currententity->skinnum;
-		if ((skinnum >= s_pmdl->num_skins) || (skinnum < 0))
-		{
-			ri.Con_Printf (PRINT_ALL, "R_AliasSetupSkin %s: no such skin # %d\n", 
-				currentmodel->name, skinnum);
-			skinnum = 0;
-		}
-
-		pskindesc = currentmodel->skins[skinnum];
-	}
-
-	if ( !pskindesc )
-		return false;
-
-	r_affinetridesc.pskin = pskindesc->pixels[0];
-	r_affinetridesc.skinwidth = pskindesc->width;
-	r_affinetridesc.skinheight = pskindesc->height;
-
-	R_PolysetUpdateTables ();		// FIXME: precalc edge lookups
-
-	return true;
-}
-
-
-/*
-================
-R_AliasSetupLighting
-
-  FIXME: put lighting into tables
-================
-*/
-void R_AliasSetupLighting (void)
-{
-	alight_t		lighting;
-	float			lightvec[3] = {-1, 0, 0};
-	vec3_t			light;
-	int				i, j;
-
-	// all components of light should be identical in software
-	if ( currententity->flags & RF_FULLBRIGHT )
-	{
-		for (i=0 ; i<3 ; i++)
-			light[i] = 1.0;
-	}
-	else
-	{
-		R_LightPoint (currententity->origin, light);
-	}
-
-	// save off light value for server to look at (BIG HACK!)
-	if ( currententity->flags & RF_WEAPONMODEL )
-		r_lightlevel->value = 150.0 * light[0];
-
-
-	if ( currententity->flags & RF_MINLIGHT )
-	{
-		for (i=0 ; i<3 ; i++)
-			if (light[i] < 0.1)
-				light[i] = 0.1;
-	}
-
-	if ( currententity->flags & RF_GLOW )
-	{	// bonus items will pulse with time
-		float	scale;
-		float	min;
-
-		scale = 0.1 * sin(r_newrefdef.time*7);
-		for (i=0 ; i<3 ; i++)
-		{
-			min = light[i] * 0.8;
-			light[i] += scale;
-			if (light[i] < min)
-				light[i] = min;
-		}
-	}
-
-	j = (light[0] + light[1] + light[2])*0.3333*255;
-
-	lighting.ambientlight = j;
-	lighting.shadelight = j;
-
-	lighting.plightvec = lightvec;
-
-// clamp lighting so it doesn't overbright as much
-	if (lighting.ambientlight > 128)
-		lighting.ambientlight = 128;
-	if (lighting.ambientlight + lighting.shadelight > 192)
-		lighting.shadelight = 192 - lighting.ambientlight;
-
-// guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have
-// to clamp off the bottom
-	r_ambientlight = lighting.ambientlight;
-
-	if (r_ambientlight < LIGHT_MIN)
-		r_ambientlight = LIGHT_MIN;
-
-	r_ambientlight = (255 - r_ambientlight) << VID_CBITS;
-
-	if (r_ambientlight < LIGHT_MIN)
-		r_ambientlight = LIGHT_MIN;
-
-	r_shadelight = lighting.shadelight;
-
-	if (r_shadelight < 0)
-		r_shadelight = 0;
-
-	r_shadelight *= VID_GRADES;
-
-// rotate the lighting vector into the model's frame of reference
-	r_plightvec[0] =  DotProduct( lighting.plightvec, s_alias_forward );
-	r_plightvec[1] = -DotProduct( lighting.plightvec, s_alias_right );
-	r_plightvec[2] =  DotProduct( lighting.plightvec, s_alias_up );
-}
-
-
-/*
-=================
-R_AliasSetupFrames
-
-=================
-*/
-void R_AliasSetupFrames( dmdl_t *pmdl )
-{
-	int thisframe = currententity->frame;
-	int lastframe = currententity->oldframe;
-
-	if ( ( thisframe >= pmdl->num_frames ) || ( thisframe < 0 ) )
-	{
-		ri.Con_Printf (PRINT_ALL, "R_AliasSetupFrames %s: no such thisframe %d\n", 
-			currentmodel->name, thisframe);
-		thisframe = 0;
-	}
-	if ( ( lastframe >= pmdl->num_frames ) || ( lastframe < 0 ) )
-	{
-		ri.Con_Printf (PRINT_ALL, "R_AliasSetupFrames %s: no such lastframe %d\n", 
-			currentmodel->name, lastframe);
-		lastframe = 0;
-	}
-
-	r_thisframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames 
-		+ thisframe * pmdl->framesize);
-
-	r_lastframe = (daliasframe_t *)((byte *)pmdl + pmdl->ofs_frames 
-		+ lastframe * pmdl->framesize);
-}
-
-/*
-** R_AliasSetUpLerpData
-**
-** Precomputes lerp coefficients used for the whole frame.
-*/
-void R_AliasSetUpLerpData( dmdl_t *pmdl, float backlerp )
-{
-	float	frontlerp;
-	vec3_t	translation, vectors[3];
-	int		i;
-
-	frontlerp = 1.0F - backlerp;
-
-	/*
-	** convert entity's angles into discrete vectors for R, U, and F
-	*/
-	AngleVectors (currententity->angles, vectors[0], vectors[1], vectors[2]);
-
-	/*
-	** translation is the vector from last position to this position
-	*/
-	VectorSubtract (currententity->oldorigin, currententity->origin, translation);
-
-	/*
-	** move should be the delta back to the previous frame * backlerp
-	*/
-	r_lerp_move[0] =  DotProduct(translation, vectors[0]);	// forward
-	r_lerp_move[1] = -DotProduct(translation, vectors[1]);	// left
-	r_lerp_move[2] =  DotProduct(translation, vectors[2]);	// up
-
-	VectorAdd( r_lerp_move, r_lastframe->translate, r_lerp_move );
-
-	for (i=0 ; i<3 ; i++)
-	{
-		r_lerp_move[i] = backlerp*r_lerp_move[i] + frontlerp * r_thisframe->translate[i];
-	}
-
-	for (i=0 ; i<3 ; i++)
-	{
-		r_lerp_frontv[i] = frontlerp * r_thisframe->scale[i];
-		r_lerp_backv[i]  = backlerp  * r_lastframe->scale[i];
-	}
-}
-
-/*
-================
-R_AliasDrawModel
-================
-*/
-void R_AliasDrawModel (void)
-{
-	extern void	(*d_pdrawspans)(void *);
-	extern void R_PolysetDrawSpans8_Opaque( void * );
-	extern void R_PolysetDrawSpans8_33( void * );
-	extern void R_PolysetDrawSpans8_66( void * );
-	extern void R_PolysetDrawSpansConstant8_33( void * );
-	extern void R_PolysetDrawSpansConstant8_66( void * );
-
-	s_pmdl = (dmdl_t *)currentmodel->extradata;
-
-	if ( r_lerpmodels->value == 0 )
-		currententity->backlerp = 0;
-
-	if ( currententity->flags & RF_WEAPONMODEL )
-	{
-		if ( r_lefthand->value == 1.0F )
-			aliasxscale = -aliasxscale;
-		else if ( r_lefthand->value == 2.0F )
-			return;
-	}
-
-	/*
-	** we have to set our frame pointers and transformations before
-	** doing any real work
-	*/
-	R_AliasSetupFrames( s_pmdl );
-	R_AliasSetUpTransform();
-
-	// see if the bounding box lets us trivially reject, also sets
-	// trivial accept status
-	if ( R_AliasCheckBBox() == BBOX_TRIVIAL_REJECT )
-	{
-		if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
-		{
-			aliasxscale = -aliasxscale;
-		}
-		return;
-	}
-
-	// set up the skin and verify it exists
-	if ( !R_AliasSetupSkin () )
-	{
-		ri.Con_Printf( PRINT_ALL, "R_AliasDrawModel %s: NULL skin found\n",
-			currentmodel->name);
-		return;
-	}
-
-	r_amodels_drawn++;
-	R_AliasSetupLighting ();
-
-	/*
-	** select the proper span routine based on translucency
-	*/
-	// PMM - added double damage shell
-	// PMM - reordered to handle blending
-	if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM) )
-	{
-		int		color;
-
-		// PMM - added double
-		color = currententity->flags & ( RF_SHELL_RED | RF_SHELL_GREEN | RF_SHELL_BLUE | RF_SHELL_DOUBLE | RF_SHELL_HALF_DAM);
-		// PMM - reordered, old code first
-/*
-		if ( color == RF_SHELL_RED )
-			r_aliasblendcolor = SHELL_RED_COLOR;
-		else if ( color == RF_SHELL_GREEN )
-			r_aliasblendcolor = SHELL_GREEN_COLOR;
-		else if ( color == RF_SHELL_BLUE )
-			r_aliasblendcolor = SHELL_BLUE_COLOR;
-		else if ( color == (RF_SHELL_RED | RF_SHELL_GREEN) )
-			r_aliasblendcolor = SHELL_RG_COLOR;
-		else if ( color == (RF_SHELL_RED | RF_SHELL_BLUE) )
-			r_aliasblendcolor = SHELL_RB_COLOR;
-		else if ( color == (RF_SHELL_BLUE | RF_SHELL_GREEN) )
-			r_aliasblendcolor = SHELL_BG_COLOR;
-		// PMM - added this .. it's yellowish
-		else if ( color == (RF_SHELL_DOUBLE) )
-			r_aliasblendcolor = SHELL_DOUBLE_COLOR;
-		else if ( color == (RF_SHELL_HALF_DAM) )
-			r_aliasblendcolor = SHELL_HALF_DAM_COLOR;
-		// pmm
-		else
-			r_aliasblendcolor = SHELL_WHITE_COLOR;
-*/
-		if ( color & RF_SHELL_RED )
-		{
-			if ( ( color & RF_SHELL_BLUE) && ( color & RF_SHELL_GREEN) )
-				r_aliasblendcolor = SHELL_WHITE_COLOR;
-			else if ( color & (RF_SHELL_BLUE | RF_SHELL_DOUBLE))
-				r_aliasblendcolor = SHELL_RB_COLOR;
-			else
-				r_aliasblendcolor = SHELL_RED_COLOR;
-		}
-		else if ( color & RF_SHELL_BLUE)
-		{
-			if ( color & RF_SHELL_DOUBLE )
-				r_aliasblendcolor = SHELL_CYAN_COLOR;
-			else
-				r_aliasblendcolor = SHELL_BLUE_COLOR;
-		}
-		else if ( color & (RF_SHELL_DOUBLE) )
-			r_aliasblendcolor = SHELL_DOUBLE_COLOR;
-		else if ( color & (RF_SHELL_HALF_DAM) )
-			r_aliasblendcolor = SHELL_HALF_DAM_COLOR;
-		else if ( color & RF_SHELL_GREEN )
-			r_aliasblendcolor = SHELL_GREEN_COLOR;
-		else
-			r_aliasblendcolor = SHELL_WHITE_COLOR;
-
-
-		if ( currententity->alpha > 0.33 )
-			d_pdrawspans = R_PolysetDrawSpansConstant8_66;
-		else
-			d_pdrawspans = R_PolysetDrawSpansConstant8_33;
-	}
-	else if ( currententity->flags & RF_TRANSLUCENT )
-	{
-		if ( currententity->alpha > 0.66 )
-			d_pdrawspans = R_PolysetDrawSpans8_Opaque;
-		else if ( currententity->alpha > 0.33 )
-			d_pdrawspans = R_PolysetDrawSpans8_66;
-		else
-			d_pdrawspans = R_PolysetDrawSpans8_33;
-	}
-	else
-	{
-		d_pdrawspans = R_PolysetDrawSpans8_Opaque;
-	}
-
-	/*
-	** compute this_frame and old_frame addresses
-	*/
-	R_AliasSetUpLerpData( s_pmdl, currententity->backlerp );
-
-	if (currententity->flags & RF_DEPTHHACK)
-		s_ziscale = (float)0x8000 * (float)0x10000 * 3.0;
-	else
-		s_ziscale = (float)0x8000 * (float)0x10000;
-
-	R_AliasPreparePoints ();
-
-	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
-	{
-		aliasxscale = -aliasxscale;
-	}
-}
-
-
-
--- a/ref_soft/r_bsp.c
+++ /dev/null
@@ -1,637 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_bsp.c
-
-#include "r_local.h"
-
-//
-// current entity info
-//
-qboolean		insubmodel;
-entity_t		*currententity;
-vec3_t			modelorg;		// modelorg is the viewpoint reletive to
-								// the currently rendering entity
-vec3_t			r_entorigin;	// the currently rendering entity in world
-								// coordinates
-
-float			entity_rotation[3][3];
-
-int				r_currentbkey;
-
-typedef enum {touchessolid, drawnode, nodrawnode} solidstate_t;
-
-#define MAX_BMODEL_VERTS	500			// 6K
-#define MAX_BMODEL_EDGES	1000		// 12K
-
-static mvertex_t	*pbverts;
-static bedge_t		*pbedges;
-static int			numbverts, numbedges;
-
-static mvertex_t	*pfrontenter, *pfrontexit;
-
-static qboolean		makeclippededge;
-
-
-//===========================================================================
-
-/*
-================
-R_EntityRotate
-================
-*/
-void R_EntityRotate (vec3_t vec)
-{
-	vec3_t	tvec;
-
-	VectorCopy (vec, tvec);
-	vec[0] = DotProduct (entity_rotation[0], tvec);
-	vec[1] = DotProduct (entity_rotation[1], tvec);
-	vec[2] = DotProduct (entity_rotation[2], tvec);
-}
-
-
-/*
-================
-R_RotateBmodel
-================
-*/
-void R_RotateBmodel (void)
-{
-	float	angle, s, c, temp1[3][3], temp2[3][3], temp3[3][3];
-
-// TODO: should use a look-up table
-// TODO: should really be stored with the entity instead of being reconstructed
-// TODO: could cache lazily, stored in the entity
-// TODO: share work with R_SetUpAliasTransform
-
-// yaw
-	angle = currententity->angles[YAW];		
-	angle = angle * M_PI*2 / 360;
-	s = sin(angle);
-	c = cos(angle);
-
-	temp1[0][0] = c;
-	temp1[0][1] = s;
-	temp1[0][2] = 0;
-	temp1[1][0] = -s;
-	temp1[1][1] = c;
-	temp1[1][2] = 0;
-	temp1[2][0] = 0;
-	temp1[2][1] = 0;
-	temp1[2][2] = 1;
-
-
-// pitch
-	angle = currententity->angles[PITCH];		
-	angle = angle * M_PI*2 / 360;
-	s = sin(angle);
-	c = cos(angle);
-
-	temp2[0][0] = c;
-	temp2[0][1] = 0;
-	temp2[0][2] = -s;
-	temp2[1][0] = 0;
-	temp2[1][1] = 1;
-	temp2[1][2] = 0;
-	temp2[2][0] = s;
-	temp2[2][1] = 0;
-	temp2[2][2] = c;
-
-	R_ConcatRotations (temp2, temp1, temp3);
-
-// roll
-	angle = currententity->angles[ROLL];		
-	angle = angle * M_PI*2 / 360;
-	s = sin(angle);
-	c = cos(angle);
-
-	temp1[0][0] = 1;
-	temp1[0][1] = 0;
-	temp1[0][2] = 0;
-	temp1[1][0] = 0;
-	temp1[1][1] = c;
-	temp1[1][2] = s;
-	temp1[2][0] = 0;
-	temp1[2][1] = -s;
-	temp1[2][2] = c;
-
-	R_ConcatRotations (temp1, temp3, entity_rotation);
-
-//
-// rotate modelorg and the transformation matrix
-//
-	R_EntityRotate (modelorg);
-	R_EntityRotate (vpn);
-	R_EntityRotate (vright);
-	R_EntityRotate (vup);
-
-	R_TransformFrustum ();
-}
-
-
-/*
-================
-R_RecursiveClipBPoly
-
-Clip a bmodel poly down the world bsp tree
-================
-*/
-void R_RecursiveClipBPoly (bedge_t *pedges, mnode_t *pnode, msurface_t *psurf)
-{
-	bedge_t		*psideedges[2], *pnextedge, *ptedge;
-	int			i, side, lastside;
-	float		dist, frac, lastdist;
-	mplane_t	*splitplane, tplane;
-	mvertex_t	*pvert, *plastvert, *ptvert;
-	mnode_t		*pn;
-	int			area;
-
-	psideedges[0] = psideedges[1] = NULL;
-
-	makeclippededge = false;
-
-// transform the BSP plane into model space
-// FIXME: cache these?
-	splitplane = pnode->plane;
-	tplane.dist = splitplane->dist -
-			DotProduct(r_entorigin, splitplane->normal);
-	tplane.normal[0] = DotProduct (entity_rotation[0], splitplane->normal);
-	tplane.normal[1] = DotProduct (entity_rotation[1], splitplane->normal);
-	tplane.normal[2] = DotProduct (entity_rotation[2], splitplane->normal);
-
-// clip edges to BSP plane
-	for ( ; pedges ; pedges = pnextedge)
-	{
-		pnextedge = pedges->pnext;
-
-	// set the status for the last point as the previous point
-	// FIXME: cache this stuff somehow?
-		plastvert = pedges->v[0];
-		lastdist = DotProduct (plastvert->position, tplane.normal) -
-				   tplane.dist;
-
-		if (lastdist > 0)
-			lastside = 0;
-		else
-			lastside = 1;
-
-		pvert = pedges->v[1];
-
-		dist = DotProduct (pvert->position, tplane.normal) - tplane.dist;
-
-		if (dist > 0)
-			side = 0;
-		else
-			side = 1;
-
-		if (side != lastside)
-		{
-		// clipped
-			if (numbverts >= MAX_BMODEL_VERTS)
-				return;
-
-		// generate the clipped vertex
-			frac = lastdist / (lastdist - dist);
-			ptvert = &pbverts[numbverts++];
-			ptvert->position[0] = plastvert->position[0] +
-					frac * (pvert->position[0] -
-					plastvert->position[0]);
-			ptvert->position[1] = plastvert->position[1] +
-					frac * (pvert->position[1] -
-					plastvert->position[1]);
-			ptvert->position[2] = plastvert->position[2] +
-					frac * (pvert->position[2] -
-					plastvert->position[2]);
-
-		// split into two edges, one on each side, and remember entering
-		// and exiting points
-		// FIXME: share the clip edge by having a winding direction flag?
-			if (numbedges >= (MAX_BMODEL_EDGES - 1))
-			{
-				ri.Con_Printf (PRINT_ALL,"Out of edges for bmodel\n");
-				return;
-			}
-
-			ptedge = &pbedges[numbedges];
-			ptedge->pnext = psideedges[lastside];
-			psideedges[lastside] = ptedge;
-			ptedge->v[0] = plastvert;
-			ptedge->v[1] = ptvert;
-
-			ptedge = &pbedges[numbedges + 1];
-			ptedge->pnext = psideedges[side];
-			psideedges[side] = ptedge;
-			ptedge->v[0] = ptvert;
-			ptedge->v[1] = pvert;
-
-			numbedges += 2;
-
-			if (side == 0)
-			{
-			// entering for front, exiting for back
-				pfrontenter = ptvert;
-				makeclippededge = true;
-			}
-			else
-			{
-				pfrontexit = ptvert;
-				makeclippededge = true;
-			}
-		}
-		else
-		{
-		// add the edge to the appropriate side
-			pedges->pnext = psideedges[side];
-			psideedges[side] = pedges;
-		}
-	}
-
-// if anything was clipped, reconstitute and add the edges along the clip
-// plane to both sides (but in opposite directions)
-	if (makeclippededge)
-	{
-		if (numbedges >= (MAX_BMODEL_EDGES - 2))
-		{
-			ri.Con_Printf (PRINT_ALL,"Out of edges for bmodel\n");
-			return;
-		}
-
-		ptedge = &pbedges[numbedges];
-		ptedge->pnext = psideedges[0];
-		psideedges[0] = ptedge;
-		ptedge->v[0] = pfrontexit;
-		ptedge->v[1] = pfrontenter;
-
-		ptedge = &pbedges[numbedges + 1];
-		ptedge->pnext = psideedges[1];
-		psideedges[1] = ptedge;
-		ptedge->v[0] = pfrontenter;
-		ptedge->v[1] = pfrontexit;
-
-		numbedges += 2;
-	}
-
-// draw or recurse further
-	for (i=0 ; i<2 ; i++)
-	{
-		if (psideedges[i])
-		{
-		// draw if we've reached a non-solid leaf, done if all that's left is a
-		// solid leaf, and continue down the tree if it's not a leaf
-			pn = pnode->children[i];
-
-		// we're done with this branch if the node or leaf isn't in the PVS
-			if (pn->visframe == r_visframecount)
-			{
-				if (pn->contents != CONTENTS_NODE)
-				{
-					if (pn->contents != CONTENTS_SOLID)
-					{
-						if (r_newrefdef.areabits)
-						{
-							area = ((mleaf_t *)pn)->area;
-							if (! (r_newrefdef.areabits[area>>3] & (1<<(area&7)) ) )
-								continue;		// not visible
-						}
-
-						r_currentbkey = ((mleaf_t *)pn)->key;
-						R_RenderBmodelFace (psideedges[i], psurf);
-					}
-				}
-				else
-				{
-					R_RecursiveClipBPoly (psideedges[i], pnode->children[i],
-									  psurf);
-				}
-			}
-		}
-	}
-}
-
-
-/*
-================
-R_DrawSolidClippedSubmodelPolygons
-
-Bmodel crosses multiple leafs
-================
-*/
-void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode)
-{
-	int			i, j, lindex;
-	vec_t		dot;
-	msurface_t	*psurf;
-	int			numsurfaces;
-	mplane_t	*pplane;
-	mvertex_t	bverts[MAX_BMODEL_VERTS];
-	bedge_t		bedges[MAX_BMODEL_EDGES], *pbedge;
-	medge_t		*pedge, *pedges;
-
-// FIXME: use bounding-box-based frustum clipping info?
-
-	psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
-	numsurfaces = pmodel->nummodelsurfaces;
-	pedges = pmodel->edges;
-
-	for (i=0 ; i<numsurfaces ; i++, psurf++)
-	{
-	// find which side of the node we are on
-		pplane = psurf->plane;
-
-		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
-
-	// draw the polygon
-		if (( !(psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
-			((psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
-			continue;
-
-	// FIXME: use bounding-box-based frustum clipping info?
-
-	// copy the edges to bedges, flipping if necessary so always
-	// clockwise winding
-	// FIXME: if edges and vertices get caches, these assignments must move
-	// outside the loop, and overflow checking must be done here
-		pbverts = bverts;
-		pbedges = bedges;
-		numbverts = numbedges = 0;
-		pbedge = &bedges[numbedges];
-		numbedges += psurf->numedges;
-
-		for (j=0 ; j<psurf->numedges ; j++)
-		{
-		   lindex = pmodel->surfedges[psurf->firstedge+j];
-
-			if (lindex > 0)
-			{
-				pedge = &pedges[lindex];
-				pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[0]];
-				pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[1]];
-			}
-			else
-			{
-				lindex = -lindex;
-				pedge = &pedges[lindex];
-				pbedge[j].v[0] = &r_pcurrentvertbase[pedge->v[1]];
-				pbedge[j].v[1] = &r_pcurrentvertbase[pedge->v[0]];
-			}
-
-			pbedge[j].pnext = &pbedge[j+1];
-		}
-
-		pbedge[j-1].pnext = NULL;	// mark end of edges
-
-		if ( !( psurf->texinfo->flags & ( SURF_TRANS66 | SURF_TRANS33 ) ) )
-			R_RecursiveClipBPoly (pbedge, topnode, psurf);
-		else
-			R_RenderBmodelFace( pbedge, psurf );
-	}
-}
-
-
-/*
-================
-R_DrawSubmodelPolygons
-
-All in one leaf
-================
-*/
-void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode)
-{
-	int			i;
-	vec_t		dot;
-	msurface_t	*psurf;
-	int			numsurfaces;
-	mplane_t	*pplane;
-
-// FIXME: use bounding-box-based frustum clipping info?
-
-	psurf = &pmodel->surfaces[pmodel->firstmodelsurface];
-	numsurfaces = pmodel->nummodelsurfaces;
-
-	for (i=0 ; i<numsurfaces ; i++, psurf++)
-	{
-	// find which side of the node we are on
-		pplane = psurf->plane;
-
-		dot = DotProduct (modelorg, pplane->normal) - pplane->dist;
-
-	// draw the polygon
-		if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
-			(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON)))
-		{
-			r_currentkey = ((mleaf_t *)topnode)->key;
-
-		// FIXME: use bounding-box-based frustum clipping info?
-			R_RenderFace (psurf, clipflags);
-		}
-	}
-}
-
-
-int c_drawnode;
-
-/*
-================
-R_RecursiveWorldNode
-================
-*/
-void R_RecursiveWorldNode (mnode_t *node, int clipflags)
-{
-	int			i, c, side, *pindex;
-	vec3_t		acceptpt, rejectpt;
-	mplane_t	*plane;
-	msurface_t	*surf, **mark;
-	float		d, dot;
-	mleaf_t		*pleaf;
-
-	if (node->contents == CONTENTS_SOLID)
-		return;		// solid
-
-	if (node->visframe != r_visframecount)
-		return;
-
-// cull the clipping planes if not trivial accept
-// FIXME: the compiler is doing a lousy job of optimizing here; it could be
-//  twice as fast in ASM
-	if (clipflags)
-	{
-		for (i=0 ; i<4 ; i++)
-		{
-			if (! (clipflags & (1<<i)) )
-				continue;	// don't need to clip against it
-
-		// generate accept and reject points
-		// FIXME: do with fast look-ups or integer tests based on the sign bit
-		// of the floating point values
-
-			pindex = pfrustum_indexes[i];
-
-			rejectpt[0] = (float)node->minmaxs[pindex[0]];
-			rejectpt[1] = (float)node->minmaxs[pindex[1]];
-			rejectpt[2] = (float)node->minmaxs[pindex[2]];
-			
-			d = DotProduct (rejectpt, view_clipplanes[i].normal);
-			d -= view_clipplanes[i].dist;
-			if (d <= 0)
-				return;
-			acceptpt[0] = (float)node->minmaxs[pindex[3+0]];
-			acceptpt[1] = (float)node->minmaxs[pindex[3+1]];
-			acceptpt[2] = (float)node->minmaxs[pindex[3+2]];
-
-			d = DotProduct (acceptpt, view_clipplanes[i].normal);
-			d -= view_clipplanes[i].dist;
-
-			if (d >= 0)
-				clipflags &= ~(1<<i);	// node is entirely on screen
-		}
-	}
-
-c_drawnode++;
-
-// if a leaf node, draw stuff
-	if (node->contents != -1)
-	{
-		pleaf = (mleaf_t *)node;
-
-		// check for door connected areas
-		if (r_newrefdef.areabits)
-		{
-			if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) )
-				return;		// not visible
-		}
-
-		mark = pleaf->firstmarksurface;
-		c = pleaf->nummarksurfaces;
-
-		if (c)
-		{
-			do
-			{
-				(*mark)->visframe = r_framecount;
-				mark++;
-			} while (--c);
-		}
-
-		pleaf->key = r_currentkey;
-		r_currentkey++;		// all bmodels in a leaf share the same key
-	}
-	else
-	{
-	// node is just a decision point, so go down the apropriate sides
-
-	// find which side of the node we are on
-		plane = node->plane;
-
-		switch (plane->type)
-		{
-		case PLANE_X:
-			dot = modelorg[0] - plane->dist;
-			break;
-		case PLANE_Y:
-			dot = modelorg[1] - plane->dist;
-			break;
-		case PLANE_Z:
-			dot = modelorg[2] - plane->dist;
-			break;
-		default:
-			dot = DotProduct (modelorg, plane->normal) - plane->dist;
-			break;
-		}
-	
-		if (dot >= 0)
-			side = 0;
-		else
-			side = 1;
-
-	// recurse down the children, front side first
-		R_RecursiveWorldNode (node->children[side], clipflags);
-
-	// draw stuff
-		c = node->numsurfaces;
-
-		if (c)
-		{
-			surf = r_worldmodel->surfaces + node->firstsurface;
-
-			if (dot < -BACKFACE_EPSILON)
-			{
-				do
-				{
-					if ((surf->flags & SURF_PLANEBACK) &&
-						(surf->visframe == r_framecount))
-					{
-						R_RenderFace (surf, clipflags);
-					}
-
-					surf++;
-				} while (--c);
-			}
-			else if (dot > BACKFACE_EPSILON)
-			{
-				do
-				{
-					if (!(surf->flags & SURF_PLANEBACK) &&
-						(surf->visframe == r_framecount))
-					{
-						R_RenderFace (surf, clipflags);
-					}
-
-					surf++;
-				} while (--c);
-			}
-
-		// all surfaces on the same node share the same sequence number
-			r_currentkey++;
-		}
-
-	// recurse down the back side
-		R_RecursiveWorldNode (node->children[!side], clipflags);
-	}
-}
-
-
-
-/*
-================
-R_RenderWorld
-================
-*/
-void R_RenderWorld (void)
-{
-
-	if (!r_drawworld->value)
-		return;
-	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
-		return;
-
-	c_drawnode=0;
-
-	// auto cycle the world frame for texture animation
-	r_worldentity.frame = (int)(r_newrefdef.time*2);
-	currententity = &r_worldentity;
-
-	VectorCopy (r_origin, modelorg);
-	currentmodel = r_worldmodel;
-	r_pcurrentvertbase = currentmodel->vertexes;
-
-	R_RecursiveWorldNode (currentmodel->nodes, 15);
-}
-
-
--- a/ref_soft/r_draw.c
+++ /dev/null
@@ -1,445 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-// draw.c
-
-#include "r_local.h"
-
-
-image_t		*draw_chars;				// 8*8 graphic characters
-
-//=============================================================================
-
-/*
-================
-Draw_FindPic
-================
-*/
-image_t *Draw_FindPic (char *name)
-{
-	image_t	*image;
-	char	fullname[MAX_QPATH];
-
-	if (name[0] != '/' && name[0] != '\\')
-	{
-		Com_sprintf (fullname, sizeof(fullname), "pics/%s.pcx", name);
-		image = R_FindImage (fullname, it_pic);
-	}
-	else
-		image = R_FindImage (name+1, it_pic);
-
-	return image;
-}
-
-
-
-/*
-===============
-Draw_InitLocal
-===============
-*/
-void Draw_InitLocal (void)
-{
-	draw_chars = Draw_FindPic ("conchars");
-}
-
-
-
-/*
-================
-Draw_Char
-
-Draws one 8*8 graphics character
-It can be clipped to the top of the screen to allow the console to be
-smoothly scrolled off.
-================
-*/
-void Draw_Char (int x, int y, int num)
-{
-	byte			*dest;
-	byte			*source;
-	int				drawline;	
-	int				row, col;
-
-	num &= 255;
-
-	if (num == 32 || num == 32+128)
-		return;
-
-	if (y <= -8)
-		return;			// totally off screen
-
-//	if ( ( y + 8 ) >= vid.height )
-	if ( ( y + 8 ) > vid.height )		// PGM - status text was missing in sw...
-		return;
-
-#ifdef PARANOID
-	if (y > vid.height - 8 || x < 0 || x > vid.width - 8)
-		ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: (%i, %i)", x, y);
-	if (num < 0 || num > 255)
-		ri.Sys_Error (ERR_FATAL,"Con_DrawCharacter: char %i", num);
-#endif
-
-	row = num>>4;
-	col = num&15;
-	source = draw_chars->pixels[0] + (row<<10) + (col<<3);
-
-	if (y < 0)
-	{	// clipped
-		drawline = 8 + y;
-		source -= 128*y;
-		y = 0;
-	}
-	else
-		drawline = 8;
-
-
-	dest = vid.buffer + y*vid.rowbytes + x;
-
-	while (drawline--)
-	{
-		if (source[0] != TRANSPARENT_COLOR)
-			dest[0] = source[0];
-		if (source[1] != TRANSPARENT_COLOR)
-			dest[1] = source[1];
-		if (source[2] != TRANSPARENT_COLOR)
-			dest[2] = source[2];
-		if (source[3] != TRANSPARENT_COLOR)
-			dest[3] = source[3];
-		if (source[4] != TRANSPARENT_COLOR)
-			dest[4] = source[4];
-		if (source[5] != TRANSPARENT_COLOR)
-			dest[5] = source[5];
-		if (source[6] != TRANSPARENT_COLOR)
-			dest[6] = source[6];
-		if (source[7] != TRANSPARENT_COLOR)
-			dest[7] = source[7];
-		source += 128;
-		dest += vid.rowbytes;
-	}
-}
-
-/*
-=============
-Draw_GetPicSize
-=============
-*/
-void Draw_GetPicSize (int *w, int *h, char *pic)
-{
-	image_t *gl;
-
-	gl = Draw_FindPic (pic);
-	if (!gl)
-	{
-		*w = *h = -1;
-		return;
-	}
-	*w = gl->width;
-	*h = gl->height;
-}
-
-/*
-=============
-Draw_StretchPicImplementation
-=============
-*/
-void Draw_StretchPicImplementation (int x, int y, int w, int h, image_t	*pic)
-{
-	byte			*dest, *source;
-	int				v, u, sv;
-	int				height;
-	int				f, fstep;
-	int				skip;
-
-	if ((x < 0) ||
-		(x + w > vid.width) ||
-		(y + h > vid.height))
-	{
-		ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
-	}
-
-	height = h;
-	if (y < 0)
-	{
-		skip = -y;
-		height += y;
-		y = 0;
-	}
-	else
-		skip = 0;
-
-	dest = vid.buffer + y * vid.rowbytes + x;
-
-	for (v=0 ; v<height ; v++, dest += vid.rowbytes)
-	{
-		sv = (skip + v)*pic->height/h;
-		source = pic->pixels[0] + sv*pic->width;
-		if (w == pic->width)
-			memcpy (dest, source, w);
-		else
-		{
-			f = 0;
-			fstep = pic->width*0x10000/w;
-			for (u=0 ; u<w ; u+=4)
-			{
-				dest[u] = source[f>>16];
-				f += fstep;
-				dest[u+1] = source[f>>16];
-				f += fstep;
-				dest[u+2] = source[f>>16];
-				f += fstep;
-				dest[u+3] = source[f>>16];
-				f += fstep;
-			}
-		}
-	}
-}
-
-/*
-=============
-Draw_StretchPic
-=============
-*/
-void Draw_StretchPic (int x, int y, int w, int h, char *name)
-{
-	image_t	*pic;
-
-	pic = Draw_FindPic (name);
-	if (!pic)
-	{
-		ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
-		return;
-	}
-	Draw_StretchPicImplementation (x, y, w, h, pic);
-}
-
-/*
-=============
-Draw_StretchRaw
-=============
-*/
-void Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data)
-{
-	image_t	pic;
-
-	pic.pixels[0] = data;
-	pic.width = cols;
-	pic.height = rows;
-	Draw_StretchPicImplementation (x, y, w, h, &pic);
-}
-
-/*
-=============
-Draw_Pic
-=============
-*/
-void Draw_Pic (int x, int y, char *name)
-{
-	image_t			*pic;
-	byte			*dest, *source;
-	int				v, u;
-	int				tbyte;
-	int				height;
-
-	pic = Draw_FindPic (name);
-	if (!pic)
-	{
-		ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
-		return;
-	}
-
-	if ((x < 0) ||
-		(x + pic->width > vid.width) ||
-		(y + pic->height > vid.height))
-		return;	//	ri.Sys_Error (ERR_FATAL,"Draw_Pic: bad coordinates");
-
-	height = pic->height;
-	source = pic->pixels[0];
-	if (y < 0)
-	{
-		height += y;
-		source += pic->width*-y;
-		y = 0;
-	}
-
-	dest = vid.buffer + y * vid.rowbytes + x;
-
-	if (!pic->transparent)
-	{
-		for (v=0 ; v<height ; v++)
-		{
-			memcpy (dest, source, pic->width);
-			dest += vid.rowbytes;
-			source += pic->width;
-		}
-	}
-	else
-	{
-		if (pic->width & 7)
-		{	// general
-			for (v=0 ; v<height ; v++)
-			{
-				for (u=0 ; u<pic->width ; u++)
-					if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
-						dest[u] = tbyte;
-
-				dest += vid.rowbytes;
-				source += pic->width;
-			}
-		}
-		else
-		{	// unwound
-			for (v=0 ; v<height ; v++)
-			{
-				for (u=0 ; u<pic->width ; u+=8)
-				{
-					if ( (tbyte=source[u]) != TRANSPARENT_COLOR)
-						dest[u] = tbyte;
-					if ( (tbyte=source[u+1]) != TRANSPARENT_COLOR)
-						dest[u+1] = tbyte;
-					if ( (tbyte=source[u+2]) != TRANSPARENT_COLOR)
-						dest[u+2] = tbyte;
-					if ( (tbyte=source[u+3]) != TRANSPARENT_COLOR)
-						dest[u+3] = tbyte;
-					if ( (tbyte=source[u+4]) != TRANSPARENT_COLOR)
-						dest[u+4] = tbyte;
-					if ( (tbyte=source[u+5]) != TRANSPARENT_COLOR)
-						dest[u+5] = tbyte;
-					if ( (tbyte=source[u+6]) != TRANSPARENT_COLOR)
-						dest[u+6] = tbyte;
-					if ( (tbyte=source[u+7]) != TRANSPARENT_COLOR)
-						dest[u+7] = tbyte;
-				}
-				dest += vid.rowbytes;
-				source += pic->width;
-			}
-		}
-	}
-}
-
-/*
-=============
-Draw_TileClear
-
-This repeats a 64*64 tile graphic to fill the screen around a sized down
-refresh window.
-=============
-*/
-void Draw_TileClear (int x, int y, int w, int h, char *name)
-{
-	int			i, j;
-	byte		*psrc;
-	byte		*pdest;
-	image_t		*pic;
-	int			x2;
-
-	if (x < 0)
-	{
-		w += x;
-		x = 0;
-	}
-	if (y < 0)
-	{
-		h += y;
-		y = 0;
-	}
-	if (x + w > vid.width)
-		w = vid.width - x;
-	if (y + h > vid.height)
-		h = vid.height - y;
-	if (w <= 0 || h <= 0)
-		return;
-
-	pic = Draw_FindPic (name);
-	if (!pic)
-	{
-		ri.Con_Printf (PRINT_ALL, "Can't find pic: %s\n", name);
-		return;
-	}
-	x2 = x + w;
-	pdest = vid.buffer + y*vid.rowbytes;
-	for (i=0 ; i<h ; i++, pdest += vid.rowbytes)
-	{
-		psrc = pic->pixels[0] + pic->width * ((i+y)&63);
-		for (j=x ; j<x2 ; j++)
-			pdest[j] = psrc[j&63];
-	}
-}
-
-
-/*
-=============
-Draw_Fill
-
-Fills a box of pixels with a single color
-=============
-*/
-void Draw_Fill (int x, int y, int w, int h, int c)
-{
-	byte			*dest;
-	int				u, v;
-
-	if (x+w > vid.width)
-		w = vid.width - x;
-	if (y+h > vid.height)
-		h = vid.height - y;
-	if (x < 0)
-	{
-		w += x;
-		x = 0;
-	}
-	if (y < 0)
-	{
-		h += y;
-		y = 0;
-	}
-	if (w < 0 || h < 0)
-		return;
-	dest = vid.buffer + y*vid.rowbytes + x;
-	for (v=0 ; v<h ; v++, dest += vid.rowbytes)
-		for (u=0 ; u<w ; u++)
-			dest[u] = c;
-}
-//=============================================================================
-
-/*
-================
-Draw_FadeScreen
-
-================
-*/
-void Draw_FadeScreen (void)
-{
-	int			x,y;
-	byte		*pbuf;
-	int	t;
-
-	for (y=0 ; y<vid.height ; y++)
-	{
-		pbuf = (byte *)(vid.buffer + vid.rowbytes*y);
-		t = (y & 1) << 1;
-
-		for (x=0 ; x<vid.width ; x++)
-		{
-			if ((x & 3) != t)
-				pbuf[x] = 0;
-		}
-	}
-}
--- a/ref_soft/r_edge.c
+++ /dev/null
@@ -1,1125 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_edge.c
-
-#include "r_local.h"
-
-#ifndef id386
-void R_SurfacePatch (void)
-{
-}
-
-void R_EdgeCodeStart (void)
-{
-}
-
-void R_EdgeCodeEnd (void)
-{
-}
-#endif
-
-
-#if 0
-the complex cases add new polys on most lines, so dont optimize for keeping them the same
-have multiple free span lists to try to get better coherence?
-low depth complexity -- 1 to 3 or so
-
-have a sentinal at both ends?
-#endif
-
-
-edge_t	*auxedges;
-edge_t	*r_edges, *edge_p, *edge_max;
-
-surf_t	*surfaces, *surface_p, *surf_max;
-
-// surfaces are generated in back to front order by the bsp, so if a surf
-// pointer is greater than another one, it should be drawn in front
-// surfaces[1] is the background, and is used as the active surface stack
-
-edge_t	*newedges[MAXHEIGHT];
-edge_t	*removeedges[MAXHEIGHT];
-
-espan_t	*span_p, *max_span_p;
-
-int		r_currentkey;
-
-int	current_iv;
-
-int	edge_head_u_shift20, edge_tail_u_shift20;
-
-static void (*pdrawfunc)(void);
-
-edge_t	edge_head;
-edge_t	edge_tail;
-edge_t	edge_aftertail;
-edge_t	edge_sentinel;
-
-float	fv;
-
-static int	miplevel;
-
-float		scale_for_mip;
-int			ubasestep, errorterm, erroradjustup, erroradjustdown;
-
-// FIXME: should go away
-extern void			R_RotateBmodel (void);
-extern void			R_TransformFrustum (void);
-
-
-
-void R_GenerateSpans (void);
-void R_GenerateSpansBackward (void);
-
-void R_LeadingEdge (edge_t *edge);
-void R_LeadingEdgeBackwards (edge_t *edge);
-void R_TrailingEdge (surf_t *surf, edge_t *edge);
-
-
-/*
-===============================================================================
-
-EDGE SCANNING
-
-===============================================================================
-*/
-
-/*
-==============
-R_BeginEdgeFrame
-==============
-*/
-void R_BeginEdgeFrame (void)
-{
-	int		v;
-
-	edge_p = r_edges;
-	edge_max = &r_edges[r_numallocatededges];
-
-	surface_p = &surfaces[2];	// background is surface 1,
-								//  surface 0 is a dummy
-	surfaces[1].spans = NULL;	// no background spans yet
-	surfaces[1].flags = SURF_DRAWBACKGROUND;
-
-// put the background behind everything in the world
-	if (sw_draworder->value)
-	{
-		pdrawfunc = R_GenerateSpansBackward;
-		surfaces[1].key = 0;
-		r_currentkey = 1;
-	}
-	else
-	{
-		pdrawfunc = R_GenerateSpans;
-		surfaces[1].key = 0x7FFfFFFF;
-		r_currentkey = 0;
-	}
-
-// FIXME: set with memset
-	for (v=r_refdef.vrect.y ; v<r_refdef.vrectbottom ; v++)
-	{
-		newedges[v] = removeedges[v] = NULL;
-	}
-}
-
-
-#if	!id386
-
-/*
-==============
-R_InsertNewEdges
-
-Adds the edges in the linked list edgestoadd, adding them to the edges in the
-linked list edgelist.  edgestoadd is assumed to be sorted on u, and non-empty (this is actually newedges[v]).  edgelist is assumed to be sorted on u, with a
-sentinel at the end (actually, this is the active edge table starting at
-edge_head.next).
-==============
-*/
-void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist)
-{
-	edge_t	*next_edge;
-
-	do
-	{
-		next_edge = edgestoadd->next;
-edgesearch:
-		if (edgelist->u >= edgestoadd->u)
-			goto addedge;
-		edgelist=edgelist->next;
-		if (edgelist->u >= edgestoadd->u)
-			goto addedge;
-		edgelist=edgelist->next;
-		if (edgelist->u >= edgestoadd->u)
-			goto addedge;
-		edgelist=edgelist->next;
-		if (edgelist->u >= edgestoadd->u)
-			goto addedge;
-		edgelist=edgelist->next;
-		goto edgesearch;
-
-	// insert edgestoadd before edgelist
-addedge:
-		edgestoadd->next = edgelist;
-		edgestoadd->prev = edgelist->prev;
-		edgelist->prev->next = edgestoadd;
-		edgelist->prev = edgestoadd;
-	} while ((edgestoadd = next_edge) != NULL);
-}
-
-#endif	// !id386
-	
-
-#if	!id386
-
-/*
-==============
-R_RemoveEdges
-==============
-*/
-void R_RemoveEdges (edge_t *pedge)
-{
-
-	do
-	{
-		pedge->next->prev = pedge->prev;
-		pedge->prev->next = pedge->next;
-	} while ((pedge = pedge->nextremove) != NULL);
-}
-
-#endif	// !id386
-
-
-#if	!id386
-
-/*
-==============
-R_StepActiveU
-==============
-*/
-void R_StepActiveU (edge_t *pedge)
-{
-	edge_t		*pnext_edge, *pwedge;
-
-	while (1)
-	{
-nextedge:
-		pedge->u += pedge->u_step;
-		if (pedge->u < pedge->prev->u)
-			goto pushback;
-		pedge = pedge->next;
-			
-		pedge->u += pedge->u_step;
-		if (pedge->u < pedge->prev->u)
-			goto pushback;
-		pedge = pedge->next;
-			
-		pedge->u += pedge->u_step;
-		if (pedge->u < pedge->prev->u)
-			goto pushback;
-		pedge = pedge->next;
-			
-		pedge->u += pedge->u_step;
-		if (pedge->u < pedge->prev->u)
-			goto pushback;
-		pedge = pedge->next;
-			
-		goto nextedge;		
-		
-pushback:
-		if (pedge == &edge_aftertail)
-			return;
-			
-	// push it back to keep it sorted		
-		pnext_edge = pedge->next;
-
-	// pull the edge out of the edge list
-		pedge->next->prev = pedge->prev;
-		pedge->prev->next = pedge->next;
-
-	// find out where the edge goes in the edge list
-		pwedge = pedge->prev->prev;
-
-		while (pwedge->u > pedge->u)
-		{
-			pwedge = pwedge->prev;
-		}
-
-	// put the edge back into the edge list
-		pedge->next = pwedge->next;
-		pedge->prev = pwedge;
-		pedge->next->prev = pedge;
-		pwedge->next = pedge;
-
-		pedge = pnext_edge;
-		if (pedge == &edge_tail)
-			return;
-	}
-}
-
-#endif	// !id386
-
-
-/*
-==============
-R_CleanupSpan
-==============
-*/
-void R_CleanupSpan (void)
-{
-	surf_t	*surf;
-	int		iu;
-	espan_t	*span;
-
-// now that we've reached the right edge of the screen, we're done with any
-// unfinished surfaces, so emit a span for whatever's on top
-	surf = surfaces[1].next;
-	iu = edge_tail_u_shift20;
-	if (iu > surf->last_u)
-	{
-		span = span_p++;
-		span->u = surf->last_u;
-		span->count = iu - span->u;
-		span->v = current_iv;
-		span->pnext = surf->spans;
-		surf->spans = span;
-	}
-
-// reset spanstate for all surfaces in the surface stack
-	do
-	{
-		surf->spanstate = 0;
-		surf = surf->next;
-	} while (surf != &surfaces[1]);
-}
-
-
-/*
-==============
-R_LeadingEdgeBackwards
-==============
-*/
-void R_LeadingEdgeBackwards (edge_t *edge)
-{
-	espan_t			*span;
-	surf_t			*surf, *surf2;
-	int				iu;
-
-// it's adding a new surface in, so find the correct place
-	surf = &surfaces[edge->surfs[1]];
-
-// don't start a span if this is an inverted span, with the end
-// edge preceding the start edge (that is, we've already seen the
-// end edge)
-	if (++surf->spanstate == 1)
-	{
-		surf2 = surfaces[1].next;
-
-		if (surf->key > surf2->key)
-			goto newtop;
-
-	// if it's two surfaces on the same plane, the one that's already
-	// active is in front, so keep going unless it's a bmodel
-		if (surf->insubmodel && (surf->key == surf2->key))
-		{
-		// must be two bmodels in the same leaf; don't care, because they'll
-		// never be farthest anyway
-			goto newtop;
-		}
-
-continue_search:
-
-		do
-		{
-			surf2 = surf2->next;
-		} while (surf->key < surf2->key);
-
-		if (surf->key == surf2->key)
-		{
-		// if it's two surfaces on the same plane, the one that's already
-		// active is in front, so keep going unless it's a bmodel
-			if (!surf->insubmodel)
-				goto continue_search;
-
-		// must be two bmodels in the same leaf; don't care which is really
-		// in front, because they'll never be farthest anyway
-		}
-
-		goto gotposition;
-
-newtop:
-	// emit a span (obscures current top)
-		iu = edge->u >> 20;
-
-		if (iu > surf2->last_u)
-		{
-			span = span_p++;
-			span->u = surf2->last_u;
-			span->count = iu - span->u;
-			span->v = current_iv;
-			span->pnext = surf2->spans;
-			surf2->spans = span;
-		}
-
-		// set last_u on the new span
-		surf->last_u = iu;
-				
-gotposition:
-	// insert before surf2
-		surf->next = surf2;
-		surf->prev = surf2->prev;
-		surf2->prev->next = surf;
-		surf2->prev = surf;
-	}
-}
-
-
-/*
-==============
-R_TrailingEdge
-==============
-*/
-void R_TrailingEdge (surf_t *surf, edge_t *edge)
-{
-	espan_t			*span;
-	int				iu;
-
-// don't generate a span if this is an inverted span, with the end
-// edge preceding the start edge (that is, we haven't seen the
-// start edge yet)
-	if (--surf->spanstate == 0)
-	{
-		if (surf == surfaces[1].next)
-		{
-		// emit a span (current top going away)
-			iu = edge->u >> 20;
-			if (iu > surf->last_u)
-			{
-				span = span_p++;
-				span->u = surf->last_u;
-				span->count = iu - span->u;
-				span->v = current_iv;
-				span->pnext = surf->spans;
-				surf->spans = span;
-			}
-
-		// set last_u on the surface below
-			surf->next->last_u = iu;
-		}
-
-		surf->prev->next = surf->next;
-		surf->next->prev = surf->prev;
-	}
-}
-
-
-#if	!id386
-
-/*
-==============
-R_LeadingEdge
-==============
-*/
-void R_LeadingEdge (edge_t *edge)
-{
-	espan_t			*span;
-	surf_t			*surf, *surf2;
-	int				iu;
-	float			fu, newzi, testzi, newzitop, newzibottom;
-
-	if (edge->surfs[1])
-	{
-	// it's adding a new surface in, so find the correct place
-		surf = &surfaces[edge->surfs[1]];
-
-	// don't start a span if this is an inverted span, with the end
-	// edge preceding the start edge (that is, we've already seen the
-	// end edge)
-		if (++surf->spanstate == 1)
-		{
-			surf2 = surfaces[1].next;
-
-			if (surf->key < surf2->key)
-				goto newtop;
-
-		// if it's two surfaces on the same plane, the one that's already
-		// active is in front, so keep going unless it's a bmodel
-			if (surf->insubmodel && (surf->key == surf2->key))
-			{
-			// must be two bmodels in the same leaf; sort on 1/z
-				fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
-				newzi = surf->d_ziorigin + fv*surf->d_zistepv +
-						fu*surf->d_zistepu;
-				newzibottom = newzi * 0.99;
-
-				testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
-						fu*surf2->d_zistepu;
-
-				if (newzibottom >= testzi)
-				{
-					goto newtop;
-				}
-
-				newzitop = newzi * 1.01;
-				if (newzitop >= testzi)
-				{
-					if (surf->d_zistepu >= surf2->d_zistepu)
-					{
-						goto newtop;
-					}
-				}
-			}
-
-continue_search:
-
-			do
-			{
-				surf2 = surf2->next;
-			} while (surf->key > surf2->key);
-
-			if (surf->key == surf2->key)
-			{
-			// if it's two surfaces on the same plane, the one that's already
-			// active is in front, so keep going unless it's a bmodel
-				if (!surf->insubmodel)
-					goto continue_search;
-
-			// must be two bmodels in the same leaf; sort on 1/z
-				fu = (float)(edge->u - 0xFFFFF) * (1.0 / 0x100000);
-				newzi = surf->d_ziorigin + fv*surf->d_zistepv +
-						fu*surf->d_zistepu;
-				newzibottom = newzi * 0.99;
-
-				testzi = surf2->d_ziorigin + fv*surf2->d_zistepv +
-						fu*surf2->d_zistepu;
-
-				if (newzibottom >= testzi)
-				{
-					goto gotposition;
-				}
-
-				newzitop = newzi * 1.01;
-				if (newzitop >= testzi)
-				{
-					if (surf->d_zistepu >= surf2->d_zistepu)
-					{
-						goto gotposition;
-					}
-				}
-
-				goto continue_search;
-			}
-
-			goto gotposition;
-
-newtop:
-		// emit a span (obscures current top)
-			iu = edge->u >> 20;
-
-			if (iu > surf2->last_u)
-			{
-				span = span_p++;
-				span->u = surf2->last_u;
-				span->count = iu - span->u;
-				span->v = current_iv;
-				span->pnext = surf2->spans;
-				surf2->spans = span;
-			}
-
-			// set last_u on the new span
-			surf->last_u = iu;
-				
-gotposition:
-		// insert before surf2
-			surf->next = surf2;
-			surf->prev = surf2->prev;
-			surf2->prev->next = surf;
-			surf2->prev = surf;
-		}
-	}
-}
-
-
-/*
-==============
-R_GenerateSpans
-==============
-*/
-void R_GenerateSpans (void)
-{
-	edge_t			*edge;
-	surf_t			*surf;
-
-// clear active surfaces to just the background surface
-	surfaces[1].next = surfaces[1].prev = &surfaces[1];
-	surfaces[1].last_u = edge_head_u_shift20;
-
-// generate spans
-	for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
-	{			
-		if (edge->surfs[0])
-		{
-		// it has a left surface, so a surface is going away for this span
-			surf = &surfaces[edge->surfs[0]];
-
-			R_TrailingEdge (surf, edge);
-
-			if (!edge->surfs[1])
-				continue;
-		}
-
-		R_LeadingEdge (edge);
-	}
-
-	R_CleanupSpan ();
-}
-
-#endif	// !id386
-
-
-/*
-==============
-R_GenerateSpansBackward
-==============
-*/
-void R_GenerateSpansBackward (void)
-{
-	edge_t			*edge;
-
-// clear active surfaces to just the background surface
-	surfaces[1].next = surfaces[1].prev = &surfaces[1];
-	surfaces[1].last_u = edge_head_u_shift20;
-
-// generate spans
-	for (edge=edge_head.next ; edge != &edge_tail; edge=edge->next)
-	{			
-		if (edge->surfs[0])
-			R_TrailingEdge (&surfaces[edge->surfs[0]], edge);
-
-		if (edge->surfs[1])
-			R_LeadingEdgeBackwards (edge);
-	}
-
-	R_CleanupSpan ();
-}
-
-
-/*
-==============
-R_ScanEdges
-
-Input: 
-newedges[] array
-	this has links to edges, which have links to surfaces
-
-Output:
-Each surface has a linked list of its visible spans
-==============
-*/
-void R_ScanEdges (void)
-{
-	int		iv, bottom;
-	byte	basespans[MAXSPANS*sizeof(espan_t)+CACHE_SIZE];
-	espan_t	*basespan_p;
-	surf_t	*s;
-
-	basespan_p = (espan_t *)
-			((long)(basespans + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
-	max_span_p = &basespan_p[MAXSPANS - r_refdef.vrect.width];
-
-	span_p = basespan_p;
-
-// clear active edges to just the background edges around the whole screen
-// FIXME: most of this only needs to be set up once
-	edge_head.u = r_refdef.vrect.x << 20;
-	edge_head_u_shift20 = edge_head.u >> 20;
-	edge_head.u_step = 0;
-	edge_head.prev = NULL;
-	edge_head.next = &edge_tail;
-	edge_head.surfs[0] = 0;
-	edge_head.surfs[1] = 1;
-	
-	edge_tail.u = (r_refdef.vrectright << 20) + 0xFFFFF;
-	edge_tail_u_shift20 = edge_tail.u >> 20;
-	edge_tail.u_step = 0;
-	edge_tail.prev = &edge_head;
-	edge_tail.next = &edge_aftertail;
-	edge_tail.surfs[0] = 1;
-	edge_tail.surfs[1] = 0;
-	
-	edge_aftertail.u = -1;		// force a move
-	edge_aftertail.u_step = 0;
-	edge_aftertail.next = &edge_sentinel;
-	edge_aftertail.prev = &edge_tail;
-
-// FIXME: do we need this now that we clamp x in r_draw.c?
-	edge_sentinel.u = 2000 << 24;		// make sure nothing sorts past this
-	edge_sentinel.prev = &edge_aftertail;
-
-//	
-// process all scan lines
-//
-	bottom = r_refdef.vrectbottom - 1;
-
-	for (iv=r_refdef.vrect.y ; iv<bottom ; iv++)
-	{
-		current_iv = iv;
-		fv = (float)iv;
-
-	// mark that the head (background start) span is pre-included
-		surfaces[1].spanstate = 1;
-
-		if (newedges[iv])
-		{
-			R_InsertNewEdges (newedges[iv], edge_head.next);
-		}
-
-		(*pdrawfunc) ();
-
-	// flush the span list if we can't be sure we have enough spans left for
-	// the next scan
-		if (span_p > max_span_p)
-		{
-			D_DrawSurfaces ();
-
-		// clear the surface span pointers
-			for (s = &surfaces[1] ; s<surface_p ; s++)
-				s->spans = NULL;
-
-			span_p = basespan_p;
-		}
-
-		if (removeedges[iv])
-			R_RemoveEdges (removeedges[iv]);
-
-		if (edge_head.next != &edge_tail)
-			R_StepActiveU (edge_head.next);
-	}
-
-// do the last scan (no need to step or sort or remove on the last scan)
-
-	current_iv = iv;
-	fv = (float)iv;
-
-// mark that the head (background start) span is pre-included
-	surfaces[1].spanstate = 1;
-
-	if (newedges[iv])
-		R_InsertNewEdges (newedges[iv], edge_head.next);
-
-	(*pdrawfunc) ();
-
-// draw whatever's left in the span list
-	D_DrawSurfaces ();
-}
-
-
-/*
-=========================================================================
-
-SURFACE FILLING
-
-=========================================================================
-*/
-
-msurface_t		*pface;
-surfcache_t		*pcurrentcache;
-vec3_t			transformed_modelorg;
-vec3_t			world_transformed_modelorg;
-vec3_t			local_modelorg;
-
-/*
-=============
-D_MipLevelForScale
-=============
-*/
-int D_MipLevelForScale (float scale)
-{
-	int		lmiplevel;
-
-	if (scale >= d_scalemip[0] )
-		lmiplevel = 0;
-	else if (scale >= d_scalemip[1] )
-		lmiplevel = 1;
-	else if (scale >= d_scalemip[2] )
-		lmiplevel = 2;
-	else
-		lmiplevel = 3;
-
-	if (lmiplevel < d_minmip)
-		lmiplevel = d_minmip;
-
-	return lmiplevel;
-}
-
-
-/*
-==============
-D_FlatFillSurface
-
-Simple single color fill with no texture mapping
-==============
-*/
-void D_FlatFillSurface (surf_t *surf, int color)
-{
-	espan_t	*span;
-	byte	*pdest;
-	int		u, u2;
-	
-	for (span=surf->spans ; span ; span=span->pnext)
-	{
-		pdest = (byte *)d_viewbuffer + r_screenwidth*span->v;
-		u = span->u;
-		u2 = span->u + span->count - 1;
-		for ( ; u <= u2 ; u++)
-			pdest[u] = color;
-	}
-}
-
-
-/*
-==============
-D_CalcGradients
-==============
-*/
-void D_CalcGradients (msurface_t *pface)
-{
-	mplane_t	*pplane;
-	float		mipscale;
-	vec3_t		p_temp1;
-	vec3_t		p_saxis, p_taxis;
-	float		t;
-
-	pplane = pface->plane;
-
-	mipscale = 1.0 / (float)(1 << miplevel);
-
-	TransformVector (pface->texinfo->vecs[0], p_saxis);
-	TransformVector (pface->texinfo->vecs[1], p_taxis);
-
-	t = xscaleinv * mipscale;
-	d_sdivzstepu = p_saxis[0] * t;
-	d_tdivzstepu = p_taxis[0] * t;
-
-	t = yscaleinv * mipscale;
-	d_sdivzstepv = -p_saxis[1] * t;
-	d_tdivzstepv = -p_taxis[1] * t;
-
-	d_sdivzorigin = p_saxis[2] * mipscale - xcenter * d_sdivzstepu -
-			ycenter * d_sdivzstepv;
-	d_tdivzorigin = p_taxis[2] * mipscale - xcenter * d_tdivzstepu -
-			ycenter * d_tdivzstepv;
-
-	VectorScale (transformed_modelorg, mipscale, p_temp1);
-
-	t = 0x10000*mipscale;
-	sadjust = ((fixed16_t)(DotProduct (p_temp1, p_saxis) * 0x10000 + 0.5)) -
-			((pface->texturemins[0] << 16) >> miplevel)
-			+ pface->texinfo->vecs[0][3]*t;
-	tadjust = ((fixed16_t)(DotProduct (p_temp1, p_taxis) * 0x10000 + 0.5)) -
-			((pface->texturemins[1] << 16) >> miplevel)
-			+ pface->texinfo->vecs[1][3]*t;
-
-	// PGM - changing flow speed for non-warping textures.
-	if (pface->texinfo->flags & SURF_FLOWING)
-	{
-		if(pface->texinfo->flags & SURF_WARP)
-			sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.25) - (int)(r_newrefdef.time * 0.25) ));
-		else
-			sadjust += 0x10000 * (-128 * ( (r_newrefdef.time * 0.77) - (int)(r_newrefdef.time * 0.77) ));
-	}
-	// PGM
-
-//
-// -1 (-epsilon) so we never wander off the edge of the texture
-//
-	bbextents = ((pface->extents[0] << 16) >> miplevel) - 1;
-	bbextentt = ((pface->extents[1] << 16) >> miplevel) - 1;
-}
-
-
-/*
-==============
-D_BackgroundSurf
-
-The grey background filler seen when there is a hole in the map
-==============
-*/
-void D_BackgroundSurf (surf_t *s)
-{
-// set up a gradient for the background surface that places it
-// effectively at infinity distance from the viewpoint
-	d_zistepu = 0;
-	d_zistepv = 0;
-	d_ziorigin = -0.9;
-
-	D_FlatFillSurface (s, (int)sw_clearcolor->value & 0xFF);
-	D_DrawZSpans (s->spans);
-}
-
-/*
-=================
-D_TurbulentSurf
-=================
-*/
-void D_TurbulentSurf (surf_t *s)
-{
-	d_zistepu = s->d_zistepu;
-	d_zistepv = s->d_zistepv;
-	d_ziorigin = s->d_ziorigin;
-
-	pface = s->msurf;
-	miplevel = 0;
-	cacheblock = pface->texinfo->image->pixels[0];
-	cachewidth = 64;
-
-	if (s->insubmodel)
-	{
-	// FIXME: we don't want to do all this for every polygon!
-	// TODO: store once at start of frame
-		currententity = s->entity;	//FIXME: make this passed in to
-									// R_RotateBmodel ()
-		VectorSubtract (r_origin, currententity->origin,
-				local_modelorg);
-		TransformVector (local_modelorg, transformed_modelorg);
-
-		R_RotateBmodel ();	// FIXME: don't mess with the frustum,
-							// make entity passed in
-	}
-
-	D_CalcGradients (pface);
-
-//============
-//PGM
-	// textures that aren't warping are just flowing. Use NonTurbulent8 instead
-	if(!(pface->texinfo->flags & SURF_WARP))
-		NonTurbulent8 (s->spans);
-	else
-		Turbulent8 (s->spans);
-//PGM
-//============
-
-	D_DrawZSpans (s->spans);
-
-	if (s->insubmodel)
-	{
-	//
-	// restore the old drawing state
-	// FIXME: we don't want to do this every time!
-	// TODO: speed up
-	//
-		currententity = NULL;	// &r_worldentity;
-		VectorCopy (world_transformed_modelorg,
-					transformed_modelorg);
-		VectorCopy (base_vpn, vpn);
-		VectorCopy (base_vup, vup);
-		VectorCopy (base_vright, vright);
-		R_TransformFrustum ();
-	}
-}
-
-/*
-==============
-D_SkySurf
-==============
-*/
-void D_SkySurf (surf_t *s)
-{
-	pface = s->msurf;
-	miplevel = 0;
-	if (!pface->texinfo->image)
-		return;
-	cacheblock = pface->texinfo->image->pixels[0];
-	cachewidth = 256;
-
-	d_zistepu = s->d_zistepu;
-	d_zistepv = s->d_zistepv;
-	d_ziorigin = s->d_ziorigin;
-
-	D_CalcGradients (pface);
-
-	D_DrawSpans16 (s->spans);
-
-// set up a gradient for the background surface that places it
-// effectively at infinity distance from the viewpoint
-	d_zistepu = 0;
-	d_zistepv = 0;
-	d_ziorigin = -0.9;
-
-	D_DrawZSpans (s->spans);
-}
-
-/*
-==============
-D_SolidSurf
-
-Normal surface cached, texture mapped surface
-==============
-*/
-void D_SolidSurf (surf_t *s)
-{
-	d_zistepu = s->d_zistepu;
-	d_zistepv = s->d_zistepv;
-	d_ziorigin = s->d_ziorigin;
-
-	if (s->insubmodel)
-	{
-	// FIXME: we don't want to do all this for every polygon!
-	// TODO: store once at start of frame
-		currententity = s->entity;	//FIXME: make this passed in to
-									// R_RotateBmodel ()
-		VectorSubtract (r_origin, currententity->origin, local_modelorg);
-		TransformVector (local_modelorg, transformed_modelorg);
-
-		R_RotateBmodel ();	// FIXME: don't mess with the frustum,
-							// make entity passed in
-	}
-	else
-		currententity = &r_worldentity;
-
-	pface = s->msurf;
-#if 1
-	miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
-#else
-	{
-		float dot;
-		float normal[3];
-
-		if ( s->insubmodel )
-		{
-			VectorCopy( pface->plane->normal, normal );
-//			TransformVector( pface->plane->normal, normal);
-			dot = DotProduct( normal, vpn );
-		}
-		else
-		{
-			VectorCopy( pface->plane->normal, normal );
-			dot = DotProduct( normal, vpn );
-		}
-
-		if ( pface->flags & SURF_PLANEBACK )
-			dot = -dot;
-
-		if ( dot > 0 )
-			printf( "blah" );
-
-		miplevel = D_MipLevelForScale(s->nearzi * scale_for_mip * pface->texinfo->mipadjust);
-	}
-#endif
-
-// FIXME: make this passed in to D_CacheSurface
-	pcurrentcache = D_CacheSurface (pface, miplevel);
-
-	cacheblock = (pixel_t *)pcurrentcache->data;
-	cachewidth = pcurrentcache->width;
-
-	D_CalcGradients (pface);
-
-	D_DrawSpans16 (s->spans);
-
-	D_DrawZSpans (s->spans);
-
-	if (s->insubmodel)
-	{
-	//
-	// restore the old drawing state
-	// FIXME: we don't want to do this every time!
-	// TODO: speed up
-	//
-		VectorCopy (world_transformed_modelorg,
-					transformed_modelorg);
-		VectorCopy (base_vpn, vpn);
-		VectorCopy (base_vup, vup);
-		VectorCopy (base_vright, vright);
-		R_TransformFrustum ();
-		currententity = NULL;	//&r_worldentity;
-	}
-}
-
-/*
-=============
-D_DrawflatSurfaces
-
-To allow developers to see the polygon carving of the world
-=============
-*/
-void D_DrawflatSurfaces (void)
-{
-	surf_t			*s;
-
-	for (s = &surfaces[1] ; s<surface_p ; s++)
-	{
-		if (!s->spans)
-			continue;
-
-		d_zistepu = s->d_zistepu;
-		d_zistepv = s->d_zistepv;
-		d_ziorigin = s->d_ziorigin;
-
-		// make a stable color for each surface by taking the low
-		// bits of the msurface pointer
-		D_FlatFillSurface (s, (int)s->msurf & 0xFF);
-		D_DrawZSpans (s->spans);
-	}
-}
-
-/*
-==============
-D_DrawSurfaces
-
-Rasterize all the span lists.  Guaranteed zero overdraw.
-May be called more than once a frame if the surf list overflows (higher res)
-==============
-*/
-void D_DrawSurfaces (void)
-{
-	surf_t			*s;
-
-//	currententity = NULL;	//&r_worldentity;
-	VectorSubtract (r_origin, vec3_origin, modelorg);
-	TransformVector (modelorg, transformed_modelorg);
-	VectorCopy (transformed_modelorg, world_transformed_modelorg);
-
-	if (!sw_drawflat->value)
-	{
-		for (s = &surfaces[1] ; s<surface_p ; s++)
-		{
-			if (!s->spans)
-				continue;
-
-			r_drawnpolycount++;
-
-			if (! (s->flags & (SURF_DRAWSKYBOX|SURF_DRAWBACKGROUND|SURF_DRAWTURB) ) )
-				D_SolidSurf (s);
-			else if (s->flags & SURF_DRAWSKYBOX)
-				D_SkySurf (s);
-			else if (s->flags & SURF_DRAWBACKGROUND)
-				D_BackgroundSurf (s);
-			else if (s->flags & SURF_DRAWTURB)
-				D_TurbulentSurf (s);
-		}
-	}
-	else
-		D_DrawflatSurfaces ();
-
-	currententity = NULL;	//&r_worldentity;
-	VectorSubtract (r_origin, vec3_origin, modelorg);
-	R_TransformFrustum ();
-}
-
--- a/ref_soft/r_image.c
+++ /dev/null
@@ -1,617 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-#include "r_local.h"
-
-
-#define	MAX_RIMAGES	1024
-image_t		r_images[MAX_RIMAGES];
-int			numr_images;
-
-
-/*
-===============
-R_ImageList_f
-===============
-*/
-void	R_ImageList_f (void)
-{
-	int		i;
-	image_t	*image;
-	int		texels;
-
-	ri.Con_Printf (PRINT_ALL, "------------------\n");
-	texels = 0;
-
-	for (i=0, image=r_images ; i<numr_images ; i++, image++)
-	{
-		if (image->registration_sequence <= 0)
-			continue;
-		texels += image->width*image->height;
-		switch (image->type)
-		{
-		case it_skin:
-			ri.Con_Printf (PRINT_ALL, "M");
-			break;
-		case it_sprite:
-			ri.Con_Printf (PRINT_ALL, "S");
-			break;
-		case it_wall:
-			ri.Con_Printf (PRINT_ALL, "W");
-			break;
-		case it_pic:
-			ri.Con_Printf (PRINT_ALL, "P");
-			break;
-		default:
-			ri.Con_Printf (PRINT_ALL, " ");
-			break;
-		}
-
-		ri.Con_Printf (PRINT_ALL,  " %3i %3i : %s\n",
-			image->width, image->height, image->name);
-	}
-	ri.Con_Printf (PRINT_ALL, "Total texel count: %i\n", texels);
-}
-
-
-/*
-=================================================================
-
-PCX LOADING
-
-=================================================================
-*/
-
-/*
-==============
-LoadPCX
-==============
-*/
-void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height)
-{
-	byte	*raw;
-	pcx_t	*pcx;
-	int		x, y;
-	int		len;
-	int		dataByte, runLength;
-	byte	*out, *pix;
-
-	*pic = NULL;
-
-	//
-	// load the file
-	//
-	len = ri.FS_LoadFile (filename, (void **)&raw);
-	if (!raw)
-	{
-		ri.Con_Printf (PRINT_DEVELOPER, "Bad pcx file %s\n", filename);
-		return;
-	}
-
-	//
-	// parse the PCX file
-	//
-	pcx = (pcx_t *)raw;
-
-    pcx->xmin = LittleShort(pcx->xmin);
-    pcx->ymin = LittleShort(pcx->ymin);
-    pcx->xmax = LittleShort(pcx->xmax);
-    pcx->ymax = LittleShort(pcx->ymax);
-    pcx->hres = LittleShort(pcx->hres);
-    pcx->vres = LittleShort(pcx->vres);
-    pcx->bytes_per_line = LittleShort(pcx->bytes_per_line);
-    pcx->palette_type = LittleShort(pcx->palette_type);
-
-	raw = &pcx->data;
-
-	if (pcx->manufacturer != 0x0a
-		|| pcx->version != 5
-		|| pcx->encoding != 1
-		|| pcx->bits_per_pixel != 8
-		|| pcx->xmax >= 640
-		|| pcx->ymax >= 480)
-	{
-		ri.Con_Printf (PRINT_ALL, "Bad pcx file %s\n", filename);
-		return;
-	}
-
-	out = malloc ( (pcx->ymax+1) * (pcx->xmax+1) );
-
-	*pic = out;
-
-	pix = out;
-
-	if (palette)
-	{
-		*palette = malloc(768);
-		memcpy (*palette, (byte *)pcx + len - 768, 768);
-	}
-
-	if (width)
-		*width = pcx->xmax+1;
-	if (height)
-		*height = pcx->ymax+1;
-
-	for (y=0 ; y<=pcx->ymax ; y++, pix += pcx->xmax+1)
-	{
-		for (x=0 ; x<=pcx->xmax ; )
-		{
-			dataByte = *raw++;
-
-			if((dataByte & 0xC0) == 0xC0)
-			{
-				runLength = dataByte & 0x3F;
-				dataByte = *raw++;
-			}
-			else
-				runLength = 1;
-
-			while(runLength-- > 0)
-				pix[x++] = dataByte;
-		}
-
-	}
-
-	if ( raw - (byte *)pcx > len)
-	{
-		ri.Con_Printf (PRINT_DEVELOPER, "PCX file %s was malformed", filename);
-		free (*pic);
-		*pic = NULL;
-	}
-
-	ri.FS_FreeFile (pcx);
-}
-
-/*
-=========================================================
-
-TARGA LOADING
-
-=========================================================
-*/
-
-typedef struct _TargaHeader {
-	unsigned char 	id_length, colormap_type, image_type;
-	unsigned short	colormap_index, colormap_length;
-	unsigned char	colormap_size;
-	unsigned short	x_origin, y_origin, width, height;
-	unsigned char	pixel_size, attributes;
-} TargaHeader;
-
-
-/*
-=============
-LoadTGA
-=============
-*/
-void LoadTGA (char *name, byte **pic, int *width, int *height)
-{
-	int		columns, rows, numPixels;
-	byte	*pixbuf;
-	int		row, column;
-	byte	*buf_p;
-	byte	*buffer;
-	int		length;
-	TargaHeader		targa_header;
-	byte			*targa_rgba;
-
-	*pic = NULL;
-
-	//
-	// load the file
-	//
-	length = ri.FS_LoadFile (name, (void **)&buffer);
-	if (!buffer)
-	{
-		ri.Con_Printf (PRINT_DEVELOPER, "Bad tga file %s\n", name);
-		return;
-	}
-
-	buf_p = buffer;
-
-	targa_header.id_length = *buf_p++;
-	targa_header.colormap_type = *buf_p++;
-	targa_header.image_type = *buf_p++;
-	
-	targa_header.colormap_index = LittleShort ( *((short *)buf_p) );
-	buf_p+=2;
-	targa_header.colormap_length = LittleShort ( *((short *)buf_p) );
-	buf_p+=2;
-	targa_header.colormap_size = *buf_p++;
-	targa_header.x_origin = LittleShort ( *((short *)buf_p) );
-	buf_p+=2;
-	targa_header.y_origin = LittleShort ( *((short *)buf_p) );
-	buf_p+=2;
-	targa_header.width = LittleShort ( *((short *)buf_p) );
-	buf_p+=2;
-	targa_header.height = LittleShort ( *((short *)buf_p) );
-	buf_p+=2;
-	targa_header.pixel_size = *buf_p++;
-	targa_header.attributes = *buf_p++;
-
-	if (targa_header.image_type!=2 
-		&& targa_header.image_type!=10) 
-		ri.Sys_Error (ERR_DROP, "LoadTGA: Only type 2 and 10 targa RGB images supported\n");
-
-	if (targa_header.colormap_type !=0 
-		|| (targa_header.pixel_size!=32 && targa_header.pixel_size!=24))
-		ri.Sys_Error (ERR_DROP, "LoadTGA: Only 32 or 24 bit images supported (no colormaps)\n");
-
-	columns = targa_header.width;
-	rows = targa_header.height;
-	numPixels = columns * rows;
-
-	if (width)
-		*width = columns;
-	if (height)
-		*height = rows;
-
-	targa_rgba = malloc (numPixels*4);
-	*pic = targa_rgba;
-
-	if (targa_header.id_length != 0)
-		buf_p += targa_header.id_length;  // skip TARGA image comment
-	
-	if (targa_header.image_type==2) {  // Uncompressed, RGB images
-		for(row=rows-1; row>=0; row--) {
-			pixbuf = targa_rgba + row*columns*4;
-			for(column=0; column<columns; column++) {
-				unsigned char red,green,blue,alphabyte;
-				switch (targa_header.pixel_size) {
-					case 24:
-							
-							blue = *buf_p++;
-							green = *buf_p++;
-							red = *buf_p++;
-							*pixbuf++ = red;
-							*pixbuf++ = green;
-							*pixbuf++ = blue;
-							*pixbuf++ = 255;
-							break;
-					case 32:
-							blue = *buf_p++;
-							green = *buf_p++;
-							red = *buf_p++;
-							alphabyte = *buf_p++;
-							*pixbuf++ = red;
-							*pixbuf++ = green;
-							*pixbuf++ = blue;
-							*pixbuf++ = alphabyte;
-							break;
-				}
-			}
-		}
-	}
-	else if (targa_header.image_type==10) {   // Runlength encoded RGB images
-		unsigned char red,green,blue,alphabyte,packetHeader,packetSize,j;
-		for(row=rows-1; row>=0; row--) {
-			pixbuf = targa_rgba + row*columns*4;
-			for(column=0; column<columns; ) {
-				packetHeader= *buf_p++;
-				packetSize = 1 + (packetHeader & 0x7f);
-				if (packetHeader & 0x80) {        // run-length packet
-					switch (targa_header.pixel_size) {
-						case 24:
-								blue = *buf_p++;
-								green = *buf_p++;
-								red = *buf_p++;
-								alphabyte = 255;
-								break;
-						case 32:
-								blue = *buf_p++;
-								green = *buf_p++;
-								red = *buf_p++;
-								alphabyte = *buf_p++;
-								break;
-					}
-	
-					for(j=0;j<packetSize;j++) {
-						*pixbuf++=red;
-						*pixbuf++=green;
-						*pixbuf++=blue;
-						*pixbuf++=alphabyte;
-						column++;
-						if (column==columns) { // run spans across rows
-							column=0;
-							if (row>0)
-								row--;
-							else
-								goto breakOut;
-							pixbuf = targa_rgba + row*columns*4;
-						}
-					}
-				}
-				else {                            // non run-length packet
-					for(j=0;j<packetSize;j++) {
-						switch (targa_header.pixel_size) {
-							case 24:
-									blue = *buf_p++;
-									green = *buf_p++;
-									red = *buf_p++;
-									*pixbuf++ = red;
-									*pixbuf++ = green;
-									*pixbuf++ = blue;
-									*pixbuf++ = 255;
-									break;
-							case 32:
-									blue = *buf_p++;
-									green = *buf_p++;
-									red = *buf_p++;
-									alphabyte = *buf_p++;
-									*pixbuf++ = red;
-									*pixbuf++ = green;
-									*pixbuf++ = blue;
-									*pixbuf++ = alphabyte;
-									break;
-						}
-						column++;
-						if (column==columns) { // pixel packet run spans across rows
-							column=0;
-							if (row>0)
-								row--;
-							else
-								goto breakOut;
-							pixbuf = targa_rgba + row*columns*4;
-						}						
-					}
-				}
-			}
-			breakOut:;
-		}
-	}
-
-	ri.FS_FreeFile (buffer);
-}
-
-
-//=======================================================
-
-image_t *R_FindFreeImage (void)
-{
-	image_t		*image;
-	int			i;
-
-	// find a free image_t
-	for (i=0, image=r_images ; i<numr_images ; i++,image++)
-	{
-		if (!image->registration_sequence)
-			break;
-	}
-	if (i == numr_images)
-	{
-		if (numr_images == MAX_RIMAGES)
-			ri.Sys_Error (ERR_DROP, "MAX_RIMAGES");
-		numr_images++;
-	}
-	image = &r_images[i];
-
-	return image;
-}
-
-/*
-================
-GL_LoadPic
-
-================
-*/
-image_t *GL_LoadPic (char *name, byte *pic, int width, int height, imagetype_t type)
-{
-	image_t		*image;
-	int			i, c, b;
-
-	image = R_FindFreeImage ();
-	if (strlen(name) >= sizeof(image->name))
-		ri.Sys_Error (ERR_DROP, "Draw_LoadPic: \"%s\" is too long", name);
-	strcpy (image->name, name);
-	image->registration_sequence = registration_sequence;
-
-	image->width = width;
-	image->height = height;
-	image->type = type;
-
-	c = width*height;
-	image->pixels[0] = malloc (c);
-	image->transparent = false;
-	for (i=0 ; i<c ; i++)
-	{
-		b = pic[i];
-		if (b == 255)
-			image->transparent = true;
-		image->pixels[0][i] = b;
-	}
-
-	return image;
-}
-
-/*
-================
-R_LoadWal
-================
-*/
-image_t *R_LoadWal (char *name)
-{
-	miptex_t	*mt;
-	int			ofs;
-	image_t		*image;
-	int			size;
-
-	ri.FS_LoadFile (name, (void **)&mt);
-	if (!mt)
-	{
-		ri.Con_Printf (PRINT_ALL, "R_LoadWal: can't load %s\n", name);
-		return r_notexture_mip;
-	}
-
-	image = R_FindFreeImage ();
-	strcpy (image->name, name);
-	image->width = LittleLong (mt->width);
-	image->height = LittleLong (mt->height);
-	image->type = it_wall;
-	image->registration_sequence = registration_sequence;
-
-	size = image->width*image->height * (256+64+16+4)/256;
-	image->pixels[0] = malloc (size);
-	image->pixels[1] = image->pixels[0] + image->width*image->height;
-	image->pixels[2] = image->pixels[1] + image->width*image->height/4;
-	image->pixels[3] = image->pixels[2] + image->width*image->height/16;
-
-	ofs = LittleLong (mt->offsets[0]);
-	memcpy ( image->pixels[0], (byte *)mt + ofs, size);
-
-	ri.FS_FreeFile ((void *)mt);
-
-	return image;
-}
-
-
-/*
-===============
-R_FindImage
-
-Finds or loads the given image
-===============
-*/
-image_t	*R_FindImage (char *name, imagetype_t type)
-{
-	image_t	*image;
-	int		i, len;
-	byte	*pic, *palette;
-	int		width, height;
-
-	if (!name)
-		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: NULL name");
-	len = strlen(name);
-	if (len<5)
-		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: bad name: %s", name);
-
-	// look for it
-	for (i=0, image=r_images ; i<numr_images ; i++,image++)
-	{
-		if (!strcmp(name, image->name))
-		{
-			image->registration_sequence = registration_sequence;
-			return image;
-		}
-	}
-
-	//
-	// load the pic from disk
-	//
-	pic = NULL;
-	palette = NULL;
-	if (!strcmp(name+len-4, ".pcx"))
-	{
-		LoadPCX (name, &pic, &palette, &width, &height);
-		if (!pic)
-			return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s", name);
-		image = GL_LoadPic (name, pic, width, height, type);
-	}
-	else if (!strcmp(name+len-4, ".wal"))
-	{
-		image = R_LoadWal (name);
-	}
-	else if (!strcmp(name+len-4, ".tga"))
-		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: can't load %s in software renderer", name);
-	else
-		return NULL;	// ri.Sys_Error (ERR_DROP, "R_FindImage: bad extension on: %s", name);
-
-	if (pic)
-		free(pic);
-	if (palette)
-		free(palette);
-
-	return image;
-}
-
-
-
-/*
-===============
-R_RegisterSkin
-===============
-*/
-struct image_s *R_RegisterSkin (char *name)
-{
-	return R_FindImage (name, it_skin);
-}
-
-
-/*
-================
-R_FreeUnusedImages
-
-Any image that was not touched on this registration sequence
-will be freed.
-================
-*/
-void R_FreeUnusedImages (void)
-{
-	int		i;
-	image_t	*image;
-
-	for (i=0, image=r_images ; i<numr_images ; i++, image++)
-	{
-		if (image->registration_sequence == registration_sequence)
-		{
-			Com_PageInMemory ((byte *)image->pixels[0], image->width*image->height);
-			continue;		// used this sequence
-		}
-		if (!image->registration_sequence)
-			continue;		// free texture
-		if (image->type == it_pic)
-			continue;		// don't free pics
-		// free it
-		free (image->pixels[0]);	// the other mip levels just follow
-		memset (image, 0, sizeof(*image));
-	}
-}
-
-
-
-/*
-===============
-R_InitImages
-===============
-*/
-void	R_InitImages (void)
-{
-	registration_sequence = 1;
-}
-
-/*
-===============
-R_ShutdownImages
-===============
-*/
-void	R_ShutdownImages (void)
-{
-	int		i;
-	image_t	*image;
-
-	for (i=0, image=r_images ; i<numr_images ; i++, image++)
-	{
-		if (!image->registration_sequence)
-			continue;		// free texture
-		// free it
-		free (image->pixels[0]);	// the other mip levels just follow
-		memset (image, 0, sizeof(*image));
-	}
-}
-
--- a/ref_soft/r_light.c
+++ /dev/null
@@ -1,442 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_light.c
-
-#include "r_local.h"
-
-int	r_dlightframecount;
-
-
-/*
-=============================================================================
-
-DYNAMIC LIGHTS
-
-=============================================================================
-*/
-
-/*
-=============
-R_MarkLights
-=============
-*/
-void R_MarkLights (dlight_t *light, int bit, mnode_t *node)
-{
-	mplane_t	*splitplane;
-	float		dist;
-	msurface_t	*surf;
-	int			i;
-	
-	if (node->contents != -1)
-		return;
-
-	splitplane = node->plane;
-	dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist;
-	
-//=====
-//PGM
-	i=light->intensity;
-	if(i<0)
-		i=-i;
-//PGM
-//=====
-
-	if (dist > i)	// PGM (dist > light->intensity)
-	{
-		R_MarkLights (light, bit, node->children[0]);
-		return;
-	}
-	if (dist < -i)	// PGM (dist < -light->intensity)
-	{
-		R_MarkLights (light, bit, node->children[1]);
-		return;
-	}
-		
-// mark the polygons
-	surf = r_worldmodel->surfaces + node->firstsurface;
-	for (i=0 ; i<node->numsurfaces ; i++, surf++)
-	{
-		if (surf->dlightframe != r_dlightframecount)
-		{
-			surf->dlightbits = 0;
-			surf->dlightframe = r_dlightframecount;
-		}
-		surf->dlightbits |= bit;
-	}
-
-	R_MarkLights (light, bit, node->children[0]);
-	R_MarkLights (light, bit, node->children[1]);
-}
-
-
-/*
-=============
-R_PushDlights
-=============
-*/
-void R_PushDlights (model_t *model)
-{
-	int		i;
-	dlight_t	*l;
-
-	r_dlightframecount = r_framecount;
-	for (i=0, l = r_newrefdef.dlights ; i<r_newrefdef.num_dlights ; i++, l++)
-	{
-		R_MarkLights ( l, 1<<i, 
-			model->nodes + model->firstnode);
-	}
-}
-
-
-/*
-=============================================================================
-
-LIGHT SAMPLING
-
-=============================================================================
-*/
-
-vec3_t	pointcolor;
-mplane_t		*lightplane;		// used as shadow plane
-vec3_t			lightspot;
-
-int RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
-{
-	float		front, back, frac;
-	int			side;
-	mplane_t	*plane;
-	vec3_t		mid;
-	msurface_t	*surf;
-	int			s, t, ds, dt;
-	int			i;
-	mtexinfo_t	*tex;
-	byte		*lightmap;
-	float		*scales;
-	int			maps;
-	float		samp;
-	int			r;
-
-	if (node->contents != -1)
-		return -1;		// didn't hit anything
-	
-// calculate mid point
-
-// FIXME: optimize for axial
-	plane = node->plane;
-	front = DotProduct (start, plane->normal) - plane->dist;
-	back = DotProduct (end, plane->normal) - plane->dist;
-	side = front < 0;
-	
-	if ( (back < 0) == side)
-		return RecursiveLightPoint (node->children[side], start, end);
-	
-	frac = front / (front-back);
-	mid[0] = start[0] + (end[0] - start[0])*frac;
-	mid[1] = start[1] + (end[1] - start[1])*frac;
-	mid[2] = start[2] + (end[2] - start[2])*frac;
-	if (plane->type < 3)	// axial planes
-		mid[plane->type] = plane->dist;
-
-// go down front side	
-	r = RecursiveLightPoint (node->children[side], start, mid);
-	if (r >= 0)
-		return r;		// hit something
-		
-	if ( (back < 0) == side )
-		return -1;		// didn't hit anuthing
-		
-// check for impact on this node
-	VectorCopy (mid, lightspot);
-	lightplane = plane;
-
-	surf = r_worldmodel->surfaces + node->firstsurface;
-	for (i=0 ; i<node->numsurfaces ; i++, surf++)
-	{
-		if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY)) 
-			continue;	// no lightmaps
-
-		tex = surf->texinfo;
-		
-		s = DotProduct (mid, tex->vecs[0]) + tex->vecs[0][3];
-		t = DotProduct (mid, tex->vecs[1]) + tex->vecs[1][3];
-		if (s < surf->texturemins[0] ||
-		t < surf->texturemins[1])
-			continue;
-		
-		ds = s - surf->texturemins[0];
-		dt = t - surf->texturemins[1];
-		
-		if ( ds > surf->extents[0] || dt > surf->extents[1] )
-			continue;
-
-		if (!surf->samples)
-			return 0;
-
-		ds >>= 4;
-		dt >>= 4;
-
-		lightmap = surf->samples;
-		VectorCopy (vec3_origin, pointcolor);
-		if (lightmap)
-		{
-			lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
-
-			for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
-					maps++)
-			{
-				samp = *lightmap * /* 0.5 * */ (1.0/255);	// adjust for gl scale
-				scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb;
-				VectorMA (pointcolor, samp, scales, pointcolor);
-				lightmap += ((surf->extents[0]>>4)+1) *
-						((surf->extents[1]>>4)+1);
-			}
-		}
-		
-		return 1;
-	}
-
-// go down back side
-	return RecursiveLightPoint (node->children[!side], mid, end);
-}
-
-/*
-===============
-R_LightPoint
-===============
-*/
-void R_LightPoint (vec3_t p, vec3_t color)
-{
-	vec3_t		end;
-	float		r;
-	int			lnum;
-	dlight_t	*dl;
-	float		light;
-	vec3_t		dist;
-	float		add;
-	
-	if (!r_worldmodel->lightdata)
-	{
-		color[0] = color[1] = color[2] = 1.0;
-		return;
-	}
-	
-	end[0] = p[0];
-	end[1] = p[1];
-	end[2] = p[2] - 2048;
-	
-	r = RecursiveLightPoint (r_worldmodel->nodes, p, end);
-	
-	if (r == -1)
-	{
-		VectorCopy (vec3_origin, color);
-	}
-	else
-	{
-		VectorCopy (pointcolor, color);
-	}
-
-	//
-	// add dynamic lights
-	//
-	light = 0;
-	for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
-	{
-		dl = &r_newrefdef.dlights[lnum];
-		VectorSubtract (currententity->origin,
-						dl->origin,
-						dist);
-		add = dl->intensity - VectorLength(dist);
-		add *= (1.0/256);
-		if (add > 0)
-		{
-			VectorMA (color, add, dl->color, color);
-		}
-	}
-}
-
-//===================================================================
-
-
-unsigned		blocklights[1024];	// allow some very large lightmaps
-
-/*
-===============
-R_AddDynamicLights
-===============
-*/
-void R_AddDynamicLights (void)
-{
-	msurface_t *surf;
-	int			lnum;
-	int			sd, td;
-	float		dist, rad, minlight;
-	vec3_t		impact, local;
-	int			s, t;
-	int			i;
-	int			smax, tmax;
-	mtexinfo_t	*tex;
-	dlight_t	*dl;
-	int			negativeLight;	//PGM
-
-	surf = r_drawsurf.surf;
-	smax = (surf->extents[0]>>4)+1;
-	tmax = (surf->extents[1]>>4)+1;
-	tex = surf->texinfo;
-
-	for (lnum=0 ; lnum<r_newrefdef.num_dlights ; lnum++)
-	{
-		if ( !(surf->dlightbits & (1<<lnum) ) )
-			continue;		// not lit by this light
-
-		dl = &r_newrefdef.dlights[lnum];
-		rad = dl->intensity;
-
-//=====
-//PGM
-		negativeLight = 0;
-		if(rad < 0)
-		{
-			negativeLight = 1;
-			rad = -rad;
-		}
-//PGM
-//=====
-
-		dist = DotProduct (dl->origin, surf->plane->normal) -
-				surf->plane->dist;
-		rad -= fabs(dist);
-		minlight = 32;		// dl->minlight;
-		if (rad < minlight)
-			continue;
-		minlight = rad - minlight;
-
-		for (i=0 ; i<3 ; i++)
-		{
-			impact[i] = dl->origin[i] -
-					surf->plane->normal[i]*dist;
-		}
-
-		local[0] = DotProduct (impact, tex->vecs[0]) + tex->vecs[0][3];
-		local[1] = DotProduct (impact, tex->vecs[1]) + tex->vecs[1][3];
-
-		local[0] -= surf->texturemins[0];
-		local[1] -= surf->texturemins[1];
-		
-		for (t = 0 ; t<tmax ; t++)
-		{
-			td = local[1] - t*16;
-			if (td < 0)
-				td = -td;
-			for (s=0 ; s<smax ; s++)
-			{
-				sd = local[0] - s*16;
-				if (sd < 0)
-					sd = -sd;
-				if (sd > td)
-					dist = sd + (td>>1);
-				else
-					dist = td + (sd>>1);
-//====
-//PGM
-				if(!negativeLight)
-				{
-					if (dist < minlight)
-						blocklights[t*smax + s] += (rad - dist)*256;
-				}
-				else
-				{
-					if (dist < minlight)
-						blocklights[t*smax + s] -= (rad - dist)*256;
-					if(blocklights[t*smax + s] < minlight)
-						blocklights[t*smax + s] = minlight;
-				}
-//PGM
-//====
-			}
-		}
-	}
-}
-
-/*
-===============
-R_BuildLightMap
-
-Combine and scale multiple lightmaps into the 8.8 format in blocklights
-===============
-*/
-void R_BuildLightMap (void)
-{
-	int			smax, tmax;
-	int			t;
-	int			i, size;
-	byte		*lightmap;
-	unsigned	scale;
-	int			maps;
-	msurface_t	*surf;
-
-	surf = r_drawsurf.surf;
-
-	smax = (surf->extents[0]>>4)+1;
-	tmax = (surf->extents[1]>>4)+1;
-	size = smax*tmax;
-
-	if (r_fullbright->value || !r_worldmodel->lightdata)
-	{
-		for (i=0 ; i<size ; i++)
-			blocklights[i] = 0;
-		return;
-	}
-
-// clear to no light
-	for (i=0 ; i<size ; i++)
-		blocklights[i] = 0;
-
-
-// add all the lightmaps
-	lightmap = surf->samples;
-	if (lightmap)
-		for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ;
-			 maps++)
-		{
-			scale = r_drawsurf.lightadj[maps];	// 8.8 fraction		
-			for (i=0 ; i<size ; i++)
-				blocklights[i] += lightmap[i] * scale;
-			lightmap += size;	// skip to next lightmap
-		}
-
-// add all the dynamic lights
-	if (surf->dlightframe == r_framecount)
-		R_AddDynamicLights ();
-
-// bound, invert, and shift
-	for (i=0 ; i<size ; i++)
-	{
-		t = (int)blocklights[i];
-		if (t < 0)
-			t = 0;
-		t = (255*256 - t) >> (8 - VID_CBITS);
-
-		if (t < (1 << 6))
-			t = (1 << 6);
-
-		blocklights[i] = t;
-	}
-}
-
--- a/ref_soft/r_local.h
+++ /dev/null
@@ -1,849 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-  
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-#include <stdarg.h>
-
-#include "../client/ref.h"
-
-#define REF_VERSION     "SOFT 0.01"
-
-// up / down
-#define PITCH   0
-
-// left / right
-#define YAW             1
-
-// fall over
-#define ROLL    2
-
-
-/*
-
-  skins will be outline flood filled and mip mapped
-  pics and sprites with alpha will be outline flood filled
-  pic won't be mip mapped
-
-  model skin
-  sprite frame
-  wall texture
-  pic
-
-*/
-
-typedef enum 
-{
-	it_skin,
-	it_sprite,
-	it_wall,
-	it_pic,
-	it_sky
-} imagetype_t;
-
-typedef struct image_s
-{
-	char    name[MAX_QPATH];        // game path, including extension
-	imagetype_t     type;
-	int             width, height;
-	qboolean        transparent;    // true if any 255 pixels in image
-	int             registration_sequence;  // 0 = free
-	byte		*pixels[4];				// mip levels
-} image_t;
-
-
-//===================================================================
-
-typedef unsigned char pixel_t;
-
-typedef struct vrect_s
-{
-	int                             x,y,width,height;
-	struct vrect_s  *pnext;
-} vrect_t;
-
-typedef struct
-{
-	pixel_t                 *buffer;                // invisible buffer
-	pixel_t                 *colormap;              // 256 * VID_GRADES size
-	pixel_t                 *alphamap;              // 256 * 256 translucency map
-	int                             rowbytes;               // may be > width if displayed in a window
-									// can be negative for stupid dibs
-	int						width;          
-	int						height;
-} viddef_t;
-
-typedef enum
-{
-	rserr_ok,
-
-	rserr_invalid_fullscreen,
-	rserr_invalid_mode,
-
-	rserr_unknown
-} rserr_t;
-
-extern viddef_t vid;
-
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-typedef struct
-{
-	vrect_t         vrect;                          // subwindow in video for refresh
-									// FIXME: not need vrect next field here?
-	vrect_t         aliasvrect;                     // scaled Alias version
-	int                     vrectright, vrectbottom;        // right & bottom screen coords
-	int                     aliasvrectright, aliasvrectbottom;      // scaled Alias versions
-	float           vrectrightedge;                 // rightmost right edge we care about,
-										//  for use in edge list
-	float           fvrectx, fvrecty;               // for floating-point compares
-	float           fvrectx_adj, fvrecty_adj; // left and top edges, for clamping
-	int                     vrect_x_adj_shift20;    // (vrect.x + 0.5 - epsilon) << 20
-	int                     vrectright_adj_shift20; // (vrectright + 0.5 - epsilon) << 20
-	float           fvrectright_adj, fvrectbottom_adj;
-										// right and bottom edges, for clamping
-	float           fvrectright;                    // rightmost edge, for Alias clamping
-	float           fvrectbottom;                   // bottommost edge, for Alias clamping
-	float           horizontalFieldOfView;  // at Z = 1.0, this many X is visible 
-										// 2.0 = 90 degrees
-	float           xOrigin;                        // should probably always be 0.5
-	float           yOrigin;                        // between be around 0.3 to 0.5
-
-	vec3_t          vieworg;
-	vec3_t          viewangles;
-	
-	int                     ambientlight;
-} oldrefdef_t;
-
-extern oldrefdef_t      r_refdef;
-
-#include "r_model.h"
-
-#define CACHE_SIZE      32
-
-/*
-====================================================
-
-  CONSTANTS
-
-====================================================
-*/
-
-#define VID_CBITS       6
-#define VID_GRADES      (1 << VID_CBITS)
-
-
-// r_shared.h: general refresh-related stuff shared between the refresh and the
-// driver
-
-
-#define MAXVERTS        64              // max points in a surface polygon
-#define MAXWORKINGVERTS (MAXVERTS+4)    // max points in an intermediate
-										//  polygon (while processing)
-// !!! if this is changed, it must be changed in d_ifacea.h too !!!
-#define MAXHEIGHT       1200
-#define MAXWIDTH        1600
-
-#define INFINITE_DISTANCE       0x10000         // distance that's always guaranteed to
-										//  be farther away than anything in
-										//  the scene
-
-
-// d_iface.h: interface header file for rasterization driver modules
-
-#define WARP_WIDTH              320
-#define WARP_HEIGHT             240
-
-#define MAX_LBM_HEIGHT  480
-
-
-#define PARTICLE_Z_CLIP 8.0
-
-// !!! must be kept the same as in quakeasm.h !!!
-#define TRANSPARENT_COLOR       0xFF
-
-
-// !!! if this is changed, it must be changed in d_ifacea.h too !!!
-#define TURB_TEX_SIZE   64              // base turbulent texture size
-
-// !!! if this is changed, it must be changed in d_ifacea.h too !!!
-#define CYCLE                   128             // turbulent cycle size
-
-#define SCANBUFFERPAD           0x1000
-
-#define DS_SPAN_LIST_END        -128
-
-#define NUMSTACKEDGES           2000
-#define MINEDGES                        NUMSTACKEDGES
-#define NUMSTACKSURFACES        1000
-#define MINSURFACES                     NUMSTACKSURFACES
-#define MAXSPANS                        3000
-
-// flags in finalvert_t.flags
-#define ALIAS_LEFT_CLIP                         0x0001
-#define ALIAS_TOP_CLIP                          0x0002
-#define ALIAS_RIGHT_CLIP                        0x0004
-#define ALIAS_BOTTOM_CLIP                       0x0008
-#define ALIAS_Z_CLIP                            0x0010
-#define ALIAS_XY_CLIP_MASK                      0x000F
-
-#define SURFCACHE_SIZE_AT_320X240    1024*768
-
-#define BMODEL_FULLY_CLIPPED    0x10 // value returned by R_BmodelCheckBBox ()
-									 //  if bbox is trivially rejected
-
-#define XCENTERING      (1.0 / 2.0)
-#define YCENTERING      (1.0 / 2.0)
-
-#define CLIP_EPSILON            0.001
-
-#define BACKFACE_EPSILON        0.01
-
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-#define NEAR_CLIP       0.01
-
-
-#define MAXALIASVERTS           2000    // TODO: tune this
-#define ALIAS_Z_CLIP_PLANE      4
-
-// turbulence stuff
-
-#define AMP             8*0x10000
-#define AMP2    3
-#define SPEED   20
-
-
-/*
-====================================================
-
-TYPES
-
-====================================================
-*/
-
-typedef struct
-{
-	float   u, v;
-	float   s, t;
-	float   zi;
-} emitpoint_t;
-
-/*
-** if you change this structure be sure to change the #defines
-** listed after it!
-*/
-#define SMALL_FINALVERT 0
-
-#if SMALL_FINALVERT
-
-typedef struct finalvert_s {
-	short           u, v, s, t;
-	int             l;
-	int             zi;
-	int             flags;
-	float   xyz[3];         // eye space
-} finalvert_t;
-
-#define FINALVERT_V0     0
-#define FINALVERT_V1     2
-#define FINALVERT_V2     4
-#define FINALVERT_V3     6
-#define FINALVERT_V4     8
-#define FINALVERT_V5    12
-#define FINALVERT_FLAGS 16
-#define FINALVERT_X     20
-#define FINALVERT_Y     24
-#define FINALVERT_Z     28
-#define FINALVERT_SIZE  32
-
-#else
-
-typedef struct finalvert_s {
-	int             u, v, s, t;
-	int             l;
-	int             zi;
-	int             flags;
-	float   xyz[3];         // eye space
-} finalvert_t;
-
-#define FINALVERT_V0     0
-#define FINALVERT_V1     4
-#define FINALVERT_V2     8
-#define FINALVERT_V3    12
-#define FINALVERT_V4    16
-#define FINALVERT_V5    20
-#define FINALVERT_FLAGS 24
-#define FINALVERT_X     28
-#define FINALVERT_Y     32
-#define FINALVERT_Z     36
-#define FINALVERT_SIZE  40
-
-#endif
-
-typedef struct
-{
-	void                            *pskin;
-	int                                     pskindesc;
-	int                                     skinwidth;
-	int                                     skinheight;
-	dtriangle_t                     *ptriangles;
-	finalvert_t                     *pfinalverts;
-	int                                     numtriangles;
-	int                                     drawtype;
-	int                                     seamfixupX16;
-	qboolean                        do_vis_thresh;
-	int                                     vis_thresh;
-} affinetridesc_t;
-
-typedef struct
-{
-	byte            *surfdat;       // destination for generated surface
-	int                     rowbytes;       // destination logical width in bytes
-	msurface_t      *surf;          // description for surface to generate
-	fixed8_t        lightadj[MAXLIGHTMAPS];
-							// adjust for lightmap levels for dynamic lighting
-	image_t			*image;
-	int                     surfmip;        // mipmapped ratio of surface texels / world pixels
-	int                     surfwidth;      // in mipmapped texels
-	int                     surfheight;     // in mipmapped texels
-} drawsurf_t;
-
-
-
-typedef struct {
-	int                     ambientlight;
-	int                     shadelight;
-	float           *plightvec;
-} alight_t;
-
-// clipped bmodel edges
-
-typedef struct bedge_s
-{
-	mvertex_t               *v[2];
-	struct bedge_s  *pnext;
-} bedge_t;
-
-
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-typedef struct clipplane_s
-{
-	vec3_t          normal;
-	float           dist;
-	struct          clipplane_s     *next;
-	byte            leftedge;
-	byte            rightedge;
-	byte            reserved[2];
-} clipplane_t;
-
-
-typedef struct surfcache_s
-{
-	struct surfcache_s      *next;
-	struct surfcache_s      **owner;                // NULL is an empty chunk of memory
-	int                                     lightadj[MAXLIGHTMAPS]; // checked for strobe flush
-	int                                     dlight;
-	int                                     size;           // including header
-	unsigned                        width;
-	unsigned                        height;         // DEBUG only needed for debug
-	float                           mipscale;
-	image_t							*image;
-	byte                            data[4];        // width*height elements
-} surfcache_t;
-
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-typedef struct espan_s
-{
-	int                             u, v, count;
-	struct espan_s  *pnext;
-} espan_t;
-
-// used by the polygon drawer (R_POLY.C) and sprite setup code (R_SPRITE.C)
-typedef struct
-{
-	int                     nump;
-	emitpoint_t     *pverts;
-	byte            *pixels;                        // image
-	int                     pixel_width;            // image width
-	int         pixel_height;       // image height
-	vec3_t          vup, vright, vpn;       // in worldspace, for plane eq
-	float       dist;
-	float       s_offset, t_offset;
-	float       viewer_position[3];
-	void       (*drawspanlet)( void );
-	int         stipple_parity;
-} polydesc_t;
-
-// FIXME: compress, make a union if that will help
-// insubmodel is only 1, flags is fewer than 32, spanstate could be a byte
-typedef struct surf_s
-{
-	struct surf_s   *next;                  // active surface stack in r_edge.c
-	struct surf_s   *prev;                  // used in r_edge.c for active surf stack
-	struct espan_s  *spans;                 // pointer to linked list of spans to draw
-	int                     key;                            // sorting key (BSP order)
-	int                     last_u;                         // set during tracing
-	int                     spanstate;                      // 0 = not in span
-									// 1 = in span
-									// -1 = in inverted span (end before
-									//  start)
-	int                     flags;                          // currentface flags
-	msurface_t      *msurf;
-	entity_t        *entity;
-	float           nearzi;                         // nearest 1/z on surface, for mipmapping
-	qboolean        insubmodel;
-	float           d_ziorigin, d_zistepu, d_zistepv;
-
-	int                     pad[2];                         // to 64 bytes
-} surf_t;
-
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-typedef struct edge_s
-{
-	fixed16_t               u;
-	fixed16_t               u_step;
-	struct edge_s   *prev, *next;
-	unsigned short  surfs[2];
-	struct edge_s   *nextremove;
-	float                   nearzi;
-	medge_t                 *owner;
-} edge_t;
-
-
-/*
-====================================================
-
-VARS
-
-====================================================
-*/
-
-extern int              d_spanpixcount;
-extern int              r_framecount;           // sequence # of current frame since Quake
-									//  started
-extern float    r_aliasuvscale;         // scale-up factor for screen u and v
-									//  on Alias vertices passed to driver
-extern qboolean r_dowarp;
-
-extern affinetridesc_t  r_affinetridesc;
-
-extern vec3_t   r_pright, r_pup, r_ppn;
-
-void D_DrawSurfaces (void);
-void R_DrawParticle( void );
-void D_ViewChanged (void);
-void D_WarpScreen (void);
-void R_PolysetUpdateTables (void);
-
-extern void *acolormap; // FIXME: should go away
-
-//=======================================================================//
-
-// callbacks to Quake
-
-extern drawsurf_t       r_drawsurf;
-
-void R_DrawSurface (void);
-
-extern int              c_surf;
-
-extern byte             r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
-
-
-
-
-extern float    scale_for_mip;
-
-extern qboolean         d_roverwrapped;
-extern surfcache_t      *sc_rover;
-extern surfcache_t      *d_initial_rover;
-
-extern float    d_sdivzstepu, d_tdivzstepu, d_zistepu;
-extern float    d_sdivzstepv, d_tdivzstepv, d_zistepv;
-extern float    d_sdivzorigin, d_tdivzorigin, d_ziorigin;
-
-extern  fixed16_t       sadjust, tadjust;
-extern  fixed16_t       bbextents, bbextentt;
-
-
-void D_DrawSpans16 (espan_t *pspans);
-void D_DrawZSpans (espan_t *pspans);
-void Turbulent8 (espan_t *pspan);
-void NonTurbulent8 (espan_t *pspan);	//PGM
-
-surfcache_t     *D_CacheSurface (msurface_t *surface, int miplevel);
-
-extern int      d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
-
-extern int      d_pix_min, d_pix_max, d_pix_shift;
-
-extern pixel_t  *d_viewbuffer;
-extern short *d_pzbuffer;
-extern unsigned int d_zrowbytes, d_zwidth;
-extern short    *zspantable[MAXHEIGHT];
-extern int      d_scantable[MAXHEIGHT];
-
-extern int              d_minmip;
-extern float    d_scalemip[3];
-
-//===================================================================
-
-extern int              cachewidth;
-extern pixel_t  *cacheblock;
-extern int              r_screenwidth;
-
-extern int              r_drawnpolycount;
-
-extern int      sintable[1280];
-extern int      intsintable[1280];
-extern int		blanktable[1280];		// PGM
-
-extern  vec3_t  vup, base_vup;
-extern  vec3_t  vpn, base_vpn;
-extern  vec3_t  vright, base_vright;
-
-extern  surf_t  *surfaces, *surface_p, *surf_max;
-
-// surfaces are generated in back to front order by the bsp, so if a surf
-// pointer is greater than another one, it should be drawn in front
-// surfaces[1] is the background, and is used as the active surface stack.
-// surfaces[0] is a dummy, because index 0 is used to indicate no surface
-//  attached to an edge_t
-
-//===================================================================
-
-extern vec3_t   sxformaxis[4];  // s axis transformed into viewspace
-extern vec3_t   txformaxis[4];  // t axis transformed into viewspac
-
-extern  float   xcenter, ycenter;
-extern  float   xscale, yscale;
-extern  float   xscaleinv, yscaleinv;
-extern  float   xscaleshrink, yscaleshrink;
-
-extern void TransformVector (vec3_t in, vec3_t out);
-extern void SetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
-	fixed8_t endvertu, fixed8_t endvertv);
-
-extern int      ubasestep, errorterm, erroradjustup, erroradjustdown;
-
-//===========================================================================
-
-extern cvar_t   *sw_aliasstats;
-extern cvar_t   *sw_clearcolor;
-extern cvar_t   *sw_drawflat;
-extern cvar_t   *sw_draworder;
-extern cvar_t   *sw_maxedges;
-extern cvar_t   *sw_maxsurfs;
-extern cvar_t   *sw_mipcap;
-extern cvar_t   *sw_mipscale;
-extern cvar_t   *sw_mode;
-extern cvar_t   *sw_reportsurfout;
-extern cvar_t   *sw_reportedgeout;
-extern cvar_t   *sw_stipplealpha;
-extern cvar_t   *sw_surfcacheoverride;
-extern cvar_t   *sw_waterwarp;
-
-extern cvar_t   *r_fullbright;
-extern cvar_t	*r_lefthand;
-extern cvar_t   *r_drawentities;
-extern cvar_t   *r_drawworld;
-extern cvar_t   *r_dspeeds;
-extern cvar_t   *r_lerpmodels;
-
-extern cvar_t   *r_speeds;
-
-extern cvar_t   *r_lightlevel;  //FIXME HACK
-
-extern cvar_t	*vid_fullscreen;
-extern	cvar_t	*vid_gamma;
-
-
-extern  clipplane_t     view_clipplanes[4];
-extern int              *pfrustum_indexes[4];
-
-
-//=============================================================================
-
-void R_RenderWorld (void);
-
-//=============================================================================
-
-extern  mplane_t        screenedge[4];
-
-extern  vec3_t  r_origin;
-
-extern	entity_t	r_worldentity;
-extern  model_t         *currentmodel;
-extern  entity_t                *currententity;
-extern  vec3_t  modelorg;
-extern  vec3_t  r_entorigin;
-
-extern  float   verticalFieldOfView;
-extern  float   xOrigin, yOrigin;
-
-extern  int             r_visframecount;
-
-extern msurface_t *r_alpha_surfaces;
-
-//=============================================================================
-
-void R_ClearPolyList (void);
-void R_DrawPolyList (void);
-
-//
-// current entity info
-//
-extern  qboolean                insubmodel;
-
-void R_DrawAlphaSurfaces( void );
-
-void R_DrawSprite (void);
-void R_DrawBeam( entity_t *e );
-
-void R_RenderFace (msurface_t *fa, int clipflags);
-void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf);
-void R_TransformPlane (mplane_t *p, float *normal, float *dist);
-void R_TransformFrustum (void);
-void R_DrawSurfaceBlock16 (void);
-void R_DrawSurfaceBlock8 (void);
-
-#if     id386
-
-void R_DrawSurfaceBlock8_mip0 (void);
-void R_DrawSurfaceBlock8_mip1 (void);
-void R_DrawSurfaceBlock8_mip2 (void);
-void R_DrawSurfaceBlock8_mip3 (void);
-
-#endif
-
-void R_GenSkyTile (void *pdest);
-void R_GenSkyTile16 (void *pdest);
-void R_Surf8Patch (void);
-void R_Surf16Patch (void);
-void R_DrawSubmodelPolygons (model_t *pmodel, int clipflags, mnode_t *topnode);
-void R_DrawSolidClippedSubmodelPolygons (model_t *pmodel, mnode_t *topnode);
-
-void R_AddPolygonEdges (emitpoint_t *pverts, int numverts, int miplevel);
-surf_t *R_GetSurf (void);
-void R_AliasDrawModel (void);
-void R_BeginEdgeFrame (void);
-void R_ScanEdges (void);
-void D_DrawSurfaces (void);
-void R_InsertNewEdges (edge_t *edgestoadd, edge_t *edgelist);
-void R_StepActiveU (edge_t *pedge);
-void R_RemoveEdges (edge_t *pedge);
-void R_PushDlights (model_t *model);
-
-extern void R_Surf8Start (void);
-extern void R_Surf8End (void);
-extern void R_Surf16Start (void);
-extern void R_Surf16End (void);
-extern void R_EdgeCodeStart (void);
-extern void R_EdgeCodeEnd (void);
-
-extern void R_RotateBmodel (void);
-
-extern int      c_faceclip;
-extern int      r_polycount;
-extern int      r_wholepolycount;
-
-extern int                      ubasestep, errorterm, erroradjustup, erroradjustdown;
-
-extern fixed16_t        sadjust, tadjust;
-extern fixed16_t        bbextents, bbextentt;
-
-extern mvertex_t        *r_ptverts, *r_ptvertsmax;
-
-extern float                    entity_rotation[3][3];
-
-extern int              r_currentkey;
-extern int              r_currentbkey;
-
-void    R_InitTurb (void);
-
-void R_DrawParticles (void);
-void R_SurfacePatch (void);
-
-extern int              r_amodels_drawn;
-extern edge_t   *auxedges;
-extern int              r_numallocatededges;
-extern edge_t   *r_edges, *edge_p, *edge_max;
-
-extern  edge_t  *newedges[MAXHEIGHT];
-extern  edge_t  *removeedges[MAXHEIGHT];
-
-// FIXME: make stack vars when debugging done
-extern  edge_t  edge_head;
-extern  edge_t  edge_tail;
-extern  edge_t  edge_aftertail;
-
-extern	int	r_aliasblendcolor;
-
-extern float    aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
-
-extern int              r_outofsurfaces;
-extern int              r_outofedges;
-
-extern mvertex_t        *r_pcurrentvertbase;
-extern int                      r_maxvalidedgeoffset;
-
-typedef struct
-{
-	finalvert_t *a, *b, *c;
-} aliastriangleparms_t;
-
-extern aliastriangleparms_t aliastriangleparms;
-
-void R_DrawTriangle( void );
-//void R_DrawTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2);
-void R_AliasClipTriangle (finalvert_t *index0, finalvert_t *index1, finalvert_t *index2);
-
-
-extern float    r_time1;
-extern float	da_time1, da_time2;
-extern float	dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
-extern float	se_time1, se_time2, de_time1, de_time2, dv_time1, dv_time2;
-extern int              r_frustum_indexes[4*6];
-extern int              r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
-extern qboolean r_surfsonstack;
-
-extern	mleaf_t		*r_viewleaf;
-extern	int			r_viewcluster, r_oldviewcluster;
-
-extern int              r_clipflags;
-extern int              r_dlightframecount;
-extern qboolean r_fov_greater_than_90;
-
-extern  image_t         *r_notexture_mip;
-extern  model_t         *r_worldmodel;
-
-void R_PrintAliasStats (void);
-void R_PrintTimes (void);
-void R_PrintDSpeeds (void);
-void R_AnimateLight (void);
-void R_LightPoint (vec3_t p, vec3_t color);
-void R_SetupFrame (void);
-void R_cshift_f (void);
-void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1);
-void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip);
-void R_SplitEntityOnNode2 (mnode_t *node);
-
-extern  refdef_t        r_newrefdef;
-
-extern  surfcache_t     *sc_rover, *sc_base;
-
-extern  void            *colormap;
-
-//====================================================================
-
-float R_DLightPoint (vec3_t p);
-
-void R_NewMap (void);
-void R_Register (void);
-void R_UnRegister (void);
-void Draw_InitLocal (void);
-qboolean R_Init( void *hInstance, void *wndProc );
-void R_Shutdown (void);
-void R_InitCaches (void);
-void D_FlushCaches (void);
-
-void	R_ScreenShot_f( void );
-void    R_BeginRegistration (char *map);
-struct model_s  *R_RegisterModel (char *name);
-void    R_EndRegistration (void);
-
-void    R_RenderFrame (refdef_t *fd);
-
-struct image_s  *Draw_FindPic (char *name);
-
-void    Draw_GetPicSize (int *w, int *h, char *name);
-void    Draw_Pic (int x, int y, char *name);
-void    Draw_StretchPic (int x, int y, int w, int h, char *name);
-void    Draw_StretchRaw (int x, int y, int w, int h, int cols, int rows, byte *data);
-void    Draw_Char (int x, int y, int c);
-void    Draw_TileClear (int x, int y, int w, int h, char *name);
-void    Draw_Fill (int x, int y, int w, int h, int c);
-void    Draw_FadeScreen (void);
-
-void    Draw_GetPalette (void);
-
-void	 R_BeginFrame( float camera_separation );
-
-void	R_CinematicSetPalette( const unsigned char *palette );
-
-extern unsigned d_8to24table[256]; // base
-
-void    Sys_MakeCodeWriteable (unsigned long startaddr, unsigned long length);
-void    Sys_SetFPCW (void);
-
-void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height);
-
-void    R_InitImages (void);
-void	R_ShutdownImages (void);
-image_t *R_FindImage (char *name, imagetype_t type);
-void    R_FreeUnusedImages (void);
-
-void	R_GammaCorrectAndSetPalette( const unsigned char *pal );
-
-extern mtexinfo_t  *sky_texinfo[6];
-
-void R_InitSkyBox (void);
-
-typedef struct swstate_s
-{
-	qboolean fullscreen;
-	int      prev_mode;				// last valid SW mode
-
-	byte		gammatable[256];
-	byte		currentpalette[1024];
-
-} swstate_t;
-
-void R_IMFlatShadedQuad( vec3_t a, vec3_t b, vec3_t c, vec3_t d, int color, float alpha );
-
-extern swstate_t sw_state;
-
-/*
-====================================================================
-
-IMPORTED FUNCTIONS
-
-====================================================================
-*/
-
-extern  refimport_t     ri;
-
-/*
-====================================================================
-
-IMPLEMENTATION FUNCTIONS
-
-====================================================================
-*/
-
-void		SWimp_BeginFrame( float camera_separation );
-void		SWimp_EndFrame (void);
-int			SWimp_Init( void *hInstance, void *wndProc );
-void		SWimp_SetPalette( const unsigned char *palette);
-void		SWimp_Shutdown( void );
-rserr_t		SWimp_SetMode( int *pwidth, int *pheight, int mode, qboolean fullscreen );
-void		SWimp_AppActivate( qboolean active );
-
--- a/ref_soft/r_main.c
+++ /dev/null
@@ -1,1422 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_main.c
-
-#include "r_local.h"
-
-viddef_t	vid;
-refimport_t	ri;
-
-unsigned	d_8to24table[256];
-
-entity_t	r_worldentity;
-
-char		skyname[MAX_QPATH];
-float		skyrotate;
-vec3_t		skyaxis;
-image_t		*sky_images[6];
-
-refdef_t	r_newrefdef;
-model_t		*currentmodel;
-
-model_t		*r_worldmodel;
-
-byte		r_warpbuffer[WARP_WIDTH * WARP_HEIGHT];
-
-swstate_t sw_state;
-
-void		*colormap;
-vec3_t		viewlightvec;
-alight_t	r_viewlighting = {128, 192, viewlightvec};
-float		r_time1;
-int			r_numallocatededges;
-float		r_aliasuvscale = 1.0;
-int			r_outofsurfaces;
-int			r_outofedges;
-
-qboolean	r_dowarp;
-
-mvertex_t	*r_pcurrentvertbase;
-
-int			c_surf;
-int			r_maxsurfsseen, r_maxedgesseen, r_cnumsurfs;
-qboolean	r_surfsonstack;
-int			r_clipflags;
-
-//
-// view origin
-//
-vec3_t	vup, base_vup;
-vec3_t	vpn, base_vpn;
-vec3_t	vright, base_vright;
-vec3_t	r_origin;
-
-//
-// screen size info
-//
-oldrefdef_t	r_refdef;
-float		xcenter, ycenter;
-float		xscale, yscale;
-float		xscaleinv, yscaleinv;
-float		xscaleshrink, yscaleshrink;
-float		aliasxscale, aliasyscale, aliasxcenter, aliasycenter;
-
-int		r_screenwidth;
-
-float	verticalFieldOfView;
-float	xOrigin, yOrigin;
-
-mplane_t	screenedge[4];
-
-//
-// refresh flags
-//
-int		r_framecount = 1;	// so frame counts initialized to 0 don't match
-int		r_visframecount;
-int		d_spanpixcount;
-int		r_polycount;
-int		r_drawnpolycount;
-int		r_wholepolycount;
-
-int			*pfrustum_indexes[4];
-int			r_frustum_indexes[4*6];
-
-mleaf_t		*r_viewleaf;
-int			r_viewcluster, r_oldviewcluster;
-
-image_t  	*r_notexture_mip;
-
-float	da_time1, da_time2, dp_time1, dp_time2, db_time1, db_time2, rw_time1, rw_time2;
-float	se_time1, se_time2, de_time1, de_time2;
-
-void R_MarkLeaves (void);
-
-cvar_t	*r_lefthand;
-cvar_t	*sw_aliasstats;
-cvar_t	*sw_allow_modex;
-cvar_t	*sw_clearcolor;
-cvar_t	*sw_drawflat;
-cvar_t	*sw_draworder;
-cvar_t	*sw_maxedges;
-cvar_t	*sw_maxsurfs;
-cvar_t  *sw_mode;
-cvar_t	*sw_reportedgeout;
-cvar_t	*sw_reportsurfout;
-cvar_t  *sw_stipplealpha;
-cvar_t	*sw_surfcacheoverride;
-cvar_t	*sw_waterwarp;
-
-cvar_t	*r_drawworld;
-cvar_t	*r_drawentities;
-cvar_t	*r_dspeeds;
-cvar_t	*r_fullbright;
-cvar_t  *r_lerpmodels;
-cvar_t  *r_novis;
-
-cvar_t	*r_speeds;
-cvar_t	*r_lightlevel;	//FIXME HACK
-
-cvar_t	*vid_fullscreen;
-cvar_t	*vid_gamma;
-
-//PGM
-cvar_t	*sw_lockpvs;
-//PGM
-
-#define	STRINGER(x) "x"
-
-
-#if	!id386
-
-// r_vars.c
-
-// all global and static refresh variables are collected in a contiguous block
-// to avoid cache conflicts.
-
-//-------------------------------------------------------
-// global refresh variables
-//-------------------------------------------------------
-
-// FIXME: make into one big structure, like cl or sv
-// FIXME: do separately for refresh engine and driver
-
-
-// d_vars.c
-
-// all global and static refresh variables are collected in a contiguous block
-// to avoid cache conflicts.
-
-//-------------------------------------------------------
-// global refresh variables
-//-------------------------------------------------------
-
-// FIXME: make into one big structure, like cl or sv
-// FIXME: do separately for refresh engine and driver
-
-float	d_sdivzstepu, d_tdivzstepu, d_zistepu;
-float	d_sdivzstepv, d_tdivzstepv, d_zistepv;
-float	d_sdivzorigin, d_tdivzorigin, d_ziorigin;
-
-fixed16_t	sadjust, tadjust, bbextents, bbextentt;
-
-pixel_t			*cacheblock;
-int				cachewidth;
-pixel_t			*d_viewbuffer;
-short			*d_pzbuffer;
-unsigned int	d_zrowbytes;
-unsigned int	d_zwidth;
-
-
-#endif	// !id386
-
-byte	r_notexture_buffer[1024];
-
-/*
-==================
-R_InitTextures
-==================
-*/
-void	R_InitTextures (void)
-{
-	int		x,y, m;
-	byte	*dest;
-	
-// create a simple checkerboard texture for the default
-	r_notexture_mip = (image_t *)&r_notexture_buffer;
-	
-	r_notexture_mip->width = r_notexture_mip->height = 16;
-	r_notexture_mip->pixels[0] = &r_notexture_buffer[sizeof(image_t)];
-	r_notexture_mip->pixels[1] = r_notexture_mip->pixels[0] + 16*16;
-	r_notexture_mip->pixels[2] = r_notexture_mip->pixels[1] + 8*8;
-	r_notexture_mip->pixels[3] = r_notexture_mip->pixels[2] + 4*4;
-	
-	for (m=0 ; m<4 ; m++)
-	{
-		dest = r_notexture_mip->pixels[m];
-		for (y=0 ; y< (16>>m) ; y++)
-			for (x=0 ; x< (16>>m) ; x++)
-			{
-				if (  (y< (8>>m) ) ^ (x< (8>>m) ) )
-
-					*dest++ = 0;
-				else
-					*dest++ = 0xff;
-			}
-	}	
-}
-
-
-/*
-================
-R_InitTurb
-================
-*/
-void R_InitTurb (void)
-{
-	int		i;
-	
-	for (i=0 ; i<1280 ; i++)
-	{
-		sintable[i] = AMP + sin(i*3.14159*2/CYCLE)*AMP;
-		intsintable[i] = AMP2 + sin(i*3.14159*2/CYCLE)*AMP2;	// AMP2, not 20
-		blanktable[i] = 0;			//PGM
-	}
-}
-
-void R_ImageList_f( void );
-
-void R_Register (void)
-{
-	sw_aliasstats = ri.Cvar_Get ("sw_polymodelstats", "0", 0);
-	sw_allow_modex = ri.Cvar_Get( "sw_allow_modex", "1", CVAR_ARCHIVE );
-	sw_clearcolor = ri.Cvar_Get ("sw_clearcolor", "2", 0);
-	sw_drawflat = ri.Cvar_Get ("sw_drawflat", "0", 0);
-	sw_draworder = ri.Cvar_Get ("sw_draworder", "0", 0);
-	sw_maxedges = ri.Cvar_Get ("sw_maxedges", STRINGER(MAXSTACKSURFACES), 0);
-	sw_maxsurfs = ri.Cvar_Get ("sw_maxsurfs", "0", 0);
-	sw_mipcap = ri.Cvar_Get ("sw_mipcap", "0", 0);
-	sw_mipscale = ri.Cvar_Get ("sw_mipscale", "1", 0);
-	sw_reportedgeout = ri.Cvar_Get ("sw_reportedgeout", "0", 0);
-	sw_reportsurfout = ri.Cvar_Get ("sw_reportsurfout", "0", 0);
-	sw_stipplealpha = ri.Cvar_Get( "sw_stipplealpha", "0", CVAR_ARCHIVE );
-	sw_surfcacheoverride = ri.Cvar_Get ("sw_surfcacheoverride", "0", 0);
-	sw_waterwarp = ri.Cvar_Get ("sw_waterwarp", "1", 0);
-	sw_mode = ri.Cvar_Get( "sw_mode", "0", CVAR_ARCHIVE );
-
-	r_lefthand = ri.Cvar_Get( "hand", "0", CVAR_USERINFO | CVAR_ARCHIVE );
-	r_speeds = ri.Cvar_Get ("r_speeds", "0", 0);
-	r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0);
-	r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0);
-	r_drawworld = ri.Cvar_Get ("r_drawworld", "1", 0);
-	r_dspeeds = ri.Cvar_Get ("r_dspeeds", "0", 0);
-	r_lightlevel = ri.Cvar_Get ("r_lightlevel", "0", 0);
-	r_lerpmodels = ri.Cvar_Get( "r_lerpmodels", "1", 0 );
-	r_novis = ri.Cvar_Get( "r_novis", "0", 0 );
-
-	vid_fullscreen = ri.Cvar_Get( "vid_fullscreen", "0", CVAR_ARCHIVE );
-	vid_gamma = ri.Cvar_Get( "vid_gamma", "1.0", CVAR_ARCHIVE );
-
-	ri.Cmd_AddCommand ("modellist", Mod_Modellist_f);
-	ri.Cmd_AddCommand( "screenshot", R_ScreenShot_f );
-	ri.Cmd_AddCommand( "imagelist", R_ImageList_f );
-
-	sw_mode->modified = true; // force us to do mode specific stuff later
-	vid_gamma->modified = true; // force us to rebuild the gamma table later
-
-//PGM
-	sw_lockpvs = ri.Cvar_Get ("sw_lockpvs", "0", 0);
-//PGM
-}
-
-void R_UnRegister (void)
-{
-	ri.Cmd_RemoveCommand( "screenshot" );
-	ri.Cmd_RemoveCommand ("modellist");
-	ri.Cmd_RemoveCommand( "imagelist" );
-}
-
-/*
-===============
-R_Init
-===============
-*/
-qboolean R_Init( void *hInstance, void *wndProc )
-{
-	R_InitImages ();
-	Mod_Init ();
-	Draw_InitLocal ();
-	R_InitTextures ();
-
-	R_InitTurb ();
-
-	view_clipplanes[0].leftedge = true;
-	view_clipplanes[1].rightedge = true;
-	view_clipplanes[1].leftedge = view_clipplanes[2].leftedge =
-			view_clipplanes[3].leftedge = false;
-	view_clipplanes[0].rightedge = view_clipplanes[2].rightedge =
-			view_clipplanes[3].rightedge = false;
-
-	r_refdef.xOrigin = XCENTERING;
-	r_refdef.yOrigin = YCENTERING;
-
-// TODO: collect 386-specific code in one place
-#if	id386
-	Sys_MakeCodeWriteable ((long)R_EdgeCodeStart,
-					     (long)R_EdgeCodeEnd - (long)R_EdgeCodeStart);
-	Sys_SetFPCW ();		// get bit masks for FPCW	(FIXME: is this id386?)
-#endif	// id386
-
-	r_aliasuvscale = 1.0;
-
-	R_Register ();
-	Draw_GetPalette ();
-	SWimp_Init( hInstance, wndProc );
-
-	// create the window
-	R_BeginFrame( 0 );
-
-	ri.Con_Printf (PRINT_ALL, "ref_soft version: "REF_VERSION"\n");
-
-	return true;
-}
-
-/*
-===============
-R_Shutdown
-===============
-*/
-void R_Shutdown (void)
-{
-	// free z buffer
-	if (d_pzbuffer)
-	{
-		free (d_pzbuffer);
-		d_pzbuffer = NULL;
-	}
-	// free surface cache
-	if (sc_base)
-	{
-		D_FlushCaches ();
-		free (sc_base);
-		sc_base = NULL;
-	}
-
-	// free colormap
-	if (vid.colormap)
-	{
-		free (vid.colormap);
-		vid.colormap = NULL;
-	}
-	R_UnRegister ();
-	Mod_FreeAll ();
-	R_ShutdownImages ();
-
-	SWimp_Shutdown();
-}
-
-/*
-===============
-R_NewMap
-===============
-*/
-void R_NewMap (void)
-{
-	r_viewcluster = -1;
-
-	r_cnumsurfs = sw_maxsurfs->value;
-
-	if (r_cnumsurfs <= MINSURFACES)
-		r_cnumsurfs = MINSURFACES;
-
-	if (r_cnumsurfs > NUMSTACKSURFACES)
-	{
-		surfaces = malloc (r_cnumsurfs * sizeof(surf_t));
-		surface_p = surfaces;
-		surf_max = &surfaces[r_cnumsurfs];
-		r_surfsonstack = false;
-	// surface 0 doesn't really exist; it's just a dummy because index 0
-	// is used to indicate no edge attached to surface
-		surfaces--;
-		R_SurfacePatch ();
-	}
-	else
-	{
-		r_surfsonstack = true;
-	}
-
-	r_maxedgesseen = 0;
-	r_maxsurfsseen = 0;
-
-	r_numallocatededges = sw_maxedges->value;
-
-	if (r_numallocatededges < MINEDGES)
-		r_numallocatededges = MINEDGES;
-
-	if (r_numallocatededges <= NUMSTACKEDGES)
-	{
-		auxedges = NULL;
-	}
-	else
-	{
-		auxedges = malloc (r_numallocatededges * sizeof(edge_t));
-	}
-}
-
-
-/*
-===============
-R_MarkLeaves
-
-Mark the leaves and nodes that are in the PVS for the current
-cluster
-===============
-*/
-void R_MarkLeaves (void)
-{
-	byte	*vis;
-	mnode_t	*node;
-	int		i;
-	mleaf_t	*leaf;
-	int		cluster;
-
-	if (r_oldviewcluster == r_viewcluster && !r_novis->value && r_viewcluster != -1)
-		return;
-	
-	// development aid to let you run around and see exactly where
-	// the pvs ends
-	if (sw_lockpvs->value)
-		return;
-
-	r_visframecount++;
-	r_oldviewcluster = r_viewcluster;
-
-	if (r_novis->value || r_viewcluster == -1 || !r_worldmodel->vis)
-	{
-		// mark everything
-		for (i=0 ; i<r_worldmodel->numleafs ; i++)
-			r_worldmodel->leafs[i].visframe = r_visframecount;
-		for (i=0 ; i<r_worldmodel->numnodes ; i++)
-			r_worldmodel->nodes[i].visframe = r_visframecount;
-		return;
-	}
-
-	vis = Mod_ClusterPVS (r_viewcluster, r_worldmodel);
-	
-	for (i=0,leaf=r_worldmodel->leafs ; i<r_worldmodel->numleafs ; i++, leaf++)
-	{
-		cluster = leaf->cluster;
-		if (cluster == -1)
-			continue;
-		if (vis[cluster>>3] & (1<<(cluster&7)))
-		{
-			node = (mnode_t *)leaf;
-			do
-			{
-				if (node->visframe == r_visframecount)
-					break;
-				node->visframe = r_visframecount;
-				node = node->parent;
-			} while (node);
-		}
-	}
-
-#if 0
-	for (i=0 ; i<r_worldmodel->vis->numclusters ; i++)
-	{
-		if (vis[i>>3] & (1<<(i&7)))
-		{
-			node = (mnode_t *)&r_worldmodel->leafs[i];	// FIXME: cluster
-			do
-			{
-				if (node->visframe == r_visframecount)
-					break;
-				node->visframe = r_visframecount;
-				node = node->parent;
-			} while (node);
-		}
-	}
-#endif
-}
-
-/*
-** R_DrawNullModel
-**
-** IMPLEMENT THIS!
-*/
-void R_DrawNullModel( void )
-{
-}
-
-/*
-=============
-R_DrawEntitiesOnList
-=============
-*/
-void R_DrawEntitiesOnList (void)
-{
-	int			i;
-	qboolean	translucent_entities = false;
-
-	if (!r_drawentities->value)
-		return;
-
-	// all bmodels have already been drawn by the edge list
-	for (i=0 ; i<r_newrefdef.num_entities ; i++)
-	{
-		currententity = &r_newrefdef.entities[i];
-
-		if ( currententity->flags & RF_TRANSLUCENT )
-		{
-			translucent_entities = true;
-			continue;
-		}
-
-		if ( currententity->flags & RF_BEAM )
-		{
-			modelorg[0] = -r_origin[0];
-			modelorg[1] = -r_origin[1];
-			modelorg[2] = -r_origin[2];
-			VectorCopy( vec3_origin, r_entorigin );
-			R_DrawBeam( currententity );
-		}
-		else
-		{
-			currentmodel = currententity->model;
-			if (!currentmodel)
-			{
-				R_DrawNullModel();
-				continue;
-			}
-			VectorCopy (currententity->origin, r_entorigin);
-			VectorSubtract (r_origin, r_entorigin, modelorg);
-
-			switch (currentmodel->type)
-			{
-			case mod_sprite:
-				R_DrawSprite ();
-				break;
-
-			case mod_alias:
-				R_AliasDrawModel ();
-				break;
-
-			default:
-				break;
-			}
-		}
-	}
-
-	if ( !translucent_entities )
-		return;
-
-	for (i=0 ; i<r_newrefdef.num_entities ; i++)
-	{
-		currententity = &r_newrefdef.entities[i];
-
-		if ( !( currententity->flags & RF_TRANSLUCENT ) )
-			continue;
-
-		if ( currententity->flags & RF_BEAM )
-		{
-			modelorg[0] = -r_origin[0];
-			modelorg[1] = -r_origin[1];
-			modelorg[2] = -r_origin[2];
-			VectorCopy( vec3_origin, r_entorigin );
-			R_DrawBeam( currententity );
-		}
-		else
-		{
-			currentmodel = currententity->model;
-			if (!currentmodel)
-			{
-				R_DrawNullModel();
-				continue;
-			}
-			VectorCopy (currententity->origin, r_entorigin);
-			VectorSubtract (r_origin, r_entorigin, modelorg);
-
-			switch (currentmodel->type)
-			{
-			case mod_sprite:
-				R_DrawSprite ();
-				break;
-
-			case mod_alias:
-				R_AliasDrawModel ();
-				break;
-
-			default:
-				break;
-			}
-		}
-	}
-}
-
-
-/*
-=============
-R_BmodelCheckBBox
-=============
-*/
-int R_BmodelCheckBBox (float *minmaxs)
-{
-	int			i, *pindex, clipflags;
-	vec3_t		acceptpt, rejectpt;
-	float		d;
-
-	clipflags = 0;
-
-	for (i=0 ; i<4 ; i++)
-	{
-	// generate accept and reject points
-	// FIXME: do with fast look-ups or integer tests based on the sign bit
-	// of the floating point values
-
-		pindex = pfrustum_indexes[i];
-
-		rejectpt[0] = minmaxs[pindex[0]];
-		rejectpt[1] = minmaxs[pindex[1]];
-		rejectpt[2] = minmaxs[pindex[2]];
-		
-		d = DotProduct (rejectpt, view_clipplanes[i].normal);
-		d -= view_clipplanes[i].dist;
-
-		if (d <= 0)
-			return BMODEL_FULLY_CLIPPED;
-
-		acceptpt[0] = minmaxs[pindex[3+0]];
-		acceptpt[1] = minmaxs[pindex[3+1]];
-		acceptpt[2] = minmaxs[pindex[3+2]];
-
-		d = DotProduct (acceptpt, view_clipplanes[i].normal);
-		d -= view_clipplanes[i].dist;
-
-		if (d <= 0)
-			clipflags |= (1<<i);
-	}
-
-	return clipflags;
-}
-
-
-/*
-===================
-R_FindTopnode
-
-Find the first node that splits the given box
-===================
-*/
-mnode_t *R_FindTopnode (vec3_t mins, vec3_t maxs)
-{
-	mplane_t	*splitplane;
-	int			sides;
-	mnode_t *node;
-
-	node = r_worldmodel->nodes;
-
-	while (1)
-	{
-		if (node->visframe != r_visframecount)
-			return NULL;		// not visible at all
-		
-		if (node->contents != CONTENTS_NODE)
-		{
-			if (node->contents != CONTENTS_SOLID)
-				return	node; // we've reached a non-solid leaf, so it's
-							//  visible and not BSP clipped
-			return NULL;	// in solid, so not visible
-		}
-		
-		splitplane = node->plane;
-		sides = BOX_ON_PLANE_SIDE(mins, maxs, (cplane_t *)splitplane);
-		
-		if (sides == 3)
-			return node;	// this is the splitter
-		
-	// not split yet; recurse down the contacted side
-		if (sides & 1)
-			node = node->children[0];
-		else
-			node = node->children[1];
-	}
-}
-
-
-/*
-=============
-RotatedBBox
-
-Returns an axially aligned box that contains the input box at the given rotation
-=============
-*/
-void RotatedBBox (vec3_t mins, vec3_t maxs, vec3_t angles, vec3_t tmins, vec3_t tmaxs)
-{
-	vec3_t	tmp, v;
-	int		i, j;
-	vec3_t	forward, right, up;
-
-	if (!angles[0] && !angles[1] && !angles[2])
-	{
-		VectorCopy (mins, tmins);
-		VectorCopy (maxs, tmaxs);
-		return;
-	}
-
-	for (i=0 ; i<3 ; i++)
-	{
-		tmins[i] = 99999;
-		tmaxs[i] = -99999;
-	}
-
-	AngleVectors (angles, forward, right, up);
-
-	for ( i = 0; i < 8; i++ )
-	{
-		if ( i & 1 )
-			tmp[0] = mins[0];
-		else
-			tmp[0] = maxs[0];
-
-		if ( i & 2 )
-			tmp[1] = mins[1];
-		else
-			tmp[1] = maxs[1];
-
-		if ( i & 4 )
-			tmp[2] = mins[2];
-		else
-			tmp[2] = maxs[2];
-
-
-		VectorScale (forward, tmp[0], v);
-		VectorMA (v, -tmp[1], right, v);
-		VectorMA (v, tmp[2], up, v);
-
-		for (j=0 ; j<3 ; j++)
-		{
-			if (v[j] < tmins[j])
-				tmins[j] = v[j];
-			if (v[j] > tmaxs[j])
-				tmaxs[j] = v[j];
-		}
-	}
-}
-
-/*
-=============
-R_DrawBEntitiesOnList
-=============
-*/
-void R_DrawBEntitiesOnList (void)
-{
-	int			i, clipflags;
-	vec3_t		oldorigin;
-	vec3_t		mins, maxs;
-	float		minmaxs[6];
-	mnode_t		*topnode;
-
-	if (!r_drawentities->value)
-		return;
-
-	VectorCopy (modelorg, oldorigin);
-	insubmodel = true;
-	r_dlightframecount = r_framecount;
-
-	for (i=0 ; i<r_newrefdef.num_entities ; i++)
-	{
-		currententity = &r_newrefdef.entities[i];
-		currentmodel = currententity->model;
-		if (!currentmodel)
-			continue;
-		if (currentmodel->nummodelsurfaces == 0)
-			continue;	// clip brush only
-		if ( currententity->flags & RF_BEAM )
-			continue;
-		if (currentmodel->type != mod_brush)
-			continue;
-	// see if the bounding box lets us trivially reject, also sets
-	// trivial accept status
-		RotatedBBox (currentmodel->mins, currentmodel->maxs,
-			currententity->angles, mins, maxs);
-		VectorAdd (mins, currententity->origin, minmaxs);
-		VectorAdd (maxs, currententity->origin, (minmaxs+3));
-
-		clipflags = R_BmodelCheckBBox (minmaxs);
-		if (clipflags == BMODEL_FULLY_CLIPPED)
-			continue;	// off the edge of the screen
-
-		topnode = R_FindTopnode (minmaxs, minmaxs+3);
-		if (!topnode)
-			continue;	// no part in a visible leaf
-
-		VectorCopy (currententity->origin, r_entorigin);
-		VectorSubtract (r_origin, r_entorigin, modelorg);
-
-		r_pcurrentvertbase = currentmodel->vertexes;
-
-	// FIXME: stop transforming twice
-		R_RotateBmodel ();
-
-	// calculate dynamic lighting for bmodel
-		R_PushDlights (currentmodel);
-
-		if (topnode->contents == CONTENTS_NODE)
-		{
-		// not a leaf; has to be clipped to the world BSP
-			r_clipflags = clipflags;
-			R_DrawSolidClippedSubmodelPolygons (currentmodel, topnode);
-		}
-		else
-		{
-		// falls entirely in one leaf, so we just put all the
-		// edges in the edge list and let 1/z sorting handle
-		// drawing order
-			R_DrawSubmodelPolygons (currentmodel, clipflags, topnode);
-		}
-
-	// put back world rotation and frustum clipping		
-	// FIXME: R_RotateBmodel should just work off base_vxx
-		VectorCopy (base_vpn, vpn);
-		VectorCopy (base_vup, vup);
-		VectorCopy (base_vright, vright);
-		VectorCopy (oldorigin, modelorg);
-		R_TransformFrustum ();
-	}
-
-	insubmodel = false;
-}
-
-
-/*
-================
-R_EdgeDrawing
-================
-*/
-void R_EdgeDrawing (void)
-{
-	edge_t	ledges[NUMSTACKEDGES +
-				((CACHE_SIZE - 1) / sizeof(edge_t)) + 1];
-	surf_t	lsurfs[NUMSTACKSURFACES +
-				((CACHE_SIZE - 1) / sizeof(surf_t)) + 1];
-
-	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
-		return;
-
-	if (auxedges)
-	{
-		r_edges = auxedges;
-	}
-	else
-	{
-		r_edges =  (edge_t *)
-				(((long)&ledges[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
-	}
-
-	if (r_surfsonstack)
-	{
-		surfaces =  (surf_t *)
-				(((long)&lsurfs[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
-		surf_max = &surfaces[r_cnumsurfs];
-	// surface 0 doesn't really exist; it's just a dummy because index 0
-	// is used to indicate no edge attached to surface
-		surfaces--;
-		R_SurfacePatch ();
-	}
-
-	R_BeginEdgeFrame ();
-
-	if (r_dspeeds->value)
-	{
-		rw_time1 = Sys_Milliseconds ();
-	}
-
-	R_RenderWorld ();
-
-	if (r_dspeeds->value)
-	{
-		rw_time2 = Sys_Milliseconds ();
-		db_time1 = rw_time2;
-	}
-
-	R_DrawBEntitiesOnList ();
-
-	if (r_dspeeds->value)
-	{
-		db_time2 = Sys_Milliseconds ();
-		se_time1 = db_time2;
-	}
-
-	R_ScanEdges ();
-}
-
-//=======================================================================
-
-
-/*
-=============
-R_CalcPalette
-
-=============
-*/
-void R_CalcPalette (void)
-{
-	static qboolean modified;
-	byte	palette[256][4], *in, *out;
-	int		i, j;
-	float	alpha, one_minus_alpha;
-	vec3_t	premult;
-	int		v;
-
-	alpha = r_newrefdef.blend[3];
-	if (alpha <= 0)
-	{
-		if (modified)
-		{	// set back to default
-			modified = false;
-			R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
-			return;
-		}
-		return;
-	}
-
-	modified = true;
-	if (alpha > 1)
-		alpha = 1;
-
-	premult[0] = r_newrefdef.blend[0]*alpha*255;
-	premult[1] = r_newrefdef.blend[1]*alpha*255;
-	premult[2] = r_newrefdef.blend[2]*alpha*255;
-
-	one_minus_alpha = (1.0 - alpha);
-
-	in = (byte *)d_8to24table;
-	out = palette[0];
-	for (i=0 ; i<256 ; i++, in+=4, out+=4)
-	{
-		for (j=0 ; j<3 ; j++)
-		{
-			v = premult[j] + one_minus_alpha * in[j];
-			if (v > 255)
-				v = 255;
-			out[j] = v;
-		}
-		out[3] = 255;
-	}
-
-	R_GammaCorrectAndSetPalette( ( const unsigned char * ) palette[0] );
-//	SWimp_SetPalette( palette[0] );
-}
-
-//=======================================================================
-
-void R_SetLightLevel (void)
-{
-	vec3_t		light;
-
-	if ((r_newrefdef.rdflags & RDF_NOWORLDMODEL) || (!r_drawentities->value) || (!currententity))
-	{
-		r_lightlevel->value = 150.0;
-		return;
-	}
-
-	// save off light value for server to look at (BIG HACK!)
-	R_LightPoint (r_newrefdef.vieworg, light);
-	r_lightlevel->value = 150.0 * light[0];
-}
-
-
-/*
-@@@@@@@@@@@@@@@@
-R_RenderFrame
-
-@@@@@@@@@@@@@@@@
-*/
-void R_RenderFrame (refdef_t *fd)
-{
-	r_newrefdef = *fd;
-
-	if (!r_worldmodel && !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
-		ri.Sys_Error (ERR_FATAL,"R_RenderView: NULL worldmodel");
-
-	VectorCopy (fd->vieworg, r_refdef.vieworg);
-	VectorCopy (fd->viewangles, r_refdef.viewangles);
-
-	if (r_speeds->value || r_dspeeds->value)
-		r_time1 = Sys_Milliseconds ();
-
-	R_SetupFrame ();
-
-	R_MarkLeaves ();	// done here so we know if we're in water
-
-	R_PushDlights (r_worldmodel);
-
-	R_EdgeDrawing ();
-
-	if (r_dspeeds->value)
-	{
-		se_time2 = Sys_Milliseconds ();
-		de_time1 = se_time2;
-	}
-
-	R_DrawEntitiesOnList ();
-
-	if (r_dspeeds->value)
-	{
-		de_time2 = Sys_Milliseconds ();
-		dp_time1 = Sys_Milliseconds ();
-	}
-
-	R_DrawParticles ();
-
-	if (r_dspeeds->value)
-		dp_time2 = Sys_Milliseconds ();
-
-	R_DrawAlphaSurfaces();
-
-	R_SetLightLevel ();
-
-	if (r_dowarp)
-		D_WarpScreen ();
-
-	if (r_dspeeds->value)
-		da_time1 = Sys_Milliseconds ();
-
-	if (r_dspeeds->value)
-		da_time2 = Sys_Milliseconds ();
-
-	R_CalcPalette ();
-
-	if (sw_aliasstats->value)
-		R_PrintAliasStats ();
-		
-	if (r_speeds->value)
-		R_PrintTimes ();
-
-	if (r_dspeeds->value)
-		R_PrintDSpeeds ();
-
-	if (sw_reportsurfout->value && r_outofsurfaces)
-		ri.Con_Printf (PRINT_ALL,"Short %d surfaces\n", r_outofsurfaces);
-
-	if (sw_reportedgeout->value && r_outofedges)
-		ri.Con_Printf (PRINT_ALL,"Short roughly %d edges\n", r_outofedges * 2 / 3);
-}
-
-/*
-** R_InitGraphics
-*/
-void R_InitGraphics( int width, int height )
-{
-	vid.width  = width;
-	vid.height = height;
-
-	// free z buffer
-	if ( d_pzbuffer )
-	{
-		free( d_pzbuffer );
-		d_pzbuffer = NULL;
-	}
-
-	// free surface cache
-	if ( sc_base )
-	{
-		D_FlushCaches ();
-		free( sc_base );
-		sc_base = NULL;
-	}
-
-	d_pzbuffer = malloc(vid.width*vid.height*2);
-
-	R_InitCaches ();
-
-	R_GammaCorrectAndSetPalette( ( const unsigned char *) d_8to24table );
-}
-
-/*
-** R_BeginFrame
-*/
-void R_BeginFrame( float camera_separation )
-{
-	extern void Draw_BuildGammaTable( void );
-
-	/*
-	** rebuild the gamma correction palette if necessary
-	*/
-	if ( vid_gamma->modified )
-	{
-		Draw_BuildGammaTable();
-		R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
-
-		vid_gamma->modified = false;
-	}
-
-	while ( sw_mode->modified || vid_fullscreen->modified )
-	{
-		rserr_t err;
-
-		/*
-		** if this returns rserr_invalid_fullscreen then it set the mode but not as a
-		** fullscreen mode, e.g. 320x200 on a system that doesn't support that res
-		*/
-		if ( ( err = SWimp_SetMode( &vid.width, &vid.height, sw_mode->value, vid_fullscreen->value ) ) == rserr_ok )
-		{
-			R_InitGraphics( vid.width, vid.height );
-
-			sw_state.prev_mode = sw_mode->value;
-			vid_fullscreen->modified = false;
-			sw_mode->modified = false;
-		}
-		else
-		{
-			if ( err == rserr_invalid_mode )
-			{
-				ri.Cvar_SetValue( "sw_mode", sw_state.prev_mode );
-				ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - could not set mode\n" );
-			}
-			else if ( err == rserr_invalid_fullscreen )
-			{
-				R_InitGraphics( vid.width, vid.height );
-
-				ri.Cvar_SetValue( "vid_fullscreen", 0);
-				ri.Con_Printf( PRINT_ALL, "ref_soft::R_BeginFrame() - fullscreen unavailable in this mode\n" );
-				sw_state.prev_mode = sw_mode->value;
-//				vid_fullscreen->modified = false;
-//				sw_mode->modified = false;
-			}
-			else
-			{
-				ri.Sys_Error( ERR_FATAL, "ref_soft::R_BeginFrame() - catastrophic mode change failure\n" );
-			}
-		}
-	}
-}
-
-/*
-** R_GammaCorrectAndSetPalette
-*/
-void R_GammaCorrectAndSetPalette( const unsigned char *palette )
-{
-	int i;
-
-	for ( i = 0; i < 256; i++ )
-	{
-		sw_state.currentpalette[i*4+0] = sw_state.gammatable[palette[i*4+0]];
-		sw_state.currentpalette[i*4+1] = sw_state.gammatable[palette[i*4+1]];
-		sw_state.currentpalette[i*4+2] = sw_state.gammatable[palette[i*4+2]];
-	}
-
-	SWimp_SetPalette( sw_state.currentpalette );
-}
-
-/*
-** R_CinematicSetPalette
-*/
-void R_CinematicSetPalette( const unsigned char *palette )
-{
-	byte palette32[1024];
-	int		i, j, w;
-	int		*d;
-
-	// clear screen to black to avoid any palette flash
-	w = abs(vid.rowbytes)>>2;	// stupid negative pitch win32 stuff...
-	for (i=0 ; i<vid.height ; i++, d+=w)
-	{
-		d = (int *)(vid.buffer + i*vid.rowbytes);
-		for (j=0 ; j<w ; j++)
-			d[j] = 0;
-	}
-	// flush it to the screen
-	SWimp_EndFrame ();
-
-	if ( palette )
-	{
-		for ( i = 0; i < 256; i++ )
-		{
-			palette32[i*4+0] = palette[i*3+0];
-			palette32[i*4+1] = palette[i*3+1];
-			palette32[i*4+2] = palette[i*3+2];
-			palette32[i*4+3] = 0xFF;
-		}
-
-		R_GammaCorrectAndSetPalette( palette32 );
-	}
-	else
-	{
-		R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table );
-	}
-}
-
-/*
-================
-Draw_BuildGammaTable
-================
-*/
-void Draw_BuildGammaTable (void)
-{
-	int		i, inf;
-	float	g;
-
-	g = vid_gamma->value;
-
-	if (g == 1.0)
-	{
-		for (i=0 ; i<256 ; i++)
-			sw_state.gammatable[i] = i;
-		return;
-	}
-	
-	for (i=0 ; i<256 ; i++)
-	{
-		inf = 255 * pow ( (i+0.5)/255.5 , g ) + 0.5;
-		if (inf < 0)
-			inf = 0;
-		if (inf > 255)
-			inf = 255;
-		sw_state.gammatable[i] = inf;
-	}
-}
-
-/*
-** R_DrawBeam
-*/
-void R_DrawBeam( entity_t *e )
-{
-#define NUM_BEAM_SEGS 6
-
-	int	i;
-
-	vec3_t perpvec;
-	vec3_t direction, normalized_direction;
-	vec3_t start_points[NUM_BEAM_SEGS], end_points[NUM_BEAM_SEGS];
-	vec3_t oldorigin, origin;
-
-	oldorigin[0] = e->oldorigin[0];
-	oldorigin[1] = e->oldorigin[1];
-	oldorigin[2] = e->oldorigin[2];
-
-	origin[0] = e->origin[0];
-	origin[1] = e->origin[1];
-	origin[2] = e->origin[2];
-
-	normalized_direction[0] = direction[0] = oldorigin[0] - origin[0];
-	normalized_direction[1] = direction[1] = oldorigin[1] - origin[1];
-	normalized_direction[2] = direction[2] = oldorigin[2] - origin[2];
-
-	if ( VectorNormalize( normalized_direction ) == 0 )
-		return;
-
-	PerpendicularVector( perpvec, normalized_direction );
-	VectorScale( perpvec, e->frame / 2, perpvec );
-
-	for ( i = 0; i < NUM_BEAM_SEGS; i++ )
-	{
-		RotatePointAroundVector( start_points[i], normalized_direction, perpvec, (360.0/NUM_BEAM_SEGS)*i );
-		VectorAdd( start_points[i], origin, start_points[i] );
-		VectorAdd( start_points[i], direction, end_points[i] );
-	}
-
-	for ( i = 0; i < NUM_BEAM_SEGS; i++ )
-	{
-		R_IMFlatShadedQuad( start_points[i],
-		                    end_points[i],
-							end_points[(i+1)%NUM_BEAM_SEGS],
-							start_points[(i+1)%NUM_BEAM_SEGS],
-							e->skinnum & 0xFF,
-							e->alpha );
-	}
-}
-
-
-//===================================================================
-
-/*
-============
-R_SetSky
-============
-*/
-// 3dstudio environment map names
-char	*suf[6] = {"rt", "bk", "lf", "ft", "up", "dn"};
-int	r_skysideimage[6] = {5, 2, 4, 1, 0, 3};
-extern	mtexinfo_t		r_skytexinfo[6];
-void R_SetSky (char *name, float rotate, vec3_t axis)
-{
-	int		i;
-	char	pathname[MAX_QPATH];
-
-	strncpy (skyname, name, sizeof(skyname)-1);
-	skyrotate = rotate;
-	VectorCopy (axis, skyaxis);
-
-	for (i=0 ; i<6 ; i++)
-	{
-		Com_sprintf (pathname, sizeof(pathname), "env/%s%s.pcx", skyname, suf[r_skysideimage[i]]);
-		r_skytexinfo[i].image = R_FindImage (pathname, it_sky);
-	}
-}
-
-
-/*
-===============
-Draw_GetPalette
-===============
-*/
-void Draw_GetPalette (void)
-{
-	byte	*pal, *out;
-	int		i;
-	int		r, g, b;
-
-	// get the palette and colormap
-	LoadPCX ("pics/colormap.pcx", &vid.colormap, &pal, NULL, NULL);
-	if (!vid.colormap)
-		ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx");
-	vid.alphamap = vid.colormap + 64*256;
-
-	out = (byte *)d_8to24table;
-	for (i=0 ; i<256 ; i++, out+=4)
-	{
-		r = pal[i*3+0];
-		g = pal[i*3+1];
-		b = pal[i*3+2];
-
-        out[0] = r;
-        out[1] = g;
-        out[2] = b;
-	}
-
-	free (pal);
-}
-
-struct image_s *R_RegisterSkin (char *name);
-
-/*
-@@@@@@@@@@@@@@@@@@@@@
-GetRefAPI
-
-@@@@@@@@@@@@@@@@@@@@@
-*/
-refexport_t GetRefAPI (refimport_t rimp)
-{
-	refexport_t	re;
-
-	ri = rimp;
-
-	re.api_version = API_VERSION;
-
-	re.BeginRegistration = R_BeginRegistration;
-    re.RegisterModel = R_RegisterModel;
-    re.RegisterSkin = R_RegisterSkin;
-	re.RegisterPic = Draw_FindPic;
-	re.SetSky = R_SetSky;
-	re.EndRegistration = R_EndRegistration;
-
-	re.RenderFrame = R_RenderFrame;
-
-	re.DrawGetPicSize = Draw_GetPicSize;
-	re.DrawPic = Draw_Pic;
-	re.DrawStretchPic = Draw_StretchPic;
-	re.DrawChar = Draw_Char;
-	re.DrawTileClear = Draw_TileClear;
-	re.DrawFill = Draw_Fill;
-	re.DrawFadeScreen= Draw_FadeScreen;
-
-	re.DrawStretchRaw = Draw_StretchRaw;
-
-	re.Init = R_Init;
-	re.Shutdown = R_Shutdown;
-
-	re.CinematicSetPalette = R_CinematicSetPalette;
-	re.BeginFrame = R_BeginFrame;
-	re.EndFrame = SWimp_EndFrame;
-
-	re.AppActivate = SWimp_AppActivate;
-
-	Swap_Init ();
-
-	return re;
-}
-
-#ifndef REF_HARD_LINKED
-// this is only here so the functions in q_shared.c and q_shwin.c can link
-void Sys_Error (char *error, ...)
-{
-	va_list		argptr;
-	char		text[1024];
-
-	va_start (argptr, error);
-	vsprintf (text, error, argptr);
-	va_end (argptr);
-
-	ri.Sys_Error (ERR_FATAL, "%s", text);
-}
-
-void Com_Printf (char *fmt, ...)
-{
-	va_list		argptr;
-	char		text[1024];
-
-	va_start (argptr, fmt);
-	vsprintf (text, fmt, argptr);
-	va_end (argptr);
-
-	ri.Con_Printf (PRINT_ALL, "%s", text);
-}
-
-#endif
--- a/ref_soft/r_misc.c
+++ /dev/null
@@ -1,670 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_misc.c
-
-#include "r_local.h"
-
-#define NUM_MIPS	4
-
-cvar_t	*sw_mipcap;
-cvar_t	*sw_mipscale;
-
-surfcache_t		*d_initial_rover;
-qboolean		d_roverwrapped;
-int				d_minmip;
-float			d_scalemip[NUM_MIPS-1];
-
-static float	basemip[NUM_MIPS-1] = {1.0, 0.5*0.8, 0.25*0.8};
-
-extern int			d_aflatcolor;
-
-int	d_vrectx, d_vrecty, d_vrectright_particle, d_vrectbottom_particle;
-
-int	d_pix_min, d_pix_max, d_pix_shift;
-
-int		d_scantable[MAXHEIGHT];
-short	*zspantable[MAXHEIGHT]; 
-
-/*
-================
-D_Patch
-================
-*/
-void D_Patch (void)
-{
-#if id386
-	extern void D_Aff8Patch( void );
-	static qboolean protectset8 = false;
-	extern void D_PolysetAff8Start( void );
-
-	if (!protectset8)
-	{
-		Sys_MakeCodeWriteable ((int)D_PolysetAff8Start,
-						     (int)D_Aff8Patch - (int)D_PolysetAff8Start);
-		Sys_MakeCodeWriteable ((long)R_Surf8Start,
-						 (long)R_Surf8End - (long)R_Surf8Start);
-		protectset8 = true;
-	}
-	colormap = vid.colormap;
-
-	R_Surf8Patch ();
-	D_Aff8Patch();
-#endif
-}
-/*
-================
-D_ViewChanged
-================
-*/
-unsigned char *alias_colormap;
-
-void D_ViewChanged (void)
-{
-	int		i;
-
-	scale_for_mip = xscale;
-	if (yscale > xscale)
-		scale_for_mip = yscale;
-
-	d_zrowbytes = vid.width * 2;
-	d_zwidth = vid.width;
-
-	d_pix_min = r_refdef.vrect.width / 320;
-	if (d_pix_min < 1)
-		d_pix_min = 1;
-
-	d_pix_max = (int)((float)r_refdef.vrect.width / (320.0 / 4.0) + 0.5);
-	d_pix_shift = 8 - (int)((float)r_refdef.vrect.width / 320.0 + 0.5);
-	if (d_pix_max < 1)
-		d_pix_max = 1;
-
-	d_vrectx = r_refdef.vrect.x;
-	d_vrecty = r_refdef.vrect.y;
-	d_vrectright_particle = r_refdef.vrectright - d_pix_max;
-	d_vrectbottom_particle =
-			r_refdef.vrectbottom - d_pix_max;
-
-	for (i=0 ; i<vid.height; i++)
-	{
-		d_scantable[i] = i*r_screenwidth;
-		zspantable[i] = d_pzbuffer + i*d_zwidth;
-	}
-
-	/*
-	** clear Z-buffer and color-buffers if we're doing the gallery
-	*/
-	if ( r_newrefdef.rdflags & RDF_NOWORLDMODEL )
-	{
-		memset( d_pzbuffer, 0xff, vid.width * vid.height * sizeof( d_pzbuffer[0] ) );
-		Draw_Fill( r_newrefdef.x, r_newrefdef.y, r_newrefdef.width, r_newrefdef.height,( int ) sw_clearcolor->value & 0xff );
-	}
-
-	alias_colormap = vid.colormap;
-
-	D_Patch ();
-}
-
-
-
-/*
-=============
-R_PrintTimes
-=============
-*/
-void R_PrintTimes (void)
-{
-	int		r_time2;
-	int		ms;
-
-	r_time2 = Sys_Milliseconds ();
-
-	ms = r_time2 - r_time1;
-	
-	ri.Con_Printf (PRINT_ALL,"%5i ms %3i/%3i/%3i poly %3i surf\n",
-				ms, c_faceclip, r_polycount, r_drawnpolycount, c_surf);
-	c_surf = 0;
-}
-
-
-/*
-=============
-R_PrintDSpeeds
-=============
-*/
-void R_PrintDSpeeds (void)
-{
-	int	ms, dp_time, r_time2, rw_time, db_time, se_time, de_time, da_time;
-
-	r_time2 = Sys_Milliseconds ();
-
-	da_time = (da_time2 - da_time1);
-	dp_time = (dp_time2 - dp_time1);
-	rw_time = (rw_time2 - rw_time1);
-	db_time = (db_time2 - db_time1);
-	se_time = (se_time2 - se_time1);
-	de_time = (de_time2 - de_time1);
-	ms = (r_time2 - r_time1);
-
-	ri.Con_Printf (PRINT_ALL,"%3i %2ip %2iw %2ib %2is %2ie %2ia\n",
-				ms, dp_time, rw_time, db_time, se_time, de_time, da_time);
-}
-
-
-/*
-=============
-R_PrintAliasStats
-=============
-*/
-void R_PrintAliasStats (void)
-{
-	ri.Con_Printf (PRINT_ALL,"%3i polygon model drawn\n", r_amodels_drawn);
-}
-
-
-
-/*
-===================
-R_TransformFrustum
-===================
-*/
-void R_TransformFrustum (void)
-{
-	int		i;
-	vec3_t	v, v2;
-	
-	for (i=0 ; i<4 ; i++)
-	{
-		v[0] = screenedge[i].normal[2];
-		v[1] = -screenedge[i].normal[0];
-		v[2] = screenedge[i].normal[1];
-
-		v2[0] = v[1]*vright[0] + v[2]*vup[0] + v[0]*vpn[0];
-		v2[1] = v[1]*vright[1] + v[2]*vup[1] + v[0]*vpn[1];
-		v2[2] = v[1]*vright[2] + v[2]*vup[2] + v[0]*vpn[2];
-
-		VectorCopy (v2, view_clipplanes[i].normal);
-
-		view_clipplanes[i].dist = DotProduct (modelorg, v2);
-	}
-}
-
-
-#if !(defined __linux__ && defined __i386__)
-#if !id386
-
-/*
-================
-TransformVector
-================
-*/
-void TransformVector (vec3_t in, vec3_t out)
-{
-	out[0] = DotProduct(in,vright);
-	out[1] = DotProduct(in,vup);
-	out[2] = DotProduct(in,vpn);		
-}
-
-#else
-
-__declspec( naked ) void TransformVector( vec3_t vin, vec3_t vout )
-{
-	__asm mov eax, dword ptr [esp+4]
-	__asm mov edx, dword ptr [esp+8]
-
-	__asm fld  dword ptr [eax+0]
-	__asm fmul dword ptr [vright+0]
-	__asm fld  dword ptr [eax+0]
-	__asm fmul dword ptr [vup+0]
-	__asm fld  dword ptr [eax+0]
-	__asm fmul dword ptr [vpn+0]
-
-	__asm fld  dword ptr [eax+4]
-	__asm fmul dword ptr [vright+4]
-	__asm fld  dword ptr [eax+4]
-	__asm fmul dword ptr [vup+4]
-	__asm fld  dword ptr [eax+4]
-	__asm fmul dword ptr [vpn+4]
-
-	__asm fxch st(2)
-
-	__asm faddp st(5), st(0)
-	__asm faddp st(3), st(0)
-	__asm faddp st(1), st(0)
-
-	__asm fld  dword ptr [eax+8]
-	__asm fmul dword ptr [vright+8]
-	__asm fld  dword ptr [eax+8]
-	__asm fmul dword ptr [vup+8]
-	__asm fld  dword ptr [eax+8]
-	__asm fmul dword ptr [vpn+8]
-
-	__asm fxch st(2)
-
-	__asm faddp st(5), st(0)
-	__asm faddp st(3), st(0)
-	__asm faddp st(1), st(0)
-
-	__asm fstp dword ptr [edx+8]
-	__asm fstp dword ptr [edx+4]
-	__asm fstp dword ptr [edx+0]
-
-	__asm ret
-}
-
-#endif
-#endif
-
-
-/*
-================
-R_TransformPlane
-================
-*/
-void R_TransformPlane (mplane_t *p, float *normal, float *dist)
-{
-	float	d;
-	
-	d = DotProduct (r_origin, p->normal);
-	*dist = p->dist - d;
-// TODO: when we have rotating entities, this will need to use the view matrix
-	TransformVector (p->normal, normal);
-}
-
-
-/*
-===============
-R_SetUpFrustumIndexes
-===============
-*/
-void R_SetUpFrustumIndexes (void)
-{
-	int		i, j, *pindex;
-
-	pindex = r_frustum_indexes;
-
-	for (i=0 ; i<4 ; i++)
-	{
-		for (j=0 ; j<3 ; j++)
-		{
-			if (view_clipplanes[i].normal[j] < 0)
-			{
-				pindex[j] = j;
-				pindex[j+3] = j+3;
-			}
-			else
-			{
-				pindex[j] = j+3;
-				pindex[j+3] = j;
-			}
-		}
-
-	// FIXME: do just once at start
-		pfrustum_indexes[i] = pindex;
-		pindex += 6;
-	}
-}
-
-/*
-===============
-R_ViewChanged
-
-Called every time the vid structure or r_refdef changes.
-Guaranteed to be called before the first refresh
-===============
-*/
-void R_ViewChanged (vrect_t *vr)
-{
-	int		i;
-
-	r_refdef.vrect = *vr;
-
-	r_refdef.horizontalFieldOfView = 2*tan((float)r_newrefdef.fov_x/360*M_PI);;
-	verticalFieldOfView = 2*tan((float)r_newrefdef.fov_y/360*M_PI);
-
-	r_refdef.fvrectx = (float)r_refdef.vrect.x;
-	r_refdef.fvrectx_adj = (float)r_refdef.vrect.x - 0.5;
-	r_refdef.vrect_x_adj_shift20 = (r_refdef.vrect.x<<20) + (1<<19) - 1;
-	r_refdef.fvrecty = (float)r_refdef.vrect.y;
-	r_refdef.fvrecty_adj = (float)r_refdef.vrect.y - 0.5;
-	r_refdef.vrectright = r_refdef.vrect.x + r_refdef.vrect.width;
-	r_refdef.vrectright_adj_shift20 = (r_refdef.vrectright<<20) + (1<<19) - 1;
-	r_refdef.fvrectright = (float)r_refdef.vrectright;
-	r_refdef.fvrectright_adj = (float)r_refdef.vrectright - 0.5;
-	r_refdef.vrectrightedge = (float)r_refdef.vrectright - 0.99;
-	r_refdef.vrectbottom = r_refdef.vrect.y + r_refdef.vrect.height;
-	r_refdef.fvrectbottom = (float)r_refdef.vrectbottom;
-	r_refdef.fvrectbottom_adj = (float)r_refdef.vrectbottom - 0.5;
-
-	r_refdef.aliasvrect.x = (int)(r_refdef.vrect.x * r_aliasuvscale);
-	r_refdef.aliasvrect.y = (int)(r_refdef.vrect.y * r_aliasuvscale);
-	r_refdef.aliasvrect.width = (int)(r_refdef.vrect.width * r_aliasuvscale);
-	r_refdef.aliasvrect.height = (int)(r_refdef.vrect.height * r_aliasuvscale);
-	r_refdef.aliasvrectright = r_refdef.aliasvrect.x +
-			r_refdef.aliasvrect.width;
-	r_refdef.aliasvrectbottom = r_refdef.aliasvrect.y +
-			r_refdef.aliasvrect.height;
-
-	xOrigin = r_refdef.xOrigin;
-	yOrigin = r_refdef.yOrigin;
-	
-// values for perspective projection
-// if math were exact, the values would range from 0.5 to to range+0.5
-// hopefully they wll be in the 0.000001 to range+.999999 and truncate
-// the polygon rasterization will never render in the first row or column
-// but will definately render in the [range] row and column, so adjust the
-// buffer origin to get an exact edge to edge fill
-	xcenter = ((float)r_refdef.vrect.width * XCENTERING) +
-			r_refdef.vrect.x - 0.5;
-	aliasxcenter = xcenter * r_aliasuvscale;
-	ycenter = ((float)r_refdef.vrect.height * YCENTERING) +
-			r_refdef.vrect.y - 0.5;
-	aliasycenter = ycenter * r_aliasuvscale;
-
-	xscale = r_refdef.vrect.width / r_refdef.horizontalFieldOfView;
-	aliasxscale = xscale * r_aliasuvscale;
-	xscaleinv = 1.0 / xscale;
-
-	yscale = xscale;
-	aliasyscale = yscale * r_aliasuvscale;
-	yscaleinv = 1.0 / yscale;
-	xscaleshrink = (r_refdef.vrect.width-6)/r_refdef.horizontalFieldOfView;
-	yscaleshrink = xscaleshrink;
-
-// left side clip
-	screenedge[0].normal[0] = -1.0 / (xOrigin*r_refdef.horizontalFieldOfView);
-	screenedge[0].normal[1] = 0;
-	screenedge[0].normal[2] = 1;
-	screenedge[0].type = PLANE_ANYZ;
-	
-// right side clip
-	screenedge[1].normal[0] =
-			1.0 / ((1.0-xOrigin)*r_refdef.horizontalFieldOfView);
-	screenedge[1].normal[1] = 0;
-	screenedge[1].normal[2] = 1;
-	screenedge[1].type = PLANE_ANYZ;
-	
-// top side clip
-	screenedge[2].normal[0] = 0;
-	screenedge[2].normal[1] = -1.0 / (yOrigin*verticalFieldOfView);
-	screenedge[2].normal[2] = 1;
-	screenedge[2].type = PLANE_ANYZ;
-	
-// bottom side clip
-	screenedge[3].normal[0] = 0;
-	screenedge[3].normal[1] = 1.0 / ((1.0-yOrigin)*verticalFieldOfView);
-	screenedge[3].normal[2] = 1;	
-	screenedge[3].type = PLANE_ANYZ;
-	
-	for (i=0 ; i<4 ; i++)
-		VectorNormalize (screenedge[i].normal);
-
-	D_ViewChanged ();
-}
-
-
-/*
-===============
-R_SetupFrame
-===============
-*/
-void R_SetupFrame (void)
-{
-	int			i;
-	vrect_t		vrect;
-
-	if (r_fullbright->modified)
-	{
-		r_fullbright->modified = false;
-		D_FlushCaches ();	// so all lighting changes
-	}
-	
-	r_framecount++;
-
-
-// build the transformation matrix for the given view angles
-	VectorCopy (r_refdef.vieworg, modelorg);
-	VectorCopy (r_refdef.vieworg, r_origin);
-
-	AngleVectors (r_refdef.viewangles, vpn, vright, vup);
-
-// current viewleaf
-	if ( !( r_newrefdef.rdflags & RDF_NOWORLDMODEL ) )
-	{
-		r_viewleaf = Mod_PointInLeaf (r_origin, r_worldmodel);
-		r_viewcluster = r_viewleaf->cluster;
-	}
-
-	if (sw_waterwarp->value && (r_newrefdef.rdflags & RDF_UNDERWATER) )
-		r_dowarp = true;
-	else
-		r_dowarp = false;
-
-	if (r_dowarp)
-	{	// warp into off screen buffer
-		vrect.x = 0;
-		vrect.y = 0;
-		vrect.width = r_newrefdef.width < WARP_WIDTH ? r_newrefdef.width : WARP_WIDTH;
-		vrect.height = r_newrefdef.height < WARP_HEIGHT ? r_newrefdef.height : WARP_HEIGHT;
-
-		d_viewbuffer = r_warpbuffer;
-		r_screenwidth = WARP_WIDTH;
-	}
-	else
-	{
-		vrect.x = r_newrefdef.x;
-		vrect.y = r_newrefdef.y;
-		vrect.width = r_newrefdef.width;
-		vrect.height = r_newrefdef.height;
-
-		d_viewbuffer = (void *)vid.buffer;
-		r_screenwidth = vid.rowbytes;
-	}
-	
-	R_ViewChanged (&vrect);
-
-// start off with just the four screen edge clip planes
-	R_TransformFrustum ();
-	R_SetUpFrustumIndexes ();
-
-// save base values
-	VectorCopy (vpn, base_vpn);
-	VectorCopy (vright, base_vright);
-	VectorCopy (vup, base_vup);
-
-// clear frame counts
-	c_faceclip = 0;
-	d_spanpixcount = 0;
-	r_polycount = 0;
-	r_drawnpolycount = 0;
-	r_wholepolycount = 0;
-	r_amodels_drawn = 0;
-	r_outofsurfaces = 0;
-	r_outofedges = 0;
-
-// d_setup
-	d_roverwrapped = false;
-	d_initial_rover = sc_rover;
-
-	d_minmip = sw_mipcap->value;
-	if (d_minmip > 3)
-		d_minmip = 3;
-	else if (d_minmip < 0)
-		d_minmip = 0;
-
-	for (i=0 ; i<(NUM_MIPS-1) ; i++)
-		d_scalemip[i] = basemip[i] * sw_mipscale->value;
-
-	d_aflatcolor = 0;
-}
-
-
-#if	!id386
-
-/*
-================
-R_SurfacePatch
-================
-*/
-void R_SurfacePatch (void)
-{
-	// we only patch code on Intel
-}
-
-#endif	// !id386
-
-
-/* 
-============================================================================== 
- 
-						SCREEN SHOTS 
- 
-============================================================================== 
-*/ 
-
-
-/* 
-============== 
-WritePCXfile 
-============== 
-*/ 
-void WritePCXfile (char *filename, byte *data, int width, int height,
-	int rowbytes, byte *palette) 
-{
-	int			i, j, length;
-	pcx_t		*pcx;
-	byte		*pack;
-	FILE		*f;
-
-	pcx = (pcx_t *)malloc (width*height*2+1000);
-	if (!pcx)
-		return;
-
-	pcx->manufacturer = 0x0a;	// PCX id
-	pcx->version = 5;			// 256 color
- 	pcx->encoding = 1;		// uncompressed
-	pcx->bits_per_pixel = 8;		// 256 color
-	pcx->xmin = 0;
-	pcx->ymin = 0;
-	pcx->xmax = LittleShort((short)(width-1));
-	pcx->ymax = LittleShort((short)(height-1));
-	pcx->hres = LittleShort((short)width);
-	pcx->vres = LittleShort((short)height);
-	memset (pcx->palette,0,sizeof(pcx->palette));
-	pcx->color_planes = 1;		// chunky image
-	pcx->bytes_per_line = LittleShort((short)width);
-	pcx->palette_type = LittleShort(2);		// not a grey scale
-	memset (pcx->filler,0,sizeof(pcx->filler));
-
-// pack the image
-	pack = &pcx->data;
-	
-	for (i=0 ; i<height ; i++)
-	{
-		for (j=0 ; j<width ; j++)
-		{
-			if ( (*data & 0xc0) != 0xc0)
-				*pack++ = *data++;
-			else
-			{
-				*pack++ = 0xc1;
-				*pack++ = *data++;
-			}
-		}
-
-		data += rowbytes - width;
-	}
-			
-// write the palette
-	*pack++ = 0x0c;	// palette ID byte
-	for (i=0 ; i<768 ; i++)
-		*pack++ = *palette++;
-		
-// write output file 
-	length = pack - (byte *)pcx;
-	f = fopen (filename, "wb");
-	if (!f)
-		ri.Con_Printf (PRINT_ALL, "Failed to open to %s\n", filename);
-	else
-	{
-		fwrite ((void *)pcx, 1, length, f);
-		fclose (f);
-	}
-
-	free (pcx);
-} 
- 
-
-
-/* 
-================== 
-R_ScreenShot_f
-================== 
-*/  
-void R_ScreenShot_f (void) 
-{ 
-	int			i; 
-	char		pcxname[80]; 
-	char		checkname[MAX_OSPATH];
-	FILE		*f;
-	byte		palette[768];
-
-	// create the scrnshots directory if it doesn't exist
-	Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir());
-	Sys_Mkdir (checkname);
-
-// 
-// find a file name to save it to 
-// 
-	strcpy(pcxname,"quake00.pcx");
-		
-	for (i=0 ; i<=99 ; i++) 
-	{ 
-		pcxname[5] = i/10 + '0'; 
-		pcxname[6] = i%10 + '0'; 
-		Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), pcxname);
-		f = fopen (checkname, "r");
-		if (!f)
-			break;	// file doesn't exist
-		fclose (f);
-	} 
-	if (i==100) 
-	{
-		ri.Con_Printf (PRINT_ALL, "R_ScreenShot_f: Couldn't create a PCX"); 
-		return;
-	}
-
-	// turn the current 32 bit palette into a 24 bit palette
-	for (i=0 ; i<256 ; i++)
-	{
-		palette[i*3+0] = sw_state.currentpalette[i*4+0];
-		palette[i*3+1] = sw_state.currentpalette[i*4+1];
-		palette[i*3+2] = sw_state.currentpalette[i*4+2];
-	}
-
-// 
-// save the pcx file 
-// 
-
-	WritePCXfile (checkname, vid.buffer, vid.width, vid.height, vid.rowbytes,
-				  palette);
-
-	ri.Con_Printf (PRINT_ALL, "Wrote %s\n", checkname);
-} 
-
--- a/ref_soft/r_model.c
+++ /dev/null
@@ -1,1241 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// models.c -- model loading and caching
-
-// models are the only shared resource between a client and server running
-// on the same machine.
-
-#include "r_local.h"
-
-model_t	*loadmodel;
-char	loadname[32];	// for hunk tags
-
-void Mod_LoadSpriteModel (model_t *mod, void *buffer);
-void Mod_LoadBrushModel (model_t *mod, void *buffer);
-void Mod_LoadAliasModel (model_t *mod, void *buffer);
-model_t *Mod_LoadModel (model_t *mod, qboolean crash);
-
-byte	mod_novis[MAX_MAP_LEAFS/8];
-
-#define	MAX_MOD_KNOWN	256
-model_t	mod_known[MAX_MOD_KNOWN];
-int		mod_numknown;
-
-// the inline * models from the current map are kept seperate
-model_t	mod_inline[MAX_MOD_KNOWN];
-
-int		registration_sequence;
-int		modfilelen;
-
-//===============================================================================
-
-
-/*
-================
-Mod_Modellist_f
-================
-*/
-void Mod_Modellist_f (void)
-{
-	int		i;
-	model_t	*mod;
-	int		total;
-
-	total = 0;
-	ri.Con_Printf (PRINT_ALL,"Loaded models:\n");
-	for (i=0, mod=mod_known ; i < mod_numknown ; i++, mod++)
-	{
-		if (!mod->name[0])
-			continue;
-		ri.Con_Printf (PRINT_ALL, "%8i : %s\n",mod->extradatasize, mod->name);
-		total += mod->extradatasize;
-	}
-	ri.Con_Printf (PRINT_ALL, "Total resident: %i\n", total);
-}
-
-/*
-===============
-Mod_Init
-===============
-*/
-void Mod_Init (void)
-{
-	memset (mod_novis, 0xff, sizeof(mod_novis));
-}
-
-/*
-==================
-Mod_ForName
-
-Loads in a model for the given name
-==================
-*/
-model_t *Mod_ForName (char *name, qboolean crash)
-{
-	model_t	*mod;
-	unsigned *buf;
-	int		i;
-	
-	if (!name[0])
-		ri.Sys_Error (ERR_DROP,"Mod_ForName: NULL name");
-
-	//
-	// inline models are grabbed only from worldmodel
-	//
-	if (name[0] == '*')
-	{
-		i = atoi(name+1);
-		if (i < 1 || !r_worldmodel || i >= r_worldmodel->numsubmodels)
-			ri.Sys_Error (ERR_DROP, "bad inline model number");
-		return &mod_inline[i];
-	}
-
-	//
-	// search the currently loaded models
-	//
-	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
-		if (!strcmp (mod->name, name) )
-			return mod;
-			
-	//
-	// find a free model slot spot
-	//
-	for (i=0 , mod=mod_known ; i<mod_numknown ; i++, mod++)
-	{
-		if (!mod->name[0])
-			break;	// free spot
-	}
-	if (i == mod_numknown)
-	{
-		if (mod_numknown == MAX_MOD_KNOWN)
-			ri.Sys_Error (ERR_DROP, "mod_numknown == MAX_MOD_KNOWN");
-		mod_numknown++;
-	}
-	strcpy (mod->name, name);
-	
-	//
-	// load the file
-	//
-	modfilelen = ri.FS_LoadFile (mod->name, (void **)&buf);
-	if (!buf)
-	{
-		if (crash)
-			ri.Sys_Error (ERR_DROP,"Mod_NumForName: %s not found", mod->name);
-		memset (mod->name, 0, sizeof(mod->name));
-		return NULL;
-	}
-	
-	loadmodel = mod;
-
-	//
-	// fill it in
-	//
-
-	// call the apropriate loader
-	
-	switch (LittleLong(*(unsigned *)buf))
-	{
-	case IDALIASHEADER:
-		loadmodel->extradata = Hunk_Begin (0x200000);
-		Mod_LoadAliasModel (mod, buf);
-		break;
-		
-	case IDSPRITEHEADER:
-		loadmodel->extradata = Hunk_Begin (0x10000);
-		Mod_LoadSpriteModel (mod, buf);
-		break;
-	
-	case IDBSPHEADER:
-		loadmodel->extradata = Hunk_Begin (0x1000000);
-		Mod_LoadBrushModel (mod, buf);
-		break;
-
-	default:
-		ri.Sys_Error (ERR_DROP,"Mod_NumForName: unknown fileid for %s", mod->name);
-		break;
-	}
-
-	loadmodel->extradatasize = Hunk_End ();
-
-	ri.FS_FreeFile (buf);
-
-	return mod;
-}
-
-
-/*
-===============
-Mod_PointInLeaf
-===============
-*/
-mleaf_t *Mod_PointInLeaf (vec3_t p, model_t *model)
-{
-	mnode_t		*node;
-	float		d;
-	mplane_t	*plane;
-	
-	if (!model || !model->nodes)
-		ri.Sys_Error (ERR_DROP, "Mod_PointInLeaf: bad model");
-
-	node = model->nodes;
-	while (1)
-	{
-		if (node->contents != -1)
-			return (mleaf_t *)node;
-		plane = node->plane;
-		d = DotProduct (p,plane->normal) - plane->dist;
-		if (d > 0)
-			node = node->children[0];
-		else
-			node = node->children[1];
-	}
-	
-	return NULL;	// never reached
-}
-
-
-/*
-===================
-Mod_DecompressVis
-===================
-*/
-byte *Mod_DecompressVis (byte *in, model_t *model)
-{
-	static byte	decompressed[MAX_MAP_LEAFS/8];
-	int		c;
-	byte	*out;
-	int		row;
-
-	row = (model->vis->numclusters+7)>>3;	
-	out = decompressed;
-
-#if 0
-	memcpy (out, in, row);
-#else
-	if (!in)
-	{	// no vis info, so make all visible
-		while (row)
-		{
-			*out++ = 0xff;
-			row--;
-		}
-		return decompressed;		
-	}
-
-	do
-	{
-		if (*in)
-		{
-			*out++ = *in++;
-			continue;
-		}
-	
-		c = in[1];
-		in += 2;
-		while (c)
-		{
-			*out++ = 0;
-			c--;
-		}
-	} while (out - decompressed < row);
-#endif
-	
-	return decompressed;
-}
-
-/*
-==============
-Mod_ClusterPVS
-==============
-*/
-byte *Mod_ClusterPVS (int cluster, model_t *model)
-{
-	if (cluster == -1 || !model->vis)
-		return mod_novis;
-	return Mod_DecompressVis ( (byte *)model->vis + model->vis->bitofs[cluster][DVIS_PVS],
-		model);
-}
-
-/*
-===============================================================================
-
-					BRUSHMODEL LOADING
-
-===============================================================================
-*/
-
-byte	*mod_base;
-
-
-/*
-=================
-Mod_LoadLighting
-
-Converts the 24 bit lighting down to 8 bit
-by taking the brightest component
-=================
-*/
-void Mod_LoadLighting (lump_t *l)
-{
-	int		i, size;
-	byte	*in;
-
-	if (!l->filelen)
-	{
-		loadmodel->lightdata = NULL;
-		return;
-	}
-	size = l->filelen/3;
-	loadmodel->lightdata = Hunk_Alloc (size);
-	in = (void *)(mod_base + l->fileofs);
-	for (i=0 ; i<size ; i++, in+=3)
-	{
-		if (in[0] > in[1] && in[0] > in[2])
-			loadmodel->lightdata[i] = in[0];
-		else if (in[1] > in[0] && in[1] > in[2])
-			loadmodel->lightdata[i] = in[1];
-		else
-			loadmodel->lightdata[i] = in[2];
-	}
-}
-
-
-int		r_leaftovis[MAX_MAP_LEAFS];
-int		r_vistoleaf[MAX_MAP_LEAFS];
-int		r_numvisleafs;
-
-void	R_NumberLeafs (mnode_t *node)
-{
-	mleaf_t	*leaf;
-	int		leafnum;
-
-	if (node->contents != -1)
-	{
-		leaf = (mleaf_t *)node;
-		leafnum = leaf - loadmodel->leafs;
-		if (leaf->contents & CONTENTS_SOLID)
-			return;
-		r_leaftovis[leafnum] = r_numvisleafs;
-		r_vistoleaf[r_numvisleafs] = leafnum;
-		r_numvisleafs++;
-		return;
-	}
-
-	R_NumberLeafs (node->children[0]);
-	R_NumberLeafs (node->children[1]);
-}
-
-
-/*
-=================
-Mod_LoadVisibility
-=================
-*/
-void Mod_LoadVisibility (lump_t *l)
-{
-	int		i;
-
-	if (!l->filelen)
-	{
-		loadmodel->vis = NULL;
-		return;
-	}
-	loadmodel->vis = Hunk_Alloc ( l->filelen);	
-	memcpy (loadmodel->vis, mod_base + l->fileofs, l->filelen);
-
-	loadmodel->vis->numclusters = LittleLong (loadmodel->vis->numclusters);
-	for (i=0 ; i<loadmodel->vis->numclusters ; i++)
-	{
-		loadmodel->vis->bitofs[i][0] = LittleLong (loadmodel->vis->bitofs[i][0]);
-		loadmodel->vis->bitofs[i][1] = LittleLong (loadmodel->vis->bitofs[i][1]);
-	}
-}
-
-
-/*
-=================
-Mod_LoadVertexes
-=================
-*/
-void Mod_LoadVertexes (lump_t *l)
-{
-	dvertex_t	*in;
-	mvertex_t	*out;
-	int			i, count;
-
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( (count+8)*sizeof(*out));		// extra for skybox
-
-	loadmodel->vertexes = out;
-	loadmodel->numvertexes = count;
-
-	for ( i=0 ; i<count ; i++, in++, out++)
-	{
-		out->position[0] = LittleFloat (in->point[0]);
-		out->position[1] = LittleFloat (in->point[1]);
-		out->position[2] = LittleFloat (in->point[2]);
-	}
-}
-
-/*
-=================
-Mod_LoadSubmodels
-=================
-*/
-void Mod_LoadSubmodels (lump_t *l)
-{
-	dmodel_t	*in;
-	dmodel_t	*out;
-	int			i, j, count;
-
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( count*sizeof(*out));	
-
-	loadmodel->submodels = out;
-	loadmodel->numsubmodels = count;
-
-	for ( i=0 ; i<count ; i++, in++, out++)
-	{
-		for (j=0 ; j<3 ; j++)
-		{	// spread the mins / maxs by a pixel
-			out->mins[j] = LittleFloat (in->mins[j]) - 1;
-			out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
-			out->origin[j] = LittleFloat (in->origin[j]);
-		}
-		out->headnode = LittleLong (in->headnode);
-		out->firstface = LittleLong (in->firstface);
-		out->numfaces = LittleLong (in->numfaces);
-	}
-}
-
-/*
-=================
-Mod_LoadEdges
-=================
-*/
-void Mod_LoadEdges (lump_t *l)
-{
-	dedge_t *in;
-	medge_t *out;
-	int 	i, count;
-
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( (count + 13) * sizeof(*out));	// extra for skybox
-
-	loadmodel->edges = out;
-	loadmodel->numedges = count;
-
-	for ( i=0 ; i<count ; i++, in++, out++)
-	{
-		out->v[0] = (unsigned short)LittleShort(in->v[0]);
-		out->v[1] = (unsigned short)LittleShort(in->v[1]);
-	}
-}
-
-/*
-=================
-Mod_LoadTexinfo
-=================
-*/
-void Mod_LoadTexinfo (lump_t *l)
-{
-	texinfo_t *in;
-	mtexinfo_t *out, *step;
-	int 	i, j, count;
-	float	len1, len2;
-	char	name[MAX_QPATH];
-	int		next;
-
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( (count+6)*sizeof(*out));	// extra for skybox
-
-	loadmodel->texinfo = out;
-	loadmodel->numtexinfo = count;
-
-	for ( i=0 ; i<count ; i++, in++, out++)
-	{
-		for (j=0 ; j<8 ; j++)
-			out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
-		len1 = VectorLength (out->vecs[0]);
-		len2 = VectorLength (out->vecs[1]);
-		len1 = (len1 + len2)/2;
-		if (len1 < 0.32)
-			out->mipadjust = 4;
-		else if (len1 < 0.49)
-			out->mipadjust = 3;
-		else if (len1 < 0.99)
-			out->mipadjust = 2;
-		else
-			out->mipadjust = 1;
-#if 0
-		if (len1 + len2 < 0.001)
-			out->mipadjust = 1;		// don't crash
-		else
-			out->mipadjust = 1 / floor( (len1+len2)/2 + 0.1 );
-#endif
-
-		out->flags = LittleLong (in->flags);
-
-		next = LittleLong (in->nexttexinfo);
-		if (next > 0)
-			out->next = loadmodel->texinfo + next;
-
-		Com_sprintf (name, sizeof(name), "textures/%s.wal", in->texture);
-		out->image = R_FindImage (name, it_wall);
-		if (!out->image)
-		{
-			out->image = r_notexture_mip; // texture not found
-			out->flags = 0;
-		}
-	}
-
-	// count animation frames
-	for (i=0 ; i<count ; i++)
-	{
-		out = &loadmodel->texinfo[i];
-		out->numframes = 1;
-		for (step = out->next ; step && step != out ; step=step->next)
-			out->numframes++;
-	}
-}
-
-/*
-================
-CalcSurfaceExtents
-
-Fills in s->texturemins[] and s->extents[]
-================
-*/
-void CalcSurfaceExtents (msurface_t *s)
-{
-	float	mins[2], maxs[2], val;
-	int		i,j, e;
-	mvertex_t	*v;
-	mtexinfo_t	*tex;
-	int		bmins[2], bmaxs[2];
-
-	mins[0] = mins[1] = 999999;
-	maxs[0] = maxs[1] = -99999;
-
-	tex = s->texinfo;
-	
-	for (i=0 ; i<s->numedges ; i++)
-	{
-		e = loadmodel->surfedges[s->firstedge+i];
-		if (e >= 0)
-			v = &loadmodel->vertexes[loadmodel->edges[e].v[0]];
-		else
-			v = &loadmodel->vertexes[loadmodel->edges[-e].v[1]];
-		
-		for (j=0 ; j<2 ; j++)
-		{
-			val = v->position[0] * tex->vecs[j][0] + 
-				v->position[1] * tex->vecs[j][1] +
-				v->position[2] * tex->vecs[j][2] +
-				tex->vecs[j][3];
-			if (val < mins[j])
-				mins[j] = val;
-			if (val > maxs[j])
-				maxs[j] = val;
-		}
-	}
-
-	for (i=0 ; i<2 ; i++)
-	{	
-		bmins[i] = floor(mins[i]/16);
-		bmaxs[i] = ceil(maxs[i]/16);
-
-		s->texturemins[i] = bmins[i] * 16;
-		s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
-		if (s->extents[i] < 16)
-			s->extents[i] = 16;	// take at least one cache block
-		if ( !(tex->flags & (SURF_WARP|SURF_SKY)) && s->extents[i] > 256)
-			ri.Sys_Error (ERR_DROP,"Bad surface extents");
-	}
-}
-
-
-/*
-=================
-Mod_LoadFaces
-=================
-*/
-void Mod_LoadFaces (lump_t *l)
-{
-	dface_t		*in;
-	msurface_t 	*out;
-	int			i, count, surfnum;
-	int			planenum, side;
-
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( (count+6)*sizeof(*out));	// extra for skybox
-
-	loadmodel->surfaces = out;
-	loadmodel->numsurfaces = count;
-
-	for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
-	{
-		out->firstedge = LittleLong(in->firstedge);
-		out->numedges = LittleShort(in->numedges);		
-		if (out->numedges < 3)
-			ri.Sys_Error (ERR_DROP,"Surface with %s edges", out->numedges);
-		out->flags = 0;
-
-		planenum = LittleShort(in->planenum);
-		side = LittleShort(in->side);
-		if (side)
-			out->flags |= SURF_PLANEBACK;			
-
-		out->plane = loadmodel->planes + planenum;
-
-		out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo);
-
-		CalcSurfaceExtents (out);
-				
-	// lighting info is converted from 24 bit on disk to 8 bit
-
-		for (i=0 ; i<MAXLIGHTMAPS ; i++)
-			out->styles[i] = in->styles[i];
-		i = LittleLong(in->lightofs);
-		if (i == -1)
-			out->samples = NULL;
-		else
-			out->samples = loadmodel->lightdata + i/3;
-		
-	// set the drawing flags flag
-		
-		if (!out->texinfo->image)
-			continue;
-		if (out->texinfo->flags & SURF_SKY)
-		{
-			out->flags |= SURF_DRAWSKY;
-			continue;
-		}
-		
-		if (out->texinfo->flags & SURF_WARP)
-		{
-			out->flags |= SURF_DRAWTURB;
-			for (i=0 ; i<2 ; i++)
-			{
-				out->extents[i] = 16384;
-				out->texturemins[i] = -8192;
-			}
-			continue;
-		}
-//==============
-//PGM
-		// this marks flowing surfaces as turbulent, but with the new
-		// SURF_FLOW flag.
-		if (out->texinfo->flags & SURF_FLOWING)
-		{
-			out->flags |= SURF_DRAWTURB | SURF_FLOW;
-			for (i=0 ; i<2 ; i++)
-			{
-				out->extents[i] = 16384;
-				out->texturemins[i] = -8192;
-			}
-			continue;
-		}
-//PGM
-//==============
-	}
-}
-
-
-/*
-=================
-Mod_SetParent
-=================
-*/
-void Mod_SetParent (mnode_t *node, mnode_t *parent)
-{
-	node->parent = parent;
-	if (node->contents != -1)
-		return;
-	Mod_SetParent (node->children[0], node);
-	Mod_SetParent (node->children[1], node);
-}
-
-/*
-=================
-Mod_LoadNodes
-=================
-*/
-void Mod_LoadNodes (lump_t *l)
-{
-	int			i, j, count, p;
-	dnode_t		*in;
-	mnode_t 	*out;
-
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( count*sizeof(*out));	
-
-	loadmodel->nodes = out;
-	loadmodel->numnodes = count;
-
-	for ( i=0 ; i<count ; i++, in++, out++)
-	{
-		for (j=0 ; j<3 ; j++)
-		{
-			out->minmaxs[j] = LittleShort (in->mins[j]);
-			out->minmaxs[3+j] = LittleShort (in->maxs[j]);
-		}
-	
-		p = LittleLong(in->planenum);
-		out->plane = loadmodel->planes + p;
-
-		out->firstsurface = LittleShort (in->firstface);
-		out->numsurfaces = LittleShort (in->numfaces);
-		out->contents = CONTENTS_NODE;	// differentiate from leafs
-		
-		for (j=0 ; j<2 ; j++)
-		{
-			p = LittleLong (in->children[j]);
-			if (p >= 0)
-				out->children[j] = loadmodel->nodes + p;
-			else
-				out->children[j] = (mnode_t *)(loadmodel->leafs + (-1 - p));
-		}
-	}
-	
-	Mod_SetParent (loadmodel->nodes, NULL);	// sets nodes and leafs
-}
-
-/*
-=================
-Mod_LoadLeafs
-=================
-*/
-void Mod_LoadLeafs (lump_t *l)
-{
-	dleaf_t 	*in;
-	mleaf_t 	*out;
-	int			i, j, count;
-
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( count*sizeof(*out));
-
-	loadmodel->leafs = out;
-	loadmodel->numleafs = count;
-
-	for ( i=0 ; i<count ; i++, in++, out++)
-	{
-		for (j=0 ; j<3 ; j++)
-		{
-			out->minmaxs[j] = LittleShort (in->mins[j]);
-			out->minmaxs[3+j] = LittleShort (in->maxs[j]);
-		}
-
-		out->contents = LittleLong(in->contents);
-		out->cluster = LittleShort(in->cluster);
-		out->area = LittleShort(in->area);
-
-		out->firstmarksurface = loadmodel->marksurfaces +
-			LittleShort(in->firstleafface);
-		out->nummarksurfaces = LittleShort(in->numleaffaces);
-	}	
-}
-
-
-/*
-=================
-Mod_LoadMarksurfaces
-=================
-*/
-void Mod_LoadMarksurfaces (lump_t *l)
-{	
-	int		i, j, count;
-	short		*in;
-	msurface_t **out;
-	
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( count*sizeof(*out));	
-
-	loadmodel->marksurfaces = out;
-	loadmodel->nummarksurfaces = count;
-
-	for ( i=0 ; i<count ; i++)
-	{
-		j = LittleShort(in[i]);
-		if (j >= loadmodel->numsurfaces)
-			ri.Sys_Error (ERR_DROP,"Mod_ParseMarksurfaces: bad surface number");
-		out[i] = loadmodel->surfaces + j;
-	}
-}
-
-/*
-=================
-Mod_LoadSurfedges
-=================
-*/
-void Mod_LoadSurfedges (lump_t *l)
-{	
-	int		i, count;
-	int		*in, *out;
-	
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( (count+24)*sizeof(*out));	// extra for skybox
-
-	loadmodel->surfedges = out;
-	loadmodel->numsurfedges = count;
-
-	for ( i=0 ; i<count ; i++)
-		out[i] = LittleLong (in[i]);
-}
-
-/*
-=================
-Mod_LoadPlanes
-=================
-*/
-void Mod_LoadPlanes (lump_t *l)
-{
-	int			i, j;
-	mplane_t	*out;
-	dplane_t 	*in;
-	int			count;
-	int			bits;
-	
-	in = (void *)(mod_base + l->fileofs);
-	if (l->filelen % sizeof(*in))
-		ri.Sys_Error (ERR_DROP,"MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
-	count = l->filelen / sizeof(*in);
-	out = Hunk_Alloc ( (count+6)*sizeof(*out));		// extra for skybox
-	
-	loadmodel->planes = out;
-	loadmodel->numplanes = count;
-
-	for ( i=0 ; i<count ; i++, in++, out++)
-	{
-		bits = 0;
-		for (j=0 ; j<3 ; j++)
-		{
-			out->normal[j] = LittleFloat (in->normal[j]);
-			if (out->normal[j] < 0)
-				bits |= 1<<j;
-		}
-
-		out->dist = LittleFloat (in->dist);
-		out->type = LittleLong (in->type);
-		out->signbits = bits;
-	}
-}
-
-
-/*
-=================
-Mod_LoadBrushModel
-=================
-*/
-void Mod_LoadBrushModel (model_t *mod, void *buffer)
-{
-	int			i;
-	dheader_t	*header;
-	dmodel_t 	*bm;
-	
-	loadmodel->type = mod_brush;
-	if (loadmodel != mod_known)
-		ri.Sys_Error (ERR_DROP, "Loaded a brush model after the world");
-	
-	header = (dheader_t *)buffer;
-
-	i = LittleLong (header->version);
-	if (i != BSPVERSION)
-		ri.Sys_Error (ERR_DROP,"Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION);
-
-// swap all the lumps
-	mod_base = (byte *)header;
-
-	for (i=0 ; i<sizeof(dheader_t)/4 ; i++)
-		((int *)header)[i] = LittleLong ( ((int *)header)[i]);
-
-// load into heap
-	
-	Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
-	Mod_LoadEdges (&header->lumps[LUMP_EDGES]);
-	Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
-	Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
-	Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
-	Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
-	Mod_LoadFaces (&header->lumps[LUMP_FACES]);
-	Mod_LoadMarksurfaces (&header->lumps[LUMP_LEAFFACES]);
-	Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
-	Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]);
-	Mod_LoadNodes (&header->lumps[LUMP_NODES]);
-	Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);
-	r_numvisleafs = 0;
-	R_NumberLeafs (loadmodel->nodes);
-	
-//
-// set up the submodels
-//
-	for (i=0 ; i<mod->numsubmodels ; i++)
-	{
-		model_t	*starmod;
-
-		bm = &mod->submodels[i];
-		starmod = &mod_inline[i];
-
-		*starmod = *loadmodel;
-		
-		starmod->firstmodelsurface = bm->firstface;
-		starmod->nummodelsurfaces = bm->numfaces;
-		starmod->firstnode = bm->headnode;
-		if (starmod->firstnode >= loadmodel->numnodes)
-			ri.Sys_Error (ERR_DROP, "Inline model %i has bad firstnode", i);
-
-		VectorCopy (bm->maxs, starmod->maxs);
-		VectorCopy (bm->mins, starmod->mins);
-	
-		if (i == 0)
-			*loadmodel = *starmod;
-	}
-
-	R_InitSkyBox ();
-}
-
-/*
-==============================================================================
-
-ALIAS MODELS
-
-==============================================================================
-*/
-
-/*
-=================
-Mod_LoadAliasModel
-=================
-*/
-void Mod_LoadAliasModel (model_t *mod, void *buffer)
-{
-	int					i, j;
-	dmdl_t				*pinmodel, *pheader;
-	dstvert_t			*pinst, *poutst;
-	dtriangle_t			*pintri, *pouttri;
-	daliasframe_t		*pinframe, *poutframe;
-	int					*pincmd, *poutcmd;
-	int					version;
-
-	pinmodel = (dmdl_t *)buffer;
-
-	version = LittleLong (pinmodel->version);
-	if (version != ALIAS_VERSION)
-		ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
-				 mod->name, version, ALIAS_VERSION);
-
-	pheader = Hunk_Alloc (LittleLong(pinmodel->ofs_end));
-	
-	// byte swap the header fields and sanity check
-	for (i=0 ; i<sizeof(dmdl_t)/4 ; i++)
-		((int *)pheader)[i] = LittleLong (((int *)buffer)[i]);
-
-	if (pheader->skinheight > MAX_LBM_HEIGHT)
-		ri.Sys_Error (ERR_DROP, "model %s has a skin taller than %d", mod->name,
-				   MAX_LBM_HEIGHT);
-
-	if (pheader->num_xyz <= 0)
-		ri.Sys_Error (ERR_DROP, "model %s has no vertices", mod->name);
-
-	if (pheader->num_xyz > MAX_VERTS)
-		ri.Sys_Error (ERR_DROP, "model %s has too many vertices", mod->name);
-
-	if (pheader->num_st <= 0)
-		ri.Sys_Error (ERR_DROP, "model %s has no st vertices", mod->name);
-
-	if (pheader->num_tris <= 0)
-		ri.Sys_Error (ERR_DROP, "model %s has no triangles", mod->name);
-
-	if (pheader->num_frames <= 0)
-		ri.Sys_Error (ERR_DROP, "model %s has no frames", mod->name);
-
-//
-// load base s and t vertices (not used in gl version)
-//
-	pinst = (dstvert_t *) ((byte *)pinmodel + pheader->ofs_st);
-	poutst = (dstvert_t *) ((byte *)pheader + pheader->ofs_st);
-
-	for (i=0 ; i<pheader->num_st ; i++)
-	{
-		poutst[i].s = LittleShort (pinst[i].s);
-		poutst[i].t = LittleShort (pinst[i].t);
-	}
-
-//
-// load triangle lists
-//
-	pintri = (dtriangle_t *) ((byte *)pinmodel + pheader->ofs_tris);
-	pouttri = (dtriangle_t *) ((byte *)pheader + pheader->ofs_tris);
-
-	for (i=0 ; i<pheader->num_tris ; i++)
-	{
-		for (j=0 ; j<3 ; j++)
-		{
-			pouttri[i].index_xyz[j] = LittleShort (pintri[i].index_xyz[j]);
-			pouttri[i].index_st[j] = LittleShort (pintri[i].index_st[j]);
-		}
-	}
-
-//
-// load the frames
-//
-	for (i=0 ; i<pheader->num_frames ; i++)
-	{
-		pinframe = (daliasframe_t *) ((byte *)pinmodel 
-			+ pheader->ofs_frames + i * pheader->framesize);
-		poutframe = (daliasframe_t *) ((byte *)pheader 
-			+ pheader->ofs_frames + i * pheader->framesize);
-
-		memcpy (poutframe->name, pinframe->name, sizeof(poutframe->name));
-		for (j=0 ; j<3 ; j++)
-		{
-			poutframe->scale[j] = LittleFloat (pinframe->scale[j]);
-			poutframe->translate[j] = LittleFloat (pinframe->translate[j]);
-		}
-		// verts are all 8 bit, so no swapping needed
-		memcpy (poutframe->verts, pinframe->verts, 
-			pheader->num_xyz*sizeof(dtrivertx_t));
-
-	}
-
-	mod->type = mod_alias;
-
-	//
-	// load the glcmds
-	//
-	pincmd = (int *) ((byte *)pinmodel + pheader->ofs_glcmds);
-	poutcmd = (int *) ((byte *)pheader + pheader->ofs_glcmds);
-	for (i=0 ; i<pheader->num_glcmds ; i++)
-		poutcmd[i] = LittleLong (pincmd[i]);
-
-
-	// register all skins
-	memcpy ((char *)pheader + pheader->ofs_skins, (char *)pinmodel + pheader->ofs_skins,
-		pheader->num_skins*MAX_SKINNAME);
-	for (i=0 ; i<pheader->num_skins ; i++)
-	{
-		mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
-	}
-}
-
-/*
-==============================================================================
-
-SPRITE MODELS
-
-==============================================================================
-*/
-
-/*
-=================
-Mod_LoadSpriteModel
-=================
-*/
-void Mod_LoadSpriteModel (model_t *mod, void *buffer)
-{
-	dsprite_t	*sprin, *sprout;
-	int			i;
-
-	sprin = (dsprite_t *)buffer;
-	sprout = Hunk_Alloc (modfilelen);
-
-	sprout->ident = LittleLong (sprin->ident);
-	sprout->version = LittleLong (sprin->version);
-	sprout->numframes = LittleLong (sprin->numframes);
-
-	if (sprout->version != SPRITE_VERSION)
-		ri.Sys_Error (ERR_DROP, "%s has wrong version number (%i should be %i)",
-				 mod->name, sprout->version, SPRITE_VERSION);
-
-	if (sprout->numframes > MAX_MD2SKINS)
-		ri.Sys_Error (ERR_DROP, "%s has too many frames (%i > %i)",
-				 mod->name, sprout->numframes, MAX_MD2SKINS);
-
-	// byte swap everything
-	for (i=0 ; i<sprout->numframes ; i++)
-	{
-		sprout->frames[i].width = LittleLong (sprin->frames[i].width);
-		sprout->frames[i].height = LittleLong (sprin->frames[i].height);
-		sprout->frames[i].origin_x = LittleLong (sprin->frames[i].origin_x);
-		sprout->frames[i].origin_y = LittleLong (sprin->frames[i].origin_y);
-		memcpy (sprout->frames[i].name, sprin->frames[i].name, MAX_SKINNAME);
-		mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite);
-	}
-
-	mod->type = mod_sprite;
-}
-
-//=============================================================================
-
-/*
-@@@@@@@@@@@@@@@@@@@@@
-R_BeginRegistration
-
-Specifies the model that will be used as the world
-@@@@@@@@@@@@@@@@@@@@@
-*/
-void R_BeginRegistration (char *model)
-{
-	char	fullname[MAX_QPATH];
-	cvar_t	*flushmap;
-
-	registration_sequence++;
-	r_oldviewcluster = -1;		// force markleafs
-	Com_sprintf (fullname, sizeof(fullname), "maps/%s.bsp", model);
-
-	D_FlushCaches ();
-	// explicitly free the old map if different
-	// this guarantees that mod_known[0] is the world map
-	flushmap = ri.Cvar_Get ("flushmap", "0", 0);
-	if ( strcmp(mod_known[0].name, fullname) || flushmap->value)
-		Mod_Free (&mod_known[0]);
-	r_worldmodel = R_RegisterModel (fullname);
-	R_NewMap ();
-}
-
-
-/*
-@@@@@@@@@@@@@@@@@@@@@
-R_RegisterModel
-
-@@@@@@@@@@@@@@@@@@@@@
-*/
-struct model_s *R_RegisterModel (char *name)
-{
-	model_t	*mod;
-	int		i;
-	dsprite_t	*sprout;
-	dmdl_t		*pheader;
-
-	mod = Mod_ForName (name, false);
-	if (mod)
-	{
-		mod->registration_sequence = registration_sequence;
-
-		// register any images used by the models
-		if (mod->type == mod_sprite)
-		{
-			sprout = (dsprite_t *)mod->extradata;
-			for (i=0 ; i<sprout->numframes ; i++)
-				mod->skins[i] = R_FindImage (sprout->frames[i].name, it_sprite);
-		}
-		else if (mod->type == mod_alias)
-		{
-			pheader = (dmdl_t *)mod->extradata;
-			for (i=0 ; i<pheader->num_skins ; i++)
-				mod->skins[i] = R_FindImage ((char *)pheader + pheader->ofs_skins + i*MAX_SKINNAME, it_skin);
-//PGM
-			mod->numframes = pheader->num_frames;
-//PGM
-		}
-		else if (mod->type == mod_brush)
-		{
-			for (i=0 ; i<mod->numtexinfo ; i++)
-				mod->texinfo[i].image->registration_sequence = registration_sequence;
-		}
-	}
-	return mod;
-}
-
-/*
-@@@@@@@@@@@@@@@@@@@@@
-R_EndRegistration
-
-@@@@@@@@@@@@@@@@@@@@@
-*/
-void R_EndRegistration (void)
-{
-	int		i;
-	model_t	*mod;
-
-	for (i=0, mod=mod_known ; i<mod_numknown ; i++, mod++)
-	{
-		if (!mod->name[0])
-			continue;
-		if (mod->registration_sequence != registration_sequence)
-		{	// don't need this model
-			Hunk_Free (mod->extradata);
-			memset (mod, 0, sizeof(*mod));
-		}
-		else
-		{	// make sure it is paged in
-			Com_PageInMemory (mod->extradata, mod->extradatasize);
-		}
-	}
-
-	R_FreeUnusedImages ();
-}
-
-
-//=============================================================================
-
-/*
-================
-Mod_Free
-================
-*/
-void Mod_Free (model_t *mod)
-{
-	Hunk_Free (mod->extradata);
-	memset (mod, 0, sizeof(*mod));
-}
-
-/*
-================
-Mod_FreeAll
-================
-*/
-void Mod_FreeAll (void)
-{
-	int		i;
-
-	for (i=0 ; i<mod_numknown ; i++)
-	{
-		if (mod_known[i].extradatasize)
-			Mod_Free (&mod_known[i]);
-	}
-}
--- a/ref_soft/r_model.h
+++ /dev/null
@@ -1,256 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-
-#ifndef __MODEL__
-#define __MODEL__
-
-/*
-
-d*_t structures are on-disk representations
-m*_t structures are in-memory
-
-*/
-
-
-/*
-==============================================================================
-
-BRUSH MODELS
-
-==============================================================================
-*/
-
-
-//
-// in memory representation
-//
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-typedef struct
-{
-	vec3_t		position;
-} mvertex_t;
-
-#define	SIDE_FRONT	0
-#define	SIDE_BACK	1
-#define	SIDE_ON		2
-
-
-// plane_t structure
-// !!! if this is changed, it must be changed in asm_i386.h too !!!
-typedef struct mplane_s
-{
-	vec3_t	normal;
-	float	dist;
-	byte	type;			// for texture axis selection and fast side tests
-	byte	signbits;		// signx + signy<<1 + signz<<1
-	byte	pad[2];
-} mplane_t;
-
-
-// FIXME: differentiate from texinfo SURF_ flags
-#define	SURF_PLANEBACK		2
-#define	SURF_DRAWSKY		4			// sky brush face
-#define SURF_DRAWTURB		0x10
-#define SURF_DRAWBACKGROUND	0x40
-#define SURF_DRAWSKYBOX		0x80		// sky box
-
-#define SURF_FLOW			0x100		//PGM
-
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-typedef struct
-{
-	unsigned short	v[2];
-	unsigned int	cachededgeoffset;
-} medge_t;
-
-typedef struct mtexinfo_s
-{
-	float		vecs[2][4];
-	float		mipadjust;
-	image_t		*image;
-	int			flags;
-	int			numframes;
-	struct mtexinfo_s	*next;		// animation chain
-} mtexinfo_t;
-
-typedef struct msurface_s
-{
-	int			visframe;		// should be drawn when node is crossed
-
-	int			dlightframe;
-	int			dlightbits;
-
-	mplane_t	*plane;
-	int			flags;
-
-	int			firstedge;	// look up in model->surfedges[], negative numbers
-	int			numedges;	// are backwards edges
-	
-// surface generation data
-	struct surfcache_s	*cachespots[MIPLEVELS];
-
-	short		texturemins[2];
-	short		extents[2];
-
-	mtexinfo_t	*texinfo;
-	
-// lighting info
-	byte		styles[MAXLIGHTMAPS];
-	byte		*samples;		// [numstyles*surfsize]
-
-	struct msurface_s *nextalphasurface;
-} msurface_t;
-
-
-#define	CONTENTS_NODE	-1
-typedef struct mnode_s
-{
-// common with leaf
-	int			contents;		// CONTENTS_NODE, to differentiate from leafs
-	int			visframe;		// node needs to be traversed if current
-	
-	short		minmaxs[6];		// for bounding box culling
-
-	struct mnode_s	*parent;
-
-// node specific
-	mplane_t	*plane;
-	struct mnode_s	*children[2];	
-
-	unsigned short		firstsurface;
-	unsigned short		numsurfaces;
-} mnode_t;
-
-
-
-typedef struct mleaf_s
-{
-// common with node
-	int			contents;		// wil be something other than CONTENTS_NODE
-	int			visframe;		// node needs to be traversed if current
-
-	short		minmaxs[6];		// for bounding box culling
-
-	struct mnode_s	*parent;
-
-// leaf specific
-	int			cluster;
-	int			area;
-
-	msurface_t	**firstmarksurface;
-	int			nummarksurfaces;
-	int			key;			// BSP sequence number for leaf's contents
-} mleaf_t;
-
-
-//===================================================================
-
-//
-// Whole model
-//
-
-typedef enum {mod_bad, mod_brush, mod_sprite, mod_alias } modtype_t;
-
-typedef struct model_s
-{
-	char		name[MAX_QPATH];
-
-	int			registration_sequence;
-
-	modtype_t	type;
-	int			numframes;
-	
-	int			flags;
-
-//
-// volume occupied by the model graphics
-//		
-	vec3_t		mins, maxs;
-
-//
-// solid volume for clipping (sent from server)
-//
-	qboolean	clipbox;
-	vec3_t		clipmins, clipmaxs;
-
-//
-// brush model
-//
-	int			firstmodelsurface, nummodelsurfaces;
-
-	int			numsubmodels;
-	dmodel_t	*submodels;
-
-	int			numplanes;
-	mplane_t	*planes;
-
-	int			numleafs;		// number of visible leafs, not counting 0
-	mleaf_t		*leafs;
-
-	int			numvertexes;
-	mvertex_t	*vertexes;
-
-	int			numedges;
-	medge_t		*edges;
-
-	int			numnodes;
-	int			firstnode;
-	mnode_t		*nodes;
-
-	int			numtexinfo;
-	mtexinfo_t	*texinfo;
-
-	int			numsurfaces;
-	msurface_t	*surfaces;
-
-	int			numsurfedges;
-	int			*surfedges;
-
-	int			nummarksurfaces;
-	msurface_t	**marksurfaces;
-
-	dvis_t		*vis;
-
-	byte		*lightdata;
-
-	// for alias models and sprites
-	image_t		*skins[MAX_MD2SKINS];
-	void		*extradata;
-	int			extradatasize;
-} model_t;
-
-//============================================================================
-
-void	Mod_Init (void);
-void	Mod_ClearAll (void);
-model_t *Mod_ForName (char *name, qboolean crash);
-void	*Mod_Extradata (model_t *mod);	// handles caching
-void	Mod_TouchModel (char *name);
-
-mleaf_t *Mod_PointInLeaf (float *p, model_t *model);
-byte	*Mod_ClusterPVS (int cluster, model_t *model);
-
-void Mod_Modellist_f (void);
-void Mod_FreeAll (void);
-void Mod_Free (model_t *mod);
-
-extern	int		registration_sequence;
-
-#endif	// __MODEL__
--- a/ref_soft/r_part.c
+++ /dev/null
@@ -1,638 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-#include "r_local.h"
-
-vec3_t r_pright, r_pup, r_ppn;
-
-#define PARTICLE_33     0
-#define PARTICLE_66     1
-#define PARTICLE_OPAQUE 2
-
-typedef struct
-{
-	particle_t *particle;
-	int         level;
-	int         color;
-} partparms_t;
-
-static partparms_t partparms;
-
-#if id386 && !defined __linux__
-
-static unsigned s_prefetch_address;
-
-/*
-** BlendParticleXX
-**
-** Inputs:
-** EAX = color
-** EDI = pdest
-**
-** Scratch:
-** EBX = scratch (dstcolor)
-** EBP = scratch
-**
-** Outputs:
-** none
-*/
-__declspec(naked) void BlendParticle33( void )
-{
-	//	return vid.alphamap[color + dstcolor*256];
-	__asm mov ebp, vid.alphamap
-	__asm xor ebx, ebx
-
-	__asm mov bl,  byte ptr [edi]
-	__asm shl ebx, 8
-
-	__asm add ebp, ebx
-	__asm add ebp, eax
-
-	__asm mov al,  byte ptr [ebp]
-
-	__asm mov byte ptr [edi], al
-
-	__asm ret
-}
-
-__declspec(naked) void BlendParticle66( void )
-{
-	//	return vid.alphamap[pcolor*256 + dstcolor];
-	__asm mov ebp, vid.alphamap
-	__asm xor ebx, ebx
-
-	__asm shl eax,  8
-	__asm mov bl,   byte ptr [edi]
-
-	__asm add ebp, ebx
-	__asm add ebp, eax
-
-	__asm mov al,  byte ptr [ebp]
-
-	__asm mov byte ptr [edi], al
-
-	__asm ret
-}
-
-__declspec(naked) void BlendParticle100( void )
-{
-	__asm mov byte ptr [edi], al
-	__asm ret
-}
-
-/*
-** R_DrawParticle (asm version)
-**
-** Since we use __declspec( naked ) we don't have a stack frame
-** that we can use.  Since I want to reserve EBP anyway, I tossed
-** all the important variables into statics.  This routine isn't
-** meant to be re-entrant, so this shouldn't cause any problems
-** other than a slightly higher global memory footprint.
-**
-*/
-__declspec(naked) void R_DrawParticle( void )
-{
-	static vec3_t	local, transformed;
-	static float	zi;
-	static int      u, v, tmp;
-	static short    izi;
-	static int      ebpsave;
-
-	static byte (*blendfunc)(void);
-
-	/*
-	** must be memvars since x86 can't load constants
-	** directly.  I guess I could use fld1, but that
-	** actually costs one more clock than fld [one]!
-	*/
-	static float    particle_z_clip    = PARTICLE_Z_CLIP;
-	static float    one                = 1.0F;
-	static float    point_five         = 0.5F;
-	static float    eight_thousand_hex = 0x8000;
-
-	/*
-	** save trashed variables
-	*/
-	__asm mov  ebpsave, ebp
-	__asm push esi
-	__asm push edi
-
-	/*
-	** transform the particle
-	*/
-	// VectorSubtract (pparticle->origin, r_origin, local);
-	__asm mov  esi, partparms.particle
-	__asm fld  dword ptr [esi+0]          ; p_o.x
-	__asm fsub dword ptr [r_origin+0]     ; p_o.x-r_o.x
-	__asm fld  dword ptr [esi+4]          ; p_o.y | p_o.x-r_o.x
-	__asm fsub dword ptr [r_origin+4]     ; p_o.y-r_o.y | p_o.x-r_o.x
-	__asm fld  dword ptr [esi+8]          ; p_o.z | p_o.y-r_o.y | p_o.x-r_o.x
-	__asm fsub dword ptr [r_origin+8]     ; p_o.z-r_o.z | p_o.y-r_o.y | p_o.x-r_o.x
-	__asm fxch st(2)                      ; p_o.x-r_o.x | p_o.y-r_o.y | p_o.z-r_o.z
-	__asm fstp dword ptr [local+0]        ; p_o.y-r_o.y | p_o.z-r_o.z
-	__asm fstp dword ptr [local+4]        ; p_o.z-r_o.z
-	__asm fstp dword ptr [local+8]        ; (empty)
-
-	// transformed[0] = DotProduct(local, r_pright);
-	// transformed[1] = DotProduct(local, r_pup);
-	// transformed[2] = DotProduct(local, r_ppn);
-	__asm fld  dword ptr [local+0]        ; l.x
-	__asm fmul dword ptr [r_pright+0]     ; l.x*pr.x
-	__asm fld  dword ptr [local+4]        ; l.y | l.x*pr.x
-	__asm fmul dword ptr [r_pright+4]     ; l.y*pr.y | l.x*pr.x
-	__asm fld  dword ptr [local+8]        ; l.z | l.y*pr.y | l.x*pr.x
-	__asm fmul dword ptr [r_pright+8]     ; l.z*pr.z | l.y*pr.y | l.x*pr.x
-	__asm fxch st(2)                      ; l.x*pr.x | l.y*pr.y | l.z*pr.z
-	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y | l.z*pr.z
-	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y + l.z*pr.z
-	__asm fstp  dword ptr [transformed+0] ; (empty)
-
-	__asm fld  dword ptr [local+0]        ; l.x
-	__asm fmul dword ptr [r_pup+0]        ; l.x*pr.x
-	__asm fld  dword ptr [local+4]        ; l.y | l.x*pr.x
-	__asm fmul dword ptr [r_pup+4]        ; l.y*pr.y | l.x*pr.x
-	__asm fld  dword ptr [local+8]        ; l.z | l.y*pr.y | l.x*pr.x
-	__asm fmul dword ptr [r_pup+8]        ; l.z*pr.z | l.y*pr.y | l.x*pr.x
-	__asm fxch st(2)                      ; l.x*pr.x | l.y*pr.y | l.z*pr.z
-	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y | l.z*pr.z
-	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y + l.z*pr.z
-	__asm fstp  dword ptr [transformed+4] ; (empty)
-
-	__asm fld  dword ptr [local+0]        ; l.x
-	__asm fmul dword ptr [r_ppn+0]        ; l.x*pr.x
-	__asm fld  dword ptr [local+4]        ; l.y | l.x*pr.x
-	__asm fmul dword ptr [r_ppn+4]        ; l.y*pr.y | l.x*pr.x
-	__asm fld  dword ptr [local+8]        ; l.z | l.y*pr.y | l.x*pr.x
-	__asm fmul dword ptr [r_ppn+8]        ; l.z*pr.z | l.y*pr.y | l.x*pr.x
-	__asm fxch st(2)                      ; l.x*pr.x | l.y*pr.y | l.z*pr.z
-	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y | l.z*pr.z
-	__asm faddp st(1), st                 ; l.x*pr.x + l.y*pr.y + l.z*pr.z
-	__asm fstp  dword ptr [transformed+8] ; (empty)
-
-	/*
-	** make sure that the transformed particle is not in front of
-	** the particle Z clip plane.  We can do the comparison in 
-	** integer space since we know the sign of one of the inputs
-	** and can figure out the sign of the other easily enough.
-	*/
-	//	if (transformed[2] < PARTICLE_Z_CLIP)
-	//		return;
-
-	__asm mov  eax, dword ptr [transformed+8]
-	__asm and  eax, eax
-	__asm js   end
-	__asm cmp  eax, particle_z_clip
-	__asm jl   end
-
-	/*
-	** project the point by initiating the 1/z calc
-	*/
-	//	zi = 1.0 / transformed[2];
-	__asm fld   one
-	__asm fdiv  dword ptr [transformed+8]
-
-	/*
-	** bind the blend function pointer to the appropriate blender
-	** while we're dividing
-	*/
-	//if ( level == PARTICLE_33 )
-	//	blendparticle = BlendParticle33;
-	//else if ( level == PARTICLE_66 )
-	//	blendparticle = BlendParticle66;
-	//else 
-	//	blendparticle = BlendParticle100;
-
-	__asm cmp partparms.level, PARTICLE_66
-	__asm je  blendfunc_66
-	__asm jl  blendfunc_33
-	__asm lea ebx, BlendParticle100
-	__asm jmp done_selecting_blend_func
-blendfunc_33:
-	__asm lea ebx, BlendParticle33
-	__asm jmp done_selecting_blend_func
-blendfunc_66:
-	__asm lea ebx, BlendParticle66
-done_selecting_blend_func:
-	__asm mov blendfunc, ebx
-
-	// prefetch the next particle
-	__asm mov ebp, s_prefetch_address
-	__asm mov ebp, [ebp]
-
-	// finish the above divide
-	__asm fstp  zi
-
-	// u = (int)(xcenter + zi * transformed[0] + 0.5);
-	// v = (int)(ycenter - zi * transformed[1] + 0.5);
-	__asm fld   zi                           ; zi
-	__asm fmul  dword ptr [transformed+0]    ; zi * transformed[0]
-	__asm fld   zi                           ; zi | zi * transformed[0]
-	__asm fmul  dword ptr [transformed+4]    ; zi * transformed[1] | zi * transformed[0]
-	__asm fxch  st(1)                        ; zi * transformed[0] | zi * transformed[1]
-	__asm fadd  xcenter                      ; xcenter + zi * transformed[0] | zi * transformed[1]
-	__asm fxch  st(1)                        ; zi * transformed[1] | xcenter + zi * transformed[0]
-	__asm fld   ycenter                      ; ycenter | zi * transformed[1] | xcenter + zi * transformed[0]
-    __asm fsubrp st(1), st(0)                ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0]
-  	__asm fxch  st(1)                        ; xcenter + zi * transformed[0] | ycenter + zi * transformed[1]
-  	__asm fadd  point_five                   ; xcenter + zi * transformed[0] + 0.5 | ycenter - zi * transformed[1]
-  	__asm fxch  st(1)                        ; ycenter - zi * transformed[1] | xcenter + zi * transformed[0] + 0.5 
-  	__asm fadd  point_five                   ; ycenter - zi * transformed[1] + 0.5 | xcenter + zi * transformed[0] + 0.5 
-  	__asm fxch  st(1)                        ; u | v
-  	__asm fistp dword ptr [u]                ; v
-  	__asm fistp dword ptr [v]                ; (empty)
-
-	/*
-	** clip out the particle
-	*/
-
-	//	if ((v > d_vrectbottom_particle) || 
-	//		(u > d_vrectright_particle) ||
-	//		(v < d_vrecty) ||
-	//		(u < d_vrectx))
-	//	{
-	//		return;
-	//	}
-
-	__asm mov ebx, u
-	__asm mov ecx, v
-	__asm cmp ecx, d_vrectbottom_particle
-	__asm jg  end
-	__asm cmp ecx, d_vrecty
-	__asm jl  end
-	__asm cmp ebx, d_vrectright_particle
-	__asm jg  end
-	__asm cmp ebx, d_vrectx
-	__asm jl  end
-
-	/*
-	** compute addresses of zbuffer, framebuffer, and 
-	** compute the Z-buffer reference value.
-	**
-	** EBX      = U
-	** ECX      = V
-	**
-	** Outputs:
-	** ESI = Z-buffer address
-	** EDI = framebuffer address
-	*/
-	// ESI = d_pzbuffer + (d_zwidth * v) + u;
-	__asm mov esi, d_pzbuffer             ; esi = d_pzbuffer
-	__asm mov eax, d_zwidth               ; eax = d_zwidth
-	__asm mul ecx                         ; eax = d_zwidth*v
-	__asm add eax, ebx                    ; eax = d_zwidth*v+u
-	__asm shl eax, 1                      ; eax = 2*(d_zwidth*v+u)
-	__asm add esi, eax                    ; esi = ( short * ) ( d_pzbuffer + ( d_zwidth * v ) + u )
-
-	// initiate
-	// izi = (int)(zi * 0x8000);
-	__asm fld  zi
-	__asm fmul eight_thousand_hex
-
-	// EDI = pdest = d_viewbuffer + d_scantable[v] + u;
-	__asm lea edi, [d_scantable+ecx*4]
-	__asm mov edi, [edi]
-	__asm add edi, d_viewbuffer
-	__asm add edi, ebx
-
-	// complete
-	// izi = (int)(zi * 0x8000);
-	__asm fistp tmp
-	__asm mov   eax, tmp
-	__asm mov   izi, ax
-
-	/*
-	** determine the screen area covered by the particle,
-	** which also means clamping to a min and max
-	*/
-	//	pix = izi >> d_pix_shift;
-	__asm xor edx, edx
-	__asm mov dx, izi
-	__asm mov ecx, d_pix_shift
-	__asm shr dx, cl
-
-	//	if (pix < d_pix_min)
-	//		pix = d_pix_min;
-	__asm cmp edx, d_pix_min
-	__asm jge check_pix_max
-	__asm mov edx, d_pix_min
-	__asm jmp skip_pix_clamp
-
-	//	else if (pix > d_pix_max)
-	//		pix = d_pix_max;
-check_pix_max:
-	__asm cmp edx, d_pix_max
-	__asm jle skip_pix_clamp
-	__asm mov edx, d_pix_max
-
-skip_pix_clamp:
-
-	/*
-	** render the appropriate pixels
-	**
-	** ECX = count (used for inner loop)
-	** EDX = count (used for outer loop)
-	** ESI = zbuffer
-	** EDI = framebuffer
-	*/
-	__asm mov ecx, edx
-
-	__asm cmp ecx, 1
-	__asm ja  over
-
-over:
-
-	/*
-	** at this point:
-	**
-	** ECX = count
-	*/
-	__asm push ecx
-	__asm push edi
-	__asm push esi
-
-top_of_pix_vert_loop:
-
-top_of_pix_horiz_loop:
-
-	//	for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth)
-	//	{
-	//		for (i=0 ; i<pix ; i++)
-	//		{
-	//			if (pz[i] <= izi)
-	//			{
-	//				pdest[i] = blendparticle( color, pdest[i] );
-	//			}
-	//		}
-	//	}
-	__asm xor   eax, eax
-
-	__asm mov   ax, word ptr [esi]
-
-	__asm cmp   ax, izi
-	__asm jg    end_of_horiz_loop
-
-#if ENABLE_ZWRITES_FOR_PARTICLES
-  	__asm mov   bp, izi
-  	__asm mov   word ptr [esi], bp
-#endif
-
-	__asm mov   eax, partparms.color
-
-	__asm call  [blendfunc]
-
-	__asm add   edi, 1
-	__asm add   esi, 2
-
-end_of_horiz_loop:
-
-	__asm dec   ecx
-	__asm jnz   top_of_pix_horiz_loop
-
-	__asm pop   esi
-	__asm pop   edi
-
-	__asm mov   ebp, d_zwidth
-	__asm shl   ebp, 1
-
-	__asm add   esi, ebp
-	__asm add   edi, [r_screenwidth]
-
-	__asm pop   ecx
-	__asm push  ecx
-
-	__asm push  edi
-	__asm push  esi
-
-	__asm dec   edx
-	__asm jnz   top_of_pix_vert_loop
-
-	__asm pop   ecx
-	__asm pop   ecx
-	__asm pop   ecx
-
-end:
-	__asm pop edi
-	__asm pop esi
-	__asm mov ebp, ebpsave
-	__asm ret
-}
-
-#else
-
-static byte BlendParticle33( int pcolor, int dstcolor )
-{
-	return vid.alphamap[pcolor + dstcolor*256];
-}
-
-static byte BlendParticle66( int pcolor, int dstcolor )
-{
-	return vid.alphamap[pcolor*256+dstcolor];
-}
-
-static byte BlendParticle100( int pcolor, int dstcolor )
-{
-	dstcolor = dstcolor;
-	return pcolor;
-}
-
-/*
-** R_DrawParticle
-**
-** Yes, this is amazingly slow, but it's the C reference
-** implementation and should be both robust and vaguely
-** understandable.  The only time this path should be
-** executed is if we're debugging on x86 or if we're
-** recompiling and deploying on a non-x86 platform.
-**
-** To minimize error and improve readability I went the 
-** function pointer route.  This exacts some overhead, but
-** it pays off in clean and easy to understand code.
-*/
-void R_DrawParticle( void )
-{
-	particle_t *pparticle = partparms.particle;
-	int         level     = partparms.level;
-	vec3_t	local, transformed;
-	float	zi;
-	byte	*pdest;
-	short	*pz;
-	int      color = pparticle->color;
-	int		i, izi, pix, count, u, v;
-	byte  (*blendparticle)( int, int );
-
-	/*
-	** transform the particle
-	*/
-	VectorSubtract (pparticle->origin, r_origin, local);
-
-	transformed[0] = DotProduct(local, r_pright);
-	transformed[1] = DotProduct(local, r_pup);
-	transformed[2] = DotProduct(local, r_ppn);		
-
-	if (transformed[2] < PARTICLE_Z_CLIP)
-		return;
-
-	/*
-	** bind the blend function pointer to the appropriate blender
-	*/
-	if ( level == PARTICLE_33 )
-		blendparticle = BlendParticle33;
-	else if ( level == PARTICLE_66 )
-		blendparticle = BlendParticle66;
-	else 
-		blendparticle = BlendParticle100;
-
-	/*
-	** project the point
-	*/
-	// FIXME: preadjust xcenter and ycenter
-	zi = 1.0 / transformed[2];
-	u = (int)(xcenter + zi * transformed[0] + 0.5);
-	v = (int)(ycenter - zi * transformed[1] + 0.5);
-
-	if ((v > d_vrectbottom_particle) || 
-		(u > d_vrectright_particle) ||
-		(v < d_vrecty) ||
-		(u < d_vrectx))
-	{
-		return;
-	}
-
-	/*
-	** compute addresses of zbuffer, framebuffer, and 
-	** compute the Z-buffer reference value.
-	*/
-	pz = d_pzbuffer + (d_zwidth * v) + u;
-	pdest = d_viewbuffer + d_scantable[v] + u;
-	izi = (int)(zi * 0x8000);
-
-	/*
-	** determine the screen area covered by the particle,
-	** which also means clamping to a min and max
-	*/
-	pix = izi >> d_pix_shift;
-	if (pix < d_pix_min)
-		pix = d_pix_min;
-	else if (pix > d_pix_max)
-		pix = d_pix_max;
-
-	/*
-	** render the appropriate pixels
-	*/
-	count = pix;
-
-    switch (level) {
-    case PARTICLE_33 :
-        for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
-        {
-//FIXME--do it in blocks of 8?
-            for (i=0 ; i<pix ; i++)
-            {
-                if (pz[i] <= izi)
-                {
-                    pz[i]    = izi;
-                    pdest[i] = vid.alphamap[color + ((int)pdest[i]<<8)];
-                }
-            }
-        }
-        break;
-
-    case PARTICLE_66 :
-        for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
-        {
-            for (i=0 ; i<pix ; i++)
-            {
-                if (pz[i] <= izi)
-                {
-                    pz[i]    = izi;
-                    pdest[i] = vid.alphamap[(color<<8) + (int)pdest[i]];
-                }
-            }
-        }
-        break;
-
-    default:  //100
-        for ( ; count ; count--, pz += d_zwidth, pdest += r_screenwidth)
-        {
-            for (i=0 ; i<pix ; i++)
-            {
-                if (pz[i] <= izi)
-                {
-                    pz[i]    = izi;
-                    pdest[i] = color;
-                }
-            }
-        }
-        break;
-    }
-}
-
-#endif	// !id386
-
-/*
-** R_DrawParticles
-**
-** Responsible for drawing all of the particles in the particle list
-** throughout the world.  Doesn't care if we're using the C path or
-** if we're using the asm path, it simply assigns a function pointer
-** and goes.
-*/
-void R_DrawParticles (void)
-{
-	particle_t *p;
-	int         i;
-	extern unsigned long fpu_sp24_cw, fpu_chop_cw;
-
-	VectorScale( vright, xscaleshrink, r_pright );
-	VectorScale( vup, yscaleshrink, r_pup );
-	VectorCopy( vpn, r_ppn );
-
-#if id386 && !defined __linux__
-	__asm fldcw word ptr [fpu_sp24_cw]
-#endif
-
-	for (p=r_newrefdef.particles, i=0 ; i<r_newrefdef.num_particles ; i++,p++)
-	{
-
-		if ( p->alpha > 0.66 )
-			partparms.level = PARTICLE_OPAQUE;
-		else if ( p->alpha > 0.33 )
-			partparms.level = PARTICLE_66;
-		else
-			partparms.level = PARTICLE_33;
-
-		partparms.particle = p;
-		partparms.color    = p->color;
-
-#if id386 && !defined __linux__
-		if ( i < r_newrefdef.num_particles-1 )
-			s_prefetch_address = ( unsigned int ) ( p + 1 );
-		else
-			s_prefetch_address = ( unsigned int ) r_newrefdef.particles;
-#endif
-
-		R_DrawParticle();
-	}
-
-#if id386 && !defined __linux__
-	__asm fldcw word ptr [fpu_chop_cw]
-#endif
-
-}
-
--- a/ref_soft/r_poly.c
+++ /dev/null
@@ -1,1244 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-#include <assert.h>
-#include "r_local.h"
-
-#define AFFINE_SPANLET_SIZE      16
-#define AFFINE_SPANLET_SIZE_BITS 4
-
-typedef struct
-{
-	byte     *pbase, *pdest;
-	short	 *pz;
-	fixed16_t s, t;
-	fixed16_t sstep, tstep;
-	int       izi, izistep, izistep_times_2;
-	int       spancount;
-	unsigned  u, v;
-} spanletvars_t;
-
-spanletvars_t s_spanletvars;
-
-static int r_polyblendcolor;
-
-static espan_t	*s_polygon_spans;
-
-polydesc_t	r_polydesc;
-
-msurface_t *r_alpha_surfaces;
-
-extern int *r_turb_turb;
-
-static int		clip_current;
-vec5_t	r_clip_verts[2][MAXWORKINGVERTS+2];
-
-static int		s_minindex, s_maxindex;
-
-static void R_DrawPoly( qboolean iswater );
-
-/*
-** R_DrawSpanletOpaque
-*/
-void R_DrawSpanletOpaque( void )
-{
-	unsigned btemp;
-
-	do
-	{
-		unsigned ts, tt;
-
-		ts = s_spanletvars.s >> 16;
-		tt = s_spanletvars.t >> 16;
-
-		btemp = *(s_spanletvars.pbase + (ts) + (tt) * cachewidth);
-		if (btemp != 255)
-		{
-			if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
-			{
-				*s_spanletvars.pz    = s_spanletvars.izi >> 16;
-				*s_spanletvars.pdest = btemp;
-			}
-		}
-
-		s_spanletvars.izi += s_spanletvars.izistep;
-		s_spanletvars.pdest++;
-		s_spanletvars.pz++;
-		s_spanletvars.s += s_spanletvars.sstep;
-		s_spanletvars.t += s_spanletvars.tstep;
-	} while (--s_spanletvars.spancount > 0);
-}
-
-/*
-** R_DrawSpanletTurbulentStipple33
-*/
-void R_DrawSpanletTurbulentStipple33( void )
-{
-	unsigned btemp;
-	int	     sturb, tturb;
-	byte    *pdest = s_spanletvars.pdest;
-	short   *pz    = s_spanletvars.pz;
-	int      izi   = s_spanletvars.izi;
-	
-	if ( s_spanletvars.v & 1 )
-	{
-		s_spanletvars.pdest += s_spanletvars.spancount;
-		s_spanletvars.pz    += s_spanletvars.spancount;
-
-		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
-			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
-		else
-			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
-		
-		if ( s_spanletvars.u & 1 )
-		{
-			izi += s_spanletvars.izistep;
-			s_spanletvars.s   += s_spanletvars.sstep;
-			s_spanletvars.t   += s_spanletvars.tstep;
-
-			pdest++;
-			pz++;
-			s_spanletvars.spancount--;
-		}
-
-		s_spanletvars.sstep   *= 2;
-		s_spanletvars.tstep   *= 2;
-
-		while ( s_spanletvars.spancount > 0 )
-		{
-			sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
-			tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
-			
-			btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
-			
-			if ( *pz <= ( izi >> 16 ) )
-				*pdest = btemp;
-			
-			izi               += s_spanletvars.izistep_times_2;
-			s_spanletvars.s   += s_spanletvars.sstep;
-			s_spanletvars.t   += s_spanletvars.tstep;
-			
-			pdest += 2;
-			pz    += 2;
-			
-			s_spanletvars.spancount -= 2;
-		}
-	}
-}
-
-/*
-** R_DrawSpanletTurbulentStipple66
-*/
-void R_DrawSpanletTurbulentStipple66( void )
-{
-	unsigned btemp;
-	int	     sturb, tturb;
-	byte    *pdest = s_spanletvars.pdest;
-	short   *pz    = s_spanletvars.pz;
-	int      izi   = s_spanletvars.izi;
-	
-	if ( !( s_spanletvars.v & 1 ) )
-	{
-		s_spanletvars.pdest += s_spanletvars.spancount;
-		s_spanletvars.pz    += s_spanletvars.spancount;
-
-		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
-			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
-		else
-			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
-		
-		if ( s_spanletvars.u & 1 )
-		{
-			izi += s_spanletvars.izistep;
-			s_spanletvars.s   += s_spanletvars.sstep;
-			s_spanletvars.t   += s_spanletvars.tstep;
-
-			pdest++;
-			pz++;
-			s_spanletvars.spancount--;
-		}
-
-		s_spanletvars.sstep   *= 2;
-		s_spanletvars.tstep   *= 2;
-
-		while ( s_spanletvars.spancount > 0 )
-		{
-			sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
-			tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
-			
-			btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
-			
-			if ( *pz <= ( izi >> 16 ) )
-				*pdest = btemp;
-			
-			izi               += s_spanletvars.izistep_times_2;
-			s_spanletvars.s   += s_spanletvars.sstep;
-			s_spanletvars.t   += s_spanletvars.tstep;
-			
-			pdest += 2;
-			pz    += 2;
-			
-			s_spanletvars.spancount -= 2;
-		}
-	}
-	else
-	{
-		s_spanletvars.pdest += s_spanletvars.spancount;
-		s_spanletvars.pz    += s_spanletvars.spancount;
-
-		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
-			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
-		else
-			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
-		
-		while ( s_spanletvars.spancount > 0 )
-		{
-			sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
-			tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
-			
-			btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
-			
-			if ( *pz <= ( izi >> 16 ) )
-				*pdest = btemp;
-			
-			izi               += s_spanletvars.izistep;
-			s_spanletvars.s   += s_spanletvars.sstep;
-			s_spanletvars.t   += s_spanletvars.tstep;
-			
-			pdest++;
-			pz++;
-			
-			s_spanletvars.spancount--;
-		}
-	}
-}
-
-/*
-** R_DrawSpanletTurbulentBlended
-*/
-void R_DrawSpanletTurbulentBlended66( void )
-{
-	unsigned btemp;
-	int	     sturb, tturb;
-
-	do
-	{
-		sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
-		tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
-
-		btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
-
-		if ( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) )
-			*s_spanletvars.pdest = vid.alphamap[btemp*256+*s_spanletvars.pdest];
-
-		s_spanletvars.izi += s_spanletvars.izistep;
-		s_spanletvars.pdest++;
-		s_spanletvars.pz++;
-		s_spanletvars.s += s_spanletvars.sstep;
-		s_spanletvars.t += s_spanletvars.tstep;
-
-	} while ( --s_spanletvars.spancount > 0 );
-}
-
-void R_DrawSpanletTurbulentBlended33( void )
-{
-	unsigned btemp;
-	int	     sturb, tturb;
-
-	do
-	{
-		sturb = ((s_spanletvars.s + r_turb_turb[(s_spanletvars.t>>16)&(CYCLE-1)])>>16)&63;
-		tturb = ((s_spanletvars.t + r_turb_turb[(s_spanletvars.s>>16)&(CYCLE-1)])>>16)&63;
-
-		btemp = *( s_spanletvars.pbase + ( sturb ) + ( tturb << 6 ) );
-
-		if ( *s_spanletvars.pz <= ( s_spanletvars.izi >> 16 ) )
-			*s_spanletvars.pdest = vid.alphamap[btemp+*s_spanletvars.pdest*256];
-
-		s_spanletvars.izi += s_spanletvars.izistep;
-		s_spanletvars.pdest++;
-		s_spanletvars.pz++;
-		s_spanletvars.s += s_spanletvars.sstep;
-		s_spanletvars.t += s_spanletvars.tstep;
-
-	} while ( --s_spanletvars.spancount > 0 );
-}
-
-/*
-** R_DrawSpanlet33
-*/
-void R_DrawSpanlet33( void )
-{
-	unsigned btemp;
-
-	do
-	{
-		unsigned ts, tt;
-
-		ts = s_spanletvars.s >> 16;
-		tt = s_spanletvars.t >> 16;
-
-		btemp = *(s_spanletvars.pbase + (ts) + (tt) * cachewidth);
-
-		if ( btemp != 255 )
-		{
-			if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
-			{
-				*s_spanletvars.pdest = vid.alphamap[btemp+*s_spanletvars.pdest*256];
-			}
-		}
-
-		s_spanletvars.izi += s_spanletvars.izistep;
-		s_spanletvars.pdest++;
-		s_spanletvars.pz++;
-		s_spanletvars.s += s_spanletvars.sstep;
-		s_spanletvars.t += s_spanletvars.tstep;
-	} while (--s_spanletvars.spancount > 0);
-}
-
-void R_DrawSpanletConstant33( void )
-{
-	do
-	{
-		if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
-		{
-			*s_spanletvars.pdest = vid.alphamap[r_polyblendcolor+*s_spanletvars.pdest*256];
-		}
-
-		s_spanletvars.izi += s_spanletvars.izistep;
-		s_spanletvars.pdest++;
-		s_spanletvars.pz++;
-	} while (--s_spanletvars.spancount > 0);
-}
-
-/*
-** R_DrawSpanlet66
-*/
-void R_DrawSpanlet66( void )
-{
-	unsigned btemp;
-
-	do
-	{
-		unsigned ts, tt;
-
-		ts = s_spanletvars.s >> 16;
-		tt = s_spanletvars.t >> 16;
-
-		btemp = *(s_spanletvars.pbase + (ts) + (tt) * cachewidth);
-
-		if ( btemp != 255 )
-		{
-			if (*s_spanletvars.pz <= (s_spanletvars.izi >> 16))
-			{
-				*s_spanletvars.pdest = vid.alphamap[btemp*256+*s_spanletvars.pdest];
-			}
-		}
-
-		s_spanletvars.izi += s_spanletvars.izistep;
-		s_spanletvars.pdest++;
-		s_spanletvars.pz++;
-		s_spanletvars.s += s_spanletvars.sstep;
-		s_spanletvars.t += s_spanletvars.tstep;
-	} while (--s_spanletvars.spancount > 0);
-}
-
-/*
-** R_DrawSpanlet33Stipple
-*/
-void R_DrawSpanlet33Stipple( void )
-{
-	unsigned btemp;
-	byte    *pdest = s_spanletvars.pdest;
-	short   *pz    = s_spanletvars.pz;
-	int      izi   = s_spanletvars.izi;
-	
-	if ( r_polydesc.stipple_parity ^ ( s_spanletvars.v & 1 ) )
-	{
-		s_spanletvars.pdest += s_spanletvars.spancount;
-		s_spanletvars.pz    += s_spanletvars.spancount;
-
-		if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
-			s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
-		else
-			s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
-		
-		if ( r_polydesc.stipple_parity ^ ( s_spanletvars.u & 1 ) )
-		{
-			izi += s_spanletvars.izistep;
-			s_spanletvars.s   += s_spanletvars.sstep;
-			s_spanletvars.t   += s_spanletvars.tstep;
-
-			pdest++;
-			pz++;
-			s_spanletvars.spancount--;
-		}
-
-		s_spanletvars.sstep *= 2;
-		s_spanletvars.tstep *= 2;
-
-		while ( s_spanletvars.spancount > 0 )
-		{
-			unsigned s = s_spanletvars.s >> 16;
-			unsigned t = s_spanletvars.t >> 16;
-
-			btemp = *( s_spanletvars.pbase + ( s ) + ( t * cachewidth ) );
-			
-			if ( btemp != 255 )
-			{
-				if ( *pz <= ( izi >> 16 ) )
-					*pdest = btemp;
-			}
-			
-			izi               += s_spanletvars.izistep_times_2;
-			s_spanletvars.s   += s_spanletvars.sstep;
-			s_spanletvars.t   += s_spanletvars.tstep;
-			
-			pdest += 2;
-			pz    += 2;
-			
-			s_spanletvars.spancount -= 2;
-		}
-	}
-}
-
-/*
-** R_DrawSpanlet66Stipple
-*/
-void R_DrawSpanlet66Stipple( void )
-{
-	unsigned btemp;
-	byte    *pdest = s_spanletvars.pdest;
-	short   *pz    = s_spanletvars.pz;
-	int      izi   = s_spanletvars.izi;
-
-	s_spanletvars.pdest += s_spanletvars.spancount;
-	s_spanletvars.pz    += s_spanletvars.spancount;
-
-	if ( s_spanletvars.spancount == AFFINE_SPANLET_SIZE )
-		s_spanletvars.izi += s_spanletvars.izistep << AFFINE_SPANLET_SIZE_BITS;
-	else
-		s_spanletvars.izi += s_spanletvars.izistep * s_spanletvars.izistep;
-
-	if ( r_polydesc.stipple_parity ^ ( s_spanletvars.v & 1 ) )
-	{
-		if ( r_polydesc.stipple_parity ^ ( s_spanletvars.u & 1 ) )
-		{
-			izi += s_spanletvars.izistep;
-			s_spanletvars.s += s_spanletvars.sstep;
-			s_spanletvars.t += s_spanletvars.tstep;
-
-			pdest++;
-			pz++;
-			s_spanletvars.spancount--;
-		}
-
-		s_spanletvars.sstep *= 2;
-		s_spanletvars.tstep *= 2;
-
-		while ( s_spanletvars.spancount > 0 )
-		{
-			unsigned s = s_spanletvars.s >> 16;
-			unsigned t = s_spanletvars.t >> 16;
-			
-			btemp = *( s_spanletvars.pbase + ( s ) + ( t * cachewidth ) );
-
-			if ( btemp != 255 )
-			{
-				if ( *pz <= ( izi >> 16 ) )
-					*pdest = btemp;
-			}
-			
-			izi             += s_spanletvars.izistep_times_2;
-			s_spanletvars.s += s_spanletvars.sstep;
-			s_spanletvars.t += s_spanletvars.tstep;
-			
-			pdest += 2;
-			pz    += 2;
-			
-			s_spanletvars.spancount -= 2;
-		}
-	}
-	else
-	{
-		while ( s_spanletvars.spancount > 0 )
-		{
-			unsigned s = s_spanletvars.s >> 16;
-			unsigned t = s_spanletvars.t >> 16;
-			
-			btemp = *( s_spanletvars.pbase + ( s ) + ( t * cachewidth ) );
-			
-			if ( btemp != 255 )
-			{
-				if ( *pz <= ( izi >> 16 ) )
-					*pdest = btemp;
-			}
-			
-			izi             += s_spanletvars.izistep;
-			s_spanletvars.s += s_spanletvars.sstep;
-			s_spanletvars.t += s_spanletvars.tstep;
-			
-			pdest++;
-			pz++;
-			
-			s_spanletvars.spancount--;
-		}
-	}
-}
-
-/*
-** R_ClipPolyFace
-**
-** Clips the winding at clip_verts[clip_current] and changes clip_current
-** Throws out the back side
-*/
-int R_ClipPolyFace (int nump, clipplane_t *pclipplane)
-{
-	int		i, outcount;
-	float	dists[MAXWORKINGVERTS+3];
-	float	frac, clipdist, *pclipnormal;
-	float	*in, *instep, *outstep, *vert2;
-
-	clipdist = pclipplane->dist;
-	pclipnormal = pclipplane->normal;
-	
-// calc dists
-	if (clip_current)
-	{
-		in = r_clip_verts[1][0];
-		outstep = r_clip_verts[0][0];
-		clip_current = 0;
-	}
-	else
-	{
-		in = r_clip_verts[0][0];
-		outstep = r_clip_verts[1][0];
-		clip_current = 1;
-	}
-	
-	instep = in;
-	for (i=0 ; i<nump ; i++, instep += sizeof (vec5_t) / sizeof (float))
-	{
-		dists[i] = DotProduct (instep, pclipnormal) - clipdist;
-	}
-	
-// handle wraparound case
-	dists[nump] = dists[0];
-	memcpy (instep, in, sizeof (vec5_t));
-
-
-// clip the winding
-	instep = in;
-	outcount = 0;
-
-	for (i=0 ; i<nump ; i++, instep += sizeof (vec5_t) / sizeof (float))
-	{
-		if (dists[i] >= 0)
-		{
-			memcpy (outstep, instep, sizeof (vec5_t));
-			outstep += sizeof (vec5_t) / sizeof (float);
-			outcount++;
-		}
-
-		if (dists[i] == 0 || dists[i+1] == 0)
-			continue;
-
-		if ( (dists[i] > 0) == (dists[i+1] > 0) )
-			continue;
-			
-	// split it into a new vertex
-		frac = dists[i] / (dists[i] - dists[i+1]);
-			
-		vert2 = instep + sizeof (vec5_t) / sizeof (float);
-		
-		outstep[0] = instep[0] + frac*(vert2[0] - instep[0]);
-		outstep[1] = instep[1] + frac*(vert2[1] - instep[1]);
-		outstep[2] = instep[2] + frac*(vert2[2] - instep[2]);
-		outstep[3] = instep[3] + frac*(vert2[3] - instep[3]);
-		outstep[4] = instep[4] + frac*(vert2[4] - instep[4]);
-
-		outstep += sizeof (vec5_t) / sizeof (float);
-		outcount++;
-	}	
-	
-	return outcount;
-}
-
-/*
-** R_PolygonDrawSpans
-*/
-void R_PolygonDrawSpans(espan_t *pspan, qboolean iswater )
-{
-	int			count;
-	fixed16_t	snext, tnext;
-	float		sdivz, tdivz, zi, z, du, dv, spancountminus1;
-	float		sdivzspanletstepu, tdivzspanletstepu, zispanletstepu;
-
-	s_spanletvars.pbase = cacheblock;
-
-	if ( iswater )
-		r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
-
-	sdivzspanletstepu = d_sdivzstepu * AFFINE_SPANLET_SIZE;
-	tdivzspanletstepu = d_tdivzstepu * AFFINE_SPANLET_SIZE;
-	zispanletstepu = d_zistepu * AFFINE_SPANLET_SIZE;
-
-// we count on FP exceptions being turned off to avoid range problems
-	s_spanletvars.izistep = (int)(d_zistepu * 0x8000 * 0x10000);
-	s_spanletvars.izistep_times_2 = s_spanletvars.izistep * 2;
-
-	s_spanletvars.pz = 0;
-
-	do
-	{
-		s_spanletvars.pdest   = (byte *)d_viewbuffer + ( d_scantable[pspan->v] /*r_screenwidth * pspan->v*/) + pspan->u;
-		s_spanletvars.pz      = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
-		s_spanletvars.u       = pspan->u;
-		s_spanletvars.v       = pspan->v;
-
-		count = pspan->count;
-
-		if (count <= 0)
-			goto NextSpan;
-
-	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
-		du = (float)pspan->u;
-		dv = (float)pspan->v;
-
-		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
-		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
-
-		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
-		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-	// we count on FP exceptions being turned off to avoid range problems
-		s_spanletvars.izi = (int)(zi * 0x8000 * 0x10000);
-
-		s_spanletvars.s = (int)(sdivz * z) + sadjust;
-		s_spanletvars.t = (int)(tdivz * z) + tadjust;
-
-		if ( !iswater )
-		{
-			if (s_spanletvars.s > bbextents)
-				s_spanletvars.s = bbextents;
-			else if (s_spanletvars.s < 0)
-				s_spanletvars.s = 0;
-
-			if (s_spanletvars.t > bbextentt)
-				s_spanletvars.t = bbextentt;
-			else if (s_spanletvars.t < 0)
-				s_spanletvars.t = 0;
-		}
-
-		do
-		{
-		// calculate s and t at the far end of the span
-			if (count >= AFFINE_SPANLET_SIZE )
-				s_spanletvars.spancount = AFFINE_SPANLET_SIZE;
-			else
-				s_spanletvars.spancount = count;
-
-			count -= s_spanletvars.spancount;
-
-			if (count)
-			{
-			// calculate s/z, t/z, zi->fixed s and t at far end of span,
-			// calculate s and t steps across span by shifting
-				sdivz += sdivzspanletstepu;
-				tdivz += tdivzspanletstepu;
-				zi += zispanletstepu;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-
-				snext = (int)(sdivz * z) + sadjust;
-				tnext = (int)(tdivz * z) + tadjust;
-
-				if ( !iswater )
-				{
-					if (snext > bbextents)
-						snext = bbextents;
-					else if (snext < AFFINE_SPANLET_SIZE)
-						snext = AFFINE_SPANLET_SIZE;	// prevent round-off error on <0 steps from
-									//  from causing overstepping & running off the
-									//  edge of the texture
-
-					if (tnext > bbextentt)
-						tnext = bbextentt;
-					else if (tnext < AFFINE_SPANLET_SIZE)
-						tnext = AFFINE_SPANLET_SIZE;	// guard against round-off error on <0 steps
-				}
-
-				s_spanletvars.sstep = (snext - s_spanletvars.s) >> AFFINE_SPANLET_SIZE_BITS;
-				s_spanletvars.tstep = (tnext - s_spanletvars.t) >> AFFINE_SPANLET_SIZE_BITS;
-			}
-			else
-			{
-			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
-			// can't step off polygon), clamp, calculate s and t steps across
-			// span by division, biasing steps low so we don't run off the
-			// texture
-				spancountminus1 = (float)(s_spanletvars.spancount - 1);
-				sdivz += d_sdivzstepu * spancountminus1;
-				tdivz += d_tdivzstepu * spancountminus1;
-				zi += d_zistepu * spancountminus1;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-				snext = (int)(sdivz * z) + sadjust;
-				tnext = (int)(tdivz * z) + tadjust;
-
-				if ( !iswater )
-				{
-					if (snext > bbextents)
-						snext = bbextents;
-					else if (snext < AFFINE_SPANLET_SIZE)
-						snext = AFFINE_SPANLET_SIZE;	// prevent round-off error on <0 steps from
-									//  from causing overstepping & running off the
-									//  edge of the texture
-
-					if (tnext > bbextentt)
-						tnext = bbextentt;
-					else if (tnext < AFFINE_SPANLET_SIZE)
-						tnext = AFFINE_SPANLET_SIZE;	// guard against round-off error on <0 steps
-				}
-
-				if (s_spanletvars.spancount > 1)
-				{
-					s_spanletvars.sstep = (snext - s_spanletvars.s) / (s_spanletvars.spancount - 1);
-					s_spanletvars.tstep = (tnext - s_spanletvars.t) / (s_spanletvars.spancount - 1);
-				}
-			}
-
-			if ( iswater )
-			{
-				s_spanletvars.s = s_spanletvars.s & ((CYCLE<<16)-1);
-				s_spanletvars.t = s_spanletvars.t & ((CYCLE<<16)-1);
-			}
-
-			r_polydesc.drawspanlet();
-
-			s_spanletvars.s = snext;
-			s_spanletvars.t = tnext;
-
-		} while (count > 0);
-
-NextSpan:
-		pspan++;
-
-	} while (pspan->count != DS_SPAN_LIST_END);
-}
-
-/*
-**
-** R_PolygonScanLeftEdge
-**
-** Goes through the polygon and scans the left edge, filling in 
-** screen coordinate data for the spans
-*/
-void R_PolygonScanLeftEdge (void)
-{
-	int			i, v, itop, ibottom, lmaxindex;
-	emitpoint_t	*pvert, *pnext;
-	espan_t		*pspan;
-	float		du, dv, vtop, vbottom, slope;
-	fixed16_t	u, u_step;
-
-	pspan = s_polygon_spans;
-	i = s_minindex;
-	if (i == 0)
-		i = r_polydesc.nump;
-
-	lmaxindex = s_maxindex;
-	if (lmaxindex == 0)
-		lmaxindex = r_polydesc.nump;
-
-	vtop = ceil (r_polydesc.pverts[i].v);
-
-	do
-	{
-		pvert = &r_polydesc.pverts[i];
-		pnext = pvert - 1;
-
-		vbottom = ceil (pnext->v);
-
-		if (vtop < vbottom)
-		{
-			du = pnext->u - pvert->u;
-			dv = pnext->v - pvert->v;
-
-			slope = du / dv;
-			u_step = (int)(slope * 0x10000);
-		// adjust u to ceil the integer portion
-			u = (int)((pvert->u + (slope * (vtop - pvert->v))) * 0x10000) +
-					(0x10000 - 1);
-			itop = (int)vtop;
-			ibottom = (int)vbottom;
-
-			for (v=itop ; v<ibottom ; v++)
-			{
-				pspan->u = u >> 16;
-				pspan->v = v;
-				u += u_step;
-				pspan++;
-			}
-		}
-
-		vtop = vbottom;
-
-		i--;
-		if (i == 0)
-			i = r_polydesc.nump;
-
-	} while (i != lmaxindex);
-}
-
-/*
-** R_PolygonScanRightEdge
-**
-** Goes through the polygon and scans the right edge, filling in
-** count values.
-*/
-void R_PolygonScanRightEdge (void)
-{
-	int			i, v, itop, ibottom;
-	emitpoint_t	*pvert, *pnext;
-	espan_t		*pspan;
-	float		du, dv, vtop, vbottom, slope, uvert, unext, vvert, vnext;
-	fixed16_t	u, u_step;
-
-	pspan = s_polygon_spans;
-	i = s_minindex;
-
-	vvert = r_polydesc.pverts[i].v;
-	if (vvert < r_refdef.fvrecty_adj)
-		vvert = r_refdef.fvrecty_adj;
-	if (vvert > r_refdef.fvrectbottom_adj)
-		vvert = r_refdef.fvrectbottom_adj;
-
-	vtop = ceil (vvert);
-
-	do
-	{
-		pvert = &r_polydesc.pverts[i];
-		pnext = pvert + 1;
-
-		vnext = pnext->v;
-		if (vnext < r_refdef.fvrecty_adj)
-			vnext = r_refdef.fvrecty_adj;
-		if (vnext > r_refdef.fvrectbottom_adj)
-			vnext = r_refdef.fvrectbottom_adj;
-
-		vbottom = ceil (vnext);
-
-		if (vtop < vbottom)
-		{
-			uvert = pvert->u;
-			if (uvert < r_refdef.fvrectx_adj)
-				uvert = r_refdef.fvrectx_adj;
-			if (uvert > r_refdef.fvrectright_adj)
-				uvert = r_refdef.fvrectright_adj;
-
-			unext = pnext->u;
-			if (unext < r_refdef.fvrectx_adj)
-				unext = r_refdef.fvrectx_adj;
-			if (unext > r_refdef.fvrectright_adj)
-				unext = r_refdef.fvrectright_adj;
-
-			du = unext - uvert;
-			dv = vnext - vvert;
-			slope = du / dv;
-			u_step = (int)(slope * 0x10000);
-		// adjust u to ceil the integer portion
-			u = (int)((uvert + (slope * (vtop - vvert))) * 0x10000) +
-					(0x10000 - 1);
-			itop = (int)vtop;
-			ibottom = (int)vbottom;
-
-			for (v=itop ; v<ibottom ; v++)
-			{
-				pspan->count = (u >> 16) - pspan->u;
-				u += u_step;
-				pspan++;
-			}
-		}
-
-		vtop = vbottom;
-		vvert = vnext;
-
-		i++;
-		if (i == r_polydesc.nump)
-			i = 0;
-
-	} while (i != s_maxindex);
-
-	pspan->count = DS_SPAN_LIST_END;	// mark the end of the span list 
-}
-
-/*
-** R_ClipAndDrawPoly
-*/
-void R_ClipAndDrawPoly( float alpha, qboolean isturbulent, qboolean textured )
-{
-	emitpoint_t	outverts[MAXWORKINGVERTS+3], *pout;
-	float		*pv;
-	int			i, nump;
-	float		scale;
-	vec3_t		transformed, local;
-
-	if ( !textured )
-	{
-		r_polydesc.drawspanlet = R_DrawSpanletConstant33;
-	}
-	else
-	{
-
-		/*
-		** choose the correct spanlet routine based on alpha
-		*/
-		if ( alpha == 1 )
-		{
-			// isturbulent is ignored because we know that turbulent surfaces
-			// can't be opaque
-			r_polydesc.drawspanlet = R_DrawSpanletOpaque;
-		}
-		else
-		{
-			if ( sw_stipplealpha->value )
-			{
-				if ( isturbulent )
-				{
-					if ( alpha > 0.33 )
-						r_polydesc.drawspanlet = R_DrawSpanletTurbulentStipple66;
-					else 
-						r_polydesc.drawspanlet = R_DrawSpanletTurbulentStipple33;
-				}
-				else
-				{
-					if ( alpha > 0.33 )
-						r_polydesc.drawspanlet = R_DrawSpanlet66Stipple;
-					else 
-						r_polydesc.drawspanlet = R_DrawSpanlet33Stipple;
-				}
-			}
-			else
-			{
-				if ( isturbulent )
-				{
-					if ( alpha > 0.33 )
-						r_polydesc.drawspanlet = R_DrawSpanletTurbulentBlended66;
-					else
-						r_polydesc.drawspanlet = R_DrawSpanletTurbulentBlended33;
-				}
-				else
-				{
-					if ( alpha > 0.33 )
-						r_polydesc.drawspanlet = R_DrawSpanlet66;
-					else 
-						r_polydesc.drawspanlet = R_DrawSpanlet33;
-				}
-			}
-		}
-	}
-
-	// clip to the frustum in worldspace
-	nump = r_polydesc.nump;
-	clip_current = 0;
-
-	for (i=0 ; i<4 ; i++)
-	{
-		nump = R_ClipPolyFace (nump, &view_clipplanes[i]);
-		if (nump < 3)
-			return;
-		if (nump > MAXWORKINGVERTS)
-			ri.Sys_Error(ERR_DROP, "R_ClipAndDrawPoly: too many points: %d", nump );
-	}
-
-// transform vertices into viewspace and project
-	pv = &r_clip_verts[clip_current][0][0];
-
-	for (i=0 ; i<nump ; i++)
-	{
-		VectorSubtract (pv, r_origin, local);
-		TransformVector (local, transformed);
-
-		if (transformed[2] < NEAR_CLIP)
-			transformed[2] = NEAR_CLIP;
-
-		pout = &outverts[i];
-		pout->zi = 1.0 / transformed[2];
-
-		pout->s = pv[3];
-		pout->t = pv[4];
-		
-		scale = xscale * pout->zi;
-		pout->u = (xcenter + scale * transformed[0]);
-
-		scale = yscale * pout->zi;
-		pout->v = (ycenter - scale * transformed[1]);
-
-		pv += sizeof (vec5_t) / sizeof (pv);
-	}
-
-// draw it
-	r_polydesc.nump = nump;
-	r_polydesc.pverts = outverts;
-
-	R_DrawPoly( isturbulent );
-}
-
-/*
-** R_BuildPolygonFromSurface
-*/
-void R_BuildPolygonFromSurface(msurface_t *fa)
-{
-	int			i, lindex, lnumverts;
-	medge_t		*pedges, *r_pedge;
-	int			vertpage;
-	float		*vec;
-	vec5_t     *pverts;
-	float       tmins[2] = { 0, 0 };
-
-	r_polydesc.nump = 0;
-
-	// reconstruct the polygon
-	pedges = currentmodel->edges;
-	lnumverts = fa->numedges;
-	vertpage = 0;
-
-	pverts = r_clip_verts[0];
-
-	for (i=0 ; i<lnumverts ; i++)
-	{
-		lindex = currentmodel->surfedges[fa->firstedge + i];
-
-		if (lindex > 0)
-		{
-			r_pedge = &pedges[lindex];
-			vec = currentmodel->vertexes[r_pedge->v[0]].position;
-		}
-		else
-		{
-			r_pedge = &pedges[-lindex];
-			vec = currentmodel->vertexes[r_pedge->v[1]].position;
-		}
-
-		VectorCopy (vec, pverts[i] );
-	}
-
-	VectorCopy( fa->texinfo->vecs[0], r_polydesc.vright );
-	VectorCopy( fa->texinfo->vecs[1], r_polydesc.vup );
-	VectorCopy( fa->plane->normal, r_polydesc.vpn );
-	VectorCopy( r_origin, r_polydesc.viewer_position );
-
-	if ( fa->flags & SURF_PLANEBACK )
-	{
-		VectorSubtract( vec3_origin, r_polydesc.vpn, r_polydesc.vpn );
-	}
-
-	if ( fa->texinfo->flags & SURF_WARP )
-	{
-		r_polydesc.pixels       = fa->texinfo->image->pixels[0];
-		r_polydesc.pixel_width  = fa->texinfo->image->width;
-		r_polydesc.pixel_height = fa->texinfo->image->height;
-	}
-	else
-	{
-		surfcache_t *scache;
-
-		scache = D_CacheSurface( fa, 0 );
-
-		r_polydesc.pixels       = scache->data;
-		r_polydesc.pixel_width  = scache->width;
-		r_polydesc.pixel_height = scache->height;
-
-		tmins[0] = fa->texturemins[0];
-		tmins[1] = fa->texturemins[1];
-	}
-
-	r_polydesc.dist = DotProduct( r_polydesc.vpn, pverts[0] );
-
-	r_polydesc.s_offset = fa->texinfo->vecs[0][3] - tmins[0];
-	r_polydesc.t_offset = fa->texinfo->vecs[1][3] - tmins[1];
-
-	// scrolling texture addition
-	if (fa->texinfo->flags & SURF_FLOWING)
-	{
-		r_polydesc.s_offset += -128 * ( (r_newrefdef.time*0.25) - (int)(r_newrefdef.time*0.25) );
-	}
-
-	r_polydesc.nump = lnumverts;
-}
-
-/*
-** R_PolygonCalculateGradients
-*/
-void R_PolygonCalculateGradients (void)
-{
-	vec3_t		p_normal, p_saxis, p_taxis;
-	float		distinv;
-
-	TransformVector (r_polydesc.vpn, p_normal);
-	TransformVector (r_polydesc.vright, p_saxis);
-	TransformVector (r_polydesc.vup, p_taxis);
-
-	distinv = 1.0 / (-(DotProduct (r_polydesc.viewer_position, r_polydesc.vpn)) + r_polydesc.dist );
-
-	d_sdivzstepu  =  p_saxis[0] * xscaleinv;
-	d_sdivzstepv  = -p_saxis[1] * yscaleinv;
-	d_sdivzorigin =  p_saxis[2] - xcenter * d_sdivzstepu - ycenter * d_sdivzstepv;
-
-	d_tdivzstepu  =  p_taxis[0] * xscaleinv;
-	d_tdivzstepv  = -p_taxis[1] * yscaleinv;
-	d_tdivzorigin =  p_taxis[2] - xcenter * d_tdivzstepu - ycenter * d_tdivzstepv;
-
-	d_zistepu =   p_normal[0] * xscaleinv * distinv;
-	d_zistepv =  -p_normal[1] * yscaleinv * distinv;
-	d_ziorigin =  p_normal[2] * distinv - xcenter * d_zistepu - ycenter * d_zistepv;
-
-	sadjust = (fixed16_t) ( ( DotProduct( r_polydesc.viewer_position, r_polydesc.vright) + r_polydesc.s_offset ) * 0x10000 );
-	tadjust = (fixed16_t) ( ( DotProduct( r_polydesc.viewer_position, r_polydesc.vup   ) + r_polydesc.t_offset ) * 0x10000 );
-
-// -1 (-epsilon) so we never wander off the edge of the texture
-	bbextents = (r_polydesc.pixel_width << 16) - 1;
-	bbextentt = (r_polydesc.pixel_height << 16) - 1;
-}
-
-/*
-** R_DrawPoly
-**
-** Polygon drawing function.  Uses the polygon described in r_polydesc
-** to calculate edges and gradients, then renders the resultant spans.
-**
-** This should NOT be called externally since it doesn't do clipping!
-*/
-static void R_DrawPoly( qboolean iswater )
-{
-	int			i, nump;
-	float		ymin, ymax;
-	emitpoint_t	*pverts;
-	espan_t	spans[MAXHEIGHT+1];
-
-	s_polygon_spans = spans;
-
-// find the top and bottom vertices, and make sure there's at least one scan to
-// draw
-	ymin = 999999.9;
-	ymax = -999999.9;
-	pverts = r_polydesc.pverts;
-
-	for (i=0 ; i<r_polydesc.nump ; i++)
-	{
-		if (pverts->v < ymin)
-		{
-			ymin = pverts->v;
-			s_minindex = i;
-		}
-
-		if (pverts->v > ymax)
-		{
-			ymax = pverts->v;
-			s_maxindex = i;
-		}
-
-		pverts++;
-	}
-
-	ymin = ceil (ymin);
-	ymax = ceil (ymax);
-
-	if (ymin >= ymax)
-		return;		// doesn't cross any scans at all
-
-	cachewidth = r_polydesc.pixel_width;
-	cacheblock = r_polydesc.pixels;
-
-// copy the first vertex to the last vertex, so we don't have to deal with
-// wrapping
-	nump = r_polydesc.nump;
-	pverts = r_polydesc.pverts;
-	pverts[nump] = pverts[0];
-
-	R_PolygonCalculateGradients ();
-	R_PolygonScanLeftEdge ();
-	R_PolygonScanRightEdge ();
-
-	R_PolygonDrawSpans( s_polygon_spans, iswater );
-}
-
-/*
-** R_DrawAlphaSurfaces
-*/
-void R_DrawAlphaSurfaces( void )
-{
-	msurface_t *s = r_alpha_surfaces;
-
-	currentmodel = r_worldmodel;
-
-	modelorg[0] = -r_origin[0];
-	modelorg[1] = -r_origin[1];
-	modelorg[2] = -r_origin[2];
-
-	while ( s )
-	{
-		R_BuildPolygonFromSurface( s );
-
-		if (s->texinfo->flags & SURF_TRANS66)
-			R_ClipAndDrawPoly( 0.60f, ( s->texinfo->flags & SURF_WARP) != 0, true );
-		else
-			R_ClipAndDrawPoly( 0.30f, ( s->texinfo->flags & SURF_WARP) != 0, true );
-
-		s = s->nextalphasurface;
-	}
-	
-	r_alpha_surfaces = NULL;
-}
-
-/*
-** R_IMFlatShadedQuad
-*/
-void R_IMFlatShadedQuad( vec3_t a, vec3_t b, vec3_t c, vec3_t d, int color, float alpha )
-{
-	vec3_t s0, s1;
-
-	r_polydesc.nump = 4;
-	VectorCopy( r_origin, r_polydesc.viewer_position );
-
-	VectorCopy( a, r_clip_verts[0][0] );
-	VectorCopy( b, r_clip_verts[0][1] );
-	VectorCopy( c, r_clip_verts[0][2] );
-	VectorCopy( d, r_clip_verts[0][3] );
-
-	r_clip_verts[0][0][3] = 0;
-	r_clip_verts[0][1][3] = 0;
-	r_clip_verts[0][2][3] = 0;
-	r_clip_verts[0][3][3] = 0;
-
-	r_clip_verts[0][0][4] = 0;
-	r_clip_verts[0][1][4] = 0;
-	r_clip_verts[0][2][4] = 0;
-	r_clip_verts[0][3][4] = 0;
-
-	VectorSubtract( d, c, s0 );
-	VectorSubtract( c, b, s1 );
-	CrossProduct( s0, s1, r_polydesc.vpn );
-	VectorNormalize( r_polydesc.vpn );
-
-	r_polydesc.dist = DotProduct( r_polydesc.vpn, r_clip_verts[0][0] );
-
-	r_polyblendcolor = color;
-
-	R_ClipAndDrawPoly( alpha, false, false );
-}
-
--- a/ref_soft/r_polyse.c
+++ /dev/null
@@ -1,1539 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// d_polyset.c: routines for drawing sets of polygons sharing the same
-// texture (used for Alias models)
-
-#include "r_local.h"
-
-int	rand1k[] = {
-#include "rand1k.h"
-};
-
-#define MASK_1K	0x3FF
-
-int		rand1k_index = 0;
-
-// TODO: put in span spilling to shrink list size
-// !!! if this is changed, it must be changed in d_polysa.s too !!!
-#define DPS_MAXSPANS			MAXHEIGHT+1	
-									// 1 extra for spanpackage that marks end
-
-// !!! if this is changed, it must be changed in asm_draw.h too !!!
-typedef struct {
-	void			*pdest;
-	short			*pz;
-	int				count;
-	byte			*ptex;
-	int				sfrac, tfrac, light, zi;
-} spanpackage_t;
-
-typedef struct {
-	int		isflattop;
-	int		numleftedges;
-	int		*pleftedgevert0;
-	int		*pleftedgevert1;
-	int		*pleftedgevert2;
-	int		numrightedges;
-	int		*prightedgevert0;
-	int		*prightedgevert1;
-	int		*prightedgevert2;
-} edgetable;
-
-aliastriangleparms_t aliastriangleparms;
-
-int	r_p0[6], r_p1[6], r_p2[6];
-
-byte		*d_pcolormap;
-
-int			d_aflatcolor;
-int			d_xdenom;
-
-edgetable	*pedgetable;
-
-edgetable	edgetables[12] = {
-	{0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
-	{0, 2, r_p1, r_p0, r_p2,   1, r_p1, r_p2, NULL},
-	{1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
-	{0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
-	{0, 2, r_p0, r_p2, r_p1,   1, r_p0, r_p1, NULL},
-	{0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
-	{0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
-	{0, 2, r_p2, r_p1, r_p0,   1, r_p2, r_p0, NULL},
-	{0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
-	{1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
-	{1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
-	{0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
-};
-
-// FIXME: some of these can become statics
-int				a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
-int				r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
-int				r_zistepx, r_zistepy;
-int				d_aspancount, d_countextrastep;
-
-spanpackage_t			*a_spans;
-spanpackage_t			*d_pedgespanpackage;
-static int				ystart;
-byte					*d_pdest, *d_ptex;
-short					*d_pz;
-int						d_sfrac, d_tfrac, d_light, d_zi;
-int						d_ptexextrastep, d_sfracextrastep;
-int						d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
-int						d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
-int						d_sfracbasestep, d_tfracbasestep;
-int						d_ziextrastep, d_zibasestep;
-int						d_pzextrastep, d_pzbasestep;
-
-typedef struct {
-	int		quotient;
-	int		remainder;
-} adivtab_t;
-
-static adivtab_t	adivtab[32*32] = {
-#include "adivtab.h"
-};
-
-byte	*skintable[MAX_LBM_HEIGHT];
-int		skinwidth;
-byte	*skinstart;
-
-void	(*d_pdrawspans)(spanpackage_t *pspanpackage);
-
-void R_PolysetDrawSpans8_33 (spanpackage_t *pspanpackage);
-void R_PolysetDrawSpans8_66 (spanpackage_t *pspanpackage);
-void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage);
-
-void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage);
-void R_PolysetCalcGradients (int skinwidth);
-void R_DrawNonSubdiv (void);
-void R_PolysetSetEdgeTable (void);
-void R_RasterizeAliasPolySmooth (void);
-void R_PolysetScanLeftEdge(int height);
-void R_PolysetScanLeftEdge_C(int height);
-
-// ======================
-// PGM
-// 64 65 66 67 68 69 70 71   72 73 74 75 76 77 78 79
-byte iractive = 0;
-byte irtable[256] = { 79, 78, 77, 76, 75, 74, 73, 72,		// black/white
-					  71, 70, 69, 68, 67, 66, 65, 64,
-					  64, 65, 66, 67, 68, 69, 70, 71,		// dark taupe
-					  72, 73, 74, 75, 76, 77, 78, 79,
-
-					  64, 65, 66, 67, 68, 69, 70, 71,		// slate grey
-					  72, 73, 74, 75, 76, 77, 78, 79,
-					  208, 208, 208, 208, 208, 208, 208, 208,	// unused?'
-					  64, 66, 68, 70, 72, 74, 76, 78,		// dark yellow
-					  
-					  64, 65, 66, 67, 68, 69, 70, 71,		// dark red
-					  72, 73, 74, 75, 76, 77, 78, 79,
-					  64, 65, 66, 67, 68, 69, 70, 71,		// grey/tan
-					  72, 73, 74, 75, 76, 77, 78, 79,
-
-					  64, 66, 68, 70, 72, 74, 76, 78,		// chocolate
-					  68, 67, 66, 65, 64, 65, 66, 67,		// mauve / teal
-					  68, 69, 70, 71, 72, 73, 74, 75,
-					  76, 76, 77, 77, 78, 78, 79, 79,		
-
-					  64, 65, 66, 67, 68, 69, 70, 71,		// more mauve
-					  72, 73, 74, 75, 76, 77, 78, 79,
-					  64, 65, 66, 67, 68, 69, 70, 71,		// olive
-					  72, 73, 74, 75, 76, 77, 78, 79,
-
-					  64, 65, 66, 67, 68, 69, 70, 71,		// maroon
-					  72, 73, 74, 75, 76, 77, 78, 79,
-					  64, 65, 66, 67, 68, 69, 70, 71,		// sky blue
-					  72, 73, 74, 75, 76, 77, 78, 79,
-					  
-					  64, 65, 66, 67, 68, 69, 70, 71,		// olive again
-					  72, 73, 74, 75, 76, 77, 78, 79,
-					  64, 65, 66, 67, 68, 69, 70, 71,		// nuclear green
-					  64, 65, 66, 67, 68, 69, 70, 71,		// bright yellow
-
-					  64, 65, 66, 67, 68, 69, 70, 71,		// fire colors
-					  72, 73, 74, 75, 76, 77, 78, 79,
-					  208, 208, 64, 64, 70, 71, 72, 64,		// mishmash1
-					  66, 68, 70, 64, 65, 66, 67, 68};		// mishmash2
-// PGM
-// ======================
-
-/*
-================
-R_PolysetUpdateTables
-================
-*/
-void R_PolysetUpdateTables (void)
-{
-	int		i;
-	byte	*s;
-	
-	if (r_affinetridesc.skinwidth != skinwidth ||
-		r_affinetridesc.pskin != skinstart)
-	{
-		skinwidth = r_affinetridesc.skinwidth;
-		skinstart = r_affinetridesc.pskin;
-		s = skinstart;
-		for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)
-			skintable[i] = s;
-	}
-}
-
-
-/*
-================
-R_DrawTriangle
-================
-*/
-void R_DrawTriangle( void )
-{
-	spanpackage_t spans[DPS_MAXSPANS];
-
-	int dv1_ab, dv0_ac;
-	int dv0_ab, dv1_ac;
-
-	/*
-	d_xdenom = ( aliastriangleparms.a->v[1] - aliastriangleparms.b->v[1] ) * ( aliastriangleparms.a->v[0] - aliastriangleparms.c->v[0] ) -
-			   ( aliastriangleparms.a->v[0] - aliastriangleparms.b->v[0] ) * ( aliastriangleparms.a->v[1] - aliastriangleparms.c->v[1] );
-	*/
-
-	dv0_ab = aliastriangleparms.a->u - aliastriangleparms.b->u;
-	dv1_ab = aliastriangleparms.a->v - aliastriangleparms.b->v;
-
-	if ( !( dv0_ab | dv1_ab ) )
-		return;
-
-	dv0_ac = aliastriangleparms.a->u - aliastriangleparms.c->u;
-	dv1_ac = aliastriangleparms.a->v - aliastriangleparms.c->v;
-
-	if ( !( dv0_ac | dv1_ac ) )
-		return;
-
-	d_xdenom = ( dv0_ac * dv1_ab ) - ( dv0_ab * dv1_ac );
-
-	if ( d_xdenom < 0 )
-	{
-		a_spans = spans;
-
-		r_p0[0] = aliastriangleparms.a->u;		// u
-		r_p0[1] = aliastriangleparms.a->v;		// v
-		r_p0[2] = aliastriangleparms.a->s;		// s
-		r_p0[3] = aliastriangleparms.a->t;		// t
-		r_p0[4] = aliastriangleparms.a->l;		// light
-		r_p0[5] = aliastriangleparms.a->zi;		// iz
-
-		r_p1[0] = aliastriangleparms.b->u;
-		r_p1[1] = aliastriangleparms.b->v;
-		r_p1[2] = aliastriangleparms.b->s;
-		r_p1[3] = aliastriangleparms.b->t;
-		r_p1[4] = aliastriangleparms.b->l;
-		r_p1[5] = aliastriangleparms.b->zi;
-
-		r_p2[0] = aliastriangleparms.c->u;
-		r_p2[1] = aliastriangleparms.c->v;
-		r_p2[2] = aliastriangleparms.c->s;
-		r_p2[3] = aliastriangleparms.c->t;
-		r_p2[4] = aliastriangleparms.c->l;
-		r_p2[5] = aliastriangleparms.c->zi;
-
-		R_PolysetSetEdgeTable ();
-		R_RasterizeAliasPolySmooth ();
-	}
-}
-
-
-/*
-===================
-R_PolysetScanLeftEdge_C
-====================
-*/
-void R_PolysetScanLeftEdge_C(int height)
-{
-	do
-	{
-		d_pedgespanpackage->pdest = d_pdest;
-		d_pedgespanpackage->pz = d_pz;
-		d_pedgespanpackage->count = d_aspancount;
-		d_pedgespanpackage->ptex = d_ptex;
-
-		d_pedgespanpackage->sfrac = d_sfrac;
-		d_pedgespanpackage->tfrac = d_tfrac;
-
-	// FIXME: need to clamp l, s, t, at both ends?
-		d_pedgespanpackage->light = d_light;
-		d_pedgespanpackage->zi = d_zi;
-
-		d_pedgespanpackage++;
-
-		errorterm += erroradjustup;
-		if (errorterm >= 0)
-		{
-			d_pdest += d_pdestextrastep;
-			d_pz += d_pzextrastep;
-			d_aspancount += d_countextrastep;
-			d_ptex += d_ptexextrastep;
-			d_sfrac += d_sfracextrastep;
-			d_ptex += d_sfrac >> 16;
-
-			d_sfrac &= 0xFFFF;
-			d_tfrac += d_tfracextrastep;
-			if (d_tfrac & 0x10000)
-			{
-				d_ptex += r_affinetridesc.skinwidth;
-				d_tfrac &= 0xFFFF;
-			}
-			d_light += d_lightextrastep;
-			d_zi += d_ziextrastep;
-			errorterm -= erroradjustdown;
-		}
-		else
-		{
-			d_pdest += d_pdestbasestep;
-			d_pz += d_pzbasestep;
-			d_aspancount += ubasestep;
-			d_ptex += d_ptexbasestep;
-			d_sfrac += d_sfracbasestep;
-			d_ptex += d_sfrac >> 16;
-			d_sfrac &= 0xFFFF;
-			d_tfrac += d_tfracbasestep;
-			if (d_tfrac & 0x10000)
-			{
-				d_ptex += r_affinetridesc.skinwidth;
-				d_tfrac &= 0xFFFF;
-			}
-			d_light += d_lightbasestep;
-			d_zi += d_zibasestep;
-		}
-	} while (--height);
-}
-
-/*
-===================
-FloorDivMod
-
-Returns mathematically correct (floor-based) quotient and remainder for
-numer and denom, both of which should contain no fractional part. The
-quotient must fit in 32 bits.
-FIXME: GET RID OF THIS! (FloorDivMod)
-====================
-*/
-void FloorDivMod (float numer, float denom, int *quotient,
-		int *rem)
-{
-	int		q, r;
-	float	x;
-
-	if (numer >= 0.0)
-	{
-
-		x = floor(numer / denom);
-		q = (int)x;
-		r = (int)floor(numer - (x * denom));
-	}
-	else
-	{
-	//
-	// perform operations with positive values, and fix mod to make floor-based
-	//
-		x = floor(-numer / denom);
-		q = -(int)x;
-		r = (int)floor(-numer - (x * denom));
-		if (r != 0)
-		{
-			q--;
-			r = (int)denom - r;
-		}
-	}
-
-	*quotient = q;
-	*rem = r;
-}
-
-
-/*
-===================
-R_PolysetSetUpForLineScan
-====================
-*/
-void R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
-		fixed8_t endvertu, fixed8_t endvertv)
-{
-	float		dm, dn;
-	int			tm, tn;
-	adivtab_t	*ptemp;
-
-// TODO: implement x86 version
-
-	errorterm = -1;
-
-	tm = endvertu - startvertu;
-	tn = endvertv - startvertv;
-
-	if (((tm <= 16) && (tm >= -15)) &&
-		((tn <= 16) && (tn >= -15)))
-	{
-		ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
-		ubasestep = ptemp->quotient;
-		erroradjustup = ptemp->remainder;
-		erroradjustdown = tn;
-	}
-	else
-	{
-		dm = tm;
-		dn = tn;
-
-		FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
-
-		erroradjustdown = dn;
-	}
-}
-
-
-
-/*
-================
-R_PolysetCalcGradients
-================
-*/
-#if id386 && !defined __linux__
-void R_PolysetCalcGradients( int skinwidth )
-{
-	static float xstepdenominv, ystepdenominv, t0, t1;
-	static float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
-	static float one = 1.0F, negative_one = -1.0F;
-	static unsigned long t0_int, t1_int;
-
-	extern unsigned long fpu_sp24_ceil_cw, fpu_ceil_cw, fpu_chop_cw;
-
-	/*
-	p00_minus_p20 = r_p0[0] - r_p2[0];
-	p01_minus_p21 = r_p0[1] - r_p2[1];
-	p10_minus_p20 = r_p1[0] - r_p2[0];
-	p11_minus_p21 = r_p1[1] - r_p2[1];
-	*/
-
-	__asm mov eax, dword ptr [r_p0+0]
-	__asm mov ebx, dword ptr [r_p0+4]
-	__asm sub eax, dword ptr [r_p2+0]
-	__asm sub ebx, dword ptr [r_p2+4]
-	__asm mov p00_minus_p20, eax
-	__asm mov p01_minus_p21, ebx
-	__asm fild dword ptr p00_minus_p20
-	__asm fild dword ptr p01_minus_p21
-	__asm mov eax, dword ptr [r_p1+0]
-	__asm mov ebx, dword ptr [r_p1+4]
-	__asm sub eax, dword ptr [r_p2+0]
-	__asm sub ebx, dword ptr [r_p2+4]
-	__asm fstp p01_minus_p21
-	__asm fstp p00_minus_p20
-	__asm mov p10_minus_p20, eax
-	__asm mov p11_minus_p21, ebx
-	__asm fild dword ptr p10_minus_p20
-	__asm fild dword ptr p11_minus_p21
-	__asm fstp p11_minus_p21
-	__asm fstp p10_minus_p20
-
-	/*
-	xstepdenominv = 1.0 / (float)d_xdenom;
-
-	ystepdenominv = -xstepdenominv;
-	*/
-
-	/*
-	** put FPU in single precision ceil mode
-	*/
-	__asm fldcw word ptr [fpu_sp24_ceil_cw]
-//	__asm fldcw word ptr [fpu_ceil_cw]
-
-	__asm fild  dword ptr d_xdenom    ; d_xdenom
-	__asm fdivr one                   ; 1 / d_xdenom
-	__asm fst   xstepdenominv         ; 
-	__asm fmul  negative_one          ; -( 1 / d_xdenom )
-
-// ceil () for light so positive steps are exaggerated, negative steps
-// diminished,  pushing us away from underflow toward overflow. Underflow is
-// very visible, overflow is very unlikely, because of ambient lighting
-	/*
-	t0 = r_p0[4] - r_p2[4];
-	t1 = r_p1[4] - r_p2[4];
-	r_lstepx = (int)
-			ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
-	r_lstepy = (int)
-			ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
-	*/
-	__asm mov   eax, dword ptr [r_p0+16]
-	__asm mov   ebx, dword ptr [r_p1+16]
-	__asm sub   eax, dword ptr [r_p2+16]
-	__asm sub   ebx, dword ptr [r_p2+16]
-
-	__asm fstp  ystepdenominv       ; (empty)
-
-	__asm mov   t0_int, eax
-	__asm mov   t1_int, ebx
-	__asm fild  t0_int              ; t0
-	__asm fild  t1_int              ; t1 | t0
-	__asm fxch  st(1)               ; t0 | t1
-	__asm fstp  t0                  ; t1
-	__asm fst   t1                  ; t1
-	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
-	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
-	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fsubrp st(1), st          ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fxch  st(1)
-	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
-	__asm fxch  st(1)               ; r_lstepx | r_lstepy
-	__asm fistp dword ptr [r_lstepx]
-	__asm fistp dword ptr [r_lstepy]
-
-	/*
-	** put FPU back into extended precision chop mode
-	*/
-	__asm fldcw word ptr [fpu_chop_cw]
-
-	/*
-	t0 = r_p0[2] - r_p2[2];
-	t1 = r_p1[2] - r_p2[2];
-	r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
-			xstepdenominv);
-	r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
-			ystepdenominv);
-	*/
-	__asm mov eax, dword ptr [r_p0+8]
-	__asm mov ebx, dword ptr [r_p1+8]
-	__asm sub eax, dword ptr [r_p2+8]
-	__asm sub ebx, dword ptr [r_p2+8]
-	__asm mov   t0_int, eax
-	__asm mov   t1_int, ebx
-	__asm fild  t0_int              ; t0
-	__asm fild  t1_int              ; t1 | t0
-	__asm fxch  st(1)               ; t0 | t1
-	__asm fstp  t0                  ; t1
-	__asm fst   t1                  ; (empty)
-
-	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
-	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
-	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fxch  st(1)
-	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
-	__asm fxch  st(1)               ; r_lstepx | r_lstepy
-	__asm fistp dword ptr [r_sstepx]
-	__asm fistp dword ptr [r_sstepy]
-
-	/*
-	t0 = r_p0[3] - r_p2[3];
-	t1 = r_p1[3] - r_p2[3];
-	r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
-			xstepdenominv);
-	r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
-			ystepdenominv);
-	*/
-	__asm mov eax, dword ptr [r_p0+12]
-	__asm mov ebx, dword ptr [r_p1+12]
-	__asm sub eax, dword ptr [r_p2+12]
-	__asm sub ebx, dword ptr [r_p2+12]
-
-	__asm mov   t0_int, eax
-	__asm mov   t1_int, ebx
-	__asm fild  t0_int              ; t0
-	__asm fild  t1_int              ; t1 | t0
-	__asm fxch  st(1)               ; t0 | t1
-	__asm fstp  t0                  ; t1
-	__asm fst   t1                  ; (empty)
-
-	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
-	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
-	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fxch  st(1)
-	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
-	__asm fxch  st(1)               ; r_lstepx | r_lstepy
-	__asm fistp dword ptr [r_tstepx]
-	__asm fistp dword ptr [r_tstepy]
-
-	/*
-	t0 = r_p0[5] - r_p2[5];
-	t1 = r_p1[5] - r_p2[5];
-	r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
-			xstepdenominv);
-	r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
-			ystepdenominv);
-	*/
-	__asm mov eax, dword ptr [r_p0+20]
-	__asm mov ebx, dword ptr [r_p1+20]
-	__asm sub eax, dword ptr [r_p2+20]
-	__asm sub ebx, dword ptr [r_p2+20]
-
-	__asm mov   t0_int, eax
-	__asm mov   t1_int, ebx
-	__asm fild  t0_int              ; t0
-	__asm fild  t1_int              ; t1 | t0
-	__asm fxch  st(1)               ; t0 | t1
-	__asm fstp  t0                  ; t1
-	__asm fst   t1                  ; (empty)
-
-	__asm fmul  p01_minus_p21       ; t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p01_minus_p21
-	__asm fmul  p11_minus_p21       ; t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t1                  ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p00_minus_p20       ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fld   t0                  ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fmul  p10_minus_p20       ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
-	__asm fxch  st(2)               ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
-	__asm fsubp st(3), st           ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fsubrp st(1), st           ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
-	__asm fxch  st(1)               ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fmul  xstepdenominv       ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
-	__asm fxch  st(1)
-	__asm fmul  ystepdenominv       ; r_lstepy | r_lstepx
-	__asm fxch  st(1)               ; r_lstepx | r_lstepy
-	__asm fistp dword ptr [r_zistepx]
-	__asm fistp dword ptr [r_zistepy]
-
-	/*
-#if	id386ALIAS
-	a_sstepxfrac = r_sstepx << 16;
-	a_tstepxfrac = r_tstepx << 16;
-#else
-	a_sstepxfrac = r_sstepx & 0xFFFF;
-	a_tstepxfrac = r_tstepx & 0xFFFF;
-#endif
-	*/
-	__asm mov eax, d_pdrawspans
-	__asm cmp eax, offset R_PolysetDrawSpans8_Opaque
-	__asm mov eax, r_sstepx
-	__asm mov ebx, r_tstepx
-	__asm jne translucent
-//#if id386ALIAS
-	__asm shl eax, 16
-	__asm shl ebx, 16
-	__asm jmp done_with_steps
-//#else
-translucent:
-	__asm and eax, 0ffffh
-	__asm and ebx, 0ffffh
-//#endif
-done_with_steps:
-	__asm mov a_sstepxfrac, eax
-	__asm mov a_tstepxfrac, ebx
-
-	/*
-	a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
-	*/
-	__asm mov ebx, r_tstepx
-	__asm mov ecx, r_sstepx
-	__asm sar ebx, 16
-	__asm mov eax, skinwidth
-	__asm mul ebx
-	__asm sar ecx, 16
-	__asm add eax, ecx
-	__asm mov a_ststepxwhole, eax
-}
-#else
-void R_PolysetCalcGradients (int skinwidth)
-{
-	float	xstepdenominv, ystepdenominv, t0, t1;
-	float	p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
-
-	p00_minus_p20 = r_p0[0] - r_p2[0];
-	p01_minus_p21 = r_p0[1] - r_p2[1];
-	p10_minus_p20 = r_p1[0] - r_p2[0];
-	p11_minus_p21 = r_p1[1] - r_p2[1];
-
-	xstepdenominv = 1.0 / (float)d_xdenom;
-
-	ystepdenominv = -xstepdenominv;
-
-// ceil () for light so positive steps are exaggerated, negative steps
-// diminished,  pushing us away from underflow toward overflow. Underflow is
-// very visible, overflow is very unlikely, because of ambient lighting
-	t0 = r_p0[4] - r_p2[4];
-	t1 = r_p1[4] - r_p2[4];
-	r_lstepx = (int)
-			ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
-	r_lstepy = (int)
-			ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
-
-	t0 = r_p0[2] - r_p2[2];
-	t1 = r_p1[2] - r_p2[2];
-	r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
-			xstepdenominv);
-	r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
-			ystepdenominv);
-
-	t0 = r_p0[3] - r_p2[3];
-	t1 = r_p1[3] - r_p2[3];
-	r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
-			xstepdenominv);
-	r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
-			ystepdenominv);
-
-	t0 = r_p0[5] - r_p2[5];
-	t1 = r_p1[5] - r_p2[5];
-	r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
-			xstepdenominv);
-	r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
-			ystepdenominv);
-
-//#if	id386ALIAS
-#if id386
-	if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-	{
-		a_sstepxfrac = r_sstepx << 16;
-		a_tstepxfrac = r_tstepx << 16;
-	}
-	else
-#endif
-	{
-//#else
-		a_sstepxfrac = r_sstepx & 0xFFFF;
-		a_tstepxfrac = r_tstepx & 0xFFFF;
-	}
-//#endif
-
-	a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
-}
-#endif
-
-/*
-================
-R_PolysetDrawThreshSpans8
-
-Random fizzle fade rasterizer
-================
-*/
-void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage)
-{
-	int		lcount;
-	byte	*lpdest;
-	byte	*lptex;
-	int		lsfrac, ltfrac;
-	int		llight;
-	int		lzi;
-	short	*lpz;
-
-	do
-	{
-		lcount = d_aspancount - pspanpackage->count;
-
-		errorterm += erroradjustup;
-		if (errorterm >= 0)
-		{
-			d_aspancount += d_countextrastep;
-			errorterm -= erroradjustdown;
-		}
-		else
-		{
-			d_aspancount += ubasestep;
-		}
-
-		if (lcount)
-		{
-			lpdest = pspanpackage->pdest;
-			lptex = pspanpackage->ptex;
-			lpz = pspanpackage->pz;
-			lsfrac = pspanpackage->sfrac;
-			ltfrac = pspanpackage->tfrac;
-			llight = pspanpackage->light;
-			lzi = pspanpackage->zi;
-
-			do
-			{
-				if ((lzi >> 16) >= *lpz)
-				{
-					rand1k_index = (rand1k_index + 1) & MASK_1K;
-
-					if (rand1k[rand1k_index] <= r_affinetridesc.vis_thresh)
-					{
-						*lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
-						*lpz = lzi >> 16;
-					}
-				}
-
-				lpdest++;
-				lzi += r_zistepx;
-				lpz++;
-				llight += r_lstepx;
-				lptex += a_ststepxwhole;
-				lsfrac += a_sstepxfrac;
-				lptex += lsfrac >> 16;
-				lsfrac &= 0xFFFF;
-				ltfrac += a_tstepxfrac;
-				if (ltfrac & 0x10000)
-				{
-					lptex += r_affinetridesc.skinwidth;
-					ltfrac &= 0xFFFF;
-				}
-			} while (--lcount);
-		}
-
-		pspanpackage++;
-	} while (pspanpackage->count != -999999);
-}
-
-
-/*
-================
-R_PolysetDrawSpans8
-================
-*/
-void R_PolysetDrawSpans8_33( spanpackage_t *pspanpackage)
-{
-	int		lcount;
-	byte	*lpdest;
-	byte	*lptex;
-	int		lsfrac, ltfrac;
-	int		llight;
-	int		lzi;
-	short	*lpz;
-
-	do
-	{
-		lcount = d_aspancount - pspanpackage->count;
-
-		errorterm += erroradjustup;
-		if (errorterm >= 0)
-		{
-			d_aspancount += d_countextrastep;
-			errorterm -= erroradjustdown;
-		}
-		else
-		{
-			d_aspancount += ubasestep;
-		}
-
-		if (lcount)
-		{
-			lpdest = pspanpackage->pdest;
-			lptex = pspanpackage->ptex;
-			lpz = pspanpackage->pz;
-			lsfrac = pspanpackage->sfrac;
-			ltfrac = pspanpackage->tfrac;
-			llight = pspanpackage->light;
-			lzi = pspanpackage->zi;
-
-			do
-			{
-				if ((lzi >> 16) >= *lpz)
-				{
-					int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
-
-					*lpdest = vid.alphamap[temp+ *lpdest*256];
-				}
-				lpdest++;
-				lzi += r_zistepx;
-				lpz++;
-				llight += r_lstepx;
-				lptex += a_ststepxwhole;
-				lsfrac += a_sstepxfrac;
-				lptex += lsfrac >> 16;
-				lsfrac &= 0xFFFF;
-				ltfrac += a_tstepxfrac;
-				if (ltfrac & 0x10000)
-				{
-					lptex += r_affinetridesc.skinwidth;
-					ltfrac &= 0xFFFF;
-				}
-			} while (--lcount);
-		}
-
-		pspanpackage++;
-	} while (pspanpackage->count != -999999);
-}
-
-void R_PolysetDrawSpansConstant8_33( spanpackage_t *pspanpackage)
-{
-	int		lcount;
-	byte	*lpdest;
-	int		lzi;
-	short	*lpz;
-
-	do
-	{
-		lcount = d_aspancount - pspanpackage->count;
-
-		errorterm += erroradjustup;
-		if (errorterm >= 0)
-		{
-			d_aspancount += d_countextrastep;
-			errorterm -= erroradjustdown;
-		}
-		else
-		{
-			d_aspancount += ubasestep;
-		}
-
-		if (lcount)
-		{
-			lpdest = pspanpackage->pdest;
-			lpz = pspanpackage->pz;
-			lzi = pspanpackage->zi;
-
-			do
-			{
-				if ((lzi >> 16) >= *lpz)
-				{
-					*lpdest = vid.alphamap[r_aliasblendcolor + *lpdest*256];
-				}
-				lpdest++;
-				lzi += r_zistepx;
-				lpz++;
-			} while (--lcount);
-		}
-
-		pspanpackage++;
-	} while (pspanpackage->count != -999999);
-}
-
-void R_PolysetDrawSpans8_66(spanpackage_t *pspanpackage)
-{
-	int		lcount;
-	byte	*lpdest;
-	byte	*lptex;
-	int		lsfrac, ltfrac;
-	int		llight;
-	int		lzi;
-	short	*lpz;
-
-	do
-	{
-		lcount = d_aspancount - pspanpackage->count;
-
-		errorterm += erroradjustup;
-		if (errorterm >= 0)
-		{
-			d_aspancount += d_countextrastep;
-			errorterm -= erroradjustdown;
-		}
-		else
-		{
-			d_aspancount += ubasestep;
-		}
-
-		if (lcount)
-		{
-			lpdest = pspanpackage->pdest;
-			lptex = pspanpackage->ptex;
-			lpz = pspanpackage->pz;
-			lsfrac = pspanpackage->sfrac;
-			ltfrac = pspanpackage->tfrac;
-			llight = pspanpackage->light;
-			lzi = pspanpackage->zi;
-
-			do
-			{
-				if ((lzi >> 16) >= *lpz)
-				{
-					int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
-
-					*lpdest = vid.alphamap[temp*256 + *lpdest];
-					*lpz = lzi >> 16;
-				}
-				lpdest++;
-				lzi += r_zistepx;
-				lpz++;
-				llight += r_lstepx;
-				lptex += a_ststepxwhole;
-				lsfrac += a_sstepxfrac;
-				lptex += lsfrac >> 16;
-				lsfrac &= 0xFFFF;
-				ltfrac += a_tstepxfrac;
-				if (ltfrac & 0x10000)
-				{
-					lptex += r_affinetridesc.skinwidth;
-					ltfrac &= 0xFFFF;
-				}
-			} while (--lcount);
-		}
-
-		pspanpackage++;
-	} while (pspanpackage->count != -999999);
-}
-
-void R_PolysetDrawSpansConstant8_66( spanpackage_t *pspanpackage)
-{
-	int		lcount;
-	byte	*lpdest;
-	int		lzi;
-	short	*lpz;
-
-	do
-	{
-		lcount = d_aspancount - pspanpackage->count;
-
-		errorterm += erroradjustup;
-		if (errorterm >= 0)
-		{
-			d_aspancount += d_countextrastep;
-			errorterm -= erroradjustdown;
-		}
-		else
-		{
-			d_aspancount += ubasestep;
-		}
-
-		if (lcount)
-		{
-			lpdest = pspanpackage->pdest;
-			lpz = pspanpackage->pz;
-			lzi = pspanpackage->zi;
-
-			do
-			{
-				if ((lzi >> 16) >= *lpz)
-				{
-					*lpdest = vid.alphamap[r_aliasblendcolor*256 + *lpdest];
-				}
-				lpdest++;
-				lzi += r_zistepx;
-				lpz++;
-			} while (--lcount);
-		}
-
-		pspanpackage++;
-	} while (pspanpackage->count != -999999);
-}
-
-#if !id386
-void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage)
-{
-	int		lcount;
-
-	do
-	{
-		lcount = d_aspancount - pspanpackage->count;
-
-		errorterm += erroradjustup;
-		if (errorterm >= 0)
-		{
-			d_aspancount += d_countextrastep;
-			errorterm -= erroradjustdown;
-		}
-		else
-		{
-			d_aspancount += ubasestep;
-		}
-
-		if (lcount)
-		{
-			int		lsfrac, ltfrac;
-			byte	*lpdest;
-			byte	*lptex;
-			int		llight;
-			int		lzi;
-			short	*lpz;
-
-			lpdest = pspanpackage->pdest;
-			lptex = pspanpackage->ptex;
-			lpz = pspanpackage->pz;
-			lsfrac = pspanpackage->sfrac;
-			ltfrac = pspanpackage->tfrac;
-			llight = pspanpackage->light;
-			lzi = pspanpackage->zi;
-
-			do
-			{
-				if ((lzi >> 16) >= *lpz)
-				{
-//PGM
-					if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
-						*lpdest = ((byte *)vid.colormap)[irtable[*lptex]];
-					else
-					*lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
-//PGM
-					*lpz = lzi >> 16;
-				}
-				lpdest++;
-				lzi += r_zistepx;
-				lpz++;
-				llight += r_lstepx;
-				lptex += a_ststepxwhole;
-				lsfrac += a_sstepxfrac;
-				lptex += lsfrac >> 16;
-				lsfrac &= 0xFFFF;
-				ltfrac += a_tstepxfrac;
-				if (ltfrac & 0x10000)
-				{
-					lptex += r_affinetridesc.skinwidth;
-					ltfrac &= 0xFFFF;
-				}
-			} while (--lcount);
-		}
-
-		pspanpackage++;
-	} while (pspanpackage->count != -999999);
-}
-#endif
-
-
-/*
-================
-R_PolysetFillSpans8
-================
-*/
-void R_PolysetFillSpans8 (spanpackage_t *pspanpackage)
-{
-	int				color;
-
-// FIXME: do z buffering
-
-	color = d_aflatcolor++;
-
-	while (1)
-	{
-		int		lcount;
-		byte	*lpdest;
-
-		lcount = pspanpackage->count;
-
-		if (lcount == -1)
-			return;
-
-		if (lcount)
-		{
-			lpdest = pspanpackage->pdest;
-
-			do
-			{
-				*lpdest++ = color;
-			} while (--lcount);
-		}
-
-		pspanpackage++;
-	}
-}
-
-/*
-================
-R_RasterizeAliasPolySmooth
-================
-*/
-void R_RasterizeAliasPolySmooth (void)
-{
-	int				initialleftheight, initialrightheight;
-	int				*plefttop, *prighttop, *pleftbottom, *prightbottom;
-	int				working_lstepx, originalcount;
-
-	plefttop = pedgetable->pleftedgevert0;
-	prighttop = pedgetable->prightedgevert0;
-
-	pleftbottom = pedgetable->pleftedgevert1;
-	prightbottom = pedgetable->prightedgevert1;
-
-	initialleftheight = pleftbottom[1] - plefttop[1];
-	initialrightheight = prightbottom[1] - prighttop[1];
-
-//
-// set the s, t, and light gradients, which are consistent across the triangle
-// because being a triangle, things are affine
-//
-	R_PolysetCalcGradients (r_affinetridesc.skinwidth);
-//
-// rasterize the polygon
-//
-
-//
-// scan out the top (and possibly only) part of the left edge
-//
-	d_pedgespanpackage = a_spans;
-
-	ystart = plefttop[1];
-	d_aspancount = plefttop[0] - prighttop[0];
-
-	d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
-			(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
-//#if	id386ALIAS
-#if id386
-	if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-	{
-		d_sfrac = (plefttop[2] & 0xFFFF) << 16;
-		d_tfrac = (plefttop[3] & 0xFFFF) << 16;
-	}
-//#else
-	else
-#endif
-	{
-		d_sfrac = plefttop[2] & 0xFFFF;
-		d_tfrac = plefttop[3] & 0xFFFF;
-	}
-//#endif
-	d_light = plefttop[4];
-	d_zi = plefttop[5];
-
-	d_pdest = (byte *)d_viewbuffer +
-			ystart * r_screenwidth + plefttop[0];
-	d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
-
-	if (initialleftheight == 1)
-	{
-		d_pedgespanpackage->pdest = d_pdest;
-		d_pedgespanpackage->pz = d_pz;
-		d_pedgespanpackage->count = d_aspancount;
-		d_pedgespanpackage->ptex = d_ptex;
-
-		d_pedgespanpackage->sfrac = d_sfrac;
-		d_pedgespanpackage->tfrac = d_tfrac;
-
-	// FIXME: need to clamp l, s, t, at both ends?
-		d_pedgespanpackage->light = d_light;
-		d_pedgespanpackage->zi = d_zi;
-
-		d_pedgespanpackage++;
-	}
-	else
-	{
-		R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
-							  pleftbottom[0], pleftbottom[1]);
-
-//#if	id386ALIAS
-#if id386
-		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-		{
-			d_pzbasestep = (d_zwidth + ubasestep) << 1;
-			d_pzextrastep = d_pzbasestep + 2;
-		}
-//#else
-		else
-#endif
-		{
-			d_pzbasestep = d_zwidth + ubasestep;
-			d_pzextrastep = d_pzbasestep + 1;
-		}
-//#endif
-
-		d_pdestbasestep = r_screenwidth + ubasestep;
-		d_pdestextrastep = d_pdestbasestep + 1;
-
-	// TODO: can reuse partial expressions here
-
-	// for negative steps in x along left edge, bias toward overflow rather than
-	// underflow (sort of turning the floor () we did in the gradient calcs into
-	// ceil (), but plus a little bit)
-		if (ubasestep < 0)
-			working_lstepx = r_lstepx - 1;
-		else
-			working_lstepx = r_lstepx;
-
-		d_countextrastep = ubasestep + 1;
-		d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
-				((r_tstepy + r_tstepx * ubasestep) >> 16) *
-				r_affinetridesc.skinwidth;
-//#if	id386ALIAS
-#if id386
-		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-		{
-			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
-			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
-		}
-		else
-#endif
-		{
-//#else
-			d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
-			d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
-		}
-//#endif
-		d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
-		d_zibasestep = r_zistepy + r_zistepx * ubasestep;
-
-		d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
-				((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
-				r_affinetridesc.skinwidth;
-//#if	id386ALIAS
-#if id386
-		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-		{
-			d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
-			d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
-		}
-		else
-#endif
-		{
-//#else
-			d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
-			d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
-		}
-//#endif
-		d_lightextrastep = d_lightbasestep + working_lstepx;
-		d_ziextrastep = d_zibasestep + r_zistepx;
-
-#if id386
-		if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-		{
-			R_PolysetScanLeftEdge (initialleftheight);
-		}
-		else
-#endif
-		{
-			R_PolysetScanLeftEdge_C(initialleftheight);
-		}
-	}
-
-//
-// scan out the bottom part of the left edge, if it exists
-//
-	if (pedgetable->numleftedges == 2)
-	{
-		int		height;
-
-		plefttop = pleftbottom;
-		pleftbottom = pedgetable->pleftedgevert2;
-
-		height = pleftbottom[1] - plefttop[1];
-
-// TODO: make this a function; modularize this function in general
-
-		ystart = plefttop[1];
-		d_aspancount = plefttop[0] - prighttop[0];
-		d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
-				(plefttop[3] >> 16) * r_affinetridesc.skinwidth;
-		d_sfrac = 0;
-		d_tfrac = 0;
-		d_light = plefttop[4];
-		d_zi = plefttop[5];
-
-		d_pdest = (byte *)d_viewbuffer + ystart * r_screenwidth + plefttop[0];
-		d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
-
-		if (height == 1)
-		{
-			d_pedgespanpackage->pdest = d_pdest;
-			d_pedgespanpackage->pz = d_pz;
-			d_pedgespanpackage->count = d_aspancount;
-			d_pedgespanpackage->ptex = d_ptex;
-
-			d_pedgespanpackage->sfrac = d_sfrac;
-			d_pedgespanpackage->tfrac = d_tfrac;
-
-		// FIXME: need to clamp l, s, t, at both ends?
-			d_pedgespanpackage->light = d_light;
-			d_pedgespanpackage->zi = d_zi;
-
-			d_pedgespanpackage++;
-		}
-		else
-		{
-			R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
-								  pleftbottom[0], pleftbottom[1]);
-
-			d_pdestbasestep = r_screenwidth + ubasestep;
-			d_pdestextrastep = d_pdestbasestep + 1;
-
-//#if	id386ALIAS
-#if id386
-			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-			{
-				d_pzbasestep = (d_zwidth + ubasestep) << 1;
-				d_pzextrastep = d_pzbasestep + 2;
-			}
-//#else
-			else
-#endif
-			{
-				d_pzbasestep = d_zwidth + ubasestep;
-				d_pzextrastep = d_pzbasestep + 1;
-			}
-//#endif
-
-			if (ubasestep < 0)
-				working_lstepx = r_lstepx - 1;
-			else
-				working_lstepx = r_lstepx;
-
-			d_countextrastep = ubasestep + 1;
-			d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
-					((r_tstepy + r_tstepx * ubasestep) >> 16) *
-					r_affinetridesc.skinwidth;
-//#if	id386ALIAS
-#if id386
-			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-			{
-				d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
-				d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
-			}
-//#else
-			else
-#endif
-			{
-				d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
-				d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
-			}
-//#endif
-			d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
-			d_zibasestep = r_zistepy + r_zistepx * ubasestep;
-
-			d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
-					((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
-					r_affinetridesc.skinwidth;
-//#if	id386ALIAS
-#if id386
-			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-			{
-				d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
-				d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
-			}
-			else
-#endif
-//#endif
-			{
-				d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
-				d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
-			}
-//#endif
-			d_lightextrastep = d_lightbasestep + working_lstepx;
-			d_ziextrastep = d_zibasestep + r_zistepx;
-
-#if id386
-			if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
-			{
-				R_PolysetScanLeftEdge (height);
-			}
-			else
-#endif
-			{
-				R_PolysetScanLeftEdge_C(height);
-			}
-		}
-	}
-
-// scan out the top (and possibly only) part of the right edge, updating the
-// count field
-	d_pedgespanpackage = a_spans;
-
-	R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
-						  prightbottom[0], prightbottom[1]);
-	d_aspancount = 0;
-	d_countextrastep = ubasestep + 1;
-	originalcount = a_spans[initialrightheight].count;
-	a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
-	(*d_pdrawspans) (a_spans);
-
-// scan out the bottom part of the right edge, if it exists
-	if (pedgetable->numrightedges == 2)
-	{
-		int				height;
-		spanpackage_t	*pstart;
-
-		pstart = a_spans + initialrightheight;
-		pstart->count = originalcount;
-
-		d_aspancount = prightbottom[0] - prighttop[0];
-
-		prighttop = prightbottom;
-		prightbottom = pedgetable->prightedgevert2;
-
-		height = prightbottom[1] - prighttop[1];
-
-		R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
-							  prightbottom[0], prightbottom[1]);
-
-		d_countextrastep = ubasestep + 1;
-		a_spans[initialrightheight + height].count = -999999;
-											// mark end of the spanpackages
-		(*d_pdrawspans) (pstart);
-	}
-}
-
-
-/*
-================
-R_PolysetSetEdgeTable
-================
-*/
-void R_PolysetSetEdgeTable (void)
-{
-	int			edgetableindex;
-
-	edgetableindex = 0;	// assume the vertices are already in
-						//  top to bottom order
-
-//
-// determine which edges are right & left, and the order in which
-// to rasterize them
-//
-	if (r_p0[1] >= r_p1[1])
-	{
-		if (r_p0[1] == r_p1[1])
-		{
-			if (r_p0[1] < r_p2[1])
-				pedgetable = &edgetables[2];
-			else
-				pedgetable = &edgetables[5];
-
-			return;
-		}
-		else
-		{
-			edgetableindex = 1;
-		}
-	}
-
-	if (r_p0[1] == r_p2[1])
-	{
-		if (edgetableindex)
-			pedgetable = &edgetables[8];
-		else
-			pedgetable = &edgetables[9];
-
-		return;
-	}
-	else if (r_p1[1] == r_p2[1])
-	{
-		if (edgetableindex)
-			pedgetable = &edgetables[10];
-		else
-			pedgetable = &edgetables[11];
-
-		return;
-	}
-
-	if (r_p0[1] > r_p2[1])
-		edgetableindex += 2;
-
-	if (r_p1[1] > r_p2[1])
-		edgetableindex += 4;
-
-	pedgetable = &edgetables[edgetableindex];
-}
-
-
--- a/ref_soft/r_rast.c
+++ /dev/null
@@ -1,852 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_rast.c
-
-#include <assert.h>
-
-#include "r_local.h"
-
-#define MAXLEFTCLIPEDGES		100
-
-// !!! if these are changed, they must be changed in asm_draw.h too !!!
-#define FULLY_CLIPPED_CACHED	0x80000000
-#define FRAMECOUNT_MASK			0x7FFFFFFF
-
-unsigned int	cacheoffset;
-
-int			c_faceclip;					// number of faces clipped
-
-
-clipplane_t	*entity_clipplanes;
-clipplane_t	view_clipplanes[4];
-clipplane_t	world_clipplanes[16];
-
-medge_t			*r_pedge;
-
-qboolean		r_leftclipped, r_rightclipped;
-static qboolean	makeleftedge, makerightedge;
-qboolean		r_nearzionly;
-
-int		sintable[1280];
-int		intsintable[1280];
-int		blanktable[1280];		// PGM
-
-mvertex_t	r_leftenter, r_leftexit;
-mvertex_t	r_rightenter, r_rightexit;
-
-typedef struct
-{
-	float	u,v;
-	int		ceilv;
-} evert_t;
-
-int				r_emitted;
-float			r_nearzi;
-float			r_u1, r_v1, r_lzi1;
-int				r_ceilv1;
-
-qboolean		r_lastvertvalid;
-int				r_skyframe;
-
-msurface_t		*r_skyfaces;
-mplane_t		r_skyplanes[6];
-mtexinfo_t		r_skytexinfo[6];
-mvertex_t		*r_skyverts;
-medge_t			*r_skyedges;
-int				*r_skysurfedges;
-
-// I just copied this data from a box map...
-int skybox_planes[12] = {2,-128, 0,-128, 2,128, 1,128, 0,128, 1,-128};
-
-int box_surfedges[24] = { 1,2,3,4,  -1,5,6,7,  8,9,-6,10,  -2,-7,-9,11,
-  12,-3,-11,-8,  -12,-10,-5,-4};
-int box_edges[24] = { 1,2, 2,3, 3,4, 4,1, 1,5, 5,6, 6,2, 7,8, 8,6, 5,7, 8,3, 7,4};
-
-int	box_faces[6] = {0,0,2,2,2,0};
-
-vec3_t	box_vecs[6][2] = {
-	{	{0,-1,0}, {-1,0,0} },
-	{ {0,1,0}, {0,0,-1} },
-	{	{0,-1,0}, {1,0,0} },
-	{ {1,0,0}, {0,0,-1} },
-	{ {0,-1,0}, {0,0,-1} },
-	{ {-1,0,0}, {0,0,-1} }
-};
-
-float	box_verts[8][3] = {
-	{-1,-1,-1},
-	{-1,1,-1},
-	{1,1,-1},
-	{1,-1,-1},
-	{-1,-1,1},
-	{-1,1,1},
-	{1,-1,1},
-	{1,1,1}
-};
-
-// down, west, up, north, east, south
-// {"rt", "bk", "lf", "ft", "up", "dn"};
-
-/*
-================
-R_InitSkyBox
-
-================
-*/
-void R_InitSkyBox (void)
-{
-	int		i;
-	extern model_t *loadmodel;
-
-	r_skyfaces = loadmodel->surfaces + loadmodel->numsurfaces;
-	loadmodel->numsurfaces += 6;
-	r_skyverts = loadmodel->vertexes + loadmodel->numvertexes;
-	loadmodel->numvertexes += 8;
-	r_skyedges = loadmodel->edges + loadmodel->numedges;
-	loadmodel->numedges += 12;
-	r_skysurfedges = loadmodel->surfedges + loadmodel->numsurfedges;
-	loadmodel->numsurfedges += 24;
-	if (loadmodel->numsurfaces > MAX_MAP_FACES
-		|| loadmodel->numvertexes > MAX_MAP_VERTS
-		|| loadmodel->numedges > MAX_MAP_EDGES)
-		ri.Sys_Error (ERR_DROP, "InitSkyBox: map overflow");
-
-	memset (r_skyfaces, 0, 6*sizeof(*r_skyfaces));
-	for (i=0 ; i<6 ; i++)
-	{
-		r_skyplanes[i].normal[skybox_planes[i*2]] = 1;
-		r_skyplanes[i].dist = skybox_planes[i*2+1];
-
-		VectorCopy (box_vecs[i][0], r_skytexinfo[i].vecs[0]);
-		VectorCopy (box_vecs[i][1], r_skytexinfo[i].vecs[1]);
-
-		r_skyfaces[i].plane = &r_skyplanes[i];
-		r_skyfaces[i].numedges = 4;
-		r_skyfaces[i].flags = box_faces[i] | SURF_DRAWSKYBOX;
-		r_skyfaces[i].firstedge = loadmodel->numsurfedges-24+i*4;
-		r_skyfaces[i].texinfo = &r_skytexinfo[i];
-		r_skyfaces[i].texturemins[0] = -128;
-		r_skyfaces[i].texturemins[1] = -128;
-		r_skyfaces[i].extents[0] = 256;
-		r_skyfaces[i].extents[1] = 256;
-	}
-
-	for (i=0 ; i<24 ; i++)
-		if (box_surfedges[i] > 0)
-			r_skysurfedges[i] = loadmodel->numedges-13 + box_surfedges[i];
-		else
-			r_skysurfedges[i] = - (loadmodel->numedges-13 + -box_surfedges[i]);
-
-	for(i=0 ; i<12 ; i++)
-	{
-		r_skyedges[i].v[0] = loadmodel->numvertexes-9+box_edges[i*2+0];
-		r_skyedges[i].v[1] = loadmodel->numvertexes-9+box_edges[i*2+1];
-		r_skyedges[i].cachededgeoffset = 0;
-	}
-}
-
-/*
-================
-R_EmitSkyBox
-================
-*/
-void R_EmitSkyBox (void)
-{
-	int		i, j;
-	int		oldkey;
-
-	if (insubmodel)
-		return;		// submodels should never have skies
-	if (r_skyframe == r_framecount)
-		return;		// already set this frame
-
-	r_skyframe = r_framecount;
-
-	// set the eight fake vertexes
-	for (i=0 ; i<8 ; i++)
-		for (j=0 ; j<3 ; j++)
-			r_skyverts[i].position[j] = r_origin[j] + box_verts[i][j]*128;
-
-	// set the six fake planes
-	for (i=0 ; i<6 ; i++)
-		if (skybox_planes[i*2+1] > 0)
-			r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]+128;
-		else
-			r_skyplanes[i].dist = r_origin[skybox_planes[i*2]]-128;
-
-	// fix texture offseets
-	for (i=0 ; i<6 ; i++)
-	{
-		r_skytexinfo[i].vecs[0][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[0]);
-		r_skytexinfo[i].vecs[1][3] = -DotProduct (r_origin, r_skytexinfo[i].vecs[1]);
-	}
-
-	// emit the six faces
-	oldkey = r_currentkey;
-	r_currentkey = 0x7ffffff0;
- 	for (i=0 ; i<6 ; i++)
-	{
-		R_RenderFace (r_skyfaces + i, 15);
-	}
-	r_currentkey = oldkey;		// bsp sorting order
-}
-
-
-#if	!id386
-
-/*
-================
-R_EmitEdge
-================
-*/
-void R_EmitEdge (mvertex_t *pv0, mvertex_t *pv1)
-{
-	edge_t	*edge, *pcheck;
-	int		u_check;
-	float	u, u_step;
-	vec3_t	local, transformed;
-	float	*world;
-	int		v, v2, ceilv0;
-	float	scale, lzi0, u0, v0;
-	int		side;
-
-	if (r_lastvertvalid)
-	{
-		u0 = r_u1;
-		v0 = r_v1;
-		lzi0 = r_lzi1;
-		ceilv0 = r_ceilv1;
-	}
-	else
-	{
-		world = &pv0->position[0];
-	
-	// transform and project
-		VectorSubtract (world, modelorg, local);
-		TransformVector (local, transformed);
-	
-		if (transformed[2] < NEAR_CLIP)
-			transformed[2] = NEAR_CLIP;
-	
-		lzi0 = 1.0 / transformed[2];
-	
-	// FIXME: build x/yscale into transform?
-		scale = xscale * lzi0;
-		u0 = (xcenter + scale*transformed[0]);
-		if (u0 < r_refdef.fvrectx_adj)
-			u0 = r_refdef.fvrectx_adj;
-		if (u0 > r_refdef.fvrectright_adj)
-			u0 = r_refdef.fvrectright_adj;
-	
-		scale = yscale * lzi0;
-		v0 = (ycenter - scale*transformed[1]);
-		if (v0 < r_refdef.fvrecty_adj)
-			v0 = r_refdef.fvrecty_adj;
-		if (v0 > r_refdef.fvrectbottom_adj)
-			v0 = r_refdef.fvrectbottom_adj;
-	
-		ceilv0 = (int) ceil(v0);
-	}
-
-	world = &pv1->position[0];
-
-// transform and project
-	VectorSubtract (world, modelorg, local);
-	TransformVector (local, transformed);
-
-	if (transformed[2] < NEAR_CLIP)
-		transformed[2] = NEAR_CLIP;
-
-	r_lzi1 = 1.0 / transformed[2];
-
-	scale = xscale * r_lzi1;
-	r_u1 = (xcenter + scale*transformed[0]);
-	if (r_u1 < r_refdef.fvrectx_adj)
-		r_u1 = r_refdef.fvrectx_adj;
-	if (r_u1 > r_refdef.fvrectright_adj)
-		r_u1 = r_refdef.fvrectright_adj;
-
-	scale = yscale * r_lzi1;
-	r_v1 = (ycenter - scale*transformed[1]);
-	if (r_v1 < r_refdef.fvrecty_adj)
-		r_v1 = r_refdef.fvrecty_adj;
-	if (r_v1 > r_refdef.fvrectbottom_adj)
-		r_v1 = r_refdef.fvrectbottom_adj;
-
-	if (r_lzi1 > lzi0)
-		lzi0 = r_lzi1;
-
-	if (lzi0 > r_nearzi)	// for mipmap finding
-		r_nearzi = lzi0;
-
-// for right edges, all we want is the effect on 1/z
-	if (r_nearzionly)
-		return;
-
-	r_emitted = 1;
-
-	r_ceilv1 = (int) ceil(r_v1);
-
-
-// create the edge
-	if (ceilv0 == r_ceilv1)
-	{
-	// we cache unclipped horizontal edges as fully clipped
-		if (cacheoffset != 0x7FFFFFFF)
-		{
-			cacheoffset = FULLY_CLIPPED_CACHED |
-					(r_framecount & FRAMECOUNT_MASK);
-		}
-
-		return;		// horizontal edge
-	}
-
-	side = ceilv0 > r_ceilv1;
-
-	edge = edge_p++;
-
-	edge->owner = r_pedge;
-
-	edge->nearzi = lzi0;
-
-	if (side == 0)
-	{
-	// trailing edge (go from p1 to p2)
-		v = ceilv0;
-		v2 = r_ceilv1 - 1;
-
-		edge->surfs[0] = surface_p - surfaces;
-		edge->surfs[1] = 0;
-
-		u_step = ((r_u1 - u0) / (r_v1 - v0));
-		u = u0 + ((float)v - v0) * u_step;
-	}
-	else
-	{
-	// leading edge (go from p2 to p1)
-		v2 = ceilv0 - 1;
-		v = r_ceilv1;
-
-		edge->surfs[0] = 0;
-		edge->surfs[1] = surface_p - surfaces;
-
-		u_step = ((u0 - r_u1) / (v0 - r_v1));
-		u = r_u1 + ((float)v - r_v1) * u_step;
-	}
-
-	edge->u_step = u_step*0x100000;
-	edge->u = u*0x100000 + 0xFFFFF;
-
-// we need to do this to avoid stepping off the edges if a very nearly
-// horizontal edge is less than epsilon above a scan, and numeric error causes
-// it to incorrectly extend to the scan, and the extension of the line goes off
-// the edge of the screen
-// FIXME: is this actually needed?
-	if (edge->u < r_refdef.vrect_x_adj_shift20)
-		edge->u = r_refdef.vrect_x_adj_shift20;
-	if (edge->u > r_refdef.vrectright_adj_shift20)
-		edge->u = r_refdef.vrectright_adj_shift20;
-
-//
-// sort the edge in normally
-//
-	u_check = edge->u;
-	if (edge->surfs[0])
-		u_check++;	// sort trailers after leaders
-
-	if (!newedges[v] || newedges[v]->u >= u_check)
-	{
-		edge->next = newedges[v];
-		newedges[v] = edge;
-	}
-	else
-	{
-		pcheck = newedges[v];
-		while (pcheck->next && pcheck->next->u < u_check)
-			pcheck = pcheck->next;
-		edge->next = pcheck->next;
-		pcheck->next = edge;
-	}
-
-	edge->nextremove = removeedges[v2];
-	removeedges[v2] = edge;
-}
-
-
-/*
-================
-R_ClipEdge
-================
-*/
-void R_ClipEdge (mvertex_t *pv0, mvertex_t *pv1, clipplane_t *clip)
-{
-	float		d0, d1, f;
-	mvertex_t	clipvert;
-
-	if (clip)
-	{
-		do
-		{
-			d0 = DotProduct (pv0->position, clip->normal) - clip->dist;
-			d1 = DotProduct (pv1->position, clip->normal) - clip->dist;
-
-			if (d0 >= 0)
-			{
-			// point 0 is unclipped
-				if (d1 >= 0)
-				{
-				// both points are unclipped
-					continue;
-				}
-
-			// only point 1 is clipped
-
-			// we don't cache clipped edges
-				cacheoffset = 0x7FFFFFFF;
-
-				f = d0 / (d0 - d1);
-				clipvert.position[0] = pv0->position[0] +
-						f * (pv1->position[0] - pv0->position[0]);
-				clipvert.position[1] = pv0->position[1] +
-						f * (pv1->position[1] - pv0->position[1]);
-				clipvert.position[2] = pv0->position[2] +
-						f * (pv1->position[2] - pv0->position[2]);
-
-				if (clip->leftedge)
-				{
-					r_leftclipped = true;
-					r_leftexit = clipvert;
-				}
-				else if (clip->rightedge)
-				{
-					r_rightclipped = true;
-					r_rightexit = clipvert;
-				}
-
-				R_ClipEdge (pv0, &clipvert, clip->next);
-				return;
-			}
-			else
-			{
-			// point 0 is clipped
-				if (d1 < 0)
-				{
-				// both points are clipped
-				// we do cache fully clipped edges
-					if (!r_leftclipped)
-						cacheoffset = FULLY_CLIPPED_CACHED |
-								(r_framecount & FRAMECOUNT_MASK);
-					return;
-				}
-
-			// only point 0 is clipped
-				r_lastvertvalid = false;
-
-			// we don't cache partially clipped edges
-				cacheoffset = 0x7FFFFFFF;
-
-				f = d0 / (d0 - d1);
-				clipvert.position[0] = pv0->position[0] +
-						f * (pv1->position[0] - pv0->position[0]);
-				clipvert.position[1] = pv0->position[1] +
-						f * (pv1->position[1] - pv0->position[1]);
-				clipvert.position[2] = pv0->position[2] +
-						f * (pv1->position[2] - pv0->position[2]);
-
-				if (clip->leftedge)
-				{
-					r_leftclipped = true;
-					r_leftenter = clipvert;
-				}
-				else if (clip->rightedge)
-				{
-					r_rightclipped = true;
-					r_rightenter = clipvert;
-				}
-
-				R_ClipEdge (&clipvert, pv1, clip->next);
-				return;
-			}
-		} while ((clip = clip->next) != NULL);
-	}
-
-// add the edge
-	R_EmitEdge (pv0, pv1);
-}
-
-#endif	// !id386
-
-
-/*
-================
-R_EmitCachedEdge
-================
-*/
-void R_EmitCachedEdge (void)
-{
-	edge_t		*pedge_t;
-
-	pedge_t = (edge_t *)((unsigned long)r_edges + r_pedge->cachededgeoffset);
-
-	if (!pedge_t->surfs[0])
-		pedge_t->surfs[0] = surface_p - surfaces;
-	else
-		pedge_t->surfs[1] = surface_p - surfaces;
-
-	if (pedge_t->nearzi > r_nearzi)	// for mipmap finding
-		r_nearzi = pedge_t->nearzi;
-
-	r_emitted = 1;
-}
-
-
-/*
-================
-R_RenderFace
-================
-*/
-void R_RenderFace (msurface_t *fa, int clipflags)
-{
-	int			i, lindex;
-	unsigned	mask;
-	mplane_t	*pplane;
-	float		distinv;
-	vec3_t		p_normal;
-	medge_t		*pedges, tedge;
-	clipplane_t	*pclip;
-
-	// translucent surfaces are not drawn by the edge renderer
-	if (fa->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
-	{
-		fa->nextalphasurface = r_alpha_surfaces;
-		r_alpha_surfaces = fa;
-		return;
-	}
-
-	// sky surfaces encountered in the world will cause the
-	// environment box surfaces to be emited
-	if ( fa->texinfo->flags & SURF_SKY )
-	{
-		R_EmitSkyBox ();	
-		return;
-	}
-
-// skip out if no more surfs
-	if ((surface_p) >= surf_max)
-	{
-		r_outofsurfaces++;
-		return;
-	}
-
-// ditto if not enough edges left, or switch to auxedges if possible
-	if ((edge_p + fa->numedges + 4) >= edge_max)
-	{
-		r_outofedges += fa->numedges;
-		return;
-	}
-
-	c_faceclip++;
-
-// set up clip planes
-	pclip = NULL;
-
-	for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
-	{
-		if (clipflags & mask)
-		{
-			view_clipplanes[i].next = pclip;
-			pclip = &view_clipplanes[i];
-		}
-	}
-
-// push the edges through
-	r_emitted = 0;
-	r_nearzi = 0;
-	r_nearzionly = false;
-	makeleftedge = makerightedge = false;
-	pedges = currentmodel->edges;
-	r_lastvertvalid = false;
-
-	for (i=0 ; i<fa->numedges ; i++)
-	{
-		lindex = currentmodel->surfedges[fa->firstedge + i];
-
-		if (lindex > 0)
-		{
-			r_pedge = &pedges[lindex];
-
-		// if the edge is cached, we can just reuse the edge
-			if (!insubmodel)
-			{
-				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
-				{
-					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
-						r_framecount)
-					{
-						r_lastvertvalid = false;
-						continue;
-					}
-				}
-				else
-				{
-					if ((((unsigned long)edge_p - (unsigned long)r_edges) >
-						 r_pedge->cachededgeoffset) &&
-						(((edge_t *)((unsigned long)r_edges +
-						 r_pedge->cachededgeoffset))->owner == r_pedge))
-					{
-						R_EmitCachedEdge ();
-						r_lastvertvalid = false;
-						continue;
-					}
-				}
-			}
-
-		// assume it's cacheable
-			cacheoffset = (byte *)edge_p - (byte *)r_edges;
-			r_leftclipped = r_rightclipped = false;
-			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[0]],
-						&r_pcurrentvertbase[r_pedge->v[1]],
-						pclip);
-			r_pedge->cachededgeoffset = cacheoffset;
-
-			if (r_leftclipped)
-				makeleftedge = true;
-			if (r_rightclipped)
-				makerightedge = true;
-			r_lastvertvalid = true;
-		}
-		else
-		{
-			lindex = -lindex;
-			r_pedge = &pedges[lindex];
-		// if the edge is cached, we can just reuse the edge
-			if (!insubmodel)
-			{
-				if (r_pedge->cachededgeoffset & FULLY_CLIPPED_CACHED)
-				{
-					if ((r_pedge->cachededgeoffset & FRAMECOUNT_MASK) ==
-						r_framecount)
-					{
-						r_lastvertvalid = false;
-						continue;
-					}
-				}
-				else
-				{
-				// it's cached if the cached edge is valid and is owned
-				// by this medge_t
-					if ((((unsigned long)edge_p - (unsigned long)r_edges) >
-						 r_pedge->cachededgeoffset) &&
-						(((edge_t *)((unsigned long)r_edges +
-						 r_pedge->cachededgeoffset))->owner == r_pedge))
-					{
-						R_EmitCachedEdge ();
-						r_lastvertvalid = false;
-						continue;
-					}
-				}
-			}
-
-		// assume it's cacheable
-			cacheoffset = (byte *)edge_p - (byte *)r_edges;
-			r_leftclipped = r_rightclipped = false;
-			R_ClipEdge (&r_pcurrentvertbase[r_pedge->v[1]],
-						&r_pcurrentvertbase[r_pedge->v[0]],
-						pclip);
-			r_pedge->cachededgeoffset = cacheoffset;
-
-			if (r_leftclipped)
-				makeleftedge = true;
-			if (r_rightclipped)
-				makerightedge = true;
-			r_lastvertvalid = true;
-		}
-	}
-
-// if there was a clip off the left edge, add that edge too
-// FIXME: faster to do in screen space?
-// FIXME: share clipped edges?
-	if (makeleftedge)
-	{
-		r_pedge = &tedge;
-		r_lastvertvalid = false;
-		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
-	}
-
-// if there was a clip off the right edge, get the right r_nearzi
-	if (makerightedge)
-	{
-		r_pedge = &tedge;
-		r_lastvertvalid = false;
-		r_nearzionly = true;
-		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
-	}
-
-// if no edges made it out, return without posting the surface
-	if (!r_emitted)
-		return;
-
-	r_polycount++;
-
-	surface_p->msurf = fa;
-	surface_p->nearzi = r_nearzi;
-	surface_p->flags = fa->flags;
-	surface_p->insubmodel = insubmodel;
-	surface_p->spanstate = 0;
-	surface_p->entity = currententity;
-	surface_p->key = r_currentkey++;
-	surface_p->spans = NULL;
-
-	pplane = fa->plane;
-// FIXME: cache this?
-	TransformVector (pplane->normal, p_normal);
-// FIXME: cache this?
-	distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
-
-	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
-	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
-	surface_p->d_ziorigin = p_normal[2] * distinv -
-			xcenter * surface_p->d_zistepu -
-			ycenter * surface_p->d_zistepv;
-
-	surface_p++;
-}
-
-
-/*
-================
-R_RenderBmodelFace
-================
-*/
-void R_RenderBmodelFace (bedge_t *pedges, msurface_t *psurf)
-{
-	int			i;
-	unsigned	mask;
-	mplane_t	*pplane;
-	float		distinv;
-	vec3_t		p_normal;
-	medge_t		tedge;
-	clipplane_t	*pclip;
-
-	if (psurf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66))
-	{
-		psurf->nextalphasurface = r_alpha_surfaces;
-		r_alpha_surfaces = psurf;
-		return;
-	}
-
-// skip out if no more surfs
-	if (surface_p >= surf_max)
-	{
-		r_outofsurfaces++;
-		return;
-	}
-
-// ditto if not enough edges left, or switch to auxedges if possible
-	if ((edge_p + psurf->numedges + 4) >= edge_max)
-	{
-		r_outofedges += psurf->numedges;
-		return;
-	}
-
-	c_faceclip++;
-
-// this is a dummy to give the caching mechanism someplace to write to
-	r_pedge = &tedge;
-
-// set up clip planes
-	pclip = NULL;
-
-	for (i=3, mask = 0x08 ; i>=0 ; i--, mask >>= 1)
-	{
-		if (r_clipflags & mask)
-		{
-			view_clipplanes[i].next = pclip;
-			pclip = &view_clipplanes[i];
-		}
-	}
-
-// push the edges through
-	r_emitted = 0;
-	r_nearzi = 0;
-	r_nearzionly = false;
-	makeleftedge = makerightedge = false;
-// FIXME: keep clipped bmodel edges in clockwise order so last vertex caching
-// can be used?
-	r_lastvertvalid = false;
-
-	for ( ; pedges ; pedges = pedges->pnext)
-	{
-		r_leftclipped = r_rightclipped = false;
-		R_ClipEdge (pedges->v[0], pedges->v[1], pclip);
-
-		if (r_leftclipped)
-			makeleftedge = true;
-		if (r_rightclipped)
-			makerightedge = true;
-	}
-
-// if there was a clip off the left edge, add that edge too
-// FIXME: faster to do in screen space?
-// FIXME: share clipped edges?
-	if (makeleftedge)
-	{
-		r_pedge = &tedge;
-		R_ClipEdge (&r_leftexit, &r_leftenter, pclip->next);
-	}
-
-// if there was a clip off the right edge, get the right r_nearzi
-	if (makerightedge)
-	{
-		r_pedge = &tedge;
-		r_nearzionly = true;
-		R_ClipEdge (&r_rightexit, &r_rightenter, view_clipplanes[1].next);
-	}
-
-// if no edges made it out, return without posting the surface
-	if (!r_emitted)
-		return;
-
-	r_polycount++;
-
-	surface_p->msurf = psurf;
-	surface_p->nearzi = r_nearzi;
-	surface_p->flags = psurf->flags;
-	surface_p->insubmodel = true;
-	surface_p->spanstate = 0;
-	surface_p->entity = currententity;
-	surface_p->key = r_currentbkey;
-	surface_p->spans = NULL;
-
-	pplane = psurf->plane;
-// FIXME: cache this?
-	TransformVector (pplane->normal, p_normal);
-// FIXME: cache this?
-	distinv = 1.0 / (pplane->dist - DotProduct (modelorg, pplane->normal));
-
-	surface_p->d_zistepu = p_normal[0] * xscaleinv * distinv;
-	surface_p->d_zistepv = -p_normal[1] * yscaleinv * distinv;
-	surface_p->d_ziorigin = p_normal[2] * distinv -
-			xcenter * surface_p->d_zistepu -
-			ycenter * surface_p->d_zistepv;
-
-	surface_p++;
-}
-
--- a/ref_soft/r_scan.c
+++ /dev/null
@@ -1,591 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// d_scan.c
-//
-// Portable C scan-level rasterization code, all pixel depths.
-
-#include "r_local.h"
-
-unsigned char	*r_turb_pbase, *r_turb_pdest;
-fixed16_t		r_turb_s, r_turb_t, r_turb_sstep, r_turb_tstep;
-int				*r_turb_turb;
-int				r_turb_spancount;
-
-void D_DrawTurbulent8Span (void);
-
-
-/*
-=============
-D_WarpScreen
-
-this performs a slight compression of the screen at the same time as
-the sine warp, to keep the edges from wrapping
-=============
-*/
-void D_WarpScreen (void)
-{
-	int		w, h;
-	int		u,v, u2, v2;
-	byte	*dest;
-	int		*turb;
-	int		*col;
-	byte	**row;
-
-	static int	cached_width, cached_height;
-	static byte	*rowptr[1200+AMP2*2];
-	static int	column[1600+AMP2*2];
-
-	//
-	// these are constant over resolutions, and can be saved
-	//
-	w = r_newrefdef.width;
-	h = r_newrefdef.height;
-	if (w != cached_width || h != cached_height)
-	{
-		cached_width = w;
-		cached_height = h;
-		for (v=0 ; v<h+AMP2*2 ; v++)
-		{
-			v2 = (int)((float)v/(h + AMP2 * 2) * r_refdef.vrect.height);
-			rowptr[v] = r_warpbuffer + (WARP_WIDTH * v2);
-		}
-
-		for (u=0 ; u<w+AMP2*2 ; u++)
-		{
-			u2 = (int)((float)u/(w + AMP2 * 2) * r_refdef.vrect.width);
-			column[u] = u2;
-		}
-	}
-
-	turb = intsintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
-	dest = vid.buffer + r_newrefdef.y * vid.rowbytes + r_newrefdef.x;
-
-	for (v=0 ; v<h ; v++, dest += vid.rowbytes)
-	{
-		col = &column[turb[v]];
-		row = &rowptr[v];
-		for (u=0 ; u<w ; u+=4)
-		{
-			dest[u+0] = row[turb[u+0]][col[u+0]];
-			dest[u+1] = row[turb[u+1]][col[u+1]];
-			dest[u+2] = row[turb[u+2]][col[u+2]];
-			dest[u+3] = row[turb[u+3]][col[u+3]];
-		}
-	}
-}
-
-
-#if	!id386
-
-/*
-=============
-D_DrawTurbulent8Span
-=============
-*/
-void D_DrawTurbulent8Span (void)
-{
-	int		sturb, tturb;
-
-	do
-	{
-		sturb = ((r_turb_s + r_turb_turb[(r_turb_t>>16)&(CYCLE-1)])>>16)&63;
-		tturb = ((r_turb_t + r_turb_turb[(r_turb_s>>16)&(CYCLE-1)])>>16)&63;
-		*r_turb_pdest++ = *(r_turb_pbase + (tturb<<6) + sturb);
-		r_turb_s += r_turb_sstep;
-		r_turb_t += r_turb_tstep;
-	} while (--r_turb_spancount > 0);
-}
-
-#endif	// !id386
-
-
-/*
-=============
-Turbulent8
-=============
-*/
-void Turbulent8 (espan_t *pspan)
-{
-	int				count;
-	fixed16_t		snext, tnext;
-	float			sdivz, tdivz, zi, z, du, dv, spancountminus1;
-	float			sdivz16stepu, tdivz16stepu, zi16stepu;
-	
-	r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
-
-	r_turb_sstep = 0;	// keep compiler happy
-	r_turb_tstep = 0;	// ditto
-
-	r_turb_pbase = (unsigned char *)cacheblock;
-
-	sdivz16stepu = d_sdivzstepu * 16;
-	tdivz16stepu = d_tdivzstepu * 16;
-	zi16stepu = d_zistepu * 16;
-
-	do
-	{
-		r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
-				(r_screenwidth * pspan->v) + pspan->u);
-
-		count = pspan->count;
-
-	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
-		du = (float)pspan->u;
-		dv = (float)pspan->v;
-
-		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
-		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
-		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
-		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-
-		r_turb_s = (int)(sdivz * z) + sadjust;
-		if (r_turb_s > bbextents)
-			r_turb_s = bbextents;
-		else if (r_turb_s < 0)
-			r_turb_s = 0;
-
-		r_turb_t = (int)(tdivz * z) + tadjust;
-		if (r_turb_t > bbextentt)
-			r_turb_t = bbextentt;
-		else if (r_turb_t < 0)
-			r_turb_t = 0;
-
-		do
-		{
-		// calculate s and t at the far end of the span
-			if (count >= 16)
-				r_turb_spancount = 16;
-			else
-				r_turb_spancount = count;
-
-			count -= r_turb_spancount;
-
-			if (count)
-			{
-			// calculate s/z, t/z, zi->fixed s and t at far end of span,
-			// calculate s and t steps across span by shifting
-				sdivz += sdivz16stepu;
-				tdivz += tdivz16stepu;
-				zi += zi16stepu;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-
-				snext = (int)(sdivz * z) + sadjust;
-				if (snext > bbextents)
-					snext = bbextents;
-				else if (snext < 16)
-					snext = 16;	// prevent round-off error on <0 steps from
-								//  from causing overstepping & running off the
-								//  edge of the texture
-
-				tnext = (int)(tdivz * z) + tadjust;
-				if (tnext > bbextentt)
-					tnext = bbextentt;
-				else if (tnext < 16)
-					tnext = 16;	// guard against round-off error on <0 steps
-
-				r_turb_sstep = (snext - r_turb_s) >> 4;
-				r_turb_tstep = (tnext - r_turb_t) >> 4;
-			}
-			else
-			{
-			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
-			// can't step off polygon), clamp, calculate s and t steps across
-			// span by division, biasing steps low so we don't run off the
-			// texture
-				spancountminus1 = (float)(r_turb_spancount - 1);
-				sdivz += d_sdivzstepu * spancountminus1;
-				tdivz += d_tdivzstepu * spancountminus1;
-				zi += d_zistepu * spancountminus1;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-				snext = (int)(sdivz * z) + sadjust;
-				if (snext > bbextents)
-					snext = bbextents;
-				else if (snext < 16)
-					snext = 16;	// prevent round-off error on <0 steps from
-								//  from causing overstepping & running off the
-								//  edge of the texture
-
-				tnext = (int)(tdivz * z) + tadjust;
-				if (tnext > bbextentt)
-					tnext = bbextentt;
-				else if (tnext < 16)
-					tnext = 16;	// guard against round-off error on <0 steps
-
-				if (r_turb_spancount > 1)
-				{
-					r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
-					r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
-				}
-			}
-
-			r_turb_s = r_turb_s & ((CYCLE<<16)-1);
-			r_turb_t = r_turb_t & ((CYCLE<<16)-1);
-
-			D_DrawTurbulent8Span ();
-
-			r_turb_s = snext;
-			r_turb_t = tnext;
-
-		} while (count > 0);
-
-	} while ((pspan = pspan->pnext) != NULL);
-}
-
-//====================
-//PGM
-/*
-=============
-NonTurbulent8 - this is for drawing scrolling textures. they're warping water textures
-	but the turbulence is automatically 0.
-=============
-*/
-void NonTurbulent8 (espan_t *pspan)
-{
-	int				count;
-	fixed16_t		snext, tnext;
-	float			sdivz, tdivz, zi, z, du, dv, spancountminus1;
-	float			sdivz16stepu, tdivz16stepu, zi16stepu;
-	
-//	r_turb_turb = sintable + ((int)(r_newrefdef.time*SPEED)&(CYCLE-1));
-	r_turb_turb = blanktable;
-
-	r_turb_sstep = 0;	// keep compiler happy
-	r_turb_tstep = 0;	// ditto
-
-	r_turb_pbase = (unsigned char *)cacheblock;
-
-	sdivz16stepu = d_sdivzstepu * 16;
-	tdivz16stepu = d_tdivzstepu * 16;
-	zi16stepu = d_zistepu * 16;
-
-	do
-	{
-		r_turb_pdest = (unsigned char *)((byte *)d_viewbuffer +
-				(r_screenwidth * pspan->v) + pspan->u);
-
-		count = pspan->count;
-
-	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
-		du = (float)pspan->u;
-		dv = (float)pspan->v;
-
-		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
-		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
-		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
-		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-
-		r_turb_s = (int)(sdivz * z) + sadjust;
-		if (r_turb_s > bbextents)
-			r_turb_s = bbextents;
-		else if (r_turb_s < 0)
-			r_turb_s = 0;
-
-		r_turb_t = (int)(tdivz * z) + tadjust;
-		if (r_turb_t > bbextentt)
-			r_turb_t = bbextentt;
-		else if (r_turb_t < 0)
-			r_turb_t = 0;
-
-		do
-		{
-		// calculate s and t at the far end of the span
-			if (count >= 16)
-				r_turb_spancount = 16;
-			else
-				r_turb_spancount = count;
-
-			count -= r_turb_spancount;
-
-			if (count)
-			{
-			// calculate s/z, t/z, zi->fixed s and t at far end of span,
-			// calculate s and t steps across span by shifting
-				sdivz += sdivz16stepu;
-				tdivz += tdivz16stepu;
-				zi += zi16stepu;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-
-				snext = (int)(sdivz * z) + sadjust;
-				if (snext > bbextents)
-					snext = bbextents;
-				else if (snext < 16)
-					snext = 16;	// prevent round-off error on <0 steps from
-								//  from causing overstepping & running off the
-								//  edge of the texture
-
-				tnext = (int)(tdivz * z) + tadjust;
-				if (tnext > bbextentt)
-					tnext = bbextentt;
-				else if (tnext < 16)
-					tnext = 16;	// guard against round-off error on <0 steps
-
-				r_turb_sstep = (snext - r_turb_s) >> 4;
-				r_turb_tstep = (tnext - r_turb_t) >> 4;
-			}
-			else
-			{
-			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
-			// can't step off polygon), clamp, calculate s and t steps across
-			// span by division, biasing steps low so we don't run off the
-			// texture
-				spancountminus1 = (float)(r_turb_spancount - 1);
-				sdivz += d_sdivzstepu * spancountminus1;
-				tdivz += d_tdivzstepu * spancountminus1;
-				zi += d_zistepu * spancountminus1;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-				snext = (int)(sdivz * z) + sadjust;
-				if (snext > bbextents)
-					snext = bbextents;
-				else if (snext < 16)
-					snext = 16;	// prevent round-off error on <0 steps from
-								//  from causing overstepping & running off the
-								//  edge of the texture
-
-				tnext = (int)(tdivz * z) + tadjust;
-				if (tnext > bbextentt)
-					tnext = bbextentt;
-				else if (tnext < 16)
-					tnext = 16;	// guard against round-off error on <0 steps
-
-				if (r_turb_spancount > 1)
-				{
-					r_turb_sstep = (snext - r_turb_s) / (r_turb_spancount - 1);
-					r_turb_tstep = (tnext - r_turb_t) / (r_turb_spancount - 1);
-				}
-			}
-
-			r_turb_s = r_turb_s & ((CYCLE<<16)-1);
-			r_turb_t = r_turb_t & ((CYCLE<<16)-1);
-
-			D_DrawTurbulent8Span ();
-
-			r_turb_s = snext;
-			r_turb_t = tnext;
-
-		} while (count > 0);
-
-	} while ((pspan = pspan->pnext) != NULL);
-}
-//PGM
-//====================
-
-
-#if	!id386
-
-/*
-=============
-D_DrawSpans16
-
-  FIXME: actually make this subdivide by 16 instead of 8!!!
-=============
-*/
-void D_DrawSpans16 (espan_t *pspan)
-{
-	int				count, spancount;
-	unsigned char	*pbase, *pdest;
-	fixed16_t		s, t, snext, tnext, sstep, tstep;
-	float			sdivz, tdivz, zi, z, du, dv, spancountminus1;
-	float			sdivz8stepu, tdivz8stepu, zi8stepu;
-
-	sstep = 0;	// keep compiler happy
-	tstep = 0;	// ditto
-
-	pbase = (unsigned char *)cacheblock;
-
-	sdivz8stepu = d_sdivzstepu * 8;
-	tdivz8stepu = d_tdivzstepu * 8;
-	zi8stepu = d_zistepu * 8;
-
-	do
-	{
-		pdest = (unsigned char *)((byte *)d_viewbuffer +
-				(r_screenwidth * pspan->v) + pspan->u);
-
-		count = pspan->count;
-
-	// calculate the initial s/z, t/z, 1/z, s, and t and clamp
-		du = (float)pspan->u;
-		dv = (float)pspan->v;
-
-		sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu;
-		tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu;
-		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
-		z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-
-		s = (int)(sdivz * z) + sadjust;
-		if (s > bbextents)
-			s = bbextents;
-		else if (s < 0)
-			s = 0;
-
-		t = (int)(tdivz * z) + tadjust;
-		if (t > bbextentt)
-			t = bbextentt;
-		else if (t < 0)
-			t = 0;
-
-		do
-		{
-		// calculate s and t at the far end of the span
-			if (count >= 8)
-				spancount = 8;
-			else
-				spancount = count;
-
-			count -= spancount;
-
-			if (count)
-			{
-			// calculate s/z, t/z, zi->fixed s and t at far end of span,
-			// calculate s and t steps across span by shifting
-				sdivz += sdivz8stepu;
-				tdivz += tdivz8stepu;
-				zi += zi8stepu;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-
-				snext = (int)(sdivz * z) + sadjust;
-				if (snext > bbextents)
-					snext = bbextents;
-				else if (snext < 8)
-					snext = 8;	// prevent round-off error on <0 steps from
-								//  from causing overstepping & running off the
-								//  edge of the texture
-
-				tnext = (int)(tdivz * z) + tadjust;
-				if (tnext > bbextentt)
-					tnext = bbextentt;
-				else if (tnext < 8)
-					tnext = 8;	// guard against round-off error on <0 steps
-
-				sstep = (snext - s) >> 3;
-				tstep = (tnext - t) >> 3;
-			}
-			else
-			{
-			// calculate s/z, t/z, zi->fixed s and t at last pixel in span (so
-			// can't step off polygon), clamp, calculate s and t steps across
-			// span by division, biasing steps low so we don't run off the
-			// texture
-				spancountminus1 = (float)(spancount - 1);
-				sdivz += d_sdivzstepu * spancountminus1;
-				tdivz += d_tdivzstepu * spancountminus1;
-				zi += d_zistepu * spancountminus1;
-				z = (float)0x10000 / zi;	// prescale to 16.16 fixed-point
-				snext = (int)(sdivz * z) + sadjust;
-				if (snext > bbextents)
-					snext = bbextents;
-				else if (snext < 8)
-					snext = 8;	// prevent round-off error on <0 steps from
-								//  from causing overstepping & running off the
-								//  edge of the texture
-
-				tnext = (int)(tdivz * z) + tadjust;
-				if (tnext > bbextentt)
-					tnext = bbextentt;
-				else if (tnext < 8)
-					tnext = 8;	// guard against round-off error on <0 steps
-
-				if (spancount > 1)
-				{
-					sstep = (snext - s) / (spancount - 1);
-					tstep = (tnext - t) / (spancount - 1);
-				}
-			}
-
-			do
-			{
-				*pdest++ = *(pbase + (s >> 16) + (t >> 16) * cachewidth);
-				s += sstep;
-				t += tstep;
-			} while (--spancount > 0);
-
-			s = snext;
-			t = tnext;
-
-		} while (count > 0);
-
-	} while ((pspan = pspan->pnext) != NULL);
-}
-
-#endif
-
-
-#if	!id386
-
-/*
-=============
-D_DrawZSpans
-=============
-*/
-void D_DrawZSpans (espan_t *pspan)
-{
-	int				count, doublecount, izistep;
-	int				izi;
-	short			*pdest;
-	unsigned		ltemp;
-	float			zi;
-	float			du, dv;
-
-// FIXME: check for clamping/range problems
-// we count on FP exceptions being turned off to avoid range problems
-	izistep = (int)(d_zistepu * 0x8000 * 0x10000);
-
-	do
-	{
-		pdest = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u;
-
-		count = pspan->count;
-
-	// calculate the initial 1/z
-		du = (float)pspan->u;
-		dv = (float)pspan->v;
-
-		zi = d_ziorigin + dv*d_zistepv + du*d_zistepu;
-	// we count on FP exceptions being turned off to avoid range problems
-		izi = (int)(zi * 0x8000 * 0x10000);
-
-		if ((long)pdest & 0x02)
-		{
-			*pdest++ = (short)(izi >> 16);
-			izi += izistep;
-			count--;
-		}
-
-		if ((doublecount = count >> 1) > 0)
-		{
-			do
-			{
-				ltemp = izi >> 16;
-				izi += izistep;
-				ltemp |= izi & 0xFFFF0000;
-				izi += izistep;
-				*(int *)pdest = ltemp;
-				pdest += 2;
-			} while (--doublecount > 0);
-		}
-
-		if (count & 1)
-			*pdest = (short)(izi >> 16);
-
-	} while ((pspan = pspan->pnext) != NULL);
-}
-
-#endif
-
--- a/ref_soft/r_sprite.c
+++ /dev/null
@@ -1,123 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_sprite.c
-#include "r_local.h"
-
-extern polydesc_t r_polydesc;
-
-void R_BuildPolygonFromSurface(msurface_t *fa);
-void R_PolygonCalculateGradients (void);
-
-extern void R_PolyChooseSpanletRoutine( float alpha, qboolean isturbulent );
-
-extern vec5_t r_clip_verts[2][MAXWORKINGVERTS+2];
-
-extern void	R_ClipAndDrawPoly( float alpha, qboolean isturbulent, qboolean textured );
-
-/*
-** R_DrawSprite
-**
-** Draw currententity / currentmodel as a single texture
-** mapped polygon
-*/
-void R_DrawSprite (void)
-{
-	vec5_t		*pverts;
-	vec3_t		left, up, right, down;
-	dsprite_t	*s_psprite;
-	dsprframe_t	*s_psprframe;
-
-
-	s_psprite = (dsprite_t *)currentmodel->extradata;
-#if 0
-	if (currententity->frame >= s_psprite->numframes
-		|| currententity->frame < 0)
-	{
-		ri.Con_Printf (PRINT_ALL, "No such sprite frame %i\n", 
-			currententity->frame);
-		currententity->frame = 0;
-	}
-#endif
-	currententity->frame %= s_psprite->numframes;
-
-	s_psprframe = &s_psprite->frames[currententity->frame];
-
-	r_polydesc.pixels       = currentmodel->skins[currententity->frame]->pixels[0];
-	r_polydesc.pixel_width  = s_psprframe->width;
-	r_polydesc.pixel_height = s_psprframe->height;
-	r_polydesc.dist         = 0;
-
-	// generate the sprite's axes, completely parallel to the viewplane.
-	VectorCopy (vup, r_polydesc.vup);
-	VectorCopy (vright, r_polydesc.vright);
-	VectorCopy (vpn, r_polydesc.vpn);
-
-// build the sprite poster in worldspace
-	VectorScale (r_polydesc.vright, 
-		s_psprframe->width - s_psprframe->origin_x, right);
-	VectorScale (r_polydesc.vup, 
-		s_psprframe->height - s_psprframe->origin_y, up);
-	VectorScale (r_polydesc.vright,
-		-s_psprframe->origin_x, left);
-	VectorScale (r_polydesc.vup,
-		-s_psprframe->origin_y, down);
-
-	// invert UP vector for sprites
-	VectorInverse( r_polydesc.vup );
-
-	pverts = r_clip_verts[0];
-
-	pverts[0][0] = r_entorigin[0] + up[0] + left[0];
-	pverts[0][1] = r_entorigin[1] + up[1] + left[1];
-	pverts[0][2] = r_entorigin[2] + up[2] + left[2];
-	pverts[0][3] = 0;
-	pverts[0][4] = 0;
-
-	pverts[1][0] = r_entorigin[0] + up[0] + right[0];
-	pverts[1][1] = r_entorigin[1] + up[1] + right[1];
-	pverts[1][2] = r_entorigin[2] + up[2] + right[2];
-	pverts[1][3] = s_psprframe->width;
-	pverts[1][4] = 0;
-
-	pverts[2][0] = r_entorigin[0] + down[0] + right[0];
-	pverts[2][1] = r_entorigin[1] + down[1] + right[1];
-	pverts[2][2] = r_entorigin[2] + down[2] + right[2];
-	pverts[2][3] = s_psprframe->width;
-	pverts[2][4] = s_psprframe->height;
-
-	pverts[3][0] = r_entorigin[0] + down[0] + left[0];
-	pverts[3][1] = r_entorigin[1] + down[1] + left[1];
-	pverts[3][2] = r_entorigin[2] + down[2] + left[2];
-	pverts[3][3] = 0;
-	pverts[3][4] = s_psprframe->height;
-
-	r_polydesc.nump = 4;
-	r_polydesc.s_offset = ( r_polydesc.pixel_width  >> 1);
-	r_polydesc.t_offset = ( r_polydesc.pixel_height >> 1);
-	VectorCopy( modelorg, r_polydesc.viewer_position );
-
-	r_polydesc.stipple_parity = 1;
-	if ( currententity->flags & RF_TRANSLUCENT )
-		R_ClipAndDrawPoly ( currententity->alpha, false, true );
-	else
-		R_ClipAndDrawPoly ( 1.0F, false, true );
-	r_polydesc.stipple_parity = 0;
-}
-
--- a/ref_soft/r_surf.c
+++ /dev/null
@@ -1,651 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// r_surf.c: surface-related refresh code
-
-#include "r_local.h"
-
-drawsurf_t	r_drawsurf;
-
-int				lightleft, sourcesstep, blocksize, sourcetstep;
-int				lightdelta, lightdeltastep;
-int				lightright, lightleftstep, lightrightstep, blockdivshift;
-unsigned		blockdivmask;
-void			*prowdestbase;
-unsigned char	*pbasesource;
-int				surfrowbytes;	// used by ASM files
-unsigned		*r_lightptr;
-int				r_stepback;
-int				r_lightwidth;
-int				r_numhblocks, r_numvblocks;
-unsigned char	*r_source, *r_sourcemax;
-
-void R_DrawSurfaceBlock8_mip0 (void);
-void R_DrawSurfaceBlock8_mip1 (void);
-void R_DrawSurfaceBlock8_mip2 (void);
-void R_DrawSurfaceBlock8_mip3 (void);
-
-static void	(*surfmiptable[4])(void) = {
-	R_DrawSurfaceBlock8_mip0,
-	R_DrawSurfaceBlock8_mip1,
-	R_DrawSurfaceBlock8_mip2,
-	R_DrawSurfaceBlock8_mip3
-};
-
-void R_BuildLightMap (void);
-extern	unsigned		blocklights[1024];	// allow some very large lightmaps
-
-float           surfscale;
-qboolean        r_cache_thrash;         // set if surface cache is thrashing
-
-int         sc_size;
-surfcache_t	*sc_rover, *sc_base;
-
-/*
-===============
-R_TextureAnimation
-
-Returns the proper texture for a given time and base texture
-===============
-*/
-image_t *R_TextureAnimation (mtexinfo_t *tex)
-{
-	int		c;
-
-	if (!tex->next)
-		return tex->image;
-
-	c = currententity->frame % tex->numframes;
-	while (c)
-	{
-		tex = tex->next;
-		c--;
-	}
-
-	return tex->image;
-}
-
-
-/*
-===============
-R_DrawSurface
-===============
-*/
-void R_DrawSurface (void)
-{
-	unsigned char	*basetptr;
-	int				smax, tmax, twidth;
-	int				u;
-	int				soffset, basetoffset, texwidth;
-	int				horzblockstep;
-	unsigned char	*pcolumndest;
-	void			(*pblockdrawer)(void);
-	image_t			*mt;
-
-	surfrowbytes = r_drawsurf.rowbytes;
-
-	mt = r_drawsurf.image;
-	
-	r_source = mt->pixels[r_drawsurf.surfmip];
-	
-// the fractional light values should range from 0 to (VID_GRADES - 1) << 16
-// from a source range of 0 - 255
-	
-	texwidth = mt->width >> r_drawsurf.surfmip;
-
-	blocksize = 16 >> r_drawsurf.surfmip;
-	blockdivshift = 4 - r_drawsurf.surfmip;
-	blockdivmask = (1 << blockdivshift) - 1;
-	
-	r_lightwidth = (r_drawsurf.surf->extents[0]>>4)+1;
-
-	r_numhblocks = r_drawsurf.surfwidth >> blockdivshift;
-	r_numvblocks = r_drawsurf.surfheight >> blockdivshift;
-
-//==============================
-
-	pblockdrawer = surfmiptable[r_drawsurf.surfmip];
-// TODO: only needs to be set when there is a display settings change
-	horzblockstep = blocksize;
-
-	smax = mt->width >> r_drawsurf.surfmip;
-	twidth = texwidth;
-	tmax = mt->height >> r_drawsurf.surfmip;
-	sourcetstep = texwidth;
-	r_stepback = tmax * twidth;
-
-	r_sourcemax = r_source + (tmax * smax);
-
-	soffset = r_drawsurf.surf->texturemins[0];
-	basetoffset = r_drawsurf.surf->texturemins[1];
-
-// << 16 components are to guarantee positive values for %
-	soffset = ((soffset >> r_drawsurf.surfmip) + (smax << 16)) % smax;
-	basetptr = &r_source[((((basetoffset >> r_drawsurf.surfmip) 
-		+ (tmax << 16)) % tmax) * twidth)];
-
-	pcolumndest = r_drawsurf.surfdat;
-
-	for (u=0 ; u<r_numhblocks; u++)
-	{
-		r_lightptr = blocklights + u;
-
-		prowdestbase = pcolumndest;
-
-		pbasesource = basetptr + soffset;
-
-		(*pblockdrawer)();
-
-		soffset = soffset + blocksize;
-		if (soffset >= smax)
-			soffset = 0;
-
-		pcolumndest += horzblockstep;
-	}
-}
-
-
-//=============================================================================
-
-#if	!id386
-
-/*
-================
-R_DrawSurfaceBlock8_mip0
-================
-*/
-void R_DrawSurfaceBlock8_mip0 (void)
-{
-	int				v, i, b, lightstep, lighttemp, light;
-	unsigned char	pix, *psource, *prowdest;
-
-	psource = pbasesource;
-	prowdest = prowdestbase;
-
-	for (v=0 ; v<r_numvblocks ; v++)
-	{
-	// FIXME: make these locals?
-	// FIXME: use delta rather than both right and left, like ASM?
-		lightleft = r_lightptr[0];
-		lightright = r_lightptr[1];
-		r_lightptr += r_lightwidth;
-		lightleftstep = (r_lightptr[0] - lightleft) >> 4;
-		lightrightstep = (r_lightptr[1] - lightright) >> 4;
-
-		for (i=0 ; i<16 ; i++)
-		{
-			lighttemp = lightleft - lightright;
-			lightstep = lighttemp >> 4;
-
-			light = lightright;
-
-			for (b=15; b>=0; b--)
-			{
-				pix = psource[b];
-				prowdest[b] = ((unsigned char *)vid.colormap)
-						[(light & 0xFF00) + pix];
-				light += lightstep;
-			}
-	
-			psource += sourcetstep;
-			lightright += lightrightstep;
-			lightleft += lightleftstep;
-			prowdest += surfrowbytes;
-		}
-
-		if (psource >= r_sourcemax)
-			psource -= r_stepback;
-	}
-}
-
-
-/*
-================
-R_DrawSurfaceBlock8_mip1
-================
-*/
-void R_DrawSurfaceBlock8_mip1 (void)
-{
-	int				v, i, b, lightstep, lighttemp, light;
-	unsigned char	pix, *psource, *prowdest;
-
-	psource = pbasesource;
-	prowdest = prowdestbase;
-
-	for (v=0 ; v<r_numvblocks ; v++)
-	{
-	// FIXME: make these locals?
-	// FIXME: use delta rather than both right and left, like ASM?
-		lightleft = r_lightptr[0];
-		lightright = r_lightptr[1];
-		r_lightptr += r_lightwidth;
-		lightleftstep = (r_lightptr[0] - lightleft) >> 3;
-		lightrightstep = (r_lightptr[1] - lightright) >> 3;
-
-		for (i=0 ; i<8 ; i++)
-		{
-			lighttemp = lightleft - lightright;
-			lightstep = lighttemp >> 3;
-
-			light = lightright;
-
-			for (b=7; b>=0; b--)
-			{
-				pix = psource[b];
-				prowdest[b] = ((unsigned char *)vid.colormap)
-						[(light & 0xFF00) + pix];
-				light += lightstep;
-			}
-	
-			psource += sourcetstep;
-			lightright += lightrightstep;
-			lightleft += lightleftstep;
-			prowdest += surfrowbytes;
-		}
-
-		if (psource >= r_sourcemax)
-			psource -= r_stepback;
-	}
-}
-
-
-/*
-================
-R_DrawSurfaceBlock8_mip2
-================
-*/
-void R_DrawSurfaceBlock8_mip2 (void)
-{
-	int				v, i, b, lightstep, lighttemp, light;
-	unsigned char	pix, *psource, *prowdest;
-
-	psource = pbasesource;
-	prowdest = prowdestbase;
-
-	for (v=0 ; v<r_numvblocks ; v++)
-	{
-	// FIXME: make these locals?
-	// FIXME: use delta rather than both right and left, like ASM?
-		lightleft = r_lightptr[0];
-		lightright = r_lightptr[1];
-		r_lightptr += r_lightwidth;
-		lightleftstep = (r_lightptr[0] - lightleft) >> 2;
-		lightrightstep = (r_lightptr[1] - lightright) >> 2;
-
-		for (i=0 ; i<4 ; i++)
-		{
-			lighttemp = lightleft - lightright;
-			lightstep = lighttemp >> 2;
-
-			light = lightright;
-
-			for (b=3; b>=0; b--)
-			{
-				pix = psource[b];
-				prowdest[b] = ((unsigned char *)vid.colormap)
-						[(light & 0xFF00) + pix];
-				light += lightstep;
-			}
-	
-			psource += sourcetstep;
-			lightright += lightrightstep;
-			lightleft += lightleftstep;
-			prowdest += surfrowbytes;
-		}
-
-		if (psource >= r_sourcemax)
-			psource -= r_stepback;
-	}
-}
-
-
-/*
-================
-R_DrawSurfaceBlock8_mip3
-================
-*/
-void R_DrawSurfaceBlock8_mip3 (void)
-{
-	int				v, i, b, lightstep, lighttemp, light;
-	unsigned char	pix, *psource, *prowdest;
-
-	psource = pbasesource;
-	prowdest = prowdestbase;
-
-	for (v=0 ; v<r_numvblocks ; v++)
-	{
-	// FIXME: make these locals?
-	// FIXME: use delta rather than both right and left, like ASM?
-		lightleft = r_lightptr[0];
-		lightright = r_lightptr[1];
-		r_lightptr += r_lightwidth;
-		lightleftstep = (r_lightptr[0] - lightleft) >> 1;
-		lightrightstep = (r_lightptr[1] - lightright) >> 1;
-
-		for (i=0 ; i<2 ; i++)
-		{
-			lighttemp = lightleft - lightright;
-			lightstep = lighttemp >> 1;
-
-			light = lightright;
-
-			for (b=1; b>=0; b--)
-			{
-				pix = psource[b];
-				prowdest[b] = ((unsigned char *)vid.colormap)
-						[(light & 0xFF00) + pix];
-				light += lightstep;
-			}
-	
-			psource += sourcetstep;
-			lightright += lightrightstep;
-			lightleft += lightleftstep;
-			prowdest += surfrowbytes;
-		}
-
-		if (psource >= r_sourcemax)
-			psource -= r_stepback;
-	}
-}
-
-#endif
-
-
-//============================================================================
-
-
-/*
-================
-R_InitCaches
-
-================
-*/
-void R_InitCaches (void)
-{
-	int		size;
-	int		pix;
-
-	// calculate size to allocate
-	if (sw_surfcacheoverride->value)
-	{
-		size = sw_surfcacheoverride->value;
-	}
-	else
-	{
-		size = SURFCACHE_SIZE_AT_320X240;
-
-		pix = vid.width*vid.height;
-		if (pix > 64000)
-			size += (pix-64000)*3;
-	}		
-
-	// round up to page size
-	size = (size + 8191) & ~8191;
-
-	ri.Con_Printf (PRINT_ALL,"%ik surface cache\n", size/1024);
-
-	sc_size = size;
-	sc_base = (surfcache_t *)malloc(size);
-	sc_rover = sc_base;
-	
-	sc_base->next = NULL;
-	sc_base->owner = NULL;
-	sc_base->size = sc_size;
-}
-
-
-/*
-==================
-D_FlushCaches
-==================
-*/
-void D_FlushCaches (void)
-{
-	surfcache_t     *c;
-	
-	if (!sc_base)
-		return;
-
-	for (c = sc_base ; c ; c = c->next)
-	{
-		if (c->owner)
-			*c->owner = NULL;
-	}
-	
-	sc_rover = sc_base;
-	sc_base->next = NULL;
-	sc_base->owner = NULL;
-	sc_base->size = sc_size;
-}
-
-/*
-=================
-D_SCAlloc
-=================
-*/
-surfcache_t     *D_SCAlloc (int width, int size)
-{
-	surfcache_t             *new;
-	qboolean                wrapped_this_time;
-
-	if ((width < 0) || (width > 256))
-		ri.Sys_Error (ERR_FATAL,"D_SCAlloc: bad cache width %d\n", width);
-
-	if ((size <= 0) || (size > 0x10000))
-		ri.Sys_Error (ERR_FATAL,"D_SCAlloc: bad cache size %d\n", size);
-	
-	size = (int)&((surfcache_t *)0)->data[size];
-	size = (size + 3) & ~3;
-	if (size > sc_size)
-		ri.Sys_Error (ERR_FATAL,"D_SCAlloc: %i > cache size of %i",size, sc_size);
-
-// if there is not size bytes after the rover, reset to the start
-	wrapped_this_time = false;
-
-	if ( !sc_rover || (byte *)sc_rover - (byte *)sc_base > sc_size - size)
-	{
-		if (sc_rover)
-		{
-			wrapped_this_time = true;
-		}
-		sc_rover = sc_base;
-	}
-		
-// colect and free surfcache_t blocks until the rover block is large enough
-	new = sc_rover;
-	if (sc_rover->owner)
-		*sc_rover->owner = NULL;
-	
-	while (new->size < size)
-	{
-	// free another
-		sc_rover = sc_rover->next;
-		if (!sc_rover)
-			ri.Sys_Error (ERR_FATAL,"D_SCAlloc: hit the end of memory");
-		if (sc_rover->owner)
-			*sc_rover->owner = NULL;
-			
-		new->size += sc_rover->size;
-		new->next = sc_rover->next;
-	}
-
-// create a fragment out of any leftovers
-	if (new->size - size > 256)
-	{
-		sc_rover = (surfcache_t *)( (byte *)new + size);
-		sc_rover->size = new->size - size;
-		sc_rover->next = new->next;
-		sc_rover->width = 0;
-		sc_rover->owner = NULL;
-		new->next = sc_rover;
-		new->size = size;
-	}
-	else
-		sc_rover = new->next;
-	
-	new->width = width;
-// DEBUG
-	if (width > 0)
-		new->height = (size - sizeof(*new) + sizeof(new->data)) / width;
-
-	new->owner = NULL;              // should be set properly after return
-
-	if (d_roverwrapped)
-	{
-		if (wrapped_this_time || (sc_rover >= d_initial_rover))
-			r_cache_thrash = true;
-	}
-	else if (wrapped_this_time)
-	{       
-		d_roverwrapped = true;
-	}
-
-	return new;
-}
-
-
-/*
-=================
-D_SCDump
-=================
-*/
-void D_SCDump (void)
-{
-	surfcache_t             *test;
-
-	for (test = sc_base ; test ; test = test->next)
-	{
-		if (test == sc_rover)
-			ri.Con_Printf (PRINT_ALL,"ROVER:\n");
-		ri.Con_Printf (PRINT_ALL,"%p : %i bytes     %i width\n",test, test->size, test->width);
-	}
-}
-
-//=============================================================================
-
-// if the num is not a power of 2, assume it will not repeat
-
-int     MaskForNum (int num)
-{
-	if (num==128)
-		return 127;
-	if (num==64)
-		return 63;
-	if (num==32)
-		return 31;
-	if (num==16)
-		return 15;
-	return 255;
-}
-
-int D_log2 (int num)
-{
-	int     c;
-	
-	c = 0;
-	
-	while (num>>=1)
-		c++;
-	return c;
-}
-
-//=============================================================================
-
-/*
-================
-D_CacheSurface
-================
-*/
-surfcache_t *D_CacheSurface (msurface_t *surface, int miplevel)
-{
-	surfcache_t     *cache;
-
-//
-// if the surface is animating or flashing, flush the cache
-//
-	r_drawsurf.image = R_TextureAnimation (surface->texinfo);
-	r_drawsurf.lightadj[0] = r_newrefdef.lightstyles[surface->styles[0]].white*128;
-	r_drawsurf.lightadj[1] = r_newrefdef.lightstyles[surface->styles[1]].white*128;
-	r_drawsurf.lightadj[2] = r_newrefdef.lightstyles[surface->styles[2]].white*128;
-	r_drawsurf.lightadj[3] = r_newrefdef.lightstyles[surface->styles[3]].white*128;
-	
-//
-// see if the cache holds apropriate data
-//
-	cache = surface->cachespots[miplevel];
-
-	if (cache && !cache->dlight && surface->dlightframe != r_framecount
-			&& cache->image == r_drawsurf.image
-			&& cache->lightadj[0] == r_drawsurf.lightadj[0]
-			&& cache->lightadj[1] == r_drawsurf.lightadj[1]
-			&& cache->lightadj[2] == r_drawsurf.lightadj[2]
-			&& cache->lightadj[3] == r_drawsurf.lightadj[3] )
-		return cache;
-
-//
-// determine shape of surface
-//
-	surfscale = 1.0 / (1<<miplevel);
-	r_drawsurf.surfmip = miplevel;
-	r_drawsurf.surfwidth = surface->extents[0] >> miplevel;
-	r_drawsurf.rowbytes = r_drawsurf.surfwidth;
-	r_drawsurf.surfheight = surface->extents[1] >> miplevel;
-	
-//
-// allocate memory if needed
-//
-	if (!cache)     // if a texture just animated, don't reallocate it
-	{
-		cache = D_SCAlloc (r_drawsurf.surfwidth,
-						   r_drawsurf.surfwidth * r_drawsurf.surfheight);
-		surface->cachespots[miplevel] = cache;
-		cache->owner = &surface->cachespots[miplevel];
-		cache->mipscale = surfscale;
-	}
-	
-	if (surface->dlightframe == r_framecount)
-		cache->dlight = 1;
-	else
-		cache->dlight = 0;
-
-	r_drawsurf.surfdat = (pixel_t *)cache->data;
-	
-	cache->image = r_drawsurf.image;
-	cache->lightadj[0] = r_drawsurf.lightadj[0];
-	cache->lightadj[1] = r_drawsurf.lightadj[1];
-	cache->lightadj[2] = r_drawsurf.lightadj[2];
-	cache->lightadj[3] = r_drawsurf.lightadj[3];
-
-//
-// draw and light the surface texture
-//
-	r_drawsurf.surf = surface;
-
-	c_surf++;
-
-	// calculate the lightings
-	R_BuildLightMap ();
-	
-	// rasterize the surface into the cache
-	R_DrawSurface ();
-
-	return cache;
-}
-
-
--- a/ref_soft/rand1k.h
+++ /dev/null
@@ -1,123 +1,0 @@
-/*
-Copyright (C) 1997-2001 Id Software, Inc.
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-
-*/
-// 1K random numbers in the range 0-255
-0, 144, 49, 207, 149, 122, 89, 229, 210, 191,
-44, 219, 181, 131, 77, 3, 23, 93, 37, 42,
-253, 114, 30, 1, 2, 96, 136, 146, 154, 155,
-42, 169, 115, 90, 14, 155, 200, 205, 133, 77,
-224, 186, 244, 236, 138, 36, 118, 60, 220, 53,
-199, 215, 255, 255, 156, 100, 68, 76, 215, 6,
-96, 23, 173, 14, 2, 235, 70, 69, 150, 176,
-214, 185, 124, 52, 190, 119, 117, 242, 190, 27,
-153, 98, 188, 155, 146, 92, 38, 57, 108, 205,
-132, 253, 192, 88, 43, 168, 125, 16, 179, 129,
-37, 243, 36, 231, 177, 77, 109, 18, 247, 174,
-39, 224, 210, 149, 48, 45, 209, 121, 39, 129,
-187, 103, 71, 145, 174, 193, 184, 121, 31, 94,
-213, 8, 132, 169, 109, 26, 243, 235, 140, 88,
-120, 95, 216, 81, 116, 69, 251, 76, 189, 145,
-50, 194, 214, 101, 128, 227, 7, 254, 146, 12,
-136, 49, 215, 160, 168, 50, 215, 31, 28, 190,
-80, 240, 73, 86, 35, 187, 213, 181, 153, 191,
-64, 36, 0, 15, 206, 218, 53, 29, 141, 3,
-29, 116, 192, 175, 139, 18, 111, 51, 178, 74,
-111, 59, 147, 136, 160, 41, 129, 246, 178, 236,
-48, 86, 45, 254, 117, 255, 24, 160, 24, 112,
-238, 12, 229, 74, 58, 196, 105, 51, 160, 154,
-115, 119, 153, 162, 218, 212, 159, 184, 144, 96,
-47, 188, 142, 231, 62, 48, 154, 178, 149, 89,
-126, 20, 189, 156, 158, 176, 205, 38, 147, 222,
-233, 157, 186, 11, 170, 249, 80, 145, 78, 44,
-27, 222, 217, 190, 39, 83, 20, 19, 164, 209,
-139, 114, 104, 76, 119, 128, 39, 82, 188, 80,
-211, 245, 223, 185, 76, 241, 32, 16, 200, 134,
-156, 244, 18, 224, 167, 82, 26, 129, 58, 74,
-235, 141, 169, 29, 126, 97, 127, 203, 130, 97,
-176, 136, 155, 101, 1, 181, 25, 159, 220, 125,
-191, 127, 97, 201, 141, 91, 244, 161, 45, 95,
-33, 190, 243, 156, 7, 84, 14, 163, 33, 216,
-221, 152, 184, 218, 3, 32, 181, 157, 55, 16,
-43, 159, 87, 81, 94, 169, 205, 206, 134, 156,
-204, 230, 37, 161, 103, 64, 34, 218, 16, 109,
-146, 77, 140, 57, 79, 28, 206, 34, 72, 201,
-229, 202, 190, 157, 92, 219, 58, 221, 58, 63,
-138, 252, 13, 20, 134, 109, 24, 66, 228, 59,
-37, 32, 238, 20, 12, 15, 86, 234, 102, 110,
-242, 214, 136, 215, 177, 101, 66, 1, 134, 244,
-102, 61, 149, 65, 175, 241, 111, 227, 1, 240,
-153, 201, 147, 36, 56, 98, 1, 106, 21, 168,
-218, 16, 207, 169, 177, 205, 135, 175, 36, 176,
-186, 199, 7, 222, 164, 180, 21, 141, 242, 15,
-70, 37, 251, 158, 74, 236, 94, 177, 55, 39,
-61, 133, 230, 27, 231, 113, 20, 200, 43, 249,
-198, 222, 53, 116, 0, 192, 29, 103, 79, 254,
-9, 64, 48, 63, 39, 158, 226, 240, 50, 199,
-165, 168, 232, 116, 235, 170, 38, 162, 145, 108,
-241, 138, 148, 137, 65, 101, 89, 9, 203, 50,
-17, 99, 151, 18, 50, 39, 164, 116, 154, 178,
-112, 175, 101, 213, 151, 51, 243, 224, 100, 252,
-47, 229, 147, 113, 160, 181, 12, 73, 66, 104,
-229, 181, 186, 229, 100, 101, 231, 79, 99, 146,
-90, 187, 190, 188, 189, 35, 51, 69, 174, 233,
-94, 132, 28, 232, 51, 132, 167, 112, 176, 23,
-20, 19, 7, 90, 78, 178, 36, 101, 17, 172,
-185, 50, 177, 157, 167, 139, 25, 139, 12, 249,
-118, 248, 186, 135, 174, 177, 95, 99, 12, 207,
-43, 15, 79, 200, 54, 82, 124, 2, 112, 130,
-155, 194, 102, 89, 215, 241, 159, 255, 13, 144,
-221, 99, 78, 72, 6, 156, 100, 4, 7, 116,
-219, 239, 102, 186, 156, 206, 224, 149, 152, 20,
-203, 118, 151, 150, 145, 208, 172, 87, 2, 68,
-87, 59, 197, 95, 222, 29, 185, 161, 228, 46,
-137, 230, 199, 247, 50, 230, 204, 244, 217, 227,
-160, 47, 157, 67, 64, 187, 201, 43, 182, 123,
-20, 206, 218, 31, 78, 146, 121, 195, 49, 186,
-254, 3, 165, 177, 44, 18, 70, 173, 214, 142,
-95, 199, 59, 163, 59, 52, 248, 72, 5, 196,
-38, 12, 2, 89, 164, 87, 106, 106, 23, 139,
-179, 86, 168, 224, 137, 145, 13, 119, 66, 109,
-221, 124, 22, 144, 181, 199, 221, 217, 75, 221,
-165, 191, 212, 195, 223, 232, 233, 133, 112, 27,
-90, 210, 109, 43, 0, 168, 198, 16, 22, 98,
-175, 206, 39, 36, 12, 88, 4, 250, 165, 13,
-234, 163, 110, 5, 62, 100, 167, 200, 5, 211,
-35, 162, 140, 251, 118, 54, 76, 200, 87, 123,
-155, 26, 252, 193, 38, 116, 182, 255, 198, 164,
-159, 242, 176, 74, 145, 74, 140, 182, 63, 139,
-126, 243, 171, 195, 159, 114, 204, 190, 253, 52,
-161, 232, 151, 235, 129, 125, 115, 227, 240, 46,
-64, 51, 187, 240, 160, 10, 164, 8, 142, 139,
-114, 15, 254, 32, 153, 12, 44, 169, 85, 80,
-167, 105, 109, 56, 173, 42, 127, 129, 205, 111,
-1, 86, 96, 32, 211, 187, 228, 164, 166, 131,
-187, 188, 245, 119, 92, 28, 231, 210, 116, 27,
-222, 194, 10, 106, 239, 17, 42, 54, 29, 151,
-30, 158, 148, 176, 187, 234, 171, 76, 207, 96,
-255, 197, 52, 43, 99, 46, 148, 50, 245, 48,
-97, 77, 30, 50, 11, 197, 194, 225, 0, 114,
-109, 205, 118, 126, 191, 61, 143, 23, 236, 228,
-219, 15, 125, 161, 191, 193, 65, 232, 202, 51,
-141, 13, 133, 202, 180, 6, 187, 141, 234, 224,
-204, 78, 101, 123, 13, 166, 0, 196, 193, 56,
-39, 14, 171, 8, 88, 178, 204, 111, 251, 162,
-75, 122, 223, 20, 25, 36, 36, 235, 79, 95,
-208, 11, 208, 61, 229, 65, 68, 53, 58, 216,
-223, 227, 216, 155, 10, 44, 47, 91, 115, 47,
-228, 159, 139, 233