|  | @@ -150,7 +150,7 @@ const char *repr(const char *data) {
 | 
	
		
			
				|  |  |    return buffer;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -#define CHUNKSIZE 32
 | 
	
		
			
				|  |  | +#define CHUNKSIZE 40
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  void zf_repr_chunk(int LOG_LEVEL, const char *chunk) {
 | 
	
		
			
				|  |  |    const char *output = repr(chunk);
 | 
	
	
		
			
				|  | @@ -760,6 +760,45 @@ int send_file(int fd, char *filename) {
 | 
	
		
			
				|  |  |    return 1;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +void send_goto(int fd, int x, int y) {
 | 
	
		
			
				|  |  | +  char gbuffer[16];
 | 
	
		
			
				|  |  | +  char * cp;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  sprintf(gbuffer, "\x1b[%d;%dH", y, x);
 | 
	
		
			
				|  |  | +  write(fd, gbuffer, strlen(gbuffer));
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +int send_file(int fd, int x, int y, char *filename) {
 | 
	
		
			
				|  |  | +  FILE *fp;
 | 
	
		
			
				|  |  | +  char buffer[100];
 | 
	
		
			
				|  |  | +  int read;
 | 
	
		
			
				|  |  | +  int pos;
 | 
	
		
			
				|  |  | +  fp = fopen(filename, "rb");
 | 
	
		
			
				|  |  | +  if (fp == NULL) {
 | 
	
		
			
				|  |  | +    ZF_LOGD("Failed to open %s", filename);
 | 
	
		
			
				|  |  | +    return 0;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  send_goto(fd, x,y);
 | 
	
		
			
				|  |  | +  y++;
 | 
	
		
			
				|  |  | +  char *cp, * last_cp;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  while ((read = fread(buffer, 1, sizeof(buffer), fp)) > 0) {
 | 
	
		
			
				|  |  | +    buffer[read] = 0;
 | 
	
		
			
				|  |  | +    last_cp = buffer;
 | 
	
		
			
				|  |  | +    while ( ( cp = strchr(last_cp, '\n')) != NULL) {
 | 
	
		
			
				|  |  | +      *cp = 0;
 | 
	
		
			
				|  |  | +      write(fd, last_cp, strlen(last_cp)); 
 | 
	
		
			
				|  |  | +      send_goto(fd, x,y);
 | 
	
		
			
				|  |  | +      y++;
 | 
	
		
			
				|  |  | +      last_cp = cp + 1;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    write(fd, last_cp, strlen(last_cp));
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  | +  fclose(fp);
 | 
	
		
			
				|  |  | +  return 1;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /**
 | 
	
		
			
				|  |  |   * process_trigger( fd, *cp )
 | 
	
		
			
				|  |  |   *
 | 
	
	
		
			
				|  | @@ -772,7 +811,7 @@ int send_file(int fd, char *filename) {
 | 
	
		
			
				|  |  |  const char *process_trigger(int fd, const char *cp) {
 | 
	
		
			
				|  |  |    char ch;
 | 
	
		
			
				|  |  |    int i, x, y;
 | 
	
		
			
				|  |  | -  ch = toupper(*cp);
 | 
	
		
			
				|  |  | +  ch = *cp;
 | 
	
		
			
				|  |  |    cp++;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    switch (ch) {
 | 
	
	
		
			
				|  | @@ -817,7 +856,23 @@ const char *process_trigger(int fd, const char *cp) {
 | 
	
		
			
				|  |  |      write_color(fd, i);
 | 
	
		
			
				|  |  |    } break;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  case 'F': {
 | 
	
		
			
				|  |  | +  case 'F':
 | 
	
		
			
				|  |  | +  case 'f': {
 | 
	
		
			
				|  |  | +    int x, y, pos = 0;
 | 
	
		
			
				|  |  | +    if (ch == 'f') {
 | 
	
		
			
				|  |  | +      pos = 1;
 | 
	
		
			
				|  |  | +      x = (*cp) - '0';
 | 
	
		
			
				|  |  | +      cp++;
 | 
	
		
			
				|  |  | +      x *= 10;
 | 
	
		
			
				|  |  | +      x += (*cp) - '0';
 | 
	
		
			
				|  |  | +      cp++;
 | 
	
		
			
				|  |  | +      y = (*cp) - '0';
 | 
	
		
			
				|  |  | +      cp++;
 | 
	
		
			
				|  |  | +      y *= 10;
 | 
	
		
			
				|  |  | +      y += (*cp) - '0';
 | 
	
		
			
				|  |  | +      cp++;
 | 
	
		
			
				|  |  | +      ZF_LOGI( "file at (%d, %d)", x, y);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |      // Ok, look for filename
 | 
	
		
			
				|  |  |      char ansifile[32] = "./hh/";
 | 
	
		
			
				|  |  |      char *ap = ansifile + strlen(ansifile);
 | 
	
	
		
			
				|  | @@ -830,7 +885,11 @@ const char *process_trigger(int fd, const char *cp) {
 | 
	
		
			
				|  |  |      strcat(ansifile, ".ans");
 | 
	
		
			
				|  |  |      cp++;
 | 
	
		
			
				|  |  |      ZF_LOGD("FILE [%s]", ansifile);
 | 
	
		
			
				|  |  | -    send_file(fd, ansifile);
 | 
	
		
			
				|  |  | +    if (pos) {
 | 
	
		
			
				|  |  | +      send_file(fd, x, y, ansifile);
 | 
	
		
			
				|  |  | +    } else {
 | 
	
		
			
				|  |  | +      send_file(fd, ansifile);
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  |    } break;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    case 'G': {
 | 
	
	
		
			
				|  | @@ -966,7 +1025,7 @@ void render(int fd, const char *string_out) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    reset_render();
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -  ZF_LOGD("render(%d, %s)", fd, repr(string_out));
 | 
	
		
			
				|  |  | +  ZF_LOGV("render(%d, %s)", fd, repr(string_out));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    // Check our time from time to time.
 | 
	
		
			
				|  |  |    // If we start running long, disable sleeps.
 | 
	
	
		
			
				|  | @@ -1066,9 +1125,7 @@ void harry_idle_event(int fd) {
 | 
	
		
			
				|  |  |    */
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    sprintf(buffer, "^S2^C%02d%s^P2^CR^D%02d", color, cp, (int)strlen(cp));
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    ZF_LOGD("harry_event: render(%d, \"%s\")", fd, buffer);
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    render(fd, buffer);
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1358,7 +1415,6 @@ int mangle(int fd, char *buffer) {
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    ZF_LOGI("mangle:");
 | 
	
		
			
				|  |  |    ZF_LOGI_REPR(buffer);
 | 
	
		
			
				|  |  | -  ZF_LOGI("mangle(%s)", repr(buffer));
 | 
	
		
			
				|  |  |    // strcpy(work, buffer);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /*
 | 
	
	
		
			
				|  | @@ -1375,11 +1431,10 @@ int mangle(int fd, char *buffer) {
 | 
	
		
			
				|  |  |        display ANSI graphic file, with delays ... then CLS
 | 
	
		
			
				|  |  |     */
 | 
	
		
			
				|  |  |    const char *ANSI_CLS = "\x1b[2J";
 | 
	
		
			
				|  |  | -  static int ANSI_CLS_count = 0; // count the number we've seen
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |    cp = strstr(buffer, ANSI_CLS);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    if (cp != NULL) {
 | 
	
		
			
				|  |  | +    static int ANSI_CLS_count = 0; // count the number we've seen
 | 
	
		
			
				|  |  |      ZF_LOGI("seen: ANSI_CLS");
 | 
	
		
			
				|  |  |      ANSI_CLS_count++;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1398,23 +1453,20 @@ int mangle(int fd, char *buffer) {
 | 
	
		
			
				|  |  |        if (random_activate(3)) {
 | 
	
		
			
				|  |  |          char display[100] = "";
 | 
	
		
			
				|  |  |          int needs_cls = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          struct file_need {
 | 
	
		
			
				|  |  |            const char *filename;
 | 
	
		
			
				|  |  |            int cls;
 | 
	
		
			
				|  |  | -        } possibles[] = {
 | 
	
		
			
				|  |  | -            {"goofy_head", 1},
 | 
	
		
			
				|  |  | -            {
 | 
	
		
			
				|  |  | -                "bat",
 | 
	
		
			
				|  |  | -                1,
 | 
	
		
			
				|  |  | -            },
 | 
	
		
			
				|  |  | -            {"panther", 1},
 | 
	
		
			
				|  |  | -            {"wolf", 1}
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -            //          bat.ans       creature.ans  goofy_head.ans  panther.ans
 | 
	
		
			
				|  |  | -            //          skull.ans
 | 
	
		
			
				|  |  | -            // blinkman.ans  dog.ans       guy.ans         skull2.ans   wolf.ans
 | 
	
		
			
				|  |  | +          int rand_pos;
 | 
	
		
			
				|  |  | +        } possibles[] = {{"goofy_head", 1, 0}, {"bat", 1, 0},
 | 
	
		
			
				|  |  | +                         {"panther", 1, 0},    {"wolf", 1, 0},
 | 
	
		
			
				|  |  | +                         {"skull", 0, 1},      {"skull2", 0, 1},
 | 
	
		
			
				|  |  | +                         {"guy", 0, 1},        {"blinkman", 0, 1}};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        //          bat.ans       creature.ans  goofy_head.ans  panther.ans
 | 
	
		
			
				|  |  | +        //          skull.ans
 | 
	
		
			
				|  |  | +        // blinkman.ans  dog.ans       guy.ans         skull2.ans   wolf.ans
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  |          static LastSeen last_files(2);
 | 
	
		
			
				|  |  |          int r;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1422,6 +1474,16 @@ int mangle(int fd, char *buffer) {
 | 
	
		
			
				|  |  |            r = randint((sizeof(possibles) / sizeof(file_need)));
 | 
	
		
			
				|  |  |          } while (last_files.seen_before(r));
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +        int x, y;
 | 
	
		
			
				|  |  | +        x = randint(50) + 1;
 | 
	
		
			
				|  |  | +        y = randint(12) + 1;
 | 
	
		
			
				|  |  | +        char fgoto[10];
 | 
	
		
			
				|  |  | +        if (possibles[r].rand_pos) {
 | 
	
		
			
				|  |  | +          sprintf(fgoto, "^f%02d%02d", x, y);
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          strcpy(fgoto, "^F");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          // (2); // (sizeof(possibles) / sizeof(file_need)) - 1);
 | 
	
		
			
				|  |  |          needs_cls = possibles[r].cls;
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1433,8 +1495,8 @@ int mangle(int fd, char *buffer) {
 | 
	
		
			
				|  |  |          // I tried a ^P2 before doing this .. but I'd rather have the picture up
 | 
	
		
			
				|  |  |          // right away I think.
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        sprintf(display, "%s^F%s.^P3%s", needs_cls ? "\x1b[2J" : "\n\r\n\r",
 | 
	
		
			
				|  |  | -                possibles[r].filename, restore_color);
 | 
	
		
			
				|  |  | +        sprintf(display, "%s%s%s.^P3%s", needs_cls ? "\x1b[2J" : "",
 | 
	
		
			
				|  |  | +                fgoto, possibles[r].filename, restore_color);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |          ZF_LOGI("mangle(ANSI_CLS): %d file inserted %s", r, repr(display));
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -1507,7 +1569,6 @@ int mangle(int fd, char *buffer) {
 | 
	
		
			
				|  |  |            if (string_insert(buffer, BSIZE * 4, cp - buffer, display)) {
 | 
	
		
			
				|  |  |              ZF_LOGI("mangle(ANSI_CLS):");
 | 
	
		
			
				|  |  |              ZF_LOGI_REPR(buffer);
 | 
	
		
			
				|  |  | -            ZF_LOGI("mangle(ANSI_CLS): [%s]", repr(buffer));
 | 
	
		
			
				|  |  |              need_render = 1;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              /*
 |