shithub: qk1

Download patch

ref: fc4eb838ab4af811315b80e91164e00d1ec8d6b9
parent: c994e5681e1db75fe14a52d4be7ac461993c1f39
author: Konstantinn Bonnet <qu7uux@gmail.com>
date: Wed Feb 11 19:13:05 EST 2015

make work on 9front

- mostly sound: in_9.c, vid_9.c, sys_9.c
- stubs: cd_9, net_udp
- buggered: snd_9
- useless stdio: cl_demo.c, draw.c
- host.c: initdraw before starting input stuff
- mkfile: linking errors, no idea how to fix yet (includes?)
- quakedef.h: pragma pack: required for assumed struct sizes
- screen.c: one instance of fp exception

--- a/.hgignore
+++ b/.hgignore
@@ -1,4 +1,5 @@
 syntax:glob
-*.[1-9o]
+*.[1-9qv]
 *qk1
+*.out
 id1/
--- a/README
+++ b/README
@@ -1,26 +1,71 @@
 qk1 - port of Quake to 9front
 =============================
-Does not work. Nothing to see here, move along.
+	- based on linux/x11 code from original gpl release
+	- setup:
+		. mk install
+		. mkdir id1
+		. cp /n/quakecd/id1/*.pak id1/
+		. run from same dir...
+	- unfinished and very buggy (both shitty new code and badly ported old code)
+	- sound does not work; assume that you should always launch with -nosound
+	- assume high resolutions don't work well and are very crash prone (e.g. > 800x600)
+		. exit with: Hunk_Alloc: failed on ... => not enough memory
+		use [-mem megabytes], e.g.:
+			% qk1 -nosound -mem 10
+	- don't use -winsize, -width, -height; just resize the window (bugsbugsbugs)
+	- mouse is grabbed using _windowed_mouse cvar
+		. open console (~)
+		. type _windowed_mouse 1 (can autocomplete w/ tab)
+		. setting now saved in .cfg
+	- assume it can crash with mouse still being captured (in_9.c)
+		. if window size < physical screen size, swipe mouse super to exit the window
+		(bug in mproc)
+	- tested on 386 and amd64 only
 
-builds only with p9p on linux/386 and amd64; bugged to hell.
-actually, untested on 386, because linux crosscompiling and p9p on not-OSX.
 
-plan9 shit missing completely, asm not ungccfied.
-
-intrusive changes:
+port notes
+----------
 	- pr_strings: assumed 32bit pointer arithmetic: use PR_GetStr() instead of
 	  dealing with it directly; may be ass
-	- global cppdefotomy
+	- global cppdefotomy, removing code seen as useless for plan9
 
 
-bugs
-----
+bugs present in linux/x11
+-------------------------
 	- compile with PARANOID -> MSG_WriteByte complains about range error and
-	  exits. no idea why. (386/amd64)
-	- new game while already ingame -> front falls off (amd64)
-		. most of the time: exit with R_RenderView: called without enough stack
+	  exits. no idea why.
+	- new game while already ingame -> front falls off
+		. most of the time: exits with R_RenderView: called without enough stack
+		. sometimes: goes batshit on the console (->press y again and quit normally, etc.)
+	- compile with BAN_TEST -> net_dgrm build fails
+	- sprites/particles not scaled on high resolutions
+	- mouselook was completely fucked; still is somewhat
+		. when paused, if _windowed_mouse 1, can still look around with the mouse, even
+		if world is frozen
+	- fp exceptions galore
 
 
+todo
+----
+	- kill stdio; other than stdio uses, NULL -> nil; same for *printf
+	- vid_9.c: remove/limit stupid
+	- net_9p.c
+	- net_udp.c + net_dgrm.c: actuallyport
+	- snd_9.c: actuallyport
+	- cd_9.c: everything; just specigy via cvar a folder and look for files there?
+	- kill mouse on crash
+	- mproc: better grabout shit
+	- free mouselook without needing +mlook
+	- plan9-like install
+	- fix *Printf functions (console.c, sys_9.c, etc.)
+	- do something about all the fucking shit printed in console
+	- caps lock == Kctl
+	- ungrab mouse when entering console or menus a la games/doom (IN_Grabm())
+	- clean up *_9.c
+	- linking errors with -T cflag
+	- fix potential fp exceptions in code rather than ignoring them
+
+
 legal
 -----
-Quake, hence qk1, are licensed under the GPLv2. See COPYING for details.
+Quake, hence qk1, is licensed under the GPLv2. See COPYING for details.
--- a/cd_9.c
+++ b/cd_9.c
@@ -1,117 +1,94 @@
 #include <u.h>
 #include <libc.h>
-//#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 "quakedef.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;
+qboolean cdValid = false;
+qboolean playing = false;
+qboolean wasPlaying = false;
+qboolean initialized = false;
+qboolean enabled = true;
+qboolean playLooping = false;
+float cdvolume;
+byte remap[100];
+byte playTrack;
+byte maxTrack;
+int cdfile = -1;
+char cd_dev[64] = "/dev/cdrom";
 
-static int cdfile = -1;
-static char cd_dev[64] = "/dev/cdrom";
 
-static void CDAudio_Eject(void)
+void CDAudio_Eject (void)
 {
-	if (cdfile == -1 || !enabled)
-		return; // no cd init'd
+	if(cdfile == -1 || !enabled)
+		return;
 
-	if ( ioctl(cdfile, CDROMEJECT) == -1 ) 
-		Con_DPrintf("ioctl cdromeject failed\n");
+	Con_DPrintf("CDAudio_Eject: PORTME\n");
 }
 
-
-static void CDAudio_CloseDoor(void)
+void CDAudio_CloseDoor (void)
 {
-	if (cdfile == -1 || !enabled)
-		return; // no cd init'd
+	if(cdfile == -1 || !enabled)
+		return;
 
-	if ( ioctl(cdfile, CDROMCLOSETRAY) == -1 ) 
-		Con_DPrintf("ioctl cdromclosetray failed\n");
+	Con_DPrintf("CDAudio_CloseDoor: PORTME\n");
 }
 
-static int CDAudio_GetAudioDiskInfo(void)
+int CDAudio_GetAudioDiskInfo (void)
 {
-	struct cdrom_tochdr tochdr;
-
 	cdValid = false;
+	Con_DPrintf("CDAudio_GetAudioDiskInfo: PORTME\n");
+	return -1;
 
-	if ( ioctl(cdfile, CDROMREADTOCHDR, &tochdr) == -1 ) 
-    {
-      Con_DPrintf("ioctl cdromreadtochdr failed\n");
-	  return -1;
-    }
+	/*
+	struct cdrom_tochdr tochdr;
 
-	if (tochdr.cdth_trk0 < 1)
-	{
+	if(tochdr.cdth_trk0 < 1){
 		Con_DPrintf("CDAudio: no music tracks\n");
 		return -1;
 	}
-
 	cdValid = true;
 	maxTrack = tochdr.cdth_trk1;
-
 	return 0;
+	*/
 }
 
-
-void CDAudio_Play(byte track, qboolean looping)
+void CDAudio_Play (byte track, qboolean looping)
 {
-	struct cdrom_tocentry entry;
-	struct cdrom_ti ti;
-
-	if (cdfile == -1 || !enabled)
+	if(cdfile == -1 || !enabled)
 		return;
 	
-	if (!cdValid)
-	{
+	if(!cdValid){
 		CDAudio_GetAudioDiskInfo();
-		if (!cdValid)
+		if(!cdValid)
 			return;
 	}
 
 	track = remap[track];
-
-	if (track < 1 || track > maxTrack)
-	{
+	if(track < 1 || track > maxTrack){
 		Con_DPrintf("CDAudio: Bad track number %u.\n", track);
 		return;
 	}
 
+	Con_DPrintf("CDAudio_Play: PORTME\n");
+	return;
+
+	/*
+	struct cdrom_tocentry entry;
+	struct cdrom_ti ti;
+
 	// don't try to play a non-audio track
 	entry.cdte_track = track;
 	entry.cdte_format = CDROM_MSF;
-    if ( ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1 )
-	{
+	if(ioctl(cdfile, CDROMREADTOCENTRY, &entry) == -1){
 		Con_DPrintf("ioctl cdromreadtocentry failed\n");
 		return;
 	}
-	if (entry.cdte_ctrl == CDROM_DATA_TRACK)
-	{
+	if(entry.cdte_ctrl == CDROM_DATA_TRACK){
 		Con_Printf("CDAudio: track %i is not audio\n", track);
 		return;
 	}
 
-	if (playing)
-	{
-		if (playTrack == track)
+	if(playing){
+		if(playTrack == track)
 			return;
 		CDAudio_Stop();
 	}
@@ -120,184 +97,137 @@
 	ti.cdti_trk1 = track;
 	ti.cdti_ind0 = 1;
 	ti.cdti_ind1 = 99;
-
-	if ( ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1 ) 
-    {
+	if(ioctl(cdfile, CDROMPLAYTRKIND, &ti) == -1) {
 		Con_DPrintf("ioctl cdromplaytrkind failed\n");
 		return;
-    }
-
-	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
+	}
+	if(ioctl(cdfile, CDROMRESUME) == -1) 
 		Con_DPrintf("ioctl cdromresume failed\n");
+	*/
 
 	playLooping = looping;
 	playTrack = track;
 	playing = true;
 
-	if (cdvolume == 0.0)
-		CDAudio_Pause ();
+	if(cdvolume == 0.0)
+		CDAudio_Pause();
 }
 
-
-void CDAudio_Stop(void)
+void CDAudio_Stop (void)
 {
-	if (cdfile == -1 || !enabled)
+	if(cdfile == -1 || !enabled || !playing)
 		return;
-	
-	if (!playing)
-		return;
 
-	if ( ioctl(cdfile, CDROMSTOP) == -1 )
-		Con_DPrintf("ioctl cdromstop failed (%d)\n", errno);
+	Con_DPrintf("CDAudio_Stop: PORTME\n");
 
 	wasPlaying = false;
 	playing = false;
 }
 
-void CDAudio_Pause(void)
+void CDAudio_Pause (void)
 {
-	if (cdfile == -1 || !enabled)
+	if(cdfile == -1 || !enabled || !playing)
 		return;
 
-	if (!playing)
-		return;
+	Con_DPrintf("CDAudio_Pause: PORTME\n");
 
-	if ( ioctl(cdfile, CDROMPAUSE) == -1 ) 
-		Con_DPrintf("ioctl cdrompause failed\n");
-
 	wasPlaying = playing;
 	playing = false;
 }
 
-
-void CDAudio_Resume(void)
+void CDAudio_Resume (void)
 {
-	if (cdfile == -1 || !enabled)
+	if(cdfile == -1 || !enabled || !cdValid || !wasPlaying)
 		return;
-	
-	if (!cdValid)
-		return;
 
-	if (!wasPlaying)
-		return;
-	
-	if ( ioctl(cdfile, CDROMRESUME) == -1 ) 
-		Con_DPrintf("ioctl cdromresume failed\n");
+	Con_DPrintf("CDAudio_Resume: PORTME\n");
+
 	playing = true;
 }
 
-static void CD_f (void)
+void CD_f (void)
 {
-	char	*command;
-	int		ret;
-	int		n;
+	int ret, n;
+	char *command;
 
-	if (Cmd_Argc() < 2)
+	if(Cmd_Argc() < 2)
 		return;
 
-	command = Cmd_Argv (1);
-
-	if (Q_strcasecmp(command, "on") == 0)
-	{
+	command = Cmd_Argv(1);
+	if(Q_strcasecmp(command, "on") == 0){
 		enabled = true;
 		return;
 	}
-
-	if (Q_strcasecmp(command, "off") == 0)
-	{
-		if (playing)
+	if(Q_strcasecmp(command, "off") == 0){
+		if(playing)
 			CDAudio_Stop();
 		enabled = false;
 		return;
 	}
-
-	if (Q_strcasecmp(command, "reset") == 0)
-	{
+	if(Q_strcasecmp(command, "reset") == 0){
 		enabled = true;
-		if (playing)
+		if(playing)
 			CDAudio_Stop();
-		for (n = 0; n < 100; n++)
+		for(n = 0; n < 100; n++)
 			remap[n] = n;
 		CDAudio_GetAudioDiskInfo();
 		return;
 	}
-
-	if (Q_strcasecmp(command, "remap") == 0)
-	{
+	if(Q_strcasecmp(command, "remap") == 0){
 		ret = Cmd_Argc() - 2;
-		if (ret <= 0)
-		{
-			for (n = 1; n < 100; n++)
-				if (remap[n] != n)
+		if(ret <= 0){
+			for(n = 1; n < 100; n++)
+				if(remap[n] != n)
 					Con_Printf("  %u -> %u\n", n, remap[n]);
 			return;
 		}
-		for (n = 1; n <= ret; n++)
-			remap[n] = Q_atoi(Cmd_Argv (n+1));
+		for(n = 1; n <= ret; n++)
+			remap[n] = Q_atoi(Cmd_Argv(n+1));
 		return;
 	}
-
-	if (Q_strcasecmp(command, "close") == 0)
-	{
+	if(Q_strcasecmp(command, "close") == 0){
 		CDAudio_CloseDoor();
 		return;
 	}
-
-	if (!cdValid)
-	{
+	if(!cdValid){
 		CDAudio_GetAudioDiskInfo();
-		if (!cdValid)
-		{
+		if(!cdValid){
 			Con_Printf("No CD in player.\n");
 			return;
 		}
 	}
-
-	if (Q_strcasecmp(command, "play") == 0)
-	{
-		CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), false);
+	if(Q_strcasecmp(command, "play") == 0){
+		CDAudio_Play((byte)Q_atoi(Cmd_Argv(2)), false);
 		return;
 	}
-
-	if (Q_strcasecmp(command, "loop") == 0)
-	{
-		CDAudio_Play((byte)Q_atoi(Cmd_Argv (2)), true);
+	if(Q_strcasecmp(command, "loop") == 0){
+		CDAudio_Play((byte)Q_atoi(Cmd_Argv(2)), true);
 		return;
 	}
-
-	if (Q_strcasecmp(command, "stop") == 0)
-	{
+	if(Q_strcasecmp(command, "stop") == 0){
 		CDAudio_Stop();
 		return;
 	}
-
-	if (Q_strcasecmp(command, "pause") == 0)
-	{
+	if (Q_strcasecmp(command, "pause") == 0){
 		CDAudio_Pause();
 		return;
 	}
-
-	if (Q_strcasecmp(command, "resume") == 0)
-	{
+	if(Q_strcasecmp(command, "resume") == 0){
 		CDAudio_Resume();
 		return;
 	}
-
-	if (Q_strcasecmp(command, "eject") == 0)
-	{
-		if (playing)
+	if(Q_strcasecmp(command, "eject") == 0){
+		if(playing)
 			CDAudio_Stop();
 		CDAudio_Eject();
 		cdValid = false;
 		return;
 	}
-
-	if (Q_strcasecmp(command, "info") == 0)
-	{
+	if(Q_strcasecmp(command, "info") == 0){
 		Con_Printf("%u tracks\n", maxTrack);
-		if (playing)
+		if(playing)
 			Con_Printf("Currently %s track %u\n", playLooping ? "looping" : "playing", playTrack);
-		else if (wasPlaying)
+		else if(wasPlaying)
 			Con_Printf("Paused %s track %u\n", playLooping ? "looping" : "playing", playTrack);
 		Con_Printf("Volume is %f\n", cdvolume);
 		return;
@@ -304,44 +234,45 @@
 	}
 }
 
-void CDAudio_Update(void)
+void CDAudio_Update (void)
 {
-	struct cdrom_subchnl subchnl;
-	static time_t lastchk;
+	static long lastchk;
 
-	if (!enabled)
+	if(!enabled)
 		return;
 
-	if (bgmvolume.value != cdvolume)
-	{
-		if (cdvolume)
-		{
-			Cvar_SetValue ("bgmvolume", 0.0);
+	if(bgmvolume.value != cdvolume){
+		if(cdvolume){
+			Cvar_SetValue("bgmvolume", 0.0);
 			cdvolume = bgmvolume.value;
-			CDAudio_Pause ();
-		}
-		else
-		{
-			Cvar_SetValue ("bgmvolume", 1.0);
+			CDAudio_Pause();
+		}else{
+			Cvar_SetValue("bgmvolume", 1.0);
 			cdvolume = bgmvolume.value;
-			CDAudio_Resume ();
+			CDAudio_Resume();
 		}
 	}
+	if(playing && lastchk < time(nil)){
+		lastchk = time(nil) + 2;	//two seconds between chks
 
-	if (playing && lastchk < time(NULL)) {
-		lastchk = time(NULL) + 2; //two seconds between chks
+		Con_DPrintf("CDAudio_Update: PORTME\n");
+
+		/*
+		struct cdrom_subchnl subchnl;
+
 		subchnl.cdsc_format = CDROM_MSF;
-		if (ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
+		if(ioctl(cdfile, CDROMSUBCHNL, &subchnl) == -1 ) {
 			Con_DPrintf("ioctl cdromsubchnl failed\n");
 			playing = false;
 			return;
 		}
-		if (subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY &&
-			subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED) {
+		if(subchnl.cdsc_audiostatus != CDROM_AUDIO_PLAY
+		&& subchnl.cdsc_audiostatus != CDROM_AUDIO_PAUSED){
 			playing = false;
-			if (playLooping)
+			if(playLooping)
 				CDAudio_Play(playTrack, true);
 		}
+		*/
 	}
 }
 
@@ -349,19 +280,21 @@
 {
 	int i;
 
-	if (cls.state == ca_dedicated)
+	if(cls.state == ca_dedicated)
 		return -1;
-
-	if (COM_CheckParm("-nocdaudio"))
+	if(COM_CheckParm("-nocdaudio"))
 		return -1;
 
-	if ((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) {
+	/* FIXME */
+	return -1;
+
+	if((i = COM_CheckParm("-cddev")) != 0 && i < com_argc - 1) {
 		strncpy(cd_dev, com_argv[i + 1], sizeof(cd_dev));
-		cd_dev[sizeof(cd_dev) - 1] = 0;
+		cd_dev[sizeof(cd_dev)-1] = 0;
 	}
 
-	if ((cdfile = open(cd_dev, OREAD)) == -1) {
-		Con_Printf("CDAudio_Init: open of \"%s\" failed (%i)\n", cd_dev, errno);
+	if((cdfile = open(cd_dev, OREAD)) == -1){
+		Con_Printf("CDAudio_Init %s: %r\n", cd_dev);
 		cdfile = -1;
 		return -1;
 	}
@@ -371,13 +304,12 @@
 	initialized = true;
 	enabled = true;
 
-	if (CDAudio_GetAudioDiskInfo())
-	{
+	if(CDAudio_GetAudioDiskInfo()){
 		Con_Printf("CDAudio_Init: No CD in player.\n");
 		cdValid = false;
 	}
 
-	Cmd_AddCommand ("cd", CD_f);
+	Cmd_AddCommand("cd", CD_f);
 
 	Con_Printf("CD Audio Initialized\n");
 
@@ -384,10 +316,9 @@
 	return 0;
 }
 
-
-void CDAudio_Shutdown(void)
+void CDAudio_Shutdown (void)
 {
-	if (!initialized)
+	if(!initialized)
 		return;
 	CDAudio_Stop();
 	close(cdfile);
--- a/cl_demo.c
+++ b/cl_demo.c
@@ -212,7 +212,7 @@
 	else
 		track = -1;	
 
-	sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));
+	sprint (name, "%s/%s", com_gamedir, Cmd_Argv(1));
 	
 //
 // start the map up
--- a/common.c
+++ b/common.c
@@ -256,8 +256,6 @@
 		}
 		if (!c1)
 			return 0;               // strings are equal
-//              s1++;
-//              s2++;
 	}
 }
 
@@ -1170,7 +1168,7 @@
 =============================================================================
 */
 
-int     com_filesize;
+vlong	com_filesize;
 
 
 //
@@ -1304,7 +1302,8 @@
 void COM_CopyFile (char *netpath, char *cachepath)
 {
 	int             in, out;
-	int             remaining, count;
+	int             count;
+	vlong		remaining;
 	char    buf[4096];
 	
 	remaining = Sys_FileOpenRead (netpath, &in);            
--- a/common.h
+++ b/common.h
@@ -143,7 +143,7 @@
 
 //============================================================================
 
-extern int com_filesize;
+extern vlong com_filesize;
 struct cache_user_s;
 
 extern	char	com_gamedir[MAX_OSPATH];
--- a/draw.c
+++ b/draw.c
@@ -527,7 +527,7 @@
 	conback = Draw_CachePic ("gfx/conback.lmp");
 
 // hack the version number directly into the pic
-	sprintf (ver, "((9)quake nil) %4.2f", (float)VERSION);
+	sprint (ver, "(9)quake %4.2f", (float)VERSION);
 	dest = conback->data + 320*186 + 320 - 11 - 8*strlen(ver);
 
 	for (x=0 ; x<strlen(ver) ; x++)
--- a/host.c
+++ b/host.c
@@ -812,8 +812,8 @@
 		if (!host_colormap)
 			Sys_Error ("Couldn't load gfx/colormap.lmp");
 
-		IN_Init ();
 		VID_Init (host_basepal);
+		IN_Init ();
 
 		Draw_Init ();
 		SCR_Init ();
--- a/in_9.c
+++ b/in_9.c
@@ -1,0 +1,311 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include "quakedef.h"
+
+cvar_t _windowed_mouse = {"_windowed_mouse","0", true};
+cvar_t m_filter = {"m_filter","0", true};
+float old_windowed_mouse;
+qboolean mouse_avail;
+int mouse_buttons = 3;
+int mouse_buttonstate, mouse_oldbuttonstate;
+float mouse_x, mouse_y, old_mouse_x, old_mouse_y, p_mouse_x, p_mouse_y;
+
+struct {
+	int key;
+	int down;
+} keyq[64];
+int keyq_head = 0;
+int keyq_tail = 0;
+int mouseactive;
+int kpid = -1, mpid = -1;
+
+/* vid_9.c */
+extern int config_notify;
+extern Point center;
+extern Rectangle grabout;
+
+
+void Sys_SendKeyEvents(void)
+{
+	if(old_windowed_mouse != _windowed_mouse.value){
+		old_windowed_mouse = _windowed_mouse.value;
+		if(!_windowed_mouse.value)
+			IN_Grabm(0);
+		else
+			IN_Grabm(1);
+	}
+
+	while(keyq_head != keyq_tail){
+		Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down);
+		keyq_tail = keyq_tail+1 & 63;
+	}
+}
+
+void IN_Commands (void)
+{
+	int i;
+
+	if(!mouse_avail)
+		return;
+
+	/* FIXMEGASHIT */
+	for(i = 0; i < mouse_buttons; i++){
+		if(mouse_buttonstate & 1<<i && ~mouse_oldbuttonstate & 1<<i)
+			Key_Event(K_MOUSE1+i, true);
+		if (~mouse_buttonstate & 1<<i && mouse_oldbuttonstate & 1<<i)
+			Key_Event(K_MOUSE1+i, false);
+	}
+	mouse_oldbuttonstate = mouse_buttonstate;
+}
+
+void IN_Move (usercmd_t *cmd)
+{
+	if(!mouse_avail)
+		return;
+   
+	if(m_filter.value){
+		mouse_x = (mouse_x + old_mouse_x) * 0.5;
+		mouse_y = (mouse_y + old_mouse_y) * 0.5;
+	}
+	old_mouse_x = mouse_x;
+	old_mouse_y = mouse_y;
+	mouse_x *= sensitivity.value;
+	mouse_y *= sensitivity.value;
+   
+	if(in_strafe.state & 1 || lookstrafe.value && in_mlook.state & 1)
+		cmd->sidemove += m_side.value * mouse_x;
+	else
+		cl.viewangles[YAW] -= m_yaw.value * mouse_x;
+	if(in_mlook.state & 1)
+		V_StopPitchDrift();
+   
+	if(in_mlook.state & 1 && ~in_strafe.state & 1){
+		cl.viewangles[PITCH] += m_pitch.value * mouse_y;
+		if(cl.viewangles[PITCH] > 80)
+			cl.viewangles[PITCH] = 80;
+		if(cl.viewangles[PITCH] < -70)
+			cl.viewangles[PITCH] = -70;
+	}else{
+		if(in_strafe.state & 1 && noclip_anglehack)
+			cmd->upmove -= m_forward.value * mouse_y;
+		else
+			cmd->forwardmove -= m_forward.value * mouse_y;
+	}
+	mouse_x = mouse_y = 0.0;
+}
+
+int runetokey (Rune r)
+{
+	int k = 0;
+
+	switch(r){
+	case Kpgup:	k = K_PGUP; break;
+	case Kpgdown:	k = K_PGDN; break;
+	case Khome:	k = K_HOME; break;
+	case Kend:	k = K_END; break;
+	case Kleft:	k = K_LEFTARROW; break;
+	case Kright:	k = K_RIGHTARROW; break;
+	case Kdown:	k = K_DOWNARROW; break;
+	case Kup:	k = K_UPARROW; break;
+	case Kesc:	k = K_ESCAPE; break;
+	case '\n':	k = K_ENTER; break;
+	case '\t':	k = K_TAB; break;
+	case KF|1:	k = K_F1; break;
+	case KF|2:	k = K_F2; break;
+	case KF|3:	k = K_F3; break;
+	case KF|4:	k = K_F4; break;
+	case KF|5:	k = K_F5; break;
+	case KF|6:	k = K_F6; break;
+	case KF|7:	k = K_F7; break;
+	case KF|8:	k = K_F8; break;
+	case KF|9:	k = K_F9; break;
+	case KF|10:	k = K_F10; break;
+	case KF|11:	k = K_F11; break;
+	case KF|12:	k = K_F12; break;
+	case Kbs:	k = K_BACKSPACE; break;
+	case Kdel:	k = K_DEL; break;
+	case Kbreak:	k = K_PAUSE; break;
+	case Kshift:	k = K_SHIFT; break;
+	case Kctl:	k = K_CTRL; break;
+	case Kalt:
+	case Kaltgr:	k = K_ALT; break;
+	case Kins:	k = K_INS; break;
+	default:
+		if(r < 0x80)
+			k = r;
+	}
+	return k;
+}
+
+void kproc (void)
+{
+	int n, k, fd;
+	char buf[128], kdown[128] = {0}, *s;
+	Rune r;
+
+	if((fd = open("/dev/kbd", OREAD)) < 0)
+		sysfatal("open /dev/kbd: %r");
+
+	/* FIXMESS */
+
+	while((n = read(fd, buf, sizeof(buf))) > 0){
+		buf[n-1] = 0;
+
+		switch(*buf){
+		case 'c':
+			/*
+			chartorune(&r, buf+1);
+			if(r){
+				keyq[keyq_head].key = runetokey(r);
+				keyq[keyq_head].down = true;
+				keyq_head = keyq_head+1 & 63;
+			}
+			*/
+			/* fall through */
+		default:
+			continue;
+		case 'k':
+			s = buf+1;
+			while(*s){
+				s += chartorune(&r, s);
+				if(utfrune(kdown+1, r) == nil){
+					if(k = runetokey(r)){
+						keyq[keyq_head].key = k;
+						keyq[keyq_head].down = true;
+						keyq_head = keyq_head+1 & 63;
+					}
+				}
+			}
+			break;
+		case 'K':
+			s = kdown+1;
+			while(*s){
+				s += chartorune(&r, s);
+				if(utfrune(buf+1, r) == nil){
+					if(k = runetokey(r)){
+						keyq[keyq_head].key = k;
+						keyq[keyq_head].down = false;
+						keyq_head = keyq_head+1 & 63;
+					}
+				}
+			}
+			break;
+		}
+		strcpy(kdown, buf);
+	}
+	close(fd);
+}
+
+void mproc (void)
+{
+	int b, n, nerr, fd;
+	char buf[1+5*12];
+	Point m;
+
+	if((fd = open("/dev/mouse", ORDWR)) < 0)
+		sysfatal("open /dev/mouse: %r");
+
+	memset(&m, 0, sizeof m);
+	nerr = 0;
+	for(;;){
+		if((n = read(fd, buf, sizeof buf)) != 1+4*12){
+			Con_Printf("mouse: bad count %d not 49: %r\n", n);
+			if(n < 0 || ++nerr > 10)
+				break;
+			continue;
+		}
+		nerr = 0;
+		switch(*buf){
+		case 'r':
+			config_notify = 1;
+			/* fall through */
+		case 'm':
+			if(!mouseactive)
+				break;
+
+			m.x = atoi(buf+1+0*12);
+			m.y = atoi(buf+1+1*12);
+			//m.buttons = atoi(buf+1+2*12);
+			b = atoi(buf+1+2*12);
+
+			/* FIXME: does not work well */
+			if(_windowed_mouse.value){
+				if(!ptinrect(m, grabout)){
+					fprint(fd, "m%d %d", center.x, center.y);
+					m = center;
+					p_mouse_x = center.x;
+					p_mouse_y = center.y;
+				}
+			}
+			mouse_x = (float)(m.x - p_mouse_x);
+			mouse_y = (float)(m.y - p_mouse_y);
+			p_mouse_x = m.x;
+			p_mouse_y = m.y;
+
+			mouse_buttonstate = b&1 | (b&2)<<1 | (b&4)>>1;
+			break;
+		}
+	}
+	close(fd);
+}
+
+void IN_Grabm (int on)
+{
+	static char nocurs[2*4+2*2*16] = {0};
+	static int fd = -1;
+
+	if(mouseactive == on)
+		return;
+	if(mouseactive = on){
+		if((fd = open("/dev/cursor", ORDWR|OCEXEC)) < 0){
+			Con_Printf("%s IN_Grabm: open: %r", argv0);
+			return;
+		}
+		write(fd, nocurs, sizeof(nocurs));
+	}else if(fd >= 0){
+		close(fd);
+		fd = -1;
+	}
+}
+
+void IN_Shutdown (void)
+{
+	IN_Grabm(0);
+	if(kpid != -1){
+		postnote(PNPROC, kpid, "shutdown");
+		kpid = -1;
+	}
+	if(mpid != -1){
+		postnote(PNPROC, mpid, "shutdown");
+		mpid = -1;
+	}
+	mouse_avail = 0;
+}
+
+void IN_Init (void)
+{
+	int pid;
+
+	Cvar_RegisterVariable(&_windowed_mouse);
+	Cvar_RegisterVariable(&m_filter);
+	IN_Grabm(1);
+	if((pid = rfork(RFPROC|RFMEM|RFFDG)) == 0){
+		kproc();
+		exits(nil);
+	}
+	kpid = pid;
+	if(COM_CheckParm("-nomouse"))
+		return;
+	/* FIXME: notify(catch) if crash -> disable mouse */
+	if((pid = rfork(RFPROC|RFMEM|RFFDG)) == 0){
+		mproc();
+		exits(nil);
+	}
+	mpid = pid;
+	p_mouse_x = p_mouse_y = mouse_x = mouse_y = 0.0;
+	mouse_avail = 1;
+}
--- a/input.h
+++ b/input.h
@@ -13,3 +13,5 @@
 void IN_ClearStates (void);
 // restores all button and position states to defaults
 
+void IN_Grabm (int on);
+// grab or ungrab mouse
--- a/mkfile
+++ b/mkfile
@@ -123,3 +123,7 @@
 	zone.h\
 
 </sys/src/cmd/mkone
+
+# FIXME (packing error?)
+CFLAGS=-FVw
+#LDFLAGS=-v
--- a/net.h
+++ b/net.h
@@ -219,7 +219,6 @@
 extern int hostCacheCount;
 extern hostcache_t hostcache[HOSTCACHESIZE];
 
-#ifndef __linux__
 #ifndef htonl
 extern u32int htonl (u32int hostlong);
 #endif
@@ -231,7 +230,6 @@
 #endif
 #ifndef ntohs
 extern unsigned short ntohs (unsigned short netshort);
-#endif
 #endif
 
 #ifdef IDGODS
--- a/net_dgrm.c
+++ b/net_dgrm.c
@@ -1,11 +1,10 @@
-// net_dgrm.c
+#include <u.h>
+#include <libc.h>
 
 // This is enables a simple IP banning mechanism
-#define BAN_TEST
+//#define BAN_TEST	/* FIXME */
 
 #ifdef BAN_TEST
-#include <u.h>
-#include <libc.h>
 #define AF_INET 		2	/* internet */
 struct in_addr
 {
@@ -131,7 +130,7 @@
 			break;
 	}
 }
-#endif
+#endif // BAN_TEST
 
 
 int Datagram_SendMessage (qsocket_t *sock, sizebuf_t *data)
--- a/net_udp.c
+++ b/net_udp.c
@@ -1,23 +1,10 @@
-/* FIXME */
-//#include <u.h>
-//#include <libc.h>
-#include <stdint.h>
-#include <string.h>
-#include <setjmp.h>
-typedef uintptr_t uintptr;
-typedef uint32_t u32int;
-
+#include <u.h>
+#include <libc.h>
 #include "quakedef.h"
 
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <sys/param.h>
-#include <sys/ioctl.h>
-#include <errno.h>
+/* FIXME FIXME FIXME */
 
+/*
 extern int gethostname (char *, int);
 extern int close (int);
 
@@ -29,21 +16,20 @@
 static struct qsockaddr broadcastaddr;
 
 static u32int myAddr;
+*/
 
 #include "net_udp.h"
 
-//=============================================================================
-
 int UDP_Init (void)
 {
 	struct hostent *local;
-	char	buff[MAXHOSTNAMELEN];
+	/*char	buff[MAXHOSTNAMELEN];*/
 	struct qsockaddr addr;
 	char *colon;
 	
 	if (COM_CheckParm ("-noudp"))
 		return -1;
-
+	/*
 	// determine my name & address
 	gethostname(buff, MAXHOSTNAMELEN);
 	local = gethostbyname(buff);
@@ -73,20 +59,21 @@
 	tcpipAvailable = true;
 
 	return net_controlsocket;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 void UDP_Shutdown (void)
 {
+	/*
 	UDP_Listen (false);
 	UDP_CloseSocket (net_controlsocket);
+	*/
 }
 
-//=============================================================================
-
 void UDP_Listen (qboolean state)
 {
+	/*
 	// enable listening
 	if (state)
 	{
@@ -102,12 +89,12 @@
 		return;
 	UDP_CloseSocket (net_acceptsocket);
 	net_acceptsocket = -1;
+	*/
 }
 
-//=============================================================================
-
 int UDP_OpenSocket (int port)
 {
+	/*
 	int newsocket;
 	struct sockaddr_in address;
 	qboolean _true = true;
@@ -129,19 +116,20 @@
 ErrorReturn:
 	close (newsocket);
 	return -1;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_CloseSocket (int socket)
 {
+	/*
 	if (socket == net_broadcastsocket)
 		net_broadcastsocket = 0;
 	return close (socket);
+	*/
+	return -1;
 }
 
-
-//=============================================================================
 /*
 ============
 PartialIPAddress
@@ -152,6 +140,7 @@
 */
 static int PartialIPAddress (char *in, struct qsockaddr *hostaddr)
 {
+	/*
 	char buff[256];
 	char *b;
 	int addr;
@@ -197,8 +186,9 @@
 	((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
 	
 	return 0;
+	*/
+	return -1;
 }
-//=============================================================================
 
 int UDP_Connect (int socket, struct qsockaddr *addr)
 {
@@ -205,10 +195,9 @@
 	return 0;
 }
 
-//=============================================================================
-
 int UDP_CheckNewConnections (void)
 {
+	/*
 	u32int	available;
 
 	if (net_acceptsocket == -1)
@@ -219,12 +208,13 @@
 	if (available)
 		return net_acceptsocket;
 	return -1;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr)
 {
+	/*
 	int addrlen = sizeof (struct qsockaddr);
 	int ret;
 
@@ -232,12 +222,13 @@
 	if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED))
 		return 0;
 	return ret;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_MakeSocketBroadcastCapable (int socket)
 {
+	/*
 	int				i = 1;
 
 	// make this socket broadcast capable
@@ -246,12 +237,13 @@
 	net_broadcastsocket = socket;
 
 	return 0;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_Broadcast (int socket, byte *buf, int len)
 {
+	/*
 	int ret;
 
 	if (socket != net_broadcastsocket)
@@ -267,12 +259,13 @@
 	}
 
 	return UDP_Write (socket, buf, len, &broadcastaddr);
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr)
 {
+	/*
 	int ret;
 
 	ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr));
@@ -279,12 +272,13 @@
 	if (ret == -1 && errno == EWOULDBLOCK)
 		return 0;
 	return ret;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 char *UDP_AddrToString (struct qsockaddr *addr)
 {
+	/*
 	static char buffer[22];
 	int haddr;
 
@@ -291,12 +285,13 @@
 	haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
 	sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff, (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, ntohs(((struct sockaddr_in *)addr)->sin_port));
 	return buffer;
+	*/
+	return nil;
 }
 
-//=============================================================================
-
 int UDP_StringToAddr (char *string, struct qsockaddr *addr)
 {
+	/*
 	int ha1, ha2, ha3, ha4, hp;
 	int ipaddr;
 
@@ -307,12 +302,13 @@
 	((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
 	((struct sockaddr_in *)addr)->sin_port = htons(hp);
 	return 0;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_GetSocketAddr (int socket, struct qsockaddr *addr)
 {
+	/*
 	int addrlen = sizeof(struct qsockaddr);
 	unsigned int a;
 
@@ -323,12 +319,13 @@
 		((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
 
 	return 0;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name)
 {
+	/*
 	struct hostent *hostentry;
 
 	hostentry = gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
@@ -340,12 +337,13 @@
 
 	Q_strcpy (name, UDP_AddrToString (addr));
 	return 0;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_GetAddrFromName(char *name, struct qsockaddr *addr)
 {
+	/*
 	struct hostent *hostentry;
 
 	if (name[0] >= '0' && name[0] <= '9')
@@ -360,12 +358,13 @@
 	((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
 
 	return 0;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
 {
+	/*
 	if (addr1->sa_family != addr2->sa_family)
 		return -1;
 
@@ -376,20 +375,21 @@
 		return 1;
 
 	return 0;
+	*/
+	return -1;
 }
 
-//=============================================================================
-
 int UDP_GetSocketPort (struct qsockaddr *addr)
 {
-	return ntohs(((struct sockaddr_in *)addr)->sin_port);
+	//return ntohs(((struct sockaddr_in *)addr)->sin_port);
+	return -1;
 }
 
-
 int UDP_SetSocketPort (struct qsockaddr *addr, int port)
 {
+	/*
 	((struct sockaddr_in *)addr)->sin_port = htons(port);
 	return 0;
+	*/
+	return -1;
 }
-
-//=============================================================================
--- a/pr_edict.c
+++ b/pr_edict.c
@@ -986,7 +986,7 @@
 	progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat");
 	if (!progs)
 		Sys_Error ("PR_LoadProgs: couldn't load progs.dat");
-	Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
+	Con_DPrintf ("Programs occupy %lldK.\n", com_filesize/1024);
 
 	for (i=0 ; i<com_filesize ; i++)
 		CRC_ProcessByte (&pr_crc, ((byte *)progs)[i]);
--- a/progs.h
+++ b/progs.h
@@ -85,7 +85,6 @@
 #define	G_EDICT(o) ((edict_t *)((byte *)sv.edicts+ *(int *)&pr_globals[o]))
 #define G_EDICTNUM(o) NUM_FOR_EDICT(G_EDICT(o))
 #define	G_VECTOR(o) (&pr_globals[o])
-/* FIXME: amd64 */
 #define	G_STRING(o) (PR_Str(*(string_t *)&pr_globals[o]))
 #define	G_FUNCTION(o) (*(func_t *)&pr_globals[o])
 
@@ -92,7 +91,6 @@
 #define	E_FLOAT(e,o) (((float*)&e->v)[o])
 #define	E_INT(e,o) (*(int *)&((float*)&e->v)[o])
 #define	E_VECTOR(e,o) (&((float*)&e->v)[o])
-/* FIXME: amd64 */
 #define	E_STRING(e,o) (PR_Str(*(string_t *)&((float*)&e->v)[o]))
 
 extern	int		type_size[8];
--- a/quakedef.h
+++ b/quakedef.h
@@ -5,12 +5,7 @@
 //#define	PARANOID			// speed sapping error checking
 #define	GAMENAME	"id1"		// directory to look in by default
 
-#include <stdio.h>
-//#include <math.h>
-//#include <string.h>
-//#include <stdarg.h>
-//#include <stdlib.h>
-//#include <setjmp.h>
+#include <stdio.h>	/* FIXME */
 
 #define	VID_LockBuffer()
 #define	VID_UnlockBuffer()
@@ -153,6 +148,9 @@
 // This makes anyone on id's net privileged
 // Use for multiplayer testing only - VERY dangerous!!!
 // #define IDGODS
+
+/* FIXME: if hj no dicks, struct sizes screw up lump loading, see zB model.c errors */
+#pragma pack on
 
 #include "common.h"
 #include "bspfile.h"
--- a/screen.c
+++ b/screen.c
@@ -177,7 +177,7 @@
 */
 float CalcFov (float fov_x, float width, float height)
 {
-        float   a;
+        float   a = 0;
         float   x;
 
         if (fov_x < 1 || fov_x > 179)
@@ -185,8 +185,8 @@
 
         x = width/tan(fov_x/360*M_PI);
 
-        a = atan (height/x);
-
+	if(x != 0)
+        	a = atan (height/x);
         a = a*360/M_PI;
 
         return a;
--- a/snd_9.c
+++ b/snd_9.c
@@ -1,253 +1,103 @@
 #include <u.h>
 #include <libc.h>
-//#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 "quakedef.h"
 
 int audio_fd;
 int snd_inited;
 
-static int tryrates[] = { 11025, 22051, 44100, 8000 };
+int tryrates[] = { 11025, 22051, 44100, 8000 };
 
 qboolean SNDDMA_Init(void)
 {
+	int i;
 
-	int rc;
-    int fmt;
-	int tmp;
-    int i;
-    char *s;
-	struct audio_buf_info info;
-	int caps;
-
 	snd_inited = 0;
 
-// open /dev/dsp, confirm capability to mmap, and get size of dma buffer
-
-    audio_fd = open("/dev/dsp", OREAD);
-    if (audio_fd < 0)
-	{
-		perror("/dev/dsp");
-        Con_Printf("Could not open /dev/dsp\n");
+	if((audio_fd = open("/dev/audio", OWRITE)) < 0){
+		Con_Printf("%s open /dev/audio: %r\n", argv0);
 		return 0;
 	}
 
-    rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
-    if (rc < 0)
-	{
-		perror("/dev/dsp");
-		Con_Printf("Could not reset /dev/dsp\n");
-		close(audio_fd);
-		return 0;
-	}
+	// get size of dma buffer
+	/*
+	rc = ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
+	rc = ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps);
+	rc = ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info);
+	*/
 
-	if (ioctl(audio_fd, SNDCTL_DSP_GETCAPS, &caps)==-1)
-	{
-		perror("/dev/dsp");
-        Con_Printf("Sound driver too old\n");
-		close(audio_fd);
-		return 0;
-	}
-
-	if (!(caps & DSP_CAP_TRIGGER) || !(caps & DSP_CAP_MMAP))
-	{
-		Con_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");
-		Con_Printf("Um, can't do GETOSPACE?\n");
-		close(audio_fd);
-		return 0;
-    }
-    
 	shm = &sn;
-    shm->splitbuffer = 0;
+	shm->splitbuffer = 0;
 
-// set sample bits & speed
-
-    s = getenv("QUAKE_SOUND_SAMPLEBITS");
-    if (s) shm->samplebits = atoi(s);
-	else if ((i = COM_CheckParm("-sndbits")) != 0)
+	if((i = COM_CheckParm("-sndbits")) != 0)
 		shm->samplebits = atoi(com_argv[i+1]);
-	if (shm->samplebits != 16 && shm->samplebits != 8)
-    {
-        ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &fmt);
-        if (fmt & AFMT_S16_LE) shm->samplebits = 16;
-        else if (fmt & AFMT_U8) shm->samplebits = 8;
-    }
+	if(shm->samplebits != 16 && shm->samplebits != 8)
+		shm->samplebits = 16;
 
-    s = getenv("QUAKE_SOUND_SPEED");
-    if (s) shm->speed = atoi(s);
-	else if ((i = COM_CheckParm("-sndspeed")) != 0)
+	if((i = COM_CheckParm("-sndspeed")) != 0)
 		shm->speed = atoi(com_argv[i+1]);
-    else
-    {
-        for (i=0 ; i<sizeof(tryrates)/4 ; i++)
-            if (!ioctl(audio_fd, SNDCTL_DSP_SPEED, &tryrates[i])) break;
-        shm->speed = tryrates[i];
-    }
+	else
+		shm->speed = 44100;
 
-    s = getenv("QUAKE_SOUND_CHANNELS");
-    if (s) shm->channels = atoi(s);
-	else if ((i = COM_CheckParm("-sndmono")) != 0)
+	shm->channels = 2;
+	if(COM_CheckParm("-sndmono") != 0)
 		shm->channels = 1;
-	else if ((i = COM_CheckParm("-sndstereo")) != 0)
+	else if(COM_CheckParm("-sndstereo") != 0)
 		shm->channels = 2;
-    else shm->channels = 2;
 
-	shm->samples = info.fragstotal * info.fragsize / (shm->samplebits/8);
+	//shm->samples = info.fragstotal * info.fragsize / (shm->samplebits/8);
+	shm->samples = 1024;
 	shm->submission_chunk = 1;
 
-// memory map the dma buffer
+	// memory map the dma buffer
+	//shm->buffer = mmap(NULL, info.frags.total * info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
 
-	shm->buffer = (unsigned char *) mmap(NULL, info.fragstotal
-		* info.fragsize, PROT_WRITE, MAP_FILE|MAP_SHARED, audio_fd, 0);
-	if (!shm->buffer || shm->buffer == (unsigned char *)-1)
-	{
-		perror("/dev/dsp");
-		Con_Printf("Could not mmap /dev/dsp\n");
+	if((shm->buffer = malloc(shm->samplebits/8 * shm->samples)) == nil){
+		Con_Printf("%s malloc: %r\n", argv0);
 		close(audio_fd);
 		return 0;
 	}
 
-	tmp = 0;
-	if (shm->channels == 2)
-		tmp = 1;
-    rc = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
-    if (rc < 0)
-    {
-		perror("/dev/dsp");
-        Con_Printf("Could not set /dev/dsp to stereo=%d", shm->channels);
-		close(audio_fd);
-        return 0;
-    }
-	if (tmp)
-		shm->channels = 2;
-	else
-		shm->channels = 1;
+	/*
+	rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed);
+	rc = shm->samplebits == 16 ? AFMT_S16_LE : AFMT_U8;
+	rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
 
-    rc = ioctl(audio_fd, SNDCTL_DSP_SPEED, &shm->speed);
-    if (rc < 0)
-    {
-		perror("/dev/dsp");
-        Con_Printf("Could not set /dev/dsp speed to %d", shm->speed);
-		close(audio_fd);
-        return 0;
-    }
+	// toggle the trigger & start her up
+	rc = 0;
+	rc  = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &rc);
+	rc = PCM_ENABLE_OUTPUT;
+	rc = ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &tmp);
+	*/
 
-    if (shm->samplebits == 16)
-    {
-        rc = AFMT_S16_LE;
-        rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
-        if (rc < 0)
-		{
-			perror("/dev/dsp");
-			Con_Printf("Could not support 16-bit data.  Try 8-bit.\n");
-			close(audio_fd);
-			return 0;
-		}
-    }
-    else if (shm->samplebits == 8)
-    {
-        rc = AFMT_U8;
-        rc = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &rc);
-        if (rc < 0)
-		{
-			perror("/dev/dsp");
-			Con_Printf("Could not support 8-bit data.\n");
-			close(audio_fd);
-			return 0;
-		}
-    }
-	else
-	{
-		perror("/dev/dsp");
-		Con_Printf("%d-bit sound not supported.", shm->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("/dev/dsp");
-		Con_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("/dev/dsp");
-		Con_Printf("Could not toggle.\n");
-		close(audio_fd);
-		return 0;
-	}
-
 	shm->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("/dev/dsp");
-		Con_Printf("Uh, sound dead.\n");
-		close(audio_fd);
-		snd_inited = 0;
+	if (!snd_inited)
 		return 0;
-	}
-//	shm->samplepos = (count.bytes / (shm->samplebits / 8)) & (shm->samples-1);
-//	fprintf(stderr, "%d    \r", count.ptr);
-	shm->samplepos = count.ptr / (shm->samplebits / 8);
 
-	return shm->samplepos;
+	/* FIXME */
+	//shm->samplepos = count.bytes/shm->samplebits/8 & shm->samples-1;
+	//shm->samplepos = count.ptr / (shm->samplebits / 8);
 
+	return shm->samplepos;
 }
 
 void SNDDMA_Shutdown(void)
 {
-	if (snd_inited)
-	{
+	if(snd_inited){
 		close(audio_fd);
+		free(shm->buffer);	/* FIXME: fault read */
 		snd_inited = 0;
 	}
 }
 
-/*
-==============
-SNDDMA_Submit
-
-Send sound to device if buffer isn't really the dma buffer
-===============
-*/
 void SNDDMA_Submit(void)
 {
+	/* FIXME */
+	//write(audio_fd, shm->buffer, sizeof shm->buffer);
+	write(audio_fd, shm->buffer, shm->samplebits/8 * shm->samples);
 }
-
--- a/snd_mem.c
+++ b/snd_mem.c
@@ -230,7 +230,7 @@
 GetWavinfo
 ============
 */
-wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength)
+wavinfo_t GetWavinfo (char *name, byte *wav, vlong wavlength)
 {
 	wavinfo_t	info;
 	int     i;
--- a/sound.h
+++ b/sound.h
@@ -147,7 +147,7 @@
 void S_LocalSound (char *s);
 sfxcache_t *S_LoadSound (sfx_t *s);
 
-wavinfo_t GetWavinfo (char *name, byte *wav, int wavlength);
+wavinfo_t GetWavinfo (char *name, byte *wav, vlong wavlength);
 
 void SND_InitScaletable (void);
 void SNDDMA_Submit(void);
--- a/sys.h
+++ b/sys.h
@@ -3,50 +3,27 @@
 //
 // file IO
 //
-
-// returns the file size
-// return -1 if file is not present
-// the file should be in BINARY mode for stupid OSs that care
-int Sys_FileOpenRead (char *path, int *hndl);
-
+// returns the file size, -1 if file not found
+vlong Sys_FileOpenRead (char *path, int *hndl);
 int Sys_FileOpenWrite (char *path);
 void Sys_FileClose (int handle);
 void Sys_FileSeek (int handle, int position);
 int Sys_FileRead (int handle, void *dest, int count);
 int Sys_FileWrite (int handle, void *data, int count);
-int	Sys_FileTime (char *path);
+int Sys_FileTime (char *path);
 void Sys_mkdir (char *path);
 
 //
-// memory protection
-//
-void Sys_MakeCodeWriteable (uintptr startaddr, uintptr length);
-
-//
 // system IO
 //
-void Sys_DebugLog(char *file, char *fmt, ...);
-
 void Sys_Error (char *error, ...);
-// an error will cause the entire program to exit
-
 void Sys_Printf (char *fmt, ...);
-// send text to the console
-
 void Sys_Quit (void);
-
 double Sys_FloatTime (void);
-
 char *Sys_ConsoleInput (void);
 
-void Sys_Sleep (void);
-// called to yield for a little bit so as
-// not to hog cpu when paused or debugging
-
 void Sys_SendKeyEvents (void);
 // Perform Key_Event () callbacks until the input que is empty
 
 void Sys_LowFPPrecision (void);
 void Sys_HighFPPrecision (void);
-void Sys_SetFPCW (void);
-
--- a/sys_9.c
+++ b/sys_9.c
@@ -1,345 +1,149 @@
 #include <u.h>
 #include <libc.h>
-//#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 "quakedef.h"
 
-qboolean			isDedicated;
-
+qboolean isDedicated;
 int nostdout = 0;
-
 char *basedir = ".";
 char *cachedir = "/tmp";
+cvar_t sys_linerefresh = {"sys_linerefresh","0"};	// set for entity display
 
-cvar_t  sys_linerefresh = {"sys_linerefresh","0"};// set for entity display
 
-// =======================================================================
-// General routines
-// =======================================================================
-
-void Sys_DebugNumber(int y, int val)
-{
-}
-
-/*
 void Sys_Printf (char *fmt, ...)
 {
-	va_list		argptr;
-	char		text[1024];
-	
-	va_start (argptr,fmt);
-	vsprintf (text,fmt,argptr);
-	va_end (argptr);
-	fprintf(stderr, "%s", text);
-	
-	Con_Print (text);
-}
+	char buf[1024];
+	va_list arg;
+	uchar *p;
 
-void Sys_Printf (char *fmt, ...)
-{
-
-    va_list     argptr;
-    char        text[1024], *t_p;
-    int         l, r;
-
-	if (nostdout)
+	/* FIXME: does not work, fix your megashit code */
+	if(nostdout)
 		return;
+	va_start(arg, fmt);
+	vseprint(buf, buf+sizeof(buf), fmt, arg);
+	va_end(arg);
 
-    va_start (argptr,fmt);
-    vsprintf (text,fmt,argptr);
-    va_end (argptr);
-
-    l = strlen(text);
-    t_p = text;
-
-// make sure everything goes through, even though we are non-blocking
-    while (l)
-    {
-        r = write (1, text, l);
-        if (r != l)
-            sleep (0);
-        if (r > 0)
-        {
-            t_p += r;
-            l -= r;
-        }
-    }
-
-}
-*/
-
-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)
-        return;
-
-	for (p = (unsigned char *)text; *p; p++) {
+	for(p = (uchar *)buf; *p; p++){
 		*p &= 0x7f;
-		if ((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
-			printf("[%02x]", *p);
+		if((*p > 128 || *p < 32) && *p != 10 && *p != 13 && *p != 9)
+			print("[%02x]", *p);
 		else
-			putc(*p, stdout);
+			write(1, p, sizeof *p);
 	}
 }
 
-/*
-static char end1[] =
-"\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H                QUAKE: The Doomed Dimension \x1b[33mby \x1b[44mid\x1b[41m Software                      \x1b[2;1H  ----------------------------------------------------------------------------  \x1b[3;1H           CALL 1-800-IDGAMES TO ORDER OR FOR TECHNICAL SUPPORT                 \x1b[4;1H             PRICE: $45.00 (PRICES MAY VARY OUTSIDE THE US.)                    \x1b[5;1H                                                                                \x1b[6;1H  \x1b[37mYes! You only have one fourth of this incredible epic. That is because most   \x1b[7;1H   of you have paid us nothing or at most, very little. You could steal the     \x1b[8;1H   game from a friend. But we both know you'll be punished by God if you do.    \x1b[9;1H        \x1b[33mWHY RISK ETERNAL DAMNATION? CALL 1-800-IDGAMES AND BUY NOW!             \x1b[10;1H             \x1b[37mRemember, we love you almost as much as He does.                   \x1b[11;1H                                                                                \x1b[12;1H            \x1b[33mProgramming: \x1b[37mJohn Carmack, Michael Abrash, John Cash                \x1b[13;1H       \x1b[33mDesign: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits         \x1b[14;1H                     \x1b[33mArt: \x1b[37mAdrian Carmack, Kevin Cloud                           \x1b[15;1H               \x1b[33mBiz: \x1b[37mJay Wilbur, Mike Wilson, Donna Jackson                      \x1b[16;1H            \x1b[33mProjects: \x1b[37mShawn Green   \x1b[33mSupport: \x1b[37mBarrett Alexander                  \x1b[17;1H              \x1b[33mSound Effects: \x1b[37mTrent Reznor and Nine Inch Nails                   \x1b[18;1H  For other information or details on ordering outside the US, check out the    \x1b[19;1H     files accompanying QUAKE or our website at http://www.idsoftware.com.      \x1b[20;1H    \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc.        \x1b[21;1H     All rights reserved. NIN logo is a registered trademark licensed to        \x1b[22;1H                 Nothing Interactive, Inc. All rights reserved.                 \x1b[40m\x1b[23;1H\x1b[0m";
-static char end2[] =
-"\x1b[?7h\x1b[40m\x1b[2J\x1b[0;1;41m\x1b[1;1H        QUAKE \x1b[33mby \x1b[44mid\x1b[41m Software                                                    \x1b[2;1H -----------------------------------------------------------------------------  \x1b[3;1H        \x1b[37mWhy did you quit from the registered version of QUAKE? Did the          \x1b[4;1H        scary monsters frighten you? Or did Mr. Sandman tug at your             \x1b[5;1H        little lids? No matter! What is important is you love our               \x1b[6;1H        game, and gave us your money. Congratulations, you are probably         \x1b[7;1H        not a thief.                                                            \x1b[8;1H                                                           Thank You.           \x1b[9;1H        \x1b[33;44mid\x1b[41m Software is:                                                         \x1b[10;1H        PROGRAMMING: \x1b[37mJohn Carmack, Michael Abrash, John Cash                    \x1b[11;1H        \x1b[33mDESIGN: \x1b[37mJohn Romero, Sandy Petersen, American McGee, Tim Willits        \x1b[12;1H        \x1b[33mART: \x1b[37mAdrian Carmack, Kevin Cloud                                        \x1b[13;1H        \x1b[33mBIZ: \x1b[37mJay Wilbur, Mike Wilson     \x1b[33mPROJECTS MAN: \x1b[37mShawn Green              \x1b[14;1H        \x1b[33mBIZ ASSIST: \x1b[37mDonna Jackson        \x1b[33mSUPPORT: \x1b[37mBarrett Alexander             \x1b[15;1H        \x1b[33mSOUND EFFECTS AND MUSIC: \x1b[37mTrent Reznor and Nine Inch Nails               \x1b[16;1H                                                                                \x1b[17;1H        If you need help running QUAKE refer to the text files in the           \x1b[18;1H        QUAKE directory, or our website at http://www.idsoftware.com.           \x1b[19;1H        If all else fails, call our technical support at 1-800-IDGAMES.         \x1b[20;1H      \x1b[0;41mQuake is a trademark of Id Software, inc., (c)1996 Id Software, inc.      \x1b[21;1H        All rights reserved. NIN logo is a registered trademark licensed        \x1b[22;1H             to Nothing Interactive, Inc. All rights reserved.                  \x1b[23;1H\x1b[40m\x1b[0m";
-
-*/
 void Sys_Quit (void)
 {
 	Host_Shutdown();
-    fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
-	/*
-	if (registered.value)
-		printf("%s", end2);
-	else
-		printf("%s", end1);
-	*/
-	fflush(stdout);
-	exit(0);
+	//fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
+	exits(nil);
 }
 
-void Sys_Init(void)
+void Sys_Error (char *error, ...)
 {
-}
+	char buf[1024], *out;
+	va_list arg;
 
-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);
-    
-    va_start (argptr,error);
-    vsprintf (string,error,argptr);
-    va_end (argptr);
-	fprintf(stderr, "Error: %s\n", string);
-
-	Host_Shutdown ();
-	exit (1);
-
+	/* FIXME: does not work, fix your megashit code */
+	//fcntl (0, F_SETFL, fcntl (0, F_GETFL, 0) & ~FNDELAY);
+	out = seprint(buf, buf+sizeof(buf), "%s: ", argv0);
+	va_start(arg, error);
+	out = vseprint(out, buf+sizeof(buf), error, arg);
+	va_end(arg);
+	write(2, buf, out-buf);
+	/* FIXME: newline */
+	Host_Shutdown();
+	exits("ending");
 } 
 
-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)
+int Sys_FileTime (char *path)
 {
-	struct	stat	buf;
-	
-	if (stat (path,&buf) == -1)
+	/* FIXME: man 5 intro, man 2 stat, man 2 fcall */
+	uchar	sb[1024];
+
+	if(stat(path, sb, sizeof sb) < 0){
+		fprint(2, "%s stat %s: %r\n", argv0, path);
 		return -1;
-	
-	return buf.st_mtime;
+	}
+
+	/* FIXME */
+	return *((int *)(sb+25));
 }
 
-
 void Sys_mkdir (char *path)
 {
-    mkdir (path, 0777);
+	int	d;
+
+	if((d = create(path, OREAD, DMDIR|0777)) < 0)
+		fprint(2, "%s create %s: %r\n", argv0, path);
+	else
+		close(d);
 }
 
-int Sys_FileOpenRead (char *path, int *handle)
+vlong Sys_FileOpenRead (char *path, int *handle)
 {
-	int	h;
-	struct stat	fileinfo;
-    
-	
-	/*h = open (path, O_RDONLY, 0666);*/
-	h = open (path, OREAD);
-	*handle = h;
-	if (h == -1)
-		return -1;
-	
-	if (fstat (h,&fileinfo) == -1)
-		Sys_Error ("Error fstating %s", path);
+	int	d;
+	uchar	bs[1024];
 
-	return fileinfo.st_size;
+	d = open (path, OREAD);
+	*handle = d;
+	if(d < 0)
+		return -1;
+	if(fstat(d, bs, sizeof bs) < 0)
+		Sys_Error("%s fstat %s: %r", argv0, path);
+	/* FIXME */
+	return *((vlong *)(bs+33));
 }
 
 int Sys_FileOpenWrite (char *path)
 {
-	int     handle;
+	int     d;
 
-	umask (0);
-	
-	/*handle = open(path,O_RDWR | O_CREAT | O_TRUNC, 0666);*/
-	handle = open(path, OREAD);
-
-	if (handle == -1)
-		Sys_Error ("Error opening %s: %s", path,strerror(errno));
-
-	return handle;
+	if((d = open(path, OREAD|OTRUNC)) < 0)
+		Sys_Error("%s open %s: %r", argv0, path);
+	return d;
 }
 
 int Sys_FileWrite (int handle, void *src, int count)
 {
-	return write (handle, src, count);
+	return write(handle, src, count);
 }
 
 void Sys_FileClose (int handle)
 {
-	close (handle);
+	close(handle);
 }
 
 void Sys_FileSeek (int handle, int position)
 {
-	lseek (handle, position, SEEK_SET);
+	seek(handle, position, 0);
 }
 
 int Sys_FileRead (int handle, void *dest, int count)
 {
-    return read (handle, dest, count);
+	return read(handle, dest, count);
 }
 
-void Sys_DebugLog(char *file, char *fmt, ...)
-{
-    va_list argptr; 
-    static char data[1024];
-    int fd;
-    
-    va_start(argptr, fmt);
-    vsprintf(data, fmt, argptr);
-    va_end(argptr);
-//    fd = open(file, O_WRONLY | O_BINARY | O_CREAT | O_APPEND, 0666);
-    /*fd = open(file, O_WRONLY | O_CREAT | O_APPEND, 0666);*/
-	fd = open(file, OREAD);
-    write(fd, data, strlen(data));
-    close(fd);
-}
-
-void Sys_EditFile(char *filename)
-{
-
-	char cmd[256];
-	char *term;
-	char *editor;
-
-	term = getenv("TERM");
-	if (term && !strcmp(term, "xterm"))
-	{
-		editor = getenv("VISUAL");
-		if (!editor)
-			editor = getenv("EDITOR");
-		if (!editor)
-			editor = getenv("EDIT");
-		if (!editor)
-			editor = "vi";
-		sprintf(cmd, "xterm -e %s %s", editor, filename);
-		system(cmd);
-	}
-
-}
-
 double Sys_FloatTime (void)
 {
-    struct timeval tp;
-    struct timezone tzp; 
-    static int      secbase; 
-    
-    gettimeofday(&tp, &tzp);  
+	static long	secbase;
 
-    if (!secbase)
-    {
-        secbase = tp.tv_sec;
-        return tp.tv_usec/1000000.0;
-    }
-
-    return (tp.tv_sec - secbase) + tp.tv_usec/1000000.0;
+	if(secbase == 0)
+		secbase = time(nil);
+	return nsec()/1000000000.0 - secbase;
 }
 
-// =======================================================================
-// Sleeps for microseconds
-// =======================================================================
-
-static volatile int oktogo;
-
-void alarm_handler(int x)
-{
-	oktogo=1;
-}
-
-void Sys_LineRefresh(void)
-{
-}
-
-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;
+	static char	text[256];
+	int     len;
 
-	if (cls.state == ca_dedicated) {
-		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 < 1)
-			return NULL;
-		text[len-1] = 0;    // rip off the /n and terminate
-
+	if(cls.state == ca_dedicated){
+		if((len = read(0, text, sizeof(text))) < 1)
+			return nil;
+		text[len-1] = '\0';
 		return text;
 	}
-	return NULL;
+	return nil;
 }
 
 void Sys_HighFPPrecision (void)
@@ -350,20 +154,20 @@
 {
 }
 
+void Sys_LineRefresh (void)
+{
+}
+
 int main (int c, char **v)
 {
+	double	time, oldtime, newtime;
+	quakeparms_t	parms;
+	extern int	vcrFile;
+	extern int	recording;
+	int	j;
 
-	double		time, oldtime, newtime;
-	quakeparms_t parms;
-	extern int vcrFile;
-	extern int recording;
-	int j;
+	argv0 = *v;
 
-//	static char cwd[1024];
-
-//	signal(SIGFPE, floating_point_exception_handler);
-	signal(SIGFPE, SIG_IGN);
-
 	memset(&parms, 0, sizeof(parms));
 
 	COM_InitArgv(c, v);
@@ -372,80 +176,49 @@
 	parms.memsize = 8*1024*1024;
 
 	j = COM_CheckParm("-mem");
-	if (j)
-		parms.memsize = (int) (Q_atof(com_argv[j+1]) * 1024 * 1024);
-	parms.membase = malloc (parms.memsize);
+	if(j)
+		parms.memsize = (int)(Q_atof(com_argv[j+1]) * 1024*1024);
 
+	parms.membase = malloc(parms.memsize);
 	parms.basedir = basedir;
-// caching is disabled by default, use -cachedir to enable
-//	parms.cachedir = cachedir;
 
-	fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
+	//fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
 
-    Host_Init(&parms);
+	/* ignore fp exceptions (bad), rendering shit assumes they are */
+	setfcr(getfcr() & ~(FPOVFL|FPUNFL|FPINVAL|FPZDIV));	/* FIXME */
 
-	Sys_Init();
+	Host_Init(&parms);
 
-	if (COM_CheckParm("-nostdout"))
+	if(COM_CheckParm("-nostdout"))
 		nostdout = 1;
-	else {
-		fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
-		printf ("Linux Quake -- Version %0.3f\n", LINUX_VERSION);
+	else{
+		//fcntl(0, F_SETFL, fcntl (0, F_GETFL, 0) | FNDELAY);
+		print("(9)quake %4.2f\n", (float)VERSION);
 	}
 
-    oldtime = Sys_FloatTime () - 0.1;
-    while (1)
-    {
-// find time spent rendering last frame
-        newtime = Sys_FloatTime ();
-        time = newtime - oldtime;
+	oldtime = Sys_FloatTime () - 0.1;
+	for(;;){
+		// find time spent rendering last frame
+		newtime = Sys_FloatTime ();
+		time = newtime - oldtime;
 
-        if (cls.state == ca_dedicated)
-        {   // play vcrfiles at max speed
-            if (time < sys_ticrate.value && (vcrFile == -1 || recording) )
-            {
-				usleep(1);
-                continue;       // not time to run a server only tic yet
-            }
-            time = sys_ticrate.value;
-        }
+		if(cls.state == ca_dedicated){   // play vcrfiles at max speed
+			if(time < sys_ticrate.value && (vcrFile == -1 || recording)){
+				//usleep(1);
+				continue;       // not time to run a server only tic yet
+			}
+			time = sys_ticrate.value;
+        	}
 
-        if (time > sys_ticrate.value*2)
-            oldtime = newtime;
-        else
-            oldtime += time;
+		if(time > sys_ticrate.value*2)
+			oldtime = newtime;
+		else
+			oldtime += time;
 
-        Host_Frame (time);
+		Host_Frame(time);
 
-// graphic debugging aids
-        if (sys_linerefresh.value)
-            Sys_LineRefresh ();
-    }
-
+		// graphic debugging aids
+		if (sys_linerefresh.value)
+			Sys_LineRefresh ();
+	}
 }
-
-
-/*
-================
-Sys_MakeCodeWriteable
-================
-*/
-void Sys_MakeCodeWriteable (uintptr startaddr, uintptr length)
-{
-
-	int r;
-	uintptr 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");
-
-}
-
--- a/vid_9.c
+++ b/vid_9.c
@@ -1,680 +1,299 @@
-#define _BSD
-
 #include <u.h>
 #include <libc.h>
-//#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 <draw.h>
 #include "quakedef.h"
 #include "d_local.h"
 
-cvar_t		_windowed_mouse = {"_windowed_mouse","0", true};
-cvar_t		m_filter = {"m_filter","0", true};
-float old_windowed_mouse;
+extern int scr_fullupdate;
 
-qboolean        mouse_avail;
-int             mouse_buttons=3;
-int             mouse_oldbuttonstate;
-int             mouse_buttonstate;
-float   mouse_x, mouse_y;
-float   old_mouse_x, old_mouse_y;
-int p_mouse_x;
-int p_mouse_y;
+int config_notify;
 int ignorenext;
 int bits_per_pixel;
-
-typedef struct
-{
-	int input;
-	int output;
-} keymap_t;
-
-viddef_t vid; // global video state
+viddef_t vid;	// global video state
 unsigned short d_8to16table[256];
-
-int		num_shades=32;
-
-int	d_con_indirect = 0;
-
-int		vid_buffersize;
-
-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;
-
-static int				x_shmeventtype;
-//static XShmSegmentInfo	x_shminfo;
-
-static qboolean			oktodraw = false;
-
-int XShmQueryExtension(Display *);
-int XShmGetEventBase(Display *);
-
-int current_framebuffer;
-static XImage			*x_framebuffer[2] = { 0, 0 };
-static XShmSegmentInfo	x_shminfo[2];
-
-static int verbose=0;
-
-static byte current_palette[768];
-
-static int X11_highhunkmark;
-static int X11_buffersize;
-
+int d_con_indirect = 0;
+uchar *framebuf;	/* draw buffer */
+byte current_palette[768];
+int X11_highhunkmark;
+int X11_buffersize;
 int vid_surfcachesize;
 void *vid_surfcache;
+typedef u16int PIXEL16;
+typedef u32int PIXEL24;
+PIXEL16 st2d_8to16table[256];
+PIXEL24 st2d_8to24table[256];
+int shiftmask_fl = 0;
+int r_shift, g_shift, b_shift;
+uint r_mask, g_mask, b_mask;
+Point center;		/* of window */
+Rectangle grabout;	/* center mouse outside of this if cvar set */
 
 void (*vid_menudrawfn)(void);
 void (*vid_menukeyfn)(int key);
-void VID_MenuKey (int key);
 
-typedef unsigned short PIXEL16;
-typedef u32int PIXEL24;
-static PIXEL16 st2d_8to16table[256];
-static PIXEL24 st2d_8to24table[256];
-static int shiftmask_fl=0;
-static int r_shift,g_shift,b_shift;
-static uint r_mask,g_mask,b_mask;
 
-void shiftmask_init()
+void shiftmask_init (void)
 {
-    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;
+	uint x;
+
+	r_mask = 0xff0000;
+	g_mask = 0xff00;
+	b_mask = 0xff;
+	for(r_shift = -8, x = 1; x < r_mask; x <<= 1)
+		r_shift++;
+	for(g_shift = -8, x = 1; x < g_mask; x <<= 1)
+		g_shift++;
+	for(b_shift = -8, x = 1; x < b_mask; x <<= 1)
+		b_shift++;
+	shiftmask_fl = 1;
 }
 
-PIXEL16 xlib_rgb16(int r,int g,int b)
+PIXEL16 xlib_rgb16 (int r, int g, int b)
 {
-    PIXEL16 p;
-    if(shiftmask_fl==0) shiftmask_init();
-    p=0;
+	PIXEL16 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;
+	if(shiftmask_fl == 0)
+		shiftmask_init();
+	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;
 }
 
-PIXEL24 xlib_rgb24(int r,int g,int b)
+PIXEL24 xlib_rgb24 (int r, int g, int b)
 {
-    PIXEL24 p;
-    if(shiftmask_fl==0) shiftmask_init();
-    p=0;
+	PIXEL24 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;
+	if(shiftmask_fl == 0)
+		shiftmask_init();
+	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)
+void st2_fixup (uchar *data, int x, int y, int width, int height)
 {
-	int xi,yi;
-	unsigned char *src;
+	int yi;
+	uchar *src;
 	PIXEL16 *dest;
 	register int count, n;
 
-	if( (x<0)||(y<0) )return;
+	if(x < 0 || y < 0)
+		return;
 
-	for (yi = y; yi < (y+height); yi++) {
-		src = &framebuf->data [yi * framebuf->bytes_per_line];
+	for(yi = y; yi < y+height; yi++){
+		src = &data[yi*vid.rowbytes];
 
 		// Duff's Device
 		count = width;
-		n = (count + 7) / 8;
-		dest = ((PIXEL16 *)src) + x+width - 1;
-		src += x+width - 1;
+		n = (count+7) / 8;
+		dest = ((PIXEL16 *)src) + x+width-1;
+		src += x+width-1;
 
-		switch (count % 8) {
-		case 0:	do {	*dest-- = st2d_8to16table[*src--];
-		case 7:			*dest-- = st2d_8to16table[*src--];
-		case 6:			*dest-- = st2d_8to16table[*src--];
-		case 5:			*dest-- = st2d_8to16table[*src--];
-		case 4:			*dest-- = st2d_8to16table[*src--];
-		case 3:			*dest-- = st2d_8to16table[*src--];
-		case 2:			*dest-- = st2d_8to16table[*src--];
-		case 1:			*dest-- = st2d_8to16table[*src--];
-				} while (--n > 0);
+		switch(count % 8){
+		case 0:	do{	*dest-- = st2d_8to16table[*src--];
+		case 7:		*dest-- = st2d_8to16table[*src--];
+		case 6:		*dest-- = st2d_8to16table[*src--];
+		case 5:		*dest-- = st2d_8to16table[*src--];
+		case 4:		*dest-- = st2d_8to16table[*src--];
+		case 3:		*dest-- = st2d_8to16table[*src--];
+		case 2:		*dest-- = st2d_8to16table[*src--];
+		case 1:		*dest-- = st2d_8to16table[*src--];
+			}while(--n > 0);
 		}
-
-//		for(xi = (x+width-1); xi >= x; xi--) {
-//			dest[xi] = st2d_8to16table[src[xi]];
-//		}
+		//for(xi = x+width-1; xi >= x; xi--)
+		//	dest[xi] = st2d_8to16table[src[xi]];
 	}
 }
 
-void st3_fixup( XImage *framebuf, int x, int y, int width, int height)
+void st3_fixup (uchar *data, int x, int y, int width, int height)
 {
-	int xi,yi;
-	unsigned char *src;
+	int yi;
+	uchar *src;
 	PIXEL24 *dest;
 	register int count, n;
 
-	if( (x<0)||(y<0) )return;
+	if(x < 0 || y < 0)
+		return;
 
-	for (yi = y; yi < (y+height); yi++) {
-		src = &framebuf->data [yi * framebuf->bytes_per_line];
+	for(yi = y; yi < y+height; yi++){
+		src = &data[yi*vid.rowbytes];
 
 		// Duff's Device
 		count = width;
-		n = (count + 7) / 8;
-		dest = ((PIXEL24 *)src) + x+width - 1;
-		src += x+width - 1;
+		n = (count+7) / 8;
+		dest = ((PIXEL24 *)src) + x+width-1;
+		src += x+width-1;
 
 		switch (count % 8) {
-		case 0:	do {	*dest-- = st2d_8to24table[*src--];
-		case 7:			*dest-- = st2d_8to24table[*src--];
-		case 6:			*dest-- = st2d_8to24table[*src--];
-		case 5:			*dest-- = st2d_8to24table[*src--];
-		case 4:			*dest-- = st2d_8to24table[*src--];
-		case 3:			*dest-- = st2d_8to24table[*src--];
-		case 2:			*dest-- = st2d_8to24table[*src--];
-		case 1:			*dest-- = st2d_8to24table[*src--];
-				} while (--n > 0);
+		case 0:	do{	*dest-- = st2d_8to24table[*src--];
+		case 7:		*dest-- = st2d_8to24table[*src--];
+		case 6:		*dest-- = st2d_8to24table[*src--];
+		case 5:		*dest-- = st2d_8to24table[*src--];
+		case 4:		*dest-- = st2d_8to24table[*src--];
+		case 3:		*dest-- = st2d_8to24table[*src--];
+		case 2:		*dest-- = st2d_8to24table[*src--];
+		case 1:		*dest-- = st2d_8to24table[*src--];
+			}while(--n > 0);
 		}
-
-//		for(xi = (x+width-1); xi >= x; xi--) {
-//			dest[xi] = st2d_8to16table[src[xi]];
-//		}
+		//for(xi = x+width-1; xi >= x; xi--)
+		//	dest[xi] = st2d_8to16table[src[xi]];
 	}
 }
 
-
-// ========================================================================
-// Tragic death handler
-// ========================================================================
-
-void TragicDeath(int signal_num)
+void ResetFrameBuffer (void)
 {
-	XAutoRepeatOn(x_disp);
-	XCloseDisplay(x_disp);
-	Sys_Error("This death brought to you by the number %d\n", signal_num);
-}
-
-// ========================================================================
-// 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]);
+	if(framebuf)
+		free(framebuf);
+	if(d_pzbuffer){
+		D_FlushCaches();
+		Hunk_FreeToHighMark(X11_highhunkmark);
+		d_pzbuffer = nil;
 	}
+	X11_highhunkmark = Hunk_HighMark();
 
-	if (d_pzbuffer)
-	{
-		D_FlushCaches ();
-		Hunk_FreeToHighMark (X11_highhunkmark);
-		d_pzbuffer = NULL;
-	}
-	X11_highhunkmark = Hunk_HighMark ();
-
-// alloc an extra line in case we want to wrap, and allocate the z-buffer
-	X11_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
-
-	vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height);
-
+	// alloc an extra line in case we want to wrap, and allocate the z-buffer
+	X11_buffersize = vid.width * vid.height * sizeof(*d_pzbuffer);
+	vid_surfcachesize = D_SurfaceCacheForRes(vid.width, vid.height);
 	X11_buffersize += vid_surfcachesize;
 
-	d_pzbuffer = Hunk_HighAllocName (X11_buffersize, "video");
-	if (d_pzbuffer == NULL)
-		Sys_Error ("Not enough memory for video mode\n");
+	d_pzbuffer = Hunk_HighAllocName(X11_buffersize, "video");
+	if(d_pzbuffer == nil)
+		Sys_Error("Not enough memory for video mode\n");
 
-	vid_surfcache = (byte *) d_pzbuffer
-		+ vid.width * vid.height * sizeof (*d_pzbuffer);
+	vid_surfcache = (byte *)d_pzbuffer + vid.width * vid.height * sizeof(*d_pzbuffer);
 
 	D_InitCaches(vid_surfcache, vid_surfcachesize);
 
-	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]);
+	framebuf = malloc(sizeof *framebuf * Dx(screen->r) * Dy(screen->r) * screen->depth/8);
+	vid.buffer = framebuf;
 	vid.conbuffer = vid.buffer;
-
 }
 
-void ResetSharedFrameBuffers(void)
-{
-
-	int size;
-	int key;
-	int minsize = getpagesize();
-	int frm;
-
-	if (d_pzbuffer)
-	{
-		D_FlushCaches ();
-		Hunk_FreeToHighMark (X11_highhunkmark);
-		d_pzbuffer = NULL;
-	}
-
-	X11_highhunkmark = Hunk_HighMark ();
-
-// alloc an extra line in case we want to wrap, and allocate the z-buffer
-	X11_buffersize = vid.width * vid.height * sizeof (*d_pzbuffer);
-
-	vid_surfcachesize = D_SurfaceCacheForRes (vid.width, vid.height);
-
-	X11_buffersize += vid_surfcachesize;
-
-	d_pzbuffer = Hunk_HighAllocName (X11_buffersize, "video");
-	if (d_pzbuffer == NULL)
-		Sys_Error ("Not enough memory for video mode\n");
-
-	vid_surfcache = (byte *) d_pzbuffer
-		+ vid.width * vid.height * sizeof (*d_pzbuffer);
-
-	D_InitCaches(vid_surfcache, vid_surfcachesize);
-
-	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);
-
-		printf("VID: shared memory id=%d, addr=0x%p\n", x_shminfo[frm].shmid,
-			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);
-
-	}
-
-}
-
 // Called at startup to set up translation tables, takes 256 8 bit RGB values
 // the palette data will go away after the call, so it must be copied off if
 // the video driver will need it again
 
-void	VID_Init (unsigned char *palette)
+void VID_Init (unsigned char *palette)
 {
+	int pnum;
 
-   int pnum, i;
-   XVisualInfo template;
-   int num_visuals;
-   int template_mask;
-   
-   ignorenext=0;
-   vid.width = 320;
-   vid.height = 200;
-   vid.maxwarpwidth = WARP_WIDTH;
-   vid.maxwarpheight = WARP_HEIGHT;
-   vid.numpages = 2;
-   vid.colormap = host_colormap;
-   //	vid.cbits = VID_CBITS;
-   //	vid.grades = VID_GRADES;
-   vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
-   
-	srandom(getpid());
+	ignorenext = 0;
+	//vid.width = 320;
+	//vid.height = 200;
+	vid.width = -1;
+	vid.height = -1;
+	vid.maxwarpwidth = WARP_WIDTH;
+	vid.maxwarpheight = WARP_HEIGHT;
+	vid.numpages = 2;
+	vid.colormap = host_colormap;
+	//vid.cbits = VID_CBITS;
+	//vid.grades = VID_GRADES;
+	vid.fullbright = 256 - LittleLong(*((int *)vid.colormap + 2048));
 
-	verbose=COM_CheckParm("-verbose");
+	srand(getpid());	/* glibc srandom() affects rand() too, right? */
 
-// 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);
-	}
-
-	XAutoRepeatOff(x_disp);
-
-// for debugging only
-	XSynchronize(x_disp, True);
-
-// check for command-line window size
-	if ((pnum=COM_CheckParm("-winsize")))
-	{
-		if (pnum >= com_argc-2)
+	if(pnum = COM_CheckParm("-winsize")){
+		if(pnum >= com_argc-2)
 			Sys_Error("VID: -winsize <width> <height>\n");
 		vid.width = Q_atoi(com_argv[pnum+1]);
 		vid.height = Q_atoi(com_argv[pnum+2]);
-		if (!vid.width || !vid.height)
+		if(!vid.width || !vid.height)
 			Sys_Error("VID: Bad window width/height\n");
 	}
-	if ((pnum=COM_CheckParm("-width"))) {
-		if (pnum >= com_argc-1)
+	if(pnum = COM_CheckParm("-width")){
+		if(pnum >= com_argc-1)
 			Sys_Error("VID: -width <width>\n");
 		vid.width = Q_atoi(com_argv[pnum+1]);
-		if (!vid.width)
+		if(!vid.width)
 			Sys_Error("VID: Bad window width\n");
 	}
-	if ((pnum=COM_CheckParm("-height"))) {
-		if (pnum >= com_argc-1)
+	if(pnum = COM_CheckParm("-height")){
+		if(pnum >= com_argc-1)
 			Sys_Error("VID: -height <height>\n");
 		vid.height = Q_atoi(com_argv[pnum+1]);
-		if (!vid.height)
+		if(!vid.height)
 			Sys_Error("VID: Bad window height\n");
 	}
 
-	template_mask = 0;
+	if(initdraw(nil, nil, "quake") < 0)
+		Sys_Error("%s initdraw: %r", argv0);
 
-// 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(vid.width == -1)
+		vid.width = Dx(screen->r);
+	if(vid.height == -1)
+		vid.height = Dy(screen->r);
 
-// If not specified, use default visual
-	else
-	{
-		int screen;
-		screen = XDefaultScreen(x_disp);
-		template.visualid =
-			XVisualIDFromVisual(XDefaultVisual(x_disp, screen));
-		template_mask = VisualIDMask;
-	}
+	/* TODO: resize properly if -winsize,.. params provided, draw centered */
 
-// 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 (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);
-	}
-
-	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 = StructureNotifyMask | KeyPressMask
-	     | KeyReleaseMask | ExposureMask | PointerMotionMask |
-	     ButtonPressMask | ButtonReleaseMask;
-	   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,"xquake");
-
-
-		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);
-			VID_SetPalette(palette);
-			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;
+	if(screen->chan == CMAP8)
+		VID_SetPalette(palette);
+	ResetFrameBuffer();
+	center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
+	grabout = insetrect(screen->r, Dx(screen->r)/8);
+	vid.rowbytes = Dx(screen->r) * screen->depth/8;
+	vid.buffer = framebuf;
 	vid.direct = 0;
-	vid.conbuffer = x_framebuffer[0]->data;
+	vid.conbuffer = framebuf;
 	vid.conrowbytes = vid.rowbytes;
 	vid.conwidth = vid.width;
 	vid.conheight = vid.height;
-	vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
+	/* FIXME */
+	vid.aspect = (float)vid.height / (float)vid.width * (320.0/240.0);
 
-//	XSynchronize(x_disp, False);
-
+	draw(screen, screen->r, display->black, nil, ZP);
 }
 
-void VID_ShiftPalette(unsigned char *p)
+void VID_ShiftPalette (unsigned char *p)
 {
 	VID_SetPalette(p);
 }
 
-
-
-void VID_SetPalette(unsigned char *palette)
+void VID_SetPalette (unsigned char *palette)
 {
-
 	int i;
-	XColor colors[256];
 
-	for(i=0;i<256;i++) {
-		st2d_8to16table[i]= xlib_rgb16(palette[i*3], palette[i*3+1],palette[i*3+2]);
-		st2d_8to24table[i]= xlib_rgb24(palette[i*3], palette[i*3+1],palette[i*3+2]);
+	for(i = 0; i < 256; i++){
+		st2d_8to16table[i] = xlib_rgb16(palette[i*3], palette[i*3+1], palette[i*3+2]);
+		st2d_8to24table[i] = xlib_rgb24(palette[i*3], palette[i*3+1], palette[i*3+2]);
 	}
-
-	if (x_visinfo->class == PseudoColor && x_visinfo->depth == 8)
-	{
-		if (palette != current_palette)
+	if(screen->chan == 8){
+		if(palette != current_palette)
 			memcpy(current_palette, palette, 768);
-		for (i=0 ; i<256 ; i++)
-		{
+		/* FIXME
+		XColor colors[256];
+		for(i = 0 ; i < 256 ; i++){
 			colors[i].pixel = i;
 			colors[i].flags = DoRed|DoGreen|DoBlue;
 			colors[i].red = palette[i*3] * 257;
@@ -682,474 +301,82 @@
 			colors[i].blue = palette[i*3+2] * 257;
 		}
 		XStoreColors(x_disp, x_cmap, colors, 256);
+		*/
 	}
 
 }
 
-// Called at shutdown
-
-void	VID_Shutdown (void)
+void VID_Shutdown (void)
 {
 	Con_Printf("VID_Shutdown\n");
-	XAutoRepeatOn(x_disp);
-	XCloseDisplay(x_disp);
 }
 
-int XLateKey(XKeyEvent *ev)
+/* flush given rectangles from view buffer to the screen */
+void VID_Update (vrect_t *rects)
 {
+	Rectangle svr, dr;
+	Image *im;
 
-	int key;
-	char buf[64];
-	KeySym keysym;
-
-	key = 0;
-
-	XLookupString(ev, buf, sizeof buf, &keysym, 0);
-
-	switch(keysym)
-	{
-		case XK_KP_Page_Up:
-		case XK_Page_Up:	 key = K_PGUP; break;
-
-		case XK_KP_Page_Down:
-		case XK_Page_Down:	 key = K_PGDN; break;
-
-		case XK_KP_Home:
-		case XK_Home:	 key = K_HOME; break;
-
-		case XK_KP_End:
-		case XK_End:	 key = K_END; break;
-
-		case XK_KP_Left:
-		case XK_Left:	 key = K_LEFTARROW; break;
-
-		case XK_KP_Right:
-		case XK_Right:	key = K_RIGHTARROW;		break;
-
-		case XK_KP_Down:
-		case XK_Down:	 key = K_DOWNARROW; break;
-
-		case XK_KP_Up:
-		case XK_Up:		 key = K_UPARROW;	 break;
-
-		case XK_Escape: key = K_ESCAPE;		break;
-
-		case XK_KP_Enter:
-		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:
-		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_AUX30;	break;
-
-		case XK_Insert:
-		case XK_KP_Insert: key = K_INS; break;
-
-		case XK_KP_Multiply: key = '*'; break;
-		case XK_KP_Add: key = '+'; break;
-		case XK_KP_Subtract: key = '-'; break;
-		case XK_KP_Divide: key = '/'; break;
-		default:
-			key = *(unsigned char*)buf;
-			if (key >= 'A' && key <= 'Z')
-				key = key - 'A' + 'a';
-//			fprintf(stdout, "case 0x0%x: key = ___;break;/* [%c] */\n", keysym);
-			break;
-	} 
-
-	return key;
-}
-
-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;
-						      
-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) {
-			mouse_x = (float) ((int)x_event.xmotion.x - (int)(vid.width/2));
-			mouse_y = (float) ((int)x_event.xmotion.y - (int)(vid.height/2));
-//printf("m: x=%d,y=%d, mx=%3.2f,my=%3.2f\n", 
-//	x_event.xmotion.x, x_event.xmotion.y, mouse_x, mouse_y);
-
-			/* move the mouse to the window center again */
-			XSelectInput(x_disp,x_win,StructureNotifyMask|KeyPressMask
-				|KeyReleaseMask|ExposureMask
-				|ButtonPressMask
-				|ButtonReleaseMask);
-			XWarpPointer(x_disp,None,x_win,0,0,0,0, 
-				(vid.width/2),(vid.height/2));
-			XSelectInput(x_disp,x_win,StructureNotifyMask|KeyPressMask
-				|KeyReleaseMask|ExposureMask
-				|PointerMotionMask|ButtonPressMask
-				|ButtonReleaseMask);
-		} else {
-			mouse_x = (float) (x_event.xmotion.x-p_mouse_x);
-			mouse_y = (float) (x_event.xmotion.y-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:
-//printf("config notify\n");
-		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);
-		}
-	}
-}
-
-// flushes the given rectangles from the view buffer to the screen
-
-void	VID_Update (vrect_t *rects)
-{
-	vrect_t full;
-
-// if the window changes dimension, skip this frame
-
-	if (config_notify)
-	{
-		fprintf(stderr, "config notify\n");
+	if(config_notify){		/* skip this frame if window resize */
 		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.conbuffer = vid.buffer;
+		if(getwindow(display, Refnone) < 0)
+			Sys_Error("%s getwindow: %r", argv0);
+		vid.width = Dx(screen->r);
+		vid.height = Dy(screen->r);
+		ResetFrameBuffer();
+		center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
+		grabout = insetrect(screen->r, Dx(screen->r)/8);
+		vid.rowbytes = vid.width * screen->depth/8;
+		vid.buffer = framebuf;
+		vid.conbuffer = framebuf;
 		vid.conwidth = vid.width;
 		vid.conheight = vid.height;
 		vid.conrowbytes = vid.rowbytes;
-		vid.recalc_refdef = 1;				// force a surface cache flush
+		vid.recalc_refdef = 1;			// force a surface cache flush
+		draw(screen, screen->r, display->black, nil, ZP);
 		Con_CheckResize();
 		Con_Clear_f();
 		return;
 	}
 
-	// force full update if not 8bit
-	if (x_visinfo->depth != 8) {
-		extern int scr_fullupdate;
-
+	if(screen->chan != CMAP8)	/* force full update if not 8bit */
 		scr_fullupdate = 0;
-	}
 
+	/* FIXME: seems to crash later with DBlack rather than DNofill, why? */
+	im = allocimage(display, Rect(0, 0, vid.width, vid.height), screen->chan, 1, DNofill);
 
-	if (doShm)
-	{
+	svr = screen->clipr;
+	while(rects){
+		if(screen->chan == RGB16)
+			st2_fixup(framebuf, rects->x, rects->y,
+				rects->width, rects->height);
+		/* FIXME: ??? just assume truecolor? (not RGB16 or CMAP8) */
+		else if(screen->chan == RGB24 || screen->chan == RGBA32 || screen->chan == XRGB32)
+			st3_fixup(framebuf, rects->x, rects->y,
+				rects->width, rects->height);
 
-		while (rects)
-		{
-			if (x_visinfo->depth == 16)
-				st2_fixup( x_framebuffer[current_framebuffer], 
-					rects->x, rects->y, rects->width,
-					rects->height);
-			else if (x_visinfo->depth == 24)
-				st3_fixup( x_framebuffer[current_framebuffer], 
-					rects->x, rects->y, rects->width,
-					rects->height);
-			if (!XShmPutImage(x_disp, x_win, x_gc,
-				x_framebuffer[current_framebuffer], rects->x, rects->y,
-				rects->x, rects->y, rects->width, rects->height, True))
-					Sys_Error("VID_Update: XShmPutImage failed\n");
-			oktodraw = false;
-			while (!oktodraw) GetEvent();
-			rects = rects->pnext;
-		}
-		current_framebuffer = !current_framebuffer;
-		vid.buffer = x_framebuffer[current_framebuffer]->data;
-		vid.conbuffer = vid.buffer;
-		XSync(x_disp, False);
+		/* FIXME */
+		//loadimage(im, im->r, &framebuf[rects->x*vid.rowbytes];
+		loadimage(im, im->r, framebuf, vid.height * vid.rowbytes);
+		dr = Rpt(addpt(screen->r.min, Pt(rects->x, rects->y)),
+			addpt(screen->r.min, Pt(rects->x+rects->width, rects->y+rects->height)));
+		//replclipr(screen, 0, dr);	/* FIXME: necessary? */
+		draw(screen, dr, im, nil, ZP);
+		rects = rects->pnext;
 	}
-	else
-	{
-		while (rects)
-		{
-			if (x_visinfo->depth == 16)
-				st2_fixup( x_framebuffer[current_framebuffer], 
-					rects->x, rects->y, rects->width,
-					rects->height);
-			else if (x_visinfo->depth == 24)
-				st3_fixup( x_framebuffer[current_framebuffer], 
-					rects->x, rects->y, rects->width,
-					rects->height);
-			XPutImage(x_disp, x_win, x_gc, x_framebuffer[0], rects->x,
-				rects->y, rects->x, rects->y, rects->width, rects->height);
-			rects = rects->pnext;
-		}
-		XSync(x_disp, False);
-	}
-
+	replclipr(screen, 0, svr);
+	freeimage(im);
+	flushimage(display, 1);
 }
 
-static int dither;
-
-void VID_DitherOn(void)
-{
-    if (dither == 0)
-    {
-		vid.recalc_refdef = 1;
-        dither = 1;
-    }
-}
-
-void VID_DitherOff(void)
-{
-    if (dither)
-    {
-		vid.recalc_refdef = 1;
-        dither = 0;
-    }
-}
-
-int Sys_OpenWindow(void)
-{
-	return 0;
-}
-
-void Sys_EraseWindow(int window)
-{
-}
-
-void Sys_DrawCircle(int window, int x, int y, int r)
-{
-}
-
-void Sys_DisplayWindow(int window)
-{
-}
-
-void Sys_SendKeyEvents(void)
-{
-// get events from x server
-	if (x_disp)
-	{
-		while (XPending(x_disp)) GetEvent();
-		while (keyq_head != keyq_tail)
-		{
-			Key_Event(keyq[keyq_tail].key, keyq[keyq_tail].down);
-			keyq_tail = (keyq_tail + 1) & 63;
-		}
-	}
-}
-
-/*
-char *Sys_ConsoleInput (void)
-{
-
-	static char	text[256];
-	int		len;
-	fd_set  readfds;
-	int		ready;
-	struct timeval timeout;
-
-	timeout.tv_sec = 0;
-	timeout.tv_usec = 0;
-	FD_ZERO(&readfds);
-	FD_SET(0, &readfds);
-	ready = select(1, &readfds, 0, 0, &timeout);
-
-	if (ready>0)
-	{
-		len = read (0, text, sizeof(text));
-		if (len >= 1)
-		{
-			text[len-1] = 0;	// rip off the /n and terminate
-			return text;
-		}
-	}
-
-	return 0;
-	
-}
-*/
-
 void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
 {
-// direct drawing of the "accessing disk" icon isn't supported under Linux
+	// direct drawing of the "accessing disk" icon isn't supported under Linux
+	USED(x, y, pbitmap, width, height);
 }
 
 void D_EndDirectRect (int x, int y, int width, int height)
 {
-// direct drawing of the "accessing disk" icon isn't supported under Linux
-}
-
-void IN_Init (void)
-{
-	Cvar_RegisterVariable (&_windowed_mouse);
-	Cvar_RegisterVariable (&m_filter);
-   if ( COM_CheckParm ("-nomouse") )
-     return;
-   mouse_x = mouse_y = 0.0;
-   mouse_avail = 1;
-}
-
-void IN_Shutdown (void)
-{
-   mouse_avail = 0;
-}
-
-void IN_Commands (void)
-{
-	int i;
-   
-	if (!mouse_avail) return;
-   
-	for (i=0 ; i<mouse_buttons ; i++) {
-		if ( (mouse_buttonstate & (1<<i)) && !(mouse_oldbuttonstate & (1<<i)) )
-			Key_Event (K_MOUSE1 + i, true);
-
-		if ( !(mouse_buttonstate & (1<<i)) && (mouse_oldbuttonstate & (1<<i)) )
-			Key_Event (K_MOUSE1 + i, false);
-	}
-	mouse_oldbuttonstate = mouse_buttonstate;
-}
-
-void IN_Move (usercmd_t *cmd)
-{
-	if (!mouse_avail)
-		return;
-   
-	if (m_filter.value) {
-		mouse_x = (mouse_x + old_mouse_x) * 0.5;
-		mouse_y = (mouse_y + old_mouse_y) * 0.5;
-	}
-
-	old_mouse_x = mouse_x;
-	old_mouse_y = mouse_y;
-   
-	mouse_x *= sensitivity.value;
-	mouse_y *= sensitivity.value;
-   
-	if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
-		cmd->sidemove += m_side.value * mouse_x;
-	else
-		cl.viewangles[YAW] -= m_yaw.value * mouse_x;
-	if (in_mlook.state & 1)
-		V_StopPitchDrift ();
-   
-	if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) {
-		cl.viewangles[PITCH] += m_pitch.value * mouse_y;
-		if (cl.viewangles[PITCH] > 80)
-			cl.viewangles[PITCH] = 80;
-		if (cl.viewangles[PITCH] < -70)
-			cl.viewangles[PITCH] = -70;
-	} else {
-		if ((in_strafe.state & 1) && noclip_anglehack)
-			cmd->upmove -= m_forward.value * mouse_y;
-		else
-			cmd->forwardmove -= m_forward.value * mouse_y;
-	}
-	mouse_x = mouse_y = 0.0;
+	// direct drawing of the "accessing disk" icon isn't supported under Linux
+	USED(x, y, width, height);
 }