-- 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: b4dddad64122649d9da6340032275d1756930e74:
path_to:
revision_to:

git.thebackupbox.net

hackvr

git://git.thebackupbox.net/hackvr

commit b4dddad64122649d9da6340032275d1756930e74
Author: epoch <epoch@hacking.allowed.org>
Date:   Fri Dec 9 15:54:33 2016 -0600

    LOTS OF SHIT

diff --git a/IPs_to_triangle.sh b/IPs_to_triangle.sh
new file mode 100755
index 0000000000000000000000000000000000000000..a84e3dba040d34b260d7873cab1c5c5407b803e1
--- /dev/null
+++ b/IPs_to_triangle.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+whob | egrep '^IP|^Lat|^Long' | cut '-d ' -f2- | paste - - - | tr '\t' ' ' | awk '{print $1, $3, $2, 0, $3, $2, 0, $3, $2, 0}' | xargs -L1 printf '%s addtriangle %s %s %s %s %s %s %s %s %s\n'
diff --git a/cornell_box/cb.dat b/cornell_box/cb.dat
new file mode 100644
index 0000000000000000000000000000000000000000..33c189df5469862c4ed74e0fff97079a51566d26
--- /dev/null
+++ b/cornell_box/cb.dat
@@ -0,0 +1,5 @@
+#floor
+552.8 0.0   0.0
+  0.0 0.0   0.0
+  0.0 0.0 559.2
+549.6 0.0 559.2
diff --git a/filebrowser/filebrow.sh b/filebrowser/backend-filebrowser.sh
similarity index 68%
rename from filebrowser/filebrow.sh
rename to filebrowser/backend-filebrowser.sh

index ef6911abb9cc5c12b3a45c9080dc5ead612a343f..

index ..9cbf11a14716113b18cab27b691e7522a68b8b6b 100755

--- a/filebrowser/filebrow.sh
+++ b/filebrowser/backend-filebrowser.sh
@@ -4,8 +4,10 @@
 #cd or start that file
 #repeat.
 while true;do
-  echo
-  echo .* * | tr ' ' '\n'
+#not sure why this needs to be printed to show up every time.
+  echo ..
+  echo ..
+  find . -maxdepth 1 #| tr ' ' '\n' #wut? no?
   read -r selection
   if [ -f "$selection" ];then
     xdg-open "$selection" #good enough?
@@ -13,4 +15,5 @@ while true;do
   if [ -d "$selection" ];then
     cd "$selection"
   fi
+  echo
 done
diff --git a/filebrowser/backend-gopher.sh b/filebrowser/backend-gopher.sh
new file mode 100755
index 0000000000000000000000000000000000000000..69e1bbe56425991a5428b41f52c5b2c1317d87d2
--- /dev/null
+++ b/filebrowser/backend-gopher.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+#give a list of files.
+#wait for a selection on stdin
+#cd or start that file
+#repeat.
+server=192.168.0.2
+port=70
+selection=/
+while true;do
+#not sure why this needs to be printed to show up every time.
+  printf '%s\n' "$selection" | ncat "$server" "$port"
+  read -r selection
+  echo
+done
diff --git a/filebrowser/frontend-hackvr.sh b/filebrowser/frontend-hackvr.sh
new file mode 100755
index 0000000000000000000000000000000000000000..f04e5343cc33ab66ef94625abcab284daf91c2f6
--- /dev/null
+++ b/filebrowser/frontend-hackvr.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+stdbuf -oL $1 < p | ./list_to_cubes.sh | ../hackvr epoch | ./action_to_target.sh > p
diff --git a/filebrowser/frontend-zenity.sh b/filebrowser/frontend-zenity.sh
new file mode 100755
index 0000000000000000000000000000000000000000..acb7cd73aa78928a71033996bd8be64e6b6ea16f
--- /dev/null
+++ b/filebrowser/frontend-zenity.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+stdbuf -oL $1 < p | stdbuf -oL tr '\n' ' ' | sed -u 's/$/_/' | stdbuf -oL tr '_' '\n' | xargs -L1 zenity --list --column file > p
diff --git a/filebrowser/hackvr-frontend.sh b/filebrowser/hackvr-frontend.sh
deleted file mode 100755
index 002ba42b717eab7c8e33c5fd3a51725ce53c08de..0000000000000000000000000000000000000000
--- a/filebrowser/hackvr-frontend.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-stdbuf -oL ./filebrow.sh < p | ./list_to_cubes.sh | ../hackvr epoch | ./action_to_target.sh > p
diff --git a/filebrowser/list_to_cubes.sh b/filebrowser/list_to_cubes.sh

index 5de89a67fe191202a2f3462ff2714bec55afe337..

index ..d4ad6885575ba0a58f38882ac978736fd232d1a5 100755

--- a/filebrowser/list_to_cubes.sh
+++ b/filebrowser/list_to_cubes.sh
@@ -1,4 +1,13 @@
 #!/bin/bash
+# blank lines deleteallexcept epoch
+# expected input format:
+#
+# line1
+# line2
+# line3
+#
+# line1
+# line2
 while read -r line;do
  if [ "_$line" != '_' ];then
 #  ../tools/obj2hackvr.pl "$line" ../meshes/cube.obj
diff --git a/filebrowser/zenity-frontend.sh b/filebrowser/zenity-frontend.sh
deleted file mode 100755
index 0ba5efbcfb89c9f2aa236d8b2cbb8aea2d9bf576..0000000000000000000000000000000000000000
--- a/filebrowser/zenity-frontend.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-cat p | ./filebrow.sh | tr -d '\n' | xargs -L1  zenity --list --column file > p
diff --git a/ma2.dat b/ma2.dat
new file mode 100644
index 0000000000000000000000000000000000000000..f771aa3c40ad18a306bf9dae3d12ebdf98bc3fe9
--- /dev/null
+++ b/ma2.dat
@@ -0,0 +1,9 @@
+-180.0 1.0
+-135.0 -1.0
+-90.0 1.0
+-45.0 -1.0
+0.0 1.0
+45.0 -1.0
+90.0 1.0
+135.0 -1.0
+180.0 1.0
diff --git a/map.dat b/map.dat
new file mode 100644
index 0000000000000000000000000000000000000000..13b026c97d6e83e2cf47bbcabc0f28f611a64267
--- /dev/null
+++ b/map.dat
@@ -0,0 +1,18 @@
+1.0 -180.0
+-1.0 -135.0
+1.0 -90.0
+-1.0 -45.0
+1.0 0.0
+-1.0 45.0
+1.0 90.0
+-1.0 135.0
+1.0 180.0
+-180.0 1.0
+-135.0 -1.0
+-90.0 1.0
+-45.0 -1.0
+0.0 1.0
+45.0 -1.0
+90.0 1.0
+135.0 -1.0
+180.0 1.0
diff --git a/map2globe.py b/map2globe.py
new file mode 100755
index 0000000000000000000000000000000000000000..52ab4162eb55dc784bcf10586bbf7d63cdd20187
--- /dev/null
+++ b/map2globe.py
@@ -0,0 +1,47 @@
+#!/usr/bin/python3.4
+
+import sys
+import math
+
+plat=0
+plon=0
+lat=0
+lon=0
+x="0"
+y="0"
+z="0"
+
+#lon goes from -180 to +180
+#lat goes from -90 to +90
+# / 90 * math.pi
+#they need to be in the range 0 to 2pi?
+
+while(1):
+ #print (plat,plon,lat,lon)
+ try:
+  line=input()
+  line.strip('\r\n')
+  (lon,lat)=map(float,filter(None,line.split(' ')))
+  slat=(((lat)/180)*math.pi)
+  slon=(((lon)/180)*math.pi)
+  (x,y,z)=map(str,(math.cos(slat)*math.cos(slon), math.sin(slat),math.cos(slat)*math.sin(slon)))
+#  (x,y,z)=map(str,(slon,slat,0))
+ except EOFError:
+  print("# reached EOF")
+  break
+ except ValueError:
+  #ignore this line
+  print("# read an invalid line: " + line)
+  if(line == ""):
+   (lat,lon,x,y,z)=(0,0,"","","")
+ except:
+  e = sys.exc_info()[0]
+  print("# error: " + str(e))
+  break
+ if(lat and lon and x and y and z and plat and plon and px and py and pz): #if the previouses exist
+  print("globe addshape 3 " + x + " " + y + " " + z + " " + x + " " + y + " " + z + " " + px + " " + py + " " + pz)
+
+#set previouses to currents
+ (plat,plon,px,py,pz)=(lat,lon,x,y,z)
+
+print("# done")
diff --git a/meshes/monkey.blend b/meshes/monkey.blend
new file mode 100644
index 0000000000000000000000000000000000000000..1561c5996f47845ea9f48fb58c345c908de467c0
Binary files /dev/null and b/meshes/monkey.blend differ
diff --git a/tests/automata b/tests/automata
new file mode 100755
index 0000000000000000000000000000000000000000..7cec568cbb2aca61c0064dad690f612f81f8db13
Binary files /dev/null and b/tests/automata differ
diff --git a/tests/automata.c b/tests/automata.c
new file mode 100644
index 0000000000000000000000000000000000000000..35629e039c4ef5487951ed03606a7ecfac229aa4
--- /dev/null
+++ b/tests/automata.c
@@ -0,0 +1,453 @@
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#define __USE_GNU //for longer math constants
+#include <math.h>
+
+//#define DEBUG
+
+#define SPLIT_SCREEN 2
+#define CAMERA_SEPARATION 3
+
+#define DEPTH_FACTOR 0.965
+
+#define TRIANGLES 256
+
+#define min(a,b) (((a)<(b))?(a):(b))
+#define max(a,b) (((a)>(b))?(a):(b))
+
+//for one camera, not the whole thing.
+//3 camera
+//#define WIDTH 320
+//#define HEIGHT 240
+//1 camera
+//#define WIDTH 800
+//#define HEIGHT 600
+//2 camera
+#define WIDTH 400
+#define HEIGHT 300
+
+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 {
+  int x;
+  int y;
+  int z;
+  int xr;//rotations
+  int yr;
+  int zr;
+} camera;
+
+struct triangle {//use array or linked list?
+  char *id;
+  int x1;
+  int y1;
+  int z1;
+  int x2;
+  int y2;
+  int z2;
+  int x3;
+  int y3;
+  int z3;
+//  int dist;//most recent distance calculated from the camera
+};
+
+struct mainwin {
+  int x;
+  int y;
+  int depth;
+  int mousex;
+  int mousey;
+  int rmousex;
+  int rmousey;
+  int buttonpressed;
+  int width;
+  int height;
+  int border_width;
+  int xoff;
+  int math_error;
+  char *user;
+  XColor green;
+  Colormap color_map;
+  Display *dpy;
+  Window w;
+  GC gc;
+  struct triangle *triangle[TRIANGLES];
+} global;
+
+
+float zmagic(int z) {
+ float tmp=pow(DEPTH_FACTOR,(camera.z-z));
+// float tmp=pow(DEPTH_FACTOR,(camera.z-z))/(camera.z-z);
+// float tmp=pow(DEPTH_FACTOR,(camera.z-z)*(camera.z-z)*(camera.z-z));
+ //measure the distance form the camera and error out if it is too far away.
+// if((camera.z - z) >= 0) return(global.math_error=1);
+ //return (float)1 / (float)(camera.z - z);
+ return tmp;
+}
+
+int to2D(int cw,int w,int z,int d) {
+  return (d/2) - (((w-cw) / zmagic(z)) * 16 );
+}
+
+
+float distance(int x1,int y1,int x2,int y2) {
+ return sqrt(((x2-x1)*(x2-x1))+((y2-y1)*(y2-y1)));
+}
+
+long double d2r(int d) {
+ while(d<0) d+=360;
+ return (long double)(d%360) / 180.0l * M_PIl;
+}
+
+int rotateXabout(int x1,int y1,int z1,int x2,int y2,int z2,int degrees) {
+ long double radians=(long double)degrees / (long double)180 * M_PIl;//M_PIl for long double
+ long double radius=distance(x1,z1,x2,z2);
+ if(radius == 0) return x2;
+ return x2 + radius * cosl(acosl(((long double)x2-(long double)x1)/radius)+radians);
+}
+
+int rotateZabout(int x1,int y1,int z1,int x2,int y2,int z2,int degrees) {
+ long double radians=(long double)degrees / (long double)180 * M_PIl;//M_PIl for long double
+ long double radius=distance(x1,z1,x2,z2);
+ if(radius == 0) return z2;
+ return z2 + radius * sinl(asinl(((long double)z2-(long double)z1)/radius)+radians);
+}
+
+
+int to2Dx(int x,int y,int z) {
+  int newx=rotateXabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newy=y;//rotateYabout(x,y,z,camera.x,camera.y,camera.z,camera.xr);
+  int newz=rotateZabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  return to2D(camera.x,newx,newz,global.width/SPLIT_SCREEN);
+//  return to2D(camera.x,x,z,global.width/SPLIT_SCREEN);
+}
+
+int to2Dy(int x,int y,int z) {
+  int newx=rotateXabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newy=y;//rotateYabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newz=rotateZabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  return to2D(camera.y,newy,newz,global.height);
+//  return to2D(camera.y,y,z,global.height);
+}
+
+void XDrawTriangle(int x1,int y1,int x2,int y2,int x3,int y3) {
+ int x;
+ XDrawLine(global.dpy,global.w,global.gc,x1,y1,x2,y2);
+ XDrawLine(global.dpy,global.w,global.gc,x2,y2,x3,y3);
+ XDrawLine(global.dpy,global.w,global.gc,x3,y3,x1,y1);
+}
+
+void XDrawFilledTriangle(int x1,int y1,int x2,int y2,int x3,int y3,int density) {
+ int x,y;
+ int b;
+ float m;
+
+ XDrawLine(global.dpy,global.w,global.gc,x1,y1,x2,y2);
+ XDrawLine(global.dpy,global.w,global.gc,x2,y2,x3,y3);
+ XDrawLine(global.dpy,global.w,global.gc,x3,y3,x1,y1);
+
+ m=(float)(y1-y2)/(float)(x1-x2);
+ b=y1-(m*x1);
+ for(x=min(x1,x2);x<max(x1,x2);x+=4) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x3,y3,x,y);
+ }
+
+ m=(float)(y2-y3)/(float)(x2-x3);
+ b=y2-(m*x2);
+ for(x=min(x2,x3);x<max(x2,x3);x+=4) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x1,y1,x,y);
+ }
+
+ m=(float)(y3-y1)/(float)(x3-x1);
+ b=y3-(m*x3);
+ for(x=min(x3,x1);x<max(x3,x1);x+=4) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x2,y2,x,y);
+ }
+}
+
+void draw3Dtriangle(int x1,int y1,int z1,int x2,int y2,int z2,int x3,int y3,int z3) {
+  char coords[256];
+  global.math_error=0;
+  int tx1=to2Dx(x1,y1,z1);
+  int ty1=to2Dy(x1,y1,z1);
+  //draw string...
+  int tx2=to2Dx(x2,y2,z2);
+  int ty2=to2Dy(x2,y2,z2);
+  int tx3=to2Dx(x3,y3,z3);
+  int ty3=to2Dy(x3,y3,z3);
+  if(!global.math_error) {
+#ifdef DEBUG
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x1,y1,z1);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx1,ty1,coords,strlen(coords));
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x2,y2,z2);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx2,ty2,coords,strlen(coords));
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x3,y3,z3);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx3,ty3,coords,strlen(coords));
+#endif
+    XDrawTriangle(global.xoff+tx1,ty1,global.xoff+tx2,ty2,global.xoff+tx3,ty3);
+//    XDrawFilledTriangle(global.xoff+tx1,ty1,global.xoff+tx2,ty2,global.xoff+tx3,ty3);
+  }
+}
+
+void draw3Dline(int x1,int y1,int z1,int x2,int y2,int z2) {
+  global.math_error=0;
+  int tx1=to2Dx(x1,y1,z1);
+  int ty1=to2Dy(x1,y1,z1);
+  int tx2=to2Dx(x2,y2,z2);
+  int ty2=to2Dy(x2,y2,z2);
+  if(!global.math_error) {
+    XDrawLine(global.dpy,global.w,global.gc,global.xoff+tx1,ty1,global.xoff+tx2,ty2);
+  }
+  global.math_error=0;
+}
+
+
+//is basing this all on triangles best, or should I use polygons?
+//void pushTriangle(x1,y1,z1,1) {
+//  for(i=0;global.triangle[i];i++);
+//  global.triangle[i]=malloc(sizeof(struct triangle));
+//  global.triangle[i]->x1=x1;
+//}
+//void pushSquare() {
+//  pushTriangle();
+//  pushTriangle();
+//}
+
+void drawCube(int x,int y,int z,int i) {
+//this is just drawing the cube.
+    draw3Dline(x,y,z,x,y,z+i);
+    draw3Dline(x,y,z,x,y+i,z);
+    draw3Dline(x,y,z,x+i,y,z);
+
+    draw3Dline(x+i,y+i,z+0,x+i,y+0,z+0);
+    draw3Dline(x+i,y+i,z+0,x+0,y+i,z+0);
+
+    draw3Dline(x+0,y+i,z+i,x+0,y+i,z+0);
+    draw3Dline(x+0,y+i,z+i,x+0,y+0,z+i);
+
+    draw3Dline(x+i,y+0,z+i,x+i,y+0,z+0);
+    draw3Dline(x+i,y+0,z+i,x+0,y+0,z+i);
+
+    draw3Dline(x+i,y+i,z+i,x+i,y+i,z+0);
+    draw3Dline(x+i,y+i,z+i,x+i,y+0,z+i);
+    draw3Dline(x+i,y+i,z+i,x+0,y+i,z+i);
+}
+
+int applyrule(int a,int b,int c,int rule) {
+ return (rule >> ((!!a<<2) | (!!b<<1) | (!!c)) ) % 2;
+}
+
+char field[HEIGHT+1][WIDTH+1];
+
+void draw_screen(Display *dpy,Window w,GC gc) {
+  int i,j,k;
+  int cn=0;//camera number.
+  char **files;
+  static int offset=0;
+  XFontStruct *font=XLoadQueryFont(dpy,"fixed");
+  XCharStruct overall;
+  int direction,ascent,descent;
+  char coords[256];
+  int x,y,z,x1,y1,x2,y2;
+  XEvent e;
+  XClearWindow(dpy, w);
+
+  j=0;
+  for(i=0;i<HEIGHT;i++) {
+   for(j=0;j<WIDTH;j++) {
+    if(field[i][j]) XDrawPoint(dpy,w,gc,j,i);
+   }
+  }
+  XFlush(dpy);
+}
+
+int load_file(FILE *fp) {
+ struct triangle *to;
+ struct triangle t;
+ char *command;
+ static int i=0;//used to store the last triangle.
+
+ for(;global.triangle[i];i++) ;//hop to the end.
+
+ fcntl(fileno(fp),F_SETFL,O_NONBLOCK);
+
+ for(;;i++) {
+  if(feof(fp))  {
+   //printf("resetting EOF\n");
+   clearerr(fp);
+  }
+  if(fscanf(fp,"%ms %ms %d %d %d %d %d %d %d %d %d",&(t.id),&command,&(t.x1),&(t.y1),&(t.z1),&(t.x2),&(t.y2),&(t.z2),&(t.x3),&(t.y3),&(t.z3)) > 0) {
+   /*if(!strcmp(command,"addsquare")) { } */
+   if(!strcmp(command,"addtriangle")) {
+    global.triangle[i]=malloc(sizeof(struct triangle));
+    to=global.triangle[i];
+    memcpy(to,&t,sizeof(t));
+   }
+   if(!strcmp(command,"move")) {
+    for(i=0;global.triangle[i];i++) {
+     if(!strcmp(global.triangle[i]->id,t.id)) {
+      global.triangle[i]->x1+=t.x1;
+      global.triangle[i]->y1+=t.y1;
+      global.triangle[i]->z1+=t.z1;
+
+      global.triangle[i]->x2+=t.x1;
+      global.triangle[i]->y2+=t.y1;
+      global.triangle[i]->z2+=t.z1;
+
+      global.triangle[i]->x3+=t.x1;
+      global.triangle[i]->y3+=t.y1;
+      global.triangle[i]->z3+=t.z1;
+     }
+    }
+   }
+   global.triangle[i+1]=0;
+   draw_screen(global.dpy,global.w,global.gc);
+  } else {
+   global.triangle[i]=0;
+   break;
+  }
+ }
+}
+
+int export_file(FILE *fp) {
+ struct triangle *to;
+ int i;
+ for(i=0;global.triangle[i];i++) {
+  to=global.triangle[i];
+  printf("%s addtriangle %d %d %d %d %d %d %d %d %d\n",to->id,to->x1,to->y1,to->z1,to->x2,to->y2,to->z2,to->x3,to->y3,to->z3);
+ }
+}
+
+
+int main(int argc,char *argv[]) {
+  char redraw=0;
+  if(argc < 2) {
+   fprintf(stderr,"usage: hackvr yourname < from_others > to_others\n");
+   return 1;
+  } else {
+   global.user=strdup(argv[1]);
+  }
+  setbuf(stdin,0);
+  setbuf(stdout,0);
+  Display *dpy = XOpenDisplay(0);
+  assert(dpy);
+  global.dpy=dpy;
+  unsigned int mask;
+  int i;
+  XEvent e;
+  XSetWindowAttributes attributes;
+  int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+  int whiteColor = //WhitePixel(dpy, DefaultScreen(dpy));
+  attributes.background_pixel=blackColor;
+  Window w = XCreateWindow(dpy,DefaultRootWindow(dpy),0,0,WIDTH*SPLIT_SCREEN,HEIGHT,1,DefaultDepth(dpy,DefaultScreen(dpy)),InputOutput,DefaultVisual(dpy,DefaultScreen(dpy))\
+                           ,CWBackPixel, &attributes);
+  global.w=w;
+  global.triangle[0]=0;//we'll allocate as we need more.
+
+  int j;
+
+  for(i=0;i<HEIGHT;i++) {
+   for(j=0;j<WIDTH;j++) {
+    if(i==0) field[i][j]=rand()%2;
+    else field[i][j]=(j==0 || j==WIDTH)?0:applyrule(field[i-1][j-1],field[i-1][j],field[i-1][j+1],22);
+   }
+  }
+
+  Window root,child;
+  XSelectInput(dpy, w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|ResizeRedirectMask|KeyPressMask);
+  XMapWindow(dpy, w);
+  XStoreName(dpy,w,"hackvr");
+  GC gc = XCreateGC(dpy, w, 0, 0);
+  global.gc=gc;
+  global.color_map=DefaultColormap(dpy, DefaultScreen(dpy));
+  XAllocNamedColor(dpy, global.color_map, "green", &global.green, &global.green);
+  XSetForeground(dpy, gc, global.green.pixel);
+//  XSetForeground(dpy, gc, whiteColor);
+  for(;;) {
+    load_file(stdin);
+    XNextEvent(dpy, &e);
+    redraw=1;
+    switch(e.type) {
+      case MotionNotify:
+        XQueryPointer(dpy,w,&root,&child,&global.rmousex,&global.rmousey,&global.mousex,&global.mousey,&mask);
+        break;
+      case ButtonPress:
+        global.buttonpressed=e.xbutton.button;
+        break;
+      case ButtonRelease:
+        global.buttonpressed=0;
+        break;
+      case ResizeRequest:
+        XGetGeometry(dpy,w,&root,&global.x,&global.y,&global.width,&global.height,&global.border_width,&global.depth);
+      case KeyPress:
+        switch(XLookupKeysym(&e.xkey,0)) {
+          case XK_Up:
+           //fix these to use calculated values down there.
+           //printf("%s move 0 0 1 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr));
+           camera.x+=5*sinl(d2r(camera.yr)); break;
+          case XK_Down:
+           //printf("%s move 0 0 -1 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+180));
+           camera.x+=5*sinl(d2r(camera.yr+180)); break;
+          case XK_Left:
+           //printf("%s move 1 0 0 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+90));
+           camera.x+=5*sinl(d2r(camera.yr+90)); break;
+          case XK_Right:
+           //printf("%s move -1 0 0 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+270));
+           camera.x+=5*sinl(d2r(camera.yr+270)); break;
+          case XK_w:
+           //printf("%s move 0 1 0 0 0 0 0 0 0\n",global.user);
+           camera.y+=5; break;
+          case XK_s:
+           //printf("%s move 0 -1 0 0 0 0 0 0 0\n",global.user);
+           camera.y-=5; break;
+          case XK_q:
+           camera.yr+=5; break;
+          case XK_e:
+           camera.yr-=5; break;
+          case XK_Escape: return 0;
+          default:
+           redraw=0;
+           break;
+        }
+      default:
+        redraw=0;
+        break;
+    }
+    //if(redraw)
+    draw_screen(dpy,w,gc);
+  }
+  return 0;
+}
diff --git a/tests/automata_text b/tests/automata_text
new file mode 100755
index 0000000000000000000000000000000000000000..28d79ccef13301b4e8d8931a9a750d4eb6cd33b8
Binary files /dev/null and b/tests/automata_text differ
diff --git a/tests/automata_text.c b/tests/automata_text.c
new file mode 100644
index 0000000000000000000000000000000000000000..574c4021a043bf660ebd9b85a6caa9febf983b9a
--- /dev/null
+++ b/tests/automata_text.c
@@ -0,0 +1,34 @@
+#include <stdio.h>
+#include <string.h>
+
+#define HE he
+#define WI wi
+#define RULE rule
+
+
+int main(int argc,char *argv[]) {
+  int i,j;
+  int rule=atoi(argv[1]);
+  char str[256];//lel. close enough.
+  int wi=read(0,str,sizeof(str)-1)*8;
+  int he=atoi(argv[2]);
+  char f[HE+1][WI+1];
+  f[0][WI/2]=1;
+  for(i=0;i<HE;i++) {
+   for(j=0;j<WI;j++) {
+    if(i==0) f[i][j]=(str[j/8]>>(j%8))%2;
+    else f[i][j]=(RULE >> ((!!f[(i+HE-1)%HE][(j+WI-1)%WI]<<2) | (!!f[(i+HE-1)%HE][j]<<1) | (!!f[(i+HE-1)%HE][(j+1)%WI])) & 1);
+   }
+  }
+  for(i=0;i<HE;i++) {
+   for(j=0;j<WI;j++) {
+    if(f[i][j]) {
+     printf("%c",f[i][j]+'0');
+    } else {
+     printf(" ");
+    }
+   }
+   printf("\n");
+  }
+ return 0;
+}
diff --git a/tests/prog-2 b/tests/prog-2
new file mode 100755
index 0000000000000000000000000000000000000000..007a226290e4cb5c6638532a125a6fb9ce248bf5
Binary files /dev/null and b/tests/prog-2 differ
diff --git a/tests/prog-2.c b/tests/prog-2.c
new file mode 100644
index 0000000000000000000000000000000000000000..8af45481747c2aa4a7d84323b2f0f7354531c669
--- /dev/null
+++ b/tests/prog-2.c
@@ -0,0 +1,175 @@
+#include <X11/Xlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+struct mainwin {
+  int x;
+  int y;
+  int depth;
+  int mousex;
+  int mousey;
+  int rmousex;
+  int rmousey;
+  int buttonpressed;
+  int width;
+  int height;
+  int border_width;
+  XColor green;
+  Colormap color_map;
+} global;
+
+int mycmp(const void *a,const void *b) {
+// printf("comparing '%s' and '%s'\n",*(char **)a,*(char **)b);
+ return strcmp(*(char **)a,*(char **)b);
+}
+
+char **ls(char *dir) {
+  DIR *fd;
+  char **files=malloc(sizeof(char *) * 1000);
+  struct dirent *d;
+  int i;
+  fd = opendir(".");
+  if (fd) {
+    for (i=0;(d = readdir(fd)) != NULL;i++) {
+      files[i]=strdup(d->d_name);
+    }
+    files[i]=0;
+    closedir(fd);
+  }
+  //now to sort files in numerical order.
+//       void qsort(void *base, size_t nmemb, size_t size,
+//                  int (*compar)(const void *, const void *));
+  qsort(files,i,sizeof(char *),mycmp);
+  return files;
+}
+
+void freels(char **files) {
+  int i;
+  for(i=0;files[i];i++) {
+    free(files[i]);
+  }
+  free(files);
+}
+
+void draw_screen(Display *dpy,Window w,GC gc) {
+  int i;
+  char **files;
+  static int offset=0;
+  XFontStruct *font=XLoadQueryFont(dpy,"fixed");
+  XCharStruct overall;
+  int direction,ascent,descent;
+  char coords[256];
+  int x,y;
+  XEvent e;
+  XClearWindow(dpy, w);
+  snprintf(coords,sizeof(coords)-1,"x: %d y: %d",global.mousex,global.mousey);
+  files=ls(".");
+  for(i=0;files[i];i++) {
+    XTextExtents(font,files[i],strlen(files[i]),&direction,&ascent,&descent,&overall);
+    x=30;
+    y=((ascent+descent)*(i+3))+offset;
+    XDrawString(dpy,w,gc,x,y,files[i],strlen(files[i]));
+    if(global.mousex > x && global.mousex < x+overall.width && global.mousey > y-ascent && global.mousey < y+descent) {
+     if(global.buttonpressed) {
+       if(chdir(files[i])) if(!fork()) execlp("xdg-open","xdg-open",files[i],0);
+       else offset=0;
+     }
+     //top line
+     XDrawLine(dpy,w,gc,0,y-ascent,x+overall.width,y-ascent);
+     //bottom line
+     XDrawLine(dpy,w,gc,x,y+descent,global.width,y+descent);
+     //left line
+     XDrawLine(dpy,w,gc,x,y-ascent,x,y+descent);
+     //right line
+     XDrawLine(dpy,w,gc,x+overall.width,y-ascent,x+overall.width,y+descent);
+    }
+  }
+  //  ||
+  // \||/
+  //  \/
+  x=4;
+  y=global.height-16;
+
+  XDrawLine(dpy,w,gc,x+4+1,y+0+1,x+4+1,y+8+1);
+  XDrawLine(dpy,w,gc,x+0+1,y+4+1,x+4+1,y+8+1);
+  XDrawLine(dpy,w,gc,x+8+1,y+4+1,x+4+1,y+8+1);
+
+  if(global.mousex > x && global.mousex < x+10 && global.mousey > y && global.mousey < y+10) {
+   if(global.buttonpressed) {
+    offset-=40;
+   }
+   XDrawLine(dpy,w,gc,x,y,x+10,y);
+   XDrawLine(dpy,w,gc,x,y+10,x+10,y+10);
+   XDrawLine(dpy,w,gc,x,y,x,y+10);
+   XDrawLine(dpy,w,gc,x+10,y,x+10,y+10);
+  }
+  //  /\
+  // /||\
+  //  ||
+  x=4;
+  y=16;
+
+  XDrawLine(dpy,w,gc,x+4+1,y+0+1,x+4+1,y+8+1);
+  XDrawLine(dpy,w,gc,x+0+1,y+4+1,x+4+1,y+0+1);
+  XDrawLine(dpy,w,gc,x+8+1,y+4+1,x+4+1,y+0+1);
+
+  if(global.mousex > x && global.mousex < x+10 && global.mousey > y && global.mousey < y+10) {
+   if(global.buttonpressed) {
+    offset+=40;
+   }
+   XDrawLine(dpy,w,gc,x,y,x+10,y);
+   XDrawLine(dpy,w,gc,x,y+10,x+10,y+10);
+   XDrawLine(dpy,w,gc,x,y,x,y+10);
+   XDrawLine(dpy,w,gc,x+10,y,x+10,y+10);
+  }
+
+  XDrawString(dpy,w,gc,0,0+ascent,coords,strlen(coords));
+  XFlush(dpy);
+}
+
+int main(int argc,char *argv[])
+{
+  Display *dpy = XOpenDisplay(0);
+  assert(dpy);
+  unsigned int mask;
+  XEvent e;
+  XSetWindowAttributes attributes;
+  int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+  int whiteColor = //WhitePixel(dpy, DefaultScreen(dpy));
+  attributes.background_pixel=blackColor;
+  Window w = XCreateWindow(dpy,DefaultRootWindow(dpy),0,0,500,400,1,DefaultDepth(dpy,DefaultScreen(dpy)),InputOutput,DefaultVisual(dpy,DefaultScreen(dpy))\
+                           ,CWBackPixel, &attributes);
+  Window root,child;
+  XSelectInput(dpy, w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|ResizeRedirectMask);
+  XMapWindow(dpy, w);
+  XStoreName(dpy,w,"hackhackhack");
+  GC gc = XCreateGC(dpy, w, 0, 0);
+  global.color_map=DefaultColormap(dpy, DefaultScreen(dpy));
+  XAllocNamedColor(dpy, global.color_map, "green", &global.green, &global.green);
+  XSetForeground(dpy, gc, global.green.pixel);
+//  XSetForeground(dpy, gc, whiteColor);
+  for(;;) {
+    draw_screen(dpy,w,gc);
+    XNextEvent(dpy, &e);
+    switch(e.type) {
+      case MotionNotify:
+        XQueryPointer(dpy,w,&root,&child,&global.rmousex,&global.rmousey,&global.mousex,&global.mousey,&mask);
+        break;
+      case ButtonPress:
+        global.buttonpressed=e.xbutton.button;
+        break;
+      case ButtonRelease:
+        global.buttonpressed=0;
+        break;
+      case ResizeRequest:
+        XGetGeometry(dpy,w,&root,&global.x,&global.y,&global.width,&global.height,&global.border_width,&global.depth);
+      default:
+        break;
+    }
+  }
+  return 0;
+}
diff --git a/tests/readline b/tests/readline
new file mode 100755
index 0000000000000000000000000000000000000000..f45ea8cfcf3b5e9c137c428c66021c5a8f9dbb4e
Binary files /dev/null and b/tests/readline differ
diff --git a/tests/readline.c b/tests/readline.c
new file mode 100644
index 0000000000000000000000000000000000000000..76d6a2d5f8d7878b51c8cfbe11f86d8cd674b83a
--- /dev/null
+++ b/tests/readline.c
@@ -0,0 +1,20 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+char *read_line_hack(FILE *fp,int len) {
+ short in;
+ char *t;
+ if((in=fgetc(fp)) == '\n') {
+  t=malloc(len+1);
+  t[len]=0;
+  return t;
+ }
+ t=read_line_hack(fp,len+1);
+ t[len]=in;
+ return t;
+}
+
+int main() {
+ char *t=read_line_hack(stdin,0);
+ printf("%s\n",t);
+}
diff --git a/tests/rotate b/tests/rotate
new file mode 100755
index 0000000000000000000000000000000000000000..9266b2be3f74b5677a68e9286cb65fc8f22b8e4d
Binary files /dev/null and b/tests/rotate differ
diff --git a/tests/rotate.c b/tests/rotate.c
new file mode 100644
index 0000000000000000000000000000000000000000..7f7b9bc6747d6900fba8bad085b2ed8fd25fdb93
--- /dev/null
+++ b/tests/rotate.c
@@ -0,0 +1,458 @@
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#define __USE_GNU //for longer math constants
+#include <math.h>
+
+//#define DEBUG
+
+#define SPLIT_SCREEN 2
+#define CAMERA_SEPARATION 3
+
+#define DEPTH_FACTOR 0.965
+
+#define TRIANGLES 256
+
+#define min(a,b) (((a)<(b))?(a):(b))
+#define max(a,b) (((a)>(b))?(a):(b))
+
+//for one camera, not the whole thing.
+//3 camera
+//#define WIDTH 320
+//#define HEIGHT 240
+//1 camera
+//#define WIDTH 800
+//#define HEIGHT 600
+//2 camera
+#define WIDTH 400
+#define HEIGHT 300
+
+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 {
+  int x;
+  int y;
+  int z;
+  int xr;//rotations
+  int yr;
+  int zr;
+} camera;
+
+struct triangle {//use array or linked list?
+  char *id;
+  int x1;
+  int y1;
+  int z1;
+  int x2;
+  int y2;
+  int z2;
+  int x3;
+  int y3;
+  int z3;
+//  int dist;//most recent distance calculated from the camera
+};
+
+struct mainwin {
+  int x;
+  int y;
+  int depth;
+  int mousex;
+  int mousey;
+  int rmousex;
+  int rmousey;
+  int buttonpressed;
+  int width;
+  int height;
+  int border_width;
+  int xoff;
+  int math_error;
+  char *user;
+  XColor green;
+  Colormap color_map;
+  Display *dpy;
+  Window w;
+  GC gc;
+  struct triangle *triangle[TRIANGLES];
+} global;
+
+
+float zmagic(int z) {
+ float tmp=pow(DEPTH_FACTOR,(camera.z-z));
+// float tmp=pow(DEPTH_FACTOR,(camera.z-z))/(camera.z-z);
+// float tmp=pow(DEPTH_FACTOR,(camera.z-z)*(camera.z-z)*(camera.z-z));
+ //measure the distance form the camera and error out if it is too far away.
+// if((camera.z - z) >= 0) return(global.math_error=1);
+ //return (float)1 / (float)(camera.z - z);
+ return tmp;
+}
+
+int to2D(int cw,int w,int z,int d) {
+  return (d/2) - (((w-cw) / zmagic(z)) * 16 );
+}
+
+
+float distance(int x1,int y1,int x2,int y2) {
+ return sqrt(((x2-x1)*(x2-x1))+((y2-y1)*(y2-y1)));
+}
+
+long double d2r(int d) {
+ while(d<0) d+=360;
+ return (long double)(d%360) / 180.0l * M_PIl;
+}
+
+int rotateXabout(int x1,int y1,int z1,int x2,int y2,int z2,int degrees) {
+ long double radians=(long double)degrees / (long double)180 * M_PIl;//M_PIl for long double
+ long double radius=distance(x1,z1,x2,z2);
+ if(radius == 0) return x2;
+ return x2 + radius * cosl(acosl(((long double)x2-(long double)x1)/radius)+radians);
+}
+
+int rotateZabout(int x1,int y1,int z1,int x2,int y2,int z2,int degrees) {
+ long double radians=(long double)degrees / (long double)180 * M_PIl;//M_PIl for long double
+ long double radius=distance(x1,z1,x2,z2);
+ if(radius == 0) return z2;
+ return z2 + radius * sinl(asinl(((long double)z2-(long double)z1)/radius)+radians);
+}
+
+
+int to2Dx(int x,int y,int z) {
+  int newx=rotateXabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newy=y;//rotateYabout(x,y,z,camera.x,camera.y,camera.z,camera.xr);
+  int newz=rotateZabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  return to2D(camera.x,newx,newz,global.width/SPLIT_SCREEN);
+//  return to2D(camera.x,x,z,global.width/SPLIT_SCREEN);
+}
+
+int to2Dy(int x,int y,int z) {
+  int newx=rotateXabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newy=y;//rotateYabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newz=rotateZabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  return to2D(camera.y,newy,newz,global.height);
+//  return to2D(camera.y,y,z,global.height);
+}
+
+void XDrawTriangle(int x1,int y1,int x2,int y2,int x3,int y3) {
+ int x;
+ XDrawLine(global.dpy,global.w,global.gc,x1,y1,x2,y2);
+ XDrawLine(global.dpy,global.w,global.gc,x2,y2,x3,y3);
+ XDrawLine(global.dpy,global.w,global.gc,x3,y3,x1,y1);
+}
+
+void XDrawFilledTriangle(int x1,int y1,int x2,int y2,int x3,int y3) {
+ int x,y;
+ int b;
+ float m;
+
+ XDrawLine(global.dpy,global.w,global.gc,x1,y1,x2,y2);
+ XDrawLine(global.dpy,global.w,global.gc,x2,y2,x3,y3);
+ XDrawLine(global.dpy,global.w,global.gc,x3,y3,x1,y1);
+
+ m=(float)(y1-y2)/(float)(x1-x2);
+ b=y1-(m*x1);
+ for(x=min(x1,x2);x<max(x1,x2);x++) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x3,y3,x,y);
+ }
+
+ m=(float)(y2-y3)/(float)(x2-x3);
+ b=y2-(m*x2);
+ for(x=min(x2,x3);x<max(x2,x3);x++) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x1,y1,x,y);
+ }
+
+ m=(float)(y3-y1)/(float)(x3-x1);
+ b=y3-(m*x3);
+ for(x=min(x3,x1);x<max(x3,x1);x++) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x2,y2,x,y);
+ }
+}
+
+void draw3Dtriangle(int x1,int y1,int z1,int x2,int y2,int z2,int x3,int y3,int z3) {
+  char coords[256];
+  global.math_error=0;
+  int tx1=to2Dx(x1,y1,z1);
+  int ty1=to2Dy(x1,y1,z1);
+  //draw string...
+  int tx2=to2Dx(x2,y2,z2);
+  int ty2=to2Dy(x2,y2,z2);
+  int tx3=to2Dx(x3,y3,z3);
+  int ty3=to2Dy(x3,y3,z3);
+  if(!global.math_error) {
+#ifdef DEBUG
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x1,y1,z1);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx1,ty1,coords,strlen(coords));
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x2,y2,z2);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx2,ty2,coords,strlen(coords));
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x3,y3,z3);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx3,ty3,coords,strlen(coords));
+#endif
+    XDrawTriangle(global.xoff+tx1,ty1,global.xoff+tx2,ty2,global.xoff+tx3,ty3);
+//    XDrawFilledTriangle(global.xoff+tx1,ty1,global.xoff+tx2,ty2,global.xoff+tx3,ty3);
+  }
+}
+
+void draw3Dline(int x1,int y1,int z1,int x2,int y2,int z2) {
+  global.math_error=0;
+  int tx1=to2Dx(x1,y1,z1);
+  int ty1=to2Dy(x1,y1,z1);
+  int tx2=to2Dx(x2,y2,z2);
+  int ty2=to2Dy(x2,y2,z2);
+  if(!global.math_error) {
+    XDrawLine(global.dpy,global.w,global.gc,global.xoff+tx1,ty1,global.xoff+tx2,ty2);
+  }
+  global.math_error=0;
+}
+
+
+//is basing this all on triangles best, or should I use polygons?
+//void pushTriangle(x1,y1,z1,1) {
+//  for(i=0;global.triangle[i];i++);
+//  global.triangle[i]=malloc(sizeof(struct triangle));
+//  global.triangle[i]->x1=x1;
+//}
+//void pushSquare() {
+//  pushTriangle();
+//  pushTriangle();
+//}
+
+void drawCube(int x,int y,int z,int i) {
+//this is just drawing the cube.
+    draw3Dline(x,y,z,x,y,z+i);
+    draw3Dline(x,y,z,x,y+i,z);
+    draw3Dline(x,y,z,x+i,y,z);
+
+    draw3Dline(x+i,y+i,z+0,x+i,y+0,z+0);
+    draw3Dline(x+i,y+i,z+0,x+0,y+i,z+0);
+
+    draw3Dline(x+0,y+i,z+i,x+0,y+i,z+0);
+    draw3Dline(x+0,y+i,z+i,x+0,y+0,z+i);
+
+    draw3Dline(x+i,y+0,z+i,x+i,y+0,z+0);
+    draw3Dline(x+i,y+0,z+i,x+0,y+0,z+i);
+
+    draw3Dline(x+i,y+i,z+i,x+i,y+i,z+0);
+    draw3Dline(x+i,y+i,z+i,x+i,y+0,z+i);
+    draw3Dline(x+i,y+i,z+i,x+0,y+i,z+i);
+}
+
+void draw_screen(Display *dpy,Window w,GC gc) {
+  int i,j,k;
+  int cn=0;//camera number.
+  char **files;
+  static int offset=0;
+  XFontStruct *font=XLoadQueryFont(dpy,"fixed");
+  XCharStruct overall;
+  int direction,ascent,descent;
+  char coords[256];
+  int x,y,z,x1,y1,x2,y2;
+  XEvent e;
+  XClearWindow(dpy, w);
+
+  //struct triangle **triangle;
+  //for(i=0;global.triangle[i];i++);
+  //triangle=malloc(sizeof(struct triangle *) * i);
+  //for(i=0;global.triangle[i];i++) {
+  // triangle[i]=malloc(sizeof(struct triangle));
+  // memcpy(triangle[i],global.triangle[i],sizeof(triangle));
+  //}
+  //triangle[i]=0;
+
+    XDrawLine(dpy,w,gc,global.xoff,global.height/2,global.xoff+WIDTH,global.height/2);
+    snprintf(coords,sizeof(coords)-1,"x: %d y: %d",global.mousex,global.mousey);
+    XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
+    XDrawString(dpy,w,gc,global.xoff,0+ascent,coords,strlen(coords));
+    snprintf(coords,sizeof(coords)-1,"cx: %d cy: %d cz: %d",camera.x,camera.y,camera.z);
+    XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
+    XDrawString(dpy,w,gc,global.xoff,(descent+0+ascent)*2,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(dpy,w,gc,global.xoff,(descent+0+ascent)*3,coords,strlen(coords));
+
+  j=0;
+  for(i=camera.yr;i<camera.yr+270;i+=10) {
+    XDrawLine(dpy,w,gc,rotateXabout(75-j,0,75-j,100,0,100,i),rotateZabout(75,0,75,100,0,100,i),100,100);
+    j++;
+  }
+
+  XFlush(dpy);
+}
+
+int load_file(FILE *fp) {
+ struct triangle *to;
+ struct triangle t;
+ char *command;
+ static int i=0;//used to store the last triangle.
+
+ for(;global.triangle[i];i++) ;//hop to the end.
+
+ fcntl(fileno(fp),F_SETFL,O_NONBLOCK);
+
+ for(;;i++) {
+  if(feof(fp))  {
+   //printf("resetting EOF\n");
+   clearerr(fp);
+  }
+  if(fscanf(fp,"%ms %ms %d %d %d %d %d %d %d %d %d",&(t.id),&command,&(t.x1),&(t.y1),&(t.z1),&(t.x2),&(t.y2),&(t.z2),&(t.x3),&(t.y3),&(t.z3)) > 0) {
+   /*if(!strcmp(command,"addsquare")) { } */
+   if(!strcmp(command,"addtriangle")) {
+    global.triangle[i]=malloc(sizeof(struct triangle));
+    to=global.triangle[i];
+    memcpy(to,&t,sizeof(t));
+   }
+   if(!strcmp(command,"move")) {
+    for(i=0;global.triangle[i];i++) {
+     if(!strcmp(global.triangle[i]->id,t.id)) {
+      global.triangle[i]->x1+=t.x1;
+      global.triangle[i]->y1+=t.y1;
+      global.triangle[i]->z1+=t.z1;
+
+      global.triangle[i]->x2+=t.x1;
+      global.triangle[i]->y2+=t.y1;
+      global.triangle[i]->z2+=t.z1;
+
+      global.triangle[i]->x3+=t.x1;
+      global.triangle[i]->y3+=t.y1;
+      global.triangle[i]->z3+=t.z1;
+     }
+    }
+   }
+   global.triangle[i+1]=0;
+   draw_screen(global.dpy,global.w,global.gc);
+  } else {
+   global.triangle[i]=0;
+   break;
+  }
+ }
+}
+
+int export_file(FILE *fp) {
+ struct triangle *to;
+ int i;
+ for(i=0;global.triangle[i];i++) {
+  to=global.triangle[i];
+  printf("%s addtriangle %d %d %d %d %d %d %d %d %d\n",to->id,to->x1,to->y1,to->z1,to->x2,to->y2,to->z2,to->x3,to->y3,to->z3);
+ }
+}
+
+
+int main(int argc,char *argv[]) {
+  char redraw=0;
+  if(argc < 2) {
+   fprintf(stderr,"usage: hackvr yourname < from_others > to_others\n");
+   return 1;
+  } else {
+   global.user=strdup(argv[1]);
+  }
+  setbuf(stdin,0);
+  setbuf(stdout,0);
+  Display *dpy = XOpenDisplay(0);
+  assert(dpy);
+  global.dpy=dpy;
+  unsigned int mask;
+  int i;
+  XEvent e;
+  XSetWindowAttributes attributes;
+  int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+  int whiteColor = //WhitePixel(dpy, DefaultScreen(dpy));
+  attributes.background_pixel=blackColor;
+  Window w = XCreateWindow(dpy,DefaultRootWindow(dpy),0,0,WIDTH*SPLIT_SCREEN,HEIGHT,1,DefaultDepth(dpy,DefaultScreen(dpy)),InputOutput,DefaultVisual(dpy,DefaultScreen(dpy))\
+                           ,CWBackPixel, &attributes);
+  global.w=w;
+  global.triangle[0]=0;//we'll allocate as we need more.
+  Window root,child;
+  XSelectInput(dpy, w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|ResizeRedirectMask|KeyPressMask);
+  XMapWindow(dpy, w);
+  XStoreName(dpy,w,"hackvr");
+  GC gc = XCreateGC(dpy, w, 0, 0);
+  global.gc=gc;
+  global.color_map=DefaultColormap(dpy, DefaultScreen(dpy));
+  XAllocNamedColor(dpy, global.color_map, "green", &global.green, &global.green);
+  XSetForeground(dpy, gc, global.green.pixel);
+//  XSetForeground(dpy, gc, whiteColor);
+  for(;;) {
+    load_file(stdin);
+    XNextEvent(dpy, &e);
+    redraw=1;
+    switch(e.type) {
+      case MotionNotify:
+        XQueryPointer(dpy,w,&root,&child,&global.rmousex,&global.rmousey,&global.mousex,&global.mousey,&mask);
+        break;
+      case ButtonPress:
+        global.buttonpressed=e.xbutton.button;
+        break;
+      case ButtonRelease:
+        global.buttonpressed=0;
+        break;
+      case ResizeRequest:
+        XGetGeometry(dpy,w,&root,&global.x,&global.y,&global.width,&global.height,&global.border_width,&global.depth);
+      case KeyPress:
+        switch(XLookupKeysym(&e.xkey,0)) {
+          case XK_Up:
+           //fix these to use calculated values down there.
+           //printf("%s move 0 0 1 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr));
+           camera.x+=5*sinl(d2r(camera.yr)); break;
+          case XK_Down:
+           //printf("%s move 0 0 -1 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+180));
+           camera.x+=5*sinl(d2r(camera.yr+180)); break;
+          case XK_Left:
+           //printf("%s move 1 0 0 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+90));
+           camera.x+=5*sinl(d2r(camera.yr+90)); break;
+          case XK_Right:
+           //printf("%s move -1 0 0 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+270));
+           camera.x+=5*sinl(d2r(camera.yr+270)); break;
+          case XK_w:
+           //printf("%s move 0 1 0 0 0 0 0 0 0\n",global.user);
+           camera.y+=5; break;
+          case XK_s:
+           //printf("%s move 0 -1 0 0 0 0 0 0 0\n",global.user);
+           camera.y-=5; break;
+          case XK_q:
+           camera.yr+=5; break;
+          case XK_e:
+           camera.yr-=5; break;
+          case XK_Escape: return 0;
+          default:
+           redraw=0;
+           break;
+        }
+      default:
+        redraw=0;
+        break;
+    }
+    //if(redraw)
+    draw_screen(dpy,w,gc);
+  }
+  return 0;
+}
diff --git a/tests/splitter.c b/tests/splitter.c
new file mode 100644
index 0000000000000000000000000000000000000000..25292f621b21e0279eb4674585c7f8bd24c34244
--- /dev/null
+++ b/tests/splitter.c
@@ -0,0 +1,53 @@
+char **line_splitter(char *line,int *rlen) {
+ char **a;
+ int i=0,j=0;
+ int len;
+ len=1;
+ for(i=0;line[i] && line[i] == ' ';i++);//skip leading space
+ for(;line[i];) {
+  for(;line[i] && line[i] != ' ';i++);//skip rest of data
+  for(;line[i] && line[i] == ' ';i++);//skip rest of space
+  len++;
+ }
+ 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]) {
+   line[i]=0;
+   i++;
+  } else {
+   //we're at the end! I guess return this shit.
+   len++;
+   a[len]=0;
+   *rlen=len;
+   return a;
+  }
+  for(;line[i] && line[i] == ' ';i++);//skip rest of space
+  if(line[i]) {
+   len++;
+   a[len]=line+i;
+  } else {
+   len++;
+   a[len]=0;
+   *rlen=len;
+   return a;
+  }
+ }
+ *rlen=len;
+ return a;
+}
+
+int main(int argc,char *argv[]) {
+ char **a;
+ int len;
+ int i;
+ a=line_splitter(strdup(argv[1]),&len);
+ for(i=0;i<len;i++) {
+  printf("a[%d]=\"%s\"\n",i,a[i]);
+ }
+ return 0;
+}
diff --git a/tests/test b/tests/test
new file mode 100755
index 0000000000000000000000000000000000000000..fa10061d21e7bdbaeb1122f1c9f18073736d02cf
Binary files /dev/null and b/tests/test differ
diff --git a/tests/test.c b/tests/test.c
new file mode 100644
index 0000000000000000000000000000000000000000..4817a5b8db02f05a5deb5db71e9482ad629a3351
--- /dev/null
+++ b/tests/test.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+
+typedef double long c3_t;
+typedef double long c2_t;
+typedef struct {
+  int x;
+  int y;
+} cs_t;
+
+cs_t derp() {
+  return (cs_t){2,3};
+}
+
+int main(int argc,char *argv[]) {
+ cs_t cs=derp();
+ printf("%d,%d\n",cs.x,cs.y);
+ switch(1) {
+   case 1:
+    printf("first\n");
+    break;
+   default:
+    printf("third.\n");
+    break;
+ }
+ return 0;
+}
diff --git a/tests/triangle b/tests/triangle
new file mode 100755
index 0000000000000000000000000000000000000000..beb83caae21c121eb2b7fc5c997add4798029d60
Binary files /dev/null and b/tests/triangle differ
diff --git a/tests/triangle.c b/tests/triangle.c
new file mode 100644
index 0000000000000000000000000000000000000000..e503cceed3e37adc1de81ee2fe9c42cfad66fcaf
--- /dev/null
+++ b/tests/triangle.c
@@ -0,0 +1,460 @@
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#define __USE_GNU //for longer math constants
+#include <math.h>
+
+//#define DEBUG
+
+#define SPLIT_SCREEN 2
+#define CAMERA_SEPARATION 3
+
+#define DEPTH_FACTOR 0.965
+
+#define TRIANGLES 256
+
+#define min(a,b) (((a)<(b))?(a):(b))
+#define max(a,b) (((a)>(b))?(a):(b))
+
+//for one camera, not the whole thing.
+//3 camera
+//#define WIDTH 320
+//#define HEIGHT 240
+//1 camera
+//#define WIDTH 800
+//#define HEIGHT 600
+//2 camera
+#define WIDTH 400
+#define HEIGHT 300
+
+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 {
+  int x;
+  int y;
+  int z;
+  int xr;//rotations
+  int yr;
+  int zr;
+} camera;
+
+struct triangle {//use array or linked list?
+  char *id;
+  int x1;
+  int y1;
+  int z1;
+  int x2;
+  int y2;
+  int z2;
+  int x3;
+  int y3;
+  int z3;
+//  int dist;//most recent distance calculated from the camera
+};
+
+struct mainwin {
+  int x;
+  int y;
+  int depth;
+  int mousex;
+  int mousey;
+  int rmousex;
+  int rmousey;
+  int buttonpressed;
+  int width;
+  int height;
+  int border_width;
+  int xoff;
+  int math_error;
+  char *user;
+  XColor green;
+  Colormap color_map;
+  Display *dpy;
+  Window w;
+  GC gc;
+  struct triangle *triangle[TRIANGLES];
+} global;
+
+
+float zmagic(int z) {
+ float tmp=pow(DEPTH_FACTOR,(camera.z-z));
+// float tmp=pow(DEPTH_FACTOR,(camera.z-z))/(camera.z-z);
+// float tmp=pow(DEPTH_FACTOR,(camera.z-z)*(camera.z-z)*(camera.z-z));
+ //measure the distance form the camera and error out if it is too far away.
+// if((camera.z - z) >= 0) return(global.math_error=1);
+ //return (float)1 / (float)(camera.z - z);
+ return tmp;
+}
+
+int to2D(int cw,int w,int z,int d) {
+  return (d/2) - (((w-cw) / zmagic(z)) * 16 );
+}
+
+
+float distance(int x1,int y1,int x2,int y2) {
+ return sqrt(((x2-x1)*(x2-x1))+((y2-y1)*(y2-y1)));
+}
+
+long double d2r(int d) {
+ while(d<0) d+=360;
+ return (long double)(d%360) / 180.0l * M_PIl;
+}
+
+int rotateXabout(int x1,int y1,int z1,int x2,int y2,int z2,int degrees) {
+ long double radians=(long double)degrees / (long double)180 * M_PIl;//M_PIl for long double
+ long double radius=distance(x1,z1,x2,z2);
+ if(radius == 0) return x2;
+ return x2 + radius * cosl(acosl(((long double)x2-(long double)x1)/radius)+radians);
+}
+
+int rotateZabout(int x1,int y1,int z1,int x2,int y2,int z2,int degrees) {
+ long double radians=(long double)degrees / (long double)180 * M_PIl;//M_PIl for long double
+ long double radius=distance(x1,z1,x2,z2);
+ if(radius == 0) return z2;
+ return z2 + radius * sinl(asinl(((long double)z2-(long double)z1)/radius)+radians);
+}
+
+
+int to2Dx(int x,int y,int z) {
+  int newx=rotateXabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newy=y;//rotateYabout(x,y,z,camera.x,camera.y,camera.z,camera.xr);
+  int newz=rotateZabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  return to2D(camera.x,newx,newz,global.width/SPLIT_SCREEN);
+//  return to2D(camera.x,x,z,global.width/SPLIT_SCREEN);
+}
+
+int to2Dy(int x,int y,int z) {
+  int newx=rotateXabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newy=y;//rotateYabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  int newz=rotateZabout(x,y,z,camera.x,camera.y,camera.z,camera.yr);
+  return to2D(camera.y,newy,newz,global.height);
+//  return to2D(camera.y,y,z,global.height);
+}
+
+void XDrawTriangle(int x1,int y1,int x2,int y2,int x3,int y3) {
+ int x;
+ XDrawLine(global.dpy,global.w,global.gc,x1,y1,x2,y2);
+ XDrawLine(global.dpy,global.w,global.gc,x2,y2,x3,y3);
+ XDrawLine(global.dpy,global.w,global.gc,x3,y3,x1,y1);
+}
+
+void XDrawFilledTriangle(int x1,int y1,int x2,int y2,int x3,int y3,int density) {
+ int x,y;
+ int b;
+ float m;
+
+ XDrawLine(global.dpy,global.w,global.gc,x1,y1,x2,y2);
+ XDrawLine(global.dpy,global.w,global.gc,x2,y2,x3,y3);
+ XDrawLine(global.dpy,global.w,global.gc,x3,y3,x1,y1);
+
+ m=(float)(y1-y2)/(float)(x1-x2);
+ b=y1-(m*x1);
+ for(x=min(x1,x2);x<max(x1,x2);x+=4) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x3,y3,x,y);
+ }
+
+ m=(float)(y2-y3)/(float)(x2-x3);
+ b=y2-(m*x2);
+ for(x=min(x2,x3);x<max(x2,x3);x+=4) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x1,y1,x,y);
+ }
+
+ m=(float)(y3-y1)/(float)(x3-x1);
+ b=y3-(m*x3);
+ for(x=min(x3,x1);x<max(x3,x1);x+=4) {
+  y=m*x+b;
+  XDrawLine(global.dpy,global.w,global.gc,x2,y2,x,y);
+ }
+}
+
+void draw3Dtriangle(int x1,int y1,int z1,int x2,int y2,int z2,int x3,int y3,int z3) {
+  char coords[256];
+  global.math_error=0;
+  int tx1=to2Dx(x1,y1,z1);
+  int ty1=to2Dy(x1,y1,z1);
+  //draw string...
+  int tx2=to2Dx(x2,y2,z2);
+  int ty2=to2Dy(x2,y2,z2);
+  int tx3=to2Dx(x3,y3,z3);
+  int ty3=to2Dy(x3,y3,z3);
+  if(!global.math_error) {
+#ifdef DEBUG
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x1,y1,z1);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx1,ty1,coords,strlen(coords));
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x2,y2,z2);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx2,ty2,coords,strlen(coords));
+     snprintf(coords,sizeof(coords)-1,"(%d,%d,%d)",x3,y3,z3);
+     XDrawString(global.dpy,global.w,global.gc,global.xoff+tx3,ty3,coords,strlen(coords));
+#endif
+    XDrawTriangle(global.xoff+tx1,ty1,global.xoff+tx2,ty2,global.xoff+tx3,ty3);
+//    XDrawFilledTriangle(global.xoff+tx1,ty1,global.xoff+tx2,ty2,global.xoff+tx3,ty3);
+  }
+}
+
+void draw3Dline(int x1,int y1,int z1,int x2,int y2,int z2) {
+  global.math_error=0;
+  int tx1=to2Dx(x1,y1,z1);
+  int ty1=to2Dy(x1,y1,z1);
+  int tx2=to2Dx(x2,y2,z2);
+  int ty2=to2Dy(x2,y2,z2);
+  if(!global.math_error) {
+    XDrawLine(global.dpy,global.w,global.gc,global.xoff+tx1,ty1,global.xoff+tx2,ty2);
+  }
+  global.math_error=0;
+}
+
+
+//is basing this all on triangles best, or should I use polygons?
+//void pushTriangle(x1,y1,z1,1) {
+//  for(i=0;global.triangle[i];i++);
+//  global.triangle[i]=malloc(sizeof(struct triangle));
+//  global.triangle[i]->x1=x1;
+//}
+//void pushSquare() {
+//  pushTriangle();
+//  pushTriangle();
+//}
+
+void drawCube(int x,int y,int z,int i) {
+//this is just drawing the cube.
+    draw3Dline(x,y,z,x,y,z+i);
+    draw3Dline(x,y,z,x,y+i,z);
+    draw3Dline(x,y,z,x+i,y,z);
+
+    draw3Dline(x+i,y+i,z+0,x+i,y+0,z+0);
+    draw3Dline(x+i,y+i,z+0,x+0,y+i,z+0);
+
+    draw3Dline(x+0,y+i,z+i,x+0,y+i,z+0);
+    draw3Dline(x+0,y+i,z+i,x+0,y+0,z+i);
+
+    draw3Dline(x+i,y+0,z+i,x+i,y+0,z+0);
+    draw3Dline(x+i,y+0,z+i,x+0,y+0,z+i);
+
+    draw3Dline(x+i,y+i,z+i,x+i,y+i,z+0);
+    draw3Dline(x+i,y+i,z+i,x+i,y+0,z+i);
+    draw3Dline(x+i,y+i,z+i,x+0,y+i,z+i);
+}
+
+void draw_screen(Display *dpy,Window w,GC gc) {
+  int i,j,k;
+  int cn=0;//camera number.
+  char **files;
+  static int offset=0;
+  XFontStruct *font=XLoadQueryFont(dpy,"fixed");
+  XCharStruct overall;
+  int direction,ascent,descent;
+  char coords[256];
+  int x,y,z,x1,y1,x2,y2;
+  XEvent e;
+  XClearWindow(dpy, w);
+
+  //struct triangle **triangle;
+  //for(i=0;global.triangle[i];i++);
+  //triangle=malloc(sizeof(struct triangle *) * i);
+  //for(i=0;global.triangle[i];i++) {
+  // triangle[i]=malloc(sizeof(struct triangle));
+  // memcpy(triangle[i],global.triangle[i],sizeof(triangle));
+  //}
+  //triangle[i]=0;
+
+    XDrawLine(dpy,w,gc,global.xoff,global.height/2,global.xoff+WIDTH,global.height/2);
+    snprintf(coords,sizeof(coords)-1,"x: %d y: %d",global.mousex,global.mousey);
+    XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
+    XDrawString(dpy,w,gc,global.xoff,0+ascent,coords,strlen(coords));
+    snprintf(coords,sizeof(coords)-1,"cx: %d cy: %d cz: %d",camera.x,camera.y,camera.z);
+    XTextExtents(font,coords,strlen(coords),&direction,&ascent,&descent,&overall);
+    XDrawString(dpy,w,gc,global.xoff,(descent+0+ascent)*2,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(dpy,w,gc,global.xoff,(descent+0+ascent)*3,coords,strlen(coords));
+
+  j=0;
+/*
+  for(i=camera.yr;i<camera.yr+270;i+=10) {
+    XDrawLine(dpy,w,gc,rotateXabout(75-j,0,75-j,100,0,100,i),rotateZabout(75,0,75,100,0,100,i),100,100);
+    j++;
+  }
+*/
+  XDrawFilledTriangle(10,10,300,60,60,300,1);
+  XFlush(dpy);
+}
+
+int load_file(FILE *fp) {
+ struct triangle *to;
+ struct triangle t;
+ char *command;
+ static int i=0;//used to store the last triangle.
+
+ for(;global.triangle[i];i++) ;//hop to the end.
+
+ fcntl(fileno(fp),F_SETFL,O_NONBLOCK);
+
+ for(;;i++) {
+  if(feof(fp))  {
+   //printf("resetting EOF\n");
+   clearerr(fp);
+  }
+  if(fscanf(fp,"%ms %ms %d %d %d %d %d %d %d %d %d",&(t.id),&command,&(t.x1),&(t.y1),&(t.z1),&(t.x2),&(t.y2),&(t.z2),&(t.x3),&(t.y3),&(t.z3)) > 0) {
+   /*if(!strcmp(command,"addsquare")) { } */
+   if(!strcmp(command,"addtriangle")) {
+    global.triangle[i]=malloc(sizeof(struct triangle));
+    to=global.triangle[i];
+    memcpy(to,&t,sizeof(t));
+   }
+   if(!strcmp(command,"move")) {
+    for(i=0;global.triangle[i];i++) {
+     if(!strcmp(global.triangle[i]->id,t.id)) {
+      global.triangle[i]->x1+=t.x1;
+      global.triangle[i]->y1+=t.y1;
+      global.triangle[i]->z1+=t.z1;
+
+      global.triangle[i]->x2+=t.x1;
+      global.triangle[i]->y2+=t.y1;
+      global.triangle[i]->z2+=t.z1;
+
+      global.triangle[i]->x3+=t.x1;
+      global.triangle[i]->y3+=t.y1;
+      global.triangle[i]->z3+=t.z1;
+     }
+    }
+   }
+   global.triangle[i+1]=0;
+   draw_screen(global.dpy,global.w,global.gc);
+  } else {
+   global.triangle[i]=0;
+   break;
+  }
+ }
+}
+
+int export_file(FILE *fp) {
+ struct triangle *to;
+ int i;
+ for(i=0;global.triangle[i];i++) {
+  to=global.triangle[i];
+  printf("%s addtriangle %d %d %d %d %d %d %d %d %d\n",to->id,to->x1,to->y1,to->z1,to->x2,to->y2,to->z2,to->x3,to->y3,to->z3);
+ }
+}
+
+
+int main(int argc,char *argv[]) {
+  char redraw=0;
+  if(argc < 2) {
+   fprintf(stderr,"usage: hackvr yourname < from_others > to_others\n");
+   return 1;
+  } else {
+   global.user=strdup(argv[1]);
+  }
+  setbuf(stdin,0);
+  setbuf(stdout,0);
+  Display *dpy = XOpenDisplay(0);
+  assert(dpy);
+  global.dpy=dpy;
+  unsigned int mask;
+  int i;
+  XEvent e;
+  XSetWindowAttributes attributes;
+  int blackColor = BlackPixel(dpy, DefaultScreen(dpy));
+  int whiteColor = //WhitePixel(dpy, DefaultScreen(dpy));
+  attributes.background_pixel=blackColor;
+  Window w = XCreateWindow(dpy,DefaultRootWindow(dpy),0,0,WIDTH*SPLIT_SCREEN,HEIGHT,1,DefaultDepth(dpy,DefaultScreen(dpy)),InputOutput,DefaultVisual(dpy,DefaultScreen(dpy))\
+                           ,CWBackPixel, &attributes);
+  global.w=w;
+  global.triangle[0]=0;//we'll allocate as we need more.
+  Window root,child;
+  XSelectInput(dpy, w, PointerMotionMask|StructureNotifyMask|ButtonPressMask|ButtonReleaseMask|ResizeRedirectMask|KeyPressMask);
+  XMapWindow(dpy, w);
+  XStoreName(dpy,w,"hackvr");
+  GC gc = XCreateGC(dpy, w, 0, 0);
+  global.gc=gc;
+  global.color_map=DefaultColormap(dpy, DefaultScreen(dpy));
+  XAllocNamedColor(dpy, global.color_map, "green", &global.green, &global.green);
+  XSetForeground(dpy, gc, global.green.pixel);
+//  XSetForeground(dpy, gc, whiteColor);
+  for(;;) {
+    load_file(stdin);
+    XNextEvent(dpy, &e);
+    redraw=1;
+    switch(e.type) {
+      case MotionNotify:
+        XQueryPointer(dpy,w,&root,&child,&global.rmousex,&global.rmousey,&global.mousex,&global.mousey,&mask);
+        break;
+      case ButtonPress:
+        global.buttonpressed=e.xbutton.button;
+        break;
+      case ButtonRelease:
+        global.buttonpressed=0;
+        break;
+      case ResizeRequest:
+        XGetGeometry(dpy,w,&root,&global.x,&global.y,&global.width,&global.height,&global.border_width,&global.depth);
+      case KeyPress:
+        switch(XLookupKeysym(&e.xkey,0)) {
+          case XK_Up:
+           //fix these to use calculated values down there.
+           //printf("%s move 0 0 1 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr));
+           camera.x+=5*sinl(d2r(camera.yr)); break;
+          case XK_Down:
+           //printf("%s move 0 0 -1 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+180));
+           camera.x+=5*sinl(d2r(camera.yr+180)); break;
+          case XK_Left:
+           //printf("%s move 1 0 0 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+90));
+           camera.x+=5*sinl(d2r(camera.yr+90)); break;
+          case XK_Right:
+           //printf("%s move -1 0 0 0 0 0 0 0 0\n",global.user);
+           camera.z+=5*cosl(d2r(camera.yr+270));
+           camera.x+=5*sinl(d2r(camera.yr+270)); break;
+          case XK_w:
+           //printf("%s move 0 1 0 0 0 0 0 0 0\n",global.user);
+           camera.y+=5; break;
+          case XK_s:
+           //printf("%s move 0 -1 0 0 0 0 0 0 0\n",global.user);
+           camera.y-=5; break;
+          case XK_q:
+           camera.yr+=5; break;
+          case XK_e:
+           camera.yr-=5; break;
+          case XK_Escape: return 0;
+          default:
+           redraw=0;
+           break;
+        }
+      default:
+        redraw=0;
+        break;
+    }
+    //if(redraw)
+    draw_screen(dpy,w,gc);
+  }
+  return 0;
+}
diff --git a/tests/ungets.c b/tests/ungets.c
new file mode 100644
index 0000000000000000000000000000000000000000..73741004aaa9db3147f95956197d049fd109bfce
--- /dev/null
+++ b/tests/ungets.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main() {
+ ungetc('a',stdin);
+ ungetc('b',stdin);
+ printf("%c",fgetc(stdin));
+ printf("%c",fgetc(stdin));
+ printf("\n");
+}
diff --git a/tools/dat2hackvr.pl b/tools/dat2hackvr.pl
new file mode 100755
index 0000000000000000000000000000000000000000..2a2fbe153fd575e3367cd70c96e87f47246e6fda
--- /dev/null
+++ b/tools/dat2hackvr.pl
@@ -0,0 +1,34 @@
+#!/usr/bin/perl
+
+use strict;
+
+die "usage: dat2hackvr.pl name file\n" unless $ARGV[0];
+
+my $line;
+my $prev;
+my $first;
+open(FILE,$ARGV[1]) if $ARGV[1];
+while($line=<FILE>) {
+ chomp $line;
+ if(!($line =~ m/^#/)) {
+  if($line eq "") {
+#   print $ARGV[0];
+#   print " addtriangle ";
+#   print $prev . " 0 " . $first . " 0 " . $first . " 0";
+#   print "\n";
+   $first="";
+  } else {
+   if($prev ne "") {
+    print $ARGV[0];
+    print " addshape 2 ";
+    print $line . " 0 " . $prev . " 0";
+    print "\n";
+   }
+   $prev="";
+  }
+  if($first eq "") {
+   $first=$line;
+  }
+  $prev=$line;
+ }
+}
diff --git a/tools/obj2hackvr.pl b/tools/obj2hackvr.pl

index 793b5eaea8c76e3c593efa05c0bbd0fa9d8bf8a3..

index ..d8727e21397f82697f876321c8607d13dbd1efd5 100755

--- a/tools/obj2hackvr.pl
+++ b/tools/obj2hackvr.pl
@@ -32,13 +32,28 @@ while(<FILE>) {
 # }
 #}

+#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+0);$i++) {
+#  print " ";
+#  print $vertices[$points[$i]];
+# }
+# print "\n";
+#}
+
+#convert to triangles
 foreach $tmp (@faces) {
  @points=split(/ /,$tmp);
  @points = map { $_ =~ s/\/.+$//g; $_; } @points;
 # print @points;
  for($i=2;$i<(@points);$i++) {
   print $ARGV[0];
-  print " addtriangle ";
+  print " addshape 3 ";
   print $vertices[$points[0]-1];
   print " ";
   print $vertices[$points[$i-1]-1];
diff --git a/traceroute_hackvr.sh b/traceroute_hackvr.sh
new file mode 100755
index 0000000000000000000000000000000000000000..cdf9c698b600f8191eba2fc5389689f0fb58e328
--- /dev/null
+++ b/traceroute_hackvr.sh
@@ -0,0 +1,2 @@
+#!/bin/bash
+cat <(./tools/dat2hackvr.pl world world/world_110m.txt) ./world_camera <(./traceroute_to_dat.sh $1 | cut '-d ' -f2- | awk '{print $2,$1}' | tail -n+2 | ./tools/dat2hackvr.pl route /dev/stdin) /dev/stdin | ./hackvr epoch
diff --git a/traceroute_to_dat.sh b/traceroute_to_dat.sh
new file mode 100755
index 0000000000000000000000000000000000000000..5b088844d6f15e50166b6fa2b6676c47a26e70dc
--- /dev/null
+++ b/traceroute_to_dat.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+traceroute -n $1 | tail -n+2 | sed 's/^ *//g' | cut '-d ' -f3 | whob | egrep '^IP|^Lat|^Long' | cut '-d ' -f2- | paste - - - | tr '\t' ' '
diff --git a/traceroute_to_triangles.sh b/traceroute_to_triangles.sh
new file mode 100755
index 0000000000000000000000000000000000000000..4f1a1c7a88494823b73283fcc42c0200d68d9a5a
--- /dev/null
+++ b/traceroute_to_triangles.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+traceroute -n $1 | tail -n+2 | cut '-d ' -f4 | ./IPs_to_triangle.sh
diff --git a/world_camera b/world_camera
new file mode 100644
index 0000000000000000000000000000000000000000..074688a356c59ad650d47089b488685787eef65c
--- /dev/null
+++ b/world_camera
@@ -0,0 +1,7 @@
+epoch set camera.p.x -0.000000
+epoch set camera.p.y 5.000000
+epoch set camera.p.z -12.000000
+epoch set camera.xr 270
+epoch set camera.yr 270
+epoch set camera.zr 0
+epoch set camera.zoom 2.000000

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

-- Response ended

-- Page fetched on Sun Jun 2 16:28:45 2024