VecSound Decoder in C(++) example

/*
 To work the first commented out byte (a counter) of each register must be uncommented.
 The counter to how many different bytes are used within the  "SHANNON'-coding...
*/

#include <fstream.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>

#define PHRASES MAX 100
#define MAX PHRASE LEN 100
struct phrase
{
     int phrase[MAX PHRASE LEN];
     int len;
     int count;
};
phrase phrases[PHRASES MAX];

const MAXBUFF = 2000000;
//START inclusive
#define ENCODE START 0
//END exclusive
#define ENCODE END 11

FILE *inFile;
FILE *outFile;
FILE *outFile2;
unsigned char buf[MAXBUFF];
unsigned char out buf[MAXBUFF/11+11][11];
int len;
int vbl len;
int byte pointer read = 0;
int byte pointer write = 0;

int current bit counter = -1;
int current out byte=0;


#define MAP BIT MAX 127
#define MAP CODE MAX 255

int map[MAP BIT MAX][MAP CODE MAX];

int GET BYTE()
{
  current bit counter = -1;
  return buf[byte pointer read++];
}
void WRITE BYTE(int byte)
{
  fprintf(outFile," DB $%02X \n",byte);
  fwrite(&byte,1,1,outFile2);
}

int GET BIT()
{
  if (current bit counter == -1)
  {
    current out byte = GET BYTE();
    current bit counter = 7;
  }
  if (current out byte&(1<<(current bit counter--)))
  {
    return 1;
  }
  return 0;
}

int total unpack count = 0;

int main( int argc, char* argv[] )
{
  cout " nCalling ";
  for (int ii=0;ii<argc;ii++)
    cout " "argv[ii];
  cout " \n \n";
  if ( argc != 2 )
  {
    cout "Usage: decode <infile> \n";
    return 0;
  }
  inFile=fopen(argv[1],"rb");
  if( !inFile )
  {
    cout "A file error occured with " argv[1] "! \n";
    return 2;
  }
  len=fread( buf, sizeof(char),sizeof(char)*MAXBUFF,inFile );
  fclose(inFile);
  printf("Length of file: %i \n",len);

  vbl len = GET BYTE()*256+GET BYTE();
  printf("Length of track: %i \n",vbl len);
  int ym register;

  outFile=fopen("out int.asm","wb+");
  if (!outFile)
  {
    printf("File Open Error! \n");
    return 1;
  }
  outFile2=fopen("out int.bin","wb+");
  if (!outFile2)
  {
    printf("File Open Error! \n");
    return 1;
  }

  fprintf(outFile," DW %i ; length of track \n", vbl len);


  for (ym register=ENCODE START; ym register< ENCODE END; ym register++)
  {
    int to map = GET BYTE();
    int i;
    printf("Register %i has %i different "bytes' \n", ym register, to map);
    // initialize mapper
    fprintf(outFile,"; mapper for ym register %i \n", ym register);
    fprintf(outFile," DB $%02X ; uses different bytes \n", to map);
    for (i=0; i < MAP BIT MAX; i++)
    {
      for (int j=0; j < MAP CODE MAX; j++)
      {
        map[i][j] = -1;
      }
    }
    int no phrases=0;
    for (i=0; i < to map; i++)
    {
      int bits = GET BYTE();
      int code = GET BYTE();
      int real byte = GET BYTE();

      fprintf(outFile," DB %02X, %02X, %02X ; bits, code, realbyte \n", bits, code, real byte);
      if ((bits&127) > MAP BIT MAX)
      {
        printf("Bit overflow - bye! \n");
        exit(1);
      }

      map[bits&127][code] = real byte;
      if (bits&128)
      {
        no phrases++;
        map[bits&127][code]+=256;
      }
    }
    fprintf(outFile,"; Phrases follow (%i) \n",no phrases);
    // load phrases
    for (i=0;i<no phrases;i++)
    {
      phrases[i].len = GET BYTE();
      fprintf(outFile," DB %02X", phrases[i].len);
      int j;
      for (j=0;j < phrases[i].len; j++)
      {
        phrases[i].phrase[j] = GET BYTE();
        fprintf(outFile,", %02X", phrases[i].phrase[j]);
      }
    fprintf(outFile," \n");
    }

    fprintf(outFile,"; Data follows...\n");
    // done... now start decoding!
    int byte decrunched count = 0;
    while (byte decrunched count < vbl len)
    {
      int RLE count = 0;

      if (GET BIT() == 0)
      {
        // one byte
        RLE count = 1;
      }
      else
      {
        // rle encoded
        int count bits = 1; // already got a 1, see above
        while (GET BIT() == 1)
        {
          count bits++;
        }
        count bits+=2; // plus two, since we start coding with 3 bits

        // the following count bits represent the RLE count
        // lsb first
        for (i=0; i < count bits; i++)
        {
          RLE count+= i);
        }
      }

      // in RLE count now the number of times we should repeat the
      // following bit data...
      // msb first
      int bits = 0;
      int code = 0;
      int is phrase = 0;
      int unpacked byte = 0;
      while (1)
      {
        code = 1;
        code += GET BIT();
        bits++;
        if (map[bits][code] != -1)
        {
          unpacked byte = map[bits][code];
          if (unpacked byte>=256)
          {
            is phrase = 1;
            unpacked byte -= 256;
          }
          break;
        }
      }
/*
    fprintf(outFile,"; byte decrunched count %i \n",byte decrunched count);
    if (is phrase == 0)
      fprintf(outFile,"; byte %02X, times %i \n",unpacked byte,RLE count);
    else
      fprintf(outFile,"; phrase %02X, times %i \n",unpacked byte,RLE count);
*/
      for (i=0; i<RLE count; i++)
      {
        if (is phrase == 0)
        {
          WRITE BYTE(unpacked byte);
          byte decrunched count++;
          total unpack count++;
        }
        else
        {
          int j;
          for (j=0;j<phrases[unpacked byte].len;j++)
          {
            WRITE BYTE(phrases[unpacked byte].phrase[j]);
            byte decrunched count++;
            total unpack count++;
          }
        }
      }
    }
  }
  printf("Bytes unpacked: %i \n", total unpack count);
  fclose(outFile);
  fclose(outFile2);

  return 0;
}