~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/d3dx9_36/effect.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Copyright 2010 Christian Costa
  3  * Copyright 2011 Rico Schüller
  4  *
  5  * This library is free software; you can redistribute it and/or
  6  * modify it under the terms of the GNU Lesser General Public
  7  * License as published by the Free Software Foundation; either
  8  * version 2.1 of the License, or (at your option) any later version.
  9  *
 10  * This library is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 13  * Lesser General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU Lesser General Public
 16  * License along with this library; if not, write to the Free Software
 17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 18  */
 19 
 20 #include "config.h"
 21 #include "wine/port.h"
 22 #define NONAMELESSUNION
 23 #include "wine/debug.h"
 24 #include "wine/unicode.h"
 25 
 26 #include "windef.h"
 27 #include "wingdi.h"
 28 #include "d3dx9_36_private.h"
 29 
 30 /* Constants for special INT/FLOAT conversation */
 31 #define INT_FLOAT_MULTI 255.0f
 32 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
 33 
 34 WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
 35 
 36 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl;
 37 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl;
 38 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl;
 39 
 40 enum STATE_CLASS
 41 {
 42     SC_LIGHTENABLE,
 43     SC_FVF,
 44     SC_LIGHT,
 45     SC_MATERIAL,
 46     SC_NPATCHMODE,
 47     SC_PIXELSHADER,
 48     SC_RENDERSTATE,
 49     SC_SETSAMPLER,
 50     SC_SAMPLERSTATE,
 51     SC_TEXTURE,
 52     SC_TEXTURESTAGE,
 53     SC_TRANSFORM,
 54     SC_VERTEXSHADER,
 55     SC_SHADERCONST,
 56     SC_UNKNOWN,
 57 };
 58 
 59 enum MATERIAL_TYPE
 60 {
 61     MT_DIFFUSE,
 62     MT_AMBIENT,
 63     MT_SPECULAR,
 64     MT_EMISSIVE,
 65     MT_POWER,
 66 };
 67 
 68 enum LIGHT_TYPE
 69 {
 70     LT_TYPE,
 71     LT_DIFFUSE,
 72     LT_SPECULAR,
 73     LT_AMBIENT,
 74     LT_POSITION,
 75     LT_DIRECTION,
 76     LT_RANGE,
 77     LT_FALLOFF,
 78     LT_ATTENUATION0,
 79     LT_ATTENUATION1,
 80     LT_ATTENUATION2,
 81     LT_THETA,
 82     LT_PHI,
 83 };
 84 
 85 enum SHADER_CONSTANT_TYPE
 86 {
 87     SCT_VSFLOAT,
 88     SCT_VSBOOL,
 89     SCT_VSINT,
 90     SCT_PSFLOAT,
 91     SCT_PSBOOL,
 92     SCT_PSINT,
 93 };
 94 
 95 enum STATE_TYPE
 96 {
 97     ST_CONSTANT,
 98     ST_PARAMETER,
 99     ST_FXLC,
100 };
101 
102 struct d3dx_parameter
103 {
104     char *name;
105     char *semantic;
106     void *data;
107     D3DXPARAMETER_CLASS class;
108     D3DXPARAMETER_TYPE  type;
109     UINT rows;
110     UINT columns;
111     UINT element_count;
112     UINT annotation_count;
113     UINT member_count;
114     DWORD flags;
115     UINT bytes;
116 
117     D3DXHANDLE *annotation_handles;
118     D3DXHANDLE *member_handles;
119 };
120 
121 struct d3dx_state
122 {
123     UINT operation;
124     UINT index;
125     enum STATE_TYPE type;
126     D3DXHANDLE parameter;
127 };
128 
129 struct d3dx_sampler
130 {
131     UINT state_count;
132     struct d3dx_state *states;
133 };
134 
135 struct d3dx_pass
136 {
137     char *name;
138     UINT state_count;
139     UINT annotation_count;
140 
141     struct d3dx_state *states;
142     D3DXHANDLE *annotation_handles;
143 };
144 
145 struct d3dx_technique
146 {
147     char *name;
148     UINT pass_count;
149     UINT annotation_count;
150 
151     D3DXHANDLE *annotation_handles;
152     D3DXHANDLE *pass_handles;
153 };
154 
155 struct ID3DXBaseEffectImpl
156 {
157     ID3DXBaseEffect ID3DXBaseEffect_iface;
158     LONG ref;
159 
160     struct ID3DXEffectImpl *effect;
161 
162     UINT parameter_count;
163     UINT technique_count;
164 
165     D3DXHANDLE *parameter_handles;
166     D3DXHANDLE *technique_handles;
167 };
168 
169 struct ID3DXEffectImpl
170 {
171     ID3DXEffect ID3DXEffect_iface;
172     LONG ref;
173 
174     LPD3DXEFFECTSTATEMANAGER manager;
175     LPDIRECT3DDEVICE9 device;
176     LPD3DXEFFECTPOOL pool;
177     D3DXHANDLE active_technique;
178     D3DXHANDLE active_pass;
179 
180     ID3DXBaseEffect *base_effect;
181 };
182 
183 struct ID3DXEffectCompilerImpl
184 {
185     ID3DXEffectCompiler ID3DXEffectCompiler_iface;
186     LONG ref;
187 
188     ID3DXBaseEffect *base_effect;
189 };
190 
191 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
192         struct d3dx_parameter *parameter, LPCSTR name);
193 static struct d3dx_parameter *get_parameter_annotation_by_name(struct d3dx_parameter *parameter, LPCSTR name);
194 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects);
195 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st);
196 
197 static const struct
198 {
199     enum STATE_CLASS class;
200     UINT op;
201     LPCSTR name;
202 }
203 state_table[] =
204 {
205     /* Render sates */
206     {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
207     {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
208     {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
209     {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
210     {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
211     {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
212     {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
213     {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
214     {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
215     {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
216     {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
217     {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
218     {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
219     {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
220     {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
221     {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
222     {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
223     {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
224     {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
225     {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
226     {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
227     {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
228     {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
229     {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
230     {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
231     {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
232     {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
233     {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
234     {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
235     {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
236     {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
237     {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
238     {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
239     {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
240     {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
241     {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
242     {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
243     {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
244     {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
245     {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
246     {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
247     {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
248     {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
249     {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
250     {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
251     {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
252     {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
253     {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
254     {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
255     {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
256     {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
257     {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
258     {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
259     {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
260     {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
261     {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
262     {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
263     {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
264     {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
265     {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
266     {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
267     {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
268     {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
269     {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
270     {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
271     {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
272     {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
273     {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
274     {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
275     {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
276     {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
277     {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
278     {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
279     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
280     {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
281     {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
282     {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
283     {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
284     {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
285     {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
286     {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
287     {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
288     {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
289     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
290     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
291     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
292     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
293     {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
294     {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
295     {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
296     {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
297     {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
298     {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
299     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
300     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
301     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
302     {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
303     {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
304     {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
305     {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
306     {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
307     {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
308     {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
309     /* Texture stages */
310     {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
311     {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
312     {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
313     {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
314     {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
315     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
316     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
317     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
318     {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
319     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
320     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
321     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
322     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
323     {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
324     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
325     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
326     {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
327     /* */
328     {SC_UNKNOWN, 0, "UNKNOWN"},
329     /* NPatchMode */
330     {SC_NPATCHMODE, 0, "NPatchMode"},
331     /* */
332     {SC_UNKNOWN, 0, "UNKNOWN"},
333     /* Transform */
334     {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
335     {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
336     {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
337     {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
338     /* Material */
339     {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
340     {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
341     {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
342     {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
343     {SC_MATERIAL, MT_POWER, "MaterialPower"},
344     /* Light */
345     {SC_LIGHT, LT_TYPE, "LightType"},
346     {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
347     {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
348     {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
349     {SC_LIGHT, LT_POSITION, "LightPosition"},
350     {SC_LIGHT, LT_DIRECTION, "LightDirection"},
351     {SC_LIGHT, LT_RANGE, "LightRange"},
352     {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
353     {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
354     {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
355     {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
356     {SC_LIGHT, LT_THETA, "LightTheta"},
357     {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
358     /* Ligthenable */
359     {SC_LIGHTENABLE, 0, "LightEnable"},
360     /* Vertexshader */
361     {SC_VERTEXSHADER, 0, "Vertexshader"},
362     /* Pixelshader */
363     {SC_PIXELSHADER, 0, "Pixelshader"},
364     /* Shader constants */
365     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
366     {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
367     {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
368     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
369     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
370     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
371     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
372     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
373     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
374     {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
375     {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
376     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
377     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
378     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
379     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
380     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
381     /* Texture */
382     {SC_TEXTURE, 0, "Texture"},
383     /* Sampler states */
384     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
385     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
386     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
387     {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
388     {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
389     {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
390     {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
391     {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
392     {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
393     {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
394     {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
395     {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
396     {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
397     /* Set sampler */
398     {SC_SETSAMPLER, 0, "Sampler"},
399 };
400 
401 static inline void read_dword(const char **ptr, DWORD *d)
402 {
403     memcpy(d, *ptr, sizeof(*d));
404     *ptr += sizeof(*d);
405 }
406 
407 static void skip_dword_unknown(const char **ptr, unsigned int count)
408 {
409     unsigned int i;
410     DWORD d;
411 
412     FIXME("Skipping %u unknown DWORDs:\n", count);
413     for (i = 0; i < count; ++i)
414     {
415         read_dword(ptr, &d);
416         FIXME("\t0x%08x\n", d);
417     }
418 }
419 
420 static inline struct d3dx_parameter *get_parameter_struct(D3DXHANDLE handle)
421 {
422     return (struct d3dx_parameter *) handle;
423 }
424 
425 static inline struct d3dx_pass *get_pass_struct(D3DXHANDLE handle)
426 {
427     return (struct d3dx_pass *) handle;
428 }
429 
430 static inline struct d3dx_technique *get_technique_struct(D3DXHANDLE handle)
431 {
432     return (struct d3dx_technique *) handle;
433 }
434 
435 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
436 {
437     return (D3DXHANDLE) parameter;
438 }
439 
440 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
441 {
442     return (D3DXHANDLE) technique;
443 }
444 
445 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
446 {
447     return (D3DXHANDLE) pass;
448 }
449 
450 static struct d3dx_technique *is_valid_technique(struct ID3DXBaseEffectImpl *base, D3DXHANDLE technique)
451 {
452     unsigned int i;
453 
454     for (i = 0; i < base->technique_count; ++i)
455     {
456         if (base->technique_handles[i] == technique)
457         {
458             return get_technique_struct(technique);
459         }
460     }
461 
462     return NULL;
463 }
464 
465 static struct d3dx_pass *is_valid_pass(struct ID3DXBaseEffectImpl *base, D3DXHANDLE pass)
466 {
467     unsigned int i, k;
468 
469     for (i = 0; i < base->technique_count; ++i)
470     {
471         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
472 
473         for (k = 0; k < technique->pass_count; ++k)
474         {
475             if (technique->pass_handles[k] == pass)
476             {
477                 return get_pass_struct(pass);
478             }
479         }
480     }
481 
482     return NULL;
483 }
484 
485 static struct d3dx_parameter *is_valid_sub_parameter(struct d3dx_parameter *param, D3DXHANDLE parameter)
486 {
487     unsigned int i, count;
488     struct d3dx_parameter *p;
489 
490     for (i = 0; i < param->annotation_count; ++i)
491     {
492         if (param->annotation_handles[i] == parameter)
493         {
494             return get_parameter_struct(parameter);
495         }
496 
497         p = is_valid_sub_parameter(get_parameter_struct(param->annotation_handles[i]), parameter);
498         if (p) return p;
499     }
500 
501     if (param->element_count) count = param->element_count;
502     else count = param->member_count;
503 
504     for (i = 0; i < count; ++i)
505     {
506         if (param->member_handles[i] == parameter)
507         {
508             return get_parameter_struct(parameter);
509         }
510 
511         p = is_valid_sub_parameter(get_parameter_struct(param->member_handles[i]), parameter);
512         if (p) return p;
513     }
514 
515     return NULL;
516 }
517 
518 static struct d3dx_parameter *is_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
519 {
520     unsigned int i, k, m;
521     struct d3dx_parameter *p;
522 
523     for (i = 0; i < base->parameter_count; ++i)
524     {
525         if (base->parameter_handles[i] == parameter)
526         {
527             return get_parameter_struct(parameter);
528         }
529 
530         p = is_valid_sub_parameter(get_parameter_struct(base->parameter_handles[i]), parameter);
531         if (p) return p;
532     }
533 
534     for (i = 0; i < base->technique_count; ++i)
535     {
536         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
537 
538         for (k = 0; k < technique->pass_count; ++k)
539         {
540             struct d3dx_pass *pass = get_pass_struct(technique->pass_handles[k]);
541 
542             for (m = 0; m < pass->annotation_count; ++m)
543             {
544                 if (pass->annotation_handles[i] == parameter)
545                 {
546                     return get_parameter_struct(parameter);
547                 }
548 
549                 p = is_valid_sub_parameter(get_parameter_struct(pass->annotation_handles[m]), parameter);
550                 if (p) return p;
551             }
552         }
553 
554         for (k = 0; k < technique->annotation_count; ++k)
555         {
556             if (technique->annotation_handles[k] == parameter)
557             {
558                 return get_parameter_struct(parameter);
559             }
560 
561             p = is_valid_sub_parameter(get_parameter_struct(technique->annotation_handles[k]), parameter);
562             if (p) return p;
563         }
564     }
565 
566     return NULL;
567 }
568 
569 static inline struct d3dx_parameter *get_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
570 {
571     struct d3dx_parameter *param = is_valid_parameter(base, parameter);
572 
573     if (!param) param = get_parameter_by_name(base, NULL, parameter);
574 
575     return param;
576 }
577 
578 static void free_state(struct d3dx_state *state)
579 {
580     free_parameter_state(state->parameter, FALSE, FALSE, state->type);
581 }
582 
583 static void free_sampler(struct d3dx_sampler *sampler)
584 {
585     UINT i;
586 
587     for (i = 0; i < sampler->state_count; ++i)
588     {
589         free_state(&sampler->states[i]);
590     }
591     HeapFree(GetProcessHeap(), 0, sampler->states);
592 }
593 
594 static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
595 {
596     free_parameter_state(handle, element, child, ST_CONSTANT);
597 }
598 
599 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st)
600 {
601     unsigned int i;
602     struct d3dx_parameter *param = get_parameter_struct(handle);
603 
604     TRACE("Free parameter %p, name %s, type %s, child %s, state_type %x\n", param, param->name,
605             debug_d3dxparameter_type(param->type), child ? "yes" : "no", st);
606 
607     if (!param)
608     {
609         return;
610     }
611 
612     if (param->annotation_handles)
613     {
614         for (i = 0; i < param->annotation_count; ++i)
615         {
616             free_parameter(param->annotation_handles[i], FALSE, FALSE);
617         }
618         HeapFree(GetProcessHeap(), 0, param->annotation_handles);
619     }
620 
621     if (param->member_handles)
622     {
623         unsigned int count;
624 
625         if (param->element_count) count = param->element_count;
626         else count = param->member_count;
627 
628         for (i = 0; i < count; ++i)
629         {
630             free_parameter(param->member_handles[i], param->element_count != 0, TRUE);
631         }
632         HeapFree(GetProcessHeap(), 0, param->member_handles);
633     }
634 
635     if (param->class == D3DXPC_OBJECT && !param->element_count)
636     {
637         switch (param->type)
638         {
639             case D3DXPT_STRING:
640                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
641                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
642                 break;
643 
644             case D3DXPT_TEXTURE:
645             case D3DXPT_TEXTURE1D:
646             case D3DXPT_TEXTURE2D:
647             case D3DXPT_TEXTURE3D:
648             case D3DXPT_TEXTURECUBE:
649             case D3DXPT_PIXELSHADER:
650             case D3DXPT_VERTEXSHADER:
651                 if (st == ST_CONSTANT)
652                 {
653                     if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
654                 }
655                 else
656                 {
657                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
658                 }
659                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
660                 break;
661 
662             case D3DXPT_SAMPLER:
663             case D3DXPT_SAMPLER1D:
664             case D3DXPT_SAMPLER2D:
665             case D3DXPT_SAMPLER3D:
666             case D3DXPT_SAMPLERCUBE:
667                 if (st == ST_CONSTANT)
668                 {
669                     free_sampler((struct d3dx_sampler *)param->data);
670                 }
671                 else
672                 {
673                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
674                 }
675                 /* samplers have always own data, so free that */
676                 HeapFree(GetProcessHeap(), 0, param->data);
677                 break;
678 
679             default:
680                 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
681                 break;
682         }
683     }
684     else
685     {
686         if (!child)
687         {
688             if (st != ST_CONSTANT)
689             {
690                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
691             }
692             HeapFree(GetProcessHeap(), 0, param->data);
693         }
694     }
695 
696     /* only the parent has to release name and semantic */
697     if (!element)
698     {
699         HeapFree(GetProcessHeap(), 0, param->name);
700         HeapFree(GetProcessHeap(), 0, param->semantic);
701     }
702 
703     HeapFree(GetProcessHeap(), 0, param);
704 }
705 
706 static void free_pass(D3DXHANDLE handle)
707 {
708     unsigned int i;
709     struct d3dx_pass *pass = get_pass_struct(handle);
710 
711     TRACE("Free pass %p\n", pass);
712 
713     if (!pass)
714     {
715         return;
716     }
717 
718     if (pass->annotation_handles)
719     {
720         for (i = 0; i < pass->annotation_count; ++i)
721         {
722             free_parameter(pass->annotation_handles[i], FALSE, FALSE);
723         }
724         HeapFree(GetProcessHeap(), 0, pass->annotation_handles);
725     }
726 
727     if (pass->states)
728     {
729         for (i = 0; i < pass->state_count; ++i)
730         {
731             free_state(&pass->states[i]);
732         }
733         HeapFree(GetProcessHeap(), 0, pass->states);
734     }
735 
736     HeapFree(GetProcessHeap(), 0, pass->name);
737     HeapFree(GetProcessHeap(), 0, pass);
738 }
739 
740 static void free_technique(D3DXHANDLE handle)
741 {
742     unsigned int i;
743     struct d3dx_technique *technique = get_technique_struct(handle);
744 
745     TRACE("Free technique %p\n", technique);
746 
747     if (!technique)
748     {
749         return;
750     }
751 
752     if (technique->annotation_handles)
753     {
754         for (i = 0; i < technique->annotation_count; ++i)
755         {
756             free_parameter(technique->annotation_handles[i], FALSE, FALSE);
757         }
758         HeapFree(GetProcessHeap(), 0, technique->annotation_handles);
759     }
760 
761     if (technique->pass_handles)
762     {
763         for (i = 0; i < technique->pass_count; ++i)
764         {
765             free_pass(technique->pass_handles[i]);
766         }
767         HeapFree(GetProcessHeap(), 0, technique->pass_handles);
768     }
769 
770     HeapFree(GetProcessHeap(), 0, technique->name);
771     HeapFree(GetProcessHeap(), 0, technique);
772 }
773 
774 static void free_base_effect(struct ID3DXBaseEffectImpl *base)
775 {
776     unsigned int i;
777 
778     TRACE("Free base effect %p\n", base);
779 
780     if (base->parameter_handles)
781     {
782         for (i = 0; i < base->parameter_count; ++i)
783         {
784             free_parameter(base->parameter_handles[i], FALSE, FALSE);
785         }
786         HeapFree(GetProcessHeap(), 0, base->parameter_handles);
787     }
788 
789     if (base->technique_handles)
790     {
791         for (i = 0; i < base->technique_count; ++i)
792         {
793             free_technique(base->technique_handles[i]);
794         }
795         HeapFree(GetProcessHeap(), 0, base->technique_handles);
796     }
797 }
798 
799 static void free_effect(struct ID3DXEffectImpl *effect)
800 {
801     TRACE("Free effect %p\n", effect);
802 
803     if (effect->base_effect)
804     {
805         effect->base_effect->lpVtbl->Release(effect->base_effect);
806     }
807 
808     if (effect->pool)
809     {
810         effect->pool->lpVtbl->Release(effect->pool);
811     }
812 
813     if (effect->manager)
814     {
815         IUnknown_Release(effect->manager);
816     }
817 
818     IDirect3DDevice9_Release(effect->device);
819 }
820 
821 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler)
822 {
823     TRACE("Free effect compiler %p\n", compiler);
824 
825     if (compiler->base_effect)
826     {
827         compiler->base_effect->lpVtbl->Release(compiler->base_effect);
828     }
829 }
830 
831 static INT get_int(D3DXPARAMETER_TYPE type, LPCVOID data)
832 {
833     INT i;
834 
835     switch (type)
836     {
837         case D3DXPT_FLOAT:
838             i = *(FLOAT *)data;
839             break;
840 
841         case D3DXPT_INT:
842             i = *(INT *)data;
843             break;
844 
845         case D3DXPT_BOOL:
846             i = *(BOOL *)data;
847             break;
848 
849         default:
850             i = 0;
851             FIXME("Unhandled type %s. This should not happen!\n", debug_d3dxparameter_type(type));
852             break;
853     }
854 
855     return i;
856 }
857 
858 inline static FLOAT get_float(D3DXPARAMETER_TYPE type, LPCVOID data)
859 {
860     FLOAT f;
861 
862     switch (type)
863     {
864         case D3DXPT_FLOAT:
865             f = *(FLOAT *)data;
866             break;
867 
868         case D3DXPT_INT:
869             f = *(INT *)data;
870             break;
871 
872         case D3DXPT_BOOL:
873             f = *(BOOL *)data;
874             break;
875 
876         default:
877             f = 0.0f;
878             FIXME("Unhandled type %s. This should not happen!\n", debug_d3dxparameter_type(type));
879             break;
880     }
881 
882     return f;
883 }
884 
885 static inline BOOL get_bool(LPCVOID data)
886 {
887     return (*(DWORD *)data) ? TRUE : FALSE;
888 }
889 
890 static void set_number(LPVOID outdata, D3DXPARAMETER_TYPE outtype, LPCVOID indata, D3DXPARAMETER_TYPE intype)
891 {
892     TRACE("Changing from type %i to type %i\n", intype, outtype);
893 
894     switch (outtype)
895     {
896         case D3DXPT_FLOAT:
897             *(FLOAT *)outdata = get_float(intype, indata);
898             break;
899 
900         case D3DXPT_BOOL:
901             *(BOOL *)outdata = get_bool(indata);
902             break;
903 
904         case D3DXPT_INT:
905             *(INT *)outdata = get_int(intype, indata);
906             break;
907 
908         default:
909             FIXME("Error converting to type %i\n", outtype);
910             *(INT *)outdata = 0;
911             break;
912     }
913 }
914 
915 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
916 {
917     UINT i;
918 
919     for (i = 0; i < 4; ++i)
920     {
921         ((FLOAT *)vector)[i] = i < param->columns ? get_float(param->type, (DWORD *)param->data + i) : 0.0f;
922     }
923 }
924 
925 static void set_vector(struct d3dx_parameter *param, CONST D3DXVECTOR4 *vector)
926 {
927     UINT i;
928 
929     for (i = 0; i < param->columns; ++i)
930     {
931         set_number((FLOAT *)param->data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
932     }
933 }
934 
935 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix)
936 {
937     UINT i, k;
938 
939     for (i = 0; i < 4; ++i)
940     {
941         for (k = 0; k < 4; ++k)
942         {
943             if ((i < param->rows) && (k < param->columns))
944                 matrix->u.m[i][k] = get_float(param->type, (FLOAT *)param->data + i * param->columns + k);
945             else
946                 matrix->u.m[i][k] = 0.0f;
947         }
948     }
949 }
950 
951 static void set_matrix(struct d3dx_parameter *param, CONST D3DXMATRIX *matrix)
952 {
953     UINT i, k;
954 
955     for (i = 0; i < 4; ++i)
956     {
957         for (k = 0; k < 4; ++k)
958         {
959             if ((i < param->rows) && (k < param->columns))
960                 set_number((FLOAT *)param->data + i * param->columns + k, param->type, &matrix->u.m[i][k], D3DXPT_FLOAT);
961         }
962     }
963 }
964 
965 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_parameter *parameter, LPCSTR name)
966 {
967     UINT element;
968     struct d3dx_parameter *temp_parameter;
969     LPCSTR part;
970 
971     TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
972 
973     if (!name || !*name) return parameter;
974 
975     element = atoi(name);
976     part = strchr(name, ']') + 1;
977 
978     if (parameter->element_count > element)
979     {
980         temp_parameter = get_parameter_struct(parameter->member_handles[element]);
981 
982         switch (*part++)
983         {
984             case '.':
985                 return get_parameter_by_name(NULL, temp_parameter, part);
986 
987             case '@':
988                 return get_parameter_annotation_by_name(temp_parameter, part);
989 
990             case '\0':
991                 TRACE("Returning parameter %p\n", temp_parameter);
992                 return temp_parameter;
993 
994             default:
995                 FIXME("Unhandled case \"%c\"\n", *--part);
996                 break;
997         }
998     }
999 
1000     TRACE("Parameter not found\n");
1001     return NULL;
1002 }
1003 
1004 static struct d3dx_parameter *get_parameter_annotation_by_name(struct d3dx_parameter *parameter, LPCSTR name)
1005 {
1006     UINT i, length;
1007     struct d3dx_parameter *temp_parameter;
1008     LPCSTR part;
1009 
1010     TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
1011 
1012     if (!name || !*name) return parameter;
1013 
1014     length = strcspn( name, "[.@" );
1015     part = name + length;
1016 
1017     for (i = 0; i < parameter->annotation_count; ++i)
1018     {
1019         temp_parameter = get_parameter_struct(parameter->annotation_handles[i]);
1020 
1021         if (!strcmp(temp_parameter->name, name))
1022         {
1023             TRACE("Returning parameter %p\n", temp_parameter);
1024             return temp_parameter;
1025         }
1026         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
1027         {
1028             switch (*part++)
1029             {
1030                 case '.':
1031                     return get_parameter_by_name(NULL, temp_parameter, part);
1032 
1033                 case '[':
1034                     return get_parameter_element_by_name(temp_parameter, part);
1035 
1036                 default:
1037                     FIXME("Unhandled case \"%c\"\n", *--part);
1038                     break;
1039             }
1040         }
1041     }
1042 
1043     TRACE("Parameter not found\n");
1044     return NULL;
1045 }
1046 
1047 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
1048         struct d3dx_parameter *parameter, LPCSTR name)
1049 {
1050     UINT i, count, length;
1051     struct d3dx_parameter *temp_parameter;
1052     D3DXHANDLE *handles;
1053     LPCSTR part;
1054 
1055     TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
1056 
1057     if (!name || !*name) return parameter;
1058 
1059     if (!parameter)
1060     {
1061         count = base->parameter_count;
1062         handles = base->parameter_handles;
1063     }
1064     else
1065     {
1066         count = parameter->member_count;
1067         handles = parameter->member_handles;
1068     }
1069 
1070     length = strcspn( name, "[.@" );
1071     part = name + length;
1072 
1073     for (i = 0; i < count; i++)
1074     {
1075         temp_parameter = get_parameter_struct(handles[i]);
1076 
1077         if (!strcmp(temp_parameter->name, name))
1078         {
1079             TRACE("Returning parameter %p\n", temp_parameter);
1080             return temp_parameter;
1081         }
1082         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
1083         {
1084             switch (*part++)
1085             {
1086                 case '.':
1087                     return get_parameter_by_name(NULL, temp_parameter, part);
1088 
1089                 case '@':
1090                     return get_parameter_annotation_by_name(temp_parameter, part);
1091 
1092                 case '[':
1093                     return get_parameter_element_by_name(temp_parameter, part);
1094 
1095                 default:
1096                     FIXME("Unhandled case \"%c\"\n", *--part);
1097                     break;
1098             }
1099         }
1100     }
1101 
1102     TRACE("Parameter not found\n");
1103     return NULL;
1104 }
1105 
1106 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
1107 {
1108     return (0xfeff0000 | ((major) << 8) | (minor));
1109 }
1110 
1111 static inline struct ID3DXBaseEffectImpl *impl_from_ID3DXBaseEffect(ID3DXBaseEffect *iface)
1112 {
1113     return CONTAINING_RECORD(iface, struct ID3DXBaseEffectImpl, ID3DXBaseEffect_iface);
1114 }
1115 
1116 /*** IUnknown methods ***/
1117 static HRESULT WINAPI ID3DXBaseEffectImpl_QueryInterface(ID3DXBaseEffect *iface, REFIID riid, void **object)
1118 {
1119     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
1120 
1121     if (IsEqualGUID(riid, &IID_IUnknown) ||
1122         IsEqualGUID(riid, &IID_ID3DXBaseEffect))
1123     {
1124         iface->lpVtbl->AddRef(iface);
1125         *object = iface;
1126         return S_OK;
1127     }
1128 
1129     ERR("Interface %s not found\n", debugstr_guid(riid));
1130 
1131     return E_NOINTERFACE;
1132 }
1133 
1134 static ULONG WINAPI ID3DXBaseEffectImpl_AddRef(ID3DXBaseEffect *iface)
1135 {
1136     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1137 
1138     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
1139 
1140     return InterlockedIncrement(&This->ref);
1141 }
1142 
1143 static ULONG WINAPI ID3DXBaseEffectImpl_Release(ID3DXBaseEffect *iface)
1144 {
1145     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1146     ULONG ref = InterlockedDecrement(&This->ref);
1147 
1148     TRACE("iface %p: Release from %u\n", iface, ref + 1);
1149 
1150     if (!ref)
1151     {
1152         free_base_effect(This);
1153         HeapFree(GetProcessHeap(), 0, This);
1154     }
1155 
1156     return ref;
1157 }
1158 
1159 /*** ID3DXBaseEffect methods ***/
1160 static HRESULT WINAPI ID3DXBaseEffectImpl_GetDesc(ID3DXBaseEffect *iface, D3DXEFFECT_DESC *desc)
1161 {
1162     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1163 
1164     FIXME("iface %p, desc %p partial stub\n", This, desc);
1165 
1166     if (!desc)
1167     {
1168         WARN("Invalid argument specified.\n");
1169         return D3DERR_INVALIDCALL;
1170     }
1171 
1172     /* Todo: add creator and function count */
1173     desc->Creator = NULL;
1174     desc->Functions = 0;
1175     desc->Parameters = This->parameter_count;
1176     desc->Techniques = This->technique_count;
1177 
1178     return D3D_OK;
1179 }
1180 
1181 static HRESULT WINAPI ID3DXBaseEffectImpl_GetParameterDesc(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
1182 {
1183     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1184     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1185 
1186     TRACE("iface %p, parameter %p, desc %p\n", This, parameter, desc);
1187 
1188     if (!desc || !param)
1189     {
1190         WARN("Invalid argument specified.\n");
1191         return D3DERR_INVALIDCALL;
1192     }
1193 
1194     desc->Name = param->name;
1195     desc->Semantic = param->semantic;
1196     desc->Class = param->class;
1197     desc->Type = param->type;
1198     desc->Rows = param->rows;
1199     desc->Columns = param->columns;
1200     desc->Elements = param->element_count;
1201     desc->Annotations = param->annotation_count;
1202     desc->StructMembers = param->member_count;
1203     desc->Flags = param->flags;
1204     desc->Bytes = param->bytes;
1205 
1206     return D3D_OK;
1207 }
1208 
1209 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTechniqueDesc(ID3DXBaseEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
1210 {
1211     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1212     struct d3dx_technique *tech = technique ? is_valid_technique(This, technique) : get_technique_struct(This->technique_handles[0]);
1213 
1214     TRACE("iface %p, technique %p, desc %p\n", This, technique, desc);
1215 
1216     if (!desc || !tech)
1217     {
1218         WARN("Invalid argument specified.\n");
1219         return D3DERR_INVALIDCALL;
1220     }
1221 
1222     desc->Name = tech->name;
1223     desc->Passes = tech->pass_count;
1224     desc->Annotations = tech->annotation_count;
1225 
1226     return D3D_OK;
1227 }
1228 
1229 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPassDesc(ID3DXBaseEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
1230 {
1231     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1232     struct d3dx_pass *p = is_valid_pass(This, pass);
1233 
1234     TRACE("iface %p, pass %p, desc %p\n", This, pass, desc);
1235 
1236     if (!desc || !p)
1237     {
1238         WARN("Invalid argument specified.\n");
1239         return D3DERR_INVALIDCALL;
1240     }
1241 
1242     desc->Name = p->name;
1243     desc->Annotations = p->annotation_count;
1244 
1245     FIXME("Pixel shader and vertex shader are not supported, yet.\n");
1246     desc->pVertexShaderFunction = NULL;
1247     desc->pPixelShaderFunction = NULL;
1248 
1249     return D3D_OK;
1250 }
1251 
1252 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFunctionDesc(ID3DXBaseEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
1253 {
1254     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1255 
1256     FIXME("iface %p, shader %p, desc %p stub\n", This, shader, desc);
1257 
1258     return E_NOTIMPL;
1259 }
1260 
1261 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
1262 {
1263     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1264     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1265 
1266     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
1267 
1268     if (!parameter)
1269     {
1270         if (index < This->parameter_count)
1271         {
1272             TRACE("Returning parameter %p\n", This->parameter_handles[index]);
1273             return This->parameter_handles[index];
1274         }
1275     }
1276     else
1277     {
1278         if (param && !param->element_count && index < param->member_count)
1279         {
1280             TRACE("Returning parameter %p\n", param->member_handles[index]);
1281             return param->member_handles[index];
1282         }
1283     }
1284 
1285     WARN("Invalid argument specified.\n");
1286 
1287     return NULL;
1288 }
1289 
1290 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR name)
1291 {
1292     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1293     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1294     D3DXHANDLE handle;
1295 
1296     TRACE("iface %p, parameter %p, name %s\n", This, parameter, debugstr_a(name));
1297 
1298     if (!name)
1299     {
1300         handle = get_parameter_handle(param);
1301         TRACE("Returning parameter %p\n", handle);
1302         return handle;
1303     }
1304 
1305     handle = get_parameter_handle(get_parameter_by_name(This, param, name));
1306     TRACE("Returning parameter %p\n", handle);
1307 
1308     return handle;
1309 }
1310 
1311 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterBySemantic(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
1312 {
1313     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1314     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1315     struct d3dx_parameter *temp_param;
1316     UINT i;
1317 
1318     TRACE("iface %p, parameter %p, semantic %s\n", This, parameter, debugstr_a(semantic));
1319 
1320     if (!parameter)
1321     {
1322         for (i = 0; i < This->parameter_count; ++i)
1323         {
1324             temp_param = get_parameter_struct(This->parameter_handles[i]);
1325 
1326             if (!temp_param->semantic)
1327             {
1328                 if (!semantic)
1329                 {
1330                     TRACE("Returning parameter %p\n", This->parameter_handles[i]);
1331                     return This->parameter_handles[i];
1332                 }
1333                 continue;
1334             }
1335 
1336             if (!strcasecmp(temp_param->semantic, semantic))
1337             {
1338                 TRACE("Returning parameter %p\n", This->parameter_handles[i]);
1339                 return This->parameter_handles[i];
1340             }
1341         }
1342     }
1343     else if (param)
1344     {
1345         for (i = 0; i < param->member_count; ++i)
1346         {
1347             temp_param = get_parameter_struct(param->member_handles[i]);
1348 
1349             if (!temp_param->semantic)
1350             {
1351                 if (!semantic)
1352                 {
1353                     TRACE("Returning parameter %p\n", param->member_handles[i]);
1354                     return param->member_handles[i];
1355                 }
1356                 continue;
1357             }
1358 
1359             if (!strcasecmp(temp_param->semantic, semantic))
1360             {
1361                 TRACE("Returning parameter %p\n", param->member_handles[i]);
1362                 return param->member_handles[i];
1363             }
1364         }
1365     }
1366 
1367     WARN("Invalid argument specified\n");
1368 
1369     return NULL;
1370 }
1371 
1372 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterElement(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
1373 {
1374     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1375     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1376 
1377     TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
1378 
1379     if (!param)
1380     {
1381         if (index < This->parameter_count)
1382         {
1383             TRACE("Returning parameter %p\n", This->parameter_handles[index]);
1384             return This->parameter_handles[index];
1385         }
1386     }
1387     else
1388     {
1389         if (index < param->element_count)
1390         {
1391             TRACE("Returning parameter %p\n", param->member_handles[index]);
1392             return param->member_handles[index];
1393         }
1394     }
1395 
1396     WARN("Invalid argument specified\n");
1397 
1398     return NULL;
1399 }
1400 
1401 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechnique(ID3DXBaseEffect *iface, UINT index)
1402 {
1403     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1404 
1405     TRACE("iface %p, index %u\n", This, index);
1406 
1407     if (index >= This->technique_count)
1408     {
1409         WARN("Invalid argument specified.\n");
1410         return NULL;
1411     }
1412 
1413     TRACE("Returning technique %p\n", This->technique_handles[index]);
1414 
1415     return This->technique_handles[index];
1416 }
1417 
1418 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechniqueByName(ID3DXBaseEffect *iface, LPCSTR name)
1419 {
1420     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1421     unsigned int i;
1422 
1423     TRACE("iface %p, name %s stub\n", This, debugstr_a(name));
1424 
1425     if (!name)
1426     {
1427         WARN("Invalid argument specified.\n");
1428         return NULL;
1429     }
1430 
1431     for (i = 0; i < This->technique_count; ++i)
1432     {
1433         struct d3dx_technique *tech = get_technique_struct(This->technique_handles[i]);
1434 
1435         if (!strcmp(tech->name, name))
1436         {
1437             TRACE("Returning technique %p\n", This->technique_handles[i]);
1438             return This->technique_handles[i];
1439         }
1440     }
1441 
1442     WARN("Invalid argument specified.\n");
1443 
1444     return NULL;
1445 }
1446 
1447 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPass(ID3DXBaseEffect *iface, D3DXHANDLE technique, UINT index)
1448 {
1449     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1450     struct d3dx_technique *tech = is_valid_technique(This, technique);
1451 
1452     TRACE("iface %p, technique %p, index %u\n", This, technique, index);
1453 
1454     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
1455 
1456     if (tech && index < tech->pass_count)
1457     {
1458         TRACE("Returning pass %p\n", tech->pass_handles[index]);
1459         return tech->pass_handles[index];
1460     }
1461 
1462     WARN("Invalid argument specified.\n");
1463 
1464     return NULL;
1465 }
1466 
1467 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPassByName(ID3DXBaseEffect *iface, D3DXHANDLE technique, LPCSTR name)
1468 {
1469     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1470     struct d3dx_technique *tech = is_valid_technique(This, technique);
1471 
1472     TRACE("iface %p, technique %p, name %s\n", This, technique, debugstr_a(name));
1473 
1474     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
1475 
1476     if (tech && name)
1477     {
1478         unsigned int i;
1479 
1480         for (i = 0; i < tech->pass_count; ++i)
1481         {
1482             struct d3dx_pass *pass = get_pass_struct(tech->pass_handles[i]);
1483 
1484             if (!strcmp(pass->name, name))
1485             {
1486                 TRACE("Returning pass %p\n", tech->pass_handles[i]);
1487                 return tech->pass_handles[i];
1488             }
1489         }
1490     }
1491 
1492     WARN("Invalid argument specified.\n");
1493 
1494     return NULL;
1495 }
1496 
1497 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunction(ID3DXBaseEffect *iface, UINT index)
1498 {
1499     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1500 
1501     FIXME("iface %p, index %u stub\n", This, index);
1502 
1503     return NULL;
1504 }
1505 
1506 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunctionByName(ID3DXBaseEffect *iface, LPCSTR name)
1507 {
1508     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1509 
1510     FIXME("iface %p, name %s stub\n", This, debugstr_a(name));
1511 
1512     return NULL;
1513 }
1514 
1515 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotation(ID3DXBaseEffect *iface, D3DXHANDLE object, UINT index)
1516 {
1517     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1518     struct d3dx_parameter *param = get_valid_parameter(This, object);
1519     struct d3dx_pass *pass = is_valid_pass(This, object);
1520     struct d3dx_technique *technique = is_valid_technique(This, object);
1521     UINT annotation_count = 0;
1522     D3DXHANDLE *annotation_handles = NULL;
1523 
1524     FIXME("iface %p, object %p, index %u partial stub\n", This, object, index);
1525 
1526     if (pass)
1527     {
1528         annotation_count = pass->annotation_count;
1529         annotation_handles = pass->annotation_handles;
1530     }
1531     else if (technique)
1532     {
1533         annotation_count = technique->annotation_count;
1534         annotation_handles = technique->annotation_handles;
1535     }
1536     else if (param)
1537     {
1538         annotation_count = param->annotation_count;
1539         annotation_handles = param->annotation_handles;
1540     }
1541     /* Todo: add funcs */
1542 
1543     if (index < annotation_count)
1544     {
1545         TRACE("Returning parameter %p\n", annotation_handles[index]);
1546         return annotation_handles[index];
1547     }
1548 
1549     WARN("Invalid argument specified\n");
1550 
1551     return NULL;
1552 }
1553 
1554 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotationByName(ID3DXBaseEffect *iface, D3DXHANDLE object, LPCSTR name)
1555 {
1556     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1557     struct d3dx_parameter *param = get_valid_parameter(This, object);
1558     struct d3dx_pass *pass = is_valid_pass(This, object);
1559     struct d3dx_technique *technique = is_valid_technique(This, object);
1560     UINT annotation_count = 0, i;
1561     D3DXHANDLE *annotation_handles = NULL;
1562 
1563     FIXME("iface %p, object %p, name %s partial stub\n", This, object, debugstr_a(name));
1564 
1565     if (!name)
1566     {
1567         WARN("Invalid argument specified\n");
1568         return NULL;
1569     }
1570 
1571     if (pass)
1572     {
1573         annotation_count = pass->annotation_count;
1574         annotation_handles = pass->annotation_handles;
1575     }
1576     else if (technique)
1577     {
1578         annotation_count = technique->annotation_count;
1579         annotation_handles = technique->annotation_handles;
1580     }
1581     else if (param)
1582     {
1583         annotation_count = param->annotation_count;
1584         annotation_handles = param->annotation_handles;
1585     }
1586     /* Todo: add funcs */
1587 
1588     for (i = 0; i < annotation_count; i++)
1589     {
1590         struct d3dx_parameter *anno = get_parameter_struct(annotation_handles[i]);
1591 
1592         if (!strcmp(anno->name, name))
1593         {
1594             TRACE("Returning parameter %p\n", anno);
1595             return get_parameter_handle(anno);
1596         }
1597     }
1598 
1599     WARN("Invalid argument specified\n");
1600 
1601     return NULL;
1602 }
1603 
1604 static HRESULT WINAPI ID3DXBaseEffectImpl_SetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
1605 {
1606     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1607     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1608 
1609     TRACE("iface %p, parameter %p, data %p, bytes %u\n", This, parameter, data, bytes);
1610 
1611     if (!param)
1612     {
1613         WARN("Invalid parameter %p specified\n", parameter);
1614         return D3DERR_INVALIDCALL;
1615     }
1616 
1617     /* samplers don't touch data */
1618     if (param->class == D3DXPC_OBJECT && (param->type == D3DXPT_SAMPLER
1619             || param->type == D3DXPT_SAMPLER1D || param->type == D3DXPT_SAMPLER2D
1620             || param->type == D3DXPT_SAMPLER3D || param->type == D3DXPT_SAMPLERCUBE))
1621     {
1622         TRACE("Sampler: returning E_FAIL\n");
1623         return E_FAIL;
1624     }
1625 
1626     if (data && param->bytes <= bytes)
1627     {
1628         switch (param->type)
1629         {
1630             case D3DXPT_VOID:
1631             case D3DXPT_BOOL:
1632             case D3DXPT_INT:
1633             case D3DXPT_FLOAT:
1634                 TRACE("Copy %u bytes\n", param->bytes);
1635                 memcpy(param->data, data, param->bytes);
1636                 break;
1637 
1638             default:
1639                 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1640                 break;
1641         }
1642 
1643         return D3D_OK;
1644     }
1645 
1646     WARN("Invalid argument specified\n");
1647 
1648     return D3DERR_INVALIDCALL;
1649 }
1650 
1651 static HRESULT WINAPI ID3DXBaseEffectImpl_GetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
1652 {
1653     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1654     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1655 
1656     TRACE("iface %p, parameter %p, data %p, bytes %u\n", This, parameter, data, bytes);
1657 
1658     if (!param)
1659     {
1660         WARN("Invalid parameter %p specified\n", parameter);
1661         return D3DERR_INVALIDCALL;
1662     }
1663 
1664     /* samplers don't touch data */
1665     if (param->class == D3DXPC_OBJECT && (param->type == D3DXPT_SAMPLER
1666             || param->type == D3DXPT_SAMPLER1D || param->type == D3DXPT_SAMPLER2D
1667             || param->type == D3DXPT_SAMPLER3D || param->type == D3DXPT_SAMPLERCUBE))
1668     {
1669         TRACE("Sampler: returning E_FAIL\n");
1670         return E_FAIL;
1671     }
1672 
1673     if (data && param->bytes <= bytes)
1674     {
1675         TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
1676 
1677         switch (param->type)
1678         {
1679             case D3DXPT_VOID:
1680             case D3DXPT_BOOL:
1681             case D3DXPT_INT:
1682             case D3DXPT_FLOAT:
1683             case D3DXPT_STRING:
1684                 break;
1685 
1686             case D3DXPT_VERTEXSHADER:
1687             case D3DXPT_PIXELSHADER:
1688             case D3DXPT_TEXTURE:
1689             case D3DXPT_TEXTURE1D:
1690             case D3DXPT_TEXTURE2D:
1691             case D3DXPT_TEXTURE3D:
1692             case D3DXPT_TEXTURECUBE:
1693             {
1694                 UINT i;
1695 
1696                 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
1697                 {
1698                     IUnknown *unk = ((IUnknown **)param->data)[i];
1699                     if (unk) IUnknown_AddRef(unk);
1700                 }
1701                 break;
1702             }
1703 
1704             default:
1705                 FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
1706                 break;
1707         }
1708 
1709         TRACE("Copy %u bytes\n", param->bytes);
1710         memcpy(data, param->data, param->bytes);
1711         return D3D_OK;
1712     }
1713 
1714     WARN("Invalid argument specified\n");
1715 
1716     return D3DERR_INVALIDCALL;
1717 }
1718 
1719 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL b)
1720 {
1721     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1722     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1723 
1724     TRACE("iface %p, parameter %p, b %s\n", This, parameter, b ? "TRUE" : "FALSE");
1725 
1726     if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1727     {
1728         set_number(param->data, param->type, &b, D3DXPT_BOOL);
1729         return D3D_OK;
1730     }
1731 
1732     WARN("Invalid argument specified\n");
1733 
1734     return D3DERR_INVALIDCALL;
1735 }
1736 
1737 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b)
1738 {
1739     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1740     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1741 
1742     TRACE("iface %p, parameter %p, b %p\n", This, parameter, b);
1743 
1744     if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
1745     {
1746         *b = get_bool(param->data);
1747         TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
1748         return D3D_OK;
1749     }
1750 
1751     WARN("Invalid argument specified\n");
1752 
1753     return D3DERR_INVALIDCALL;
1754 }
1755 
1756 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
1757 {
1758     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1759     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1760 
1761     TRACE("iface %p, parameter %p, b %p, count %u\n", This, parameter, b, count);
1762 
1763     if (param)
1764     {
1765         UINT i, size = min(count, param->bytes / sizeof(DWORD));
1766 
1767         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1768 
1769         switch (param->class)
1770         {
1771             case D3DXPC_SCALAR:
1772             case D3DXPC_VECTOR:
1773             case D3DXPC_MATRIX_ROWS:
1774                 for (i = 0; i < size; ++i)
1775                 {
1776                     set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_BOOL);
1777                 }
1778                 return D3D_OK;
1779 
1780             case D3DXPC_OBJECT:
1781             case D3DXPC_STRUCT:
1782                 break;
1783 
1784             default:
1785                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1786                 break;
1787         }
1788     }
1789 
1790     WARN("Invalid argument specified\n");
1791 
1792     return D3DERR_INVALIDCALL;
1793 }
1794 
1795 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
1796 {
1797     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1798     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1799 
1800     TRACE("iface %p, parameter %p, b %p, count %u\n", This, parameter, b, count);
1801 
1802     if (b && param && (param->class == D3DXPC_SCALAR
1803             || param->class == D3DXPC_VECTOR
1804             || param->class == D3DXPC_MATRIX_ROWS
1805             || param->class == D3DXPC_MATRIX_COLUMNS))
1806     {
1807         UINT i, size = min(count, param->bytes / sizeof(DWORD));
1808 
1809         for (i = 0; i < size; ++i)
1810         {
1811             b[i] = get_bool((DWORD *)param->data + i);
1812         }
1813         return D3D_OK;
1814     }
1815 
1816     WARN("Invalid argument specified\n");
1817 
1818     return D3DERR_INVALIDCALL;
1819 }
1820 
1821 static HRESULT WINAPI ID3DXBaseEffectImpl_SetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT n)
1822 {
1823     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1824     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1825 
1826     TRACE("iface %p, parameter %p, n %i\n", This, parameter, n);
1827 
1828     if (param && !param->element_count)
1829     {
1830         if (param->rows == 1 && param->columns == 1)
1831         {
1832             set_number(param->data, param->type, &n, D3DXPT_INT);
1833             return D3D_OK;
1834         }
1835 
1836         /*
1837          * Split the value, if parameter is a vector with dimension 3 or 4.
1838          */
1839         if (param->type == D3DXPT_FLOAT &&
1840             ((param->class == D3DXPC_VECTOR && param->columns != 2) ||
1841             (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1842         {
1843             TRACE("Vector fixup\n");
1844 
1845             *(FLOAT *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
1846             ((FLOAT *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
1847             ((FLOAT *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
1848             if (param->rows * param->columns > 3)
1849             {
1850                 ((FLOAT *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
1851             }
1852             return D3D_OK;
1853         }
1854     }
1855 
1856     WARN("Invalid argument specified\n");
1857 
1858     return D3DERR_INVALIDCALL;
1859 }
1860 
1861 static HRESULT WINAPI ID3DXBaseEffectImpl_GetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n)
1862 {
1863     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1864     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1865 
1866     TRACE("iface %p, parameter %p, n %p\n", This, parameter, n);
1867 
1868     if (n && param && !param->element_count)
1869     {
1870         if (param->columns == 1 && param->rows == 1)
1871         {
1872             *n = get_int(param->type, param->data);
1873             TRACE("Returning %i\n", *n);
1874             return D3D_OK;
1875         }
1876 
1877         if (param->type == D3DXPT_FLOAT &&
1878                 ((param->class == D3DXPC_VECTOR && param->columns != 2)
1879                 || (param->class == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
1880         {
1881             TRACE("Vector fixup\n");
1882 
1883             /* all components (3,4) are clamped (0,255) and put in the INT */
1884             *n = (INT)(min(max(0.0f, *((FLOAT *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI);
1885             *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
1886             *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
1887             if (param->columns * param->rows > 3)
1888             {
1889                 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
1890             }
1891 
1892             TRACE("Returning %i\n", *n);
1893             return D3D_OK;
1894         }
1895     }
1896 
1897     WARN("Invalid argument specified\n");
1898 
1899     return D3DERR_INVALIDCALL;
1900 }
1901 
1902 static HRESULT WINAPI ID3DXBaseEffectImpl_SetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
1903 {
1904     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1905     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1906 
1907     TRACE("iface %p, parameter %p, n %p, count %u\n", This, parameter, n, count);
1908 
1909     if (param)
1910     {
1911         UINT i, size = min(count, param->bytes / sizeof(DWORD));
1912 
1913         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
1914 
1915         switch (param->class)
1916         {
1917             case D3DXPC_SCALAR:
1918             case D3DXPC_VECTOR:
1919             case D3DXPC_MATRIX_ROWS:
1920                 for (i = 0; i < size; ++i)
1921                 {
1922                     set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
1923                 }
1924                 return D3D_OK;
1925 
1926             case D3DXPC_OBJECT:
1927             case D3DXPC_STRUCT:
1928                 break;
1929 
1930             default:
1931                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
1932                 break;
1933         }
1934     }
1935 
1936     WARN("Invalid argument specified\n");
1937 
1938     return D3DERR_INVALIDCALL;
1939 }
1940 
1941 static HRESULT WINAPI ID3DXBaseEffectImpl_GetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
1942 {
1943     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1944     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1945 
1946     TRACE("iface %p, parameter %p, n %p, count %u\n", This, parameter, n, count);
1947 
1948     if (n && param && (param->class == D3DXPC_SCALAR
1949             || param->class == D3DXPC_VECTOR
1950             || param->class == D3DXPC_MATRIX_ROWS
1951             || param->class == D3DXPC_MATRIX_COLUMNS))
1952     {
1953         UINT i, size = min(count, param->bytes / sizeof(DWORD));
1954 
1955         for (i = 0; i < size; ++i)
1956         {
1957             n[i] = get_int(param->type, (DWORD *)param->data + i);
1958         }
1959         return D3D_OK;
1960     }
1961 
1962     WARN("Invalid argument specified\n");
1963 
1964     return D3DERR_INVALIDCALL;
1965 }
1966 
1967 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT f)
1968 {
1969     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1970     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1971 
1972     TRACE("iface %p, parameter %p, f %f\n", This, parameter, f);
1973 
1974     if (param && !param->element_count && param->rows == 1 && param->columns == 1)
1975     {
1976         set_number((DWORD *)param->data, param->type, &f, D3DXPT_FLOAT);
1977         return D3D_OK;
1978     }
1979 
1980     WARN("Invalid argument specified\n");
1981 
1982     return D3DERR_INVALIDCALL;
1983 }
1984 
1985 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f)
1986 {
1987     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
1988     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
1989 
1990     TRACE("iface %p, parameter %p, f %p\n", This, parameter, f);
1991 
1992     if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
1993     {
1994         *f = get_float(param->type, (DWORD *)param->data);
1995         TRACE("Returning %f\n", *f);
1996         return D3D_OK;
1997     }
1998 
1999     WARN("Invalid argument specified\n");
2000 
2001     return D3DERR_INVALIDCALL;
2002 }
2003 
2004 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
2005 {
2006     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2007     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2008 
2009     TRACE("iface %p, parameter %p, f %p, count %u\n", This, parameter, f, count);
2010 
2011     if (param)
2012     {
2013         UINT i, size = min(count, param->bytes / sizeof(DWORD));
2014 
2015         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2016 
2017         switch (param->class)
2018         {
2019             case D3DXPC_SCALAR:
2020             case D3DXPC_VECTOR:
2021             case D3DXPC_MATRIX_ROWS:
2022                 for (i = 0; i < size; ++i)
2023                 {
2024                     set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
2025                 }
2026                 return D3D_OK;
2027 
2028             case D3DXPC_OBJECT:
2029             case D3DXPC_STRUCT:
2030                 break;
2031 
2032             default:
2033                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2034                 break;
2035         }
2036     }
2037 
2038     WARN("Invalid argument specified\n");
2039 
2040     return D3DERR_INVALIDCALL;
2041 }
2042 
2043 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
2044 {
2045     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2046     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2047 
2048     TRACE("iface %p, parameter %p, f %p, count %u\n", This, parameter, f, count);
2049 
2050     if (f && param && (param->class == D3DXPC_SCALAR
2051             || param->class == D3DXPC_VECTOR
2052             || param->class == D3DXPC_MATRIX_ROWS
2053             || param->class == D3DXPC_MATRIX_COLUMNS))
2054     {
2055         UINT i, size = min(count, param->bytes / sizeof(DWORD));
2056 
2057         for (i = 0; i < size; ++i)
2058         {
2059             f[i] = get_float(param->type, (DWORD *)param->data + i);
2060         }
2061         return D3D_OK;
2062     }
2063 
2064     WARN("Invalid argument specified\n");
2065 
2066     return D3DERR_INVALIDCALL;
2067 }
2068 
2069 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVector(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
2070 {
2071     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2072     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2073 
2074     TRACE("iface %p, parameter %p, vector %p\n", This, parameter, vector);
2075 
2076     if (param && !param->element_count)
2077     {
2078         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2079 
2080         switch (param->class)
2081         {
2082             case D3DXPC_SCALAR:
2083             case D3DXPC_VECTOR:
2084                 if (param->type == D3DXPT_INT && param->bytes == 4)
2085                 {
2086                     DWORD tmp;
2087 
2088                     TRACE("INT fixup\n");
2089                     tmp = (DWORD)(max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI);
2090                     tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
2091                     tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
2092                     tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
2093 
2094                     *(INT *)param->data = tmp;
2095                     return D3D_OK;
2096                 }
2097                 set_vector(param, vector);
2098                 return D3D_OK;
2099 
2100             case D3DXPC_MATRIX_ROWS:
2101             case D3DXPC_OBJECT:
2102             case D3DXPC_STRUCT:
2103                 break;
2104 
2105             default:
2106                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2107                 break;
2108         }
2109     }
2110 
2111     WARN("Invalid argument specified\n");
2112 
2113     return D3DERR_INVALIDCALL;
2114 }
2115 
2116 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVector(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
2117 {
2118     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2119     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2120 
2121     TRACE("iface %p, parameter %p, vector %p\n", This, parameter, vector);
2122 
2123     if (vector && param && !param->element_count)
2124     {
2125         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2126 
2127         switch (param->class)
2128         {
2129             case D3DXPC_SCALAR:
2130             case D3DXPC_VECTOR:
2131                 if (param->type == D3DXPT_INT && param->bytes == 4)
2132                 {
2133                     TRACE("INT fixup\n");
2134                     vector->x = (((*(INT *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
2135                     vector->y = (((*(INT *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
2136                     vector->z = ((*(INT *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
2137                     vector->w = (((*(INT *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
2138                     return D3D_OK;
2139                 }
2140                 get_vector(param, vector);
2141                 return D3D_OK;
2142 
2143             case D3DXPC_MATRIX_ROWS:
2144             case D3DXPC_OBJECT:
2145             case D3DXPC_STRUCT:
2146                 break;
2147 
2148             default:
2149                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2150                 break;
2151         }
2152     }
2153 
2154     WARN("Invalid argument specified\n");
2155 
2156     return D3DERR_INVALIDCALL;
2157 }
2158 
2159 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
2160 {
2161     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2162     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2163 
2164     TRACE("iface %p, parameter %p, vector %p, count %u stub\n", This, parameter, vector, count);
2165 
2166     if (param && param->element_count && param->element_count >= count)
2167     {
2168         UINT i;
2169 
2170         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2171 
2172         switch (param->class)
2173         {
2174             case D3DXPC_VECTOR:
2175                 for (i = 0; i < count; ++i)
2176                 {
2177                     set_vector(get_parameter_struct(param->member_handles[i]), &vector[i]);
2178                 }
2179                 return D3D_OK;
2180 
2181             case D3DXPC_SCALAR:
2182             case D3DXPC_MATRIX_ROWS:
2183             case D3DXPC_OBJECT:
2184             case D3DXPC_STRUCT:
2185                 break;
2186 
2187             default:
2188                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2189                 break;
2190         }
2191     }
2192 
2193     WARN("Invalid argument specified\n");
2194 
2195     return D3DERR_INVALIDCALL;
2196 }
2197 
2198 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
2199 {
2200     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2201     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2202 
2203     TRACE("iface %p, parameter %p, vector %p, count %u\n", This, parameter, vector, count);
2204 
2205     if (!count) return D3D_OK;
2206 
2207     if (vector && param && count <= param->element_count)
2208     {
2209         UINT i;
2210 
2211         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2212 
2213         switch (param->class)
2214         {
2215             case D3DXPC_VECTOR:
2216                 for (i = 0; i < count; ++i)
2217                 {
2218                     get_vector(get_parameter_struct(param->member_handles[i]), &vector[i]);
2219                 }
2220                 return D3D_OK;
2221 
2222             case D3DXPC_SCALAR:
2223             case D3DXPC_MATRIX_ROWS:
2224             case D3DXPC_OBJECT:
2225             case D3DXPC_STRUCT:
2226                 break;
2227 
2228             default:
2229                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2230                 break;
2231         }
2232     }
2233 
2234     WARN("Invalid argument specified\n");
2235 
2236     return D3DERR_INVALIDCALL;
2237 }
2238 
2239 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
2240 {
2241     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2242     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2243 
2244     TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
2245 
2246     if (param && !param->element_count)
2247     {
2248         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2249 
2250         switch (param->class)
2251         {
2252             case D3DXPC_MATRIX_ROWS:
2253                 set_matrix(param, matrix);
2254                 return D3D_OK;
2255 
2256             case D3DXPC_SCALAR:
2257             case D3DXPC_VECTOR:
2258             case D3DXPC_OBJECT:
2259             case D3DXPC_STRUCT:
2260                 break;
2261 
2262             default:
2263                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2264                 break;
2265         }
2266     }
2267 
2268     WARN("Invalid argument specified\n");
2269 
2270     return D3DERR_INVALIDCALL;
2271 }
2272 
2273 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
2274 {
2275     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2276     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2277 
2278     TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
2279 
2280     if (matrix && param && !param->element_count)
2281     {
2282         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2283 
2284         switch (param->class)
2285         {
2286             case D3DXPC_MATRIX_ROWS:
2287                 get_matrix(param, matrix);
2288                 return D3D_OK;
2289 
2290             case D3DXPC_SCALAR:
2291             case D3DXPC_VECTOR:
2292             case D3DXPC_OBJECT:
2293             case D3DXPC_STRUCT:
2294                 break;
2295 
2296             default:
2297                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2298                 break;
2299         }
2300     }
2301 
2302     WARN("Invalid argument specified\n");
2303 
2304     return D3DERR_INVALIDCALL;
2305 }
2306 
2307 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2308 {
2309     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2310     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2311 
2312     TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
2313 
2314     if (param && param->element_count >= count)
2315     {
2316         UINT i;
2317 
2318         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2319 
2320         switch (param->class)
2321         {
2322             case D3DXPC_MATRIX_ROWS:
2323                 for (i = 0; i < count; ++i)
2324                 {
2325                     set_matrix(get_parameter_struct(param->member_handles[i]), &matrix[i]);
2326                 }
2327                 return D3D_OK;
2328 
2329             case D3DXPC_SCALAR:
2330             case D3DXPC_VECTOR:
2331             case D3DXPC_OBJECT:
2332             case D3DXPC_STRUCT:
2333                 break;
2334 
2335             default:
2336                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2337                 break;
2338         }
2339     }
2340 
2341     WARN("Invalid argument specified\n");
2342 
2343     return D3DERR_INVALIDCALL;
2344 }
2345 
2346 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2347 {
2348     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2349     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2350 
2351     TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
2352 
2353     if (!count) return D3D_OK;
2354 
2355     if (matrix && param && count <= param->element_count)
2356     {
2357         UINT i;
2358 
2359         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2360 
2361         switch (param->class)
2362         {
2363             case D3DXPC_MATRIX_ROWS:
2364                 for (i = 0; i < count; ++i)
2365                 {
2366                     get_matrix(get_parameter_struct(param->member_handles[i]), &matrix[i]);
2367                 }
2368                 return D3D_OK;
2369 
2370             case D3DXPC_SCALAR:
2371             case D3DXPC_VECTOR:
2372             case D3DXPC_OBJECT:
2373             case D3DXPC_STRUCT:
2374                 break;
2375 
2376             default:
2377                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2378                 break;
2379         }
2380     }
2381 
2382     WARN("Invalid argument specified\n");
2383 
2384     return D3DERR_INVALIDCALL;
2385 }
2386 
2387 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2388 {
2389     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2390 
2391     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2392 
2393     return E_NOTIMPL;
2394 }
2395 
2396 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2397 {
2398     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2399 
2400     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2401 
2402     return E_NOTIMPL;
2403 }
2404 
2405 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
2406 {
2407     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2408     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2409     D3DXMATRIX m;
2410 
2411     TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
2412 
2413     if (param && !param->element_count)
2414     {
2415         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2416 
2417         switch (param->class)
2418         {
2419             case D3DXPC_MATRIX_ROWS:
2420                 set_matrix(param, D3DXMatrixTranspose(&m, matrix));
2421                 return D3D_OK;
2422 
2423             case D3DXPC_SCALAR:
2424             case D3DXPC_VECTOR:
2425             case D3DXPC_OBJECT:
2426             case D3DXPC_STRUCT:
2427                 break;
2428 
2429             default:
2430                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2431                 break;
2432         }
2433     }
2434 
2435     WARN("Invalid argument specified\n");
2436 
2437     return D3DERR_INVALIDCALL;
2438 }
2439 
2440 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
2441 {
2442     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2443     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2444     D3DXMATRIX m;
2445 
2446     TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
2447 
2448     if (matrix && param && !param->element_count)
2449     {
2450         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2451 
2452         switch (param->class)
2453         {
2454             case D3DXPC_SCALAR:
2455             case D3DXPC_VECTOR:
2456                 get_matrix(param, matrix);
2457                 return D3D_OK;
2458 
2459             case D3DXPC_MATRIX_ROWS:
2460                 get_matrix(param, &m);
2461                 D3DXMatrixTranspose(matrix, &m);
2462                 return D3D_OK;
2463 
2464             case D3DXPC_OBJECT:
2465             case D3DXPC_STRUCT:
2466                 break;
2467 
2468             default:
2469                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2470                 break;
2471         }
2472     }
2473 
2474     WARN("Invalid argument specified\n");
2475 
2476     return D3DERR_INVALIDCALL;
2477 }
2478 
2479 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
2480 {
2481     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2482     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2483     D3DXMATRIX m;
2484 
2485     TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
2486 
2487     if (param && param->element_count >= count)
2488     {
2489         UINT i;
2490 
2491         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2492 
2493         switch (param->class)
2494         {
2495             case D3DXPC_MATRIX_ROWS:
2496                 for (i = 0; i < count; ++i)
2497                 {
2498                     set_matrix(get_parameter_struct(param->member_handles[i]), D3DXMatrixTranspose(&m, &matrix[i]));
2499                 }
2500                 return D3D_OK;
2501 
2502             case D3DXPC_SCALAR:
2503             case D3DXPC_VECTOR:
2504             case D3DXPC_OBJECT:
2505             case D3DXPC_STRUCT:
2506                 break;
2507 
2508             default:
2509                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2510                 break;
2511         }
2512     }
2513 
2514     WARN("Invalid argument specified\n");
2515 
2516     return D3DERR_INVALIDCALL;
2517 }
2518 
2519 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
2520 {
2521     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2522     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2523 
2524     TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
2525 
2526     if (!count) return D3D_OK;
2527 
2528     if (matrix && param && count <= param->element_count)
2529     {
2530         UINT i;
2531 
2532         TRACE("Class %s\n", debug_d3dxparameter_class(param->class));
2533 
2534         switch (param->class)
2535         {
2536             case D3DXPC_MATRIX_ROWS:
2537                 for (i = 0; i < count; ++i)
2538                 {
2539                     D3DXMATRIX m;
2540 
2541                     get_matrix(get_parameter_struct(param->member_handles[i]), &m);
2542                     D3DXMatrixTranspose(&matrix[i], &m);
2543                 }
2544                 return D3D_OK;
2545 
2546             case D3DXPC_SCALAR:
2547             case D3DXPC_VECTOR:
2548             case D3DXPC_OBJECT:
2549             case D3DXPC_STRUCT:
2550                 break;
2551 
2552             default:
2553                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
2554                 break;
2555         }
2556     }
2557 
2558     WARN("Invalid argument specified\n");
2559 
2560     return D3DERR_INVALIDCALL;
2561 }
2562 
2563 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
2564 {
2565     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2566 
2567     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2568 
2569     return E_NOTIMPL;
2570 }
2571 
2572 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
2573 {
2574     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2575 
2576     FIXME("iface %p, parameter %p, matrix %p, count %u stub\n", This, parameter, matrix, count);
2577 
2578     return E_NOTIMPL;
2579 }
2580 
2581 static HRESULT WINAPI ID3DXBaseEffectImpl_SetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR string)
2582 {
2583     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2584 
2585     FIXME("iface %p, parameter %p, string %p stub\n", This, parameter, string);
2586 
2587     return E_NOTIMPL;
2588 }
2589 
2590 static HRESULT WINAPI ID3DXBaseEffectImpl_GetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
2591 {
2592     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2593     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2594 
2595     TRACE("iface %p, parameter %p, string %p\n", This, parameter, string);
2596 
2597     if (string && param && !param->element_count && param->type == D3DXPT_STRING)
2598     {
2599         *string = *(LPCSTR *)param->data;
2600         TRACE("Returning %s\n", debugstr_a(*string));
2601         return D3D_OK;
2602     }
2603 
2604     WARN("Invalid argument specified\n");
2605 
2606     return D3DERR_INVALIDCALL;
2607 }
2608 
2609 static HRESULT WINAPI ID3DXBaseEffectImpl_SetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
2610 {
2611     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2612     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2613 
2614     TRACE("iface %p, parameter %p, texture %p\n", This, parameter, texture);
2615 
2616     if (param && !param->element_count &&
2617             (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2618             || param->type == D3DXPT_TEXTURE2D || param->type ==  D3DXPT_TEXTURE3D
2619             || param->type == D3DXPT_TEXTURECUBE))
2620     {
2621         LPDIRECT3DBASETEXTURE9 oltexture = *(LPDIRECT3DBASETEXTURE9 *)param->data;
2622 
2623         if (texture) IDirect3DBaseTexture9_AddRef(texture);
2624         if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
2625 
2626         *(LPDIRECT3DBASETEXTURE9 *)param->data = texture;
2627 
2628         return D3D_OK;
2629     }
2630 
2631     WARN("Invalid argument specified\n");
2632 
2633     return D3DERR_INVALIDCALL;
2634 }
2635 
2636 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
2637 {
2638     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2639     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2640 
2641     TRACE("iface %p, parameter %p, texture %p\n", This, parameter, texture);
2642 
2643     if (texture && param && !param->element_count &&
2644             (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
2645             || param->type == D3DXPT_TEXTURE2D || param->type ==  D3DXPT_TEXTURE3D
2646             || param->type == D3DXPT_TEXTURECUBE))
2647     {
2648         *texture = *(LPDIRECT3DBASETEXTURE9 *)param->data;
2649         if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
2650         TRACE("Returning %p\n", *texture);
2651         return D3D_OK;
2652     }
2653 
2654     WARN("Invalid argument specified\n");
2655 
2656     return D3DERR_INVALIDCALL;
2657 }
2658 
2659 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPixelShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
2660 {
2661     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2662     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2663 
2664     TRACE("iface %p, parameter %p, pshader %p\n", This, parameter, pshader);
2665 
2666     if (pshader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
2667     {
2668         *pshader = *(LPDIRECT3DPIXELSHADER9 *)param->data;
2669         if (*pshader) IDirect3DPixelShader9_AddRef(*pshader);
2670         TRACE("Returning %p\n", *pshader);
2671         return D3D_OK;
2672     }
2673 
2674     WARN("Invalid argument specified\n");
2675 
2676     return D3DERR_INVALIDCALL;
2677 }
2678 
2679 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVertexShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
2680 {
2681     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2682     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
2683 
2684     TRACE("iface %p, parameter %p, vshader %p\n", This, parameter, vshader);
2685 
2686     if (vshader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
2687     {
2688         *vshader = *(LPDIRECT3DVERTEXSHADER9 *)param->data;
2689         if (*vshader) IDirect3DVertexShader9_AddRef(*vshader);
2690         TRACE("Returning %p\n", *vshader);
2691         return D3D_OK;
2692     }
2693 
2694     WARN("Invalid argument specified\n");
2695 
2696     return D3DERR_INVALIDCALL;
2697 }
2698 
2699 static HRESULT WINAPI ID3DXBaseEffectImpl_SetArrayRange(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
2700 {
2701     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
2702 
2703     FIXME("iface %p, parameter %p, start %u, end %u stub\n", This, parameter, start, end);
2704 
2705     return E_NOTIMPL;
2706 }
2707 
2708 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl =
2709 {
2710     /*** IUnknown methods ***/
2711     ID3DXBaseEffectImpl_QueryInterface,
2712     ID3DXBaseEffectImpl_AddRef,
2713     ID3DXBaseEffectImpl_Release,
2714     /*** ID3DXBaseEffect methods ***/
2715     ID3DXBaseEffectImpl_GetDesc,
2716     ID3DXBaseEffectImpl_GetParameterDesc,
2717     ID3DXBaseEffectImpl_GetTechniqueDesc,
2718     ID3DXBaseEffectImpl_GetPassDesc,
2719     ID3DXBaseEffectImpl_GetFunctionDesc,
2720     ID3DXBaseEffectImpl_GetParameter,
2721     ID3DXBaseEffectImpl_GetParameterByName,
2722     ID3DXBaseEffectImpl_GetParameterBySemantic,
2723     ID3DXBaseEffectImpl_GetParameterElement,
2724     ID3DXBaseEffectImpl_GetTechnique,
2725     ID3DXBaseEffectImpl_GetTechniqueByName,
2726     ID3DXBaseEffectImpl_GetPass,
2727     ID3DXBaseEffectImpl_GetPassByName,
2728     ID3DXBaseEffectImpl_GetFunction,
2729     ID3DXBaseEffectImpl_GetFunctionByName,
2730     ID3DXBaseEffectImpl_GetAnnotation,
2731     ID3DXBaseEffectImpl_GetAnnotationByName,
2732     ID3DXBaseEffectImpl_SetValue,
2733     ID3DXBaseEffectImpl_GetValue,
2734     ID3DXBaseEffectImpl_SetBool,
2735     ID3DXBaseEffectImpl_GetBool,
2736     ID3DXBaseEffectImpl_SetBoolArray,
2737     ID3DXBaseEffectImpl_GetBoolArray,
2738     ID3DXBaseEffectImpl_SetInt,
2739     ID3DXBaseEffectImpl_GetInt,
2740     ID3DXBaseEffectImpl_SetIntArray,
2741     ID3DXBaseEffectImpl_GetIntArray,
2742     ID3DXBaseEffectImpl_SetFloat,
2743     ID3DXBaseEffectImpl_GetFloat,
2744     ID3DXBaseEffectImpl_SetFloatArray,
2745     ID3DXBaseEffectImpl_GetFloatArray,
2746     ID3DXBaseEffectImpl_SetVector,
2747     ID3DXBaseEffectImpl_GetVector,
2748     ID3DXBaseEffectImpl_SetVectorArray,
2749     ID3DXBaseEffectImpl_GetVectorArray,
2750     ID3DXBaseEffectImpl_SetMatrix,
2751     ID3DXBaseEffectImpl_GetMatrix,
2752     ID3DXBaseEffectImpl_SetMatrixArray,
2753     ID3DXBaseEffectImpl_GetMatrixArray,
2754     ID3DXBaseEffectImpl_SetMatrixPointerArray,
2755     ID3DXBaseEffectImpl_GetMatrixPointerArray,
2756     ID3DXBaseEffectImpl_SetMatrixTranspose,
2757     ID3DXBaseEffectImpl_GetMatrixTranspose,
2758     ID3DXBaseEffectImpl_SetMatrixTransposeArray,
2759     ID3DXBaseEffectImpl_GetMatrixTransposeArray,
2760     ID3DXBaseEffectImpl_SetMatrixTransposePointerArray,
2761     ID3DXBaseEffectImpl_GetMatrixTransposePointerArray,
2762     ID3DXBaseEffectImpl_SetString,
2763     ID3DXBaseEffectImpl_GetString,
2764     ID3DXBaseEffectImpl_SetTexture,
2765     ID3DXBaseEffectImpl_GetTexture,
2766     ID3DXBaseEffectImpl_GetPixelShader,
2767     ID3DXBaseEffectImpl_GetVertexShader,
2768     ID3DXBaseEffectImpl_SetArrayRange,
2769 };
2770 
2771 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
2772 {
2773     return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
2774 }
2775 
2776 /*** IUnknown methods ***/
2777 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
2778 {
2779     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
2780 
2781     if (IsEqualGUID(riid, &IID_IUnknown) ||
2782         IsEqualGUID(riid, &IID_ID3DXEffect))
2783     {
2784         iface->lpVtbl->AddRef(iface);
2785         *object = iface;
2786         return S_OK;
2787     }
2788 
2789     ERR("Interface %s not found\n", debugstr_guid(riid));
2790 
2791     return E_NOINTERFACE;
2792 }
2793 
2794 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
2795 {
2796     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2797 
2798     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
2799 
2800     return InterlockedIncrement(&This->ref);
2801 }
2802 
2803 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
2804 {
2805     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2806     ULONG ref = InterlockedDecrement(&This->ref);
2807 
2808     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
2809 
2810     if (!ref)
2811     {
2812         free_effect(This);
2813         HeapFree(GetProcessHeap(), 0, This);
2814     }
2815 
2816     return ref;
2817 }
2818 
2819 /*** ID3DXBaseEffect methods ***/
2820 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
2821 {
2822     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2823     ID3DXBaseEffect *base = This->base_effect;
2824 
2825     TRACE("Forward iface %p, base %p\n", This, base);
2826 
2827     return ID3DXBaseEffectImpl_GetDesc(base, desc);
2828 }
2829 
2830 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
2831 {
2832     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2833     ID3DXBaseEffect *base = This->base_effect;
2834 
2835     TRACE("Forward iface %p, base %p\n", This, base);
2836 
2837     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
2838 }
2839 
2840 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
2841 {
2842     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2843     ID3DXBaseEffect *base = This->base_effect;
2844 
2845     TRACE("Forward iface %p, base %p\n", This, base);
2846 
2847     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
2848 }
2849 
2850 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
2851 {
2852     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2853     ID3DXBaseEffect *base = This->base_effect;
2854 
2855     TRACE("Forward iface %p, base %p\n", This, base);
2856 
2857     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
2858 }
2859 
2860 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
2861 {
2862     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2863     ID3DXBaseEffect *base = This->base_effect;
2864 
2865     TRACE("Forward iface %p, base %p\n", This, base);
2866 
2867     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
2868 }
2869 
2870 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2871 {
2872     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2873     ID3DXBaseEffect *base = This->base_effect;
2874 
2875     TRACE("Forward iface %p, base %p\n", This, base);
2876 
2877     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
2878 }
2879 
2880 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR name)
2881 {
2882     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2883     ID3DXBaseEffect *base = This->base_effect;
2884 
2885     TRACE("Forward iface %p, base %p\n", This, base);
2886 
2887     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
2888 }
2889 
2890 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
2891 {
2892     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2893     ID3DXBaseEffect *base = This->base_effect;
2894 
2895     TRACE("Forward iface %p, base %p\n", This, base);
2896 
2897     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
2898 }
2899 
2900 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
2901 {
2902     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2903     ID3DXBaseEffect *base = This->base_effect;
2904 
2905     TRACE("Forward iface %p, base %p\n", This, base);
2906 
2907     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
2908 }
2909 
2910 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
2911 {
2912     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2913     ID3DXBaseEffect *base = This->base_effect;
2914 
2915     TRACE("Forward iface %p, base %p\n", This, base);
2916 
2917     return ID3DXBaseEffectImpl_GetTechnique(base, index);
2918 }
2919 
2920 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, LPCSTR name)
2921 {
2922     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2923     ID3DXBaseEffect *base = This->base_effect;
2924 
2925     TRACE("Forward iface %p, base %p\n", This, base);
2926 
2927     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
2928 }
2929 
2930 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
2931 {
2932     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2933     ID3DXBaseEffect *base = This->base_effect;
2934 
2935     TRACE("Forward iface %p, base %p\n", This, base);
2936 
2937     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
2938 }
2939 
2940 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface, D3DXHANDLE technique, LPCSTR name)
2941 {
2942     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2943     ID3DXBaseEffect *base = This->base_effect;
2944 
2945     TRACE("Forward iface %p, base %p\n", This, base);
2946 
2947     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
2948 }
2949 
2950 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
2951 {
2952     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2953     ID3DXBaseEffect *base = This->base_effect;
2954 
2955     TRACE("Forward iface %p, base %p\n", This, base);
2956 
2957     return ID3DXBaseEffectImpl_GetFunction(base, index);
2958 }
2959 
2960 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, LPCSTR name)
2961 {
2962     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2963     ID3DXBaseEffect *base = This->base_effect;
2964 
2965     TRACE("Forward iface %p, base %p\n", This, base);
2966 
2967     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
2968 }
2969 
2970 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
2971 {
2972     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2973     ID3DXBaseEffect *base = This->base_effect;
2974 
2975     TRACE("Forward iface %p, base %p\n", This, base);
2976 
2977     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
2978 }
2979 
2980 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface, D3DXHANDLE object, LPCSTR name)
2981 {
2982     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2983     ID3DXBaseEffect *base = This->base_effect;
2984 
2985     TRACE("Forward iface %p, base %p\n", This, base);
2986 
2987     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
2988 }
2989 
2990 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
2991 {
2992     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
2993     ID3DXBaseEffect *base = This->base_effect;
2994 
2995     TRACE("Forward iface %p, base %p\n", This, base);
2996 
2997     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
2998 }
2999 
3000 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
3001 {
3002     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3003     ID3DXBaseEffect *base = This->base_effect;
3004 
3005     TRACE("Forward iface %p, base %p\n", This, base);
3006 
3007     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
3008 }
3009 
3010 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
3011 {
3012     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3013     ID3DXBaseEffect *base = This->base_effect;
3014 
3015     TRACE("Forward iface %p, base %p\n", This, base);
3016 
3017     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
3018 }
3019 
3020 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
3021 {
3022     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3023     ID3DXBaseEffect *base = This->base_effect;
3024 
3025     TRACE("Forward iface %p, base %p\n", This, base);
3026 
3027     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
3028 }
3029 
3030 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
3031 {
3032     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3033     ID3DXBaseEffect *base = This->base_effect;
3034 
3035     TRACE("Forward iface %p, base %p\n", This, base);
3036 
3037     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
3038 }
3039 
3040 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
3041 {
3042     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3043     ID3DXBaseEffect *base = This->base_effect;
3044 
3045     TRACE("Forward iface %p, base %p\n", This, base);
3046 
3047     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
3048 }
3049 
3050 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
3051 {
3052     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3053     ID3DXBaseEffect *base = This->base_effect;
3054 
3055     TRACE("Forward iface %p, base %p\n", This, base);
3056 
3057     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
3058 }
3059 
3060 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
3061 {
3062     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3063     ID3DXBaseEffect *base = This->base_effect;
3064 
3065     TRACE("Forward iface %p, base %p\n", This, base);
3066 
3067     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
3068 }
3069 
3070 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
3071 {
3072     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3073     ID3DXBaseEffect *base = This->base_effect;
3074 
3075     TRACE("Forward iface %p, base %p\n", This, base);
3076 
3077     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
3078 }
3079 
3080 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
3081 {
3082     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3083     ID3DXBaseEffect *base = This->base_effect;
3084 
3085     TRACE("Forward iface %p, base %p\n", This, base);
3086 
3087     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
3088 }
3089 
3090 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT f)
3091 {
3092     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3093     ID3DXBaseEffect *base = This->base_effect;
3094 
3095     TRACE("Forward iface %p, base %p\n", This, base);
3096 
3097     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
3098 }
3099 
3100 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f)
3101 {
3102     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3103     ID3DXBaseEffect *base = This->base_effect;
3104 
3105     TRACE("Forward iface %p, base %p\n", This, base);
3106 
3107     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
3108 }
3109 
3110 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
3111 {
3112     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3113     ID3DXBaseEffect *base = This->base_effect;
3114 
3115     TRACE("Forward iface %p, base %p\n", This, base);
3116 
3117     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
3118 }
3119 
3120 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
3121 {
3122     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3123     ID3DXBaseEffect *base = This->base_effect;
3124 
3125     TRACE("Forward iface %p, base %p\n", This, base);
3126 
3127     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
3128 }
3129 
3130 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
3131 {
3132     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3133     ID3DXBaseEffect *base = This->base_effect;
3134 
3135     TRACE("Forward iface %p, base %p\n", This, base);
3136 
3137     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
3138 }
3139 
3140 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
3141 {
3142     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3143     ID3DXBaseEffect *base = This->base_effect;
3144 
3145     TRACE("Forward iface %p, base %p\n", This, base);
3146 
3147     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
3148 }
3149 
3150 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
3151 {
3152     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3153     ID3DXBaseEffect *base = This->base_effect;
3154 
3155     TRACE("Forward iface %p, base %p\n", This, base);
3156 
3157     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
3158 }
3159 
3160 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
3161 {
3162     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3163     ID3DXBaseEffect *base = This->base_effect;
3164 
3165     TRACE("Forward iface %p, base %p\n", This, base);
3166 
3167     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
3168 }
3169 
3170 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
3171 {
3172     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3173     ID3DXBaseEffect *base = This->base_effect;
3174 
3175     TRACE("Forward iface %p, base %p\n", This, base);
3176 
3177     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
3178 }
3179 
3180 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
3181 {
3182     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3183     ID3DXBaseEffect *base = This->base_effect;
3184 
3185     TRACE("Forward iface %p, base %p\n", This, base);
3186 
3187     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
3188 }
3189 
3190 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
3191 {
3192     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3193     ID3DXBaseEffect *base = This->base_effect;
3194 
3195     TRACE("Forward iface %p, base %p\n", This, base);
3196 
3197     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
3198 }
3199 
3200 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3201 {
3202     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3203     ID3DXBaseEffect *base = This->base_effect;
3204 
3205     TRACE("Forward iface %p, base %p\n", This, base);
3206 
3207     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
3208 }
3209 
3210 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
3211 {
3212     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3213     ID3DXBaseEffect *base = This->base_effect;
3214 
3215     TRACE("Forward iface %p, base %p\n", This, base);
3216 
3217     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
3218 }
3219 
3220 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3221 {
3222     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3223     ID3DXBaseEffect *base = This->base_effect;
3224 
3225     TRACE("Forward iface %p, base %p\n", This, base);
3226 
3227     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
3228 }
3229 
3230 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
3231 {
3232     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3233     ID3DXBaseEffect *base = This->base_effect;
3234 
3235     TRACE("Forward iface %p, base %p\n", This, base);
3236 
3237     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
3238 }
3239 
3240 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
3241 {
3242     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3243     ID3DXBaseEffect *base = This->base_effect;
3244 
3245     TRACE("Forward iface %p, base %p\n", This, base);
3246 
3247     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
3248 }
3249 
3250 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
3251 {
3252     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3253     ID3DXBaseEffect *base = This->base_effect;
3254 
3255     TRACE("Forward iface %p, base %p\n", This, base);
3256 
3257     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
3258 }
3259 
3260 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
3261 {
3262     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3263     ID3DXBaseEffect *base = This->base_effect;
3264 
3265     TRACE("Forward iface %p, base %p\n", This, base);
3266 
3267     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
3268 }
3269 
3270 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
3271 {
3272     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3273     ID3DXBaseEffect *base = This->base_effect;
3274 
3275     TRACE("Forward iface %p, base %p\n", This, base);
3276 
3277     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
3278 }
3279 
3280 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
3281 {
3282     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3283     ID3DXBaseEffect *base = This->base_effect;
3284 
3285     TRACE("Forward iface %p, base %p\n", This, base);
3286 
3287     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
3288 }
3289 
3290 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR string)
3291 {
3292     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3293     ID3DXBaseEffect *base = This->base_effect;
3294 
3295     TRACE("Forward iface %p, base %p\n", This, base);
3296 
3297     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
3298 }
3299 
3300 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
3301 {
3302     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3303     ID3DXBaseEffect *base = This->base_effect;
3304 
3305     TRACE("Forward iface %p, base %p\n", This, base);
3306 
3307     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
3308 }
3309 
3310 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
3311 {
3312     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3313     ID3DXBaseEffect *base = This->base_effect;
3314 
3315     TRACE("Forward iface %p, base %p\n", This, base);
3316 
3317     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
3318 }
3319 
3320 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
3321 {
3322     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3323     ID3DXBaseEffect *base = This->base_effect;
3324 
3325     TRACE("Forward iface %p, base %p\n", This, base);
3326 
3327     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
3328 }
3329 
3330 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
3331 {
3332     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3333     ID3DXBaseEffect *base = This->base_effect;
3334 
3335     TRACE("Forward iface %p, base %p\n", This, base);
3336 
3337     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
3338 }
3339 
3340 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
3341 {
3342     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3343     ID3DXBaseEffect *base = This->base_effect;
3344 
3345     TRACE("Forward iface %p, base %p\n", This, base);
3346 
3347     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
3348 }
3349 
3350 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
3351 {
3352     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3353     ID3DXBaseEffect *base = This->base_effect;
3354 
3355     TRACE("Forward iface %p, base %p\n", This, base);
3356 
3357     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
3358 }
3359 
3360 /*** ID3DXEffect methods ***/
3361 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, LPD3DXEFFECTPOOL *pool)
3362 {
3363     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3364 
3365     TRACE("iface %p, pool %p\n", This, pool);
3366 
3367     if (!pool)
3368     {
3369         WARN("Invalid argument supplied.\n");
3370         return D3DERR_INVALIDCALL;
3371     }
3372 
3373     if (This->pool)
3374     {
3375         This->pool->lpVtbl->AddRef(This->pool);
3376     }
3377 
3378     *pool = This->pool;
3379 
3380     TRACE("Returning pool %p\n", *pool);
3381 
3382     return S_OK;
3383 }
3384 
3385 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
3386 {
3387     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3388     struct ID3DXBaseEffectImpl *base = impl_from_ID3DXBaseEffect(This->base_effect);
3389     struct d3dx_technique *tech = is_valid_technique(base, technique);
3390 
3391     TRACE("iface %p, technique %p\n", This, technique);
3392 
3393     if (!tech) tech = get_technique_struct(iface->lpVtbl->GetTechniqueByName(iface, technique));
3394 
3395     if (tech)
3396     {
3397         UINT i;
3398 
3399         for (i = 0; i < base->technique_count; ++i)
3400         {
3401             struct d3dx_technique *t = get_technique_struct(base->technique_handles[i]);
3402 
3403             if (tech == t)
3404             {
3405                 This->active_technique = get_technique_handle(t);
3406                 TRACE("Technique %u (%p)\n", i, tech);
3407                 return D3D_OK;
3408             }
3409         }
3410     }
3411 
3412     WARN("Invalid argument supplied.\n");
3413 
3414     return D3DERR_INVALIDCALL;
3415 }
3416 
3417 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
3418 {
3419     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3420 
3421     TRACE("iface %p\n", This);
3422 
3423     return This->active_technique;
3424 }
3425 
3426 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
3427 {
3428     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3429 
3430     FIXME("(%p)->(%p): stub\n", This, technique);
3431 
3432     return D3D_OK;
3433 }
3434 
3435 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
3436 {
3437     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3438 
3439     FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
3440 
3441     return E_NOTIMPL;
3442 }
3443 
3444 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
3445 {
3446     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3447 
3448     FIXME("(%p)->(%p, %p): stub\n", This, parameter, technique);
3449 
3450     return FALSE;
3451 }
3452 
3453 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
3454 {
3455     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3456     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
3457 
3458     FIXME("iface %p, passes %p, flags %#x partial stub\n", This, passes, flags);
3459 
3460     if (passes && technique)
3461     {
3462         if (This->manager || flags & D3DXFX_DONOTSAVESTATE)
3463         {
3464             TRACE("State capturing disabled.\n");
3465         }
3466         else
3467         {
3468             FIXME("State capturing not supported, yet!\n");
3469         }
3470 
3471         *passes = technique->pass_count;
3472 
3473         return D3D_OK;
3474     }
3475 
3476     WARN("Invalid argument supplied.\n");
3477 
3478     return D3DERR_INVALIDCALL;
3479 }
3480 
3481 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
3482 {
3483     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3484     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
3485 
3486     TRACE("iface %p, pass %u\n", This, pass);
3487 
3488     if (technique && pass < technique->pass_count && !This->active_pass)
3489     {
3490         This->active_pass = technique->pass_handles[pass];
3491 
3492         FIXME("No states applied, yet!\n");
3493 
3494         return D3D_OK;
3495     }
3496 
3497     WARN("Invalid argument supplied.\n");
3498 
3499     return D3DERR_INVALIDCALL;
3500 }
3501 
3502 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect* iface)
3503 {
3504     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3505 
3506     FIXME("(%p)->(): stub\n", This);
3507 
3508     return E_NOTIMPL;
3509 }
3510 
3511 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
3512 {
3513     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3514 
3515     TRACE("iface %p\n", This);
3516 
3517     if (This->active_pass)
3518     {
3519          This->active_pass = NULL;
3520          return D3D_OK;
3521     }
3522 
3523     WARN("Invalid call.\n");
3524 
3525     return D3DERR_INVALIDCALL;
3526 }
3527 
3528 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect* iface)
3529 {
3530     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3531 
3532     FIXME("(%p)->(): stub\n", This);
3533 
3534     return E_NOTIMPL;
3535 }
3536 
3537 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, LPDIRECT3DDEVICE9 *device)
3538 {
3539     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3540 
3541     TRACE("iface %p, device %p\n", This, device);
3542 
3543     if (!device)
3544     {
3545         WARN("Invalid argument supplied.\n");
3546         return D3DERR_INVALIDCALL;
3547     }
3548 
3549     IDirect3DDevice9_AddRef(This->device);
3550 
3551     *device = This->device;
3552 
3553     TRACE("Returning device %p\n", *device);
3554 
3555     return S_OK;
3556 }
3557 
3558 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
3559 {
3560     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3561 
3562     FIXME("(%p)->(): stub\n", This);
3563 
3564     return E_NOTIMPL;
3565 }
3566 
3567 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
3568 {
3569     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3570 
3571     FIXME("(%p)->(): stub\n", This);
3572 
3573     return E_NOTIMPL;
3574 }
3575 
3576 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER manager)
3577 {
3578     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3579 
3580     TRACE("iface %p, manager %p\n", This, manager);
3581 
3582     if (manager) IUnknown_AddRef(manager);
3583     if (This->manager) IUnknown_Release(This->manager);
3584 
3585     This->manager = manager;
3586 
3587     return D3D_OK;
3588 }
3589 
3590 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER *manager)
3591 {
3592     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3593 
3594     TRACE("iface %p, manager %p\n", This, manager);
3595 
3596     if (!manager)
3597     {
3598         WARN("Invalid argument supplied.\n");
3599         return D3DERR_INVALIDCALL;
3600     }
3601 
3602     if (This->manager) IUnknown_AddRef(This->manager);
3603     *manager = This->manager;
3604 
3605     return D3D_OK;
3606 }
3607 
3608 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
3609 {
3610     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3611 
3612     FIXME("(%p)->(): stub\n", This);
3613 
3614     return E_NOTIMPL;
3615 }
3616 
3617 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
3618 {
3619     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3620 
3621     FIXME("(%p)->(): stub\n", This);
3622 
3623     return NULL;
3624 }
3625 
3626 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
3627 {
3628     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3629 
3630     FIXME("(%p)->(%p): stub\n", This, parameter_block);
3631 
3632     return E_NOTIMPL;
3633 }
3634 
3635 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
3636 {
3637     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3638 
3639     FIXME("(%p)->(%p): stub\n", This, parameter_block);
3640 
3641     return E_NOTIMPL;
3642 }
3643 
3644 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect* iface, LPDIRECT3DDEVICE9 device, LPD3DXEFFECT* effect)
3645 {
3646     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3647 
3648     FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
3649 
3650     return E_NOTIMPL;
3651 }
3652 
3653 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect* iface, D3DXHANDLE parameter, LPCVOID data, UINT byte_offset, UINT bytes)
3654 {
3655     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
3656 
3657     FIXME("(%p)->(%p, %p, %u, %u): stub\n", This, parameter, data, byte_offset, bytes);
3658 
3659     return E_NOTIMPL;
3660 }
3661 
3662 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
3663 {
3664     /*** IUnknown methods ***/
3665     ID3DXEffectImpl_QueryInterface,
3666     ID3DXEffectImpl_AddRef,
3667     ID3DXEffectImpl_Release,
3668     /*** ID3DXBaseEffect methods ***/
3669     ID3DXEffectImpl_GetDesc,
3670     ID3DXEffectImpl_GetParameterDesc,
3671     ID3DXEffectImpl_GetTechniqueDesc,
3672     ID3DXEffectImpl_GetPassDesc,
3673     ID3DXEffectImpl_GetFunctionDesc,
3674     ID3DXEffectImpl_GetParameter,
3675     ID3DXEffectImpl_GetParameterByName,
3676     ID3DXEffectImpl_GetParameterBySemantic,
3677     ID3DXEffectImpl_GetParameterElement,
3678     ID3DXEffectImpl_GetTechnique,
3679     ID3DXEffectImpl_GetTechniqueByName,
3680     ID3DXEffectImpl_GetPass,
3681     ID3DXEffectImpl_GetPassByName,
3682     ID3DXEffectImpl_GetFunction,
3683     ID3DXEffectImpl_GetFunctionByName,
3684     ID3DXEffectImpl_GetAnnotation,
3685     ID3DXEffectImpl_GetAnnotationByName,
3686     ID3DXEffectImpl_SetValue,
3687     ID3DXEffectImpl_GetValue,
3688     ID3DXEffectImpl_SetBool,
3689     ID3DXEffectImpl_GetBool,
3690     ID3DXEffectImpl_SetBoolArray,
3691     ID3DXEffectImpl_GetBoolArray,
3692     ID3DXEffectImpl_SetInt,
3693     ID3DXEffectImpl_GetInt,
3694     ID3DXEffectImpl_SetIntArray,
3695     ID3DXEffectImpl_GetIntArray,
3696     ID3DXEffectImpl_SetFloat,
3697     ID3DXEffectImpl_GetFloat,
3698     ID3DXEffectImpl_SetFloatArray,
3699     ID3DXEffectImpl_GetFloatArray,
3700     ID3DXEffectImpl_SetVector,
3701     ID3DXEffectImpl_GetVector,
3702     ID3DXEffectImpl_SetVectorArray,
3703     ID3DXEffectImpl_GetVectorArray,
3704     ID3DXEffectImpl_SetMatrix,
3705     ID3DXEffectImpl_GetMatrix,
3706     ID3DXEffectImpl_SetMatrixArray,
3707     ID3DXEffectImpl_GetMatrixArray,
3708     ID3DXEffectImpl_SetMatrixPointerArray,
3709     ID3DXEffectImpl_GetMatrixPointerArray,
3710     ID3DXEffectImpl_SetMatrixTranspose,
3711     ID3DXEffectImpl_GetMatrixTranspose,
3712     ID3DXEffectImpl_SetMatrixTransposeArray,
3713     ID3DXEffectImpl_GetMatrixTransposeArray,
3714     ID3DXEffectImpl_SetMatrixTransposePointerArray,
3715     ID3DXEffectImpl_GetMatrixTransposePointerArray,
3716     ID3DXEffectImpl_SetString,
3717     ID3DXEffectImpl_GetString,
3718     ID3DXEffectImpl_SetTexture,
3719     ID3DXEffectImpl_GetTexture,
3720     ID3DXEffectImpl_GetPixelShader,
3721     ID3DXEffectImpl_GetVertexShader,
3722     ID3DXEffectImpl_SetArrayRange,
3723     /*** ID3DXEffect methods ***/
3724     ID3DXEffectImpl_GetPool,
3725     ID3DXEffectImpl_SetTechnique,
3726     ID3DXEffectImpl_GetCurrentTechnique,
3727     ID3DXEffectImpl_ValidateTechnique,
3728     ID3DXEffectImpl_FindNextValidTechnique,
3729     ID3DXEffectImpl_IsParameterUsed,
3730     ID3DXEffectImpl_Begin,
3731     ID3DXEffectImpl_BeginPass,
3732     ID3DXEffectImpl_CommitChanges,
3733     ID3DXEffectImpl_EndPass,
3734     ID3DXEffectImpl_End,
3735     ID3DXEffectImpl_GetDevice,
3736     ID3DXEffectImpl_OnLostDevice,
3737     ID3DXEffectImpl_OnResetDevice,
3738     ID3DXEffectImpl_SetStateManager,
3739     ID3DXEffectImpl_GetStateManager,
3740     ID3DXEffectImpl_BeginParameterBlock,
3741     ID3DXEffectImpl_EndParameterBlock,
3742     ID3DXEffectImpl_ApplyParameterBlock,
3743     ID3DXEffectImpl_DeleteParameterBlock,
3744     ID3DXEffectImpl_CloneEffect,
3745     ID3DXEffectImpl_SetRawValue
3746 };
3747 
3748 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
3749 {
3750     return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
3751 }
3752 
3753 /*** IUnknown methods ***/
3754 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
3755 {
3756     TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
3757 
3758     if (IsEqualGUID(riid, &IID_IUnknown) ||
3759         IsEqualGUID(riid, &IID_ID3DXEffectCompiler))
3760     {
3761         iface->lpVtbl->AddRef(iface);
3762         *object = iface;
3763         return S_OK;
3764     }
3765 
3766     ERR("Interface %s not found\n", debugstr_guid(riid));
3767 
3768     return E_NOINTERFACE;
3769 }
3770 
3771 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
3772 {
3773     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3774 
3775     TRACE("iface %p: AddRef from %u\n", iface, This->ref);
3776 
3777     return InterlockedIncrement(&This->ref);
3778 }
3779 
3780 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
3781 {
3782     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3783     ULONG ref = InterlockedDecrement(&This->ref);
3784 
3785     TRACE("iface %p: Release from %u\n", iface, ref + 1);
3786 
3787     if (!ref)
3788     {
3789         free_effect_compiler(This);
3790         HeapFree(GetProcessHeap(), 0, This);
3791     }
3792 
3793     return ref;
3794 }
3795 
3796 /*** ID3DXBaseEffect methods ***/
3797 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
3798 {
3799     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3800     ID3DXBaseEffect *base = This->base_effect;
3801 
3802     TRACE("Forward iface %p, base %p\n", This, base);
3803 
3804     return ID3DXBaseEffectImpl_GetDesc(base, desc);
3805 }
3806 
3807 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
3808 {
3809     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3810     ID3DXBaseEffect *base = This->base_effect;
3811 
3812     TRACE("Forward iface %p, base %p\n", This, base);
3813 
3814     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
3815 }
3816 
3817 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
3818 {
3819     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3820     ID3DXBaseEffect *base = This->base_effect;
3821 
3822     TRACE("Forward iface %p, base %p\n", This, base);
3823 
3824     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
3825 }
3826 
3827 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
3828 {
3829     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3830     ID3DXBaseEffect *base = This->base_effect;
3831 
3832     TRACE("Forward iface %p, base %p\n", This, base);
3833 
3834     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
3835 }
3836 
3837 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
3838 {
3839     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3840     ID3DXBaseEffect *base = This->base_effect;
3841 
3842     TRACE("Forward iface %p, base %p\n", This, base);
3843 
3844     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
3845 }
3846 
3847 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
3848 {
3849     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3850     ID3DXBaseEffect *base = This->base_effect;
3851 
3852     TRACE("Forward iface %p, base %p\n", This, base);
3853 
3854     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
3855 }
3856 
3857 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR name)
3858 {
3859     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3860     ID3DXBaseEffect *base = This->base_effect;
3861 
3862     TRACE("Forward iface %p, base %p\n", This, base);
3863 
3864     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
3865 }
3866 
3867 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR semantic)
3868 {
3869     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3870     ID3DXBaseEffect *base = This->base_effect;
3871 
3872     TRACE("Forward iface %p, base %p\n", This, base);
3873 
3874     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
3875 }
3876 
3877 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
3878 {
3879     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3880     ID3DXBaseEffect *base = This->base_effect;
3881 
3882     TRACE("Forward iface %p, base %p\n", This, base);
3883 
3884     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
3885 }
3886 
3887 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
3888 {
3889     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3890     ID3DXBaseEffect *base = This->base_effect;
3891 
3892     TRACE("Forward iface %p, base %p\n", This, base);
3893 
3894     return ID3DXBaseEffectImpl_GetTechnique(base, index);
3895 }
3896 
3897 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, LPCSTR name)
3898 {
3899     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3900     ID3DXBaseEffect *base = This->base_effect;
3901 
3902     TRACE("Forward iface %p, base %p\n", This, base);
3903 
3904     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
3905 }
3906 
3907 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
3908 {
3909     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3910     ID3DXBaseEffect *base = This->base_effect;
3911 
3912     TRACE("Forward iface %p, base %p\n", This, base);
3913 
3914     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
3915 }
3916 
3917 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface, D3DXHANDLE technique, LPCSTR name)
3918 {
3919     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3920     ID3DXBaseEffect *base = This->base_effect;
3921 
3922     TRACE("Forward iface %p, base %p\n", This, base);
3923 
3924     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
3925 }
3926 
3927 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
3928 {
3929     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3930     ID3DXBaseEffect *base = This->base_effect;
3931 
3932     TRACE("Forward iface %p, base %p\n", This, base);
3933 
3934     return ID3DXBaseEffectImpl_GetFunction(base, index);
3935 }
3936 
3937 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, LPCSTR name)
3938 {
3939     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3940     ID3DXBaseEffect *base = This->base_effect;
3941 
3942     TRACE("Forward iface %p, base %p\n", This, base);
3943 
3944     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
3945 }
3946 
3947 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface, D3DXHANDLE object, UINT index)
3948 {
3949     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3950     ID3DXBaseEffect *base = This->base_effect;
3951 
3952     TRACE("Forward iface %p, base %p\n", This, base);
3953 
3954     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
3955 }
3956 
3957 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface, D3DXHANDLE object, LPCSTR name)
3958 {
3959     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3960     ID3DXBaseEffect *base = This->base_effect;
3961 
3962     TRACE("Forward iface %p, base %p\n", This, base);
3963 
3964     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
3965 }
3966 
3967 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
3968 {
3969     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3970     ID3DXBaseEffect *base = This->base_effect;
3971 
3972     TRACE("Forward iface %p, base %p\n", This, base);
3973 
3974     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
3975 }
3976 
3977 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
3978 {
3979     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3980     ID3DXBaseEffect *base = This->base_effect;
3981 
3982     TRACE("Forward iface %p, base %p\n", This, base);
3983 
3984     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
3985 }
3986 
3987 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
3988 {
3989     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
3990     ID3DXBaseEffect *base = This->base_effect;
3991 
3992     TRACE("Forward iface %p, base %p\n", This, base);
3993 
3994     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
3995 }
3996 
3997 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
3998 {
3999     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4000     ID3DXBaseEffect *base = This->base_effect;
4001 
4002     TRACE("Forward iface %p, base %p\n", This, base);
4003 
4004     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
4005 }
4006 
4007 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
4008 {
4009     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4010     ID3DXBaseEffect *base = This->base_effect;
4011 
4012     TRACE("Forward iface %p, base %p\n", This, base);
4013 
4014     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
4015 }
4016 
4017 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
4018 {
4019     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4020     ID3DXBaseEffect *base = This->base_effect;
4021 
4022     TRACE("Forward iface %p, base %p\n", This, base);
4023 
4024     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
4025 }
4026 
4027 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
4028 {
4029     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4030     ID3DXBaseEffect *base = This->base_effect;
4031 
4032     TRACE("Forward iface %p, base %p\n", This, base);
4033 
4034     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
4035 }
4036 
4037 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
4038 {
4039     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4040     ID3DXBaseEffect *base = This->base_effect;
4041 
4042     TRACE("Forward iface %p, base %p\n", This, base);
4043 
4044     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
4045 }
4046 
4047 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
4048 {
4049     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4050     ID3DXBaseEffect *base = This->base_effect;
4051 
4052     TRACE("Forward iface %p, base %p\n", This, base);
4053 
4054     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
4055 }
4056 
4057 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n, UINT count)
4058 {
4059     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4060     ID3DXBaseEffect *base = This->base_effect;
4061 
4062     TRACE("Forward iface %p, base %p\n", This, base);
4063 
4064     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
4065 }
4066 
4067 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT f)
4068 {
4069     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4070     ID3DXBaseEffect *base = This->base_effect;
4071 
4072     TRACE("Forward iface %p, base %p\n", This, base);
4073 
4074     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
4075 }
4076 
4077 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f)
4078 {
4079     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4080     ID3DXBaseEffect *base = This->base_effect;
4081 
4082     TRACE("Forward iface %p, base %p\n", This, base);
4083 
4084     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
4085 }
4086 
4087 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
4088 {
4089     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4090     ID3DXBaseEffect *base = This->base_effect;
4091 
4092     TRACE("Forward iface %p, base %p\n", This, base);
4093 
4094     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
4095 }
4096 
4097 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
4098 {
4099     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4100     ID3DXBaseEffect *base = This->base_effect;
4101 
4102     TRACE("Forward iface %p, base %p\n", This, base);
4103 
4104     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
4105 }
4106 
4107 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
4108 {
4109     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4110     ID3DXBaseEffect *base = This->base_effect;
4111 
4112     TRACE("Forward iface %p, base %p\n", This, base);
4113 
4114     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
4115 }
4116 
4117 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
4118 {
4119     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4120     ID3DXBaseEffect *base = This->base_effect;
4121 
4122     TRACE("Forward iface %p, base %p\n", This, base);
4123 
4124     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
4125 }
4126 
4127 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
4128 {
4129     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4130     ID3DXBaseEffect *base = This->base_effect;
4131 
4132     TRACE("Forward iface %p, base %p\n", This, base);
4133 
4134     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
4135 }
4136 
4137 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
4138 {
4139     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4140     ID3DXBaseEffect *base = This->base_effect;
4141 
4142     TRACE("Forward iface %p, base %p\n", This, base);
4143 
4144     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
4145 }
4146 
4147 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
4148 {
4149     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4150     ID3DXBaseEffect *base = This->base_effect;
4151 
4152     TRACE("Forward iface %p, base %p\n", This, base);
4153 
4154     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
4155 }
4156 
4157 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
4158 {
4159     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4160     ID3DXBaseEffect *base = This->base_effect;
4161 
4162     TRACE("Forward iface %p, base %p\n", This, base);
4163 
4164     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
4165 }
4166 
4167 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
4168 {
4169     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4170     ID3DXBaseEffect *base = This->base_effect;
4171 
4172     TRACE("Forward iface %p, base %p\n", This, base);
4173 
4174     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
4175 }
4176 
4177 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4178 {
4179     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4180     ID3DXBaseEffect *base = This->base_effect;
4181 
4182     TRACE("Forward iface %p, base %p\n", This, base);
4183 
4184     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
4185 }
4186 
4187 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
4188 {
4189     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4190     ID3DXBaseEffect *base = This->base_effect;
4191 
4192     TRACE("Forward iface %p, base %p\n", This, base);
4193 
4194     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
4195 }
4196 
4197 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4198 {
4199     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4200     ID3DXBaseEffect *base = This->base_effect;
4201 
4202     TRACE("Forward iface %p, base %p\n", This, base);
4203 
4204     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
4205 }
4206 
4207 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
4208 {
4209     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4210     ID3DXBaseEffect *base = This->base_effect;
4211 
4212     TRACE("Forward iface %p, base %p\n", This, base);
4213 
4214     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
4215 }
4216 
4217 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
4218 {
4219     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4220     ID3DXBaseEffect *base = This->base_effect;
4221 
4222     TRACE("Forward iface %p, base %p\n", This, base);
4223 
4224     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
4225 }
4226 
4227 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
4228 {
4229     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4230     ID3DXBaseEffect *base = This->base_effect;
4231 
4232     TRACE("Forward iface %p, base %p\n", This, base);
4233 
4234     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
4235 }
4236 
4237 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
4238 {
4239     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4240     ID3DXBaseEffect *base = This->base_effect;
4241 
4242     TRACE("Forward iface %p, base %p\n", This, base);
4243 
4244     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
4245 }
4246 
4247 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
4248 {
4249     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4250     ID3DXBaseEffect *base = This->base_effect;
4251 
4252     TRACE("Forward iface %p, base %p\n", This, base);
4253 
4254     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
4255 }
4256 
4257 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
4258 {
4259     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4260     ID3DXBaseEffect *base = This->base_effect;
4261 
4262     TRACE("Forward iface %p, base %p\n", This, base);
4263 
4264     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
4265 }
4266 
4267 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR string)
4268 {
4269     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4270     ID3DXBaseEffect *base = This->base_effect;
4271 
4272     TRACE("Forward iface %p, base %p\n", This, base);
4273 
4274     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
4275 }
4276 
4277 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR *string)
4278 {
4279     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4280     ID3DXBaseEffect *base = This->base_effect;
4281 
4282     TRACE("Forward iface %p, base %p\n", This, base);
4283 
4284     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
4285 }
4286 
4287 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
4288 {
4289     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4290     ID3DXBaseEffect *base = This->base_effect;
4291 
4292     TRACE("Forward iface %p, base %p\n", This, base);
4293 
4294     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
4295 }
4296 
4297 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
4298 {
4299     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4300     ID3DXBaseEffect *base = This->base_effect;
4301 
4302     TRACE("Forward iface %p, base %p\n", This, base);
4303 
4304     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
4305 }
4306 
4307 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
4308 {
4309     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4310     ID3DXBaseEffect *base = This->base_effect;
4311 
4312     TRACE("Forward iface %p, base %p\n", This, base);
4313 
4314     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
4315 }
4316 
4317 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
4318 {
4319     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4320     ID3DXBaseEffect *base = This->base_effect;
4321 
4322     TRACE("Forward iface %p, base %p\n", This, base);
4323 
4324     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
4325 }
4326 
4327 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT start, UINT end)
4328 {
4329     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4330     ID3DXBaseEffect *base = This->base_effect;
4331 
4332     TRACE("Forward iface %p, base %p\n", This, base);
4333 
4334     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
4335 }
4336 
4337 /*** ID3DXEffectCompiler methods ***/
4338 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
4339 {
4340     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4341 
4342     FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
4343 
4344     return E_NOTIMPL;
4345 }
4346 
4347 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
4348 {
4349     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4350 
4351     FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
4352 
4353     return E_NOTIMPL;
4354 }
4355 
4356 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
4357         LPD3DXBUFFER *effect, LPD3DXBUFFER *error_msgs)
4358 {
4359     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4360 
4361     FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
4362 
4363     return E_NOTIMPL;
4364 }
4365 
4366 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
4367         LPCSTR target, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *error_msgs, LPD3DXCONSTANTTABLE *constant_table)
4368 {
4369     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
4370 
4371     FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
4372             This, function, target, flags, shader, error_msgs, constant_table);
4373 
4374     return E_NOTIMPL;
4375 }
4376 
4377 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
4378 {
4379     /*** IUnknown methods ***/
4380     ID3DXEffectCompilerImpl_QueryInterface,
4381     ID3DXEffectCompilerImpl_AddRef,
4382     ID3DXEffectCompilerImpl_Release,
4383     /*** ID3DXBaseEffect methods ***/
4384     ID3DXEffectCompilerImpl_GetDesc,
4385     ID3DXEffectCompilerImpl_GetParameterDesc,
4386     ID3DXEffectCompilerImpl_GetTechniqueDesc,
4387     ID3DXEffectCompilerImpl_GetPassDesc,
4388     ID3DXEffectCompilerImpl_GetFunctionDesc,
4389     ID3DXEffectCompilerImpl_GetParameter,
4390     ID3DXEffectCompilerImpl_GetParameterByName,
4391     ID3DXEffectCompilerImpl_GetParameterBySemantic,
4392     ID3DXEffectCompilerImpl_GetParameterElement,
4393     ID3DXEffectCompilerImpl_GetTechnique,
4394     ID3DXEffectCompilerImpl_GetTechniqueByName,
4395     ID3DXEffectCompilerImpl_GetPass,
4396     ID3DXEffectCompilerImpl_GetPassByName,
4397     ID3DXEffectCompilerImpl_GetFunction,
4398     ID3DXEffectCompilerImpl_GetFunctionByName,
4399     ID3DXEffectCompilerImpl_GetAnnotation,
4400     ID3DXEffectCompilerImpl_GetAnnotationByName,
4401     ID3DXEffectCompilerImpl_SetValue,
4402     ID3DXEffectCompilerImpl_GetValue,
4403     ID3DXEffectCompilerImpl_SetBool,
4404     ID3DXEffectCompilerImpl_GetBool,
4405     ID3DXEffectCompilerImpl_SetBoolArray,
4406     ID3DXEffectCompilerImpl_GetBoolArray,
4407     ID3DXEffectCompilerImpl_SetInt,
4408     ID3DXEffectCompilerImpl_GetInt,
4409     ID3DXEffectCompilerImpl_SetIntArray,
4410     ID3DXEffectCompilerImpl_GetIntArray,
4411     ID3DXEffectCompilerImpl_SetFloat,
4412     ID3DXEffectCompilerImpl_GetFloat,
4413     ID3DXEffectCompilerImpl_SetFloatArray,
4414     ID3DXEffectCompilerImpl_GetFloatArray,
4415     ID3DXEffectCompilerImpl_SetVector,
4416     ID3DXEffectCompilerImpl_GetVector,
4417     ID3DXEffectCompilerImpl_SetVectorArray,
4418     ID3DXEffectCompilerImpl_GetVectorArray,
4419     ID3DXEffectCompilerImpl_SetMatrix,
4420     ID3DXEffectCompilerImpl_GetMatrix,
4421     ID3DXEffectCompilerImpl_SetMatrixArray,
4422     ID3DXEffectCompilerImpl_GetMatrixArray,
4423     ID3DXEffectCompilerImpl_SetMatrixPointerArray,
4424     ID3DXEffectCompilerImpl_GetMatrixPointerArray,
4425     ID3DXEffectCompilerImpl_SetMatrixTranspose,
4426     ID3DXEffectCompilerImpl_GetMatrixTranspose,
4427     ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
4428     ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
4429     ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
4430     ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
4431     ID3DXEffectCompilerImpl_SetString,
4432     ID3DXEffectCompilerImpl_GetString,
4433     ID3DXEffectCompilerImpl_SetTexture,
4434     ID3DXEffectCompilerImpl_GetTexture,
4435     ID3DXEffectCompilerImpl_GetPixelShader,
4436     ID3DXEffectCompilerImpl_GetVertexShader,
4437     ID3DXEffectCompilerImpl_SetArrayRange,
4438     /*** ID3DXEffectCompiler methods ***/
4439     ID3DXEffectCompilerImpl_SetLiteral,
4440     ID3DXEffectCompilerImpl_GetLiteral,
4441     ID3DXEffectCompilerImpl_CompileEffect,
4442     ID3DXEffectCompilerImpl_CompileShader,
4443 };
4444 
4445 static HRESULT d3dx9_parse_sampler(struct d3dx_sampler *sampler, const char *data, const char **ptr, D3DXHANDLE *objects)
4446 {
4447     HRESULT hr;
4448     UINT i;
4449     struct d3dx_state *states;
4450 
4451     read_dword(ptr, &sampler->state_count);
4452     TRACE("Count: %u\n", sampler->state_count);
4453 
4454     states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * sampler->state_count);
4455     if (!states)
4456     {
4457         ERR("Out of memory\n");
4458         return E_OUTOFMEMORY;
4459     }
4460 
4461     for (i = 0; i < sampler->state_count; ++i)
4462     {
4463         hr = d3dx9_parse_state(&states[i], data, ptr, objects);
4464         if (hr != D3D_OK)
4465         {
4466             WARN("Failed to parse state\n");
4467             goto err_out;
4468         }
4469     }
4470 
4471     sampler->states = states;
4472 
4473     return D3D_OK;
4474 
4475 err_out:
4476 
4477     for (i = 0; i < sampler->state_count; ++i)
4478     {
4479         free_state(&states[i]);
4480     }
4481 
4482     HeapFree(GetProcessHeap(), 0, states);
4483 
4484     return hr;
4485 }
4486 
4487 static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, const char *data, const char **ptr, D3DXHANDLE *objects)
4488 {
4489     unsigned int i;
4490     HRESULT hr;
4491     UINT old_size = 0;
4492     DWORD id;
4493 
4494     if (param->element_count)
4495     {
4496         param->data = value;
4497 
4498         for (i = 0; i < param->element_count; ++i)
4499         {
4500             struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
4501 
4502             hr = d3dx9_parse_value(member, value ? (char *)value + old_size : NULL, data, ptr, objects);
4503             if (hr != D3D_OK)
4504             {
4505                 WARN("Failed to parse value\n");
4506                 return hr;
4507             }
4508 
4509             old_size += member->bytes;
4510         }
4511 
4512         return D3D_OK;
4513     }
4514 
4515     switch(param->class)
4516     {
4517         case D3DXPC_SCALAR:
4518         case D3DXPC_VECTOR:
4519         case D3DXPC_MATRIX_ROWS:
4520         case D3DXPC_MATRIX_COLUMNS:
4521             param->data = value;
4522             break;
4523 
4524         case D3DXPC_STRUCT:
4525             param->data = value;
4526 
4527             for (i = 0; i < param->member_count; ++i)
4528             {
4529                 struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
4530 
4531                 hr = d3dx9_parse_value(member, (char *)value + old_size, data, ptr, objects);
4532                 if (hr != D3D_OK)
4533                 {
4534                     WARN("Failed to parse value\n");
4535                     return hr;
4536                 }
4537 
4538                 old_size += member->bytes;
4539             }
4540             break;
4541 
4542         case D3DXPC_OBJECT:
4543             switch (param->type)
4544             {
4545                 case D3DXPT_STRING:
4546                 case D3DXPT_TEXTURE:
4547                 case D3DXPT_TEXTURE1D:
4548                 case D3DXPT_TEXTURE2D:
4549                 case D3DXPT_TEXTURE3D:
4550                 case D3DXPT_TEXTURECUBE:
4551                 case D3DXPT_PIXELSHADER:
4552                 case D3DXPT_VERTEXSHADER:
4553                     read_dword(ptr, &id);
4554                     TRACE("Id: %u\n", id);
4555                     objects[id] = get_parameter_handle(param);
4556                     param->data = value;
4557                     break;
4558 
4559                 case D3DXPT_SAMPLER:
4560                 case D3DXPT_SAMPLER1D:
4561                 case D3DXPT_SAMPLER2D:
4562                 case D3DXPT_SAMPLER3D:
4563                 case D3DXPT_SAMPLERCUBE:
4564                 {
4565                     struct d3dx_sampler *sampler;
4566 
4567                     sampler = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
4568                     if (!sampler)
4569                     {
4570                         ERR("Out of memory\n");
4571                         return E_OUTOFMEMORY;
4572                     }
4573 
4574                     hr = d3dx9_parse_sampler(sampler, data, ptr, objects);
4575                     if (hr != D3D_OK)
4576                     {
4577                         HeapFree(GetProcessHeap(), 0, sampler);
4578                         WARN("Failed to parse sampler\n");
4579                         return hr;
4580                     }
4581 
4582                     param->data = sampler;
4583                     break;
4584                 }
4585 
4586                 default:
4587                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4588                     break;
4589             }
4590             break;
4591 
4592         default:
4593             FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
4594             break;
4595     }
4596 
4597     return D3D_OK;
4598 }
4599 
4600 static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *data, const char *ptr, D3DXHANDLE *objects)
4601 {
4602     UINT size = param->bytes;
4603     HRESULT hr;
4604     void *value = NULL;
4605 
4606     TRACE("param size: %u\n", size);
4607 
4608     if (size)
4609     {
4610         value = HeapAlloc(GetProcessHeap(), 0, size);
4611         if (!value)
4612         {
4613             ERR("Failed to allocate data memory.\n");
4614             return E_OUTOFMEMORY;
4615         }
4616 
4617         TRACE("Data: %s.\n", debugstr_an(ptr, size));
4618         memcpy(value, ptr, size);
4619     }
4620 
4621     hr = d3dx9_parse_value(param, value, data, &ptr, objects);
4622     if (hr != D3D_OK)
4623     {
4624         WARN("Failed to parse value\n");
4625         HeapFree(GetProcessHeap(), 0, value);
4626         return hr;
4627     }
4628 
4629     return D3D_OK;
4630 }
4631 
4632 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
4633 {
4634     DWORD size;
4635 
4636     read_dword(&ptr, &size);
4637     TRACE("Name size: %#x\n", size);
4638 
4639     if (!size)
4640     {
4641         return D3D_OK;
4642     }
4643 
4644     *name = HeapAlloc(GetProcessHeap(), 0, size);
4645     if (!*name)
4646     {
4647         ERR("Failed to allocate name memory.\n");
4648         return E_OUTOFMEMORY;
4649     }
4650 
4651     TRACE("Name: %s.\n", debugstr_an(ptr, size));
4652     memcpy(*name, ptr, size);
4653 
4654     return D3D_OK;
4655 }
4656 
4657 static HRESULT d3dx9_copy_data(char **str, const char **ptr)
4658 {
4659     DWORD size;
4660 
4661     read_dword(ptr, &size);
4662     TRACE("Data size: %#x\n", size);
4663 
4664     *str = HeapAlloc(GetProcessHeap(), 0, size);
4665     if (!*str)
4666     {
4667         ERR("Failed to allocate name memory.\n");
4668         return E_OUTOFMEMORY;
4669     }
4670 
4671     TRACE("Data: %s.\n", debugstr_an(*ptr, size));
4672     memcpy(*str, *ptr, size);
4673 
4674     *ptr += ((size + 3) & ~3);
4675 
4676     return D3D_OK;
4677 }
4678 
4679 static HRESULT d3dx9_parse_data(struct d3dx_parameter *param, const char **ptr, LPDIRECT3DDEVICE9 device)
4680 {
4681     DWORD size;
4682     HRESULT hr;
4683 
4684     TRACE("Parse data for parameter %s, type %s\n", debugstr_a(param->name), debug_d3dxparameter_type(param->type));
4685 
4686     read_dword(ptr, &size);
4687     TRACE("Data size: %#x\n", size);
4688 
4689     if (!size)
4690     {
4691         TRACE("Size is 0\n");
4692         *(void **)param->data = NULL;
4693         return D3D_OK;
4694     }
4695 
4696     switch (param->type)
4697     {
4698         case D3DXPT_STRING:
4699             /* re-read with size (sizeof(DWORD) = 4) */
4700             hr = d3dx9_parse_name((LPSTR *)param->data, *ptr - 4);
4701             if (hr != D3D_OK)
4702             {
4703                 WARN("Failed to parse string data\n");
4704                 return hr;
4705             }
4706             break;
4707 
4708         case D3DXPT_VERTEXSHADER:
4709             hr = IDirect3DDevice9_CreateVertexShader(device, (DWORD *)*ptr, (LPDIRECT3DVERTEXSHADER9 *)param->data);
4710             if (hr != D3D_OK)
4711             {
4712                 WARN("Failed to create vertex shader\n");
4713                 return hr;
4714             }
4715             break;
4716 
4717         case D3DXPT_PIXELSHADER:
4718             hr = IDirect3DDevice9_CreatePixelShader(device, (DWORD *)*ptr, (LPDIRECT3DPIXELSHADER9 *)param->data);
4719             if (hr != D3D_OK)
4720             {
4721                 WARN("Failed to create pixel shader\n");
4722                 return hr;
4723             }
4724             break;
4725 
4726         default:
4727             FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4728             break;
4729     }
4730 
4731 
4732     *ptr += ((size + 3) & ~3);
4733 
4734     return D3D_OK;
4735 }
4736 
4737 static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const char *data, const char **ptr,
4738         struct d3dx_parameter *parent, UINT flags)
4739 {
4740     DWORD offset;
4741     HRESULT hr;
4742     D3DXHANDLE *member_handles = NULL;
4743     UINT i;
4744 
4745     param->flags = flags;
4746 
4747     if (!parent)
4748     {
4749         read_dword(ptr, &param->type);
4750         TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
4751 
4752         read_dword(ptr, &param->class);
4753         TRACE("Class: %s\n", debug_d3dxparameter_class(param->class));
4754 
4755         read_dword(ptr, &offset);
4756         TRACE("Type name offset: %#x\n", offset);
4757         hr = d3dx9_parse_name(&param->name, data + offset);
4758         if (hr != D3D_OK)
4759         {
4760             WARN("Failed to parse name\n");
4761             goto err_out;
4762         }
4763 
4764         read_dword(ptr, &offset);
4765         TRACE("Type semantic offset: %#x\n", offset);
4766         hr = d3dx9_parse_name(&param->semantic, data + offset);
4767         if (hr != D3D_OK)
4768         {
4769             WARN("Failed to parse semantic\n");
4770             goto err_out;
4771         }
4772 
4773         read_dword(ptr, &param->element_count);
4774         TRACE("Elements: %u\n", param->element_count);
4775 
4776         switch (param->class)
4777         {
4778             case D3DXPC_VECTOR:
4779                 read_dword(ptr, &param->columns);
4780                 TRACE("Columns: %u\n", param->columns);
4781 
4782                 read_dword(ptr, &param->rows);
4783                 TRACE("Rows: %u\n", param->rows);
4784 
4785                 /* sizeof(DWORD) * rows * columns */
4786                 param->bytes = 4 * param->rows * param->columns;
4787                 break;
4788 
4789             case D3DXPC_SCALAR:
4790             case D3DXPC_MATRIX_ROWS:
4791             case D3DXPC_MATRIX_COLUMNS:
4792                 read_dword(ptr, &param->rows);
4793                 TRACE("Rows: %u\n", param->rows);
4794 
4795                 read_dword(ptr, &param->columns);
4796                 TRACE("Columns: %u\n", param->columns);
4797 
4798                 /* sizeof(DWORD) * rows * columns */
4799                 param->bytes = 4 * param->rows * param->columns;
4800                 break;
4801 
4802             case D3DXPC_STRUCT:
4803                 read_dword(ptr, &param->member_count);
4804                 TRACE("Members: %u\n", param->member_count);
4805                 break;
4806 
4807             case D3DXPC_OBJECT:
4808                 switch (param->type)
4809                 {
4810                     case D3DXPT_STRING:
4811                         param->bytes = sizeof(LPCSTR);
4812                         break;
4813 
4814                     case D3DXPT_PIXELSHADER:
4815                         param->bytes = sizeof(LPDIRECT3DPIXELSHADER9);
4816                         break;
4817 
4818                     case D3DXPT_VERTEXSHADER:
4819                         param->bytes = sizeof(LPDIRECT3DVERTEXSHADER9);
4820                         break;
4821 
4822                     case D3DXPT_TEXTURE:
4823                     case D3DXPT_TEXTURE1D:
4824                     case D3DXPT_TEXTURE2D:
4825                     case D3DXPT_TEXTURE3D:
4826                     case D3DXPT_TEXTURECUBE:
4827                         param->bytes = sizeof(LPDIRECT3DBASETEXTURE9);
4828                         break;
4829 
4830                     case D3DXPT_SAMPLER:
4831                     case D3DXPT_SAMPLER1D:
4832                     case D3DXPT_SAMPLER2D:
4833                     case D3DXPT_SAMPLER3D:
4834                     case D3DXPT_SAMPLERCUBE:
4835                         param->bytes = 0;
4836                         break;
4837 
4838                     default:
4839                         FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
4840                         break;
4841                 }
4842                 break;
4843 
4844             default:
4845                 FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class));
4846                 break;
4847         }
4848     }
4849     else
4850     {
4851         /* elements */
4852         param->type = parent->type;
4853         param->class = parent->class;
4854         param->name = parent->name;
4855         param->semantic = parent->semantic;
4856         param->element_count = 0;
4857         param->annotation_count = 0;
4858         param->member_count = parent->member_count;
4859         param->bytes = parent->bytes;
4860         param->rows = parent->rows;
4861         param->columns = parent->columns;
4862     }
4863 
4864     if (param->element_count)
4865     {
4866         unsigned int param_bytes = 0;
4867         const char *save_ptr = *ptr;
4868 
4869         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->element_count);
4870         if (!member_handles)
4871         {
4872             ERR("Out of memory\n");
4873             hr = E_OUTOFMEMORY;
4874             goto err_out;
4875         }
4876 
4877         for (i = 0; i < param->element_count; ++i)
4878         {
4879             struct d3dx_parameter *member;
4880             *ptr = save_ptr;
4881 
4882             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4883             if (!member)
4884             {
4885                 ERR("Out of memory\n");
4886                 hr = E_OUTOFMEMORY;
4887                 goto err_out;
4888             }
4889 
4890             member_handles[i] = get_parameter_handle(member);
4891 
4892             hr = d3dx9_parse_effect_typedef(member, data, ptr, param, flags);
4893             if (hr != D3D_OK)
4894             {
4895                 WARN("Failed to parse member\n");
4896                 goto err_out;
4897             }
4898 
4899             param_bytes += member->bytes;
4900         }
4901 
4902         param->bytes = param_bytes;
4903     }
4904     else if (param->member_count)
4905     {
4906         member_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->member_count);
4907         if (!member_handles)
4908         {
4909             ERR("Out of memory\n");
4910             hr = E_OUTOFMEMORY;
4911             goto err_out;
4912         }
4913 
4914         for (i = 0; i < param->member_count; ++i)
4915         {
4916             struct d3dx_parameter *member;
4917 
4918             member = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
4919             if (!member)
4920             {
4921                 ERR("Out of memory\n");
4922                 hr = E_OUTOFMEMORY;
4923                 goto err_out;
4924             }
4925 
4926             member_handles[i] = get_parameter_handle(member);
4927 
4928             hr = d3dx9_parse_effect_typedef(member, data, ptr, NULL, flags);
4929             if (hr != D3D_OK)
4930             {
4931                 WARN("Failed to parse member\n");
4932                 goto err_out;
4933             }
4934 
4935             param->bytes += member->bytes;
4936         }
4937     }
4938 
4939     param->member_handles = member_handles;
4940 
4941     return D3D_OK;
4942 
4943 err_out:
4944 
4945     if (member_handles)
4946     {
4947         unsigned int count;
4948 
4949         if (param->element_count) count = param->element_count;
4950         else count = param->member_count;
4951 
4952         for (i = 0; i < count; ++i)
4953         {
4954             free_parameter(member_handles[i], param->element_count != 0, TRUE);
4955         }
4956         HeapFree(GetProcessHeap(), 0, member_handles);
4957     }
4958 
4959     if (!parent)
4960     {
4961         HeapFree(GetProcessHeap(), 0, param->name);
4962         HeapFree(GetProcessHeap(), 0, param->semantic);
4963     }
4964     param->name = NULL;
4965     param->semantic = NULL;
4966 
4967     return hr;
4968 }
4969 
4970 static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const char *data, const char **ptr, D3DXHANDLE *objects)
4971 {
4972     DWORD offset;
4973     const char *ptr2;
4974     HRESULT hr;
4975 
4976     anno->flags = D3DX_PARAMETER_ANNOTATION;
4977 
4978     read_dword(ptr, &offset);
4979     TRACE("Typedef offset: %#x\n", offset);
4980     ptr2 = data + offset;
4981     hr = d3dx9_parse_effect_typedef(anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
4982     if (hr != D3D_OK)
4983     {
4984         WARN("Failed to parse type definition\n");
4985         return hr;
4986     }
4987 
4988     read_dword(ptr, &offset);
4989     TRACE("Value offset: %#x\n", offset);
4990     hr = d3dx9_parse_init_value(anno, data, data + offset, objects);
4991     if (hr != D3D_OK)
4992     {
4993         WARN("Failed to parse value\n");
4994         return hr;
4995     }
4996 
4997     return D3D_OK;
4998 }
4999 
5000 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects)
5001 {
5002     DWORD offset;
5003     const char *ptr2;
5004     HRESULT hr;
5005     struct d3dx_parameter *parameter;
5006 
5007     parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
5008     if (!parameter)
5009     {
5010         ERR("Out of memory\n");
5011         return E_OUTOFMEMORY;
5012     }
5013 
5014     state->type = ST_CONSTANT;
5015 
5016     read_dword(ptr, &state->operation);
5017     TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
5018 
5019     read_dword(ptr, &state->index);
5020     TRACE("Index: %#x\n", state->index);
5021 
5022     read_dword(ptr, &offset);
5023     TRACE("Typedef offset: %#x\n", offset);
5024     ptr2 = data + offset;
5025     hr = d3dx9_parse_effect_typedef(parameter, data, &ptr2, NULL, 0);
5026     if (hr != D3D_OK)
5027     {
5028         WARN("Failed to parse type definition\n");
5029         goto err_out;
5030     }
5031 
5032     read_dword(ptr, &offset);
5033     TRACE("Value offset: %#x\n", offset);
5034     hr = d3dx9_parse_init_value(parameter, data, data + offset, objects);
5035     if (hr != D3D_OK)
5036     {
5037         WARN("Failed to parse value\n");
5038         goto err_out;
5039     }
5040 
5041     state->parameter = get_parameter_handle(parameter);
5042 
5043     return D3D_OK;
5044 
5045 err_out:
5046 
5047     free_parameter(get_parameter_handle(parameter), FALSE, FALSE);
5048 
5049     return hr;
5050 }
5051 
5052 static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const char *data, const char **ptr, D3DXHANDLE *objects)
5053 {
5054     DWORD offset;
5055     HRESULT hr;
5056     unsigned int i;
5057     D3DXHANDLE *annotation_handles = NULL;
5058     const char *ptr2;
5059 
5060     read_dword(ptr, &offset);
5061     TRACE("Typedef offset: %#x\n", offset);
5062     ptr2 = data + offset;
5063 
5064     read_dword(ptr, &offset);
5065     TRACE("Value offset: %#x\n", offset);
5066 
5067     read_dword(ptr, &param->flags);
5068     TRACE("Flags: %#x\n", param->flags);
5069 
5070     read_dword(ptr, &param->annotation_count);
5071     TRACE("Annotation count: %u\n", param->annotation_count);
5072 
5073     hr = d3dx9_parse_effect_typedef(param, data, &ptr2, NULL, param->flags);
5074     if (hr != D3D_OK)
5075     {
5076         WARN("Failed to parse type definition\n");
5077         return hr;
5078     }
5079 
5080     hr = d3dx9_parse_init_value(param, data, data + offset, objects);
5081     if (hr != D3D_OK)
5082     {
5083         WARN("Failed to parse value\n");
5084         return hr;
5085     }
5086 
5087     if (param->annotation_count)
5088     {
5089         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * param->annotation_count);
5090         if (!annotation_handles)
5091         {
5092             ERR("Out of memory\n");
5093             hr = E_OUTOFMEMORY;
5094             goto err_out;
5095         }
5096 
5097         for (i = 0; i < param->annotation_count; ++i)
5098         {
5099             struct d3dx_parameter *annotation;
5100 
5101             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
5102             if (!annotation)
5103             {
5104                 ERR("Out of memory\n");
5105                 hr = E_OUTOFMEMORY;
5106                 goto err_out;
5107             }
5108 
5109             annotation_handles[i] = get_parameter_handle(annotation);
5110 
5111             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
5112             if (hr != D3D_OK)
5113             {
5114                 WARN("Failed to parse annotation\n");
5115                 goto err_out;
5116             }
5117         }
5118     }
5119 
5120     param->annotation_handles = annotation_handles;
5121 
5122     return D3D_OK;
5123 
5124 err_out:
5125 
5126     if (annotation_handles)
5127     {
5128         for (i = 0; i < param->annotation_count; ++i)
5129         {
5130             free_parameter(annotation_handles[i], FALSE, FALSE);
5131         }
5132         HeapFree(GetProcessHeap(), 0, annotation_handles);
5133     }
5134 
5135     return hr;
5136 }
5137 
5138 static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr, D3DXHANDLE *objects)
5139 {
5140     DWORD offset;
5141     HRESULT hr;
5142     unsigned int i;
5143     D3DXHANDLE *annotation_handles = NULL;
5144     struct d3dx_state *states = NULL;
5145     char *name = NULL;
5146 
5147     read_dword(ptr, &offset);
5148     TRACE("Pass name offset: %#x\n", offset);
5149     hr = d3dx9_parse_name(&name, data + offset);
5150     if (hr != D3D_OK)
5151     {
5152         WARN("Failed to parse name\n");
5153         goto err_out;
5154     }
5155 
5156     read_dword(ptr, &pass->annotation_count);
5157     TRACE("Annotation count: %u\n", pass->annotation_count);
5158 
5159     read_dword(ptr, &pass->state_count);
5160     TRACE("State count: %u\n", pass->state_count);
5161 
5162     if (pass->annotation_count)
5163     {
5164         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * pass->annotation_count);
5165         if (!annotation_handles)
5166         {
5167             ERR("Out of memory\n");
5168             hr = E_OUTOFMEMORY;
5169             goto err_out;
5170         }
5171 
5172         for (i = 0; i < pass->annotation_count; ++i)
5173         {
5174             struct d3dx_parameter *annotation;
5175 
5176             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
5177             if (!annotation)
5178             {
5179                 ERR("Out of memory\n");
5180                 hr = E_OUTOFMEMORY;
5181                 goto err_out;
5182             }
5183 
5184             annotation_handles[i] = get_parameter_handle(annotation);
5185 
5186             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
5187             if (hr != D3D_OK)
5188             {
5189                 WARN("Failed to parse annotations\n");
5190                 goto err_out;
5191             }
5192         }
5193     }
5194 
5195     if (pass->state_count)
5196     {
5197         states = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
5198         if (!states)
5199         {
5200             ERR("Out of memory\n");
5201             hr = E_OUTOFMEMORY;
5202             goto err_out;
5203         }
5204 
5205         for (i = 0; i < pass->state_count; ++i)
5206         {
5207             hr = d3dx9_parse_state(&states[i], data, ptr, objects);
5208             if (hr != D3D_OK)
5209             {
5210                 WARN("Failed to parse annotations\n");
5211                 goto err_out;
5212             }
5213         }
5214     }
5215 
5216     pass->name = name;
5217     pass->annotation_handles = annotation_handles;
5218     pass->states = states;
5219 
5220     return D3D_OK;
5221 
5222 err_out:
5223 
5224     if (annotation_handles)
5225     {
5226         for (i = 0; i < pass->annotation_count; ++i)
5227         {
5228             free_parameter(annotation_handles[i], FALSE, FALSE);
5229         }
5230         HeapFree(GetProcessHeap(), 0, annotation_handles);
5231     }
5232 
5233     if (states)
5234     {
5235         for (i = 0; i < pass->state_count; ++i)
5236         {
5237             free_state(&states[i]);
5238         }
5239         HeapFree(GetProcessHeap(), 0, states);
5240     }
5241 
5242     HeapFree(GetProcessHeap(), 0, name);
5243 
5244     return hr;
5245 }
5246 
5247 static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data, const char **ptr, D3DXHANDLE *objects)
5248 {
5249     DWORD offset;
5250     HRESULT hr;
5251     unsigned int i;
5252     D3DXHANDLE *annotation_handles = NULL;
5253     D3DXHANDLE *pass_handles = NULL;
5254     char *name = NULL;
5255 
5256     read_dword(ptr, &offset);
5257     TRACE("Technique name offset: %#x\n", offset);
5258     hr = d3dx9_parse_name(&name, data + offset);
5259     if (hr != D3D_OK)
5260     {
5261         WARN("Failed to parse name\n");
5262         goto err_out;
5263     }
5264 
5265     read_dword(ptr, &technique->annotation_count);
5266     TRACE("Annotation count: %u\n", technique->annotation_count);
5267 
5268     read_dword(ptr, &technique->pass_count);
5269     TRACE("Pass count: %u\n", technique->pass_count);
5270 
5271     if (technique->annotation_count)
5272     {
5273         annotation_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * technique->annotation_count);
5274         if (!annotation_handles)
5275         {
5276             ERR("Out of memory\n");
5277             hr = E_OUTOFMEMORY;
5278             goto err_out;
5279         }
5280 
5281         for (i = 0; i < technique->annotation_count; ++i)
5282         {
5283             struct d3dx_parameter *annotation;
5284 
5285             annotation = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
5286             if (!annotation)
5287             {
5288                 ERR("Out of memory\n");
5289                 hr = E_OUTOFMEMORY;
5290                 goto err_out;
5291             }
5292 
5293             annotation_handles[i] = get_parameter_handle(annotation);
5294 
5295             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
5296             if (hr != D3D_OK)
5297             {
5298                 WARN("Failed to parse annotations\n");
5299                 goto err_out;
5300             }
5301         }
5302     }
5303 
5304     if (technique->pass_count)
5305     {
5306         pass_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass_handles) * technique->pass_count);
5307         if (!pass_handles)
5308         {
5309             ERR("Out of memory\n");
5310             hr = E_OUTOFMEMORY;
5311             goto err_out;
5312         }
5313 
5314         for (i = 0; i < technique->pass_count; ++i)
5315         {
5316             struct d3dx_pass *pass;
5317 
5318             pass = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass));
5319             if (!pass)
5320             {
5321                 ERR("Out of memory\n");
5322                 hr = E_OUTOFMEMORY;
5323                 goto err_out;
5324             }
5325 
5326             pass_handles[i] = get_pass_handle(pass);
5327 
5328             hr = d3dx9_parse_effect_pass(pass, data, ptr, objects);
5329             if (hr != D3D_OK)
5330             {
5331                 WARN("Failed to parse passes\n");
5332                 goto err_out;
5333             }
5334         }
5335     }
5336 
5337     technique->name = name;
5338     technique->pass_handles = pass_handles;
5339     technique->annotation_handles = annotation_handles;
5340 
5341     return D3D_OK;
5342 
5343 err_out:
5344 
5345     if (pass_handles)
5346     {
5347         for (i = 0; i < technique->pass_count; ++i)
5348         {
5349             free_pass(pass_handles[i]);
5350         }
5351         HeapFree(GetProcessHeap(), 0, pass_handles);
5352     }
5353 
5354     if (annotation_handles)
5355     {
5356         for (i = 0; i < technique->annotation_count; ++i)
5357         {
5358             free_parameter(annotation_handles[i], FALSE, FALSE);
5359         }
5360         HeapFree(GetProcessHeap(), 0, annotation_handles);
5361     }
5362 
5363     HeapFree(GetProcessHeap(), 0, name);
5364 
5365     return hr;
5366 }
5367 
5368 static HRESULT d3dx9_parse_resource(struct ID3DXBaseEffectImpl *base, const char *data, const char **ptr)
5369 {
5370     DWORD technique_index;
5371     DWORD index, state_index, usage, element_index;
5372     struct d3dx_state *state;
5373     struct d3dx_parameter *param;
5374     HRESULT hr = E_FAIL;
5375 
5376     read_dword(ptr, &technique_index);
5377     TRACE("techn: %u\n", technique_index);
5378 
5379     read_dword(ptr, &index);
5380     TRACE("index: %u\n", index);
5381 
5382     read_dword(ptr, &element_index);
5383     TRACE("element_index: %u\n", element_index);
5384 
5385     read_dword(ptr, &state_index);
5386     TRACE("state_index: %u\n", state_index);
5387 
5388     read_dword(ptr, &usage);
5389     TRACE("usage: %u\n", usage);
5390 
5391     if (technique_index == 0xffffffff)
5392     {
5393         struct d3dx_parameter *parameter;
5394         struct d3dx_sampler *sampler;
5395 
5396         if (index >= base->parameter_count)
5397         {
5398             FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
5399             return E_FAIL;
5400         }
5401 
5402         parameter = get_parameter_struct(base->parameter_handles[index]);
5403         if (element_index != 0xffffffff)
5404         {
5405             if (element_index >= parameter->element_count && parameter->element_count != 0)
5406             {
5407                 FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
5408                 return E_FAIL;
5409             }
5410 
5411             if (parameter->element_count != 0) parameter = get_parameter_struct(parameter->member_handles[element_index]);
5412         }
5413 
5414         sampler = parameter->data;
5415         if (state_index >= sampler->state_count)
5416         {
5417             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
5418             return E_FAIL;
5419         }
5420 
5421         state = &sampler->states[state_index];
5422     }
5423     else
5424     {
5425         struct d3dx_technique *technique;
5426         struct d3dx_pass *pass;
5427 
5428         if (technique_index >= base->technique_count)
5429         {
5430             FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
5431             return E_FAIL;
5432         }
5433 
5434         technique = get_technique_struct(base->technique_handles[technique_index]);
5435         if (index >= technique->pass_count)
5436         {
5437             FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
5438             return E_FAIL;
5439         }
5440 
5441         pass = get_pass_struct(technique->pass_handles[index]);
5442         if (state_index >= pass->state_count)
5443         {
5444             FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
5445             return E_FAIL;
5446         }
5447 
5448         state = &pass->states[state_index];
5449     }
5450 
5451     param = get_parameter_struct(state->parameter);
5452 
5453     switch (usage)
5454     {
5455         case 0:
5456             TRACE("usage 0: type %s\n", debug_d3dxparameter_type(param->type));
5457             switch (param->type)
5458             {
5459                 case D3DXPT_VERTEXSHADER:
5460                 case D3DXPT_PIXELSHADER:
5461                     state->type = ST_CONSTANT;
5462                     hr = d3dx9_parse_data(param, ptr, base->effect->device);
5463                     break;
5464 
5465                 case D3DXPT_BOOL:
5466                 case D3DXPT_INT:
5467                 case D3DXPT_FLOAT:
5468                 case D3DXPT_STRING:
5469                     state->type = ST_FXLC;
5470                     hr = d3dx9_copy_data(param->data, ptr);
5471                     break;
5472 
5473                 default:
5474                     FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
5475                     break;
5476             }
5477             break;
5478 
5479         case 1:
5480             state->type = ST_PARAMETER;
5481             hr = d3dx9_copy_data(param->data, ptr);
5482             if (hr == D3D_OK)
5483             {
5484                 TRACE("Mapping to parameter %s\n", *(char **)param->data);
5485             }
5486             break;
5487 
5488         default:
5489             FIXME("Unknown usage %x\n", usage);
5490             break;
5491     }
5492 
5493     return hr;
5494 }
5495 
5496 static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *data, UINT data_size, DWORD start)
5497 {
5498     const char *ptr = data + start;
5499     D3DXHANDLE *parameter_handles = NULL;
5500     D3DXHANDLE *technique_handles = NULL;
5501     D3DXHANDLE *objects = NULL;
5502     UINT stringcount, objectcount, resourcecount;
5503     HRESULT hr;
5504     UINT i;
5505 
5506     read_dword(&ptr, &base->parameter_count);
5507     TRACE("Parameter count: %u\n", base->parameter_count);
5508 
5509     read_dword(&ptr, &base->technique_count);
5510     TRACE("Technique count: %u\n", base->technique_count);
5511 
5512     skip_dword_unknown(&ptr, 1);
5513 
5514     read_dword(&ptr, &objectcount);
5515     TRACE("Object count: %u\n", objectcount);
5516 
5517     objects = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*objects) * objectcount);
5518     if (!objects)
5519     {
5520         ERR("Out of memory\n");
5521         hr = E_OUTOFMEMORY;
5522         goto err_out;
5523     }
5524 
5525     if (base->parameter_count)
5526     {
5527         parameter_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter_handles) * base->parameter_count);
5528         if (!parameter_handles)
5529         {
5530             ERR("Out of memory\n");
5531             hr = E_OUTOFMEMORY;
5532             goto err_out;
5533         }
5534 
5535         for (i = 0; i < base->parameter_count; ++i)
5536         {
5537             struct d3dx_parameter *parameter;
5538 
5539             parameter = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
5540             if (!parameter)
5541             {
5542                 ERR("Out of memory\n");
5543                 hr = E_OUTOFMEMORY;
5544                 goto err_out;
5545             }
5546 
5547             parameter_handles[i] = get_parameter_handle(parameter);
5548 
5549             hr = d3dx9_parse_effect_parameter(parameter, data, &ptr, objects);
5550             if (hr != D3D_OK)
5551             {
5552                 WARN("Failed to parse parameter\n");
5553                 goto err_out;
5554             }
5555         }
5556     }
5557 
5558     if (base->technique_count)
5559     {
5560         technique_handles = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique_handles) * base->technique_count);
5561         if (!technique_handles)
5562         {
5563             ERR("Out of memory\n");
5564             hr = E_OUTOFMEMORY;
5565             goto err_out;
5566         }
5567 
5568         for (i = 0; i < base->technique_count; ++i)
5569         {
5570             struct d3dx_technique *technique;
5571 
5572             technique = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique));
5573             if (!technique)
5574             {
5575                 ERR("Out of memory\n");
5576                 hr = E_OUTOFMEMORY;
5577                 goto err_out;
5578             }
5579 
5580             technique_handles[i] = get_technique_handle(technique);
5581 
5582             hr = d3dx9_parse_effect_technique(technique, data, &ptr, objects);
5583             if (hr != D3D_OK)
5584             {
5585                 WARN("Failed to parse technique\n");
5586                 goto err_out;
5587             }
5588         }
5589     }
5590 
5591     /* needed for further parsing */
5592     base->technique_handles = technique_handles;
5593     base->parameter_handles = parameter_handles;
5594 
5595     read_dword(&ptr, &stringcount);
5596     TRACE("String count: %u\n", stringcount);
5597 
5598     read_dword(&ptr, &resourcecount);
5599     TRACE("Resource count: %u\n", resourcecount);
5600 
5601     for (i = 0; i < stringcount; ++i)
5602     {
5603         DWORD id;
5604         struct d3dx_parameter *param;
5605 
5606         read_dword(&ptr, &id);
5607         TRACE("Id: %u\n", id);
5608 
5609         param = get_parameter_struct(objects[id]);
5610 
5611         hr = d3dx9_parse_data(param, &ptr, base->effect->device);
5612         if (hr != D3D_OK)
5613         {
5614             WARN("Failed to parse data\n");
5615             goto err_out;
5616         }
5617     }
5618 
5619     for (i = 0; i < resourcecount; ++i)
5620     {
5621         TRACE("parse resource %u\n", i);
5622 
5623         hr = d3dx9_parse_resource(base, data, &ptr);
5624         if (hr != D3D_OK)
5625         {
5626             WARN("Failed to parse data\n");
5627             goto err_out;
5628         }
5629     }
5630 
5631     HeapFree(GetProcessHeap(), 0, objects);
5632 
5633     return D3D_OK;
5634 
5635 err_out:
5636 
5637     if (technique_handles)
5638     {
5639         for (i = 0; i < base->technique_count; ++i)
5640         {
5641             free_technique(technique_handles[i]);
5642         }
5643         HeapFree(GetProcessHeap(), 0, technique_handles);
5644     }
5645 
5646     if (parameter_handles)
5647     {
5648         for (i = 0; i < base->parameter_count; ++i)
5649         {
5650             free_parameter(parameter_handles[i], FALSE, FALSE);
5651         }
5652         HeapFree(GetProcessHeap(), 0, parameter_handles);
5653     }
5654 
5655     base->technique_handles = NULL;
5656     base->parameter_handles = NULL;
5657 
5658     HeapFree(GetProcessHeap(), 0, objects);
5659 
5660     return hr;
5661 }
5662 
5663 static HRESULT d3dx9_base_effect_init(struct ID3DXBaseEffectImpl *base,
5664         const char *data, SIZE_T data_size, struct ID3DXEffectImpl *effect)
5665 {
5666     DWORD tag, offset;
5667     const char *ptr = data;
5668     HRESULT hr;
5669 
5670     TRACE("base %p, data %p, data_size %lu, effect %p\n", base, data, data_size, effect);
5671 
5672     base->ID3DXBaseEffect_iface.lpVtbl = &ID3DXBaseEffect_Vtbl;
5673     base->ref = 1;
5674     base->effect = effect;
5675 
5676     read_dword(&ptr, &tag);
5677     TRACE("Tag: %x\n", tag);
5678 
5679     if (tag != d3dx9_effect_version(9, 1))
5680     {
5681         /* todo: compile hlsl ascii code */
5682         FIXME("HLSL ascii effects not supported, yet\n");
5683 
5684         /* Show the start of the shader for debugging info. */
5685         TRACE("effect:\n%s\n", debugstr_an(data, data_size > 40 ? 40 : data_size));
5686     }
5687     else
5688     {
5689         read_dword(&ptr, &offset);
5690         TRACE("Offset: %x\n", offset);
5691 
5692         hr = d3dx9_parse_effect(base, ptr, data_size, offset);
5693         if (hr != D3D_OK)
5694         {
5695             FIXME("Failed to parse effect.\n");
5696             return hr;
5697         }
5698     }
5699 
5700     return D3D_OK;
5701 }
5702 
5703 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, LPDIRECT3DDEVICE9 device,
5704         const char *data, SIZE_T data_size, LPD3DXEFFECTPOOL pool)
5705 {
5706     HRESULT hr;
5707     struct ID3DXBaseEffectImpl *object = NULL;
5708 
5709     TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
5710 
5711     effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl;
5712     effect->ref = 1;
5713 
5714     if (pool) pool->lpVtbl->AddRef(pool);
5715     effect->pool = pool;
5716 
5717     IDirect3DDevice9_AddRef(device);
5718     effect->device = device;
5719 
5720     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5721     if (!object)
5722     {
5723         ERR("Out of memory\n");
5724         hr = E_OUTOFMEMORY;
5725         goto err_out;
5726     }
5727 
5728     hr = d3dx9_base_effect_init(object, data, data_size, effect);
5729     if (hr != D3D_OK)
5730     {
5731         FIXME("Failed to parse effect.\n");
5732         goto err_out;
5733     }
5734 
5735     effect->base_effect = &object->ID3DXBaseEffect_iface;
5736 
5737     /* initialize defaults - check because of unsupported ascii effects */
5738     if (object->technique_handles)
5739     {
5740         effect->active_technique = object->technique_handles[0];
5741         effect->active_pass = NULL;
5742     }
5743 
5744     return D3D_OK;
5745 
5746 err_out:
5747 
5748     HeapFree(GetProcessHeap(), 0, object);
5749     free_effect(effect);
5750 
5751     return hr;
5752 }
5753 
5754 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
5755                                   LPCVOID srcdata,
5756                                   UINT srcdatalen,
5757                                   CONST D3DXMACRO* defines,
5758                                   LPD3DXINCLUDE include,
5759                                   LPCSTR skip_constants,
5760                                   DWORD flags,
5761                                   LPD3DXEFFECTPOOL pool,
5762                                   LPD3DXEFFECT* effect,
5763                                   LPD3DXBUFFER* compilation_errors)
5764 {
5765     struct ID3DXEffectImpl *object;
5766     HRESULT hr;
5767 
5768     FIXME("(%p, %p, %u, %p, %p, %p, %#x, %p, %p, %p): semi-stub\n", device, srcdata, srcdatalen, defines, include,
5769         skip_constants, flags, pool, effect, compilation_errors);
5770 
5771     if (!device || !srcdata)
5772         return D3DERR_INVALIDCALL;
5773 
5774     if (!srcdatalen)
5775         return E_FAIL;
5776 
5777     /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
5778     if (!effect)
5779         return D3D_OK;
5780 
5781     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5782     if (!object)
5783     {
5784         ERR("Out of memory\n");
5785         return E_OUTOFMEMORY;
5786     }
5787 
5788     hr = d3dx9_effect_init(object, device, srcdata, srcdatalen, pool);
5789     if (FAILED(hr))
5790     {
5791         WARN("Failed to initialize shader reflection\n");
5792         HeapFree(GetProcessHeap(), 0, object);
5793         return hr;
5794     }
5795 
5796     *effect = &object->ID3DXEffect_iface;
5797 
5798     TRACE("Created ID3DXEffect %p\n", object);
5799 
5800     return D3D_OK;
5801 }
5802 
5803 HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
5804                                 LPCVOID srcdata,
5805                                 UINT srcdatalen,
5806                                 CONST D3DXMACRO* defines,
5807                                 LPD3DXINCLUDE include,
5808                                 DWORD flags,
5809                                 LPD3DXEFFECTPOOL pool,
5810                                 LPD3DXEFFECT* effect,
5811                                 LPD3DXBUFFER* compilation_errors)
5812 {
5813     TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
5814         include, flags, pool, effect, compilation_errors);
5815 
5816     return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
5817 }
5818 
5819 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler, const char *data, SIZE_T data_size)
5820 {
5821     HRESULT hr;
5822     struct ID3DXBaseEffectImpl *object = NULL;
5823 
5824     TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
5825 
5826     compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl;
5827     compiler->ref = 1;
5828 
5829     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5830     if (!object)
5831     {
5832         ERR("Out of memory\n");
5833         hr = E_OUTOFMEMORY;
5834         goto err_out;
5835     }
5836 
5837     hr = d3dx9_base_effect_init(object, data, data_size, NULL);
5838     if (hr != D3D_OK)
5839     {
5840         FIXME("Failed to parse effect.\n");
5841         goto err_out;
5842     }
5843 
5844     compiler->base_effect = &object->ID3DXBaseEffect_iface;
5845 
5846     return D3D_OK;
5847 
5848 err_out:
5849 
5850     HeapFree(GetProcessHeap(), 0, object);
5851     free_effect_compiler(compiler);
5852 
5853     return hr;
5854 }
5855 
5856 HRESULT WINAPI D3DXCreateEffectCompiler(LPCSTR srcdata,
5857                                         UINT srcdatalen,
5858                                         CONST D3DXMACRO *defines,
5859                                         LPD3DXINCLUDE include,
5860                                         DWORD flags,
5861                                         LPD3DXEFFECTCOMPILER *compiler,
5862                                         LPD3DXBUFFER *parse_errors)
5863 {
5864     struct ID3DXEffectCompilerImpl *object;
5865     HRESULT hr;
5866 
5867     TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
5868             srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
5869 
5870     if (!srcdata || !compiler)
5871     {
5872         WARN("Invalid arguments supplied\n");
5873         return D3DERR_INVALIDCALL;
5874     }
5875 
5876     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5877     if (!object)
5878     {
5879         ERR("Out of memory\n");
5880         return E_OUTOFMEMORY;
5881     }
5882 
5883     hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen);
5884     if (FAILED(hr))
5885     {
5886         WARN("Failed to initialize effect compiler\n");
5887         HeapFree(GetProcessHeap(), 0, object);
5888         return hr;
5889     }
5890 
5891     *compiler = &object->ID3DXEffectCompiler_iface;
5892 
5893     TRACE("Created ID3DXEffectCompiler %p\n", object);
5894 
5895     return D3D_OK;
5896 }
5897 
5898 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl;
5899 
5900 struct ID3DXEffectPoolImpl
5901 {
5902     ID3DXEffectPool ID3DXEffectPool_iface;
5903     LONG ref;
5904 };
5905 
5906 static inline struct ID3DXEffectPoolImpl *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
5907 {
5908     return CONTAINING_RECORD(iface, struct ID3DXEffectPoolImpl, ID3DXEffectPool_iface);
5909 }
5910 
5911 /*** IUnknown methods ***/
5912 static HRESULT WINAPI ID3DXEffectPoolImpl_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
5913 {
5914     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
5915 
5916     if (IsEqualGUID(riid, &IID_IUnknown) ||
5917         IsEqualGUID(riid, &IID_ID3DXEffectPool))
5918     {
5919         iface->lpVtbl->AddRef(iface);
5920         *object = iface;
5921         return S_OK;
5922     }
5923 
5924     WARN("Interface %s not found\n", debugstr_guid(riid));
5925 
5926     return E_NOINTERFACE;
5927 }
5928 
5929 static ULONG WINAPI ID3DXEffectPoolImpl_AddRef(ID3DXEffectPool *iface)
5930 {
5931     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5932 
5933     TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
5934 
5935     return InterlockedIncrement(&This->ref);
5936 }
5937 
5938 static ULONG WINAPI ID3DXEffectPoolImpl_Release(ID3DXEffectPool *iface)
5939 {
5940     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
5941     ULONG ref = InterlockedDecrement(&This->ref);
5942 
5943     TRACE("(%p)->(): Release from %u\n", This, ref + 1);
5944 
5945     if (!ref)
5946         HeapFree(GetProcessHeap(), 0, This);
5947 
5948     return ref;
5949 }
5950 
5951 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
5952 {
5953     /*** IUnknown methods ***/
5954     ID3DXEffectPoolImpl_QueryInterface,
5955     ID3DXEffectPoolImpl_AddRef,
5956     ID3DXEffectPoolImpl_Release
5957 };
5958 
5959 HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL *pool)
5960 {
5961     struct ID3DXEffectPoolImpl *object;
5962 
5963     TRACE("(%p)\n", pool);
5964 
5965     if (!pool)
5966         return D3DERR_INVALIDCALL;
5967 
5968     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
5969     if (!object)
5970     {
5971         ERR("Out of memory\n");
5972         return E_OUTOFMEMORY;
5973     }
5974 
5975     object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl;
5976     object->ref = 1;
5977 
5978     *pool = &object->ID3DXEffectPool_iface;
5979 
5980     return S_OK;
5981 }
5982 
5983 HRESULT WINAPI D3DXCreateEffectFromFileExW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
5984     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
5985     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
5986 {
5987     LPVOID buffer;
5988     HRESULT ret;
5989     DWORD size;
5990 
5991     TRACE("(%s): relay\n", debugstr_w(srcfile));
5992 
5993     if (!device || !srcfile)
5994         return D3DERR_INVALIDCALL;
5995 
5996     ret = map_view_of_file(srcfile, &buffer, &size);
5997 
5998     if (FAILED(ret))
5999         return D3DXERR_INVALIDDATA;
6000 
6001     ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6002     UnmapViewOfFile(buffer);
6003 
6004     return ret;
6005 }
6006 
6007 HRESULT WINAPI D3DXCreateEffectFromFileExA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
6008     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
6009     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6010 {
6011     LPWSTR srcfileW;
6012     HRESULT ret;
6013     DWORD len;
6014 
6015     TRACE("(void): relay\n");
6016 
6017     if (!srcfile)
6018         return D3DERR_INVALIDCALL;
6019 
6020     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6021     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6022     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6023 
6024     ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6025     HeapFree(GetProcessHeap(), 0, srcfileW);
6026 
6027     return ret;
6028 }
6029 
6030 HRESULT WINAPI D3DXCreateEffectFromFileW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
6031     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6032     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6033 {
6034     TRACE("(void): relay\n");
6035     return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6036 }
6037 
6038 HRESULT WINAPI D3DXCreateEffectFromFileA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
6039     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6040     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6041 {
6042     TRACE("(void): relay\n");
6043     return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
6044 }
6045 
6046 HRESULT WINAPI D3DXCreateEffectFromResourceExW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
6047     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
6048     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6049 {
6050     HRSRC resinfo;
6051 
6052     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
6053 
6054     if (!device)
6055         return D3DERR_INVALIDCALL;
6056 
6057     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
6058 
6059     if (resinfo)
6060     {
6061         LPVOID buffer;
6062         HRESULT ret;
6063         DWORD size;
6064 
6065         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6066 
6067         if (FAILED(ret))
6068             return D3DXERR_INVALIDDATA;
6069 
6070         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6071     }
6072 
6073     return D3DXERR_INVALIDDATA;
6074 }
6075 
6076 HRESULT WINAPI D3DXCreateEffectFromResourceExA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
6077     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
6078     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6079 {
6080     HRSRC resinfo;
6081 
6082     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
6083 
6084     if (!device)
6085         return D3DERR_INVALIDCALL;
6086 
6087     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
6088 
6089     if (resinfo)
6090     {
6091         LPVOID buffer;
6092         HRESULT ret;
6093         DWORD size;
6094 
6095         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6096 
6097         if (FAILED(ret))
6098             return D3DXERR_INVALIDDATA;
6099 
6100         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
6101     }
6102 
6103     return D3DXERR_INVALIDDATA;
6104 }
6105 
6106 HRESULT WINAPI D3DXCreateEffectFromResourceW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
6107     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6108     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6109 {
6110     TRACE("(void): relay\n");
6111     return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6112 }
6113 
6114 HRESULT WINAPI D3DXCreateEffectFromResourceA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
6115     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
6116     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
6117 {
6118     TRACE("(void): relay\n");
6119     return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
6120 }
6121 
6122 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(LPCWSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
6123     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6124 {
6125     LPVOID buffer;
6126     HRESULT ret;
6127     DWORD size;
6128 
6129     TRACE("(%s): relay\n", debugstr_w(srcfile));
6130 
6131     if (!srcfile)
6132         return D3DERR_INVALIDCALL;
6133 
6134     ret = map_view_of_file(srcfile, &buffer, &size);
6135 
6136     if (FAILED(ret))
6137         return D3DXERR_INVALIDDATA;
6138 
6139     ret = D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6140     UnmapViewOfFile(buffer);
6141 
6142     return ret;
6143 }
6144 
6145 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
6146     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6147 {
6148     LPWSTR srcfileW;
6149     HRESULT ret;
6150     DWORD len;
6151 
6152     TRACE("(void): relay\n");
6153 
6154     if (!srcfile)
6155         return D3DERR_INVALIDCALL;
6156 
6157     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
6158     srcfileW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
6159     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
6160 
6161     ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
6162     HeapFree(GetProcessHeap(), 0, srcfileW);
6163 
6164     return ret;
6165 }
6166 
6167 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, LPCSTR srcresource, const D3DXMACRO *defines,
6168     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6169 {
6170     HRSRC resinfo;
6171 
6172     TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
6173 
6174     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
6175 
6176     if (resinfo)
6177     {
6178         LPVOID buffer;
6179         HRESULT ret;
6180         DWORD size;
6181 
6182         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6183 
6184         if (FAILED(ret))
6185             return D3DXERR_INVALIDDATA;
6186 
6187         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6188     }
6189 
6190     return D3DXERR_INVALIDDATA;
6191 }
6192 
6193 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, LPCWSTR srcresource, const D3DXMACRO *defines,
6194     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
6195 {
6196     HRSRC resinfo;
6197 
6198     TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
6199 
6200     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
6201 
6202     if (resinfo)
6203     {
6204         LPVOID buffer;
6205         HRESULT ret;
6206         DWORD size;
6207 
6208         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
6209 
6210         if (FAILED(ret))
6211             return D3DXERR_INVALIDDATA;
6212 
6213         return D3DXCreateEffectCompiler(buffer, size, defines, include, flags, effectcompiler, parseerrors);
6214     }
6215 
6216     return D3DXERR_INVALIDDATA;
6217 }
6218 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.