-- Leo's gemini proxy

-- Connecting to git.thebackupbox.net:1965...

-- Connected

-- Sending request

-- Meta line: 20 text/gemini

repo: hackvr
action: commit
revision:
path_from:
revision_from: ebde46bc82bebf478db67abef5b7dc88c014706b:
path_to:
revision_to:

git.thebackupbox.net

hackvr

git://git.thebackupbox.net/hackvr

commit ebde46bc82bebf478db67abef5b7dc88c014706b
Author: epoch <epoch@hacking.allowed.org>
Date:   Tue Jan 3 00:30:28 2017 -0600

    lots and lots of shit. opengl shit is barely worked on. new pl script to obj2hackvr using more than just triangles.http://hackaday.com/blog/http://hackaday.com/blog/

diff --git a/Makefile b/Makefile
deleted file mode 100644
index fa71f1a2d402c56722894246c7a3d036ea25bcd2..0000000000000000000000000000000000000000
--- a/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-CFLAGS=-Wall -pedantic -std=c99
-
-all: hackvr slowcat
-
-hackvr: LDFLAGS=-lm -lX11
-
-clean:
-	rm hackvr
-	rm slowcat
diff --git a/filebrowser/list_to_cubes.sh b/filebrowser/list_to_cubes.sh

index d4ad6885575ba0a58f38882ac978736fd232d1a5..

index ..7f6e7942326f4c16221e3a1b4a48cf1452d23bb8 100755

--- a/filebrowser/list_to_cubes.sh
+++ b/filebrowser/list_to_cubes.sh
@@ -11,7 +11,7 @@
 while read -r line;do
  if [ "_$line" != '_' ];then
 #  ../tools/obj2hackvr.pl "$line" ../meshes/cube.obj
-  printf "%s addtriangle 1 0 0 0 1 0 0 0 0\n" "$line"
+  printf "%s addshape 3 1 0 0 0 1 0 0 0 0\n" "$line"
   printf "%s move 0 %d 0 0 0 0 0 0 0\n" "$line" "$i"
   i=$[i+2]
  else
diff --git a/hackvr.c b/hackvr.c
deleted file mode 100644
index 6689258633c7331c27034ee732e9483cb6f06409..0000000000000000000000000000000000000000
--- a/hackvr.c
+++ /dev/null
@@ -1,1314 +0,0 @@
-#define _POSIX_C_SOURCE 200809L //for fileno and strdup
-#define _BSD_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <stdlib.h>
-//#include <sys/select.h> //code to use select instead of non-blocking is commented out. might decide to use it later.
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#include <X11/Xutil.h> //for size hints
-#include <time.h>
-#define __USE_GNU //for longer math constants
-#include <math.h>
-
-int oldtime=0;
-int oldfps=0;
-int fps=0;
-
-//TODO: optimizations
-//TODO: store caches of cs_t, c2_t, and c3_t numbers.
-//TODO: don't forget to remake gophervr with this.
-//TODO: XSegment or line structs to store some shit?
-//TODO: line and triangle intersection for finding what object was clicked on
-//if I don't do hiliting I only need to calculate that upon click.
-
-#define WALK_SPEED 1
-#define SPLIT_SCREEN 1
-#define CAMERA_SEPARATION 4
-#define RED_AND_BLUE 0
-
-#define SHAPES 16386
-#define MAX_SIDES 8
-
-#define min(a,b) (((a)<(b))?(a):(b))
-#define max(a,b) (((a)>(b))?(a):(b))
-
-typedef double long real; //think this conflicts?
-//typedef float real; //think this conflicts?
-
-typedef struct {
- real x;
- real y;
- real z;
-} c3_t;
-
-typedef struct {
- real x;
- real y;
-} c2_t;
-
-typedef struct { //same as XPoint, just use that? nah...
- short x;
- short y;
-} cs_t;
-
-//TODO: will have to make some pixmaps get resized when the window does.
-//for now set them to be as big as you think you'll ever resize the window to.
-#define WIDTH 1024
-#define HEIGHT 768
-
-#define SKYRULE 90
-#define SKYW (WIDTH*5)
-#define SKYH (HEIGHT/2)
-
-Pixmap skypixmap;
-char sky[SKYH][SKYW];
-
-struct object_1 {
- int type;
- unsigned char x;
- unsigned char y;
- unsigned char z;
-};
-
-struct object_2 {
- int type;
- unsigned short x;
- unsigned short y;
- unsigned short z;
-};
-
-struct object_4 {
- int type;
- unsigned int x;
- unsigned int y;
- unsigned int z;
-};
-
-struct camera {
-  c3_t p;
-  int xr;//rotations
-  int yr;
-  int zr;
-  real zoom;
-} camera;
-
-struct c3_line {
- char *id;
- c3_t p1;
- c3_t p2;
-};
-
-struct c3_shape {//use array or linked list?
-  char *id;
-  unsigned char len;
-  c3_t p[MAX_SIDES];
-};
-
-struct mainwin {
-  int x;
-  int y;
-  unsigned int depth;
-  int mousex;
-  int mousey;
-  int rmousex;
-  int rmousey;
-  int buttonpressed;
-  unsigned int width;
-  unsigned int height;
-  unsigned int border_width;
-  XColor colors[256];
-  int xoff;
-  int math_error;
-  int mapxoff;
-  int mapyoff;
-  int split_screen;
-  int split_flip;//1 or -1
-  char *user;
-  char greyscale;
-  char drawminimap;//flag
-  char draw3d;//flag
-  char debug;//flag
-  char drawsky;//flag
-  char zsort;
-  char red_and_blue;
-  char force_redraw;
-  char selected_object[256];//meh
-  real mmz;
-  XColor green;
-  XColor red;
-  XColor blue;
-  XColor redblue[2];
-  Colormap color_map;
-  Display *dpy;
-  Window w;
-  Pixmap backbuffer;
-  Pixmap cleanbackbuffer;
-  GC gc;
-  GC backgc;
-  struct c3_shape *shape[SHAPES];
-  int shapes;
-  int derp;
-  int root_window;
-  real split;
-} global;
-
-//used to figure out what c2 values are associated with each edge of the window.
-//#define TOP     160.0
-//#define BOTTOM  -160.0
-#define TOP     240.0
-#define BOTTOM  -240.0
-#define RIGHT   320.0
-#define LEFT    -320.0
-
-int c2sX(long double x) { return (global.width/(global.split_screen / (global.red_and_blue ? global.split_screen: 1))) * ((x + RIGHT) / (RIGHT *2)) + global.xoff; }
-int s2cX(long double x) { return (x/(global.width/(global.split_screen / (global.red_and_blue?global.split_screen :1))))*(RIGHT*2)-RIGHT; }
-
-int c2sY(long double y) { return global.height * ((TOP-y) / (TOP*2)); }
-int s2cY(long double y) { return -((y/global.height) * (TOP*2) - TOP); }
-
-cs_t c2_to_cs(c2_t p) {
- return (cs_t){c2sX(p.x),c2sY(p.y)};
-}
-c2_t cs_to_c2(cs_t p) {
- return (c2_t){s2cX(p.x),s2cY(p.y)};
-}
-
-long double distance2(c2_t p1,c2_t p2) {
- return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) ));
-}
-
-long double distance3(c3_t p1,c3_t p2) {
- return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) )+( (p1.z-p2.z)*(p1.z-p2.z) ));
-}
-
-long double points_to_angle(c2_t p1,c2_t p2) {
-  long double a=atan2l(p2.y-p1.y,p2.x-p1.x);
-  return a>=0?a:M_PIl+M_PIl+a;
-}
-
-long double d2r(int d) {
- while(d<0) d+=360;
- return (long double)(d%360) / (long double)180 * M_PIl;
-}
-int r2d(real r) {
- return r / M_PIl * 180;
-}
-
-int between_angles(real angle,real lower,real upper) {
-  //lower may be higher than upper.
-  //because lower is < 0 which wraps to higher. lower is 270, upper is 90. 270-90 is in front.
-  if(lower > upper) {
-    if(angle > lower) return 1;
-    if(angle < upper) return 1;
-  }
-  if(upper > lower) {
-    if(angle > lower && angle < upper) return 1;
-  }
-  return 0;
-}
-
-/*
-B (x2,y2)
- |-.   c
-a|  '-.
- |     '-.
- '--------~
-C    b     A (x1,y1)
-*/
-
-//I'll need this for collision I guess.
-
-/*
-
-//use this for finding a line that intersects with what the camera is pointing at
-c2_t get_c2_intersection(c2_t p1,real theta,c2_t p2) {
-  real c;
-  c=distance2(p1,p2);
-  theta_a=C A B
-  b = (c/1) * (theta_a + theta_offset)
-}
-
-int get_2D_intersection_X(x1,y1,theta_offset,x2,y2) {
- int x3a,y3a,x3b,y3b;
- int a,b,c;//lenght of sides.
- int theta_a,theta_b,theta_c;//angles opposite of same named sides.
-
- //get angle C A B
- theta_a=
-// x1,y1,x2,y2
-
-//what are these d1 and d2?
- if(d1==d2) return global.math_error=1;
- c=dist(x1,y1,x2,y2);
- b = (c/1) * (theta_a + theta_offset);
- a = (c/1) * (theta_b + theta_offset);
-
- x3b=sin(theta_a) * b;
- y3b=cos(theta_a) * b;
- x3a=sin(theta_a) * a;
- y3a=cos(theta_a) * a;
- printf("x: %d %d\nx: %d %d\n",x3a,y3a,x3b,y3b);
-}
-
-int get_2D_intersection_Y(x,y,d,x,z,d) {
- int x3a,y3a,x3b,y3b;
- int a,b,c;//lenght of sides.
- int theta_a,theta_b,theta_c;//angles opposite of same named sides.
-
- //get angle from A to B.
- x1,y1,x2,y2
-
- if(d1==d2) return global.math_error=1;
- c=dist(x1,y1,x2,y2);
- b = (c/1) * theta_a;
- a = (c/1) * theta_b;
-
- x3b=sin(a) * b;
- y3b=cos(a) * b;
- x3a=sin(a) * a;
- y3a=cos(a) * a;
- printf("y: %d %d\ny: %d %d\n",x3a,y3a,x3b,y3b);
-}
-*/
-
-void draw_cs_line(cs_t p1,cs_t p2) {
-  XDrawLine(global.dpy,global.backbuffer,global.backgc,p1.x,p1.y,p2.x,p2.y);
-}
-
-void draw_c2_line(c2_t p1,c2_t p2) {
-  draw_cs_line(c2_to_cs(p1),c2_to_cs(p2));
-}
-
-#define MAGIC(x) (1.0l-(1.0l/powl(1.01l,(x)))) //??? might want to have some changables in here
-
-real magic(real x) {
-  return MAGIC(x);
-}
-
-void draw_graph(real (*fun)(real x)) {
- c2_t pa;
- draw_c2_line((c2_t){LEFT,0},(c2_t){RIGHT,0});
- draw_c2_line((c2_t){0,TOP},(c2_t){0,BOTTOM});
- for(pa.x=LEFT;pa.x<RIGHT;pa.x+=5.0) {
-  draw_c2_line((c2_t){pa.x,2.0},(c2_t){pa.x,-2.0});
- }
- for(pa.y=BOTTOM;pa.y<TOP;pa.y+=5.0) {
-  draw_c2_line((c2_t){-2.0,pa.y},(c2_t){2.0,pa.y});
- }
- for(pa.x=LEFT;pa.x<RIGHT;pa.x+=1.0) {
-  draw_c2_line((c2_t){pa.x,fun(pa.x)},(c2_t){pa.x+1.0,fun(pa.x+1.0)});
- }
-}
-
-c2_t rotate_c2(c2_t p1,c2_t p2,real dr) {
-  c2_t p3;
-  real d=distance2(p1,p2);
-  real r=points_to_angle(p1,p2);
-  r=r+dr;
-  p3.x=(sinl(r) * d) + p2.x;
-  p3.y=(cosl(r) * d) + p2.y;
-  return p3;
-}
-
-c3_t rotate_c3_xr(c3_t p1,c3_t p2,real xr) {//rotate y and z around camera based on xr (looking up and down)
-  c2_t tmp;
-  tmp=rotate_c2((c2_t){p1.y,p1.z},(c2_t){p2.y,p2.z},xr);
-  return (c3_t){p1.x,tmp.x,tmp.y};
-}
-c3_t rotate_c3_yr(c3_t p1,c3_t p2,real yr) {//rotate x and z around camera based on yr (looking left and right)
-  c2_t tmp;
-  tmp=rotate_c2((c2_t){p1.x,p1.z},(c2_t){p2.x,p2.z},yr);
-  return (c3_t){tmp.x,p1.y,tmp.y};
-}
-c3_t rotate_c3_zr(c3_t p1,c3_t p2,real zr) {//rotate x and y around camera based on zr (cocking your head to a side)
-  c2_t tmp;
-  tmp=rotate_c2((c2_t){p1.x,p1.y},(c2_t){p2.x,p2.y},zr);
-  return (c3_t){tmp.x,tmp.y,p1.z};
-}
-
-void rotate_shape_yr(struct c3_shape *s) {//changes input value!
- int i=0;
- for(i=0;i<s->len+(s->len==1);i++) s->p[0]=rotate_c3_yr(s->p[0],camera.p,camera.yr);
-}
-
-c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE
-  c2_t p2;
-//  c3_t tmp1;
-//  c3_t tmp2;
-//  c3_t tmp3;
-  c3_t final;
-//these rotations need to be about the previous axis after the axis itself has been rotated.
-//  final=rotate_c3_yr(p3,camera.p,d2r(camera.yr));//rotate everything around the camera's location.
-  final=rotate_c3_yr(p3,(c3_t){0,0,0},d2r(camera.yr));//rotate everything around the center no matter what.
-//  tmp2=rotate_c3_xr(tmp1,camera.p,d2r(camera.xr));
-//  final=rotate_c3_zr(tmp2,camera.p,d2r(camera.zr));
-  real delta_x=(camera.p.x - final.x);
-  real delta_y=(camera.p.y - final.y);
-  real delta_z=(camera.p.z - final.z);
-//  real d=distance3(camera.p,final);
-  p2.y=camera.zoom * (delta_y * MAGIC(delta_z) - delta_y);
-  p2.x=camera.zoom * (delta_x * MAGIC(delta_z) - delta_x);
-  return p2;
-}
-
-void draw_c3_line(c3_t p1,c3_t p2) {
-// if(!between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p1.x,p1.z}),0,90) ||
-//    !between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p2.x,p2.z}),0,90)) return;
- if(global.drawminimap == 1) {
-  draw_c2_line((c2_t){(camera.p.x-2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x+2)*global.mmz,(camera.p.z-2)*global.mmz});
-  draw_c2_line((c2_t){(camera.p.x+2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x-2)*global.mmz,(camera.p.z-2)*global.mmz});
-  draw_c2_line((c2_t){p1.x*global.mmz,p1.z*global.mmz},(c2_t){p2.x*global.mmz,p2.z*global.mmz});
- }
- if(global.drawminimap == 2) {//map rotates.
-  c3_t t1=rotate_c3_yr(p1,camera.p,d2r(camera.yr));
-  c3_t t2=rotate_c3_yr(p2,camera.p,d2r(camera.yr));
-  draw_c2_line((c2_t){t1.x*global.mmz,t1.z*global.mmz},(c2_t){t2.x*global.mmz,t2.z*global.mmz});
- }
- if(global.draw3d != 0) draw_c2_line(c3_to_c2(p1),c3_to_c2(p2));
- if(global.debug) {
-
- }
-}
-
-cs_t c3_to_cs(c3_t p) {
- return c2_to_cs(c3_to_c2(p));
-}
-
-real shitdist2(c3_t p1,c3_t p2) {
- return sqrtl(((p1.x - p2.x) * (p1.x - p2.x)) +
-        ((p1.y - p2.y) * (p1.y - p2.y)) +
-        ((p1.z - p2.z) * (p1.z - p2.z)));
-}
-
-real shitdist(struct c3_shape s,c3_t p) {
-// apply rotation then find distance?
- int i;
- struct c3_shape s_;
- real total;
- s_=s;
- rotate_shape_yr(&s_);
- for(i=0;i<s_.len+(s_.len==1);i++) {
-  total+=shitdist2(s_.p[i],camera.p);
- }
- return (total) / (real)(s_.len+(s_.len==1));
-}
-
-
-void HatchLines(c2_t p1,c2_t p2,c2_t p3,int density) {
- real i=0;
- for(i=1;i<density;i=i+1) {//only need 1/2, not 0/2 and 2/2, those are edges of the triangle.
-  draw_c2_line(
-   (c2_t){((i*p1.x)+((density-i)*p3.x))/density,
-          ((i*p1.y)+((density-i)*p3.y))/density},
-   (c2_t){((i*p2.x)+((density-i)*p3.x))/density,
-          ((i*p2.y)+((density-i)*p3.y))/density}
-  );
- }
-}
-
-/*void DrawHatchedTriangle(struct c3_triangle t,int d) {
- c2_t p1,p2,p3;
- p1=c3_to_c2(t.p1);
- p2=c3_to_c2(t.p2);
- p3=c3_to_c2(t.p3);
- HatchLines(p1,p2,p3,d);
- HatchLines(p2,p3,p1,d);
- HatchLines(p1,p3,p2,d);
-}*/
-
-//^ subdivision algorithm for display purposes only.
-//black out the rest of the triangle first?
-//sounds alright to me...
-
-void draw_cs_text(cs_t p,char *text) {
- char t[256];
- int direction,ascent,descent;
- XFontStruct *font=XLoadQueryFont(global.dpy,"fixed");
- XCharStruct overall;
- snprintf(t,sizeof(t)-1,"%s",text);
- XTextExtents(font,text,strlen(text),&direction,&ascent,&descent,&overall);
- XDrawString(global.dpy,global.backbuffer,global.backgc,p.x,p.y+(descent+ascent),text,strlen(text));
-}
-
-void draw_c2_text(c2_t p,char *text) {
- cs_t p2=c2_to_cs(p);
- draw_cs_text(p2,text);
-}
-
-void draw_c3_text(c3_t p,char *text) {
- cs_t p2=c3_to_cs(p);
- draw_cs_text(p2,text);
-}
-
-/*
-cs_t *c3s_to_css(c3_t *p3,int len) {
- cs_t *ps=malloc(sizeof(cs_t) * len);
- int i;
- for(i=0;i<len;i++) ps[i]=c3_to_cs(p3[i]);
- return ps;
-}*/
-
-void draw_c3_shape(struct c3_shape s) {
-// char line[1024];
- int i=0;
- int w,h;
- XPoint p[s.len+(s.len==1)];
- cs_t tmp;
- for(i=0;i<s.len+(s.len==1);i++) {
-  tmp=c3_to_cs(s.p[i]);
-  p[i]=(XPoint){tmp.x,tmp.y};
- }
- if(global.draw3d == 1) { // wireframe
-  switch(s.len) {
-   case 1:
-    w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
-    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
-    p[0].x-=h;
-    p[0].y-=h;
-    XDrawArc(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
-    break;
-   case 2:
-    XDrawLine(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
-    break;
-   default:
-    for(i=0;i<s.len;i++) {
-     XDrawLines(global.dpy,global.backbuffer,global.backgc,p,s.len,CoordModeOrigin);
-    }
-    break;
-  }
- }
- if(global.draw3d == 2) { //draw it filled in
-  switch(s.len) {
-   case 1:
-    w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
-    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
-    p[0].x-=h;
-    p[0].y-=h;
-    XFillArc(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
-    break;
-   case 2:
-    XDrawLine(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
-    break;
-   default:
-    XFillPolygon(global.dpy,global.backbuffer,global.backgc,p,s.len,Convex,CoordModeOrigin);
-    break;
-  }
- }
-// if(global.draw3d == 3) { //hashed
-//  XSetForeground(global.dpy, global.backgc, global.colors[0].pixel);
-  //XDrawFilledShape(c3_to_cs(t.p1),c3_to_cs(t.p2),c3_to_cs(t.p3));//clear out this triangle.
-//  XSetForeground(global.dpy, global.backgc, global.green.pixel);
-  //upgrade me! DrawHatchedTriangle(t,10 - (shitdist(t,camera.p) / 10));//how to get density?
-// }
-/* if(global.debug) {
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p1.x,t.p1.y,t.p1.z);
-  draw_c3_text(t.p1,line);
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p2.x,t.p2.y,t.p2.z);
-  draw_c3_text(t.p2,line);
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p3.x,t.p3.y,t.p3.z);
-  draw_c3_text(t.p3,line);
-*/
-// }
-}
-
-typedef struct {
- struct c3_shape *s;
- real d;
-} zsort_t;
-
-int compar(zsort_t *a,zsort_t *b) {
- return ((a->d) > (b->d));
-}
-
-
-/*
-void draw_c3_point_text(c3_t p,char *text) {
- char coords[256];
- int direction,ascent,descent;
- cs_t p2;
- p2=c3_to_cs(p);
- snprintf(coords,sizeof(coords)-1,"(%Lf,%Lf,%Lf)",p.x,p.y,p.z);
- XTextExtents(font,text,strlen(text),&direction,&ascent,&descent,&overall);
- XDrawString(global.dpy,global.backbuffer,global.backgc,p2.x,p2.y+(descent+ascent),coords,strlen(coords));
-}*/
-
-void draw_screen(Display *dpy,Window w,GC gc) {
-  int i;
-  int colori=100;
-  int cn=0;//camera number.
-  XFontStruct *font=XLoadQueryFont(global.dpy,"fixed");
-  XCharStruct overall;
-  int direction,ascent,descent;
-  char coords[256];
-  XGCValues gcval;
-  zsort_t zs[SHAPES];
-  XCopyArea(global.dpy,global.cleanbackbuffer,global.backbuffer,gc,0,0,global.width,global.height,0,0);//clear the backbuffer.
-//  XCopyPlane(global.dpy,global.cleanbackbuffer,global.backbuffer,gc,0,0,global.width,global.height,0,0,1);//clear the backbuffer.
-
-  XRectangle cliprect;
-  cliprect.x=0;
-  cliprect.y=0;
-  cliprect.width=global.width/global.split_screen;
-  cliprect.height=global.height;
-
-  real oldx=camera.p.x;
-  real oldz=camera.p.z;
-  if(global.split_screen > 1) {
-   camera.p.z-=(global.split_flip)*((global.split/global.split_screen)*cosl(d2r(camera.yr+180)));
-   camera.p.x-=(global.split_flip)*((global.split/global.split_screen)*sinl(d2r(camera.yr+180)));
-  }
-  for(cn=0;cn<global.split_screen;cn++) {
-    if(global.red_and_blue) {
-     //set color for left half to red and right half to blue
-     //and draw mode for the gc to GXOr
-     global.xoff=0;
-     gcval.function=GXor;
-     XChangeGC(global.dpy,global.backgc,GCFunction,&gcval);
-    } else {
-     global.xoff=(global.width/global.split_screen)*cn;
-    }
-    if(!global.red_and_blue) XSetClipRectangles(global.dpy,global.backgc,global.xoff,0,&cliprect,1,Unsorted);
-    //if(global.drawminimap == 3) { draw_graph(magic); continue; }
-    if(global.drawsky) {
-     XCopyArea(global.dpy,skypixmap,global.backbuffer,global.backgc,((camera.yr*5)+SKYW)%SKYW,0,WIDTH,global.height/2,0,0);
-    }
-    if(global.draw3d) {
-//      draw_c2_line((c2_t){LEFT,0},(c2_t){RIGHT,0}); //horizon
-    }
-    if(time(0) == oldtime) {
-     fps++;
-    }
-    else {
-     oldtime=time(0);
-     oldfps=fps;
-     fps=0;
-    }
-    //XSetForeground(global.dpy, global.backgc, global.green.pixel);
-    if(global.debug) {
-      snprintf(coords,sizeof(coords)-1,"debug: %s minimap: %d 3d: %d fps: %d shapes: %d",global.debug?"on":"off",global.drawminimap,global.draw3d,oldfps,global.shapes);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*1,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"x: %d y: %d",global.mousex,global.mousey);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*2,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"cx: %Lf cy: %Lf cz: %Lf",camera.p.x,camera.p.y,camera.p.z);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*3,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"xr: %d yr: %d zr: %d",camera.xr,camera.yr,camera.zr);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*4,coords,strlen(coords));
-    }
-
-//  if(global.drawminimap) {//this isn't even useful I guess.
-   //cx1=(sinl(d2r(camera.yr+270))*7l);
-   //cy1=(cosl(d2r(camera.yr+270))*7l);
-   //cx2=(sinl(d2r(camera.yr+90))*7l);
-   //cy2=(cosl(d2r(camera.yr+90))*7l);
-//   draw_c2_line((c2_t){0,0},(c2_t){10,10});
-//   draw_c2_line((c2_t){0,0},(c2_t){-10,10});
-//   draw_c2_line((c2_t){10,10},(c2_t){-10,10});
-//  }
-
-/* cube
-   draw_c3_line((c3_t){-3,0,-3},(c3_t){-3,0,3});
-   draw_c3_line((c3_t){-3,0,-3},(c3_t){-3,6,-3});
-   draw_c3_line((c3_t){-3,0,-3},(c3_t){3,0,-3});
-
-   draw_c3_line((c3_t){3,6,3},(c3_t){3,6,-3});
-   draw_c3_line((c3_t){3,6,3},(c3_t){-3,6,3});
-   draw_c3_line((c3_t){3,6,3},(c3_t){3,0,3});
-
-   draw_c3_line((c3_t){-3,0,3},(c3_t){3,0,3});
-   draw_c3_line((c3_t){-3,0,3},(c3_t){-3,6,3});
-
-   draw_c3_line((c3_t){-3,6,-3},(c3_t){-3,6,3});
-   draw_c3_line((c3_t){-3,6,-3},(c3_t){3,6,-3});
-
-   draw_c3_line((c3_t){3,0,-3},(c3_t){3,0,3});
-   draw_c3_line((c3_t){3,0,-3},(c3_t){3,6,-3});
-*/
-/*
-   //floor grid
-   for(i=-21;i<21;i+=3) {
-    for(j=-21;j<21;j+=3) {
-     //draw_c3_triangle((struct c3_triangle){"id",(c3_t){i,0,j},(c3_t){i,0,j+3},(c3_t){i+3,0,j}});
-     draw_c3_line((c3_t){i,0,j},(c3_t){i,0,j+3});
-     draw_c3_line((c3_t){i,0,j},(c3_t){i+3,0,j});
-    }
-   }
-*/
-   //apply rotation?
-   // load up the triangles to render... after applying rotation?
-   for(i=0;global.shape[i];i++) {
-    zs[i].s=global.shape[i];
-    //rotate_shape(zs[i].s);
-   }
-   //
-   if(1) {//global.zsort) {
-    for(i=0;global.shape[i];i++) {
-     zs[i].d=shitdist(*(zs[i].s),camera.p);
-    }
-    qsort(&zs,i,sizeof(zs[0]),(__compar_fn_t)compar);//sort these zs structs based on d.
-   }
-   //draw all triangles
-   if(zs[0].s) {
-    strcpy(global.selected_object,zs[0].s->id);
-   }
-   for(i=0;global.shape[i];i++) {
-    //now we pick the color of this triangle!
-    if(global.red_and_blue) {
-     if(cn==0) {
-      XSetForeground(global.dpy,global.backgc,global.red.pixel);
-     } else {
-      XSetForeground(global.dpy,global.backgc,global.blue.pixel);
-     }
-//tests of blending grayscale with red and blue
-//     draw_c3_triangle(*(zs[i].t));
-    } else {
-     if(!strcmp(global.selected_object,zs[i].s->id)) {
-      //XSetForeground(global.dpy,global.backgc,global.green.pixel);
-     } else {
-      if(global.greyscale) {
-       if(zs[i].d > 0) {
-        if(zs[i].d < 100) {
-         colori=zs[i].d;
-        }
-       }
-       colori=(int)(zs[i].d)%100;
-       XSetForeground(global.dpy,global.backgc,global.colors[(int)(100.0-(colori))].pixel);//picking the color here only works if...
-      }
-     }
-    }
-    draw_c3_shape(*(zs[i].s));
-   }
-   XSetForeground(global.dpy, global.backgc, global.green.pixel);
-   if(global.debug) {
-    snprintf(coords,sizeof(coords)-1,"selected object: %s",global.selected_object);
-    XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-    XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*5,coords,strlen(coords));
-   }
-   camera.p.z+=(global.split_flip)*(global.split*cosl(d2r(camera.yr+180)));
-   camera.p.x+=(global.split_flip)*(global.split*sinl(d2r(camera.yr+180)));
-
-
-  }
-
-//TODO: figure out what all this shit is and either update or remove.
-//DONT USE WIDTH for shit.
-/*
-  x1=nextX(WIDTH/2,HEIGHT/2,d2r(camera.yr),40);
-  y1=nextY(WIDTH/2,HEIGHT/2,d2r(camera.yr),40);
-  x2=nextX(WIDTH/2,HEIGHT/2,d2r(camera.yr+180),80);
-  y2=nextY(WIDTH/2,HEIGHT/2,d2r(camera.yr+180),80);
-  XDrawLine(global.dpy,w,gc,WIDTH/2,HEIGHT/2,x1,y1);
-  XDrawLine(global.dpy,w,gc,WIDTH/2,HEIGHT/2,x2,y2);
-
-  XDrawLine(global.dpy,w,gc,0,HEIGHT/2,WIDTH,HEIGHT/2);
-
-  x1=global.mousex;
-  y1=global.mousey;
-  real a=points_to_angle((c2_t){0,0},cs_to_c2((cs_t){x1,y1}));
-
-  snprintf(coords,sizeof(coords)-1,"%llf",a);
-  XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*6,coords,strlen(coords));
-  snprintf(coords,sizeof(coords)-1,"%llf",points_to_angle(cs_to_c2((cs_t){global.mousex,global.mousey}),(c2_t){0,0})+(M_PIl/2));
-  XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*7,coords,strlen(coords));
-  XDrawLine(global.dpy,w,gc,global.mousex,global.mousey,global.width/2,global.height/2);
-
-  real c=cosl(d2r(camera.yr) - a) * distance((c2_t){x1,y1},(c2_t){WIDTH/2,HEIGHT/2});
-  x2=nextX(x1,y1,d2r(camera.yr-90),c);
-  y2=nextY(x1,y1,d2r(camera.yr-90),c);
-  XDrawLine(global.dpy,w,gc,x1,y1,x2,y2);
-*/
-  camera.p.x = oldx;
-  camera.p.z = oldz; //-= cn*CAMERA_SEPARATION;
-//  XClearWindow(global.dpy, w);
-  XCopyArea(global.dpy,global.backbuffer,w,gc,0,0,global.width,global.height,0,0);//move backbuffer to window
-//  XCopyPlane(global.dpy,global.backbuffer,w,gc,0,0,global.width,global.height,0,0,0x000100);//move backbuffer to window
-}
-
-/* does not return the newline. */
-char *read_line_hack(FILE *fp,int len) {
- short in;
- char *t;
- switch(in=fgetc(fp)) {
-  case '\n':
-   t=malloc(len+1);
-   t[len]=0;
-   return t;
-  case -1:
-   return 0;
-  default:
-   if((t=read_line_hack(fp,len+1))) t[len]=in;
-   break;
- }
- return t;
-}
-
-//warning: clobbers input
-//skips leading and trailing space.
-//compresses multiple spaces to one.
-//return length of array
-char **line_splitter(char *line,int *rlen) {
- char **a;
- int len,i=0;
- len=1;//we're just counting how much we'll need the first loop through.
- for(i=0;line[i] && line[i] == ' ';i++);//skip leading space
- for(;line[i];len++) {
-  for(;line[i] && line[i] != ' ';i++);//skip rest of data
-  for(;line[i] && line[i] == ' ';i++);//skip rest of space
- }
- a=malloc(sizeof(char *) * len+1);
- a[len]=0;
- len=0;//reuse!
- for(i=0;line[i] && line[i] == ' ';i++);//skip leading space
- a[len]=line+i;
- for(;;) {
-  for(;line[i] && line[i] != ' ';i++);//skip rest of data
-  if(!line[i]) break;
-  line[i++]=0;
-  for(;line[i] && line[i] == ' ';i++);//skip rest of space
-  if(!line[i]) break;
-  a[++len]=line+i;
- }
- a[++len]=0;
- *rlen=len;
- return a;
-}
-
-void set_aspect_ratio() {
- XSizeHints *hints=XAllocSizeHints();
- hints->min_aspect.x=4*(global.split_screen / (global.red_and_blue ? global.split_screen : 1));
- hints->min_aspect.y=3;
- hints->max_aspect.x=4*(global.split_screen / (global.red_and_blue ? global.split_screen : 1));
- hints->max_aspect.y=3;
- hints->flags=PAspect;
- XSetWMNormalHints(global.dpy,global.w,hints);
-}
-
-int load_stdin() {
- struct c3_shape s;
-// struct c3_line l;
- char *command;
- char *line;
- char *id;
- char **a;
- int len;
- int ret=0;
- int j,k,l;
- //struct timeval timeout;
- //fd_set master;
- //fd_set readfs;
- //FD_ZERO(&master);
- //FD_ZERO(&readfs);
- //FD_SET(0,&master);//just stdin.
- int i;//used to store the last triangle. even though I have a global for that. >_>
-
-// printf("# entering load_stdin()\n");
- for(i=0;global.shape[i];i++) ;//hop to the end.
- fcntl(0,F_SETFL,O_NONBLOCK);
- if(feof(stdin))  {
-  clearerr(stdin);
- }
- // readfs=master;
- // timeout.tv_sec=0;
- // timeout.tv_usec=1;
- // if((j=select(1,&readfs,0,0,&timeout)) == -1) {
- //  perror("select");
- //  return 0;
- // }
- // if(FD_ISSET(0,&readfs)) {
- while((line=read_line_hack(stdin,0))) {//load as long there's something to load
-  if(*line == '#') return 0;
-  //printf("# read command: %s\n",line);
-  a=line_splitter(line,&len);
-  if(len > 1) {
-   id=a[0];
-   command=a[1];
-  } else {
-   printf("Ohhhh. shit.\n");
-   return 0;
-  }
-  ret=1;
-  if(!strcmp(command,"deleteallexcept")) {
-   for(j=0;global.shape[j];j++) {//mark first. compress later.
-    if(strcmp(global.shape[j]->id,a[2])) {//TODO: memory leak!
-     //free(global.triangle[j]->id);
-     //free(global.triangle[j]);
-     global.shape[j]=0;
-    }
-   }
-   l=0;
-   for(k=0;k<j;k++) {
-    while(global.shape[l] == 0 && l < j) l++;
-    global.shape[k]=global.shape[l];
-   }
-   continue;
-  }
-  if(!strcmp(command,"deletegroup")) {
-   for(j=0;global.shape[j];j++) {//mark first. compress later.
-    if(!strcmp(global.shape[j]->id,s.id)) {//??? where is s.id supposed to be set from?
-     free(global.shape[j]->id);
-     free(global.shape[j]);
-     global.shape[j]=0;
-    }
-   }
-   l=0;
-   for(k=0;k<j;k++) {
-    while(global.shape[l] == 0 && l < j) l++;
-    global.shape[k]=global.shape[l];
-   }
-   continue;
-  }
-  if(!strcmp(command,"assimilate")) {
-   if(len == 3) {
-    for(j=0;global.shape[j];j++) {
-     if(!strcmp(global.shape[j]->id,a[2])) {
-      free(global.shape[j]->id);
-      global.shape[j]->id=strdup(id);
-     }
-    }
-   }
-   continue;
-  }
-  if(!strcmp(command,"renamegroup")) {
-   if(len == 4) {
-    for(j=0;global.shape[j];j++) {
-     if(!strcmp(global.shape[j]->id,a[2])) {
-      free(global.shape[j]->id);
-      global.shape[j]->id=strdup(a[3]);
-     }
-    }
-   }
-   continue;
-  }
-  if(!strcmp(command,"export")) {
-   for(j=0;global.shape[j];j++) {
-    if(!strcmp(global.shape[j]->id,a[2])) {
-//     to=global.shape[j];
-//     printf("%s addshape %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf\n",a[2],
-//            to->p1.x,to->p1.y,to->p1.z,
-//            to->p2.x,to->p2.y,to->p2.z,
-//            to->p3.x,to->p3.y,to->p3.z
-//           );
-    }
-   }
-   continue;
-  }
-  if(!strcmp(command,"dump")) {
-   printf("%s set camera.p.x %Lf\n",global.user,camera.p.x);
-   printf("%s set camera.p.y %Lf\n",global.user,camera.p.y);
-   printf("%s set camera.p.z %Lf\n",global.user,camera.p.z);
-   printf("%s set camera.xr %d\n",global.user,camera.xr);
-   printf("%s set camera.yr %d\n",global.user,camera.yr);
-   printf("%s set camera.zr %d\n",global.user,camera.zr);
-   printf("%s set camera.zoom %Lf\n",global.user,camera.zoom);
-   continue;
-  }
-  if(!strcmp(command,"quit")) {
-   return -1;
-  }
-  if(!strcmp(command,"set")) { //set variable //TODO: add more things to this.
-   if(len != 3 && len != 4) continue;
-   if(len == 4) {
-    if(!strcmp(a[2],"camera.p.x")) camera.p.x=strtold(a[3],0);
-    else if(!strcmp(a[2],"camera.p.y")) camera.p.y=strtold(a[3],0);
-    else if(!strcmp(a[2],"camera.p.z")) camera.p.z=strtold(a[3],0);
-    else if(!strcmp(a[2],"camera.zoom")) camera.zoom=strtold(a[3],0);
-    else if(!strcmp(a[2],"camera.xr")) camera.xr=atoi(a[3]);
-    else if(!strcmp(a[2],"camera.yr")) camera.yr=atoi(a[3]);
-    else if(!strcmp(a[2],"camera.zr")) camera.zr=atoi(a[3]);
-    else printf("# unknown variable: %s\n",a[2]);
-    continue;
-   }
-   if(!strcmp(a[2],"force_redraw")) global.force_redraw^=1;
-   else if(!strcmp(a[2],"red_and_blue")) { global.red_and_blue^=1; set_aspect_ratio(); }
-   else { printf("# unknown variable: %s\n",a[2]); continue; }
-   printf("# %s toggled!\n",a[2]);
-   continue;
-  }
-  if(!strcmp(command,"addshape")) {
-   if(len > 3) {
-    global.shape[i]=malloc(sizeof(struct c3_shape));
-    global.shape[i]->id=strdup(id);
-    global.shape[i]->len=strtold(a[2],0);
-    for(j=0;j < global.shape[i]->len+(global.shape[i]->len==1);j++) {
-     global.shape[i]->p[j].x=strtold(a[(j*3)+3],0);//second arg is just for a return value. set to 0 if you don't want it.
-     global.shape[i]->p[j].y=strtold(a[(j*3)+4],0);
-     global.shape[i]->p[j].z=strtold(a[(j*3)+5],0);
-    }
-    i++;
-    global.shapes=i;
-    global.shape[i]=0;
-   } else {
-    printf("# ERROR: wrong amount of parts for addshape. got: %d expected: 11\n",len);
-   }
-   continue;
-  }
-  if(!strcmp(command,"scaleup")) {//should this scale separately so it can be a deform too?
-   for(i=0;global.shape[i];i++) {
-    if(!strcmp(global.shape[i]->id,id)) {
-     for(j=0;j < global.shape[i]->len+(global.shape[i]->len==1);j++) {
-      global.shape[i]->p[j].x*=strtold(a[2],0);
-      global.shape[i]->p[j].y*=strtold(a[2],0);
-      global.shape[i]->p[j].z*=strtold(a[2],0);
-     }
-    }
-   }
-   continue;
-    //return ret;
-  }
-  if(!strcmp(command,"move")) {
-   if(len > 4) {
-    for(i=0;global.shape[i];i++) {
-     if(!strcmp(global.shape[i]->id,id)) {
-      for(j=0;j < global.shape[i]->len+(global.shape[i]->len==1);j++) {
-       global.shape[i]->p[j].x+=strtold(a[2],0);
-       global.shape[i]->p[j].y+=strtold(a[3],0);
-       global.shape[i]->p[j].z+=strtold(a[4],0);
-      }
-     }
-    }
-   }
-   else {
-    printf("# ERROR: wrong amount of parts for move. got: %d expected: 11\n",len);
-   }
-   continue;
-   //return ret;
-  }
-  printf("# I don't know what command you're talking about. %s\n",command);
-/*   if(!strcmp(command,"rotate")) {
-     for(i=0;global.shape[i];i++) {
-      global.shape[i]->p1=rotate_c3_about()
-      global.shape[i]->p2=
-      global.shape[i]->p3=
-     }
-*/
-  free(line);
-  if(a) free(a);
- }
- return ret;
-}
-
-int export_file(FILE *fp) {//not used yet. maybe export in obj optionally? no. that should be an external program
-// struct c3_shape *to;
-// int i;
-// for(i=0;global.shape[i];i++) {
-//  to=global.shape[i];
-//  printf("%s addshape %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf %Lf\n",to->id,to->p1.x,to->p1.y,to->p1.z,to->p2.x,to->p2.y,to->p2.z,to->p3.x,to->p3.y,to->p3.z);
-// }
- return 0;
-}
-
-//push a string back into stdin so it can be read by the file loader. :P
-int selfcommand(char *s) {
- char t;
- if(!strlen(s)) return 0;
- ungetc(s[strlen(s)-1],stdin);
- t=s[strlen(s)-1];
- s[strlen(s)-1]=0;
- selfcommand(s);
- putchar(t);
- return 0;
-}
-
-int keypress_handler(int sym) {
-  char line[1024];
-  real tmpx;
-//  real tmpy; //unused atm
-  real tmpz;
-  switch(sym) {
-   case XK_Return:
-    snprintf(line,sizeof(line)-1,"%s action %s\n",global.user,global.selected_object);
-    selfcommand(line);
-    break;
-   case XK_Up:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+90));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+90));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Down:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+270));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+270));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Left:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Right:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+180));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+180));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_w:
-    camera.p.y+=1;
-    snprintf(line,sizeof(line)-1,"%s move 0 1 0 0 0 0 0 0 0\n",global.user);
-    selfcommand(line);
-    break;
-   case XK_s:
-    camera.p.y-=1;
-    snprintf(line,sizeof(line)-1,"%s move 0 -1 0 0 0 0 0 0 0\n",global.user);
-    selfcommand(line);
-    break;
-   case XK_r:
-    camera.xr+=5;
-    while(camera.xr > 360) camera.xr-=360;
-    break;
-   case XK_y:
-    camera.xr-=5;
-    while(camera.xr < 0) camera.xr+=360;
-    break;
-   case XK_q:
-    camera.yr+=5;
-    while(camera.yr > 360) camera.yr-=360;
-    break;
-   case XK_e:
-    camera.yr-=5;
-    while(camera.yr < 0) camera.yr+=360;
-    break;
-   case XK_u:
-    camera.zr+=5;
-    while(camera.zr > 360) camera.zr-=360;
-    break;
-   case XK_o:
-    camera.zr-=5;
-    while(camera.zr < 0) camera.zr+=360;
-    break;
-   case XK_z: camera.zoom+=1; break;
-   case XK_x: camera.zoom-=1; break;
-   case XK_c: global.mmz*=1.1; break;
-   case XK_v: global.mmz/=1.1; break;
-   case XK_h: global.split+=1; break;
-   case XK_j: global.split-=1; break;
-   case XK_d:
-    global.debug ^= 1;
-    break;
-   case XK_f:
-    global.derp ^= 1;
-    break;
-   case XK_m:
-    global.drawminimap += 1;
-    global.drawminimap %= 4;
-    break;
-   case XK_a:
-    global.drawsky ^= 1;
-    break;
-   case XK_3:
-    global.draw3d += 1;
-    global.draw3d %= 4;
-    break;
-   case XK_Escape:
-    return -1;
-   default:
-    return 0;
-    break;
- }
- return 1;
-}
-
-
-int main(int argc,char *argv[]) {
-  Cursor cursor;
-  XEvent e;
-  XSetWindowAttributes attributes;
-  Window root,child;//why do I have this?
-//  XColor toss;
-  int i,j;
-  char tmp[64];
-  unsigned int mask;
-  char redraw=0;
-  if(argc < 2) {
-   fprintf(stderr,"usage: hackvr yourname < from_others > to_others\n");
-   return 1;
-  } else {
-   global.user=strdup(argv[1]);
-  }
-  fcntl(1,F_SETFL,O_NONBLOCK);//won't work
-  printf("# Opening X Display... (%s)\n",getenv("DISPLAY"));
-  if((global.dpy = XOpenDisplay(0)) == NULL) return printf("# failure.\n"),2;
-  else printf("# done.\n");
-  global.color_map=DefaultColormap(global.dpy, DefaultScreen(global.dpy));
-
-  printf("# generating grays...\n");
-  for(i=0;i<=100;i++) {
-   snprintf(tmp,sizeof(tmp),"gray%d",i);
-   XAllocNamedColor(global.dpy,global.color_map,tmp,&global.colors[i],&global.colors[i]);
-  }
-  printf("# done.\n");
-  setbuf(stdin,0);
-  setbuf(stdout,0);
-  assert(global.dpy);
-  global.split_screen=SPLIT_SCREEN;
-  global.split_flip=-1;
-  global.split=5;
-  global.root_window=0;
-  global.red_and_blue=RED_AND_BLUE;
-  //global.colors[0]=BlackPixel(global.dpy,DefaultScreen(global.dpy));
-//  int whiteColor = //WhitePixel(global.dpy, DefaultScreen(global.dpy));
-  attributes.background_pixel=global.colors[0].pixel;
-  if(global.root_window) {
-   global.w = DefaultRootWindow(global.dpy); //this is still buggy.
-  } else {
-   global.w = XCreateWindow(global.dpy,DefaultRootWindow(global.dpy),0,0,WIDTH*(global.split_screen / (global.red_and_blue ? global.split_screen : 1)),HEIGHT,1,DefaultDepth(global.dpy,DefaultScreen(global.dpy)),InputOutput,DefaultVisual(global.dpy,DefaultScreen(global.dpy))\
-                    ,CWBackPixel, &attributes);
-   set_aspect_ratio();
-   XSelectInput(global.dpy, global.w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask|ExposureMask);
-  }
-  XMapWindow(global.dpy, global.w);
-  XStoreName(global.dpy,global.w,"hackvr");
-  global.greyscale=1;
-  global.zsort=1;
-  global.shape[0]=0;//we'll allocate as we need more.
-  global.gc=XCreateGC(global.dpy, global.w, 0, 0);
-
-  if(global.red_and_blue) {
-   global.width=WIDTH;
-  } else {
-   global.width=WIDTH*global.split_screen;
-  }
-  global.height=HEIGHT;
-
-  global.backbuffer=XCreatePixmap(global.dpy,global.w,global.width,global.height,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
-  global.cleanbackbuffer=XCreatePixmap(global.dpy,global.w,global.width,global.height,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
-
-//backbuffer is uninitialized
-  global.backgc=XCreateGC(global.dpy,global.backbuffer,0,0);
-
-  cursor=XCreateFontCursor(global.dpy,XC_crosshair);
-  XDefineCursor(global.dpy, global.w, cursor);
-
-  XAllocNamedColor(global.dpy, global.color_map, "green", &global.green, &global.green);
-  XAllocNamedColor(global.dpy, global.color_map, "red", &global.red, &global.red);
-  XAllocNamedColor(global.dpy, global.color_map, "blue", &global.blue, &global.blue);
-  XAllocNamedColor(global.dpy, global.color_map, "red", &global.redblue[0], &global.redblue[0]);
-  XAllocNamedColor(global.dpy, global.color_map, "blue", &global.redblue[1], &global.redblue[1]);
-  XSetForeground(global.dpy, global.gc, global.green.pixel);
-  XSetForeground(global.dpy, global.backgc, global.colors[0].pixel);//black. we're about to draw the blank background using this.
-  XSetBackground(global.dpy, global.gc, global.colors[160].pixel);
-  XSetBackground(global.dpy, global.backgc, global.colors[140].pixel);
-
-  XFillRectangle(global.dpy,global.cleanbackbuffer,global.backgc,0,0,global.width,global.height);
-  XSetForeground(global.dpy, global.backgc, global.green.pixel);
-
-//  XSetForeground(global.dpy, gc, whiteColor);
-// this was taking a "long" time.
-  printf("# generating sky... ");
-  skypixmap=XCreatePixmap(global.dpy,global.w,SKYW,SKYH,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
-  for(i=0;i<SKYH;i++) {
-   for(j=0;j<SKYW;j++) {
-    if(i==0) sky[i][j]=rand()%2;
-    else {
-     sky[i][j]=(SKYRULE >> ((!!sky[i-1][(j+(SKYW)-1)%(SKYW)]<<2) | (!!sky[i-1][j]<<1) | (!!sky[i-1][j+1%(SKYW)])) & 1);
-     if(sky[i][j]) {
-      XDrawPoint(global.dpy,skypixmap,global.backgc,j,i);
-     }
-    }
-   }
-  }
-  printf("done.\n");
-
-  global.mapxoff=global.width/2;
-  global.mapyoff=global.height/2;
-  global.drawminimap=0;
-  global.draw3d=1;
-  global.debug=0;
-  global.force_redraw=1;//use this for checking proper fps I guess.
-  camera.zoom=30.0l;
-  camera.xr=270;
-  camera.yr=270;
-  camera.zr=0;
-  global.mmz=1;
-  camera.p.x=0;
-  camera.p.z=6;
-  camera.p.y=5;
-  printf("# entering main loop\n");
-  for(;;) {
-    redraw=global.force_redraw;
-    while(XPending(global.dpy)) {//these are taking too long?
-     XNextEvent(global.dpy, &e);
-//     printf("# handling event with type: %d\n",e.type);
-     switch(e.type) {
-//       case Expose:
-//         if(e.xexpose.count == 0) redraw=1;
-//         break;
-       case MotionNotify:
-         redraw=1;
-         XQueryPointer(global.dpy,global.w,&root,&child,&global.rmousex,&global.rmousey,&global.mousex,&global.mousey,&mask);
-         break;
-       case ButtonPress:
-         redraw=1;
-         global.buttonpressed=e.xbutton.button;
-         break;
-       case ButtonRelease:
-         redraw=1;
-         global.buttonpressed=0;
-         break;
-       case ConfigureNotify:
-         redraw=1;
-         XGetGeometry(global.dpy,global.w,&root,&global.x,&global.y,&global.width,&global.height,&global.border_width,&global.depth);
-         if(global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1 )) / 4 * 3 != global.height) {
-          if(global.height * 3 / 4 == global.height) {
-           printf("math doesn't work.\n");
-          }
-          printf("# DERPY WM CANT TAKE A HINT %d / %d / 4 * 3 = %d != %d\n",global.width,global.split_screen,global.width /global.split_screen /4 * 3,global.height);
-          if(global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1)) / 4 * 3 < global.height) {
-           global.height=global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1)) / 4 * 3;
-          } else {
-           global.width=global.height * 3 / 4 * (global.split_screen / (global.red_and_blue ? global.split_screen : 1));
-          }
-         }
-         global.mapxoff=global.width/(global.split_screen / (global.red_and_blue ? global.split_screen : 1))/2;
-         global.mapyoff=global.height/2;
-         break;
-       case KeyPress:
-         redraw=1;
-         if(keypress_handler(XLookupKeysym(&e.xkey,0)) == -1) {
-          printf("# exiting\n");
-          return 0;
-         }
-         break;
-       default:
-         //printf("# received event with type: %d\n",e.type);
-         break;
-     }
-    }
-    switch(load_stdin()) {
-     case -1:
-      return 0;
-      break;
-     case 0:
-      break;
-     default:
-      redraw=1;
-      break;
-    }
-    //camera.yr+=2;
-    if(redraw) {
-     draw_screen(global.dpy,global.w,global.gc);
-    }
-    //usleep(10000);
-  }
-  return 0;
-}
diff --git a/slowcat.c b/slowcat.c
deleted file mode 100644
index facd2cc698c28107fbcf5f687c553260d1951d1f..0000000000000000000000000000000000000000
--- a/slowcat.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#define _BSD_SOURCE
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int main(int argc,char *argv[]) {
- short in;
- FILE *fp=stdin;
- if(argc < 2) {
-  fprintf(stderr,"usage: slowcat delay [file1] [file2] [...]\n");
-  return 1;
- }
- if(argc > 2) {
-  fp=fopen(argv[2],"r");
- }
- do {
-  while((in=fgetc(fp)) != -1) {
-   printf("%c",in);
-   if(in == '\n') {
-    fflush(stdout);
-    usleep(atoi(argv[1]));
-   }
-  }
-  fclose(fp);
-  argv++;
- } while((fp=fopen(argv[1],"r")));
- return 0;
-}
diff --git a/src/Makefile b/src/Makefile

index 136e8d26ec4fd974329f28007ea28438e147b49e..

index ..6ae7cee589a4edfafcaf9addb48e6fc58ccac8de 100644

--- a/src/Makefile
+++ b/src/Makefile
@@ -1,20 +1,21 @@
 ### if you want X11: CFLAGS=-Wall -pedantic -std=c99 -DGRAPHICAL
 ### and add graphics.o to hackvr build target.
 ### fuck it. I'll fix it later.
-CFLAGS=-Wall -pedantic -std=c99 -DGRAPHICAL
+CFLAGS=-Wall -pedantic -std=c99 -DGRAPHICAL -ffast-math
+#CFLAGS=-std=c99 -DGRAPHICAL -ffast-math

 all: hackvr slowcat

 hackvr: LDLIBS=-lm -lX11
-hackvr: hackvr.o graphics.o
+hackvr: hackvr.o graphics.o graphics_x11.o

-# x11.o: LDLIBS=-lm -lX11
+graphics_x11.o: LDLIBS=-lm -lX11

 hackvr.o: LDLIBS=-lm -lX11

 graphics.o: LDLIBS=-lm -lX11

 clean:
-	rm hackvr
-	rm slowcat
-	rm *.o
+	rm -f hackvr
+	rm -f slowcat
+	rm -f *.o
diff --git a/src/common.h b/src/common.h

index 8f59c55a3fc0d01e841a97ca1273064bce54d086..

index ..24011f7e8f8107b4f9fa7783465fa10fcc776497 100644

--- a/src/common.h
+++ b/src/common.h
@@ -31,68 +31,43 @@ struct camera {
   real zoom;
 } camera;

-struct c3_line {
+typedef struct c3_line {
  char *id;
  c3_t p1;
  c3_t p2;
-};
+} cs_l_t;
+
+typedef struct cs_shape {
+  char *id;
+  unsigned char len;
+  cs_t p[MAX_SIDES];
+} cs_s_t;

-struct c3_shape {//use array or linked list?
+typedef struct c2_shape {
+  char *id;
+  unsigned char len;
+  c2_t p[MAX_SIDES];
+} c2_s_t;
+
+typedef struct c3_shape {//use array or linked list?
   char *id;
   unsigned char len;
   c3_t p[MAX_SIDES];
-};
+} c3_s_t;

-struct mainwin {
+struct global {
   int x;
   int y;
-  unsigned int depth;
-  int mousex;
-  int mousey;
-  int rmousex;
-  int rmousey;
-  int buttonpressed;
-  unsigned int width;
-  unsigned int height;
-  unsigned int border_width;
-  XColor colors[256];
-  int xoff;
   int math_error;
-  int mapxoff;
-  int mapyoff;
-  int split_screen;
-  int split_flip;//1 or -1
   char *user;
-  char greyscale;
   char headless;
-  char drawminimap;//flag
-  char draw3d;//flag
   char debug;//flag
-  char drawsky;//flag
-  char zsort;
-  char red_and_blue;
-  char force_redraw;
   char selected_object[256];//meh
   real mmz;
-  XColor green;
-  XColor red;
-  XColor blue;
-  XColor redblue[2];
-  Colormap color_map;
-  Display *dpy;
-  Window w;
-  Pixmap backbuffer;
-  Pixmap cleanbackbuffer;
-  GC gc;
-  GC backgc;
   struct c3_shape *shape[SHAPES];
   int shapes;
   int derp;
-  int root_window;
   real split;
-  int oldfps;
-  int fps;
-  int oldtime;
 };

 #endif
diff --git a/src/config.h b/src/config.h

index 2e79efbbe3e00185c63a109b555abf2f9f0eb8a8..

index ..324d815893beeb737bfc845be72009b170bd3251 100644

--- a/src/config.h
+++ b/src/config.h
@@ -2,6 +2,11 @@
 #ifndef _HACKVR_CONFIG_H_
 #define _HACKVR_CONFIG_H_

+//Aspect Ratio:
+#define AR_W 4
+#define AR_H 3
+
+#define DEBUG 1
 #define WALK_SPEED 1
 #define SPLIT_SCREEN 1
 #define CAMERA_SEPARATION 4
@@ -10,5 +15,6 @@
 #define MAX_SIDES 8
 #define WIDTH 1024
 #define HEIGHT 768
+#define FORCE_REDRAW 1

 #endif
diff --git a/src/graphics.c b/src/graphics.c

index 31f02742f4fd71795cc27b214d671ddf037e30c2..

index ..a8a8e69850871cad9f172ae846d0e0626839587f 100644

--- a/src/graphics.c
+++ b/src/graphics.c
@@ -8,10 +8,6 @@
 #include <dirent.h>
 #include <stdlib.h>
 //#include <sys/select.h> //code to use select instead of non-blocking is commented out. might decide to use it later.
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#include <X11/Xutil.h> //for size hints
 #include <time.h>
 #define __USE_GNU //for longer math constants
 #include <math.h>
@@ -19,6 +15,10 @@
 #include "config.h"
 #include "common.h"

+//choose which graphic's end you want here I guess?
+#include "graphics_x11.h"
+#include "graphics.h"
+
 //typedef float real; //think this conflicts?

 //TODO: will have to make some pixmaps get resized when the window does.
@@ -28,10 +28,8 @@
 #define SKYW (WIDTH*5)
 #define SKYH (HEIGHT/2)

-Pixmap skypixmap;
-char sky[SKYH][SKYW];
-
-extern struct mainwin global;
+extern struct global global;
+struct gra_global gra_global;

 #ifdef GRAPHICAL

@@ -43,11 +41,11 @@ extern struct mainwin global;
 #define RIGHT   320.0
 #define LEFT    -320.0

-int c2sX(long double x) { return (global.width/(global.split_screen / (global.red_and_blue ? global.split_screen: 1))) * ((x + RIGHT) / (RIGHT *2)) + global.xoff; }
-int s2cX(long double x) { return (x/(global.width/(global.split_screen / (global.red_and_blue?global.split_screen :1))))*(RIGHT*2)-RIGHT; }
+int c2sX(real x) { return (gra_global.width/(gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen: 1))) * ((x + RIGHT) / (RIGHT *2)) + gra_global.xoff; }
+int s2cX(real x) { return (x/(gra_global.width/(gra_global.split_screen / (gra_global.red_and_blue?gra_global.split_screen :1))))*(RIGHT*2)-RIGHT; }

-int c2sY(long double y) { return global.height * ((TOP-y) / (TOP*2)); }
-int s2cY(long double y) { return -((y/global.height) * (TOP*2) - TOP); }
+int c2sY(real y) { return gra_global.height * ((TOP-y) / (TOP*2)); }
+int s2cY(real y) { return -((y/gra_global.height) * (TOP*2) - TOP); }

 cs_t c2_to_cs(c2_t p) {
  return (cs_t){c2sX(p.x),c2sY(p.y)};
@@ -56,22 +54,22 @@ c2_t cs_to_c2(cs_t p) {
  return (c2_t){s2cX(p.x),s2cY(p.y)};
 }

-long double distance2(c2_t p1,c2_t p2) {
+real distance2(c2_t p1,c2_t p2) {
  return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) ));
 }

-long double distance3(c3_t p1,c3_t p2) {
+real distance3(c3_t p1,c3_t p2) {
  return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) )+( (p1.z-p2.z)*(p1.z-p2.z) ));
 }

-long double points_to_angle(c2_t p1,c2_t p2) {
-  long double a=atan2l(p2.y-p1.y,p2.x-p1.x);
+real points_to_angle(c2_t p1,c2_t p2) {
+  real a=atan2l(p2.y-p1.y,p2.x-p1.x);
   return a>=0?a:M_PIl+M_PIl+a;
 }

-long double d2r(int d) {
+real d2r(int d) {
  while(d<0) d+=360;
- return (long double)(d%360) / (long double)180 * M_PIl;
+ return (real)(d%360) / (real)180 * M_PIl;
 }
 int r2d(real r) {
  return r / M_PIl * 180;
@@ -154,14 +152,21 @@ int get_2D_intersection_Y(x,y,d,x,z,d) {
 }
 */

-void draw_cs_line(cs_t p1,cs_t p2) {
-  XDrawLine(global.dpy,global.backbuffer,global.backgc,p1.x,p1.y,p2.x,p2.y);
-}
-
 void draw_c2_line(c2_t p1,c2_t p2) {
   draw_cs_line(c2_to_cs(p1),c2_to_cs(p2));
 }

+void draw_c3_shape(c3_s_t s) {//outlined. needs to be filled?
+  int i;
+  cs_s_t ss;
+  ss.id=s.id;//it shouldn't disappear and we shouldn't need to make a copy.
+  ss.len=s.len;
+  for(i=0;i<s.len+(s.len==1);i++) {
+   ss.p[i]=c3_to_cs(s.p[i]);
+  }
+  draw_cs_shape(ss);
+}
+
 #define MAGIC(x) (1.0l-(1.0l/powl(1.01l,(x)))) //??? might want to have some changables in here

 real magic(real x) {
@@ -237,17 +242,17 @@ c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE
 void draw_c3_line(c3_t p1,c3_t p2) {
 // if(!between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p1.x,p1.z}),0,90) ||
 //    !between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p2.x,p2.z}),0,90)) return;
- if(global.drawminimap == 1) {
+ if(gra_global.drawminimap == 1) {
   draw_c2_line((c2_t){(camera.p.x-2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x+2)*global.mmz,(camera.p.z-2)*global.mmz});
   draw_c2_line((c2_t){(camera.p.x+2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x-2)*global.mmz,(camera.p.z-2)*global.mmz});
   draw_c2_line((c2_t){p1.x*global.mmz,p1.z*global.mmz},(c2_t){p2.x*global.mmz,p2.z*global.mmz});
  }
- if(global.drawminimap == 2) {//map rotates.
+ if(gra_global.drawminimap == 2) {//map rotates.
   c3_t t1=rotate_c3_yr(p1,camera.p,d2r(camera.yr));
   c3_t t2=rotate_c3_yr(p2,camera.p,d2r(camera.yr));
   draw_c2_line((c2_t){t1.x*global.mmz,t1.z*global.mmz},(c2_t){t2.x*global.mmz,t2.z*global.mmz});
  }
- if(global.draw3d != 0) draw_c2_line(c3_to_c2(p1),c3_to_c2(p2));
+ if(gra_global.draw3d != 0) draw_c2_line(c3_to_c2(p1),c3_to_c2(p2));
  if(global.debug) {

  }
@@ -303,16 +308,6 @@ void HatchLines(c2_t p1,c2_t p2,c2_t p3,int density) {
 //black out the rest of the triangle first?
 //sounds alright to me...

-void draw_cs_text(cs_t p,char *text) {
- char t[256];
- int direction,ascent,descent;
- XFontStruct *font=XLoadQueryFont(global.dpy,"fixed");
- XCharStruct overall;
- snprintf(t,sizeof(t)-1,"%s",text);
- XTextExtents(font,text,strlen(text),&direction,&ascent,&descent,&overall);
- XDrawString(global.dpy,global.backbuffer,global.backgc,p.x,p.y+(descent+ascent),text,strlen(text));
-}
-
 void draw_c2_text(c2_t p,char *text) {
  cs_t p2=c2_to_cs(p);
  draw_cs_text(p2,text);
@@ -331,74 +326,6 @@ cs_t *c3s_to_css(c3_t *p3,int len) {
  return ps;
 }*/

-void draw_c3_shape(struct c3_shape s) {
-// char line[1024];
- int i=0;
- int h;//,w
- XPoint p[s.len+(s.len==1)];
- cs_t tmp;
- for(i=0;i<s.len+(s.len==1);i++) {
-  tmp=c3_to_cs(s.p[i]);
-  p[i]=(XPoint){tmp.x,tmp.y};
- }
- if(global.draw3d == 1) { // wireframe
-  switch(s.len) {
-   case 1:
-    //w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
-    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
-    p[0].x-=h;
-    p[0].y-=h;
-    XDrawArc(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
-    break;
-   case 2:
-    XDrawLine(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
-    break;
-   default:
-    for(i=0;i<s.len;i++) {
-     XDrawLines(global.dpy,global.backbuffer,global.backgc,p,s.len,CoordModeOrigin);
-    }
-    break;
-  }
- }
- if(global.draw3d == 2) { //draw it filled in
-  switch(s.len) {
-   case 1:
-    //w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
-    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
-    p[0].x-=h;
-    p[0].y-=h;
-    XFillArc(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
-    break;
-   case 2:
-    XDrawLine(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
-    break;
-   default:
-    XFillPolygon(global.dpy,global.backbuffer,global.backgc,p,s.len,Convex,CoordModeOrigin);
-    break;
-  }
- }
-// if(global.draw3d == 3) { //hashed
-//  XSetForeground(global.dpy, global.backgc, global.colors[0].pixel);
-  //XDrawFilledShape(c3_to_cs(t.p1),c3_to_cs(t.p2),c3_to_cs(t.p3));//clear out this triangle.
-//  XSetForeground(global.dpy, global.backgc, global.green.pixel);
-  //upgrade me! DrawHatchedTriangle(t,10 - (shitdist(t,camera.p) / 10));//how to get density?
-// }
-/* if(global.debug) {
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p1.x,t.p1.y,t.p1.z);
-  draw_c3_text(t.p1,line);
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p2.x,t.p2.y,t.p2.z);
-  draw_c3_text(t.p2,line);
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p3.x,t.p3.y,t.p3.z);
-  draw_c3_text(t.p3,line);
-*/
-// }
-}
-
-typedef struct {
- struct c3_shape *s;
- real d;
-} zsort_t;
-
 int compar(zsort_t *a,zsort_t *b) {
  return ((a->d) > (b->d));
 }
@@ -406,80 +333,80 @@ int compar(zsort_t *a,zsort_t *b) {

 /*
 void draw_c3_point_text(c3_t p,char *text) {
- char coords[256];
+ char tmp[256];
  int direction,ascent,descent;
  cs_t p2;
  p2=c3_to_cs(p);
- snprintf(coords,sizeof(coords)-1,"(%Lf,%Lf,%Lf)",p.x,p.y,p.z);
+ snprintf(tmp,sizeof(tmp)-1,"(%Lf,%Lf,%Lf)",p.x,p.y,p.z);
  XTextExtents(font,text,strlen(text),&direction,&ascent,&descent,&overall);
- XDrawString(global.dpy,global.backbuffer,global.backgc,p2.x,p2.y+(descent+ascent),coords,strlen(coords));
+ XDrawString(global.dpy,global.backbuffer,global.backgc,p2.x,p2.y+(descent+ascent),tmp,strlen(tmp));
 }*/

-void draw_screen(Display *dpy,Window w,GC gc) {
+//push a string back into stdin so it can be read by the file loader. :P
+int selfcommand(char *s) {
+ char t;
+ if(!strlen(s)) return 0;
+ ungetc(s[strlen(s)-1],stdin);
+ t=s[strlen(s)-1];
+ s[strlen(s)-1]=0;
+ selfcommand(s);
+ putchar(t);
+ return 0;
+}
+#endif
+
+void draw_screen() {
   int i;
   int colori=100;
   int cn=0;//camera number.
-  XFontStruct *font=XLoadQueryFont(global.dpy,"fixed");
-  XCharStruct overall;
-  int direction,ascent,descent;
-  char coords[256];
-  XGCValues gcval;
+  char tmp[256];
   zsort_t zs[SHAPES];
-  XCopyArea(global.dpy,global.cleanbackbuffer,global.backbuffer,gc,0,0,global.width,global.height,0,0);//clear the backbuffer.
-//  XCopyPlane(global.dpy,global.cleanbackbuffer,global.backbuffer,gc,0,0,global.width,global.height,0,0,1);//clear the backbuffer.

-  XRectangle cliprect;
-  cliprect.x=0;
-  cliprect.y=0;
-  cliprect.width=global.width/global.split_screen;
-  cliprect.height=global.height;
+  clear_backbuffer();

   real oldx=camera.p.x;
   real oldz=camera.p.z;
-  if(global.split_screen > 1) {
-   camera.p.z-=(global.split_flip)*((global.split/global.split_screen)*cosl(d2r(camera.yr+180)));
-   camera.p.x-=(global.split_flip)*((global.split/global.split_screen)*sinl(d2r(camera.yr+180)));
+  if(gra_global.split_screen > 1) {
+   camera.p.z-=(gra_global.split_flip)*((gra_global.split/gra_global.split_screen)*cosl(d2r(camera.yr+180)));
+   camera.p.x-=(gra_global.split_flip)*((gra_global.split/gra_global.split_screen)*sinl(d2r(camera.yr+180)));
   }
-  for(cn=0;cn<global.split_screen;cn++) {
-    if(global.red_and_blue) {
+  for(cn=0;cn<gra_global.split_screen;cn++) {
+    if(gra_global.red_and_blue) {
      //set color for left half to red and right half to blue
      //and draw mode for the gc to GXOr
-     global.xoff=0;
-     gcval.function=GXor;
-     XChangeGC(global.dpy,global.backgc,GCFunction,&gcval);
+     red_and_blue_magic();
+     gra_global.xoff=0;//we're overlapping our drawing so no offset based on camera.
     } else {
-     global.xoff=(global.width/global.split_screen)*cn;
+     gra_global.xoff=(gra_global.width/gra_global.split_screen)*cn;
+    }
+    if(!gra_global.red_and_blue) {
+     set_clipping_rectangle(gra_global.xoff,0,gra_global.width/gra_global.split_screen,gra_global.height);//
     }
-    if(!global.red_and_blue) XSetClipRectangles(global.dpy,global.backgc,global.xoff,0,&cliprect,1,Unsorted);
     //if(global.drawminimap == 3) { draw_graph(magic); continue; }
-    if(global.drawsky) {
-     XCopyArea(global.dpy,skypixmap,global.backbuffer,global.backgc,((camera.yr*5)+SKYW)%SKYW,0,WIDTH,global.height/2,0,0);
+    if(gra_global.drawsky) {
+     //XCopyArea(global.dpy,skypixmap,global.backbuffer,global.backgc,((camera.yr*5)+SKYW)%SKYW,0,WIDTH,global.height/2,0,0);
     }
-    if(global.draw3d) {
-//      draw_c2_line((c2_t){LEFT,0},(c2_t){RIGHT,0}); //horizon
+    if(gra_global.draw3d) {
+      draw_c2_line((c2_t){LEFT,0},(c2_t){RIGHT,0}); //horizon
     }
-    if(time(0) == global.oldtime) {
-     global.fps++;
+    if(time(0) == gra_global.oldtime) {
+     gra_global.fps++;
     }
     else {
-     global.oldtime=time(0);
-     global.oldfps=global.fps;
-     global.fps=0;
+     gra_global.oldtime=time(0);
+     gra_global.oldfps=gra_global.fps;
+     gra_global.fps=0;
     }
     //XSetForeground(global.dpy, global.backgc, global.green.pixel);
     if(global.debug) {
-      snprintf(coords,sizeof(coords)-1,"debug: %s minimap: %d 3d: %d fps: %d shapes: %d",global.debug?"on":"off",global.drawminimap,global.draw3d,global.oldfps,global.shapes);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*1,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"x: %d y: %d",global.mousex,global.mousey);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*2,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"cx: %Lf cy: %Lf cz: %Lf",camera.p.x,camera.p.y,camera.p.z);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*3,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"xr: %d yr: %d zr: %d",camera.xr,camera.yr,camera.zr);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*4,coords,strlen(coords));
+      snprintf(tmp,sizeof(tmp)-1,"debug: %s minimap: %d 3d: %d fps: %d shapes: %d",global.debug?"on":"off",gra_global.drawminimap,gra_global.draw3d,gra_global.oldfps,global.shapes);
+      draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+10},tmp);
+      snprintf(tmp,sizeof(tmp)-1,"x: %d y: %d",gra_global.mousex,gra_global.mousey);
+      draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+20},tmp);
+      snprintf(tmp,sizeof(tmp)-1,"cx: %Lf cy: %Lf cz: %Lf",camera.p.x,camera.p.y,camera.p.z);
+      draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+30},tmp);
+      snprintf(tmp,sizeof(tmp)-1,"xr: %d yr: %d zr: %d",camera.xr,camera.yr,camera.zr);
+      draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+40},tmp);
     }

 //  if(global.drawminimap) {//this isn't even useful I guess.
@@ -539,11 +466,11 @@ void draw_screen(Display *dpy,Window w,GC gc) {
    }
    for(i=0;global.shape[i];i++) {
     //now we pick the color of this triangle!
-    if(global.red_and_blue) {
+    if(gra_global.red_and_blue) {
      if(cn==0) {
-      XSetForeground(global.dpy,global.backgc,global.red.pixel);
+//      XSetForeground(global.dpy,global.backgc,global.red.pixel);//???
      } else {
-      XSetForeground(global.dpy,global.backgc,global.blue.pixel);
+//      XSetForeground(global.dpy,global.backgc,global.blue.pixel);//???
      }
 //tests of blending grayscale with red and blue
 //     draw_c3_triangle(*(zs[i].t));
@@ -551,29 +478,27 @@ void draw_screen(Display *dpy,Window w,GC gc) {
      if(!strcmp(global.selected_object,zs[i].s->id)) {
       //XSetForeground(global.dpy,global.backgc,global.green.pixel);
      } else {
-      if(global.greyscale) {
+      if(gra_global.greyscale) {
        if(zs[i].d > 0) {
         if(zs[i].d < 100) {
          colori=zs[i].d;
         }
        }
        colori=(int)(zs[i].d)%100;
-       XSetForeground(global.dpy,global.backgc,global.colors[(int)(100.0-(colori))].pixel);//picking the color here only works if...
+//       XSetForeground(global.dpy,global.backgc,global.colors[(int)(100.0-(colori))].pixel);//picking the color here only works if...
       }
      }
     }
+    set_color();
     draw_c3_shape(*(zs[i].s));
    }
-   XSetForeground(global.dpy, global.backgc, global.green.pixel);
+//   XSetForeground(global.dpy, global.backgc, global.green.pixel);
    if(global.debug) {
-    snprintf(coords,sizeof(coords)-1,"selected object: %s",global.selected_object);
-    XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-    XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*5,coords,strlen(coords));
+    snprintf(tmp,sizeof(tmp)-1,"selected object: %s",global.selected_object);
+    draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+50},tmp);
    }
-   camera.p.z+=(global.split_flip)*(global.split*cosl(d2r(camera.yr+180)));
-   camera.p.x+=(global.split_flip)*(global.split*sinl(d2r(camera.yr+180)));
-
-
+   camera.p.z+=(gra_global.split_flip)*(gra_global.split*cosl(d2r(camera.yr+180)));
+   camera.p.x+=(gra_global.split_flip)*(gra_global.split*sinl(d2r(camera.yr+180)));
   }

 //TODO: figure out what all this shit is and either update or remove.
@@ -592,12 +517,12 @@ void draw_screen(Display *dpy,Window w,GC gc) {
   y1=global.mousey;
   real a=points_to_angle((c2_t){0,0},cs_to_c2((cs_t){x1,y1}));

-  snprintf(coords,sizeof(coords)-1,"%llf",a);
-  XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*6,coords,strlen(coords));
-  snprintf(coords,sizeof(coords)-1,"%llf",points_to_angle(cs_to_c2((cs_t){global.mousex,global.mousey}),(c2_t){0,0})+(M_PIl/2));
-  XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*7,coords,strlen(coords));
+  snprintf(tmp,sizeof(tmp)-1,"%llf",a);
+  XTextExtents(font,tmp,strlen(tmp),&direction,&ascent,&descent,&overall);
+  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*6,tmp,strlen(tmp));
+  snprintf(tmp,sizeof(tmp)-1,"%llf",points_to_angle(cs_to_c2((cs_t){global.mousex,global.mousey}),(c2_t){0,0})+(M_PIl/2));
+  XTextExtents(font,tmp,strlen(tmp),&direction,&ascent,&descent,&overall);
+  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*7,tmp,strlen(tmp));
   XDrawLine(global.dpy,w,gc,global.mousex,global.mousey,global.width/2,global.height/2);

   real c=cosl(d2r(camera.yr) - a) * distance((c2_t){x1,y1},(c2_t){WIDTH/2,HEIGHT/2});
@@ -607,300 +532,5 @@ void draw_screen(Display *dpy,Window w,GC gc) {
 */
   camera.p.x = oldx;
   camera.p.z = oldz; //-= cn*CAMERA_SEPARATION;
-//  XClearWindow(global.dpy, w);
-  XCopyArea(global.dpy,global.backbuffer,w,gc,0,0,global.width,global.height,0,0);//move backbuffer to window
-//  XCopyPlane(global.dpy,global.backbuffer,w,gc,0,0,global.width,global.height,0,0,0x000100);//move backbuffer to window
-}
-
-void set_aspect_ratio() {
- XSizeHints *hints=XAllocSizeHints();
- hints->min_aspect.x=4*(global.split_screen / (global.red_and_blue ? global.split_screen : 1));
- hints->min_aspect.y=3;
- hints->max_aspect.x=4*(global.split_screen / (global.red_and_blue ? global.split_screen : 1));
- hints->max_aspect.y=3;
- hints->flags=PAspect;
- XSetWMNormalHints(global.dpy,global.w,hints);
-}
-#endif
-
-#ifdef GRAPHICAL
-//push a string back into stdin so it can be read by the file loader. :P
-int selfcommand(char *s) {
- char t;
- if(!strlen(s)) return 0;
- ungetc(s[strlen(s)-1],stdin);
- t=s[strlen(s)-1];
- s[strlen(s)-1]=0;
- selfcommand(s);
- putchar(t);
- return 0;
-}
-
-int keypress_handler(int sym) {
-  char line[1024];
-  real tmpx;
-//  real tmpy; //unused atm
-  real tmpz;
-  switch(sym) {
-   case XK_Return:
-    snprintf(line,sizeof(line)-1,"%s action %s\n",global.user,global.selected_object);
-    selfcommand(line);
-    break;
-   case XK_Up:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+90));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+90));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Down:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+270));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+270));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Left:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Right:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+180));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+180));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_w:
-    camera.p.y+=1;
-    snprintf(line,sizeof(line)-1,"%s move 0 1 0 0 0 0 0 0 0\n",global.user);
-    selfcommand(line);
-    break;
-   case XK_s:
-    camera.p.y-=1;
-    snprintf(line,sizeof(line)-1,"%s move 0 -1 0 0 0 0 0 0 0\n",global.user);
-    selfcommand(line);
-    break;
-   case XK_r:
-    camera.xr+=5;
-    while(camera.xr > 360) camera.xr-=360;
-    break;
-   case XK_y:
-    camera.xr-=5;
-    while(camera.xr < 0) camera.xr+=360;
-    break;
-   case XK_q:
-    camera.yr+=5;
-    while(camera.yr > 360) camera.yr-=360;
-    break;
-   case XK_e:
-    camera.yr-=5;
-    while(camera.yr < 0) camera.yr+=360;
-    break;
-   case XK_u:
-    camera.zr+=5;
-    while(camera.zr > 360) camera.zr-=360;
-    break;
-   case XK_o:
-    camera.zr-=5;
-    while(camera.zr < 0) camera.zr+=360;
-    break;
-   case XK_z: camera.zoom+=1; break;
-   case XK_x: camera.zoom-=1; break;
-   case XK_c: global.mmz*=1.1; break;
-   case XK_v: global.mmz/=1.1; break;
-   case XK_h: global.split+=1; break;
-   case XK_j: global.split-=1; break;
-   case XK_d:
-    global.debug ^= 1;
-    break;
-   case XK_f:
-    global.derp ^= 1;
-    break;
-   case XK_m:
-    global.drawminimap += 1;
-    global.drawminimap %= 4;
-    break;
-   case XK_a:
-    global.drawsky ^= 1;
-    break;
-   case XK_3:
-    global.draw3d += 1;
-    global.draw3d %= 4;
-    break;
-   case XK_Escape:
-    return -1;
-   default:
-    return 0;
-    break;
- }
- return 1;
-}
-#endif
-
-int x11_init() {
- int i,j;
- char tmp[64];
- Cursor cursor;
- XSetWindowAttributes attributes;
-// Window root,child;//why do I have this?
-//  XColor toss;
- printf("# Opening X Display... (%s)\n",getenv("DISPLAY"));
- if((global.dpy = XOpenDisplay(0)) == NULL) return printf("# failure.\n"),2;
- else printf("# done.\n");
- global.color_map=DefaultColormap(global.dpy, DefaultScreen(global.dpy));
- printf("# generating grays...\n");
- for(i=0;i<=100;i++) {
-  snprintf(tmp,sizeof(tmp),"gray%d",i);
-  XAllocNamedColor(global.dpy,global.color_map,tmp,&global.colors[i],&global.colors[i]);
- }
- printf("# done.\n");
- assert(global.dpy);
- global.split_screen=SPLIT_SCREEN;
- global.split_flip=-1;
- global.split=5;
- global.root_window=0;
- global.red_and_blue=RED_AND_BLUE;
- //global.colors[0]=BlackPixel(global.dpy,DefaultScreen(global.dpy));
-// int whiteColor = //WhitePixel(global.dpy, DefaultScreen(global.dpy));
- attributes.background_pixel=global.colors[0].pixel;
- if(global.root_window) {
-  global.w = DefaultRootWindow(global.dpy); //this is still buggy.
- } else {
-  global.w = XCreateWindow(global.dpy,DefaultRootWindow(global.dpy),0,0,WIDTH*(global.split_screen / (global.red_and_blue ? global.split_screen : 1)),HEIGHT,1,DefaultDepth(global.dpy,DefaultScreen(global.dpy)),InputOutput,DefaultVisual(global.dpy,DefaultScreen(global.dpy))\
-                   ,CWBackPixel, &attributes);
-  set_aspect_ratio();
-  XSelectInput(global.dpy, global.w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask|ExposureMask);
- }
- XMapWindow(global.dpy, global.w);
- XStoreName(global.dpy,global.w,"hackvr");
- global.greyscale=1;
- global.zsort=1;
- global.shape[0]=0;//we'll allocate as we need more.
- global.gc=XCreateGC(global.dpy, global.w, 0, 0);
-
- if(global.red_and_blue) {
-  global.width=WIDTH;
- } else {
-  global.width=WIDTH*global.split_screen;
- }
- global.height=HEIGHT;
-
- global.backbuffer=XCreatePixmap(global.dpy,global.w,global.width,global.height,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
- global.cleanbackbuffer=XCreatePixmap(global.dpy,global.w,global.width,global.height,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
-
-//backbuffer is uninitialized
- global.backgc=XCreateGC(global.dpy,global.backbuffer,0,0);
-
- cursor=XCreateFontCursor(global.dpy,XC_crosshair);
- XDefineCursor(global.dpy, global.w, cursor);
-
- XAllocNamedColor(global.dpy, global.color_map, "green", &global.green, &global.green);
- XAllocNamedColor(global.dpy, global.color_map, "red", &global.red, &global.red);
- XAllocNamedColor(global.dpy, global.color_map, "blue", &global.blue, &global.blue);
- XAllocNamedColor(global.dpy, global.color_map, "red", &global.redblue[0], &global.redblue[0]);
- XAllocNamedColor(global.dpy, global.color_map, "blue", &global.redblue[1], &global.redblue[1]);
- XSetForeground(global.dpy, global.gc, global.green.pixel);
- XSetForeground(global.dpy, global.backgc, global.colors[0].pixel);//black. we're about to draw the blank background using this.
- XSetBackground(global.dpy, global.gc, global.colors[160].pixel);
- XSetBackground(global.dpy, global.backgc, global.colors[140].pixel);
-
- XFillRectangle(global.dpy,global.cleanbackbuffer,global.backgc,0,0,global.width,global.height);
- XSetForeground(global.dpy, global.backgc, global.green.pixel);
-
-//  XSetForeground(global.dpy, gc, whiteColor);
-// this was taking a "long" time.
- printf("# generating sky... ");
- skypixmap=XCreatePixmap(global.dpy,global.w,SKYW,SKYH,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
- for(i=0;i<SKYH;i++) {
-  for(j=0;j<SKYW;j++) {
-   if(i==0) sky[i][j]=rand()%2;
-   else {
-    sky[i][j]=(SKYRULE >> ((!!sky[i-1][(j+(SKYW)-1)%(SKYW)]<<2) | (!!sky[i-1][j]<<1) | (!!sky[i-1][j+1%(SKYW)])) & 1);
-    if(sky[i][j]) {
-     XDrawPoint(global.dpy,skypixmap,global.backgc,j,i);
-    }
-   }
-  }
- }
- printf("done.\n");
-
- global.mapxoff=global.width/2;
- global.mapyoff=global.height/2;
- global.drawminimap=0;
- global.draw3d=1;
- global.force_redraw=1;//use this for checking proper fps I guess.
- camera.zoom=30.0l;
- camera.xr=270;
- camera.yr=270;
- camera.zr=0;
- global.mmz=1;
- camera.p.x=0;
- camera.p.z=6;
- camera.p.y=5;
- return 0;
-}
-
-int x11_event_handler() {
- int redraw=0;
- XEvent e;
- Window child,root;
- //what sets mask?
- unsigned int mask;
- while(XPending(global.dpy)) {//these are taking too long?
-  XNextEvent(global.dpy, &e);
-//     printf("# handling event with type: %d\n",e.type);
-  switch(e.type) {
-//       case Expose:
-//         if(e.xexpose.count == 0) redraw=1;
-//         break;
-    case MotionNotify:
-      XQueryPointer(global.dpy,global.w,&root,&child,&global.rmousex,&global.rmousey,&global.mousex,&global.mousey,&mask);
-      redraw=1;
-      break;
-    case ButtonPress:
-      redraw=1;
-      global.buttonpressed=e.xbutton.button;
-      break;
-    case ButtonRelease:
-      redraw=1;
-      global.buttonpressed=0;
-      break;
-    case ConfigureNotify:
-      redraw=1;
-      XGetGeometry(global.dpy,global.w,&root,&global.x,&global.y,&global.width,&global.height,&global.border_width,&global.depth);
-      if(global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1 )) / 4 * 3 != global.height) {
-       if(global.height * 3 / 4 == global.height) {
-        printf("math doesn't work.\n");
-       }
-       printf("# DERPY WM CANT TAKE A HINT %d / %d / 4 * 3 = %d != %d\n",global.width,global.split_screen,global.width /global.split_screen /4 * 3,global.height);
-       if(global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1)) / 4 * 3 < global.height) {
-        global.height=global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1)) / 4 * 3;
-       } else {
-        global.width=global.height * 3 / 4 * (global.split_screen / (global.red_and_blue ? global.split_screen : 1));
-       }
-      }
-      global.mapxoff=global.width/(global.split_screen / (global.red_and_blue ? global.split_screen : 1))/2;
-      global.mapyoff=global.height/2;
-      break;
-    case KeyPress:
-      redraw=1;
-      if(keypress_handler(XLookupKeysym(&e.xkey,0)) == -1) {
-       printf("# exiting\n");
-       return -1;
-      }
-      break;
-    default:
-      //printf("# received event with type: %d\n",e.type);
-      break;
-  }
- }
- return redraw;
+  flipscreen();
 }
diff --git a/src/graphics.h b/src/graphics.h

index ff17b9ae15a469c09253ffbc66f75633deb08d1f..

index ..6f28d1efdce0a77401447a6e4d06b8d9cfe53a1b 100644

--- a/src/graphics.h
+++ b/src/graphics.h
@@ -1,11 +1,51 @@
 #ifndef _HACKVR_GRAPHICS_H_
 #define _HACKVR_GRAPHICS_H_

-#include <X11/Xlib.h>
+//#include <X11/Xlib.h>//this should be in the x11 one, not this one.

-int x11_init();
-int x11_event_handler();
-void draw_screen(Display *dpy,Window w,GC gc);
+struct gra_global {
+  unsigned int width;
+  unsigned int height;
+  int mousex;
+  int mousey;
+  int greyscale;
+  int xoff;
+  int split_screen;
+  int split;
+  int split_flip;
+  char force_redraw;
+  char red_and_blue;
+  unsigned int depth;//???
+  unsigned int border_width;
+  int oldtime;
+  int fps;
+  int oldfps;
+  char zsort;
+  char drawminimap;
+  char drawsky;
+  char draw3d;
+  int mapxoff;
+  int mapyoff;
+  int rmousex;
+  int rmousey;
+  int buttonpressed;
+};
+
+typedef struct {
+ struct c3_shape *s;
+ real d;
+} zsort_t;
+
+int graphics_init();
+int graphics_event_handler();
+void draw_screen();
 void set_aspect_ratio();
+int selfcommand(char *s);
+cs_t c3_to_cs(c3_t p);
+real d2r(int d);
+real shitdist(struct c3_shape s,c3_t p);
+
+
+int compar(zsort_t *a,zsort_t *b);

 #endif
diff --git a/src/graphics_opengl.c b/src/graphics_opengl.c
new file mode 100644
index 0000000000000000000000000000000000000000..9e200de2a528b4144d1182209a8f50510e0b7938
--- /dev/null
+++ b/src/graphics_opengl.c
@@ -0,0 +1,96 @@
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <GL/glut.h>
+
+GLenum doubleBuffer;
+GLubyte ubImage[65536];
+
+void draw_cs_line(cs_t p1,cs_t p2) {
+
+}
+
+void draw_cs_text() {
+
+}
+
+void draw_c3_shape() {
+ //oh lawdy... this should be draw_cs_shape...
+}
+
+static void
+graphics_init(void)
+{
+  GLenum type;
+  int j;
+  GLubyte *img;
+  GLsizei imgWidth = 128;
+
+  type = GLUT_RGB;
+  type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
+  glutInitDisplayMode(type);
+  glutCreateWindow("ABGR extension");
+  if (!glutExtensionSupported("GL_EXT_abgr")) {
+    printf("Couldn't find abgr extension.\n");
+    exit(0);
+  }
+
+  glMatrixMode(GL_PROJECTION);
+  glLoadIdentity();
+  gluPerspective(60.0, 1.0, 0.1, 1000.0);
+  glMatrixMode(GL_MODELVIEW);
+  glDisable(GL_DITHER);
+
+  glutKeyboardFunc(keypress_handler);
+  glutDisplayFunc(draw_screen);
+
+}
+
+/* ARGSUSED1 */
+static void
+keypress_handler(unsigned char key, int x, int y)
+{
+  switch (key) {
+  case 27:
+    exit(0);
+  }
+}
+
+static void draw_screen(void)
+{
+
+  glClearColor(0.0, 0.0, 0.0, 1.0);
+  glClear(GL_COLOR_BUFFER_BIT);
+
+
+  glRasterPos3f(0.2, -0.8, -1.5);
+  glDrawPixels(128, 128, GL_RGBA, GL_UNSIGNED_BYTE, ubImage);
+
+  if (doubleBuffer) {
+    glutSwapBuffers();
+  } else {
+    glFlush();
+  }
+}
+
+static void
+Args(int argc, char **argv)
+{
+  GLint i;
+
+  doubleBuffer = GL_TRUE;
+
+  for (i = 1; i < argc; i++) {
+    if (strcmp(argv[i], "-sb") == 0) {
+      doubleBuffer = GL_FALSE;
+    } else if (strcmp(argv[i], "-db") == 0) {
+      doubleBuffer = GL_TRUE;
+    }
+  }
+}
+
+void graphics_event_handler() {
+  glutMainLoopUpdate();
+  return 0;             /* ANSI C requires main to return int. */
+}
diff --git a/src/graphics_x11.c b/src/graphics_x11.c
new file mode 100644
index 0000000000000000000000000000000000000000..1b3166499cd0ee1e442cf59cee43b3477c1c780d
--- /dev/null
+++ b/src/graphics_x11.c
@@ -0,0 +1,448 @@
+#define _POSIX_C_SOURCE 200809L //for fileno and strdup
+#define _BSD_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdlib.h>
+//#include <sys/select.h> //code to use select instead of non-blocking is commented out. might decide to use it later.
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <X11/cursorfont.h>
+#include <X11/Xutil.h> //for size hints
+#include <time.h>
+#define __USE_GNU //for longer math constants
+#include <math.h>
+
+#include "config.h"
+#include "common.h"
+#include "graphics.h"
+#include "graphics_x11.h"
+
+//typedef float real; //think this conflicts?
+
+//TODO: will have to make some pixmaps get resized when the window does.
+//for now set them to be as big as you think you'll ever resize the window to.
+
+#define SKYRULE 90
+#define SKYW (WIDTH*5)
+#define SKYH (HEIGHT/2)
+
+Pixmap skypixmap;
+char sky[SKYH][SKYW];
+
+extern struct global global;
+extern struct gra_global gra_global;
+struct x11_global x11_global;
+
+#ifdef GRAPHICAL
+
+void draw_cs_line(cs_t p1,cs_t p2) {
+  XDrawLine(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p1.x,p1.y,p2.x,p2.y);
+}
+
+void draw_cs_text(cs_t p,char *text) {
+ char t[256];
+ int direction,ascent,descent;
+ XFontStruct *font=XLoadQueryFont(x11_global.dpy,"fixed");
+ XCharStruct overall;
+ snprintf(t,sizeof(t)-1,"%s",text);
+ XTextExtents(font,text,strlen(text),&direction,&ascent,&descent,&overall);
+ XDrawString(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p.x,p.y+(descent+ascent),text,strlen(text));
+}
+
+void draw_cs_shape(cs_s_t s) {//this is implemented as draw_cs_line... hrm. it could be moved up to graphics.c? probl no.
+  int i;
+  if(gra_global.draw3d == 1) { //wireframe
+    for(i=0;i<s.len+(s.len==1);i++) {//this shape is closed!
+      draw_cs_line(s.p[i],s.p[(i+1)%(s.len+(s.len==1))]);
+    }
+  }
+  if(gra_global.draw3d == 2) { //filled in
+    XPoint Xp[s.len+(s.len==1)];
+    for(i=0;i<s.len+(s.len==1);i++) {
+     Xp[i]=(XPoint){s.p[i].x,s.p[i].y};
+    }
+    XFillPolygon(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,Xp,s.len,Convex,CoordModeOrigin);
+  }
+}
+
+//this needs to be taken out of this file and left to graphics.c
+#if 0
+void draw_c3_shape(c3_s_t s) {
+// char line[1024];
+ int i=0;
+ int h;//,w
+ XPoint p[s.len+(s.len==1)];
+ cs_t tmp;
+ for(i=0;i<s.len+(s.len==1);i++) {
+  tmp=c3_to_cs(s.p[i]);
+  p[i]=(XPoint){tmp.x,tmp.y};
+ }
+ if(global.draw3d == 1) { // wireframe
+  switch(s.len) {
+   case 1:
+    //w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
+    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
+    p[0].x-=h;
+    p[0].y-=h;
+    XDrawArc(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
+    break;
+   case 2:
+    XDrawLine(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
+    break;
+   default:
+    for(i=0;i<s.len;i++) {
+     XDrawLines(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p,s.len,CoordModeOrigin);
+    }
+    break;
+  }
+ }
+ if(global.draw3d == 2) { //draw it filled in
+  switch(s.len) {
+   case 1:
+    //w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
+    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
+    p[0].x-=h;
+    p[0].y-=h;
+    XFillArc(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
+    break;
+   case 2:
+    XDrawLine(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
+    break;
+   default:
+    XFillPolygon(x11_global.dpy,x11_global.backbuffer,x11_global.backgc,p,s.len,Convex,CoordModeOrigin);
+    break;
+  }
+ }
+// if(global.draw3d == 3) { //hashed
+//  XSetForeground(x11_global.dpy, x11_global.backgc, global.colors[0].pixel);
+  //XDrawFilledShape(c3_to_cs(t.p1),c3_to_cs(t.p2),c3_to_cs(t.p3));//clear out this triangle.
+//  XSetForeground(x11_global.dpy, x11_global.backgc, global.green.pixel);
+  //upgrade me! DrawHatchedTriangle(t,10 - (shitdist(t,camera.p) / 10));//how to get density?
+// }
+/* if(global.debug) {
+  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p1.x,t.p1.y,t.p1.z);
+  draw_c3_text(t.p1,line);
+  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p2.x,t.p2.y,t.p2.z);
+  draw_c3_text(t.p2,line);
+  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p3.x,t.p3.y,t.p3.z);
+  draw_c3_text(t.p3,line);
+*/
+// }
+}
+#endif
+
+//should I do clipping in each graphics lib or make graphics.c just have clipping stuff?
+void clear_backbuffer() {
+  XCopyArea(x11_global.dpy,x11_global.cleanbackbuffer,x11_global.backbuffer,x11_global.gc,0,0,gra_global.width,gra_global.height,0,0);
+}
+
+void set_clipping_rectangle(int x,int y,int width,int height) {
+  XRectangle cliprect;
+  cliprect.x=x;
+  cliprect.y=y;
+  cliprect.width=width;
+  cliprect.height=height;
+  XSetClipRectangles(x11_global.dpy,x11_global.backgc,x,y,&cliprect,1,Unsorted);
+}
+
+void red_and_blue_magic() {
+  XGCValues gcval;
+  gcval.function=GXor;
+  XChangeGC(x11_global.dpy,x11_global.backgc,GCFunction,&gcval);
+}
+
+void draw_sky() {
+  XCopyArea(x11_global.dpy,skypixmap,x11_global.backbuffer,x11_global.backgc,((camera.yr*5)+SKYW)%SKYW,0,WIDTH,gra_global.height/2,0,0);
+}
+
+void set_color() {
+  XSetForeground(x11_global.dpy,x11_global.backgc,x11_global.green.pixel);
+}
+
+void flipscreen() {
+  XCopyArea(x11_global.dpy,x11_global.backbuffer,x11_global.w,x11_global.gc,0,0,gra_global.width,gra_global.height,0,0);
+}
+
+void set_aspect_ratio() {
+ XSizeHints *hints=XAllocSizeHints();
+ hints->min_aspect.x=AR_W*(gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1));
+ hints->min_aspect.y=AR_H;
+ hints->max_aspect.x=AR_W*(gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1));
+ hints->max_aspect.y=AR_H;
+ hints->flags=PAspect;
+
+ XSetWMNormalHints(x11_global.dpy,x11_global.w,hints);
+}
+
+int keypress_handler(int sym) {
+  char line[1024];
+  real tmpx;
+//  real tmpy; //unused atm
+  real tmpz;
+  switch(sym) {
+   case XK_Return:
+    snprintf(line,sizeof(line)-1,"%s action %s\n",global.user,global.selected_object);
+    selfcommand(line);
+    break;
+   case XK_Up:
+    tmpx=WALK_SPEED*sinl(d2r(camera.yr+90));
+    tmpz=WALK_SPEED*cosl(d2r(camera.yr+90));
+    camera.p.x+=tmpx;
+    camera.p.z+=tmpz;
+    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
+    selfcommand(line);
+    break;
+   case XK_Down:
+    tmpx=WALK_SPEED*sinl(d2r(camera.yr+270));
+    tmpz=WALK_SPEED*cosl(d2r(camera.yr+270));
+    camera.p.x+=tmpx;
+    camera.p.z+=tmpz;
+    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
+    selfcommand(line);
+    break;
+   case XK_Left:
+    tmpx=WALK_SPEED*sinl(d2r(camera.yr));
+    tmpz=WALK_SPEED*cosl(d2r(camera.yr));
+    camera.p.x+=tmpx;
+    camera.p.z+=tmpz;
+    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
+    selfcommand(line);
+    break;
+   case XK_Right:
+    tmpx=WALK_SPEED*sinl(d2r(camera.yr+180));
+    tmpz=WALK_SPEED*cosl(d2r(camera.yr+180));
+    camera.p.x+=tmpx;
+    camera.p.z+=tmpz;
+    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
+    selfcommand(line);
+    break;
+   case XK_w:
+    camera.p.y+=1;
+    snprintf(line,sizeof(line)-1,"%s move 0 1 0 0 0 0 0 0 0\n",global.user);
+    selfcommand(line);
+    break;
+   case XK_s:
+    camera.p.y-=1;
+    snprintf(line,sizeof(line)-1,"%s move 0 -1 0 0 0 0 0 0 0\n",global.user);
+    selfcommand(line);
+    break;
+   case XK_r:
+    camera.xr+=5;
+    while(camera.xr > 360) camera.xr-=360;
+    break;
+   case XK_y:
+    camera.xr-=5;
+    while(camera.xr < 0) camera.xr+=360;
+    break;
+   case XK_q:
+    camera.yr+=5;
+    while(camera.yr > 360) camera.yr-=360;
+    break;
+   case XK_e:
+    camera.yr-=5;
+    while(camera.yr < 0) camera.yr+=360;
+    break;
+   case XK_u:
+    camera.zr+=5;
+    while(camera.zr > 360) camera.zr-=360;
+    break;
+   case XK_o:
+    camera.zr-=5;
+    while(camera.zr < 0) camera.zr+=360;
+    break;
+   case XK_z: camera.zoom+=1; break;
+   case XK_x: camera.zoom-=1; break;
+   case XK_c: global.mmz*=1.1; break;
+   case XK_v: global.mmz/=1.1; break;
+   case XK_h: global.split+=1; break;
+   case XK_j: global.split-=1; break;
+   case XK_d:
+    global.debug ^= 1;
+    break;
+   case XK_f:
+    global.derp ^= 1;
+    break;
+   case XK_m:
+    gra_global.drawminimap += 1;
+    gra_global.drawminimap %= 4;
+    break;
+   case XK_a:
+    gra_global.drawsky ^= 1;
+    break;
+   case XK_3:
+    gra_global.draw3d += 1;
+    gra_global.draw3d %= 4;
+    break;
+   case XK_Escape:
+    return -1;
+   default:
+    return 0;
+    break;
+ }
+ return 1;
+}
+#endif
+
+int graphics_init() {
+ int i,j;
+ char tmp[64];
+ Cursor cursor;
+ XSetWindowAttributes attributes;
+// Window root,child;//why do I have this?
+//  XColor toss;
+ printf("# Opening X Display... (%s)\n",getenv("DISPLAY"));
+ if((x11_global.dpy = XOpenDisplay(0)) == NULL) return printf("# failure.\n"),2;
+ else printf("# done.\n");
+ x11_global.color_map=DefaultColormap(x11_global.dpy, DefaultScreen(x11_global.dpy));
+ printf("# generating grays...\n");
+ for(i=0;i<=100;i++) {
+  snprintf(tmp,sizeof(tmp),"gray%d",i);
+  XAllocNamedColor(x11_global.dpy,x11_global.color_map,tmp,&x11_global.colors[i],&x11_global.colors[i]);
+ }
+ printf("# done.\n");
+ assert(x11_global.dpy);
+ gra_global.split_screen=SPLIT_SCREEN;
+ gra_global.split_flip=-1;
+ gra_global.split=5;
+ x11_global.root_window=0;
+ gra_global.red_and_blue=RED_AND_BLUE;
+ //global.colors[0]=BlackPixel(x11_global.dpy,DefaultScreen(x11_global.dpy));
+// int whiteColor = //WhitePixel(x11_global.dpy, DefaultScreen(x11_global.dpy));
+ attributes.background_pixel=x11_global.colors[0].pixel;
+ if(x11_global.root_window) {
+  x11_global.w = DefaultRootWindow(x11_global.dpy); //this is still buggy.
+ } else {
+  x11_global.w = XCreateWindow(x11_global.dpy,DefaultRootWindow(x11_global.dpy),0,0,WIDTH*(gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1)),HEIGHT,1,DefaultDepth(x11_global.dpy,DefaultScreen(x11_global.dpy)),InputOutput,DefaultVisual(x11_global.dpy,DefaultScreen(x11_global.dpy))\
+                   ,CWBackPixel, &attributes);
+  set_aspect_ratio();
+  XSelectInput(x11_global.dpy, x11_global.w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask|ExposureMask);
+ }
+ XMapWindow(x11_global.dpy,x11_global.w);
+ XStoreName(x11_global.dpy,x11_global.w,"hackvr");
+ gra_global.greyscale=1;
+ gra_global.zsort=1;
+ global.shape[0]=0;//we'll allocate as we need more.
+ x11_global.gc=XCreateGC(x11_global.dpy,x11_global.w, 0, 0);
+
+ if(gra_global.red_and_blue) {
+  gra_global.width=WIDTH;
+ } else {
+  gra_global.width=WIDTH*gra_global.split_screen;
+ }
+ gra_global.height=HEIGHT;
+
+ x11_global.backbuffer=XCreatePixmap(x11_global.dpy,x11_global.w,gra_global.width,gra_global.height,DefaultDepth(x11_global.dpy,DefaultScreen(x11_global.dpy)));
+ x11_global.cleanbackbuffer=XCreatePixmap(x11_global.dpy,x11_global.w,gra_global.width,gra_global.height,DefaultDepth(x11_global.dpy,DefaultScreen(x11_global.dpy)));
+
+//backbuffer is uninitialized
+ x11_global.backgc=XCreateGC(x11_global.dpy,x11_global.backbuffer,0,0);
+
+ cursor=XCreateFontCursor(x11_global.dpy,XC_crosshair);
+ XDefineCursor(x11_global.dpy, x11_global.w, cursor);
+
+ XAllocNamedColor(x11_global.dpy, x11_global.color_map, "green", &x11_global.green, &x11_global.green);
+ XAllocNamedColor(x11_global.dpy, x11_global.color_map, "red", &x11_global.red, &x11_global.red);
+ XAllocNamedColor(x11_global.dpy, x11_global.color_map, "blue", &x11_global.blue, &x11_global.blue);
+ XAllocNamedColor(x11_global.dpy, x11_global.color_map, "red", &x11_global.redblue[0], &x11_global.redblue[0]);
+ XAllocNamedColor(x11_global.dpy, x11_global.color_map, "blue", &x11_global.redblue[1], &x11_global.redblue[1]);
+ XSetForeground(x11_global.dpy, x11_global.gc, x11_global.green.pixel);
+ XSetForeground(x11_global.dpy, x11_global.backgc, x11_global.colors[0].pixel);//black. we're about to draw the blank background using this.
+ XSetBackground(x11_global.dpy, x11_global.gc, x11_global.colors[160].pixel);
+ XSetBackground(x11_global.dpy, x11_global.backgc, x11_global.colors[140].pixel);
+
+ XFillRectangle(x11_global.dpy, x11_global.cleanbackbuffer,x11_global.backgc,0,0,gra_global.width,gra_global.height);
+ XSetForeground(x11_global.dpy, x11_global.backgc,x11_global.green.pixel);
+
+//  XSetForeground(x11_global.dpy, gc, whiteColor);
+// this was taking a "long" time.
+ printf("# generating sky... ");
+ skypixmap=XCreatePixmap(x11_global.dpy,x11_global.w,SKYW,SKYH,DefaultDepth(x11_global.dpy,DefaultScreen(x11_global.dpy)));
+ for(i=0;i<SKYH;i++) {
+  for(j=0;j<SKYW;j++) {
+   if(i==0) sky[i][j]=rand()%2;
+   else {
+    sky[i][j]=(SKYRULE >> ((!!sky[i-1][(j+(SKYW)-1)%(SKYW)]<<2) | (!!sky[i-1][j]<<1) | (!!sky[i-1][j+1%(SKYW)])) & 1);
+    if(sky[i][j]) {
+     XDrawPoint(x11_global.dpy,skypixmap,x11_global.backgc,j,i);
+    }
+   }
+  }
+ }
+ printf("done.\n");
+
+ gra_global.mapxoff=gra_global.width/2;
+ gra_global.mapyoff=gra_global.height/2;
+ gra_global.drawminimap=0;
+ gra_global.draw3d=1;
+ gra_global.force_redraw=FORCE_REDRAW;//use this for checking proper fps I guess.
+ camera.zoom=30.0l;
+ camera.xr=270;
+ camera.yr=270;
+ camera.zr=0;
+ global.mmz=1;
+ camera.p.x=0;
+ camera.p.z=6;
+ camera.p.y=5;
+ return 0;
+}
+
+int graphics_event_handler() {
+ int redraw=0;
+ XEvent e;
+ Window child,root;
+ //what sets mask?
+ unsigned int mask;
+ while(XPending(x11_global.dpy)) {//these are taking too long?
+  XNextEvent(x11_global.dpy, &e);
+//     printf("# handling event with type: %d\n",e.type);
+  switch(e.type) {
+//       case Expose:
+//         if(e.xexpose.count == 0) redraw=1;
+//         break;
+    case MotionNotify:
+      XQueryPointer(x11_global.dpy,x11_global.w,&root,&child,&gra_global.rmousex,&gra_global.rmousey,&gra_global.mousex,&gra_global.mousey,&mask);
+      redraw=1;
+      break;
+    case ButtonPress:
+      redraw=1;
+      gra_global.buttonpressed=e.xbutton.button;//what's this for? mouse?
+      break;
+    case ButtonRelease:
+      redraw=1;
+      gra_global.buttonpressed=0;//what's this for???
+      break;
+    case ConfigureNotify:
+      redraw=1;
+      XGetGeometry(x11_global.dpy,x11_global.w,&root,&global.x,&global.y,&gra_global.width,&gra_global.height,&gra_global.border_width,&gra_global.depth);
+      if(gra_global.width / (gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1 )) / AR_W * AR_H != gra_global.height) {
+       if(gra_global.width / AR_W * AR_H == gra_global.height) {
+        printf("math doesn't work.\n");
+       }
+       printf("# DERPY WM CANT TAKE A HINT %d / %d / %d * %d = %d != %d\n",gra_global.width,gra_global.split_screen,gra_global.width / (gra_global.red_and_blue ? gra_global.split_screen : 1) / AR_W * AR_H,AR_W,AR_H,gra_global.height);
+       if(gra_global.width / (gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1)) / AR_W * AR_H < gra_global.height) {
+        gra_global.height=gra_global.width / (gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1)) / AR_W * AR_H;
+       } else {
+        gra_global.width=gra_global.height * AR_H / AR_W * (gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1));
+       }
+      }
+      gra_global.mapxoff=gra_global.width/(gra_global.split_screen / (gra_global.red_and_blue ? gra_global.split_screen : 1))/2;
+      gra_global.mapyoff=gra_global.height/2;
+      break;
+    case KeyPress:
+      redraw=1;
+      if(keypress_handler(XLookupKeysym(&e.xkey,0)) == -1) {
+       printf("# exiting\n");
+       return -1;
+      }
+      break;
+    default:
+      //printf("# received event with type: %d\n",e.type);
+      break;
+  }
+ }
+ return redraw;
+}
diff --git a/src/graphics_x11.h b/src/graphics_x11.h
new file mode 100644
index 0000000000000000000000000000000000000000..8924b6163440208023e4fc2f5cae158748834b89
--- /dev/null
+++ b/src/graphics_x11.h
@@ -0,0 +1,35 @@
+#ifndef _HACKVR_GRAPHICS_X11_H_
+#define _HACKVR_GRAPHICS_X11_H_
+
+#include <X11/Xlib.h>
+
+struct x11_global {//stores global variables for the x11 *specific* shit.
+  XColor colors[256];
+  XColor green;
+  XColor red;
+  XColor blue;
+  XColor redblue[2];
+  Colormap color_map;
+  Display *dpy;
+  Window w;
+  Pixmap backbuffer;
+  Pixmap cleanbackbuffer;
+  GC gc;
+  GC backgc;
+  int root_window;
+};
+
+void draw_cs_line(cs_t p1,cs_t p2);
+void draw_cs_text(cs_t p,char *text);
+void draw_cs_shape(cs_s_t s);
+void set_aspect_ratio();
+void flipscreen();
+void set_color();
+void clear_backbuffer();
+int keypress_handler(int sym);
+int graphics_init();
+int graphics_event_handler();
+void set_clipping_rectangle(int x,int y,int width,int height);
+void red_and_blue_magic();
+
+#endif
diff --git a/src/hackvr.c b/src/hackvr.c

index 5cd0de1b0cd1c2454ed0bafbf680534e033d3917..

index ..6984a560478bac53a685034e45008612b548126b 100644

--- a/src/hackvr.c
+++ b/src/hackvr.c
@@ -8,10 +8,6 @@
 #include <dirent.h>
 #include <stdlib.h>
 //#include <sys/select.h> //code to use select instead of non-blocking is commented out. might decide to use it later.
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#include <X11/Xutil.h> //for size hints
 #include <time.h>
 #define __USE_GNU //for longer math constants
 #include <math.h>
@@ -20,6 +16,7 @@
 #include "common.h"
 #ifdef GRAPHICAL
 #include "graphics.h"
+extern struct gra_global gra_global;
 #endif

 //TODO: optimizations
@@ -32,7 +29,7 @@
 //TODO: will have to make some pixmaps get resized when the window does.
 //for now set them to be as big as you think you'll ever resize the window to.

-struct mainwin global;
+struct global global;

 /* does not return the newline. */
 char *read_line_hack(FILE *fp,int len) {
@@ -117,8 +114,12 @@ int load_stdin() {
  // if(FD_ISSET(0,&readfs)) {
  while((line=read_line_hack(stdin,0))) {//load as long there's something to load
   if(*line == '#') return 0;
-  //printf("# read command: %s\n",line);
+//  printf("# read command: %s\n",line);
   a=line_splitter(line,&len);
+//  for(i=0;i<len;i++) {
+//   printf("\"%s\" ",a[i]);
+//  }
+//  printf("\n");
   id=a[0];
   if(len > 1) {
    command=a[1];
@@ -230,9 +231,9 @@ int load_stdin() {
     else printf("# unknown variable: %s\n",a[2]);
     continue;
    }
-   if(!strcmp(a[2],"force_redraw")) global.force_redraw^=1;
 #ifdef GRAPHICAL
-   else if(!strcmp(a[2],"red_and_blue")) { global.red_and_blue^=1; set_aspect_ratio(); }
+   if(!strcmp(a[2],"force_redraw")) gra_global.force_redraw^=1;
+   else if(!strcmp(a[2],"red_and_blue")) { gra_global.red_and_blue^=1; set_aspect_ratio(); }
 #endif
    else { printf("# unknown variable: %s\n",a[2]); continue; }
    printf("# %s toggled!\n",a[2]);
@@ -240,9 +241,13 @@ int load_stdin() {
   }
   if(!strcmp(command,"addshape")) {
    if(len > 3) {
+    if(len != (strtold(a[2],0)*3)+3) {
+     printf("# ERROR: wrong amount of parts for addshape. got: %d expected %d\n",len,((int)strtold(a[2],0))*3+3);
+     continue;
+    }
     global.shape[i]=malloc(sizeof(struct c3_shape));
-    global.shape[i]->id=strdup(id);
     global.shape[i]->len=strtold(a[2],0);
+    global.shape[i]->id=strdup(id);
     for(j=0;j < global.shape[i]->len+(global.shape[i]->len==1);j++) {
      global.shape[i]->p[j].x=strtold(a[(j*3)+3],0);//second arg is just for a return value. set to 0 if you don't want it.
      global.shape[i]->p[j].y=strtold(a[(j*3)+4],0);
@@ -251,8 +256,6 @@ int load_stdin() {
     i++;
     global.shapes=i;
     global.shape[i]=0;
-   } else {
-    printf("# ERROR: wrong amount of parts for addshape. got: %d expected: 11\n",len);
    }
    continue;
   }
@@ -334,20 +337,20 @@ int main(int argc,char *argv[]) {
   fcntl(1,F_SETFL,O_NONBLOCK);//won't work
   setbuf(stdin,0);
   setbuf(stdout,0);
-  global.debug=0;
+  global.debug=DEBUG;
 #ifdef GRAPHICAL
   int redraw;
-  x11_init();
+  graphics_init();
 #endif
   printf("# entering main loop\n");
   for(;;) {
 #ifdef GRAPHICAL
-    redraw=global.force_redraw;
-    if((redraw=x11_event_handler()) == -1) {
+    redraw=gra_global.force_redraw;
+    if((redraw=graphics_event_handler()) == -1) {
      return 0;
     }
     if(redraw && !global.headless) {
-     draw_screen(global.dpy,global.w,global.gc);
+     draw_screen();
     }
 #endif
     switch(load_stdin()) {
diff --git a/src/testit.sh b/src/testit.sh
new file mode 100755
index 0000000000000000000000000000000000000000..d0911a51a1289455c926a95a28331ebbace2e7e7
--- /dev/null
+++ b/src/testit.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+../tools/obj2hackvr2.pl woman ../meshes/female_basemesh1_2.obj | ./hackvr $USER
+#../tools/obj2hackvr.pl woman ../meshes/female_basemesh1_2.obj | ./hackvr epoch
diff --git a/src/x11.c b/src/x11.c
deleted file mode 100644
index fc8bf24ef91d3ebe85715cf8aaea1c311b1774b6..0000000000000000000000000000000000000000
--- a/src/x11.c
+++ /dev/null
@@ -1,1065 +0,0 @@
-#define _POSIX_C_SOURCE 200809L //for fileno and strdup
-#define _BSD_SOURCE
-#include <stdio.h>
-#include <string.h>
-#include <fcntl.h>
-#include <assert.h>
-#include <unistd.h>
-#include <dirent.h>
-#include <stdlib.h>
-//#include <sys/select.h> //code to use select instead of non-blocking is commented out. might decide to use it later.
-#include <X11/Xlib.h>
-#include <X11/keysym.h>
-#include <X11/cursorfont.h>
-#include <X11/Xutil.h> //for size hints
-#include <time.h>
-#define __USE_GNU //for longer math constants
-#include <math.h>
-
-//TODO: optimizations
-//TODO: store caches of cs_t, c2_t, and c3_t numbers.
-//TODO: don't forget to remake gophervr with this.
-//TODO: XSegment or line structs to store some shit?
-//TODO: line and triangle intersection for finding what object was clicked on
-//if I don't do hiliting I only need to calculate that upon click.
-
-#define WALK_SPEED 1
-#define SPLIT_SCREEN 1
-#define CAMERA_SEPARATION 4
-#define RED_AND_BLUE 0
-
-#define SHAPES 16386
-#define MAX_SIDES 8
-
-#define min(a,b) (((a)<(b))?(a):(b))
-#define max(a,b) (((a)>(b))?(a):(b))
-
-typedef double long real; //think this conflicts?
-//typedef float real; //think this conflicts?
-
-typedef struct {
- real x;
- real y;
- real z;
-} c3_t;
-
-typedef struct {
- real x;
- real y;
-} c2_t;
-
-typedef struct { //same as XPoint, just use that? nah...
- short x;
- short y;
-} cs_t;
-
-//TODO: will have to make some pixmaps get resized when the window does.
-//for now set them to be as big as you think you'll ever resize the window to.
-#define WIDTH 1024
-#define HEIGHT 768
-
-#define SKYRULE 90
-#define SKYW (WIDTH*5)
-#define SKYH (HEIGHT/2)
-
-Pixmap skypixmap;
-char sky[SKYH][SKYW];
-
-struct object_1 {
- int type;
- unsigned char x;
- unsigned char y;
- unsigned char z;
-};
-
-struct object_2 {
- int type;
- unsigned short x;
- unsigned short y;
- unsigned short z;
-};
-
-struct object_4 {
- int type;
- unsigned int x;
- unsigned int y;
- unsigned int z;
-};
-
-struct camera {
-  c3_t p;
-  int xr;//rotations
-  int yr;
-  int zr;
-  real zoom;
-} camera;
-
-struct c3_line {
- char *id;
- c3_t p1;
- c3_t p2;
-};
-
-struct c3_shape {//use array or linked list?
-  char *id;
-  unsigned char len;
-  c3_t p[MAX_SIDES];
-};
-
-struct mainwin {
-  int x;
-  int y;
-  unsigned int depth;
-  int mousex;
-  int mousey;
-  int rmousex;
-  int rmousey;
-  int buttonpressed;
-  unsigned int width;
-  unsigned int height;
-  unsigned int border_width;
-  XColor colors[256];
-  int xoff;
-  int math_error;
-  int mapxoff;
-  int mapyoff;
-  int split_screen;
-  int split_flip;//1 or -1
-  char *user;
-  char greyscale;
-  char headless;
-  char drawminimap;//flag
-  char draw3d;//flag
-  char debug;//flag
-  char drawsky;//flag
-  char zsort;
-  char red_and_blue;
-  char force_redraw;
-  char selected_object[256];//meh
-  real mmz;
-  XColor green;
-  XColor red;
-  XColor blue;
-  XColor redblue[2];
-  Colormap color_map;
-  Display *dpy;
-  Window w;
-  Pixmap backbuffer;
-  Pixmap cleanbackbuffer;
-  GC gc;
-  GC backgc;
-  struct c3_shape *shape[SHAPES];
-  int shapes;
-  int derp;
-  int root_window;
-  real split;
-  int oldtime;
-  int oldfps;
-  int fps;
-} global;
-
-#ifdef GRAPHICAL
-
-//used to figure out what c2 values are associated with each edge of the window.
-//#define TOP     160.0
-//#define BOTTOM  -160.0
-#define TOP     240.0
-#define BOTTOM  -240.0
-#define RIGHT   320.0
-#define LEFT    -320.0
-
-int c2sX(long double x) { return (global.width/(global.split_screen / (global.red_and_blue ? global.split_screen: 1))) * ((x + RIGHT) / (RIGHT *2)) + global.xoff; }
-int s2cX(long double x) { return (x/(global.width/(global.split_screen / (global.red_and_blue?global.split_screen :1))))*(RIGHT*2)-RIGHT; }
-
-int c2sY(long double y) { return global.height * ((TOP-y) / (TOP*2)); }
-int s2cY(long double y) { return -((y/global.height) * (TOP*2) - TOP); }
-
-cs_t c2_to_cs(c2_t p) {
- return (cs_t){c2sX(p.x),c2sY(p.y)};
-}
-c2_t cs_to_c2(cs_t p) {
- return (c2_t){s2cX(p.x),s2cY(p.y)};
-}
-
-long double distance2(c2_t p1,c2_t p2) {
- return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) ));
-}
-
-long double distance3(c3_t p1,c3_t p2) {
- return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) )+( (p1.z-p2.z)*(p1.z-p2.z) ));
-}
-
-long double points_to_angle(c2_t p1,c2_t p2) {
-  long double a=atan2l(p2.y-p1.y,p2.x-p1.x);
-  return a>=0?a:M_PIl+M_PIl+a;
-}
-
-long double d2r(int d) {
- while(d<0) d+=360;
- return (long double)(d%360) / (long double)180 * M_PIl;
-}
-int r2d(real r) {
- return r / M_PIl * 180;
-}
-
-int between_angles(real angle,real lower,real upper) {
-  //lower may be higher than upper.
-  //because lower is < 0 which wraps to higher. lower is 270, upper is 90. 270-90 is in front.
-  if(lower > upper) {
-    if(angle > lower) return 1;
-    if(angle < upper) return 1;
-  }
-  if(upper > lower) {
-    if(angle > lower && angle < upper) return 1;
-  }
-  return 0;
-}
-
-/*
-B (x2,y2)
- |-.   c
-a|  '-.
- |     '-.
- '--------~
-C    b     A (x1,y1)
-*/
-
-//I'll need this for collision I guess.
-
-/*
-
-//use this for finding a line that intersects with what the camera is pointing at
-c2_t get_c2_intersection(c2_t p1,real theta,c2_t p2) {
-  real c;
-  c=distance2(p1,p2);
-  theta_a=C A B
-  b = (c/1) * (theta_a + theta_offset)
-}
-
-int get_2D_intersection_X(x1,y1,theta_offset,x2,y2) {
- int x3a,y3a,x3b,y3b;
- int a,b,c;//lenght of sides.
- int theta_a,theta_b,theta_c;//angles opposite of same named sides.
-
- //get angle C A B
- theta_a=
-// x1,y1,x2,y2
-
-//what are these d1 and d2?
- if(d1==d2) return global.math_error=1;
- c=dist(x1,y1,x2,y2);
- b = (c/1) * (theta_a + theta_offset);
- a = (c/1) * (theta_b + theta_offset);
-
- x3b=sin(theta_a) * b;
- y3b=cos(theta_a) * b;
- x3a=sin(theta_a) * a;
- y3a=cos(theta_a) * a;
- printf("x: %d %d\nx: %d %d\n",x3a,y3a,x3b,y3b);
-}
-
-int get_2D_intersection_Y(x,y,d,x,z,d) {
- int x3a,y3a,x3b,y3b;
- int a,b,c;//lenght of sides.
- int theta_a,theta_b,theta_c;//angles opposite of same named sides.
-
- //get angle from A to B.
- x1,y1,x2,y2
-
- if(d1==d2) return global.math_error=1;
- c=dist(x1,y1,x2,y2);
- b = (c/1) * theta_a;
- a = (c/1) * theta_b;
-
- x3b=sin(a) * b;
- y3b=cos(a) * b;
- x3a=sin(a) * a;
- y3a=cos(a) * a;
- printf("y: %d %d\ny: %d %d\n",x3a,y3a,x3b,y3b);
-}
-*/
-
-void draw_cs_line(cs_t p1,cs_t p2) {
-  XDrawLine(global.dpy,global.backbuffer,global.backgc,p1.x,p1.y,p2.x,p2.y);
-}
-
-void draw_c2_line(c2_t p1,c2_t p2) {
-  draw_cs_line(c2_to_cs(p1),c2_to_cs(p2));
-}
-
-#define MAGIC(x) (1.0l-(1.0l/powl(1.01l,(x)))) //??? might want to have some changables in here
-
-real magic(real x) {
-  return MAGIC(x);
-}
-
-void draw_graph(real (*fun)(real x)) {
- c2_t pa;
- draw_c2_line((c2_t){LEFT,0},(c2_t){RIGHT,0});
- draw_c2_line((c2_t){0,TOP},(c2_t){0,BOTTOM});
- for(pa.x=LEFT;pa.x<RIGHT;pa.x+=5.0) {
-  draw_c2_line((c2_t){pa.x,2.0},(c2_t){pa.x,-2.0});
- }
- for(pa.y=BOTTOM;pa.y<TOP;pa.y+=5.0) {
-  draw_c2_line((c2_t){-2.0,pa.y},(c2_t){2.0,pa.y});
- }
- for(pa.x=LEFT;pa.x<RIGHT;pa.x+=1.0) {
-  draw_c2_line((c2_t){pa.x,fun(pa.x)},(c2_t){pa.x+1.0,fun(pa.x+1.0)});
- }
-}
-
-c2_t rotate_c2(c2_t p1,c2_t p2,real dr) {
-  c2_t p3;
-  real d=distance2(p1,p2);
-  real r=points_to_angle(p1,p2);
-  r=r+dr;
-  p3.x=(sinl(r) * d) + p2.x;
-  p3.y=(cosl(r) * d) + p2.y;
-  return p3;
-}
-
-c3_t rotate_c3_xr(c3_t p1,c3_t p2,real xr) {//rotate y and z around camera based on xr (looking up and down)
-  c2_t tmp;
-  tmp=rotate_c2((c2_t){p1.y,p1.z},(c2_t){p2.y,p2.z},xr);
-  return (c3_t){p1.x,tmp.x,tmp.y};
-}
-c3_t rotate_c3_yr(c3_t p1,c3_t p2,real yr) {//rotate x and z around camera based on yr (looking left and right)
-  c2_t tmp;
-  tmp=rotate_c2((c2_t){p1.x,p1.z},(c2_t){p2.x,p2.z},yr);
-  return (c3_t){tmp.x,p1.y,tmp.y};
-}
-c3_t rotate_c3_zr(c3_t p1,c3_t p2,real zr) {//rotate x and y around camera based on zr (cocking your head to a side)
-  c2_t tmp;
-  tmp=rotate_c2((c2_t){p1.x,p1.y},(c2_t){p2.x,p2.y},zr);
-  return (c3_t){tmp.x,tmp.y,p1.z};
-}
-
-void rotate_shape_yr(struct c3_shape *s) {//changes input value!
- int i=0;
- for(i=0;i<s->len+(s->len==1);i++) s->p[0]=rotate_c3_yr(s->p[0],camera.p,camera.yr);
-}
-
-c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE
-  c2_t p2;
-//  c3_t tmp1;
-//  c3_t tmp2;
-//  c3_t tmp3;
-  c3_t final;
-//these rotations need to be about the previous axis after the axis itself has been rotated.
-//  final=rotate_c3_yr(p3,camera.p,d2r(camera.yr));//rotate everything around the camera's location.
-  final=rotate_c3_yr(p3,(c3_t){0,0,0},d2r(camera.yr));//rotate everything around the center no matter what.
-//  tmp2=rotate_c3_xr(tmp1,camera.p,d2r(camera.xr));
-//  final=rotate_c3_zr(tmp2,camera.p,d2r(camera.zr));
-  real delta_x=(camera.p.x - final.x);
-  real delta_y=(camera.p.y - final.y);
-  real delta_z=(camera.p.z - final.z);
-//  real d=distance3(camera.p,final);
-  p2.y=camera.zoom * (delta_y * MAGIC(delta_z) - delta_y);
-  p2.x=camera.zoom * (delta_x * MAGIC(delta_z) - delta_x);
-  return p2;
-}
-
-void draw_c3_line(c3_t p1,c3_t p2) {
-// if(!between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p1.x,p1.z}),0,90) ||
-//    !between_angles(points_to_angle((c2_t){camera.p.x,camera.p.z},(c2_t){p2.x,p2.z}),0,90)) return;
- if(global.drawminimap == 1) {
-  draw_c2_line((c2_t){(camera.p.x-2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x+2)*global.mmz,(camera.p.z-2)*global.mmz});
-  draw_c2_line((c2_t){(camera.p.x+2)*global.mmz,(camera.p.z+2)*global.mmz},(c2_t){(camera.p.x-2)*global.mmz,(camera.p.z-2)*global.mmz});
-  draw_c2_line((c2_t){p1.x*global.mmz,p1.z*global.mmz},(c2_t){p2.x*global.mmz,p2.z*global.mmz});
- }
- if(global.drawminimap == 2) {//map rotates.
-  c3_t t1=rotate_c3_yr(p1,camera.p,d2r(camera.yr));
-  c3_t t2=rotate_c3_yr(p2,camera.p,d2r(camera.yr));
-  draw_c2_line((c2_t){t1.x*global.mmz,t1.z*global.mmz},(c2_t){t2.x*global.mmz,t2.z*global.mmz});
- }
- if(global.draw3d != 0) draw_c2_line(c3_to_c2(p1),c3_to_c2(p2));
- if(global.debug) {
-
- }
-}
-
-cs_t c3_to_cs(c3_t p) {
- return c2_to_cs(c3_to_c2(p));
-}
-
-real shitdist2(c3_t p1,c3_t p2) {
- return sqrtl(((p1.x - p2.x) * (p1.x - p2.x)) +
-        ((p1.y - p2.y) * (p1.y - p2.y)) +
-        ((p1.z - p2.z) * (p1.z - p2.z)));
-}
-
-real shitdist(struct c3_shape s,c3_t p) {
-// apply rotation then find distance?
- int i;
- struct c3_shape s_;
- real total;
- s_=s;
- rotate_shape_yr(&s_);
- for(i=0;i<s_.len+(s_.len==1);i++) {
-  total+=shitdist2(s_.p[i],camera.p);
- }
- return (total) / (real)(s_.len+(s_.len==1));
-}
-
-
-void HatchLines(c2_t p1,c2_t p2,c2_t p3,int density) {
- real i=0;
- for(i=1;i<density;i=i+1) {//only need 1/2, not 0/2 and 2/2, those are edges of the triangle.
-  draw_c2_line(
-   (c2_t){((i*p1.x)+((density-i)*p3.x))/density,
-          ((i*p1.y)+((density-i)*p3.y))/density},
-   (c2_t){((i*p2.x)+((density-i)*p3.x))/density,
-          ((i*p2.y)+((density-i)*p3.y))/density}
-  );
- }
-}
-
-/*void DrawHatchedTriangle(struct c3_triangle t,int d) {
- c2_t p1,p2,p3;
- p1=c3_to_c2(t.p1);
- p2=c3_to_c2(t.p2);
- p3=c3_to_c2(t.p3);
- HatchLines(p1,p2,p3,d);
- HatchLines(p2,p3,p1,d);
- HatchLines(p1,p3,p2,d);
-}*/
-
-//^ subdivision algorithm for display purposes only.
-//black out the rest of the triangle first?
-//sounds alright to me...
-
-void draw_cs_text(cs_t p,char *text) {
- char t[256];
- int direction,ascent,descent;
- XFontStruct *font=XLoadQueryFont(global.dpy,"fixed");
- XCharStruct overall;
- snprintf(t,sizeof(t)-1,"%s",text);
- XTextExtents(font,text,strlen(text),&direction,&ascent,&descent,&overall);
- XDrawString(global.dpy,global.backbuffer,global.backgc,p.x,p.y+(descent+ascent),text,strlen(text));
-}
-
-void draw_c2_text(c2_t p,char *text) {
- cs_t p2=c2_to_cs(p);
- draw_cs_text(p2,text);
-}
-
-void draw_c3_text(c3_t p,char *text) {
- cs_t p2=c3_to_cs(p);
- draw_cs_text(p2,text);
-}
-
-/*
-cs_t *c3s_to_css(c3_t *p3,int len) {
- cs_t *ps=malloc(sizeof(cs_t) * len);
- int i;
- for(i=0;i<len;i++) ps[i]=c3_to_cs(p3[i]);
- return ps;
-}*/
-
-void draw_c3_shape(struct c3_shape s) {
-// char line[1024];
- int i=0;
- int w,h;
- XPoint p[s.len+(s.len==1)];
- cs_t tmp;
- for(i=0;i<s.len+(s.len==1);i++) {
-  tmp=c3_to_cs(s.p[i]);
-  p[i]=(XPoint){tmp.x,tmp.y};
- }
- if(global.draw3d == 1) { // wireframe
-  switch(s.len) {
-   case 1:
-    w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
-    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
-    p[0].x-=h;
-    p[0].y-=h;
-    XDrawArc(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
-    break;
-   case 2:
-    XDrawLine(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
-    break;
-   default:
-    for(i=0;i<s.len;i++) {
-     XDrawLines(global.dpy,global.backbuffer,global.backgc,p,s.len,CoordModeOrigin);
-    }
-    break;
-  }
- }
- if(global.draw3d == 2) { //draw it filled in
-  switch(s.len) {
-   case 1:
-    w=max(p[0].x,p[1].x)-min(p[0].x,p[1].x);
-    h=max(p[0].y,p[1].y)-min(p[0].y,p[1].y);
-    p[0].x-=h;
-    p[0].y-=h;
-    XFillArc(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,h*2,h*2,0,360*64);
-    break;
-   case 2:
-    XDrawLine(global.dpy,global.backbuffer,global.backgc,p[0].x,p[0].y,p[1].x,p[1].y);
-    break;
-   default:
-    XFillPolygon(global.dpy,global.backbuffer,global.backgc,p,s.len,Convex,CoordModeOrigin);
-    break;
-  }
- }
-// if(global.draw3d == 3) { //hashed
-//  XSetForeground(global.dpy, global.backgc, global.colors[0].pixel);
-  //XDrawFilledShape(c3_to_cs(t.p1),c3_to_cs(t.p2),c3_to_cs(t.p3));//clear out this triangle.
-//  XSetForeground(global.dpy, global.backgc, global.green.pixel);
-  //upgrade me! DrawHatchedTriangle(t,10 - (shitdist(t,camera.p) / 10));//how to get density?
-// }
-/* if(global.debug) {
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p1.x,t.p1.y,t.p1.z);
-  draw_c3_text(t.p1,line);
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p2.x,t.p2.y,t.p2.z);
-  draw_c3_text(t.p2,line);
-  snprintf(line,sizeof(line)-1,"(%Lf,%Lf,%Lf)",t.p3.x,t.p3.y,t.p3.z);
-  draw_c3_text(t.p3,line);
-*/
-// }
-}
-
-typedef struct {
- struct c3_shape *s;
- real d;
-} zsort_t;
-
-int compar(zsort_t *a,zsort_t *b) {
- return ((a->d) > (b->d));
-}
-
-
-/*
-void draw_c3_point_text(c3_t p,char *text) {
- char coords[256];
- int direction,ascent,descent;
- cs_t p2;
- p2=c3_to_cs(p);
- snprintf(coords,sizeof(coords)-1,"(%Lf,%Lf,%Lf)",p.x,p.y,p.z);
- XTextExtents(font,text,strlen(text),&direction,&ascent,&descent,&overall);
- XDrawString(global.dpy,global.backbuffer,global.backgc,p2.x,p2.y+(descent+ascent),coords,strlen(coords));
-}*/
-
-void draw_screen(Display *dpy,Window w,GC gc) {
-  int i;
-  int colori=100;
-  int cn=0;//camera number.
-  XFontStruct *font=XLoadQueryFont(global.dpy,"fixed");
-  XCharStruct overall;
-  int direction,ascent,descent;
-  char coords[256];
-  XGCValues gcval;
-  zsort_t zs[SHAPES];
-  XCopyArea(global.dpy,global.cleanbackbuffer,global.backbuffer,gc,0,0,global.width,global.height,0,0);//clear the backbuffer.
-//  XCopyPlane(global.dpy,global.cleanbackbuffer,global.backbuffer,gc,0,0,global.width,global.height,0,0,1);//clear the backbuffer.
-
-  XRectangle cliprect;
-  cliprect.x=0;
-  cliprect.y=0;
-  cliprect.width=global.width/global.split_screen;
-  cliprect.height=global.height;
-
-  real oldx=camera.p.x;
-  real oldz=camera.p.z;
-  if(global.split_screen > 1) {
-   camera.p.z-=(global.split_flip)*((global.split/global.split_screen)*cosl(d2r(camera.yr+180)));
-   camera.p.x-=(global.split_flip)*((global.split/global.split_screen)*sinl(d2r(camera.yr+180)));
-  }
-  for(cn=0;cn<global.split_screen;cn++) {
-    if(global.red_and_blue) {
-     //set color for left half to red and right half to blue
-     //and draw mode for the gc to GXOr
-     global.xoff=0;
-     gcval.function=GXor;
-     XChangeGC(global.dpy,global.backgc,GCFunction,&gcval);
-    } else {
-     global.xoff=(global.width/global.split_screen)*cn;
-    }
-    if(!global.red_and_blue) XSetClipRectangles(global.dpy,global.backgc,global.xoff,0,&cliprect,1,Unsorted);
-    //if(global.drawminimap == 3) { draw_graph(magic); continue; }
-    if(global.drawsky) {
-     XCopyArea(global.dpy,skypixmap,global.backbuffer,global.backgc,((camera.yr*5)+SKYW)%SKYW,0,WIDTH,global.height/2,0,0);
-    }
-    if(global.draw3d) {
-//      draw_c2_line((c2_t){LEFT,0},(c2_t){RIGHT,0}); //horizon
-    }
-    if(time(0) == global.oldtime) {
-     global.fps++;
-    }
-    else {
-     global.oldtime=time(0);
-     global.oldfps=global.fps;
-     global.fps=0;
-    }
-    //XSetForeground(global.dpy, global.backgc, global.green.pixel);
-    if(global.debug) {
-      snprintf(coords,sizeof(coords)-1,"debug: %s minimap: %d 3d: %d fps: %d shapes: %d",global.debug?"on":"off",global.drawminimap,global.draw3d,global.oldfps,global.shapes);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*1,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"x: %d y: %d",global.mousex,global.mousey);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*2,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"cx: %Lf cy: %Lf cz: %Lf",camera.p.x,camera.p.y,camera.p.z);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*3,coords,strlen(coords));
-      snprintf(coords,sizeof(coords)-1,"xr: %d yr: %d zr: %d",camera.xr,camera.yr,camera.zr);
-      XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-      XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*4,coords,strlen(coords));
-    }
-
-//  if(global.drawminimap) {//this isn't even useful I guess.
-   //cx1=(sinl(d2r(camera.yr+270))*7l);
-   //cy1=(cosl(d2r(camera.yr+270))*7l);
-   //cx2=(sinl(d2r(camera.yr+90))*7l);
-   //cy2=(cosl(d2r(camera.yr+90))*7l);
-//   draw_c2_line((c2_t){0,0},(c2_t){10,10});
-//   draw_c2_line((c2_t){0,0},(c2_t){-10,10});
-//   draw_c2_line((c2_t){10,10},(c2_t){-10,10});
-//  }
-
-/* cube
-   draw_c3_line((c3_t){-3,0,-3},(c3_t){-3,0,3});
-   draw_c3_line((c3_t){-3,0,-3},(c3_t){-3,6,-3});
-   draw_c3_line((c3_t){-3,0,-3},(c3_t){3,0,-3});
-
-   draw_c3_line((c3_t){3,6,3},(c3_t){3,6,-3});
-   draw_c3_line((c3_t){3,6,3},(c3_t){-3,6,3});
-   draw_c3_line((c3_t){3,6,3},(c3_t){3,0,3});
-
-   draw_c3_line((c3_t){-3,0,3},(c3_t){3,0,3});
-   draw_c3_line((c3_t){-3,0,3},(c3_t){-3,6,3});
-
-   draw_c3_line((c3_t){-3,6,-3},(c3_t){-3,6,3});
-   draw_c3_line((c3_t){-3,6,-3},(c3_t){3,6,-3});
-
-   draw_c3_line((c3_t){3,0,-3},(c3_t){3,0,3});
-   draw_c3_line((c3_t){3,0,-3},(c3_t){3,6,-3});
-*/
-/*
-   //floor grid
-   for(i=-21;i<21;i+=3) {
-    for(j=-21;j<21;j+=3) {
-     //draw_c3_triangle((struct c3_triangle){"id",(c3_t){i,0,j},(c3_t){i,0,j+3},(c3_t){i+3,0,j}});
-     draw_c3_line((c3_t){i,0,j},(c3_t){i,0,j+3});
-     draw_c3_line((c3_t){i,0,j},(c3_t){i+3,0,j});
-    }
-   }
-*/
-   //apply rotation?
-   // load up the triangles to render... after applying rotation?
-   for(i=0;global.shape[i];i++) {
-    zs[i].s=global.shape[i];
-    //rotate_shape(zs[i].s);
-   }
-   //
-   if(1) {//global.zsort) {
-    for(i=0;global.shape[i];i++) {
-     zs[i].d=shitdist(*(zs[i].s),camera.p);
-    }
-    qsort(&zs,i,sizeof(zs[0]),(__compar_fn_t)compar);//sort these zs structs based on d.
-   }
-   //draw all triangles
-   if(zs[0].s) {
-    strcpy(global.selected_object,zs[0].s->id);
-   }
-   for(i=0;global.shape[i];i++) {
-    //now we pick the color of this triangle!
-    if(global.red_and_blue) {
-     if(cn==0) {
-      XSetForeground(global.dpy,global.backgc,global.red.pixel);
-     } else {
-      XSetForeground(global.dpy,global.backgc,global.blue.pixel);
-     }
-//tests of blending grayscale with red and blue
-//     draw_c3_triangle(*(zs[i].t));
-    } else {
-     if(!strcmp(global.selected_object,zs[i].s->id)) {
-      //XSetForeground(global.dpy,global.backgc,global.green.pixel);
-     } else {
-      if(global.greyscale) {
-       if(zs[i].d > 0) {
-        if(zs[i].d < 100) {
-         colori=zs[i].d;
-        }
-       }
-       colori=(int)(zs[i].d)%100;
-       XSetForeground(global.dpy,global.backgc,global.colors[(int)(100.0-(colori))].pixel);//picking the color here only works if...
-      }
-     }
-    }
-    draw_c3_shape(*(zs[i].s));
-   }
-   XSetForeground(global.dpy, global.backgc, global.green.pixel);
-   if(global.debug) {
-    snprintf(coords,sizeof(coords)-1,"selected object: %s",global.selected_object);
-    XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-    XDrawString(global.dpy,global.backbuffer,global.backgc,global.xoff,global.height/2+(descent+0+ascent)*5,coords,strlen(coords));
-   }
-   camera.p.z+=(global.split_flip)*(global.split*cosl(d2r(camera.yr+180)));
-   camera.p.x+=(global.split_flip)*(global.split*sinl(d2r(camera.yr+180)));
-
-
-  }
-
-//TODO: figure out what all this shit is and either update or remove.
-//DONT USE WIDTH for shit.
-/*
-  x1=nextX(WIDTH/2,HEIGHT/2,d2r(camera.yr),40);
-  y1=nextY(WIDTH/2,HEIGHT/2,d2r(camera.yr),40);
-  x2=nextX(WIDTH/2,HEIGHT/2,d2r(camera.yr+180),80);
-  y2=nextY(WIDTH/2,HEIGHT/2,d2r(camera.yr+180),80);
-  XDrawLine(global.dpy,w,gc,WIDTH/2,HEIGHT/2,x1,y1);
-  XDrawLine(global.dpy,w,gc,WIDTH/2,HEIGHT/2,x2,y2);
-
-  XDrawLine(global.dpy,w,gc,0,HEIGHT/2,WIDTH,HEIGHT/2);
-
-  x1=global.mousex;
-  y1=global.mousey;
-  real a=points_to_angle((c2_t){0,0},cs_to_c2((cs_t){x1,y1}));
-
-  snprintf(coords,sizeof(coords)-1,"%llf",a);
-  XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*6,coords,strlen(coords));
-  snprintf(coords,sizeof(coords)-1,"%llf",points_to_angle(cs_to_c2((cs_t){global.mousex,global.mousey}),(c2_t){0,0})+(M_PIl/2));
-  XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
-  XDrawString(global.dpy,w,gc,global.xoff,(descent+0+ascent)*7,coords,strlen(coords));
-  XDrawLine(global.dpy,w,gc,global.mousex,global.mousey,global.width/2,global.height/2);
-
-  real c=cosl(d2r(camera.yr) - a) * distance((c2_t){x1,y1},(c2_t){WIDTH/2,HEIGHT/2});
-  x2=nextX(x1,y1,d2r(camera.yr-90),c);
-  y2=nextY(x1,y1,d2r(camera.yr-90),c);
-  XDrawLine(global.dpy,w,gc,x1,y1,x2,y2);
-*/
-  camera.p.x = oldx;
-  camera.p.z = oldz; //-= cn*CAMERA_SEPARATION;
-//  XClearWindow(global.dpy, w);
-  XCopyArea(global.dpy,global.backbuffer,w,gc,0,0,global.width,global.height,0,0);//move backbuffer to window
-//  XCopyPlane(global.dpy,global.backbuffer,w,gc,0,0,global.width,global.height,0,0,0x000100);//move backbuffer to window
-}
-
-#endif
-
-#ifdef GRAPHICAL
-void set_aspect_ratio() {
- XSizeHints *hints=XAllocSizeHints();
- hints->min_aspect.x=4*(global.split_screen / (global.red_and_blue ? global.split_screen : 1));
- hints->min_aspect.y=3;
- hints->max_aspect.x=4*(global.split_screen / (global.red_and_blue ? global.split_screen : 1));
- hints->max_aspect.y=3;
- hints->flags=PAspect;
- XSetWMNormalHints(global.dpy,global.w,hints);
-}
-#endif
-
-#ifdef GRAPHICAL
-//push a string back into stdin so it can be read by the file loader. :P
-int selfcommand(char *s) {
- char t;
- if(!strlen(s)) return 0;
- ungetc(s[strlen(s)-1],stdin);
- t=s[strlen(s)-1];
- s[strlen(s)-1]=0;
- selfcommand(s);
- putchar(t);
- return 0;
-}
-
-int keypress_handler(int sym) {
-  char line[1024];
-  real tmpx;
-//  real tmpy; //unused atm
-  real tmpz;
-  switch(sym) {
-   case XK_Return:
-    snprintf(line,sizeof(line)-1,"%s action %s\n",global.user,global.selected_object);
-    selfcommand(line);
-    break;
-   case XK_Up:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+90));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+90));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Down:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+270));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+270));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Left:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_Right:
-    tmpx=WALK_SPEED*sinl(d2r(camera.yr+180));
-    tmpz=WALK_SPEED*cosl(d2r(camera.yr+180));
-    camera.p.x+=tmpx;
-    camera.p.z+=tmpz;
-    snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
-    selfcommand(line);
-    break;
-   case XK_w:
-    camera.p.y+=1;
-    snprintf(line,sizeof(line)-1,"%s move 0 1 0 0 0 0 0 0 0\n",global.user);
-    selfcommand(line);
-    break;
-   case XK_s:
-    camera.p.y-=1;
-    snprintf(line,sizeof(line)-1,"%s move 0 -1 0 0 0 0 0 0 0\n",global.user);
-    selfcommand(line);
-    break;
-   case XK_r:
-    camera.xr+=5;
-    while(camera.xr > 360) camera.xr-=360;
-    break;
-   case XK_y:
-    camera.xr-=5;
-    while(camera.xr < 0) camera.xr+=360;
-    break;
-   case XK_q:
-    camera.yr+=5;
-    while(camera.yr > 360) camera.yr-=360;
-    break;
-   case XK_e:
-    camera.yr-=5;
-    while(camera.yr < 0) camera.yr+=360;
-    break;
-   case XK_u:
-    camera.zr+=5;
-    while(camera.zr > 360) camera.zr-=360;
-    break;
-   case XK_o:
-    camera.zr-=5;
-    while(camera.zr < 0) camera.zr+=360;
-    break;
-   case XK_z: camera.zoom+=1; break;
-   case XK_x: camera.zoom-=1; break;
-   case XK_c: global.mmz*=1.1; break;
-   case XK_v: global.mmz/=1.1; break;
-   case XK_h: global.split+=1; break;
-   case XK_j: global.split-=1; break;
-   case XK_d:
-    global.debug ^= 1;
-    break;
-   case XK_f:
-    global.derp ^= 1;
-    break;
-   case XK_m:
-    global.drawminimap += 1;
-    global.drawminimap %= 4;
-    break;
-   case XK_a:
-    global.drawsky ^= 1;
-    break;
-   case XK_3:
-    global.draw3d += 1;
-    global.draw3d %= 4;
-    break;
-   case XK_Escape:
-    return -1;
-   default:
-    return 0;
-    break;
- }
- return 1;
-}
-#endif
-
-int main(int argc,char *argv[]) {
-#ifdef GRAPHICAL
-  Cursor cursor;
-  XEvent e;
-  XSetWindowAttributes attributes;
-  Window root,child;//why do I have this?
-//  XColor toss;
-#endif
-  int i,j;
-  char tmp[64];
-  unsigned int mask;
-  char redraw=0;
-  if(argc < 2) {
-   fprintf(stderr,"usage: hackvr yourname < from_others > to_others\n");
-   return 1;
-  } else {
-   global.user=strdup(argv[1]);
-  }
-  fcntl(1,F_SETFL,O_NONBLOCK);//won't work
-  setbuf(stdin,0);
-  setbuf(stdout,0);
-#ifdef GRAPHICAL
-  printf("# Opening X Display... (%s)\n",getenv("DISPLAY"));
-  if((global.dpy = XOpenDisplay(0)) == NULL) return printf("# failure.\n"),2;
-  else printf("# done.\n");
-  global.color_map=DefaultColormap(global.dpy, DefaultScreen(global.dpy));
-
-  printf("# generating grays...\n");
-  for(i=0;i<=100;i++) {
-   snprintf(tmp,sizeof(tmp),"gray%d",i);
-   XAllocNamedColor(global.dpy,global.color_map,tmp,&global.colors[i],&global.colors[i]);
-  }
-  printf("# done.\n");
-  assert(global.dpy);
-  global.split_screen=SPLIT_SCREEN;
-  global.split_flip=-1;
-  global.split=5;
-  global.root_window=0;
-  global.red_and_blue=RED_AND_BLUE;
-  //global.colors[0]=BlackPixel(global.dpy,DefaultScreen(global.dpy));
-//  int whiteColor = //WhitePixel(global.dpy, DefaultScreen(global.dpy));
-  attributes.background_pixel=global.colors[0].pixel;
-  if(global.root_window) {
-   global.w = DefaultRootWindow(global.dpy); //this is still buggy.
-  } else {
-   global.w = XCreateWindow(global.dpy,DefaultRootWindow(global.dpy),0,0,WIDTH*(global.split_screen / (global.red_and_blue ? global.split_screen : 1)),HEIGHT,1,DefaultDepth(global.dpy,DefaultScreen(global.dpy)),InputOutput,DefaultVisual(global.dpy,DefaultScreen(global.dpy))\
-                    ,CWBackPixel, &attributes);
-   set_aspect_ratio();
-   XSelectInput(global.dpy, global.w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|KeyPressMask|ExposureMask);
-  }
-  XMapWindow(global.dpy, global.w);
-  XStoreName(global.dpy,global.w,"hackvr");
-  global.greyscale=1;
-  global.zsort=1;
-  global.shape[0]=0;//we'll allocate as we need more.
-  global.gc=XCreateGC(global.dpy, global.w, 0, 0);
-
-  if(global.red_and_blue) {
-   global.width=WIDTH;
-  } else {
-   global.width=WIDTH*global.split_screen;
-  }
-  global.height=HEIGHT;
-
-  global.backbuffer=XCreatePixmap(global.dpy,global.w,global.width,global.height,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
-  global.cleanbackbuffer=XCreatePixmap(global.dpy,global.w,global.width,global.height,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
-
-  global.fps=0;
-  global.oldfps=0;
-  global.oldtime=0;
-//backbuffer is uninitialized
-  global.backgc=XCreateGC(global.dpy,global.backbuffer,0,0);
-
-  cursor=XCreateFontCursor(global.dpy,XC_crosshair);
-  XDefineCursor(global.dpy, global.w, cursor);
-
-  XAllocNamedColor(global.dpy, global.color_map, "green", &global.green, &global.green);
-  XAllocNamedColor(global.dpy, global.color_map, "red", &global.red, &global.red);
-  XAllocNamedColor(global.dpy, global.color_map, "blue", &global.blue, &global.blue);
-  XAllocNamedColor(global.dpy, global.color_map, "red", &global.redblue[0], &global.redblue[0]);
-  XAllocNamedColor(global.dpy, global.color_map, "blue", &global.redblue[1], &global.redblue[1]);
-  XSetForeground(global.dpy, global.gc, global.green.pixel);
-  XSetForeground(global.dpy, global.backgc, global.colors[0].pixel);//black. we're about to draw the blank background using this.
-  XSetBackground(global.dpy, global.gc, global.colors[160].pixel);
-  XSetBackground(global.dpy, global.backgc, global.colors[140].pixel);
-
-  XFillRectangle(global.dpy,global.cleanbackbuffer,global.backgc,0,0,global.width,global.height);
-  XSetForeground(global.dpy, global.backgc, global.green.pixel);
-
-//  XSetForeground(global.dpy, gc, whiteColor);
-// this was taking a "long" time.
-  printf("# generating sky... ");
-  skypixmap=XCreatePixmap(global.dpy,global.w,SKYW,SKYH,DefaultDepth(global.dpy,DefaultScreen(global.dpy)));
-  for(i=0;i<SKYH;i++) {
-   for(j=0;j<SKYW;j++) {
-    if(i==0) sky[i][j]=rand()%2;
-    else {
-     sky[i][j]=(SKYRULE >> ((!!sky[i-1][(j+(SKYW)-1)%(SKYW)]<<2) | (!!sky[i-1][j]<<1) | (!!sky[i-1][j+1%(SKYW)])) & 1);
-     if(sky[i][j]) {
-      XDrawPoint(global.dpy,skypixmap,global.backgc,j,i);
-     }
-    }
-   }
-  }
-  printf("done.\n");
-
-  global.mapxoff=global.width/2;
-  global.mapyoff=global.height/2;
-  global.drawminimap=0;
-  global.draw3d=1;
-  global.force_redraw=1;//use this for checking proper fps I guess.
-  camera.zoom=30.0l;
-  camera.xr=270;
-  camera.yr=270;
-  camera.zr=0;
-  global.mmz=1;
-  camera.p.x=0;
-  camera.p.z=6;
-  camera.p.y=5;
-#endif
-  global.debug=0;
-  printf("# entering main loop\n");
-  for(;;) {
-    redraw=global.force_redraw;
-#ifdef GRAPHICAL
-    while(XPending(global.dpy)) {//these are taking too long?
-     XNextEvent(global.dpy, &e);
-//     printf("# handling event with type: %d\n",e.type);
-     switch(e.type) {
-//       case Expose:
-//         if(e.xexpose.count == 0) redraw=1;
-//         break;
-       case MotionNotify:
-         redraw=1;
-         XQueryPointer(global.dpy,global.w,&root,&child,&global.rmousex,&global.rmousey,&global.mousex,&global.mousey,&mask);
-         break;
-       case ButtonPress:
-         redraw=1;
-         global.buttonpressed=e.xbutton.button;
-         break;
-       case ButtonRelease:
-         redraw=1;
-         global.buttonpressed=0;
-         break;
-       case ConfigureNotify:
-         redraw=1;
-         XGetGeometry(global.dpy,global.w,&root,&global.x,&global.y,&global.width,&global.height,&global.border_width,&global.depth);
-         if(global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1 )) / 4 * 3 != global.height) {
-          if(global.height * 3 / 4 == global.height) {
-           printf("math doesn't work.\n");
-          }
-          printf("# DERPY WM CANT TAKE A HINT %d / %d / 4 * 3 = %d != %d\n",global.width,global.split_screen,global.width /global.split_screen /4 * 3,global.height);
-          if(global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1)) / 4 * 3 < global.height) {
-           global.height=global.width / (global.split_screen / (global.red_and_blue ? global.split_screen : 1)) / 4 * 3;
-          } else {
-           global.width=global.height * 3 / 4 * (global.split_screen / (global.red_and_blue ? global.split_screen : 1));
-          }
-         }
-         global.mapxoff=global.width/(global.split_screen / (global.red_and_blue ? global.split_screen : 1))/2;
-         global.mapyoff=global.height/2;
-         break;
-       case KeyPress:
-         redraw=1;
-         if(keypress_handler(XLookupKeysym(&e.xkey,0)) == -1) {
-          printf("# exiting\n");
-          return 0;
-         }
-         break;
-       default:
-         //printf("# received event with type: %d\n",e.type);
-         break;
-     }
-    }
-    if(redraw && !global.headless) {
-     draw_screen(global.dpy,global.w,global.gc);
-    }
-#endif
-    switch(load_stdin()) {
-     case -1:
-      return 0;
-      break;
-     case 0:
-      break;
-     default:
-      redraw=1;
-      break;
-    }
-  }
-  return 0;
-}
diff --git a/tools/obj2hackvr.pl b/tools/obj2hackvr.pl

index d8727e21397f82697f876321c8607d13dbd1efd5..

index ..8173eee2cf662b5325c75db978e6fe451496dcf3 100755

--- a/tools/obj2hackvr.pl
+++ b/tools/obj2hackvr.pl
@@ -16,7 +16,7 @@ my @tmp;
 my $tmp;
 open(FILE,$ARGV[1]) if $ARGV[1];
 while(<FILE>) {
- chomp;
+ $_ =~ s/[\n\r]//g;
  @linepart=split(/ /,$_,2);
  $com=$linepart[0];
  if($com eq "v") {
diff --git a/tools/obj2hackvr2.pl b/tools/obj2hackvr2.pl
new file mode 100755
index 0000000000000000000000000000000000000000..92d16a7c3980384211c2ecc9f9be3e20845b0073
--- /dev/null
+++ b/tools/obj2hackvr2.pl
@@ -0,0 +1,49 @@
+#!/usr/bin/perl
+
+use strict;
+
+die "usage: obj2hackvr.pl name file\n" unless $ARGV[0];
+
+my $i;
+my $j;
+my $com;
+my @vertices;
+my @faces;
+my @linepart;
+my @parts;
+my @points;
+my @tmp;
+my $tmp;
+open(FILE,$ARGV[1]) if $ARGV[1];
+while(<FILE>) {
+ chomp;
+ $_ =~ s/[\r\n]//g;
+ @linepart=split(/ /,$_,2);
+ $com=$linepart[0];
+ if($com eq "v") {
+  push(@vertices,$linepart[1]);
+ }
+ if($com eq "f") {
+  push(@faces,$linepart[1]);
+ }
+}
+
+#foreach $tmp (@vertices) {
+# foreach(@$tmp) {
+# print $tmp . "\n";
+# }
+#}
+
+foreach $tmp (@faces) {
+ @points=split(/ /,$tmp);
+ @points = map { $_ =~ s/\/.+$//g; $_; } @points;
+## print @points;
+ print $ARGV[0];
+ print " addshape ";
+ print @points+0;
+ for($i=0;$i<(@points);$i++) {
+  print " ";
+  print $vertices[$points[$i]-1];
+ }
+ print "\n";
+}

-----END OF PAGE-----

-- Response ended

-- Page fetched on Sun Jun 2 16:24:19 2024