Bytecode. Command length built into messages.

   1 #include <stdio.h>
   2 #include <stdlib.h>
   3 #include <stdint.h>
   4 
   5 #include <deque>
   6 
   7 bool flag = false;
   8 
   9 void fread_or_die(void * a, size_t b, int c, FILE * d)
  10 {
  11     int got = fread(a, b, c, d);
  12     if(feof(d) || ferror(d) || got != c) flag = true;
  13 }
  14 
  15 int main(int argc, char ** argv)
  16 {
  17     if(argc < 2) return puts("Need argument"), 0;
  18     for(int arg = 1; arg < argc; arg++)
  19     {
  20         auto fs = fopen(argv[arg], "rb");
  21         
  22         fseek(fs, 0x114, SEEK_SET);
  23         
  24         while(!feof(fs) and !ferror(fs) and !flag)
  25         {
  26             uint16_t command;
  27             uint8_t ints;
  28             uint8_t other;
  29             fread_or_die(&command, 2, 1, fs);
  30             fread_or_die(&ints, 1, 1, fs);
  31             fread_or_die(&other, 1, 1, fs);
  32             uint8_t strings = other & 0xF;
  33             
  34             if(flag) continue;
  35             
  36             //printf("%04X %02X %02X\n", command, ints, other);
  37             
  38             fseek(fs, 4*ints, SEEK_CUR);
  39             
  40             for(int i = 0; i < strings; i++)
  41             {
  42                 while(true)
  43                 {
  44                     char c = fgetc(fs);  
  45                     if(c == 0x0D) continue;
  46                     if(command == 0x001C and i == 1)
  47                     {
  48                         if(c=='\n'); // don't retain line wraps
  49                         else if(c!=0) putc(c, stdout);
  50                         else putc('\n', stdout); // make newlines between messages
  51                     }
  52                     if(c==0) break;
  53                 }
  54             }
  55         }
  56         
  57         fclose(fs);
  58         flag = false;
  59     }
  60 }