diff --git a/src/Makefile b/src/Makefile
index 7e006d2..1f6affa 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@ CXX=g++
 CXXOPTFLAGS=-Wall -O3 -fsigned-char -fomit-frame-pointer
 CXXFLAGS=$(CXXOPTFLAGS) -I../enet/include `sdl-config --cflags`
 
-CLIENT_LIBS=-L../enet -lenet `sdl-config --libs` -lSDL_image -lSDL_mixer -lz -lGL -lGLU 
+CLIENT_LIBS=-L../enet -lenet `sdl-config --libs` -lSDL_image -lSDL_mixer -lz -lGL -lGLU -lhid 
 CLIENT_OBJS= \
 	client.o \
 	clientextras.o \
diff --git a/src/clientextras.cpp b/src/clientextras.cpp
index 7104217..9b5cb18 100644
--- a/src/clientextras.cpp
+++ b/src/clientextras.cpp
@@ -14,11 +14,11 @@ void renderclient(dynent *d, bool team, char *mdlname, bool hellpig, float scale
     int n = 3;
     float speed = 100.0f;
     float mz = d->o.z-d->eyeheight+1.55f*scale;
-    int basetime = -((int)d&0xFFF);
+    int basetime = -((int)(size_t)d&0xFFF);
     if(d->state==CS_DEAD)
     {
         int r;
-        if(hellpig) { n = 2; r = range[3]; } else { n = (int)d%3; r = range[n]; };
+        if(hellpig) { n = 2; r = range[3]; } else { n = (int)(size_t)d%3; r = range[n]; };
         basetime = d->lastaction;
         int t = lastmillis-d->lastaction;
         if(t<0 || t>20000) return;
diff --git a/src/clientgame.cpp b/src/clientgame.cpp
index 9a1fd3c..83787ff 100644
--- a/src/clientgame.cpp
+++ b/src/clientgame.cpp
@@ -322,6 +322,7 @@ COMMANDN(jump, jumpn, ARG_DOWN);
 COMMAND(attack, ARG_DOWN);
 COMMAND(showscores, ARG_DOWN);
 
+
 void fixplayer1range()
 {
     const float MAXPITCH = 90.0f;
@@ -329,6 +330,8 @@ void fixplayer1range()
     if(player1->pitch<-MAXPITCH) player1->pitch = -MAXPITCH;
     while(player1->yaw<0.0f) player1->yaw += 360.0f;
     while(player1->yaw>=360.0f) player1->yaw -= 360.0f;
+    while(player1->roll<-180.0f) player1->roll += 360.0f;
+    while(player1->roll>=180.0f) player1->roll -= 360.0f;
 };
 
 void mousemove(int dx, int dy)
@@ -337,9 +340,66 @@ void mousemove(int dx, int dy)
     const float SENSF = 33.0f;     // try match quake sens
     player1->yaw += (dx/SENSF)*(sensitivity/(float)sensitivityscale);
     player1->pitch -= (dy/SENSF)*(sensitivity/(float)sensitivityscale)*(invmouse ? -1 : 1);
-	fixplayer1range();
+    fixplayer1range();
 };
 
+HIDInterface* hid;
+
+void spacepointinit()
+{
+    hid_return ret;
+    HIDInterfaceMatcher matcher = { 0x20ff, 0x0100, NULL, NULL, 0 };
+    
+    ret = hid_init();
+    if (ret != HID_RET_SUCCESS) {
+        fprintf(stderr, "hid_init failed with return code %d\n", ret);
+        return;
+    }
+    
+    hid = hid_new_HIDInterface();
+    if (hid == 0) {
+        fprintf(stderr, "hid_new_HIDInterface() failed, out of memory?\n");
+        return;
+    }
+    
+    ret = hid_force_open(hid, 1, &matcher, 3);
+    if (ret != HID_RET_SUCCESS) {
+        ret = hid_force_open(hid, 0, &matcher, 3);
+    }
+    if (ret != HID_RET_SUCCESS) {
+        fprintf(stderr, "hid_force_open failed with return code %d.\n", ret);
+        return;
+    }
+}
+
+void spacepointmove()
+{
+    if (hid == 0 || player1->state==CS_DEAD || intermission) return;
+    
+    char data[15];
+    memset(data, 0, sizeof(data)); 
+    hid_return ret = hid_interrupt_read(hid,0x82,data,15,0);
+    if (ret != HID_RET_SUCCESS) {
+        fprintf(stderr, "hid_interrupt_read failed with return code %d.\n", ret);
+        return;
+    }
+    
+    float qx = (((unsigned char)data[6]|((unsigned char)data[7]<<8))-32768)/32768.0f;
+    float qy = (((unsigned char)data[8]|((unsigned char)data[9]<<8))-32768)/32768.0f;
+    float qz = (((unsigned char)data[10]|((unsigned char)data[11]<<8))-32768)/32768.0f;
+    float qw = (((unsigned char)data[12]|((unsigned char)data[13]<<8))-32768)/32768.0f;
+    
+    float sqx = qx*qx;
+    float sqy = qy*qy;
+    float sqz = qz*qz;
+    float sqw = qw*qw;
+    
+    player1->yaw = (180.0f/M_PI)*atan2(2.0f * (qx*qy + qz*qw),(sqx - sqy - sqz + sqw));
+    player1->pitch = (180.0f/M_PI)*asin(-2.0f * (qx*qz - qy*qw));
+    player1->roll = (180.0f/M_PI)*atan2(2.0f * (qy*qz + qx*qw),(-sqx - sqy + sqz + sqw));
+    fixplayer1range();
+}
+
 // damage arriving from the network, monsters, yourself, all ends up here.
 
 void selfdamage(int damage, int actor, dynent *act)
@@ -351,8 +411,9 @@ void selfdamage(int damage, int actor, dynent *act)
     if(ad>player1->armour) ad = player1->armour;
     player1->armour -= ad;
     damage -= ad;
-    float droll = damage/0.5f;
-    player1->roll += player1->roll>0 ? droll : (player1->roll<0 ? -droll : (rnd(2) ? droll : -droll));  // give player a kick depending on amount of damage
+//    float droll = damage/0.5f;
+//    player1->roll += player1->roll>0 ? droll : (player1->roll<0 ? -droll : (rnd(2) ? droll : -droll));  // give player a kick depending on amount of damage
+    damage = 0;
     if((player1->health -= damage)<=0)
     {
         if(actor==-2)
@@ -427,6 +488,7 @@ dynent *getclient(int cn)   // ensure valid entity
 void initclient()
 {
     clientmap[0] = 0;
+    spacepointinit();
     initclientnet();
 };
 
diff --git a/src/main.cpp b/src/main.cpp
index 6a13729..2758698 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -42,7 +42,7 @@ void *alloc(int s)              // for some big chunks... most other allocs use
     return b;
 };
 
-int scr_w = 640;
+int scr_w = 848;
 int scr_h = 480;
 
 void screenshot()
@@ -193,6 +193,7 @@ int main(int argc, char **argv)
         readdepth(scr_w, scr_h);
         SDL_GL_SwapBuffers();
         extern void updatevol(); updatevol();
+        spacepointmove();
         if(framesinmap++<5)	// cheap hack to get rid of initial sparklies, even when triple buffering etc.
         {
 			player1->yaw += 5;
@@ -215,10 +216,10 @@ int main(int argc, char **argv)
                     keypress(event.key.keysym.sym, event.key.state==SDL_PRESSED, event.key.keysym.unicode);
                     break;
 
-                case SDL_MOUSEMOTION:
-                    if(ignore) { ignore--; break; };
-                    mousemove(event.motion.xrel, event.motion.yrel);
-                    break;
+//                case SDL_MOUSEMOTION:
+//                    if(ignore) { ignore--; break; };
+//                    mousemove(event.motion.xrel, event.motion.yrel);
+//                    break;
 
                 case SDL_MOUSEBUTTONDOWN:
                 case SDL_MOUSEBUTTONUP:
diff --git a/src/physics.cpp b/src/physics.cpp
index 9d6f27d..ac94e0d 100644
--- a/src/physics.cpp
+++ b/src/physics.cpp
@@ -298,16 +298,16 @@ void moveplayer(dynent *pl, int moveres, bool local, int curtime)
     
     // automatically apply smooth roll when strafing
 
-    if(pl->strafe==0) 
-    {
-        pl->roll = pl->roll/(1+(float)sqrt((float)curtime)/25);
-    }
-    else
-    {
-        pl->roll += pl->strafe*curtime/-30.0f;
-        if(pl->roll>maxroll) pl->roll = (float)maxroll;
-        if(pl->roll<-maxroll) pl->roll = (float)-maxroll;
-    };
+//    if(pl->strafe==0) 
+//    {
+//        pl->roll = pl->roll/(1+(float)sqrt((float)curtime)/25);
+//    }
+//    else
+//    {
+//        pl->roll += pl->strafe*curtime/-30.0f;
+//        if(pl->roll>maxroll) pl->roll = (float)maxroll;
+//        if(pl->roll<-maxroll) pl->roll = (float)-maxroll;
+//    };
     
     // play sounds on water transitions
     
diff --git a/src/protos.h b/src/protos.h
index b6a9a3c..8701b4e 100644
--- a/src/protos.h
+++ b/src/protos.h
@@ -18,7 +18,7 @@ extern void writecfg();
 // console
 extern void keypress(int code, bool isdown, int cooked);
 extern void renderconsole();
-extern void conoutf(const char *s, ...);
+extern void conoutf(const char *s, ...);
 extern char *getcurcommand();
 extern void writebinds(FILE *f);
 
@@ -76,6 +76,7 @@ extern void writeclientinfo(FILE *f);
 
 // clientgame
 extern void mousemove(int dx, int dy); 
+extern void spacepointmove();
 extern void updateworld(int millis);
 extern void startmap(char *name);
 extern void changemap(char *name);
@@ -130,7 +131,7 @@ extern void keyrepeat(bool on);
 
 // rendertext
 extern void draw_text(char *str, int left, int top, int gl_num);
-extern void draw_textf(char *fstr, int left, int top, int gl_num, ...);
+extern void draw_textf(char *fstr, int left, int top, int gl_num, ...);
 extern int text_width(char *str);
 extern void draw_envbox(int t, int fogdist);
 
diff --git a/src/server.cpp b/src/server.cpp
index 94e02a5..5f10c25 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -397,15 +397,15 @@ void serverslice(int seconds, unsigned int timeout)   // main server update, cal
             }
             case ENET_EVENT_TYPE_RECEIVE:
                 brec += event.packet->dataLength;
-                process(event.packet, (int)event.peer->data); 
+                process(event.packet, (int)(size_t)event.peer->data); 
                 if(event.packet->referenceCount==0) enet_packet_destroy(event.packet);
                 break;
 
             case ENET_EVENT_TYPE_DISCONNECT: 
-                if((int)event.peer->data<0) break;
-                printf("disconnected client (%s)\n", clients[(int)event.peer->data].hostname);
-                clients[(int)event.peer->data].type = ST_EMPTY;
-                send2(true, -1, SV_CDIS, (int)event.peer->data);
+                if((int)(size_t)event.peer->data<0) break;
+                printf("disconnected client (%s)\n", clients[(int)(size_t)event.peer->data].hostname);
+                clients[(int)(size_t)event.peer->data].type = ST_EMPTY;
+                send2(true, -1, SV_CDIS, (int)(size_t)event.peer->data);
                 event.peer->data = (void *)-1;
                 break;
         };
diff --git a/src/tools.h b/src/tools.h
index 97911a8..bc39bd2 100644
--- a/src/tools.h
+++ b/src/tools.h
@@ -7,6 +7,8 @@
 #define gamma __gamma
 #endif
 
+#include <stdbool.h>
+#include <hid.h>
 #include <math.h>
 
 #ifdef __GNUC__
@@ -19,11 +21,11 @@
 #include <stdarg.h>
 #include <limits.h>
 #include <assert.h>
-#ifdef __GNUC__
-#include <new>
-#else
-#include <new.h>
-#endif
+#ifdef __GNUC__
+#include <new>
+#else
+#include <new.h>
+#endif
 
 #ifdef NULL
 #undef NULL
@@ -65,11 +67,11 @@ inline void strn0cpy(char *d, const char *s, size_t m) { strncpy(d,s,m); d[(m)-1
 inline void strcpy_s(char *d, const char *s) { strn0cpy(d,s,_MAXDEFSTR); };
 inline void strcat_s(char *d, const char *s) { size_t n = strlen(d); strn0cpy(d+n,s,_MAXDEFSTR-n); };
 
-inline void formatstring(char *d, const char *fmt, va_list v)
-{
-    _vsnprintf(d, _MAXDEFSTR, fmt, v);
-    d[_MAXDEFSTR-1] = 0;
-};
+inline void formatstring(char *d, const char *fmt, va_list v)
+{
+    _vsnprintf(d, _MAXDEFSTR, fmt, v);
+    d[_MAXDEFSTR-1] = 0;
+};
 
 struct sprintf_s_f
 {
@@ -85,10 +87,10 @@ struct sprintf_s_f
     };
 };
 
-#define sprintf_s(d) sprintf_s_f((char *)d)
-#define sprintf_sd(d) string d; sprintf_s(d)
-#define sprintf_sdlv(d,last,fmt) string d; { va_list ap; va_start(ap, last); formatstring(d, fmt, ap); va_end(ap); }
-#define sprintf_sdv(d,fmt) sprintf_sdlv(d,fmt,fmt)
+#define sprintf_s(d) sprintf_s_f((char *)d)
+#define sprintf_sd(d) string d; sprintf_s(d)
+#define sprintf_sdlv(d,last,fmt) string d; { va_list ap; va_start(ap, last); formatstring(d, fmt, ap); va_end(ap); }
+#define sprintf_sdv(d,fmt) sprintf_sdlv(d,fmt,fmt)
 
 
 // fast pentium f2i
@@ -147,6 +149,8 @@ struct pool
     void allocnext(size_t allocsize);
 };
 
+pool *gp();
+
 template <class T> struct vector
 {
     T *buf;
