Skip to content

Commit

Permalink
Filled in and fixed some stuff in the Effect parser.
Browse files Browse the repository at this point in the history
This code is all nasty, because I'm planning to rewrite it later.
  • Loading branch information
icculus committed May 31, 2011
1 parent 31cbb0f commit 2d3e8a4
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 33 deletions.
18 changes: 18 additions & 0 deletions mojoshader.h
Expand Up @@ -699,6 +699,12 @@ void MOJOSHADER_freeParseData(const MOJOSHADER_parseData *data);

/* Effects interface... */ /* !!! FIXME: THIS API IS NOT STABLE YET! */

typedef struct MOJOSHADER_effectParam
{
const char *name;
const char *semantic;
} MOJOSHADER_effectParam;

typedef struct MOJOSHADER_effectState
{
unsigned int type;
Expand Down Expand Up @@ -754,6 +760,18 @@ typedef struct MOJOSHADER_effect
*/
const char *profile;

/*
* The number of params pointed to by (params).
*/
int param_count;

/*
* (param_count) elements of data that specify parameter bind points for
* this effect.
* This can be NULL on error or if (param_count) is zero.
*/
MOJOSHADER_effectParam *params;

/*
* The number of elements pointed to by (techniques).
*/
Expand Down
138 changes: 105 additions & 33 deletions mojoshader_effects.c
Expand Up @@ -217,11 +217,14 @@ const MOJOSHADER_effect *MOJOSHADER_parseEffect(const char *profile,
if (len < 8)
goto parseEffect_unexpectedEOF;

const uint8 *base = NULL;
if (readui32(&ptr, &len) != 0xFEFF0901) // !!! FIXME: is this always magic?
goto parseEffect_notAnEffectsFile;
else
{
const uint32 offset = readui32(&ptr, &len);
base = ptr;
//printf("base offset == %u\n", offset);
if (offset > len)
goto parseEffect_unexpectedEOF;
ptr += offset;
Expand All @@ -236,27 +239,61 @@ const MOJOSHADER_effect *MOJOSHADER_parseEffect(const char *profile,
const uint32 numparams = readui32(&ptr, &len);
const uint32 numtechniques = readui32(&ptr, &len);

readui32(&ptr, &len); // !!! FIXME: there are 8 unknown bytes here.
readui32(&ptr, &len);
readui32(&ptr, &len); // !!! FIXME: there are 8 unknown bytes here. Annotations?
/*const uint32 numobjects = */ readui32(&ptr, &len);

for (i = 0; i < numparams; i++)
if (numparams > 0)
{
if (len < 16)
goto parseEffect_unexpectedEOF;
siz = sizeof (MOJOSHADER_effectParam) * numparams;
retval->params = (MOJOSHADER_effectParam *) m(siz, d);
if (retval->params == NULL)
goto parseEffect_outOfMemory;
memset(retval->params, '\0', siz);

/*const uint32 startoffset = */ readui32(&ptr, &len);
/*const uint32 endoffset = */ readui32(&ptr, &len);
readui32(&ptr, &len); // !!! FIXME: don't know what this is.
const uint32 numannos = readui32(&ptr, &len);
for (j = 0; j < numannos; j++)
retval->param_count = numparams;

for (i = 0; i < numparams; i++)
{
if (len < 8)
if (len < 16)
goto parseEffect_unexpectedEOF;
// !!! FIXME: parse annotations.
readui32(&ptr, &len);
readui32(&ptr, &len);

const uint32 typeoffset = readui32(&ptr, &len);
const uint32 valoffset = readui32(&ptr, &len);
const uint32 flags = readui32(&ptr, &len);
const uint32 numannos = readui32(&ptr, &len);
for (j = 0; j < numannos; j++)
{
if (len < 8)
goto parseEffect_unexpectedEOF;
// !!! FIXME: parse annotations.
readui32(&ptr, &len);
readui32(&ptr, &len);
} // for

const uint8 *typeptr = base + typeoffset;
unsigned int typelen = 9999999; // !!! FIXME
const uint32 paramtype = readui32(&typeptr, &typelen);
const uint32 paramclass = readui32(&typeptr, &typelen);
const uint32 paramname = readui32(&typeptr, &typelen);
const uint32 paramsemantic = readui32(&typeptr, &typelen);

// !!! FIXME: sanity checks!
const char *namestr = ((const char *) base) + paramname;
const char *semstr = ((const char *) base) + paramsemantic;
uint32 len;
char *strptr;
len = *((const uint32 *) namestr);
strptr = (char *) m(len + 1, d);
memcpy(strptr, namestr + 4, len);
strptr[len] = '\0';
retval->params[i].name = strptr;
len = *((const uint32 *) semstr);
strptr = (char *) m(len + 1, d);
memcpy(strptr, semstr + 4, len);
strptr[len] = '\0';
retval->params[i].semantic = strptr;
} // for
} // for
} // if

uint32 numshaders = 0; // we'll calculate this later.

Expand All @@ -279,23 +316,37 @@ const MOJOSHADER_effect *MOJOSHADER_parseEffect(const char *profile,

MOJOSHADER_effectTechnique *technique = &retval->techniques[i];

// !!! FIXME: is this always 12?
const uint32 nameoffset = readui32(&ptr, &len) + 12;
readui32(&ptr, &len); // !!! FIXME: don't know what this field does.
const uint32 nameoffset = readui32(&ptr, &len);
const uint32 numannos = readui32(&ptr, &len);
const uint32 numpasses = readui32(&ptr, &len);

if (nameoffset >= _len)
goto parseEffect_unexpectedEOF;

if (numpasses > 0)
if (numannos > 0)
{
// !!! FIXME: verify this doesn't go past EOF looking for a null.
siz = strlen(((const char *) buf) + nameoffset) + 1;
technique->name = (char *) m(siz, d);
if (technique->name == NULL)
goto parseEffect_outOfMemory;
strcpy((char *) technique->name, ((const char *) buf) + nameoffset);
// !!! FIXME: expose these to the caller?
for (j = 0; j < numannos; j++)
{
if (len < 8)
goto parseEffect_unexpectedEOF;
readui32(&ptr, &len); // typedef offset
readui32(&ptr, &len); // value offset
} // for
} // if

// !!! FIXME: verify this doesn't go past EOF looking for a null.
{
const char *namestr = ((char *) base) + nameoffset;
uint32 len = *((const uint32 *) namestr);
char *strptr = (char *) m(len + 1, d);
memcpy(strptr, namestr + 4, len);
strptr[len] = '\0';
technique->name = strptr;
}

if (numpasses > 0)
{
technique->pass_count = numpasses;

siz = sizeof (MOJOSHADER_effectPass) * numpasses;
Expand All @@ -311,20 +362,34 @@ const MOJOSHADER_effect *MOJOSHADER_parseEffect(const char *profile,

MOJOSHADER_effectPass *pass = &technique->passes[j];

// !!! FIXME: is this always 12?
const uint32 passnameoffset = readui32(&ptr, &len) + 12;
readui32(&ptr, &len); // !!! FIXME: don't know what this field does.
const uint32 passnameoffset = readui32(&ptr, &len);
const uint32 numannos = readui32(&ptr, &len);
const uint32 numstates = readui32(&ptr, &len);

if (passnameoffset >= _len)
goto parseEffect_unexpectedEOF;

// !!! FIXME: verify this doesn't go past EOF looking for a null.
siz = strlen(((const char *) buf) + passnameoffset) + 1;
pass->name = (char *) m(siz, d);
if (pass->name == NULL)
goto parseEffect_outOfMemory;
strcpy((char *) pass->name, ((const char *) buf) + passnameoffset);
{
const char *namestr = ((char *) base) + passnameoffset;
uint32 len = *((const uint32 *) namestr);
char *strptr = (char *) m(len + 1, d);
memcpy(strptr, namestr + 4, len);
strptr[len] = '\0';
pass->name = strptr;
}

if (numannos > 0)
{
for (k = 0; k < numannos; k++)
{
if (len < 8)
goto parseEffect_unexpectedEOF;
// !!! FIXME: do something with this.
readui32(&ptr, &len);
readui32(&ptr, &len);
} // for
} // if

if (numstates > 0)
{
Expand Down Expand Up @@ -503,6 +568,13 @@ void MOJOSHADER_freeEffect(const MOJOSHADER_effect *_effect)

f((void *) effect->profile, d);

for (i = 0; i < effect->param_count; i++)
{
f((void *) effect->params[i].name, d);
f((void *) effect->params[i].semantic, d);
} // for
f(effect->params, d);

for (i = 0; i < effect->technique_count; i++)
{
MOJOSHADER_effectTechnique *technique = &effect->techniques[i];
Expand Down
9 changes: 9 additions & 0 deletions utils/testparse.c
Expand Up @@ -400,6 +400,15 @@ static void print_effect(const char *fname, const MOJOSHADER_effect *effect,
const MOJOSHADER_effectTechnique *technique = effect->techniques;
const MOJOSHADER_effectTexture *texture = effect->textures;
const MOJOSHADER_effectShader *shader = effect->shaders;
const MOJOSHADER_effectParam *param = effect->params;

for (i = 0; i < effect->param_count; i++, param++)
{
INDENT();
printf("PARAM #%d '%s' -> '%s'\n", i, param->name, param->semantic);
} // for

printf("\n");

for (i = 0; i < effect->technique_count; i++, technique++)
{
Expand Down

0 comments on commit 2d3e8a4

Please sign in to comment.