topical media & game development

talk show tell print

graphic-player-10-pixel-compile-dpbj.c

? / graphic-player-10-pixel-compile-dpbj.c


  /*
  Adobe Systems Incorporated(r) Source Code License Agreement
  Copyright(c) 2006 Adobe Systems Incorporated. All rights reserved.
  
  Please read this Source Code License Agreement carefully before using
  the source code.
  
  Adobe Systems Incorporated grants to you a perpetual, worldwide, non-exclusive,
  no-charge, royalty-free, irrevocable copyright license, to reproduce,
  prepare derivative works of, publicly display, publicly perform, and
  distribute this source code and such derivative works in source or
  object code form without any attribution requirements.
  
  The name "Adobe Systems Incorporated" must not be used to endorse or promote products
  derived from the source code without prior written permission.
  
  You agree to indemnify, hold harmless and defend Adobe Systems Incorporated from and
  against any loss, damage, claims or lawsuits, including attorney's
  fees that arise or result from your use or distribution of the source
  code.
  
  THIS SOURCE CODE IS PROVIDED "AS IS" AND "WITH ALL FAULTS", WITHOUT
  ANY TECHNICAL SUPPORT OR ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING,
  BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. ALSO, THERE IS NO WARRANTY OF
  NON-INFRINGEMENT, TITLE OR QUIET ENJOYMENT. IN NO EVENT SHALL MACROMEDIA
  OR ITS SUPPLIERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOURCE CODE, EVEN IF
  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
  include <stdio.h>
  include <stdint.h>
  include <string.h>
  include <strings.h>
  include <malloc.h>
  
  enum {
          pbjNop                                        = 0x00,
          pbjAdd                                        = 0x01,
          pbjSubtract                                = 0x02,
          pbjMultiply                                = 0x03,
          pbjReciprocal                        = 0x04,
          pbjDivide                                = 0x05,
          pbjAtan2                                = 0x06,
          pbjPow                                        = 0x07,
          pbjMod                                        = 0x08,
          pbjMin                                        = 0x09,
          pbjMax                                        = 0x0A,
          pbjStep                                        = 0x0B,
          pbjSin                                        = 0x0C,
          pbjCos                                        = 0x0D,
          pbjTan                                        = 0x0E,
          pbjASin                                        = 0x0F,
          pbjACos                                        = 0x10,
          pbjATan                                        = 0x11,
          pbjExp                                        = 0x12,
          pbjExp2                                        = 0x13,
          pbjLog                                        = 0x14,
          pbjLog2                                        = 0x15,
          pbjSqrt                                        = 0x16,
          pbjRSqrt                                = 0x17,
          pbjAbs                                        = 0x18,
          pbjSign                                        = 0x19,
          pbjFloor                                = 0x1A,
          pbjCeil                                        = 0x1B,
          pbjFract                                = 0x1C,
          pbjCopy                                        = 0x1D,
          pbjFloatToInt                        = 0x1E,
          pbjIntToFloat                        = 0x1F,
          pbjMatrixMatrixMultiply        = 0x20,
          pbjVectorMatrixMultiply        = 0x21,
          pbjMatrixVectorMultiply        = 0x22,
          pbjNormalize                        = 0x23,
          pbjLength                                = 0x24,
          pbjDistance                                = 0x25,
          pbjDotProduct                        = 0x26,
          pbjCrossProduct                        = 0x27,
          pbjEqual                                = 0x28,
          pbjNotEqual                                = 0x29,
          pbjLessThan                                = 0x2A,
          pbjLessThanEqual                = 0x2B,
          pbjLogicalNot                        = 0x2C,
          pbjLogicalAnd                        = 0x2D,
          pbjLogicalOr                        = 0x2E,
          pbjLogicalXor                        = 0x2F,
          pbjSampleNearest                = 0x30,
          pbjSampleBilinear                = 0x31,
          pbjLoadConstant                        = 0x32,
          pbjSelect                                = 0x33,
          pbjIf                                        = 0x34,
          pbjElse                                        = 0x35,
          pbjEndif                                = 0x36,
          pbjFloatToBool                        = 0x37,
          pbjBoolToFloat                        = 0x38,
          pbjIntToBool                        = 0x39,
          pbjBoolToInt                        = 0x3A,
          pbjVectorEqual                        = 0x3B,
          pbjVectorNotEqual                = 0x3C,
          pbjAny                                        = 0x3D,
          pbjAll                                        = 0x3E,
          pbjKernelMetaData                = 0xa0,
          pbjParameterData                = 0xa1,
          pbjParameterMetaData        = 0xa2,
          pbjTextureData                        = 0xa3,
          pbjKernelName                        = 0xa4,
          pbjVersionData                        = 0xa5,
  
          pbjTypeFloat                        = 0x01,
          pbjTypeFloat2                        = 0x02,
          pbjTypeFloat3                        = 0x03,
          pbjTypeFloat4                        = 0x04,
          pbjTypeFloat2x2                        = 0x05,
          pbjTypeFloat3x3                        = 0x06,
          pbjTypeFloat4x4                        = 0x07,
          pbjTypeInt                                = 0x08,
          pbjTypeInt2                                = 0x09,
          pbjTypeInt3                                = 0x0A,
          pbjTypeInt4                                = 0x0B,
          pbjTypeString                        = 0x0C,
          pbjTypeBool                                = 0x0D,
          pbjTypeBool2                        = 0x0E,
          pbjTypeBool3                        = 0x0F,
          pbjTypeBool4                        = 0x10,
          
          pbjSampleSizeScalar                = 0x01,
          pbjSampleSizeVector2        = 0x02,
          pbjSampleSizeVector3        = 0x03,
          pbjSampleSizeVector4        = 0x04,
  };
  
  static FILE *ifile = 0;
  static FILE *ofile = 0;
  
  const char *opNamesLo[] = {
          "nop", 
          "add", 
          "sub", 
          "mul", 
          "rcp", 
          "div", 
          "atan2", 
          "pow", 
          "mod", 
          "min", 
          "max", 
          "step", 
          "sin", 
          "cos", 
          "tan", 
          "asin", 
          "acos", 
          "atan", 
          "exp", 
          "exp2", 
          "log", 
          "log2", 
          "sqr", 
          "rsqr", 
          "abs", 
          "sign", 
          "floor", 
          "ceil", 
          "fract", 
          "mov", 
          "ftoi", 
          "itof", 
          "mmmul", 
          "vmmul", 
          "mvmul", 
          "norm", 
          "len", 
          "dist", 
          "dot", 
          "cross", 
          "equ", 
          "neq", 
          "ltn", 
          "lte", 
          "not", 
          "and", 
          "or", 
          "xor", 
          "texn", 
          "texb", 
          "set", 
          "sel", 
          "if", 
          "else", 
          "end", 
          "ftob", 
          "btof", 
          "itob", 
          "btoi", 
          "vequ", 
          "vneq",  
          "any", 
          "all", 
  };
  
  const char *opNamesHi[] = {
          "kernel",
          "parameter",
          "meta",
          "texture",
          "name",
          "version",
  };
  
  const char *matrixNames[] = {
          "",
          "2x2",
          "3x3",
          "4x4",
  };
  
  const int32_t typeSizes[] = {
          0,
          1,
          2,
          3,
          4,
          4,
          9,
          16,
          1,
          2,
          3,
          4,
          0,
          1,
          2,
          3,
          4,
  };
  
  const char *typeNames[] = {
          "",
          "float",
          "float2",
          "float3",
          "float4",
          "matrix2x2",
          "matrix3x3",
          "matrix4x4",
          "int",
          "int2",
          "int3",
          "int4",
          "bool",
          "bool2",
          "bool3",
          "bool4",
  };
  
  const char *qualifierName[] = {
          "",
          "in",
          "out",
  };
  
  bool available()
  {
          return feof(ifile)==0;
  }
  
  uint32_t readUint32()
  {
          uint8_t c0 = (uint8_t)fgetc(ifile);
          uint8_t c1 = (uint8_t)fgetc(ifile);
          uint8_t c2 = (uint8_t)fgetc(ifile);
          uint8_t c3 = (uint8_t)fgetc(ifile);
          return (c0<<24)|(c1<<16)|(c2<<8)|(c3<<0);
  }
  
  uint16_t readUint16()
  {
          uint8_t c0 = (uint8_t)fgetc(ifile);
          uint8_t c1 = (uint8_t)fgetc(ifile);
          return (c0<<8)|(c1);
  }
  
  uint8_t readUint8()
  {
          uint8_t c0 = (uint8_t)fgetc(ifile);
          return c0;
  }
  
  float readFloat()
  {
          union {
                  uint32_t i;
                  float    f;
          };
          i = (((uint32_t)((uint8_t)fgetc(ifile)))<<24)|
              (((uint32_t)((uint8_t)fgetc(ifile)))<<16)|
              (((uint32_t)((uint8_t)fgetc(ifile)))<< 8)|
              (((uint32_t)((uint8_t)fgetc(ifile)))<< 0);
          return f;
  }
  
  const char *readStrN(int32_t size)
  {
          char *str = (char *)malloc(size+1);
          fread(str,size,1,ifile);
          str[size] = 0;
          return str;
  }
  
  const char *readStr()
  {
          int32_t pos = (int32_t)ftell(ifile);
          int32_t c=0;
          for ( ; ; c++ ) {
                  if ( !available() ) {
                          return 0;
                  }
                  if ( readUint8() == 0 ) {
                          break;
                  }
          }
          fseek(ifile,pos,SEEK_SET);
          return readStrN(c+1);
  }
  
  void seek(int32_t pos)
  {
          fseek(ifile,pos,SEEK_CUR);
  }
  
  inline bool isIntReg(int32_t reg)
  { 
          return (reg&0x8000)?true:false; 
  }
  
  inline uint16_t littleToBig16(uint16_t v ) {
          return ((v>>8)&0xFF)|((v<<8)&0xFF00);
  }
  
  inline int32_t Swizzle(int32_t index, int32_t swizzle) {
          return (swizzle>>(6-index*2))&3;
  }
  
  int32_t BitCount(uint32_t n)                          
  {
          uint32_t tmp = n - ((n >> 1) & 033333333333) - ((n >> 2) & 011111111111);
          return ((tmp + (tmp >> 3)) & 030707070707) % 63;
  }
  
  int32_t IndexToDstWithMask(int32_t index, int32_t mask) 
  {
          static const int32_t map[4*16] = {
                  0x00,0x00,0x00,0x00,
                  0x03,0x00,0x00,0x00,
                  0x02,0x00,0x00,0x00,
                  0x02,0x03,0x00,0x00,
                  0x01,0x00,0x00,0x00,
                  0x01,0x03,0x00,0x00,
                  0x01,0x02,0x00,0x00,
                  0x01,0x02,0x03,0x00,
                  0x00,0x00,0x00,0x00,
                  0x00,0x03,0x00,0x00,
                  0x00,0x02,0x00,0x00,
                  0x00,0x02,0x03,0x00,
                  0x00,0x01,0x00,0x00,
                  0x00,0x01,0x03,0x00,
                  0x00,0x01,0x02,0x00,
                  0x00,0x01,0x02,0x03
          };
          return map[(mask<<2|index)];
  }
  
  void printWriteMask(int32_t writeMask, int32_t type)
  {
          if ( writeMask != 0xF ) {
                  fprintf(ofile,".");
                  const char cnam[4] = { 'r','g','b','a' };
                  for ( int c=0; c<typeSizes[type]; c++ ) {
                          fprintf(ofile,"\%c",cnam[IndexToDstWithMask(c,writeMask)]);
                  }
          }
  }
  
  void printDstReg(int32_t index, int32_t writeMask, int32_t readSize)
  {
          if ( index >= 32768 ) {
                  fprintf(ofile,"i\%d",index-32768);
          } else {
                  fprintf(ofile,"f\%d",index);
          }
          if ( writeMask != 0xF ) {
                  fprintf(ofile,".");
                  const char cnam[4] = { 'r','g','b','a' };
                  for ( int c=0; c<readSize; c++ ) {
                          fprintf(ofile,"\%c",cnam[IndexToDstWithMask(c,writeMask)]);
                  }
          }
  }
  
  void printSrcReg(int32_t index, int32_t readSwizzle, int32_t readSize)
  {
          if ( index >= 32768 ) {
                  fprintf(ofile,"i\%d",index-32768);
          } else {
                  fprintf(ofile,"f\%d",index);
          }
          if ( readSwizzle != 0x1b ) {
                  fprintf(ofile,".");
                  const char cnam[4] = { 'r','g','b','a' };
                  for ( int c=0; c<readSize; c++ ) {
                          fprintf(ofile,"\%c",cnam[Swizzle(c,readSwizzle)]);
                  }
          }
  }
  
  void parse()
  {
          bool firstins = true;
  
          for ( ; available() ; ) {
          
                  uint32_t op0 = readUint32();
                  uint32_t op1 = readUint32();
                  
                  int32_t op                                 = ( op0 >> 24 ) ;
                  int32_t dst                                = ( op0 >>  8 ) & 0xFFFF;
                  int32_t writeMask                = ( op0 >>  4 ) & 0xF;
                  int32_t matrixSize                = ( op0 >>  2 ) & 0x3;
                  int32_t readSize                = ( op0  &  3 ) + 1;
                  int32_t src                                = ( op1 >> 16 ) & 0xFFFF;
                  int32_t readSwizzle                = ( op1 >>  8 ) & 0xFF;
                  
                  dst = littleToBig16(uint16_t(dst));
                  src = littleToBig16(uint16_t(src));
  
                  if ( op <= pbjSelect ) {
                          if ( matrixSize == 0 ) {
                                  if ( op == pbjLoadConstant ) {
  
                                  } else if ( op == pbjLength ) { 
                                          if ( BitCount(writeMask) != pbjSampleSizeScalar ) {
                                                  fprintf(stderr, "(\%s) sizeof( dst ) != 1\n",opNamesLo[op&0x7F]);
                                                  goto error; 
                                          }
                                  } else if ( op == pbjSampleNearest || op == pbjSampleBilinear ) {
                                          if ( readSize != pbjSampleSizeVector2 ) {
                                                  fprintf(stderr, "(\%s) sizeof( src ) != 2\n",opNamesLo[op&0x7F]);
                                                  goto error; 
                                          }
                                  } else if ( op == pbjSelect ) {
                                          if( readSize != 1 ) { 
                                                  fprintf(stderr, "(\%s) sizeof( src ) != 1\n",opNamesLo[op&0x7F]);
                                                  goto error; 
                                          }        
                                  } else {
                                          if( BitCount(writeMask) != readSize ) { 
                                                  fprintf(stderr, "(\%s) sizeof( dst ) != sizeof( src )\n",opNamesLo[op&0x7F]);
                                                  goto error; 
                                          }        
                                  }
                          } else {
                                  if ( isIntReg(src) || isIntReg(dst) ) {
                                          fprintf(stderr, "(\%s) operation not allowed on integer types\n",opNamesLo[op&0x7F]);
                                          goto error; 
                                  }
                          }
                  }
                  
                  switch ( op ) {
                          case        pbjNop: 
                                          if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                          fprintf(ofile,"\t\%s\n",opNamesLo[op]);
                                          break;
  
                          case        pbjAdd:
                          case        pbjSubtract:                        
                          case        pbjMultiply:        
                          case        pbjDivide:
                          case        pbjMatrixMatrixMultiply:
                          case        pbjAtan2:                        
                          case        pbjPow:                                
                          case        pbjMod:                                
                          case        pbjMin:                                
                          case        pbjMax:                                
                          case        pbjStep: 
                          case        pbjCopy:                                        
                          case        pbjFloatToInt:
                          case        pbjIntToFloat: 
                          case        pbjReciprocal:
                          case        pbjSin:                                        
                          case        pbjCos:                                        
                          case        pbjTan:                                        
                          case        pbjASin:                                        
                          case        pbjACos:                                
                          case        pbjATan:                                        
                          case        pbjExp:                                        
                          case        pbjExp2:                                        
                          case        pbjLog:                                        
                          case        pbjLog2:                                        
                          case        pbjSqrt:                                        
                          case        pbjRSqrt:                                
                          case        pbjAbs:                                        
                          case        pbjSign:                                        
                          case        pbjFloor:                                
                          case        pbjCeil:                                        
                          case        pbjFract:
                          case        pbjFloatToBool:
                          case        pbjIntToBool: {        
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( matrixSize ) {
                                                          if ( writeMask != 0 ) {
                                                                  fprintf(stderr, "(\%s) (write mask:\%d) write mask not allowed\n",opNamesLo[op&0x7F],writeMask);
                                                                  goto error;
                                                          }
                                                          switch ( op ) {
                                                                  case        pbjCopy:
                                                                  case        pbjAdd:
                                                                  case        pbjSubtract:
                                                                  case        pbjMultiply:
                                                                  case        pbjReciprocal:
                                                                  case        pbjMatrixMatrixMultiply: {
                                                                                          fprintf(ofile,"\t\%s\%s\t\t\%d, \%d\n",opNamesLo[op],matrixNames[matrixSize],dst,src);
                                                                                  } break;
                                                                  default: {
                                                                                          fprintf(stderr, "(\%s) operation now allowed on matrices\n",opNamesLo[op&0x7F]);
                                                                                          goto error;
                                                                                  } break;
                                                          }
                                                  } else {
                                                          bool dstInt = false;
                                                          bool srcInt = false;
                                                          switch ( op ) {
                                                                  case        pbjAdd:
                                                                                  if ( isIntReg(dst) ) {
                                                                                          dstInt = true;
                                                                                          srcInt = true;
                                                                                  }
                                                                                  break;
                                                                  case        pbjSubtract:                        
                                                                                  if ( isIntReg(dst) ) {
                                                                                          dstInt = true;
                                                                                          srcInt = true;
                                                                                  }
                                                                                  break;
                                                                  case        pbjMultiply:                        
                                                                                  if ( isIntReg(dst) ) {
                                                                                          dstInt = true;
                                                                                          srcInt = true;
                                                                                  }
                                                                                  break;
                                                                  case        pbjDivide:
                                                                                  if ( isIntReg(dst) ) {
                                                                                          dstInt = true;
                                                                                          srcInt = true;
                                                                                  }
                                                                                  break;
                                                          }
                                                          if ( op == pbjCopy ) {
                                                                  if ( isIntReg(dst) != isIntReg(src) ) {
                                                                          fprintf(stderr, "(\%s) source and destination register type mismatch\n",opNamesLo[op&0x7F]);
                                                                          goto error;
                                                                  }
                                                          } else {
                                                                  if ( isIntReg(dst) != dstInt ) {
                                                                          fprintf(stderr, "(\%s) invalid destination register type\n",opNamesLo[op&0x7F]);
                                                                          goto error;
                                                                  }
                                                                  if ( isIntReg(src) != srcInt ) {
                                                                          fprintf(stderr, "(\%s) invalid source register type\n",opNamesLo[op&0x7F]);
                                                                          goto error;
                                                                  }
                                                          }
                                                          
                                                          fprintf(ofile,"\t");
                                                          fprintf(ofile,opNamesLo[op]);
                                                          if ( strlen(opNamesLo[op])<4) {
                                                                  fprintf(ofile,"\t\t");
                                                          } else {
                                                                  fprintf(ofile,"\t");
                                                          }
                                                          printDstReg(dst,writeMask,readSize);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src,readSwizzle,readSize);
                                                          fprintf(ofile,"\n");
                                                  }
                                          } break;
  
                          case        pbjBoolToInt:
                          case        pbjBoolToFloat: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( !isIntReg(src) ) {
                                                          fprintf(stderr, "(\%s) invalid source register type\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  if ( isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) invalid destination register type\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", ");
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  fprintf(ofile,"\n");
                                          } break;
  
                          case        pbjAny:
                          case        pbjAll: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( !isIntReg(src) ) {
                                                          fprintf(stderr, "(\%s) invalid source register type\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  if ( !isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) invalid destination register type\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", ");
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  fprintf(ofile,"\n");
                                          } break;
  
                          case        pbjVectorMatrixMultiply: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( BitCount(writeMask) != (matrixSize+1) ) {
                                                          fprintf(stderr, "(\%s) sizeof( dst ) != sizeof( src )\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\t\%s\%s\t",opNamesLo[op],matrixNames[matrixSize]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", f\%d\n",src);
                                          } break;
                                          
                          case        pbjMatrixVectorMultiply: {        
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( BitCount(writeMask) != (matrixSize+1) ) {
                                                          fprintf(stderr, "(\%s) sizeof( dst ) != sizeof( src )\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\t\%s\%s\t",opNamesLo[op],matrixNames[matrixSize]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", f\%d\n",src);
                                          } break;
                                          
                          case        pbjNormalize: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( isIntReg(src) || isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on integer types\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( readSize == pbjSampleSizeScalar ) {
                                                          fprintf(stderr, "(\%s) trying to normalize a scalar\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  } else {
                                                          fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                          printDstReg(dst,writeMask,readSize);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src,readSwizzle,readSize);
                                                          fprintf(ofile,"\n");
                                                  }
                                          } break;
                                          
                          case        pbjDistance:
                          case        pbjLength: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( matrixSize ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on matrices\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( isIntReg(src) || isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on integer values\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( readSize == pbjSampleSizeScalar ) {
                                                          fprintf(stderr, "(\%s) trying to get the length of a scalar\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  } else {
                                                          fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                          printDstReg(dst,writeMask,1);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src,readSwizzle,readSize);
                                                          fprintf(ofile,"\n");
                                                  }
                                          } break;
                                          
                          case        pbjDotProduct: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( matrixSize ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on matrices\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( isIntReg(src) || isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on integer values\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", ");
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  fprintf(ofile,"\n");
                                          } break;
                                          
                          case        pbjCrossProduct: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( matrixSize ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on matrices\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( isIntReg(src) || isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on integer values\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( readSize != 3 ) {
                                                          fprintf(stderr, "(\%s) vector type not supported\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\t\%s\t",opNamesLo[op]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", ");
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  fprintf(ofile,"\n");
                                          } break;
  
                          case        pbjEqual:                                
                          case        pbjNotEqual:  {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( matrixSize ) {
                                                          fprintf(ofile,"\t\%s\%s\t\t\%d, \%d\n",opNamesLo[op],matrixNames[matrixSize],dst,src);
                                                  } else {
                                                          fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                          printDstReg(dst,writeMask,readSize);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src,readSwizzle,readSize);
                                                          fprintf(ofile,"\n");
                                                  }
                                          } break;
                                          
                          case        pbjVectorEqual:
                          case        pbjVectorNotEqual:
                          case        pbjLessThan:                                
                          case        pbjLessThanEqual: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( matrixSize ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on matrices\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( isIntReg(src) != isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) register type mismatch\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\t\%s\t",opNamesLo[op]);
                                                  if ( strlen(opNamesLo[op]) < 4 ) {
                                                          fprintf(ofile,"\t");
                                                  }
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", ");
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  fprintf(ofile,"\n");
                                          } break;
                                          
                          case        pbjLogicalOr:
                          case        pbjLogicalXor:
                          case        pbjLogicalAnd:
                          case        pbjLogicalNot: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( matrixSize ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on matrices\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( !isIntReg(src) || !isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) operation now allowed on float values\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  if ( readSize != pbjSampleSizeScalar ) { 
                                                          fprintf(stderr, "(\%s) ( sizeof( dst ) = sizeof( src ) ) != 1\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", ");
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  fprintf(ofile,"\n");
                                          } break;
                                          
                          case        pbjSampleBilinear:
                          case        pbjSampleNearest: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( isIntReg(dst) ) {
                                                          fprintf(stderr, "(\%s) Can't sample into integer registers\n",opNamesLo[op&0x7F]);
                                                          goto error; 
                                                  }
                                                  fprintf(ofile,"\t\%s\t",opNamesLo[op]);
                                                  printDstReg(dst,writeMask,readSize);
                                                  fprintf(ofile,", ");
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  int32_t txtId = ( op1 ) & 0xFF;
                                                  fprintf(ofile,", t\%d\n",txtId);
                                          } break;
  
                          case        pbjLoadConstant: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  union {
                                                          uint8_t valuec[4];
                                                          float valuef;
                                                          uint32_t valuei;
                                                  };
                                                  valuei = op1;
                                                  if ( isIntReg(dst) ) {
                                                          fprintf(ofile,"\tset\t\t");
                                                          printDstReg(dst,writeMask,readSize);
                                                          fprintf(ofile,", \%d\n",valuei);
                                                  } else {
                                                          valuei =         (((uint32_t)(valuec[3]))<<24)|
                                                                                  (((uint32_t)(valuec[2]))<<16)|
                                                                                  (((uint32_t)(valuec[1]))<< 8)|
                                                                                  (((uint32_t)(valuec[0]))<< 0);
                                                          fprintf(ofile,"\tset\t\t");
                                                          printDstReg(dst,writeMask,readSize);
                                                          fprintf(ofile,", \%g\n",valuef);
                                                  }
                                          } break;
                                          
                          case        pbjSelect: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  uint32_t op2 = readUint32();
                                                  uint32_t op3 = readUint32();
                                                  
                                                  uint16_t src0 = op2>>16;
                                                  uint16_t src1 = op3>>16;
  
                                                  int32_t readSize0         = ( ( op2 >>  6 ) & 0x3) + 1;
                                                  int32_t readSwizzle0 = (   op2 >>  8 ) & 0xFF;
                                                  int32_t readSize1         = ( ( op3 >>  6 ) & 0x3) + 1;
                                                  int32_t readSwizzle1 = (   op3 >>  8 ) & 0xFF;
                                                  
                                                  src0 = littleToBig16(src0);
                                                  src1 = littleToBig16(src1);
  
                                                  if ( !isIntReg(src) ) {
                                                          fprintf(stderr, "(\%s) source needs to be of type int\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
  
                                                  if ( readSize0 != readSize1 ) {
                                                          fprintf(stderr, "(\%s) sizeof(src1) != sizeof(src2)\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
  
                                                  if ( matrixSize ) {
                                                          if ( !isIntReg(src0) || !isIntReg(src1) ) {
                                                                  fprintf(stderr, "(\%s) source needs to be of type int\n",opNamesLo[op&0x7F]);
                                                                  goto error;
                                                          }
                                                          fprintf(ofile,"\t\%s\%s\t\t",opNamesLo[op],matrixNames[matrixSize]);
                                                          printDstReg(dst,writeMask,readSize);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src,readSwizzle,readSize);
                                                          fprintf(ofile,", f\%d, f\%d\n",src0,src1);
                                                  } else {
                                                          if ( isIntReg(src0) != isIntReg(src1) ||
                                                                   isIntReg(src0) != isIntReg(dst) ) {
                                                                  fprintf(stderr, "(\%s) source register type mismatch\n",opNamesLo[op&0x7F]);
                                                                  goto error;
                                                          }
                                                          fprintf(ofile,"\t\%s\t\t",opNamesLo[op]);
                                                          printDstReg(dst,writeMask,readSize);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src,readSwizzle,readSize);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src0,readSwizzle0,readSize);
                                                          fprintf(ofile,", ");
                                                          printSrcReg(src1,readSwizzle1,readSize);
                                                          fprintf(ofile,"\n");
                                                  }
                                          } break;
  
                          case        pbjIf: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  if ( !isIntReg(src) ) {
                                                          fprintf(stderr, "(\%s) source needs to be of type int\n",opNamesLo[op&0x7F]);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\n\t\%s\t\t",opNamesLo[op]);
                                                  printSrcReg(src,readSwizzle,readSize);
                                                  fprintf(ofile,"\n\n");
                                          } break;
  
                          case        pbjElse: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  fprintf(ofile,"\n\t\%s\t\t\n\n",opNamesLo[op]);
                                          } break;
  
                          case        pbjEndif: {
                                                  if ( firstins ) { firstins = false; fprintf(ofile,"\n;----------------------------------------------------------\n\n"); }
                                                  fprintf(ofile,"\n\t\%s\t\t\n\n",opNamesLo[op]);
                                          } break;
                                          
                          case        pbjParameterMetaData:
                          case        pbjKernelMetaData: {
                          
                                                  seek(-7);
  
                                                  int32_t type = readUint8();
                                                  
                                                  if ( type == pbjTypeString ) {
                                                  
                                                          const char *name = readStr();
                                                          const char *meta = readStr();
  
                                                          if (op == pbjParameterMetaData) {
                                                                  fprintf(ofile,"\tmeta\t\t\"\%s\", \"\%s\"",name,meta);
                                                          } else {
                                                                  fprintf(ofile,"\tkernel\t\t\"\%s\", \"\%s\"",name,meta);
                                                          }
  
                                                  } else {
  
                                                          const char *name = readStr();
  
                                                          if (op == pbjParameterMetaData) {
  
                                                                  fprintf(ofile,"\tmeta\t\t\"\%s\"",name);
                                                                  
                                                                  int numElem = 0;
  
                                                                  switch ( type ) {
                                                                          case        pbjTypeFloat4x4:
                                                                                          numElem += 7;
                                                                          case        pbjTypeFloat3x3:
                                                                                          numElem += 5;
                                                                          case        pbjTypeFloat2x2:
                                                                          case        pbjTypeFloat4:
                                                                                          numElem++;
                                                                          case        pbjTypeFloat3:
                                                                                          numElem++;
                                                                          case        pbjTypeFloat2:
                                                                                          numElem++;
                                                                          case        pbjTypeFloat:
                                                                                          numElem++;
                                                                                          for ( int c=0; c<numElem; c++ ) {
                                                                                                  fprintf(ofile,", \%g",readFloat());
                                                                                          }
                                                                                          break;
                                                                          case        pbjTypeBool4:
                                                                          case        pbjTypeInt4:
                                                                                          numElem++;
                                                                          case        pbjTypeBool3:
                                                                          case        pbjTypeInt3:
                                                                                          numElem++;
                                                                          case        pbjTypeBool2:
                                                                          case        pbjTypeInt2:
                                                                                          numElem++;
                                                                          case        pbjTypeBool:
                                                                          case        pbjTypeInt:
                                                                                          numElem++;
                                                                                          for ( int c=0; c<numElem; c++ ) {
                                                                                                  fprintf(ofile,", \%d",(littleToBig16(readUint16())<<15)>>15);
                                                                                          }
                                                                                          break;
                                                                  }
                                                          } else {
  
                                                                  fprintf(ofile,"\tkernel\t\t\"\%s\"",name);
                                                                  switch ( type ) {
                                                                                  case        pbjTypeInt: {
                                                                                                  int32_t i = (littleToBig16(readUint16())<<15)>>15;
                                                                                                  fprintf(ofile,", \%d",i);
                                                                                                  } break;
                                                                                  default:
                                                                                                  goto error;
                                                                  }
                                                          }
                                                  }
                                                          
                                                  fprintf(ofile,"\n");
                                          } break;
  
                          case        pbjParameterData: {
                                                  seek(-7);
                                                  int32_t qualifier = readUint8();
                                                  int32_t type = readUint8();
                                                  
                                                  if ( type == pbjTypeString || qualifier > 2 || qualifier < 1) {
                                                          goto error;
                                                  } else {
                                                  
                                                          dst = littleToBig16(readUint16());
                                                          writeMask = readUint8();
                                                          
                                                          const char *paramName = readStr();
                                                          
                                                          fprintf(ofile,"\n\tparameter\t\"\%s\", \%s, ",paramName, typeNames[type] );
                                                          printDstReg(dst,writeMask,typeSizes[type]);
                                                          fprintf(ofile,", \%s",qualifierName[qualifier]);
                                                          fprintf(ofile,"\n");
                                                  }
                                                  
                                          } break;
                                          
                          case        pbjTextureData: {
                                                  seek(-7);
                                                  int32_t index = readUint8();
                                                  int32_t channels = readUint8();
                                                  fprintf(ofile,"\n\ttexture\t\t\"\%s\", t\%d",readStr(),index);
                                                  const char cnam[4] = { 'r','g','b','a' };
                                                  if ( channels != 4 ) {
                                                          fprintf(ofile,".");
                                                          for ( int c=0; c<channels; c++ ) {
                                                                  fprintf(ofile,"\%c",cnam[c]);
                                                          }
                                                  }
                                                  fprintf(ofile,"\n");
                                          } break;
                                          
                          case        pbjKernelName: {
                                                  seek(-7);
                                                  fprintf(ofile,"\tname\t\t\"\%s\"\n",readStrN(littleToBig16(readUint16())));
                                          } break;
                                          
                          case        pbjVersionData: {
                                                  seek(-7);
                                                  uint8_t a0 = readUint8();
                                                  uint8_t a1 = readUint8();
                                                  uint8_t a2 = readUint8();
                                                  uint8_t a3 = readUint8();
                                                  int32_t version = (a0)|(a1<<8)|(a2<<16)|(a3<<24);
                                                  if ( version != 1 ) {
                                                          fprintf(stderr, "(?) unsupported pbj byte code version \%d\n",version);
                                                          goto error;
                                                  }
                                                  fprintf(ofile,"\tversion\t\t\%d\n",version);
                                          } break;
                                          
                          default: {
                                                  if ( !available() ) {
                                                          return;
                                                  }
                                                  fprintf(stderr, "(?) unknown opcode %02x\n",op);
                                                  goto error;
                                          } break;
                  }
          }
  error:
          return;
  }
  
  int main(int argc, char *argv[])
  {
          if ( argc > 1) {
                  for (int32_t c = 1; c < argc; c++) {
                          if (argv[c][0] == '-') {
                                  if (argv[c][1] == 'o') {
                                          if ( argc < c+1 ) {
                                                  fprintf(stderr,"Missing output file name.\n\n");
                                                  return -1;
                                          }
                                          if ( ( ofile = fopen(argv[c+1],"wb") ) == 0 ) {
                                                  fprintf(stderr,"Could not open output file '\%s'\n\n",argv[c+1]);
                                                  return -1;
                                          }
                                  }
                          }
                  }
                  if ( ofile == 0 ) {
                          ofile = stdout;
                  }
                  if ( ( ifile = fopen(argv[1],"rb") ) != 0 ) {
                          parse();
                          fclose(ifile);
                          return 0;
                  }
                  if ( ofile && ofile != stdout ) {
                          fclose(ofile);
                  }
          }
          fprintf(stderr,"\nCan't open input file.\n\n");
          fprintf(stderr,"Usage: 'dpjb input.pbj -o output.pba' or 'dpjb input.pbj'\n\n");
          return -1;
  }
  


(C) Æliens 20/2/2008

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.