parse.c
branchtrunk
changeset 1 99ac16070d07
child 2 c37210f5e87b
equal deleted inserted replaced
0:c590c9b96076 1:99ac16070d07
       
     1 #include <stdio.h>
       
     2 #include <stdlib.h>
       
     3 
       
     4 #define SWAP32(x) (x)
       
     5 typedef unsigned int uint;
       
     6 typedef unsigned char uint8;
       
     7 typedef unsigned int uint32;
       
     8 
       
     9 // This enum complements of Filip Navara's public domain dev-cpp d3d9 header.
       
    10 typedef enum
       
    11 {
       
    12     OPCODE_NOP = 0,
       
    13     OPCODE_MOV = 1,
       
    14     OPCODE_ADD = 2,
       
    15     OPCODE_SUB = 3,
       
    16     OPCODE_MAD = 4,
       
    17     OPCODE_MUL = 5,
       
    18     OPCODE_RCP = 6,
       
    19     OPCODE_RSQ = 7,
       
    20     OPCODE_DP3 = 8,
       
    21     OPCODE_DP4 = 9,
       
    22     OPCODE_MIN = 10,
       
    23     OPCODE_MAX = 11,
       
    24     OPCODE_SLT = 12,
       
    25     OPCODE_SGE = 13,
       
    26     OPCODE_EXP = 14,
       
    27     OPCODE_LOG = 15,
       
    28     OPCODE_LIT = 16,
       
    29     OPCODE_DST = 17,
       
    30     OPCODE_LRP = 18,
       
    31     OPCODE_FRC = 19,
       
    32     OPCODE_M4x4 = 20,
       
    33     OPCODE_M4x3 = 21,
       
    34     OPCODE_M3x4 = 22,
       
    35     OPCODE_M3x3 = 23,
       
    36     OPCODE_M3x2 = 24,
       
    37     OPCODE_CALL = 25,
       
    38     OPCODE_CALLNZ = 26,
       
    39     OPCODE_LOOP = 27,
       
    40     OPCODE_RET = 28,
       
    41     OPCODE_ENDLOOP = 29,
       
    42     OPCODE_LABEL = 30,
       
    43     OPCODE_DCL = 31,
       
    44     OPCODE_POW = 32,
       
    45     OPCODE_CRS = 33,
       
    46     OPCODE_SGN = 34,
       
    47     OPCODE_ABS = 35,
       
    48     OPCODE_NRM = 36,
       
    49     OPCODE_SINCOS = 37,
       
    50     OPCODE_REP = 38,
       
    51     OPCODE_ENDREP = 39,
       
    52     OPCODE_IF = 40,
       
    53     OPCODE_IFC = 41,
       
    54     OPCODE_ELSE = 42,
       
    55     OPCODE_ENDIF = 43,
       
    56     OPCODE_BREAK = 44,
       
    57     OPCODE_BREAKC = 45,
       
    58     OPCODE_MOVA = 46,
       
    59     OPCODE_DEFB = 47,
       
    60     OPCODE_DEFI = 48,
       
    61     OPCODE_TEXCOORD = 64,
       
    62     OPCODE_TEXKILL = 65,
       
    63     OPCODE_TEX = 66,
       
    64     OPCODE_TEXBEM = 67,
       
    65     OPCODE_TEXBEML = 68,
       
    66     OPCODE_TEXREG2AR = 69,
       
    67     OPCODE_TEXREG2GB = 70,
       
    68     OPCODE_TEXM3x2PAD = 71,
       
    69     OPCODE_TEXM3x2TEX = 72,
       
    70     OPCODE_TEXM3x3PAD = 73,
       
    71     OPCODE_TEXM3x3TEX = 74,
       
    72     OPCODE_RESERVED0 = 75,
       
    73     OPCODE_TEXM3x3SPEC = 76,
       
    74     OPCODE_TEXM3x3VSPEC = 77,
       
    75     OPCODE_EXPP = 78,
       
    76     OPCODE_LOGP = 79,
       
    77     OPCODE_CND = 80,
       
    78     OPCODE_DEF = 81,
       
    79     OPCODE_TEXREG2RGB = 82,
       
    80     OPCODE_TEXDP3TEX = 83,
       
    81     OPCODE_TEXM3x2DEPTH = 84,
       
    82     OPCODE_TEXDP3 = 85,
       
    83     OPCODE_TEXM3x3 = 86,
       
    84     OPCODE_TEXDEPTH = 87,
       
    85     OPCODE_CMP = 88,
       
    86     OPCODE_BEM = 89,
       
    87     OPCODE_DP2ADD = 90,
       
    88     OPCODE_DSX = 91,
       
    89     OPCODE_DSY = 92,
       
    90     OPCODE_TEXLDD = 93,
       
    91     OPCODE_SETP = 94,
       
    92     OPCODE_TEXLDL = 95,
       
    93     OPCODE_BREAKP = 96,
       
    94     OPCODE_PHASE = 0xfffd,
       
    95 } OpcodeVal;
       
    96 
       
    97 
       
    98 static int parse_version_token(const uint32 *tokens, const uint32 tokencount)
       
    99 {
       
   100     if (tokencount == 0)
       
   101         return -1;  // no tokens at all?
       
   102 
       
   103     const uint32 token = SWAP32(*tokens);
       
   104     const uint32 shadertype = ((token >> 16) & 0xFFFF);
       
   105     const uint32 major = ((token >> 8) & 0xFF);
       
   106     const uint32 minor = (token & 0xFF);
       
   107 
       
   108     if (shadertype == 0xFFFF)
       
   109         printf("Pixel shader\n");
       
   110     else if (shadertype == 0xFFFE)
       
   111         printf("Vertex shader\n");
       
   112     else
       
   113         return -1;  // geometry shader? Unsupported at the moment. FAIL.
       
   114 
       
   115     printf("Version %u.%u\n", (uint) major, (uint) minor);
       
   116 
       
   117     return 1;  // ate one token.
       
   118 } // parse_version_token
       
   119 
       
   120 
       
   121 static int parse_comment_token(const uint32 *tokens, const uint32 tokencount)
       
   122 {
       
   123     const uint32 token = SWAP32(*tokens);
       
   124     if ((token & 0xFFFF) != 0xFFFE)
       
   125         return 0;  // not a comment token.
       
   126     else if ((token & 0x80000000) != 0)
       
   127         return -1;  // msdn docs say high bit must be zero. FAIL.
       
   128 
       
   129     const uint32 commenttoks = ((token >> 16) & 0xFFFF);
       
   130     const uint32 commentlen = commenttoks * sizeof (uint32);
       
   131     printf("Comment (%u tokens, %u bytes): ",
       
   132             (uint) commenttoks, (uint) commentlen);
       
   133 
       
   134     uint32 i = 0;
       
   135     const char *comment = (const char *) (tokens+1);
       
   136     while (i < commentlen)
       
   137         fputc(comment[i++], stdout);
       
   138 
       
   139     printf("\n");
       
   140 
       
   141     return commenttoks + 1;  // comment data plus the initial token.
       
   142 } // parse_comment_token
       
   143 
       
   144 
       
   145 static int parse_end_token(const uint32 *tokens, const uint32 tokencount)
       
   146 {
       
   147     if (SWAP32(*tokens) != 0x0000FFFF)      // end token is always 0x0000FFFF.
       
   148         return 0;  // not us, eat no tokens.
       
   149 
       
   150     printf("END\n");
       
   151 
       
   152     // we _must_ be last. If so, eat the token. Otherwise: FAIL.
       
   153     return (tokencount == 1) ? 1 : -1;
       
   154 } // parse_end_token
       
   155 
       
   156 
       
   157 static int parse_instruction_token(const uint32 *tokens, const uint32 tokencount)
       
   158 {
       
   159     const uint32 token = SWAP32(*tokens);
       
   160     const uint32 opcode = (token & 0xFFFF);
       
   161     const uint32 controls = ((token >> 16) & 0xFF);
       
   162     const uint32 insttoks = ((token >> 24) & 0x0F);
       
   163     const int coissue = (token & 0x40000000) ? 1 : 0;
       
   164     const int predicated = (token & 0x10000000) ? 1 : 0;
       
   165 
       
   166     if ((token & 0x80000000) != 0)
       
   167         return -1;  // msdn docs say high bit must be zero. FAIL.
       
   168 
       
   169     #define PARSE_OP(op) printf("OPCODE %s\n", #op);
       
   170     //case OPCODE_##op:
       
   171     //    parse_op_##op(tokens+1, opcode, controls, insttoks, coissue, predicated);
       
   172     //    break;
       
   173 
       
   174     PARSE_OP(NOP);
       
   175     PARSE_OP(MOV);
       
   176     PARSE_OP(ADD);
       
   177     PARSE_OP(SUB);
       
   178     PARSE_OP(MAD);
       
   179     PARSE_OP(MUL);
       
   180     PARSE_OP(RCP);
       
   181     PARSE_OP(RSQ);
       
   182     PARSE_OP(DP3);
       
   183     PARSE_OP(DP4);
       
   184     PARSE_OP(MIN);
       
   185     PARSE_OP(MAX);
       
   186     PARSE_OP(SLT);
       
   187     PARSE_OP(SGE);
       
   188     PARSE_OP(EXP);
       
   189     PARSE_OP(LOG);
       
   190     PARSE_OP(LIT);
       
   191     PARSE_OP(DST);
       
   192     PARSE_OP(LRP);
       
   193     PARSE_OP(FRC);
       
   194     PARSE_OP(M4x4);
       
   195     PARSE_OP(M4x3);
       
   196     PARSE_OP(M3x4);
       
   197     PARSE_OP(M3x3);
       
   198     PARSE_OP(M3x2);
       
   199     PARSE_OP(CALL);
       
   200     PARSE_OP(CALLNZ);
       
   201     PARSE_OP(LOOP);
       
   202     PARSE_OP(RET);
       
   203     PARSE_OP(ENDLOOP);
       
   204     PARSE_OP(LABEL);
       
   205     PARSE_OP(DCL);
       
   206     PARSE_OP(POW);
       
   207     PARSE_OP(CRS);
       
   208     PARSE_OP(SGN);
       
   209     PARSE_OP(ABS);
       
   210     PARSE_OP(NRM);
       
   211     PARSE_OP(SINCOS);
       
   212     PARSE_OP(REP);
       
   213     PARSE_OP(ENDREP);
       
   214     PARSE_OP(IF);
       
   215     PARSE_OP(IFC);
       
   216     PARSE_OP(ELSE);
       
   217     PARSE_OP(ENDIF);
       
   218     PARSE_OP(BREAK);
       
   219     PARSE_OP(BREAKC);
       
   220     PARSE_OP(MOVA);
       
   221     PARSE_OP(DEFB);
       
   222     PARSE_OP(DEFI);
       
   223     PARSE_OP(TEXCOORD);
       
   224     PARSE_OP(TEXKILL);
       
   225     PARSE_OP(TEX);
       
   226     PARSE_OP(TEXBEM);
       
   227     PARSE_OP(TEXBEML);
       
   228     PARSE_OP(TEXREG2AR);
       
   229     PARSE_OP(TEXREG2GB);
       
   230     PARSE_OP(TEXM3x2PAD);
       
   231     PARSE_OP(TEXM3x2TEX);
       
   232     PARSE_OP(TEXM3x3PAD);
       
   233     PARSE_OP(TEXM3x3TEX);
       
   234     PARSE_OP(RESERVED0);
       
   235     PARSE_OP(TEXM3x3SPEC);
       
   236     PARSE_OP(TEXM3x3VSPEC);
       
   237     PARSE_OP(EXPP);
       
   238     PARSE_OP(LOGP);
       
   239     PARSE_OP(CND);
       
   240     PARSE_OP(DEF);
       
   241     PARSE_OP(TEXREG2RGB);
       
   242     PARSE_OP(TEXDP3TEX);
       
   243     PARSE_OP(TEXM3x2DEPTH);
       
   244     PARSE_OP(TEXDP3);
       
   245     PARSE_OP(TEXM3x3);
       
   246     PARSE_OP(TEXDEPTH);
       
   247     PARSE_OP(CMP);
       
   248     PARSE_OP(BEM);
       
   249     PARSE_OP(DP2ADD);
       
   250     PARSE_OP(DSX);
       
   251     PARSE_OP(DSY);
       
   252     PARSE_OP(TEXLDD);
       
   253     PARSE_OP(SETP);
       
   254     PARSE_OP(TEXLDL);
       
   255     PARSE_OP(BREAKP);
       
   256     PARSE_OP(PHASE);
       
   257 
       
   258     #undef PARSE_OP
       
   259 } // parse_instruction_token
       
   260 
       
   261 
       
   262 static int parse_token(const uint32 *tokens, const uint32 tokencount)
       
   263 {
       
   264     int retval = -1;
       
   265     int rc = 0;
       
   266 
       
   267     if (tokencount == 0)
       
   268         return -1;  // shouldn't happen, but just in case...
       
   269 
       
   270     if ((rc = parse_comment_token(tokens, tokencount)) != 0)
       
   271         return rc;
       
   272 
       
   273     if ((rc = parse_end_token(tokens, tokencount)) != 0)
       
   274         return rc;
       
   275 
       
   276     if ((rc = parse_instruction_token(tokens, tokencount)) != 0)
       
   277         return rc;
       
   278 
       
   279     return -1;  // nothing handled this? FAIL.
       
   280 } // parse_token
       
   281 
       
   282 
       
   283 int D3D2GLSL_parse(const uint8 *tokenbuf, const uint32 bufsize)
       
   284 {
       
   285     const uint32 *tokens = (const uint32 *) tokenbuf;
       
   286     uint32 tokencount = bufsize / sizeof (uint32);
       
   287     int rc = parse_version_token(tokens, tokencount);
       
   288 
       
   289     // parse out the rest of the tokens after the version token...
       
   290     while ((rc > 0) && (tokencount > 0))
       
   291     {
       
   292         tokens += rc;
       
   293         tokencount -= rc;
       
   294         rc = parse_token(tokens, tokencount);
       
   295     } // while
       
   296 
       
   297     return ((rc <= 0) || (tokencount > 0)) ? 0 : 1;
       
   298 } // D3D2GLSL_parse
       
   299 
       
   300 
       
   301 int main(int argc, char **argv)
       
   302 {
       
   303     if (argv[1] != NULL)
       
   304     {
       
   305         FILE *io = fopen(argv[1], "rb");
       
   306         if (io != NULL)
       
   307         {
       
   308             uint8 *buf = (uint8 *) malloc(1000000);
       
   309             int rc = fread(buf, 1, 1000000, io);
       
   310             fclose(io);
       
   311             D3D2GLSL_parse(buf, rc);
       
   312             free(buf);
       
   313         } // if
       
   314     } // if
       
   315 
       
   316     return 0;
       
   317 } // main
       
   318 
       
   319 // end of parse.c ...
       
   320