#include "stdlib.h"
#include <stdio.h>
#include <string.h>

extern void ps4decode(unsigned int* melt_buff, 
                      unsigned char* k_work, 
                      unsigned short* tex_buff,
                      unsigned short clear_color);

unsigned char *melt_buff = NULL;

int main(int argc, char** argv)
{
    unsigned char *k_work=(unsigned char *)malloc(320*240*sizeof(unsigned char));
    unsigned short *tex_buff=(unsigned short *)malloc(295000*sizeof(short));
    unsigned short clear_color = 1;
    unsigned short *sptr;
    int i, j, k, l, buf_size;
    int itmp, x_size, y_size;
    FILE *fptr, *sfptr;
    char line[256], *ptr, ctmp;

    if( argc < 2 ) {
      fprintf( stdout, "Usage: decode <assembly files>\n" );
      exit(1);
    }

    /* open summary file */
    sfptr = fopen( "image_size.txt", "w" );
    if( sfptr == NULL ) {
      fprintf( stdout, "Unable to open summary file image_size.txt\n" );
      exit(1);
    }

    /* go through all files in arg list */
    buf_size = 2048;
    for( j = 1; j < argc; j++ ) {

      /* input file */
      fptr = fopen( argv[j], "r" );
      if( fptr == NULL ) {
        fprintf( stdout, "Unable to open input file %s\n", argv[j] );
        continue;
      }
      fprintf( stdout, "Processing file %s\n", argv[j] );

      /* parse input file */
      k = l = 0;
      if( melt_buff == NULL ) melt_buff = (unsigned char *)malloc( buf_size );
      memset( melt_buff, 0, buf_size );
      while( fgets( line, 255, fptr ) ) {
        if( strstr( line, ".byte" ) ) {
          k++;
          /* get image size */
          if( k == 2 ) {
            /* scan first byte (width) */
            ptr = strchr( line, 'x' ) + 1;
            sscanf( ptr, "%x", &itmp );
            x_size = itmp*256;
            /* scan second byte (width) */
            ptr = strchr( ptr, 'x' ) + 1;
            sscanf( ptr, "%x", &itmp );
            x_size += itmp;
            /* scan third byte (height) */
            ptr = strchr( ptr, 'x' ) + 1;
            sscanf( ptr, "%x", &itmp );
            y_size = itmp*256;
            /* scan fourth byte (height) */
            ptr = strchr( ptr, 'x' ) + 1;
            sscanf( ptr, "%x", &itmp );
            y_size += itmp;
          }  
          /* convert data */
          ptr = line;
          for( i = 0; i < 8; i++, l++ ) {
            ptr = strchr( ptr, 'x' );
            if( ptr == NULL ) break; else ptr++;
            sscanf( ptr, "%x", &itmp );
            melt_buff[l] = (unsigned char)itmp;
          }
          /* check array size */
          if( l == buf_size ) {
            buf_size += 2048;
            melt_buff = realloc( melt_buff, buf_size );
          } 
        } 
      } 
      fclose( fptr );

      /*
      for( i = 0; i < l; i++ ) {
        fprintf( stdout, " %x", melt_buff[i] );
        if( (i%8) == 7 ) fprintf( stdout, "\n" );
      }
      fprintf( stdout, "\n" ); 
      */
      ps4decode((unsigned int*)melt_buff, k_work, tex_buff, clear_color);

      /* output file */
      strcpy( line, argv[j] );
      ptr = strrchr( line, '.' );
      if( ptr ) *ptr = 0;
      strcat( line, ".raw" );
      ptr = strrchr( line, '/' );
      if( ptr ) ptr++; else ptr = line;
      fptr = fopen( ptr, "w" );
      if( !fptr ) {
        fprintf( stdout, "Unable to open output file %s\n", ptr );
        continue;
      }
    
      /* write out each component */ 
      sptr = tex_buff;
      for( k = 0; k < x_size*y_size; k++, sptr++ ) {
        ctmp = (unsigned char)(((*sptr & 0xf800)>>11) * 255.0 / 31.0);
        fputc( ctmp, fptr );
        ctmp = (unsigned char)(((*sptr & 0x07c0)>>6)  * 255.0 / 31.0);
        fputc( ctmp, fptr );
        ctmp = (unsigned char)(((*sptr & 0x003e)>>1)  * 255.0 / 31.0); 
        fputc( ctmp, fptr );
        ctmp = (*sptr & 0x1) ? 255 : 0;
        fputc( ctmp, fptr );
      }
      fclose( fptr );

      /* write summary */
      fprintf( sfptr, "%s    RGBA32    %dw x %dh\n", ptr, x_size, y_size );
    }
    fclose( sfptr );
}
