[svn] Renamed file. trunk
authoricculus
Sun, 10 Feb 2008 18:34:26 -0500
branchtrunk
changeset 8 6903b0d7d877
parent 7 18bf77bb8c07
child 9 aea1b254e6a5
[svn] Renamed file.
d3d2glsl.c
parse.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/d3d2glsl.c	Sun Feb 10 18:34:26 2008 -0500
@@ -0,0 +1,731 @@
+/**
+ * d3d2glsl; generate GLSL programs from bytecode of compiled Direct3D shaders.
+ *
+ * Please see the file LICENSE.txt in the source's root directory.
+ *
+ *  This file written by Ryan C. Gordon.
+ */
+
+// Shader bytecode format is described at MSDN:
+//  http://msdn2.microsoft.com/en-us/library/ms800307.aspx
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+typedef unsigned int uint;  // this is a printf() helper. don't use for code.
+typedef uint8_t uint8;
+typedef uint32_t uint32;
+
+// Byteswap magic...
+
+#if ((defined __GNUC__) && (defined __POWERPC__))
+    static inline uint32 SWAP32(uint32 x)
+    {
+        __asm__ __volatile__("lwbrx %0,0,%1" : "=r" (x) : "r" (&x));
+        return x;
+    } // SWAP32
+#elif defined(__POWERPC__)
+    static inline uint32 SWAP32(uint32 x)
+    {
+        return ( (((x) >> 24) & 0x000000FF) | (((x) >>  8) & 0x0000FF00) |
+                 (((x) <<  8) & 0x00FF0000) | (((x) << 24) & 0xFF000000) );
+    } // SWAP32
+#else
+#   define SWAP32(x) (x)
+#endif
+
+
+// Special-case return values from the parsing pipeline...
+
+#define END_OF_STREAM (-2)
+//#define FAIL(x) (-1)
+static int FAIL(const char *reason)
+{
+    printf("%s FAIL.\n", reason);
+    return -1;
+} // FAIL
+
+
+// one function for each opcode...
+
+typedef int (*parse_instruction_function)(const uint32 *argtokens);
+
+static int parse_NOP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_NOP
+
+static int parse_MOV(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_MOV
+
+static int parse_ADD(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_ADD
+
+static int parse_SUB(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_SUB
+
+static int parse_MAD(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_MAD
+
+static int parse_MUL(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_MUL
+
+static int parse_RCP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_RCP
+
+static int parse_RSQ(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_RSQ
+
+static int parse_DP3(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DP3
+
+static int parse_DP4(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DP4
+
+static int parse_MIN(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_MIN
+
+static int parse_MAX(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_MAX
+
+static int parse_SLT(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_SLT
+
+static int parse_SGE(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_SGE
+
+static int parse_EXP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_EXP
+
+static int parse_LOG(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_LOG
+
+static int parse_LIT(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_LIT
+
+static int parse_DST(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DST
+
+static int parse_LRP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_LRP
+
+static int parse_FRC(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_FRC
+
+static int parse_M4X4(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_M4X4
+
+static int parse_M4X3(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_M4X3
+
+static int parse_M3X4(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_M3X4
+
+static int parse_M3X3(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_M3X3
+
+static int parse_M3X2(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_M3X2
+
+static int parse_CALL(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_CALL
+
+static int parse_CALLNZ(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_CALLNZ
+
+static int parse_LOOP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_LOOP
+
+static int parse_RET(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_RET
+
+static int parse_ENDLOOP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_ENDLOOP
+
+static int parse_LABEL(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_LABEL
+
+static int parse_DCL(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DCL
+
+static int parse_POW(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_POW
+
+static int parse_CRS(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_CRS
+
+static int parse_SGN(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_SGN
+
+static int parse_ABS(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_ABS
+
+static int parse_NRM(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_NRM
+
+static int parse_SINCOS(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_SINCOS
+
+static int parse_REP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_REP
+
+static int parse_ENDREP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_ENDREP
+
+static int parse_IF(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_IF
+
+static int parse_IFC(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_IFC
+
+static int parse_ELSE(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_ELSE
+
+static int parse_ENDIF(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_ENDIF
+
+static int parse_BREAK(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_BREAK
+
+static int parse_BREAKC(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_BREAKC
+
+static int parse_MOVA(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_MOVA
+
+static int parse_DEFB(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DEFB
+
+static int parse_DEFI(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DEFI
+
+static int parse_TEXCOORD(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXCOORD
+
+static int parse_TEXKILL(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXKILL
+
+static int parse_TEX(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEX
+
+static int parse_TEXBEM(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXBEM
+
+static int parse_TEXBEML(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXBEML
+
+static int parse_TEXREG2AR(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXREG2AR
+
+static int parse_TEXREG2GB(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXREG2GB
+
+static int parse_TEXM3X2PAD(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X2PAD
+
+static int parse_TEXM3X2TEX(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X2TEX
+
+static int parse_TEXM3X3PAD(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X3PAD
+
+static int parse_TEXM3X3TEX(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X3TEX
+
+static int parse_RESERVED0(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_RESERVED0
+
+static int parse_TEXM3X3SPEC(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X3SPEC
+
+static int parse_TEXM3X3VSPEC(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X3VSPEC
+
+static int parse_EXPP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_EXPP
+
+static int parse_LOGP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_LOGP
+
+static int parse_CND(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_CND
+
+static int parse_DEF(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DEF
+
+static int parse_TEXREG2RGB(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXREG2RGB
+
+static int parse_TEXDP3TEX(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXDP3TEX
+
+static int parse_TEXM3X2DEPTH(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X2DEPTH
+
+static int parse_TEXDP3(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXDP3
+
+static int parse_TEXM3X3(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXM3X3
+
+static int parse_TEXDEPTH(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXDEPTH
+
+static int parse_CMP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_CMP
+
+static int parse_BEM(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_BEM
+
+static int parse_DP2ADD(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DP2ADD
+
+static int parse_DSX(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DSX
+
+static int parse_DSY(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_DSY
+
+static int parse_TEXLDD(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXLDD
+
+static int parse_SETP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_SETP
+
+static int parse_TEXLDL(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_TEXLDL
+
+static int parse_BREAKP(const uint32 *argtokens)
+{
+    return FAIL("unimplemented.");  // !!! FIXME
+} // parse_BREAKP
+
+static int parse_RESERVED(const uint32 *argtokens)
+{
+    return FAIL("Tried to use RESERVED opcode.");
+} // parse_BREAKP
+
+
+
+// Lookup table for instruction opcodes...
+
+typedef struct
+{
+    const char *opcode_string;
+    int arg_tokens;
+    //uint32 shader_requirements;
+    parse_instruction_function parser;
+} Instruction;
+
+// These have to be in the right order! This array is indexed by the value
+//  of the instruction token.
+static Instruction instructions[] = {
+    #define INSTRUCTION(op, args) { #op, args, parse_##op }
+    INSTRUCTION(NOP, 0),
+    INSTRUCTION(MOV, 2),
+    INSTRUCTION(ADD, 3),
+    INSTRUCTION(SUB, 3),
+    INSTRUCTION(MAD, 4),
+    INSTRUCTION(MUL, 3),
+    INSTRUCTION(RCP, 2),
+    INSTRUCTION(RSQ, 2),
+    INSTRUCTION(DP3, 3),
+    INSTRUCTION(DP4, 3),
+    INSTRUCTION(MIN, 3),
+    INSTRUCTION(MAX, 3),
+    INSTRUCTION(SLT, 3),
+    INSTRUCTION(SGE, 3),
+    INSTRUCTION(EXP, 2),
+    INSTRUCTION(LOG, 2),
+    INSTRUCTION(LIT, 2),
+    INSTRUCTION(DST, 3),
+    INSTRUCTION(LRP, 4),
+    INSTRUCTION(FRC, 2),
+    INSTRUCTION(M4X4, 3),
+    INSTRUCTION(M4X3, 3),
+    INSTRUCTION(M3X4, 3),
+    INSTRUCTION(M3X3, 3),
+    INSTRUCTION(M3X2, 3),
+    INSTRUCTION(CALL, 1),
+    INSTRUCTION(CALLNZ, 2),
+    INSTRUCTION(LOOP, 2),
+    INSTRUCTION(RET, 0),
+    INSTRUCTION(ENDLOOP, 0),
+    INSTRUCTION(LABEL, 1),
+    INSTRUCTION(DCL, -1),
+    INSTRUCTION(POW, 3),
+    INSTRUCTION(CRS, 3),
+    INSTRUCTION(SGN, 4),
+    INSTRUCTION(ABS, 2),
+    INSTRUCTION(NRM, 2),
+    INSTRUCTION(SINCOS, 4),
+    INSTRUCTION(REP, 1),
+    INSTRUCTION(ENDREP, 0),
+    INSTRUCTION(IF, 1),
+    INSTRUCTION(IFC, 2),
+    INSTRUCTION(ELSE, 0),
+    INSTRUCTION(ENDIF, 0),
+    INSTRUCTION(BREAK, 0),
+    INSTRUCTION(BREAKC, 2),
+    INSTRUCTION(MOVA, 2),
+    INSTRUCTION(DEFB, 2),
+    INSTRUCTION(DEFI, 5),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(TEXCOORD, -1),
+    INSTRUCTION(TEXKILL, 1),
+    INSTRUCTION(TEX, -1),
+    INSTRUCTION(TEXBEM, 2),
+    INSTRUCTION(TEXBEML, 2),
+    INSTRUCTION(TEXREG2AR, 2),
+    INSTRUCTION(TEXREG2GB, 2),
+    INSTRUCTION(TEXM3X2PAD, 2),
+    INSTRUCTION(TEXM3X2TEX, 2),
+    INSTRUCTION(TEXM3X3PAD, 2),
+    INSTRUCTION(TEXM3X3TEX, 2),
+    INSTRUCTION(RESERVED, 0),
+    INSTRUCTION(TEXM3X3SPEC, 3),
+    INSTRUCTION(TEXM3X3VSPEC, 2),
+    INSTRUCTION(EXPP, 2),
+    INSTRUCTION(LOGP, 2),
+    INSTRUCTION(CND, 4),
+    INSTRUCTION(DEF, 5),
+    INSTRUCTION(TEXREG2RGB, 2),
+    INSTRUCTION(TEXDP3TEX, 2),
+    INSTRUCTION(TEXM3X2DEPTH, 2),
+    INSTRUCTION(TEXDP3, 2),
+    INSTRUCTION(TEXM3X3, 2),
+    INSTRUCTION(TEXDEPTH, 1),
+    INSTRUCTION(CMP, 4),
+    INSTRUCTION(BEM, 3),
+    INSTRUCTION(DP2ADD, 4),
+    INSTRUCTION(DSX, 2),
+    INSTRUCTION(DSY, 2),
+    INSTRUCTION(TEXLDD, 5),
+    INSTRUCTION(SETP, 3),
+    INSTRUCTION(TEXLDL, 3),
+    INSTRUCTION(BREAKP, 1),  // src
+    #undef INSTRUCTION
+};
+
+
+// parse various token types...
+
+static int parse_instruction_token(const uint32 *tokens, const uint32 tokencount)
+{
+    const uint32 token = SWAP32(*tokens);
+    const uint32 opcode = (token & 0xFFFF);
+    const uint32 controls = ((token >> 16) & 0xFF);
+    const uint32 insttoks = ((token >> 24) & 0x0F);
+    const int coissue = (token & 0x40000000) ? 1 : 0;
+    const int predicated = (token & 0x10000000) ? 1 : 0;
+    const Instruction *instruction = &instructions[opcode];
+
+    if ( opcode >= (sizeof (instructions) / sizeof (instructions[0])) )
+        return 0;  // not an instruction token, or just not handled here.
+
+    if ((token & 0x80000000) != 0)
+        return FAIL("instruction token high bit must be zero.");  // so says msdn.
+
+    printf("%s\n", instruction->opcode_string);
+
+    if (instruction->arg_tokens >= 0)
+    {
+        if (instruction->arg_tokens != insttoks)
+            return FAIL("unexpected number of tokens for instruction.");
+        else if (tokencount <= instruction->arg_tokens)
+            return FAIL("not enough tokens left in shader for instruction.");
+    } // if
+
+return insttoks + 1;
+//    return instruction->parser(tokens + 1);
+} // parse_instruction_token
+
+
+static int parse_version_token(const uint32 *tokens, const uint32 tokencount)
+{
+    if (tokencount == 0)
+        return FAIL("Expected version token, got none at all.");
+
+    const uint32 token = SWAP32(*tokens);
+    const uint32 shadertype = ((token >> 16) & 0xFFFF);
+    const uint32 major = ((token >> 8) & 0xFF);
+    const uint32 minor = (token & 0xFF);
+
+    if (shadertype == 0xFFFF)
+        printf("Pixel shader\n");
+    else if (shadertype == 0xFFFE)
+        printf("Vertex shader\n");
+    else
+        return FAIL("geometry shader? Unsupported at the moment.");
+
+    printf("Version %u.%u\n", (uint) major, (uint) minor);
+
+    return 1;  // ate one token.
+} // parse_version_token
+
+
+static int parse_comment_token(const uint32 *tokens, const uint32 tokencount)
+{
+    const uint32 token = SWAP32(*tokens);
+    if ((token & 0xFFFF) != 0xFFFE)
+        return 0;  // not a comment token.
+    else if ((token & 0x80000000) != 0)
+        return FAIL("comment token high bit must be zero.");  // so says msdn.
+
+    const uint32 commenttoks = ((token >> 16) & 0xFFFF);
+    const uint32 commentlen = commenttoks * sizeof (uint32);
+    printf("Comment (%u tokens, %u bytes): ",
+            (uint) commenttoks, (uint) commentlen);
+
+    uint32 i = 0;
+    const char *comment = (const char *) (tokens+1);
+    while (i < commentlen)
+        fputc(comment[i++], stdout);
+
+    printf("\n");
+
+    return commenttoks + 1;  // comment data plus the initial token.
+} // parse_comment_token
+
+
+static int parse_end_token(const uint32 *tokens, const uint32 tokencount)
+{
+    if (SWAP32(*tokens) != 0x0000FFFF)      // end token is always 0x0000FFFF.
+        return 0;  // not us, eat no tokens.
+
+    printf("END\n");
+
+    if (tokencount != 1)  // we _must_ be last. If not: FAIL.
+        FAIL("end token before end of stream");
+
+    return END_OF_STREAM;
+} // parse_end_token
+
+
+static int parse_phase_token(const uint32 *tokens, const uint32 tokencount)
+{
+    if (SWAP32(*tokens) != 0x0000FFFD)    // phase token is always 0x0000FFFD.
+        return 0;  // not us, eat no tokens.
+    return FAIL("not sure what this thing is yet.");
+} // parse_phase_token
+
+
+static int parse_token(const uint32 *tokens, const uint32 tokencount)
+{
+    int rc = 0;
+
+    if (tokencount == 0)
+        return FAIL("unexpected end of shader.");
+
+    if ((rc = parse_comment_token(tokens, tokencount)) != 0)
+        return rc;
+
+    if ((rc = parse_end_token(tokens, tokencount)) != 0)
+        return rc;
+
+    if ((rc = parse_phase_token(tokens, tokencount)) != 0)
+        return rc;
+
+    if ((rc = parse_instruction_token(tokens, tokencount)) != 0)
+        return rc;
+
+    return FAIL("unknown token");
+} // parse_token
+
+
+// API entry point...
+
+int D3D2GLSL_parse(const uint8 *tokenbuf, const uint32 bufsize)
+{
+    const uint32 *tokens = (const uint32 *) tokenbuf;
+    uint32 tokencount = bufsize / sizeof (uint32);
+    int rc = parse_version_token(tokens, tokencount);
+
+    // parse out the rest of the tokens after the version token...
+    while (rc > 0)
+    {
+        tokens += rc;
+        tokencount -= rc;
+        rc = parse_token(tokens, tokencount);
+    } // while
+
+    return (rc == END_OF_STREAM);
+} // D3D2GLSL_parse
+
+// end of parse.c ...
+
--- a/parse.c	Sun Feb 10 18:34:12 2008 -0500
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,731 +0,0 @@
-/**
- * d3d2glsl; generate GLSL programs from bytecode of compiled Direct3D shaders.
- *
- * Please see the file LICENSE.txt in the source's root directory.
- *
- *  This file written by Ryan C. Gordon.
- */
-
-// Shader bytecode format is described at MSDN:
-//  http://msdn2.microsoft.com/en-us/library/ms800307.aspx
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-typedef unsigned int uint;  // this is a printf() helper. don't use for code.
-typedef uint8_t uint8;
-typedef uint32_t uint32;
-
-// Byteswap magic...
-
-#if ((defined __GNUC__) && (defined __POWERPC__))
-    static inline uint32 SWAP32(uint32 x)
-    {
-        __asm__ __volatile__("lwbrx %0,0,%1" : "=r" (x) : "r" (&x));
-        return x;
-    } // SWAP32
-#elif defined(__POWERPC__)
-    static inline uint32 SWAP32(uint32 x)
-    {
-        return ( (((x) >> 24) & 0x000000FF) | (((x) >>  8) & 0x0000FF00) |
-                 (((x) <<  8) & 0x00FF0000) | (((x) << 24) & 0xFF000000) );
-    } // SWAP32
-#else
-#   define SWAP32(x) (x)
-#endif
-
-
-// Special-case return values from the parsing pipeline...
-
-#define END_OF_STREAM (-2)
-//#define FAIL(x) (-1)
-static int FAIL(const char *reason)
-{
-    printf("%s FAIL.\n", reason);
-    return -1;
-} // FAIL
-
-
-// one function for each opcode...
-
-typedef int (*parse_instruction_function)(const uint32 *argtokens);
-
-static int parse_NOP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_NOP
-
-static int parse_MOV(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_MOV
-
-static int parse_ADD(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_ADD
-
-static int parse_SUB(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_SUB
-
-static int parse_MAD(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_MAD
-
-static int parse_MUL(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_MUL
-
-static int parse_RCP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_RCP
-
-static int parse_RSQ(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_RSQ
-
-static int parse_DP3(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DP3
-
-static int parse_DP4(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DP4
-
-static int parse_MIN(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_MIN
-
-static int parse_MAX(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_MAX
-
-static int parse_SLT(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_SLT
-
-static int parse_SGE(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_SGE
-
-static int parse_EXP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_EXP
-
-static int parse_LOG(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_LOG
-
-static int parse_LIT(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_LIT
-
-static int parse_DST(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DST
-
-static int parse_LRP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_LRP
-
-static int parse_FRC(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_FRC
-
-static int parse_M4X4(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_M4X4
-
-static int parse_M4X3(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_M4X3
-
-static int parse_M3X4(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_M3X4
-
-static int parse_M3X3(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_M3X3
-
-static int parse_M3X2(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_M3X2
-
-static int parse_CALL(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_CALL
-
-static int parse_CALLNZ(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_CALLNZ
-
-static int parse_LOOP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_LOOP
-
-static int parse_RET(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_RET
-
-static int parse_ENDLOOP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_ENDLOOP
-
-static int parse_LABEL(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_LABEL
-
-static int parse_DCL(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DCL
-
-static int parse_POW(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_POW
-
-static int parse_CRS(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_CRS
-
-static int parse_SGN(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_SGN
-
-static int parse_ABS(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_ABS
-
-static int parse_NRM(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_NRM
-
-static int parse_SINCOS(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_SINCOS
-
-static int parse_REP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_REP
-
-static int parse_ENDREP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_ENDREP
-
-static int parse_IF(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_IF
-
-static int parse_IFC(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_IFC
-
-static int parse_ELSE(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_ELSE
-
-static int parse_ENDIF(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_ENDIF
-
-static int parse_BREAK(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_BREAK
-
-static int parse_BREAKC(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_BREAKC
-
-static int parse_MOVA(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_MOVA
-
-static int parse_DEFB(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DEFB
-
-static int parse_DEFI(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DEFI
-
-static int parse_TEXCOORD(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXCOORD
-
-static int parse_TEXKILL(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXKILL
-
-static int parse_TEX(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEX
-
-static int parse_TEXBEM(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXBEM
-
-static int parse_TEXBEML(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXBEML
-
-static int parse_TEXREG2AR(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXREG2AR
-
-static int parse_TEXREG2GB(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXREG2GB
-
-static int parse_TEXM3X2PAD(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X2PAD
-
-static int parse_TEXM3X2TEX(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X2TEX
-
-static int parse_TEXM3X3PAD(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X3PAD
-
-static int parse_TEXM3X3TEX(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X3TEX
-
-static int parse_RESERVED0(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_RESERVED0
-
-static int parse_TEXM3X3SPEC(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X3SPEC
-
-static int parse_TEXM3X3VSPEC(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X3VSPEC
-
-static int parse_EXPP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_EXPP
-
-static int parse_LOGP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_LOGP
-
-static int parse_CND(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_CND
-
-static int parse_DEF(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DEF
-
-static int parse_TEXREG2RGB(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXREG2RGB
-
-static int parse_TEXDP3TEX(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXDP3TEX
-
-static int parse_TEXM3X2DEPTH(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X2DEPTH
-
-static int parse_TEXDP3(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXDP3
-
-static int parse_TEXM3X3(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXM3X3
-
-static int parse_TEXDEPTH(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXDEPTH
-
-static int parse_CMP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_CMP
-
-static int parse_BEM(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_BEM
-
-static int parse_DP2ADD(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DP2ADD
-
-static int parse_DSX(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DSX
-
-static int parse_DSY(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_DSY
-
-static int parse_TEXLDD(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXLDD
-
-static int parse_SETP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_SETP
-
-static int parse_TEXLDL(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_TEXLDL
-
-static int parse_BREAKP(const uint32 *argtokens)
-{
-    return FAIL("unimplemented.");  // !!! FIXME
-} // parse_BREAKP
-
-static int parse_RESERVED(const uint32 *argtokens)
-{
-    return FAIL("Tried to use RESERVED opcode.");
-} // parse_BREAKP
-
-
-
-// Lookup table for instruction opcodes...
-
-typedef struct
-{
-    const char *opcode_string;
-    int arg_tokens;
-    //uint32 shader_requirements;
-    parse_instruction_function parser;
-} Instruction;
-
-// These have to be in the right order! This array is indexed by the value
-//  of the instruction token.
-static Instruction instructions[] = {
-    #define INSTRUCTION(op, args) { #op, args, parse_##op }
-    INSTRUCTION(NOP, 0),
-    INSTRUCTION(MOV, 2),
-    INSTRUCTION(ADD, 3),
-    INSTRUCTION(SUB, 3),
-    INSTRUCTION(MAD, 4),
-    INSTRUCTION(MUL, 3),
-    INSTRUCTION(RCP, 2),
-    INSTRUCTION(RSQ, 2),
-    INSTRUCTION(DP3, 3),
-    INSTRUCTION(DP4, 3),
-    INSTRUCTION(MIN, 3),
-    INSTRUCTION(MAX, 3),
-    INSTRUCTION(SLT, 3),
-    INSTRUCTION(SGE, 3),
-    INSTRUCTION(EXP, 2),
-    INSTRUCTION(LOG, 2),
-    INSTRUCTION(LIT, 2),
-    INSTRUCTION(DST, 3),
-    INSTRUCTION(LRP, 4),
-    INSTRUCTION(FRC, 2),
-    INSTRUCTION(M4X4, 3),
-    INSTRUCTION(M4X3, 3),
-    INSTRUCTION(M3X4, 3),
-    INSTRUCTION(M3X3, 3),
-    INSTRUCTION(M3X2, 3),
-    INSTRUCTION(CALL, 1),
-    INSTRUCTION(CALLNZ, 2),
-    INSTRUCTION(LOOP, 2),
-    INSTRUCTION(RET, 0),
-    INSTRUCTION(ENDLOOP, 0),
-    INSTRUCTION(LABEL, 1),
-    INSTRUCTION(DCL, -1),
-    INSTRUCTION(POW, 3),
-    INSTRUCTION(CRS, 3),
-    INSTRUCTION(SGN, 4),
-    INSTRUCTION(ABS, 2),
-    INSTRUCTION(NRM, 2),
-    INSTRUCTION(SINCOS, 4),
-    INSTRUCTION(REP, 1),
-    INSTRUCTION(ENDREP, 0),
-    INSTRUCTION(IF, 1),
-    INSTRUCTION(IFC, 2),
-    INSTRUCTION(ELSE, 0),
-    INSTRUCTION(ENDIF, 0),
-    INSTRUCTION(BREAK, 0),
-    INSTRUCTION(BREAKC, 2),
-    INSTRUCTION(MOVA, 2),
-    INSTRUCTION(DEFB, 2),
-    INSTRUCTION(DEFI, 5),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(TEXCOORD, -1),
-    INSTRUCTION(TEXKILL, 1),
-    INSTRUCTION(TEX, -1),
-    INSTRUCTION(TEXBEM, 2),
-    INSTRUCTION(TEXBEML, 2),
-    INSTRUCTION(TEXREG2AR, 2),
-    INSTRUCTION(TEXREG2GB, 2),
-    INSTRUCTION(TEXM3X2PAD, 2),
-    INSTRUCTION(TEXM3X2TEX, 2),
-    INSTRUCTION(TEXM3X3PAD, 2),
-    INSTRUCTION(TEXM3X3TEX, 2),
-    INSTRUCTION(RESERVED, 0),
-    INSTRUCTION(TEXM3X3SPEC, 3),
-    INSTRUCTION(TEXM3X3VSPEC, 2),
-    INSTRUCTION(EXPP, 2),
-    INSTRUCTION(LOGP, 2),
-    INSTRUCTION(CND, 4),
-    INSTRUCTION(DEF, 5),
-    INSTRUCTION(TEXREG2RGB, 2),
-    INSTRUCTION(TEXDP3TEX, 2),
-    INSTRUCTION(TEXM3X2DEPTH, 2),
-    INSTRUCTION(TEXDP3, 2),
-    INSTRUCTION(TEXM3X3, 2),
-    INSTRUCTION(TEXDEPTH, 1),
-    INSTRUCTION(CMP, 4),
-    INSTRUCTION(BEM, 3),
-    INSTRUCTION(DP2ADD, 4),
-    INSTRUCTION(DSX, 2),
-    INSTRUCTION(DSY, 2),
-    INSTRUCTION(TEXLDD, 5),
-    INSTRUCTION(SETP, 3),
-    INSTRUCTION(TEXLDL, 3),
-    INSTRUCTION(BREAKP, 1),  // src
-    #undef INSTRUCTION
-};
-
-
-// parse various token types...
-
-static int parse_instruction_token(const uint32 *tokens, const uint32 tokencount)
-{
-    const uint32 token = SWAP32(*tokens);
-    const uint32 opcode = (token & 0xFFFF);
-    const uint32 controls = ((token >> 16) & 0xFF);
-    const uint32 insttoks = ((token >> 24) & 0x0F);
-    const int coissue = (token & 0x40000000) ? 1 : 0;
-    const int predicated = (token & 0x10000000) ? 1 : 0;
-    const Instruction *instruction = &instructions[opcode];
-
-    if ( opcode >= (sizeof (instructions) / sizeof (instructions[0])) )
-        return 0;  // not an instruction token, or just not handled here.
-
-    if ((token & 0x80000000) != 0)
-        return FAIL("instruction token high bit must be zero.");  // so says msdn.
-
-    printf("%s\n", instruction->opcode_string);
-
-    if (instruction->arg_tokens >= 0)
-    {
-        if (instruction->arg_tokens != insttoks)
-            return FAIL("unexpected number of tokens for instruction.");
-        else if (tokencount <= instruction->arg_tokens)
-            return FAIL("not enough tokens left in shader for instruction.");
-    } // if
-
-return insttoks + 1;
-//    return instruction->parser(tokens + 1);
-} // parse_instruction_token
-
-
-static int parse_version_token(const uint32 *tokens, const uint32 tokencount)
-{
-    if (tokencount == 0)
-        return FAIL("Expected version token, got none at all.");
-
-    const uint32 token = SWAP32(*tokens);
-    const uint32 shadertype = ((token >> 16) & 0xFFFF);
-    const uint32 major = ((token >> 8) & 0xFF);
-    const uint32 minor = (token & 0xFF);
-
-    if (shadertype == 0xFFFF)
-        printf("Pixel shader\n");
-    else if (shadertype == 0xFFFE)
-        printf("Vertex shader\n");
-    else
-        return FAIL("geometry shader? Unsupported at the moment.");
-
-    printf("Version %u.%u\n", (uint) major, (uint) minor);
-
-    return 1;  // ate one token.
-} // parse_version_token
-
-
-static int parse_comment_token(const uint32 *tokens, const uint32 tokencount)
-{
-    const uint32 token = SWAP32(*tokens);
-    if ((token & 0xFFFF) != 0xFFFE)
-        return 0;  // not a comment token.
-    else if ((token & 0x80000000) != 0)
-        return FAIL("comment token high bit must be zero.");  // so says msdn.
-
-    const uint32 commenttoks = ((token >> 16) & 0xFFFF);
-    const uint32 commentlen = commenttoks * sizeof (uint32);
-    printf("Comment (%u tokens, %u bytes): ",
-            (uint) commenttoks, (uint) commentlen);
-
-    uint32 i = 0;
-    const char *comment = (const char *) (tokens+1);
-    while (i < commentlen)
-        fputc(comment[i++], stdout);
-
-    printf("\n");
-
-    return commenttoks + 1;  // comment data plus the initial token.
-} // parse_comment_token
-
-
-static int parse_end_token(const uint32 *tokens, const uint32 tokencount)
-{
-    if (SWAP32(*tokens) != 0x0000FFFF)      // end token is always 0x0000FFFF.
-        return 0;  // not us, eat no tokens.
-
-    printf("END\n");
-
-    if (tokencount != 1)  // we _must_ be last. If not: FAIL.
-        FAIL("end token before end of stream");
-
-    return END_OF_STREAM;
-} // parse_end_token
-
-
-static int parse_phase_token(const uint32 *tokens, const uint32 tokencount)
-{
-    if (SWAP32(*tokens) != 0x0000FFFD)    // phase token is always 0x0000FFFD.
-        return 0;  // not us, eat no tokens.
-    return FAIL("not sure what this thing is yet.");
-} // parse_phase_token
-
-
-static int parse_token(const uint32 *tokens, const uint32 tokencount)
-{
-    int rc = 0;
-
-    if (tokencount == 0)
-        return FAIL("unexpected end of shader.");
-
-    if ((rc = parse_comment_token(tokens, tokencount)) != 0)
-        return rc;
-
-    if ((rc = parse_end_token(tokens, tokencount)) != 0)
-        return rc;
-
-    if ((rc = parse_phase_token(tokens, tokencount)) != 0)
-        return rc;
-
-    if ((rc = parse_instruction_token(tokens, tokencount)) != 0)
-        return rc;
-
-    return FAIL("unknown token");
-} // parse_token
-
-
-// API entry point...
-
-int D3D2GLSL_parse(const uint8 *tokenbuf, const uint32 bufsize)
-{
-    const uint32 *tokens = (const uint32 *) tokenbuf;
-    uint32 tokencount = bufsize / sizeof (uint32);
-    int rc = parse_version_token(tokens, tokencount);
-
-    // parse out the rest of the tokens after the version token...
-    while (rc > 0)
-    {
-        tokens += rc;
-        tokencount -= rc;
-        rc = parse_token(tokens, tokencount);
-    } // while
-
-    return (rc == END_OF_STREAM);
-} // D3D2GLSL_parse
-
-// end of parse.c ...
-