[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