diff options
| -rw-r--r-- | src/hackvr.c | 281 | 
1 files changed, 142 insertions, 139 deletions
| diff --git a/src/hackvr.c b/src/hackvr.c index c272074..ff60e84 100644 --- a/src/hackvr.c +++ b/src/hackvr.c @@ -9,6 +9,7 @@  #include <time.h>  #include <math.h>  #include <errno.h> +#include <signal.h>  #include "config.h"  #include "common.h" @@ -20,6 +21,11 @@  extern struct gra_global gra_global;  #endif +#include <idc.h> +extern struct idc_global idc; + +struct hvr_global global; +  //TODO: optimizations  //TODO: store caches of cs_t, c2_t, and c3_t numbers.  //TODO: don't forget to remake gophervr with this. @@ -40,7 +46,6 @@ int lum_based_on_distance(c3_s_t *s) {    return sum * 5;  } -struct global global;  //might be able to make this faster by just using fgets() and not using recursion and malloc.  /* does not return the newline. */ @@ -69,14 +74,11 @@ char *read_line_hack(FILE *fp,int len) {   return t;  } -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); - if(global.periodic_output==0) putchar(t);//output commands immediately +int selfcommand(char *s) {//send this line to be handled by ourselves and output to stdout + if(global.localecho) { +   write(global.selfpipe[1],s,strlen(s)); + } + write(1,s,strlen(s));//stdout   return 0;  } @@ -125,58 +127,44 @@ void hvr_version() {    fprintf(stderr,"# hackvr version: %s\n",HVR_VERSION);  } -int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw, and 1 to ask for redraw -// struct c3_shape s; -// struct c3_line l; -//move UP, DOWN, LEFT, RIGHT etc shit - radians tmprady; - //radians tmpradx,tmprady,tmpradz; - real tmpx,tmpy,tmpz; +int hackvr_handler(char *line); + +void hackvr_handler_idc(struct shit *me,char *line) { +  switch(hackvr_handler(line)) { +    case -1: +      exit(0); +    case 0: +      break; +    case 1: +    #ifdef GRAPHICAL +      redraw(); +    #endif +      break; +    default: +      break; +  } +} + +//this function returns -1 to quit, 0 to not ask for a redraw, and 1 to ask for redraw +int hackvr_handler(char *line) { +  int ret=0; +  int len; +  int j,i,k,l; +  c3_group_rot_t *gr; +  real tmpx,tmpy,tmpz; +  char **a;   char tmp[256]; -//^ there +// radians tmpradx,tmprady,tmpradz; +  radians tmprady; - c3_group_rot_t *gr; - char *command; - char *line=0; - char *id; - char **a=0; - int len; - int ret=0; - int j,k,l; - int counter; - //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. >_> +  char *id; +  //might use these so make command code easier to read. +  char *command; +  //char **args; -// fprintf(stderr,"# entering load_stdin()\n"); -//#ifdef _HACKVR_USE_NONBLOCK_ - for(i=0;global.shape[i];i++) ;//hop to the end. - fcntl(0,F_SETFL,O_NONBLOCK); - if(feof(stdin))  { -  clearerr(stdin); - } -//#else -/* 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)) {*/ -//#endif - counter=0; -// printf("#right before main read loop\n"); -// fflush(stdout); - for(counter=0;counter < 100 && (line=line?free(line),read_line_hack(stdin,0):read_line_hack(stdin,0));counter++) {//load as long there's something to load -  if(*line == '#') continue; +  if(*line == '#') return 0;  //  fprintf(stderr,"# read command: %s\n",line); - if(a) free(a);//use a static char pointer array so I don't have to use the heap. possible optimization. - a=line_splitter(line,&len); +  a=line_splitter(line,&len);  //  for(i=0;i<len;i++) {  //   printf("\"%s\" ",a[i]);  //  } @@ -188,7 +176,7 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,    if(len < 2) {     if(!strcmp(id,"version")) {      hvr_version(); -    continue; +    return 0;     }     if(!strcmp(id,"help")) {  #ifdef GRAPHICAL @@ -215,10 +203,10 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,      fprintf(stderr,"# * move x y z\n");      fprintf(stderr,"# * move forward|backward|up|down|left|right\n");      fprintf(stderr,"# that is all.\n"); -    continue; +    return ret;     } else {      //fprintf(stderr,"# ur not doing it right. '%s'\n",id); -    continue; +    return ret;     }    }    ret=1; @@ -252,7 +240,7 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,       global.group_rot[k]=global.group_rot[l];       global.group_rot[l]=0;      } -    continue; +    return ret;     }    }    if(!strcmp(command,"apply")) { @@ -310,7 +298,7 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,       global.group_rot[l]=0;      }      ret=1; -    continue; +    return ret;     }    }    if(!strcmp(command,"assimilate")) {//um... what do we do with the group_rotation? @@ -323,7 +311,7 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,      }     }     ret=1; -   continue; +   return ret;    }    if(!strcmp(command,"renamegroup")) {//this command doesn't need globbing     if(len == 4) { @@ -340,11 +328,11 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,      }     }     ret=1; -   continue; +   return ret;    }    if(!strcmp(command,"status")) {     fprintf(stderr,"# loops per second: %d\n",global.lps); -   continue; +   return ret;    }    if(!strcmp(command,"dump")) {//same as debug output... and the periodic data.     printf("%s set global.camera.p.x %f\n",global.user,global.camera.p.x); @@ -354,13 +342,13 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,     printf("%s set global.camera.r.y %d\n",global.user,global.camera.r.y.d);     printf("%s set global.camera.r.z %d\n",global.user,global.camera.r.z.d);     printf("%s set global.zoom %f\n",global.user,global.zoom); -   continue; +   return ret;    }    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 != 3 && len != 4) return ret;     if(len == 4) {      if(0);  #ifdef GRAPHICAL @@ -371,35 +359,43 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,      else if(!strcmp(a[2],"camera.r.x")) global.camera.r.x.d=atoi(a[3]);      else if(!strcmp(a[2],"camera.r.y")) global.camera.r.y.d=atoi(a[3]);      else if(!strcmp(a[2],"camera.r.z")) global.camera.r.z.d=atoi(a[3]); +    else if(!strcmp(a[2],"input_mode")) gra_global.input_mode=atoi(a[3]);  #endif -    else fprintf(stderr,"# unknown variable: %s\n",a[2]); +    else { +     fprintf(stderr,"# unknown variable: %s\n",a[2]); +     fprintf(stderr,"# variables: camera.{p,r}.{x,y,z}, global.zoom, input_mode"); +    }      ret=1; -    continue; +    return ret;     }  #ifdef GRAPHICAL     if(!strcmp(a[2],"global.beep")) global.beep=1;     else 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 { fprintf(stderr,"# unknown variable: %s\n",a[2]); continue; } +   else { +    fprintf(stderr,"# unknown variable: %s\n",a[2]); +    fprintf(stderr,"# variables: global.beep, force_redraw, red_and_blue\n"); +    return ret; +   }     fprintf(stderr,"# %s toggled!\n",a[2]);     ret=1; -   continue; +   return ret;    }    if(!strcmp(command,"control")) {//change what shape key commands  affect.     if(len > 2) { -    free(global.user); +    free(global.user);//need to ensure this is on the heap      global.user=strdup(a[2]); // :D     }     ret=0;//doesn't change anything yet... -   continue; +   return ret;    }    if(!strcmp(command,"addshape")) {//need to add a grouprot with this.     if(len > 3) {      if(len != ((strtold(a[3],0)+(strtold(a[3],0)==1))*3)+4) {       fprintf(stderr,"# ERROR: wrong amount of parts for addshape. got: %d expected %d\n",len,((int)strtold(a[3],0)+(strtold(a[3],0)==1))*3+4);       fprintf(stderr,"# usage: addshape color number x y z x y z repeated number of time.\n"); -     continue; +     return ret;      }      for(i=0;global.shape[i];i++) { if(i>= MAXSHAPES) abort();}//just take me to the end.      global.shape[i]=malloc(sizeof(struct c3_shape)); @@ -435,7 +431,7 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,      }     }     ret=1; -   continue; +   return ret;    }    if(!strcmp(command,"export")) {//dump shapes and group rotation for argument (or all if arg is *)     if(len > 2) { @@ -455,7 +451,7 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,       }      }     } -   continue; +   return ret;    }  //should scaleup even be inside hackvr? seems like something an external program could do... but it wouldn't act on hackvr's state. so nevermind.    if(!strcmp(command,"scaleup")) {//should this scale separately so it can be a deform too? @@ -468,8 +464,7 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,       }      }     } -   ret=1; -   continue; +   return 1;    }    if(!strcmp(command,"rotate")) {     if(len > 4) { @@ -495,7 +490,32 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,      global.group_rot[i]->r.z.d -= (-(global.group_rot[i]->r.z.d < 0)+(global.group_rot[i]->r.z.d / 360)) * 360;     }     ret=1; -   continue; +   return ret; +  } +  if(!strcmp(command,"physics")) { +   apply_physics();//lol +  } +  if(!strcmp(command,"periodic")) { +#ifdef GRAPHICAL +//     fprintf(stderr,"# loops per second: %d mouse.x: %f mouse.y: %f\n",global.lps,gra_global.mouse.x,gra_global.mouse.y); +#else +     fprintf(stderr,"# loops per second: %d\n",global.lps); +#endif +     global.periodic_output = PERIODIC_OUTPUT; +     //output any difference between current camera's state +     //and the camera state the last time we output it. +     if(memcmp(&global.old_p,&global.camera.p,sizeof(c3_t))) { +      global.old_p.x=global.camera.p.x; +      global.old_p.z=global.camera.p.z; +      global.old_p.y=global.camera.p.y; +      printf("%s move %f %f %f\n",global.user,global.old_p.x,global.old_p.y,global.old_p.z); +     } +     if(memcmp(&global.old_r,&global.camera.r,sizeof(c3_rot_t))) { +      global.old_r.x=global.camera.r.x; +      global.old_r.y=global.camera.r.y; +      global.old_r.z=global.camera.r.z; +      printf("%s rotate %d %d %d\n",global.user,global.camera.r.x.d,global.camera.r.y.d,global.camera.r.z.d); +     }    }    if(!strcmp(command,"move")) {     if(len > 2) { @@ -540,22 +560,21 @@ int load_stdin() {//this function returns -1 to quit, 0 to not ask for a redraw,       //snprintf(tmp,sizeof(tmp)-1,"%s move +%f +0 +%f\n",global.user,tmpx,tmpz);      } else {       fprintf(stderr,"# dunno what direction you're talking about. try up, down, left, right, forward, or backward\n"); -     continue; +     return ret;      }      tmpx=WALK_SPEED*sin(tmprady.r);//the camera's y rotation. -    tmpz=WALK_SPEED*cos(tmprady.r);//these are only based on  +    tmpz=WALK_SPEED*cos(tmprady.r);//these are only based on      snprintf(tmp,sizeof(tmp)-1,"%s move +%f +%f +%f\n",global.user,tmpx,tmpy,tmpz);      selfcommand(tmp);     } else {      fprintf(stderr,"# ERROR: wrong amount of parts for move. got: %d expected: 4 or 2\n",len);     }     ret=1; -   continue; +   return ret;    }    fprintf(stderr,"# I don't know what command you're talking about. %s\n",command);    //I used to have free(line) here, but this place is never gotten to if a command is found so it wasn't getting released. - } - return ret; +  return ret;  }  int export_file(FILE *fp) {//not used yet. maybe export in obj optionally? no. that should be an external program @@ -568,12 +587,22 @@ int export_file(FILE *fp) {//not used yet. maybe export in obj optionally? no. t   return 0;  } +#ifdef GRAPHICAL +void redraw_handler(struct shit *me,char *line) { +  if(gra_global.force_redraw) { +    graphics_event_handler(1); +    gra_global.force_redraw=0; +  } +} +#endif + +void alarm_handler(int sig) { +  selfcommand("periodic"); +  alarm(10);//no... +} +  int main(int argc,char *argv[]) { -  char redraw; -  time_t oldtime; -  unsigned int lps; -  c3_t old_p; -  c3_rot_t old_r; +  int i;    if(argc == 2) {     if(!strcmp(argv[1],"-v") || !strcmp(argv[1],"--version")) {      hvr_version(); @@ -589,9 +618,10 @@ int main(int argc,char *argv[]) {    }    if(argc > 1) {     //open every argument and add it to list of files to read.. -   //I could just read  +   //I could just read    } -  global.user=getenv("USER"); +  global.user=strdup(getenv("USER"));//this gets free()d later so we need to strdup it. +  global.localecho=1;    fcntl(1,F_SETFL,O_NONBLOCK);//won't work    setbuf(stdin,0); @@ -599,57 +629,30 @@ int main(int argc,char *argv[]) {    global.debug=DEBUG;    global.periodic_output=PERIODIC_OUTPUT;    global.beep=0; + +  //libidc init +  for(i=0;i<100;i++) { +    idc.fds[i].fd=-1; +  } +  idc.shitlen=0; +  #ifdef GRAPHICAL    graphics_init(); + +  fprintf(stderr,"# x11 fd: %d",input_init()); +  i=add_fd(input_init(),input_event_handler); +  idc.fds[i].read_lines_for_us=0; + +  pipe(gra_global.redraw); +  add_fd(gra_global.redraw[0],redraw_handler);//lol. write a byte to other half of pipe to redraw screen.  #endif +  add_fd(0,hackvr_handler_idc);//looks like default mode is to exit on EOF of stdin +  pipe(global.selfpipe); +  add_fd(global.selfpipe[0],hackvr_handler_idc);//looks like default mode is to exit on EOF of stdin +  //signal(SIGALRM,alarm_handler); +  //alarm(10);    fprintf(stderr,"# entering main loop\n"); -  for(lps=0;;lps++) { -    switch(redraw=load_stdin()) {//this needs to loop over all opened files. -     case -1: -      return 0; -      break; -     case 0: -      break; -     default: -      break; -    } -    if(time(0) != oldtime) { -      global.lps=lps; -      lps=0; -      oldtime=time(0); -    } -    //fprintf(stderr,"# applying physics...\n"); -    redraw |= apply_physics(); -    //fprintf(stderr,"# derping.\n"); -    if(global.periodic_output == 1) {//this is the same type of thing the debug output does. debug output now goes here. -#ifdef GRAPHICAL -     fprintf(stderr,"# loops per second: %d mouse.x: %f mouse.y: %f\n",global.lps,gra_global.mouse.x,gra_global.mouse.y); -#else -     fprintf(stderr,"# loops per second: %d\n",global.lps); -#endif -     global.periodic_output = PERIODIC_OUTPUT; -     //output any difference between current camera's state -     //and the camera state the last time we output it. -     if(memcmp(&old_p,&global.camera.p,sizeof(c3_t))) { -      old_p.x=global.camera.p.x; -      old_p.z=global.camera.p.z; -      old_p.y=global.camera.p.y; -      printf("%s move %f %f %f\n",global.user,old_p.x,old_p.y,old_p.z); -     } -     if(memcmp(&old_r,&global.camera.r,sizeof(c3_rot_t))) { -      old_r.x=global.camera.r.x; -      old_r.y=global.camera.r.y; -      old_r.z=global.camera.r.z; -      printf("%s rotate %d %d %d\n",global.user,global.camera.r.x.d,global.camera.r.y.d,global.camera.r.z.d); -     } -    } -    global.periodic_output--; -#ifdef GRAPHICAL -    if(graphics_event_handler(redraw) == -1) break;//this thing should call draw_screen when it needs to. -    if(mouse_event_handler() == -1) break; -    if(keyboard_event_handler() == -1) break; -#endif -   sleep(.01); -  } +  select_on_everything(); +    return 0;  } | 
