[PATCH 4/5] d3dx9_36: Added array and structure name parsing to constant tables (try 3)
Travis Athougies
iammisc at gmail.com
Thu Jul 14 16:06:51 CDT 2011
---
dlls/d3dx9_36/shader.c | 117 ++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 108 insertions(+), 9 deletions(-)
diff --git a/dlls/d3dx9_36/shader.c b/dlls/d3dx9_36/shader.c
index c0793a3..1906547 100644
--- a/dlls/d3dx9_36/shader.c
+++ b/dlls/d3dx9_36/shader.c
@@ -650,29 +650,120 @@ static DWORD calc_bytes(D3DXCONSTANT_DESC *desc)
return 4 * desc->Elements * desc->Rows * desc->Columns;
}
+static ctab_constant *is_valid_sub_constant(ctab_constant *base, D3DXHANDLE parameter)
+{
+ UINT i;
+ ctab_constant *c;
+
+ if (base->member_count == 0)
+ return NULL;
+
+ for (i = 0; i < base->member_count; i++)
+ {
+ if (((ctab_constant *)parameter) == &base->members[i])
+ return (ctab_constant *)parameter;
+
+ c = is_valid_sub_constant(&base->members[i], parameter);
+ if (c) return c;
+ }
+
+ return NULL;
+}
+
static ctab_constant *is_valid_constant(ID3DXConstantTableImpl *This, D3DXHANDLE parameter)
{
UINT i;
+ ctab_constant *c;
for (i = 0; i < This->desc.Constants; i++)
+ {
if ((ctab_constant *)parameter == &This->constants[i])
return (ctab_constant *)parameter;
+ c = is_valid_sub_constant(&This->constants[i], parameter);
+ if (c) return c;
+ }
+
return NULL;
}
+static ctab_constant *lookup_constant_element(ID3DXConstantTableImpl *This, ctab_constant *c, UINT index)
+{
+ if (index >= c->desc.Elements || index >= c->member_count || !c->members)
+ return NULL;
+
+ return &c->members[index];
+}
+
static ctab_constant *lookup_constant_by_name(ID3DXConstantTableImpl *This, ctab_constant *c, LPCSTR name)
{
- UINT i;
+ ctab_constant *members;
+ char *end_name, *begin_index, *end_index;
+ UINT name_length, member_count, i;
+ INT index;
TRACE("(%p, %p, %s)\n", This, c, name);
+ end_name = strchr(name, '.');
+ if (end_name)
+ name_length = end_name - name;
+ else
+ name_length = strlen(name);
+
+ begin_index = strchr(name, '[');
+ if (begin_index && (begin_index - name) < name_length)
+ {
+ index = strtol(begin_index + 1, &end_index, 10);
+ if (*end_index != ']')
+ {
+ TRACE("Invalid index in name: %s\n", name);
+ return NULL;
+ }
+ name_length = begin_index - name;
+ } else
+ index = -1;
+
if (c)
- FIXME("Only top level constant supported\n");
+ {
+ if (c->desc.Class != D3DXPC_STRUCT)
+ {
+ TRACE("Can't get %s from under %s: %s is not a structure\n", name, c->desc.Name, c->desc.Name);
+ return NULL;
+ }
- for (i = 0; i < This->desc.Constants; i++)
- if (!strcmp(This->constants[i].desc.Name, name))
- return &This->constants[i];
+ member_count = c->desc.StructMembers;
+ members = c->members;
+ }
+ else if (!c)
+ {
+ member_count = This->desc.Constants;
+ members = This->constants;
+ }
+
+ for (i = 0; i < member_count; i++)
+ {
+ if (strlen(members[i].desc.Name) == name_length && memcmp(members[i].desc.Name, name, name_length) == 0)
+ {
+ if (index == -1)
+ {
+ if (end_name)
+ return lookup_constant_by_name(This, &members[i], end_name + 1);
+ else
+ return &members[i];
+ }
+ else
+ {
+ ctab_constant *elem = lookup_constant_element(This, &members[i], index);
+ if (!elem)
+ return NULL;
+
+ if (end_name)
+ return lookup_constant_by_name(This, elem, end_name + 1);
+ else
+ return elem;
+ }
+ }
+ }
return NULL;
}
@@ -823,7 +914,18 @@ static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable*
TRACE("(%p)->(%p, %d)\n", This, constant, index);
- if (!constant)
+ if (is_valid_constant(This, constant))
+ {
+ ctab_constant *c = (ctab_constant *)constant;
+
+ if (index >= c->member_count)
+ return NULL;
+ else if (c->desc.Class != D3DXPC_STRUCT)
+ return NULL;
+
+ return (D3DXHANDLE)(DWORD_PTR)&c->members[index];
+ }
+ else if (!constant)
{
if (index >= This->desc.Constants)
return NULL;
@@ -831,10 +933,7 @@ static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstant(ID3DXConstantTable*
return (D3DXHANDLE)&This->constants[index];
}
else
- {
- FIXME("Only top level constant supported\n");
return NULL;
- }
}
static D3DXHANDLE WINAPI ID3DXConstantTableImpl_GetConstantByName(ID3DXConstantTable* iface, D3DXHANDLE constant, LPCSTR name)
--
1.6.4.4
More information about the wine-patches
mailing list