DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator
src/gui/d3d_components.h
00001 #include <TCHAR.h>
00002 
00003 /*
00004  Not documented: D3DXFillTextureTX, D3DXFillVolumeTextureTX, D3DXCreateTextureShader
00005  Code borrowed from Wine and ReactOS
00006 */
00007 
00008 #if 0 // disabled as this code currently does not support pixel shaders (see ID3DXBaseEffectImpl_GetPassDesc)
00009 #include <d3dx9shader.h>
00010 #include <Unknwn.h>
00011 
00012 HRESULT map_view_of_file(LPCWSTR filename, LPVOID *buffer, DWORD *length);
00013 
00014 //#define ARRAY_SIZE(array) (sizeof(array)/sizeof(*array))
00015 #define INT_FLOAT_MULTI 255.0f
00016 #define INT_FLOAT_MULTI_INVERSE (1/INT_FLOAT_MULTI)
00017 
00018 static BOOL get_bool(D3DXPARAMETER_TYPE type, LPCVOID data)
00019 {
00020     switch (type)
00021     {
00022         case D3DXPT_FLOAT:
00023         case D3DXPT_INT:
00024         case D3DXPT_BOOL:
00025             return *(DWORD *)data != 0;
00026 
00027         case D3DXPT_VOID:
00028             return *(BOOL *)data;
00029 
00030         default:
00031             //FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(type));
00032             return FALSE;
00033     }
00034 }
00035 
00036 static INT get_int(D3DXPARAMETER_TYPE type, LPCVOID data)
00037 {
00038     switch (type)
00039     {
00040         case D3DXPT_FLOAT:
00041             return *(FLOAT *)data;
00042 
00043         case D3DXPT_INT:
00044         case D3DXPT_VOID:
00045             return *(INT *)data;
00046 
00047         case D3DXPT_BOOL:
00048             return get_bool(type, data);
00049 
00050         default:
00051             //FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(type));
00052             return 0;
00053     }
00054 }
00055 
00056 static FLOAT get_float(D3DXPARAMETER_TYPE type, LPCVOID data)
00057 {
00058     switch (type)
00059     {
00060         case D3DXPT_FLOAT:
00061         case D3DXPT_VOID:
00062             return *(FLOAT *)data;
00063 
00064         case D3DXPT_INT:
00065             return *(INT *)data;
00066 
00067         case D3DXPT_BOOL:
00068             return get_bool(type, data);
00069 
00070         default:
00071             //FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(type));
00072             return 0.0f;
00073     }
00074 }
00075 
00076 void set_number(LPVOID outdata, D3DXPARAMETER_TYPE outtype, LPCVOID indata, D3DXPARAMETER_TYPE intype)
00077 {
00078     //TRACE("Changing from type %s to type %s\n", debug_d3dxparameter_type(intype), debug_d3dxparameter_type(outtype));
00079 
00080     if (outtype == intype)
00081     {
00082         *(DWORD *)outdata = *(DWORD *)indata;
00083         return;
00084     }
00085 
00086     switch (outtype)
00087     {
00088         case D3DXPT_FLOAT:
00089             *(FLOAT *)outdata = get_float(intype, indata);
00090             break;
00091 
00092         case D3DXPT_BOOL:
00093             *(BOOL *)outdata = get_bool(intype, indata);
00094             break;
00095 
00096         case D3DXPT_INT:
00097             *(INT *)outdata = get_int(intype, indata);
00098             break;
00099 
00100         default:
00101             //FIXME("Unhandled type %s.\n", debug_d3dxparameter_type(outtype));
00102             *(DWORD *)outdata = 0;
00103             break;
00104     }
00105 }
00106 
00107 HRESULT load_resource_into_memory(HMODULE module, HRSRC resinfo, LPVOID *buffer, DWORD *length)
00108 {
00109     HGLOBAL resource;
00110 
00111     *length = SizeofResource(module, resinfo);
00112     if(*length == 0) return HRESULT_FROM_WIN32(GetLastError());
00113 
00114     resource = LoadResource(module, resinfo);
00115     if( !resource ) return HRESULT_FROM_WIN32(GetLastError());
00116 
00117     *buffer = LockResource(resource);
00118     if(*buffer == NULL) return HRESULT_FROM_WIN32(GetLastError());
00119 
00120     return S_OK;
00121 }
00122 
00123 /*
00124 HRESULT write_buffer_to_file(const WCHAR *dst_filename, ID3DXBuffer *buffer)
00125 {
00126     HRESULT hr = S_OK;
00127     void *buffer_pointer;
00128     DWORD buffer_size;
00129     HANDLE file = CreateFileW(dst_filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
00130     if (file == INVALID_HANDLE_VALUE)
00131         return HRESULT_FROM_WIN32(GetLastError());
00132 
00133     buffer_pointer = ID3DXBuffer_GetBufferPointer(buffer);
00134     buffer_size = ID3DXBuffer_GetBufferSize(buffer);
00135 
00136     if (!WriteFile(file, buffer_pointer, buffer_size, NULL, NULL))
00137         hr = HRESULT_FROM_WIN32(GetLastError());
00138 
00139     CloseHandle(file);
00140     return hr;
00141 }
00142 */
00143 static ULONG WINAPI IUnknown_Release(LPUNKNOWN iface)
00144 {
00145     static LONG cLocks;
00146     InterlockedDecrement(&cLocks);
00147     return 1; /* non-heap-based object */
00148 }
00149 
00150 static ULONG WINAPI IUnknown_AddRef(LPUNKNOWN iface)
00151 {
00152     static LONG cLocks;
00153     InterlockedDecrement(&cLocks);
00154     return 2; /* non-heap-based object */
00155 }
00156 
00157 
00158 struct vec4
00159 {
00160     float x, y, z, w;
00161 };
00162 
00163 struct volume
00164 {
00165     UINT width;
00166     UINT height;
00167     UINT depth;
00168 };
00169 
00170 /* for internal use */
00171 enum format_type {
00172     FORMAT_ARGB,   /* unsigned */
00173     FORMAT_UNKNOWN
00174 };
00175 
00176 struct pixel_format_desc {
00177     D3DFORMAT format;
00178     BYTE bits[4];
00179     BYTE shift[4];
00180     UINT bytes_per_pixel;
00181     UINT block_width;
00182     UINT block_height;
00183     UINT block_byte_count;
00184     enum format_type type;
00185     void (*from_rgba)(const struct vec4 *src, struct vec4 *dst);
00186     void (*to_rgba)(const struct vec4 *src, struct vec4 *dst);
00187 };
00188 
00189 
00190 
00191 enum STATE_CLASS
00192 {
00193     SC_LIGHTENABLE,
00194     SC_FVF,
00195     SC_LIGHT,
00196     SC_MATERIAL,
00197     SC_NPATCHMODE,
00198     SC_PIXELSHADER,
00199     SC_RENDERSTATE,
00200     SC_SETSAMPLER,
00201     SC_SAMPLERSTATE,
00202     SC_TEXTURE,
00203     SC_TEXTURESTAGE,
00204     SC_TRANSFORM,
00205     SC_VERTEXSHADER,
00206     SC_SHADERCONST,
00207     SC_UNKNOWN,
00208 };
00209 
00210 enum MATERIAL_TYPE
00211 {
00212     MT_DIFFUSE,
00213     MT_AMBIENT,
00214     MT_SPECULAR,
00215     MT_EMISSIVE,
00216     MT_POWER,
00217 };
00218 
00219 enum LIGHT_TYPE
00220 {
00221     LT_TYPE,
00222     LT_DIFFUSE,
00223     LT_SPECULAR,
00224     LT_AMBIENT,
00225     LT_POSITION,
00226     LT_DIRECTION,
00227     LT_RANGE,
00228     LT_FALLOFF,
00229     LT_ATTENUATION0,
00230     LT_ATTENUATION1,
00231     LT_ATTENUATION2,
00232     LT_THETA,
00233     LT_PHI,
00234 };
00235 
00236 enum SHADER_CONSTANT_TYPE
00237 {
00238     SCT_VSFLOAT,
00239     SCT_VSBOOL,
00240     SCT_VSINT,
00241     SCT_PSFLOAT,
00242     SCT_PSBOOL,
00243     SCT_PSINT,
00244 };
00245 
00246 enum STATE_TYPE
00247 {
00248     ST_CONSTANT,
00249     ST_PARAMETER,
00250     ST_FXLC,
00251 };
00252 
00253 struct d3dx_parameter
00254 {
00255     char *name;
00256     char *semantic;
00257     void *data;
00258     D3DXPARAMETER_CLASS class2;
00259     D3DXPARAMETER_TYPE  type;
00260     UINT rows;
00261     UINT columns;
00262     UINT element_count;
00263     UINT annotation_count;
00264     UINT member_count;
00265     DWORD flags;
00266     UINT bytes;
00267 
00268     D3DXHANDLE *annotation_handles;
00269     D3DXHANDLE *member_handles;
00270 };
00271 
00272 struct d3dx_state
00273 {
00274     UINT operation;
00275     UINT index;
00276     enum STATE_TYPE type;
00277     D3DXHANDLE parameter;
00278 };
00279 
00280 struct d3dx_sampler
00281 {
00282     UINT state_count;
00283     struct d3dx_state *states;
00284 };
00285 
00286 struct d3dx_pass
00287 {
00288     char *name;
00289     UINT state_count;
00290     UINT annotation_count;
00291 
00292     struct d3dx_state *states;
00293     D3DXHANDLE *annotation_handles;
00294 };
00295 
00296 struct d3dx_technique
00297 {
00298     char *name;
00299     UINT pass_count;
00300     UINT annotation_count;
00301 
00302     D3DXHANDLE *annotation_handles;
00303     D3DXHANDLE *pass_handles;
00304 };
00305 
00306 struct ID3DXBaseEffectImpl
00307 {
00308     ID3DXBaseEffect* ID3DXBaseEffect_iface;
00309     LONG ref;
00310 
00311     struct ID3DXEffectImpl *effect;
00312 
00313     UINT parameter_count;
00314     UINT technique_count;
00315 
00316     D3DXHANDLE *parameter_handles;
00317     D3DXHANDLE *technique_handles;
00318 };
00319 
00320 struct ID3DXEffectImpl
00321 {
00322     ID3DXEffect* ID3DXEffect_iface;
00323     LONG ref;
00324 
00325     LPD3DXEFFECTSTATEMANAGER manager;
00326     LPDIRECT3DDEVICE9 device;
00327     LPD3DXEFFECTPOOL pool;
00328     D3DXHANDLE active_technique;
00329     D3DXHANDLE active_pass;
00330 
00331     ID3DXBaseEffect *base_effect;
00332 };
00333 
00334 struct ID3DXEffectCompilerImpl
00335 {
00336     ID3DXEffectCompiler* ID3DXEffectCompiler_iface;
00337     LONG ref;
00338 
00339     ID3DXBaseEffect *base_effect;
00340 };
00341 
00342 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
00343         struct d3dx_parameter *parameter, LPCSTR name);
00344 static struct d3dx_parameter *get_annotation_by_name(UINT handlecount, D3DXHANDLE *handles, LPCSTR name);
00345 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects);
00346 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st);
00347 
00348 static const struct
00349 {
00350     enum STATE_CLASS class2;
00351     UINT op;
00352     LPCSTR name;
00353 }
00354 state_table[] =
00355 {
00356     /* Render sates */
00357     {SC_RENDERSTATE, D3DRS_ZENABLE, "D3DRS_ZENABLE"}, /* 0x0 */
00358     {SC_RENDERSTATE, D3DRS_FILLMODE, "D3DRS_FILLMODE"},
00359     {SC_RENDERSTATE, D3DRS_SHADEMODE, "D3DRS_SHADEMODE"},
00360     {SC_RENDERSTATE, D3DRS_ZWRITEENABLE, "D3DRS_ZWRITEENABLE"},
00361     {SC_RENDERSTATE, D3DRS_ALPHATESTENABLE, "D3DRS_ALPHATESTENABLE"},
00362     {SC_RENDERSTATE, D3DRS_LASTPIXEL, "D3DRS_LASTPIXEL"},
00363     {SC_RENDERSTATE, D3DRS_SRCBLEND, "D3DRS_SRCBLEND"},
00364     {SC_RENDERSTATE, D3DRS_DESTBLEND, "D3DRS_DESTBLEND"},
00365     {SC_RENDERSTATE, D3DRS_CULLMODE, "D3DRS_CULLMODE"},
00366     {SC_RENDERSTATE, D3DRS_ZFUNC, "D3DRS_ZFUNC"},
00367     {SC_RENDERSTATE, D3DRS_ALPHAREF, "D3DRS_ALPHAREF"},
00368     {SC_RENDERSTATE, D3DRS_ALPHAFUNC, "D3DRS_ALPHAFUNC"},
00369     {SC_RENDERSTATE, D3DRS_DITHERENABLE, "D3DRS_DITHERENABLE"},
00370     {SC_RENDERSTATE, D3DRS_ALPHABLENDENABLE, "D3DRS_ALPHABLENDENABLE"},
00371     {SC_RENDERSTATE, D3DRS_FOGENABLE, "D3DRS_FOGENABLE"},
00372     {SC_RENDERSTATE, D3DRS_SPECULARENABLE, "D3DRS_SPECULARENABLE"},
00373     {SC_RENDERSTATE, D3DRS_FOGCOLOR, "D3DRS_FOGCOLOR"}, /* 0x10 */
00374     {SC_RENDERSTATE, D3DRS_FOGTABLEMODE, "D3DRS_FOGTABLEMODE"},
00375     {SC_RENDERSTATE, D3DRS_FOGSTART, "D3DRS_FOGSTART"},
00376     {SC_RENDERSTATE, D3DRS_FOGEND, "D3DRS_FOGEND"},
00377     {SC_RENDERSTATE, D3DRS_FOGDENSITY, "D3DRS_FOGDENSITY"},
00378     {SC_RENDERSTATE, D3DRS_RANGEFOGENABLE, "D3DRS_RANGEFOGENABLE"},
00379     {SC_RENDERSTATE, D3DRS_STENCILENABLE, "D3DRS_STENCILENABLE"},
00380     {SC_RENDERSTATE, D3DRS_STENCILFAIL, "D3DRS_STENCILFAIL"},
00381     {SC_RENDERSTATE, D3DRS_STENCILZFAIL, "D3DRS_STENCILZFAIL"},
00382     {SC_RENDERSTATE, D3DRS_STENCILPASS, "D3DRS_STENCILPASS"},
00383     {SC_RENDERSTATE, D3DRS_STENCILFUNC, "D3DRS_STENCILFUNC"},
00384     {SC_RENDERSTATE, D3DRS_STENCILREF, "D3DRS_STENCILREF"},
00385     {SC_RENDERSTATE, D3DRS_STENCILMASK, "D3DRS_STENCILMASK"},
00386     {SC_RENDERSTATE, D3DRS_STENCILWRITEMASK, "D3DRS_STENCILWRITEMASK"},
00387     {SC_RENDERSTATE, D3DRS_TEXTUREFACTOR, "D3DRS_TEXTUREFACTOR"},
00388     {SC_RENDERSTATE, D3DRS_WRAP0, "D3DRS_WRAP0"},
00389     {SC_RENDERSTATE, D3DRS_WRAP1, "D3DRS_WRAP1"}, /* 0x20 */
00390     {SC_RENDERSTATE, D3DRS_WRAP2, "D3DRS_WRAP2"},
00391     {SC_RENDERSTATE, D3DRS_WRAP3, "D3DRS_WRAP3"},
00392     {SC_RENDERSTATE, D3DRS_WRAP4, "D3DRS_WRAP4"},
00393     {SC_RENDERSTATE, D3DRS_WRAP5, "D3DRS_WRAP5"},
00394     {SC_RENDERSTATE, D3DRS_WRAP6, "D3DRS_WRAP6"},
00395     {SC_RENDERSTATE, D3DRS_WRAP7, "D3DRS_WRAP7"},
00396     {SC_RENDERSTATE, D3DRS_WRAP8, "D3DRS_WRAP8"},
00397     {SC_RENDERSTATE, D3DRS_WRAP9, "D3DRS_WRAP9"},
00398     {SC_RENDERSTATE, D3DRS_WRAP10, "D3DRS_WRAP10"},
00399     {SC_RENDERSTATE, D3DRS_WRAP11, "D3DRS_WRAP11"},
00400     {SC_RENDERSTATE, D3DRS_WRAP12, "D3DRS_WRAP12"},
00401     {SC_RENDERSTATE, D3DRS_WRAP13, "D3DRS_WRAP13"},
00402     {SC_RENDERSTATE, D3DRS_WRAP14, "D3DRS_WRAP14"},
00403     {SC_RENDERSTATE, D3DRS_WRAP15, "D3DRS_WRAP15"},
00404     {SC_RENDERSTATE, D3DRS_CLIPPING, "D3DRS_CLIPPING"},
00405     {SC_RENDERSTATE, D3DRS_LIGHTING, "D3DRS_LIGHTING"}, /* 0x30 */
00406     {SC_RENDERSTATE, D3DRS_AMBIENT, "D3DRS_AMBIENT"},
00407     {SC_RENDERSTATE, D3DRS_FOGVERTEXMODE, "D3DRS_FOGVERTEXMODE"},
00408     {SC_RENDERSTATE, D3DRS_COLORVERTEX, "D3DRS_COLORVERTEX"},
00409     {SC_RENDERSTATE, D3DRS_LOCALVIEWER, "D3DRS_LOCALVIEWER"},
00410     {SC_RENDERSTATE, D3DRS_NORMALIZENORMALS, "D3DRS_NORMALIZENORMALS"},
00411     {SC_RENDERSTATE, D3DRS_DIFFUSEMATERIALSOURCE, "D3DRS_DIFFUSEMATERIALSOURCE"},
00412     {SC_RENDERSTATE, D3DRS_SPECULARMATERIALSOURCE, "D3DRS_SPECULARMATERIALSOURCE"},
00413     {SC_RENDERSTATE, D3DRS_AMBIENTMATERIALSOURCE, "D3DRS_AMBIENTMATERIALSOURCE"},
00414     {SC_RENDERSTATE, D3DRS_EMISSIVEMATERIALSOURCE, "D3DRS_EMISSIVEMATERIALSOURCE"},
00415     {SC_RENDERSTATE, D3DRS_VERTEXBLEND, "D3DRS_VERTEXBLEND"},
00416     {SC_RENDERSTATE, D3DRS_CLIPPLANEENABLE, "D3DRS_CLIPPLANEENABLE"},
00417     {SC_RENDERSTATE, D3DRS_POINTSIZE, "D3DRS_POINTSIZE"},
00418     {SC_RENDERSTATE, D3DRS_POINTSIZE_MIN, "D3DRS_POINTSIZE_MIN"},
00419     {SC_RENDERSTATE, D3DRS_POINTSIZE_MAX, "D3DRS_POINTSIZE_MAX"},
00420     {SC_RENDERSTATE, D3DRS_POINTSPRITEENABLE, "D3DRS_POINTSPRITEENABLE"},
00421     {SC_RENDERSTATE, D3DRS_POINTSCALEENABLE, "D3DRS_POINTSCALEENABLE"}, /* 0x40 */
00422     {SC_RENDERSTATE, D3DRS_POINTSCALE_A, "D3DRS_POINTSCALE_A"},
00423     {SC_RENDERSTATE, D3DRS_POINTSCALE_B, "D3DRS_POINTSCALE_B"},
00424     {SC_RENDERSTATE, D3DRS_POINTSCALE_C, "D3DRS_POINTSCALE_C"},
00425     {SC_RENDERSTATE, D3DRS_MULTISAMPLEANTIALIAS, "D3DRS_MULTISAMPLEANTIALIAS"},
00426     {SC_RENDERSTATE, D3DRS_MULTISAMPLEMASK, "D3DRS_MULTISAMPLEMASK"},
00427     {SC_RENDERSTATE, D3DRS_PATCHEDGESTYLE, "D3DRS_PATCHEDGESTYLE"},
00428     {SC_RENDERSTATE, D3DRS_DEBUGMONITORTOKEN, "D3DRS_DEBUGMONITORTOKEN"},
00429     {SC_RENDERSTATE, D3DRS_INDEXEDVERTEXBLENDENABLE, "D3DRS_INDEXEDVERTEXBLENDENABLE"},
00430     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE, "D3DRS_COLORWRITEENABLE"},
00431     {SC_RENDERSTATE, D3DRS_TWEENFACTOR, "D3DRS_TWEENFACTOR"},
00432     {SC_RENDERSTATE, D3DRS_BLENDOP, "D3DRS_BLENDOP"},
00433     {SC_RENDERSTATE, D3DRS_POSITIONDEGREE, "D3DRS_POSITIONDEGREE"},
00434     {SC_RENDERSTATE, D3DRS_NORMALDEGREE, "D3DRS_NORMALDEGREE"},
00435     {SC_RENDERSTATE, D3DRS_SCISSORTESTENABLE, "D3DRS_SCISSORTESTENABLE"},
00436     {SC_RENDERSTATE, D3DRS_SLOPESCALEDEPTHBIAS, "D3DRS_SLOPESCALEDEPTHBIAS"},
00437     {SC_RENDERSTATE, D3DRS_ANTIALIASEDLINEENABLE, "D3DRS_ANTIALIASEDLINEENABLE"}, /* 0x50 */
00438     {SC_RENDERSTATE, D3DRS_MINTESSELLATIONLEVEL, "D3DRS_MINTESSELLATIONLEVEL"},
00439     {SC_RENDERSTATE, D3DRS_MAXTESSELLATIONLEVEL, "D3DRS_MAXTESSELLATIONLEVEL"},
00440     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_X, "D3DRS_ADAPTIVETESS_X"},
00441     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Y, "D3DRS_ADAPTIVETESS_Y"},
00442     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_Z, "D3DRS_ADAPTIVETESS_Z"},
00443     {SC_RENDERSTATE, D3DRS_ADAPTIVETESS_W, "D3DRS_ADAPTIVETESS_W"},
00444     {SC_RENDERSTATE, D3DRS_ENABLEADAPTIVETESSELLATION, "D3DRS_ENABLEADAPTIVETESSELLATION"},
00445     {SC_RENDERSTATE, D3DRS_TWOSIDEDSTENCILMODE, "D3DRS_TWOSIDEDSTENCILMODE"},
00446     {SC_RENDERSTATE, D3DRS_CCW_STENCILFAIL, "D3DRS_CCW_STENCILFAIL"},
00447     {SC_RENDERSTATE, D3DRS_CCW_STENCILZFAIL, "D3DRS_CCW_STENCILZFAIL"},
00448     {SC_RENDERSTATE, D3DRS_CCW_STENCILPASS, "D3DRS_CCW_STENCILPASS"},
00449     {SC_RENDERSTATE, D3DRS_CCW_STENCILFUNC, "D3DRS_CCW_STENCILFUNC"},
00450     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE1, "D3DRS_COLORWRITEENABLE1"},
00451     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE2, "D3DRS_COLORWRITEENABLE2"},
00452     {SC_RENDERSTATE, D3DRS_COLORWRITEENABLE3, "D3DRS_COLORWRITEENABLE3"},
00453     {SC_RENDERSTATE, D3DRS_BLENDFACTOR, "D3DRS_BLENDFACTOR"}, /* 0x60 */
00454     {SC_RENDERSTATE, D3DRS_SRGBWRITEENABLE, "D3DRS_SRGBWRITEENABLE"},
00455     {SC_RENDERSTATE, D3DRS_DEPTHBIAS, "D3DRS_DEPTHBIAS"},
00456     {SC_RENDERSTATE, D3DRS_SEPARATEALPHABLENDENABLE, "D3DRS_SEPARATEALPHABLENDENABLE"},
00457     {SC_RENDERSTATE, D3DRS_SRCBLENDALPHA, "D3DRS_SRCBLENDALPHA"},
00458     {SC_RENDERSTATE, D3DRS_DESTBLENDALPHA, "D3DRS_DESTBLENDALPHA"},
00459     {SC_RENDERSTATE, D3DRS_BLENDOPALPHA, "D3DRS_BLENDOPALPHA"},
00460     /* Texture stages */
00461     {SC_TEXTURESTAGE, D3DTSS_COLOROP, "D3DTSS_COLOROP"},
00462     {SC_TEXTURESTAGE, D3DTSS_COLORARG0, "D3DTSS_COLORARG0"},
00463     {SC_TEXTURESTAGE, D3DTSS_COLORARG1, "D3DTSS_COLORARG1"},
00464     {SC_TEXTURESTAGE, D3DTSS_COLORARG2, "D3DTSS_COLORARG2"},
00465     {SC_TEXTURESTAGE, D3DTSS_ALPHAOP, "D3DTSS_ALPHAOP"},
00466     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG0, "D3DTSS_ALPHAARG0"},
00467     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG1, "D3DTSS_ALPHAARG1"},
00468     {SC_TEXTURESTAGE, D3DTSS_ALPHAARG2, "D3DTSS_ALPHAARG2"},
00469     {SC_TEXTURESTAGE, D3DTSS_RESULTARG, "D3DTSS_RESULTARG"},
00470     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT00, "D3DTSS_BUMPENVMAT00"}, /* 0x70 */
00471     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT01, "D3DTSS_BUMPENVMAT01"},
00472     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT10, "D3DTSS_BUMPENVMAT10"},
00473     {SC_TEXTURESTAGE, D3DTSS_BUMPENVMAT11, "D3DTSS_BUMPENVMAT11"},
00474     {SC_TEXTURESTAGE, D3DTSS_TEXCOORDINDEX, "D3DTSS_TEXCOORDINDEX"},
00475     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLSCALE, "D3DTSS_BUMPENVLSCALE"},
00476     {SC_TEXTURESTAGE, D3DTSS_BUMPENVLOFFSET, "D3DTSS_BUMPENVLOFFSET"},
00477     {SC_TEXTURESTAGE, D3DTSS_TEXTURETRANSFORMFLAGS, "D3DTSS_TEXTURETRANSFORMFLAGS"},
00478     {SC_TEXTURESTAGE, D3DTSS_CONSTANT, "D3DTSS_CONSTANT"},
00479     /* NPatchMode */
00480     {SC_NPATCHMODE, 0, "NPatchMode"},
00481     /* FVF */
00482     {SC_FVF, 0, "FVF"},
00483     /* Transform */
00484     {SC_TRANSFORM, D3DTS_PROJECTION, "D3DTS_PROJECTION"},
00485     {SC_TRANSFORM, D3DTS_VIEW, "D3DTS_VIEW"},
00486     {SC_TRANSFORM, D3DTS_WORLD, "D3DTS_WORLD"},
00487     {SC_TRANSFORM, D3DTS_TEXTURE0, "D3DTS_TEXTURE0"},
00488     /* Material */
00489     {SC_MATERIAL, MT_DIFFUSE, "MaterialDiffuse"},
00490     {SC_MATERIAL, MT_AMBIENT, "MaterialAmbient"}, /* 0x80 */
00491     {SC_MATERIAL, MT_SPECULAR, "MaterialSpecular"},
00492     {SC_MATERIAL, MT_EMISSIVE, "MaterialEmissive"},
00493     {SC_MATERIAL, MT_POWER, "MaterialPower"},
00494     /* Light */
00495     {SC_LIGHT, LT_TYPE, "LightType"},
00496     {SC_LIGHT, LT_DIFFUSE, "LightDiffuse"},
00497     {SC_LIGHT, LT_SPECULAR, "LightSpecular"},
00498     {SC_LIGHT, LT_AMBIENT, "LightAmbient"},
00499     {SC_LIGHT, LT_POSITION, "LightPosition"},
00500     {SC_LIGHT, LT_DIRECTION, "LightDirection"},
00501     {SC_LIGHT, LT_RANGE, "LightRange"},
00502     {SC_LIGHT, LT_FALLOFF, "LightFallOff"},
00503     {SC_LIGHT, LT_ATTENUATION0, "LightAttenuation0"},
00504     {SC_LIGHT, LT_ATTENUATION1, "LightAttenuation1"},
00505     {SC_LIGHT, LT_ATTENUATION2, "LightAttenuation2"},
00506     {SC_LIGHT, LT_THETA, "LightTheta"},
00507     {SC_LIGHT, LT_PHI, "LightPhi"}, /* 0x90 */
00508     /* Ligthenable */
00509     {SC_LIGHTENABLE, 0, "LightEnable"},
00510     /* Vertexshader */
00511     {SC_VERTEXSHADER, 0, "Vertexshader"},
00512     /* Pixelshader */
00513     {SC_PIXELSHADER, 0, "Pixelshader"},
00514     /* Shader constants */
00515     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstantF"},
00516     {SC_SHADERCONST, SCT_VSBOOL, "VertexShaderConstantB"},
00517     {SC_SHADERCONST, SCT_VSINT, "VertexShaderConstantI"},
00518     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant"},
00519     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant1"},
00520     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant2"},
00521     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant3"},
00522     {SC_SHADERCONST, SCT_VSFLOAT, "VertexShaderConstant4"},
00523     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstantF"},
00524     {SC_SHADERCONST, SCT_PSBOOL, "PixelShaderConstantB"},
00525     {SC_SHADERCONST, SCT_PSINT, "PixelShaderConstantI"},
00526     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant"},
00527     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant1"}, /* 0xa0 */
00528     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant2"},
00529     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant3"},
00530     {SC_SHADERCONST, SCT_PSFLOAT, "PixelShaderConstant4"},
00531     /* Texture */
00532     {SC_TEXTURE, 0, "Texture"},
00533     /* Sampler states */
00534     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSU, "AddressU"},
00535     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSV, "AddressV"},
00536     {SC_SAMPLERSTATE, D3DSAMP_ADDRESSW, "AddressW"},
00537     {SC_SAMPLERSTATE, D3DSAMP_BORDERCOLOR, "BorderColor"},
00538     {SC_SAMPLERSTATE, D3DSAMP_MAGFILTER, "MagFilter"},
00539     {SC_SAMPLERSTATE, D3DSAMP_MINFILTER, "MinFilter"},
00540     {SC_SAMPLERSTATE, D3DSAMP_MIPFILTER, "MipFilter"},
00541     {SC_SAMPLERSTATE, D3DSAMP_MIPMAPLODBIAS, "MipMapLodBias"},
00542     {SC_SAMPLERSTATE, D3DSAMP_MAXMIPLEVEL, "MaxMipLevel"},
00543     {SC_SAMPLERSTATE, D3DSAMP_MAXANISOTROPY, "MaxAnisotropy"},
00544     {SC_SAMPLERSTATE, D3DSAMP_SRGBTEXTURE, "SRGBTexture"},
00545     {SC_SAMPLERSTATE, D3DSAMP_ELEMENTINDEX, "ElementIndex"}, /* 0xb0 */
00546     {SC_SAMPLERSTATE, D3DSAMP_DMAPOFFSET, "DMAPOffset"},
00547     /* Set sampler */
00548     {SC_SETSAMPLER, 0, "Sampler"},
00549 };
00550 
00551 static inline void read_dword(const char **ptr, DWORD *d)
00552 {
00553     memcpy(d, *ptr, sizeof(*d));
00554     *ptr += sizeof(*d);
00555 }
00556 
00557 static void skip_dword_unknown(const char **ptr, unsigned int count)
00558 {
00559     unsigned int i;
00560     DWORD d;
00561 
00562     //FIXME("Skipping %u unknown DWORDs:\n", count);
00563     for (i = 0; i < count; ++i)
00564     {
00565         read_dword(ptr, &d);
00566         //FIXME("\t0x%08x\n", d);
00567     }
00568 }
00569 
00570 static inline struct d3dx_parameter *get_parameter_struct(D3DXHANDLE handle)
00571 {
00572     return (struct d3dx_parameter *) handle;
00573 }
00574 
00575 static inline struct d3dx_pass *get_pass_struct(D3DXHANDLE handle)
00576 {
00577     return (struct d3dx_pass *) handle;
00578 }
00579 
00580 static inline struct d3dx_technique *get_technique_struct(D3DXHANDLE handle)
00581 {
00582     return (struct d3dx_technique *) handle;
00583 }
00584 
00585 static inline D3DXHANDLE get_parameter_handle(struct d3dx_parameter *parameter)
00586 {
00587     return (D3DXHANDLE) parameter;
00588 }
00589 
00590 static inline D3DXHANDLE get_technique_handle(struct d3dx_technique *technique)
00591 {
00592     return (D3DXHANDLE) technique;
00593 }
00594 
00595 static inline D3DXHANDLE get_pass_handle(struct d3dx_pass *pass)
00596 {
00597     return (D3DXHANDLE) pass;
00598 }
00599 
00600 static struct d3dx_technique *get_technique_by_name(struct ID3DXBaseEffectImpl *base, LPCSTR name)
00601 {
00602     UINT i;
00603 
00604     if (!name) return NULL;
00605 
00606     for (i = 0; i < base->technique_count; ++i)
00607     {
00608         struct d3dx_technique *tech = get_technique_struct(base->technique_handles[i]);
00609 
00610         if (!strcmp(tech->name, name)) return tech;
00611     }
00612 
00613     return NULL;
00614 }
00615 
00616 static struct d3dx_technique *is_valid_technique(struct ID3DXBaseEffectImpl *base, D3DXHANDLE technique)
00617 {
00618     struct d3dx_technique *tech = NULL;
00619     unsigned int i;
00620 
00621     for (i = 0; i < base->technique_count; ++i)
00622     {
00623         if (base->technique_handles[i] == technique)
00624         {
00625             tech = get_technique_struct(technique);
00626             break;
00627         }
00628     }
00629 
00630     if (!tech) tech = get_technique_by_name(base, technique);
00631 
00632     return tech;
00633 }
00634 
00635 static struct d3dx_pass *is_valid_pass(struct ID3DXBaseEffectImpl *base, D3DXHANDLE pass)
00636 {
00637     unsigned int i, k;
00638 
00639     for (i = 0; i < base->technique_count; ++i)
00640     {
00641         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
00642 
00643         for (k = 0; k < technique->pass_count; ++k)
00644         {
00645             if (technique->pass_handles[k] == pass)
00646             {
00647                 return get_pass_struct(pass);
00648             }
00649         }
00650     }
00651 
00652     return NULL;
00653 }
00654 
00655 static struct d3dx_parameter *is_valid_sub_parameter(struct d3dx_parameter *param, D3DXHANDLE parameter)
00656 {
00657     unsigned int i, count;
00658     struct d3dx_parameter *p;
00659 
00660     for (i = 0; i < param->annotation_count; ++i)
00661     {
00662         if (param->annotation_handles[i] == parameter)
00663         {
00664             return get_parameter_struct(parameter);
00665         }
00666 
00667         p = is_valid_sub_parameter(get_parameter_struct(param->annotation_handles[i]), parameter);
00668         if (p) return p;
00669     }
00670 
00671     if (param->element_count) count = param->element_count;
00672     else count = param->member_count;
00673 
00674     for (i = 0; i < count; ++i)
00675     {
00676         if (param->member_handles[i] == parameter)
00677         {
00678             return get_parameter_struct(parameter);
00679         }
00680 
00681         p = is_valid_sub_parameter(get_parameter_struct(param->member_handles[i]), parameter);
00682         if (p) return p;
00683     }
00684 
00685     return NULL;
00686 }
00687 
00688 static struct d3dx_parameter *is_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
00689 {
00690     unsigned int i, k, m;
00691     struct d3dx_parameter *p;
00692 
00693     for (i = 0; i < base->parameter_count; ++i)
00694     {
00695         if (base->parameter_handles[i] == parameter)
00696         {
00697             return get_parameter_struct(parameter);
00698         }
00699 
00700         p = is_valid_sub_parameter(get_parameter_struct(base->parameter_handles[i]), parameter);
00701         if (p) return p;
00702     }
00703 
00704     for (i = 0; i < base->technique_count; ++i)
00705     {
00706         struct d3dx_technique *technique = get_technique_struct(base->technique_handles[i]);
00707 
00708         for (k = 0; k < technique->pass_count; ++k)
00709         {
00710             struct d3dx_pass *pass = get_pass_struct(technique->pass_handles[k]);
00711 
00712             for (m = 0; m < pass->annotation_count; ++m)
00713             {
00714                 if (pass->annotation_handles[i] == parameter)
00715                 {
00716                     return get_parameter_struct(parameter);
00717                 }
00718 
00719                 p = is_valid_sub_parameter(get_parameter_struct(pass->annotation_handles[m]), parameter);
00720                 if (p) return p;
00721             }
00722         }
00723 
00724         for (k = 0; k < technique->annotation_count; ++k)
00725         {
00726             if (technique->annotation_handles[k] == parameter)
00727             {
00728                 return get_parameter_struct(parameter);
00729             }
00730 
00731             p = is_valid_sub_parameter(get_parameter_struct(technique->annotation_handles[k]), parameter);
00732             if (p) return p;
00733         }
00734     }
00735 
00736     return NULL;
00737 }
00738 
00739 static inline struct d3dx_parameter *get_valid_parameter(struct ID3DXBaseEffectImpl *base, D3DXHANDLE parameter)
00740 {
00741     struct d3dx_parameter *param = is_valid_parameter(base, parameter);
00742 
00743     if (!param) param = get_parameter_by_name(base, NULL, parameter);
00744 
00745     return param;
00746 }
00747 
00748 static void free_state(struct d3dx_state *state)
00749 {
00750     free_parameter_state(state->parameter, FALSE, FALSE, state->type);
00751 }
00752 
00753 static void free_sampler(struct d3dx_sampler *sampler)
00754 {
00755     UINT i;
00756 
00757     for (i = 0; i < sampler->state_count; ++i)
00758     {
00759         free_state(&sampler->states[i]);
00760     }
00761     HeapFree(GetProcessHeap(), 0, sampler->states);
00762 }
00763 
00764 static void free_parameter(D3DXHANDLE handle, BOOL element, BOOL child)
00765 {
00766     free_parameter_state(handle, element, child, ST_CONSTANT);
00767 }
00768 
00769 static void free_parameter_state(D3DXHANDLE handle, BOOL element, BOOL child, enum STATE_TYPE st)
00770 {
00771     unsigned int i;
00772     struct d3dx_parameter *param = get_parameter_struct(handle);
00773 
00774     //TRACE("Free parameter %p, name %s, type %s, child %s, state_type %x\n", param, param->name,
00775     //        debug_d3dxparameter_type(param->type), child ? "yes" : "no", st);
00776 
00777     if (!param)
00778     {
00779         return;
00780     }
00781 
00782     if (param->annotation_handles)
00783     {
00784         for (i = 0; i < param->annotation_count; ++i)
00785         {
00786             free_parameter(param->annotation_handles[i], FALSE, FALSE);
00787         }
00788         HeapFree(GetProcessHeap(), 0, param->annotation_handles);
00789     }
00790 
00791     if (param->member_handles)
00792     {
00793         unsigned int count;
00794 
00795         if (param->element_count) count = param->element_count;
00796         else count = param->member_count;
00797 
00798         for (i = 0; i < count; ++i)
00799         {
00800             free_parameter(param->member_handles[i], param->element_count != 0, TRUE);
00801         }
00802         HeapFree(GetProcessHeap(), 0, param->member_handles);
00803     }
00804 
00805     if (param->class2 == D3DXPC_OBJECT && !param->element_count)
00806     {
00807         switch (param->type)
00808         {
00809             case D3DXPT_STRING:
00810                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
00811                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
00812                 break;
00813 
00814             case D3DXPT_TEXTURE:
00815             case D3DXPT_TEXTURE1D:
00816             case D3DXPT_TEXTURE2D:
00817             case D3DXPT_TEXTURE3D:
00818             case D3DXPT_TEXTURECUBE:
00819             case D3DXPT_PIXELSHADER:
00820             case D3DXPT_VERTEXSHADER:
00821                 if (st == ST_CONSTANT)
00822                 {
00823                     if (*(IUnknown **)param->data) IUnknown_Release(*(IUnknown **)param->data);
00824                 }
00825                 else
00826                 {
00827                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
00828                 }
00829                 if (!child) HeapFree(GetProcessHeap(), 0, param->data);
00830                 break;
00831 
00832             case D3DXPT_SAMPLER:
00833             case D3DXPT_SAMPLER1D:
00834             case D3DXPT_SAMPLER2D:
00835             case D3DXPT_SAMPLER3D:
00836             case D3DXPT_SAMPLERCUBE:
00837                 if (st == ST_CONSTANT)
00838                 {
00839                     free_sampler((struct d3dx_sampler *)param->data);
00840                 }
00841                 else
00842                 {
00843                     HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
00844                 }
00845                 /* samplers have always own data, so free that */
00846                 HeapFree(GetProcessHeap(), 0, param->data);
00847                 break;
00848 
00849             default:
00850                 //FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
00851                 break;
00852         }
00853     }
00854     else
00855     {
00856         if (!child)
00857         {
00858             if (st != ST_CONSTANT)
00859             {
00860                 HeapFree(GetProcessHeap(), 0, *(LPSTR *)param->data);
00861             }
00862             HeapFree(GetProcessHeap(), 0, param->data);
00863         }
00864     }
00865 
00866     /* only the parent has to release name and semantic */
00867     if (!element)
00868     {
00869         HeapFree(GetProcessHeap(), 0, param->name);
00870         HeapFree(GetProcessHeap(), 0, param->semantic);
00871     }
00872 
00873     HeapFree(GetProcessHeap(), 0, param);
00874 }
00875 
00876 static void free_pass(D3DXHANDLE handle)
00877 {
00878     unsigned int i;
00879     struct d3dx_pass *pass = get_pass_struct(handle);
00880 
00881     //TRACE("Free pass %p\n", pass);
00882 
00883     if (!pass)
00884     {
00885         return;
00886     }
00887 
00888     if (pass->annotation_handles)
00889     {
00890         for (i = 0; i < pass->annotation_count; ++i)
00891         {
00892             free_parameter(pass->annotation_handles[i], FALSE, FALSE);
00893         }
00894         HeapFree(GetProcessHeap(), 0, pass->annotation_handles);
00895     }
00896 
00897     if (pass->states)
00898     {
00899         for (i = 0; i < pass->state_count; ++i)
00900         {
00901             free_state(&pass->states[i]);
00902         }
00903         HeapFree(GetProcessHeap(), 0, pass->states);
00904     }
00905 
00906     HeapFree(GetProcessHeap(), 0, pass->name);
00907     HeapFree(GetProcessHeap(), 0, pass);
00908 }
00909 
00910 static void free_technique(D3DXHANDLE handle)
00911 {
00912     unsigned int i;
00913     struct d3dx_technique *technique = get_technique_struct(handle);
00914 
00915     //TRACE("Free technique %p\n", technique);
00916 
00917     if (!technique)
00918     {
00919         return;
00920     }
00921 
00922     if (technique->annotation_handles)
00923     {
00924         for (i = 0; i < technique->annotation_count; ++i)
00925         {
00926             free_parameter(technique->annotation_handles[i], FALSE, FALSE);
00927         }
00928         HeapFree(GetProcessHeap(), 0, technique->annotation_handles);
00929     }
00930 
00931     if (technique->pass_handles)
00932     {
00933         for (i = 0; i < technique->pass_count; ++i)
00934         {
00935             free_pass(technique->pass_handles[i]);
00936         }
00937         HeapFree(GetProcessHeap(), 0, technique->pass_handles);
00938     }
00939 
00940     HeapFree(GetProcessHeap(), 0, technique->name);
00941     HeapFree(GetProcessHeap(), 0, technique);
00942 }
00943 
00944 static void free_base_effect(struct ID3DXBaseEffectImpl *base)
00945 {
00946     unsigned int i;
00947 
00948     //TRACE("Free base effect %p\n", base);
00949 
00950     if (base->parameter_handles)
00951     {
00952         for (i = 0; i < base->parameter_count; ++i)
00953         {
00954             free_parameter(base->parameter_handles[i], FALSE, FALSE);
00955         }
00956         HeapFree(GetProcessHeap(), 0, base->parameter_handles);
00957     }
00958 
00959     if (base->technique_handles)
00960     {
00961         for (i = 0; i < base->technique_count; ++i)
00962         {
00963             free_technique(base->technique_handles[i]);
00964         }
00965         HeapFree(GetProcessHeap(), 0, base->technique_handles);
00966     }
00967 }
00968 
00969 static void free_effect(struct ID3DXEffectImpl *effect)
00970 {
00971     //TRACE("Free effect %p\n", effect);
00972     if (effect->base_effect)
00973     {
00974         //effect->base_effect->lpVtbl->Release(effect->base_effect);
00975         effect->base_effect->Release();
00976     }
00977 
00978     if (effect->pool)
00979     {
00980         //effect->pool->lpVtbl->Release(effect->pool);
00981             effect->pool->Release();
00982     }
00983 
00984     if (effect->manager)
00985     {
00986         IUnknown_Release(effect->manager);
00987     }
00988 
00989     IDirect3DDevice9_Release(effect->device);
00990 }
00991 
00992 static void free_effect_compiler(struct ID3DXEffectCompilerImpl *compiler)
00993 {
00994     //TRACE("Free effect compiler %p\n", compiler);
00995 
00996     if (compiler->base_effect)
00997     {
00998         //compiler->base_effect->lpVtbl->Release(compiler->base_effect);
00999           compiler->base_effect->Release();
01000     }
01001 }
01002 
01003 static void get_vector(struct d3dx_parameter *param, D3DXVECTOR4 *vector)
01004 {
01005     UINT i;
01006 
01007     for (i = 0; i < 4; ++i)
01008     {
01009         if (i < param->columns)
01010             set_number((FLOAT *)vector + i, D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
01011         else
01012             ((FLOAT *)vector)[i] = 0.0f;
01013     }
01014 }
01015 
01016 static void set_vector(struct d3dx_parameter *param, CONST D3DXVECTOR4 *vector)
01017 {
01018     UINT i;
01019 
01020     for (i = 0; i < param->columns; ++i)
01021     {
01022         set_number((FLOAT *)param->data + i, param->type, (FLOAT *)vector + i, D3DXPT_FLOAT);
01023     }
01024 }
01025 
01026 static void get_matrix(struct d3dx_parameter *param, D3DXMATRIX *matrix, BOOL transpose)
01027 {
01028     UINT i, k;
01029 
01030     for (i = 0; i < 4; ++i)
01031     {
01032         for (k = 0; k < 4; ++k)
01033         {
01034             //FLOAT *tmp = transpose ? (FLOAT *)&matrix->u.m[k][i] : (FLOAT *)&matrix->u.m[i][k];
01035             FLOAT *tmp = transpose ? (FLOAT *)&matrix->m[k][i] : (FLOAT *)&matrix->m[i][k];
01036 
01037             if ((i < param->rows) && (k < param->columns))
01038                 set_number(tmp, D3DXPT_FLOAT, (DWORD *)param->data + i * param->columns + k, param->type);
01039             else
01040                 *tmp = 0.0f;
01041         }
01042     }
01043 }
01044 
01045 static void set_matrix(struct d3dx_parameter *param, const D3DXMATRIX *matrix, BOOL transpose)
01046 {
01047     UINT i, k;
01048 
01049     for (i = 0; i < param->rows; ++i)
01050     {
01051         for (k = 0; k < param->columns; ++k)
01052         {
01053             set_number((FLOAT *)param->data + i * param->columns + k, param->type,
01054                     transpose ? &matrix->m[k][i] : &matrix->m[i][k], D3DXPT_FLOAT);
01055                     //transpose ? &matrix->u.m[k][i] : &matrix->u.m[i][k], D3DXPT_FLOAT);
01056         }
01057     }
01058 }
01059 
01060 static struct d3dx_parameter *get_parameter_element_by_name(struct d3dx_parameter *parameter, LPCSTR name)
01061 {
01062     UINT element;
01063     struct d3dx_parameter *temp_parameter;
01064     LPCSTR part;
01065 
01066     //TRACE("parameter %p, name %s\n", parameter, debugstr_a(name));
01067 
01068     if (!name || !*name) return NULL;
01069 
01070     element = atoi(name);
01071     part = strchr(name, ']') + 1;
01072 
01073     /* check for empty [] && element range */
01074     if ((part - name) > 1 && parameter->element_count > element)
01075     {
01076         temp_parameter = get_parameter_struct(parameter->member_handles[element]);
01077 
01078         switch (*part++)
01079         {
01080             case '.':
01081                 return get_parameter_by_name(NULL, temp_parameter, part);
01082 
01083             case '@':
01084                 return get_annotation_by_name(temp_parameter->annotation_count, temp_parameter->annotation_handles, part);
01085 
01086             case '\0':
01087                 //TRACE("Returning parameter %p\n", temp_parameter);
01088                 return temp_parameter;
01089 
01090             default:
01091                 //FIXME("Unhandled case \"%c\"\n", *--part);
01092                 break;
01093         }
01094     }
01095 
01096     //TRACE("Parameter not found\n");
01097     return NULL;
01098 }
01099 
01100 static struct d3dx_parameter *get_annotation_by_name(UINT handlecount, D3DXHANDLE *handles, LPCSTR name)
01101 {
01102     UINT i, length;
01103     struct d3dx_parameter *temp_parameter;
01104     LPCSTR part;
01105 
01106     //TRACE("handlecount %u, handles %p, name %s\n", handlecount, handles, debugstr_a(name));
01107 
01108     if (!name || !*name) return NULL;
01109 
01110     length = strcspn( name, "[.@" );
01111     part = name + length;
01112 
01113     for (i = 0; i < handlecount; ++i)
01114     {
01115         temp_parameter = get_parameter_struct(handles[i]);
01116 
01117         if (!strcmp(temp_parameter->name, name))
01118         {
01119             //TRACE("Returning parameter %p\n", temp_parameter);
01120             return temp_parameter;
01121         }
01122         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
01123         {
01124             switch (*part++)
01125             {
01126                 case '.':
01127                     return get_parameter_by_name(NULL, temp_parameter, part);
01128 
01129                 case '[':
01130                     return get_parameter_element_by_name(temp_parameter, part);
01131 
01132                 default:
01133                     //FIXME("Unhandled case \"%c\"\n", *--part);
01134                     break;
01135             }
01136         }
01137     }
01138 
01139     //TRACE("Parameter not found\n");
01140     return NULL;
01141 }
01142 
01143 static struct d3dx_parameter *get_parameter_by_name(struct ID3DXBaseEffectImpl *base,
01144         struct d3dx_parameter *parameter, LPCSTR name)
01145 {
01146     UINT i, count, length;
01147     struct d3dx_parameter *temp_parameter;
01148     D3DXHANDLE *handles;
01149     LPCSTR part;
01150 
01151     //TRACE("base %p, parameter %p, name %s\n", base, parameter, debugstr_a(name));
01152 
01153     if (!name || !*name) return NULL;
01154 
01155     if (!parameter)
01156     {
01157         count = base->parameter_count;
01158         handles = base->parameter_handles;
01159     }
01160     else
01161     {
01162         count = parameter->member_count;
01163         handles = parameter->member_handles;
01164     }
01165 
01166     length = strcspn( name, "[.@" );
01167     part = name + length;
01168 
01169     for (i = 0; i < count; i++)
01170     {
01171         temp_parameter = get_parameter_struct(handles[i]);
01172 
01173         if (!strcmp(temp_parameter->name, name))
01174         {
01175             //TRACE("Returning parameter %p\n", temp_parameter);
01176             return temp_parameter;
01177         }
01178         else if (strlen(temp_parameter->name) == length && !strncmp(temp_parameter->name, name, length))
01179         {
01180             switch (*part++)
01181             {
01182                 case '.':
01183                     return get_parameter_by_name(NULL, temp_parameter, part);
01184 
01185                 case '@':
01186                     return get_annotation_by_name(temp_parameter->annotation_count, temp_parameter->annotation_handles, part);
01187 
01188                 case '[':
01189                     return get_parameter_element_by_name(temp_parameter, part);
01190 
01191                 default:
01192                     //FIXME("Unhandled case \"%c\"\n", *--part);
01193                     break;
01194             }
01195         }
01196     }
01197 
01198     //TRACE("Parameter not found\n");
01199     return NULL;
01200 }
01201 
01202 static inline DWORD d3dx9_effect_version(DWORD major, DWORD minor)
01203 {
01204     return (0xfeff0000 | ((major) << 8) | (minor));
01205 }
01206 
01207 static inline struct ID3DXBaseEffectImpl *impl_from_ID3DXBaseEffect(ID3DXBaseEffect *iface)
01208 {
01209     return CONTAINING_RECORD(iface, struct ID3DXBaseEffectImpl, ID3DXBaseEffect_iface);
01210 }
01211 
01212 /*** IUnknown methods ***/
01213 static HRESULT WINAPI ID3DXBaseEffectImpl_QueryInterface(ID3DXBaseEffect *iface, REFIID riid, void **object)
01214 {
01215     //TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
01216 
01217     if (IsEqualGUID(riid, (const GUID &)IID_IUnknown) ||
01218         IsEqualGUID(riid, (const GUID &)IID_ID3DXBaseEffect))
01219     {
01220         //iface->lpVtbl->AddRef(iface);
01221         iface->AddRef();
01222         *object = iface;
01223         return S_OK;
01224     }
01225 
01226     //ERR("Interface %s not found\n", debugstr_guid(riid));
01227 
01228     return E_NOINTERFACE;
01229 }
01230 
01231 static ULONG WINAPI ID3DXBaseEffectImpl_AddRef(ID3DXBaseEffect *iface)
01232 {
01233     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01234 
01235     //TRACE("iface %p: AddRef from %u\n", iface, This->ref);
01236 
01237     return InterlockedIncrement(&This->ref);
01238 }
01239 
01240 static ULONG WINAPI ID3DXBaseEffectImpl_Release(ID3DXBaseEffect *iface)
01241 {
01242     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01243     ULONG ref = InterlockedDecrement(&This->ref);
01244 
01245     //TRACE("iface %p: Release from %u\n", iface, ref + 1);
01246 
01247     if (!ref)
01248     {
01249         free_base_effect(This);
01250         HeapFree(GetProcessHeap(), 0, This);
01251     }
01252 
01253     return ref;
01254 }
01255 
01256 /*** ID3DXBaseEffect methods ***/
01257 static HRESULT WINAPI ID3DXBaseEffectImpl_GetDesc(ID3DXBaseEffect *iface, D3DXEFFECT_DESC *desc)
01258 {
01259     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01260 
01261     //FIXME("iface %p, desc %p partial stub\n", This, desc);
01262 
01263     if (!desc)
01264     {
01265         //WARN("Invalid argument specified.\n");
01266         return D3DERR_INVALIDCALL;
01267     }
01268 
01269     /* Todo: add creator and function count */
01270     desc->Creator = NULL;
01271     desc->Functions = 0;
01272     desc->Parameters = This->parameter_count;
01273     desc->Techniques = This->technique_count;
01274 
01275     return D3D_OK;
01276 }
01277 
01278 static HRESULT WINAPI ID3DXBaseEffectImpl_GetParameterDesc(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
01279 {
01280     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01281     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01282 
01283     //TRACE("iface %p, parameter %p, desc %p\n", This, parameter, desc);
01284 
01285     if (!desc || !param)
01286     {
01287         //WARN("Invalid argument specified.\n");
01288         return D3DERR_INVALIDCALL;
01289     }
01290 
01291     desc->Name = param->name;
01292     desc->Semantic = param->semantic;
01293     desc->Class = param->class2;
01294     desc->Type = param->type;
01295     desc->Rows = param->rows;
01296     desc->Columns = param->columns;
01297     desc->Elements = param->element_count;
01298     desc->Annotations = param->annotation_count;
01299     desc->StructMembers = param->member_count;
01300     desc->Flags = param->flags;
01301     desc->Bytes = param->bytes;
01302 
01303     return D3D_OK;
01304 }
01305 
01306 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTechniqueDesc(ID3DXBaseEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
01307 {
01308     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01309     struct d3dx_technique *tech = technique ? is_valid_technique(This, technique) : get_technique_struct(This->technique_handles[0]);
01310 
01311     //TRACE("iface %p, technique %p, desc %p\n", This, technique, desc);
01312 
01313     if (!desc || !tech)
01314     {
01315         //WARN("Invalid argument specified.\n");
01316         return D3DERR_INVALIDCALL;
01317     }
01318 
01319     desc->Name = tech->name;
01320     desc->Passes = tech->pass_count;
01321     desc->Annotations = tech->annotation_count;
01322 
01323     return D3D_OK;
01324 }
01325 
01326 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPassDesc(ID3DXBaseEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
01327 {
01328     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01329     struct d3dx_pass *p = is_valid_pass(This, pass);
01330 
01331     //TRACE("iface %p, pass %p, desc %p\n", This, pass, desc);
01332 
01333     if (!desc || !p)
01334     {
01335         //WARN("Invalid argument specified.\n");
01336         return D3DERR_INVALIDCALL;
01337     }
01338 
01339     desc->Name = p->name;
01340     desc->Annotations = p->annotation_count;
01341 
01342     //FIXME("Pixel shader and vertex shader are not supported, yet.\n");
01343     desc->pVertexShaderFunction = NULL;
01344     desc->pPixelShaderFunction = NULL;
01345 
01346     return D3D_OK;
01347 }
01348 
01349 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFunctionDesc(ID3DXBaseEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
01350 {
01351     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01352 
01353     //FIXME("iface %p, shader %p, desc %p stub\n", This, shader, desc);
01354 
01355     return E_NOTIMPL;
01356 }
01357 
01358 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameter(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
01359 {
01360     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01361     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01362 
01363     //TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
01364 
01365     if (!parameter)
01366     {
01367         if (index < This->parameter_count)
01368         {
01369             //TRACE("Returning parameter %p\n", This->parameter_handles[index]);
01370             return This->parameter_handles[index];
01371         }
01372     }
01373     else
01374     {
01375         if (param && !param->element_count && index < param->member_count)
01376         {
01377             //TRACE("Returning parameter %p\n", param->member_handles[index]);
01378             return param->member_handles[index];
01379         }
01380     }
01381 
01382     //WARN("Invalid argument specified.\n");
01383 
01384     return NULL;
01385 }
01386 
01387 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterByName(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR name)
01388 {
01389     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01390     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01391     D3DXHANDLE handle;
01392 
01393     //TRACE("iface %p, parameter %p, name %s\n", This, parameter, debugstr_a(name));
01394 
01395     if (!name)
01396     {
01397         handle = get_parameter_handle(param);
01398         //TRACE("Returning parameter %p\n", handle);
01399         return handle;
01400     }
01401 
01402     handle = get_parameter_handle(get_parameter_by_name(This, param, name));
01403     //TRACE("Returning parameter %p\n", handle);
01404 
01405     return handle;
01406 }
01407 
01408 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterBySemantic(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
01409 {
01410     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01411     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01412     struct d3dx_parameter *temp_param;
01413     UINT i;
01414 
01415     //TRACE("iface %p, parameter %p, semantic %s\n", This, parameter, debugstr_a(semantic));
01416 
01417     if (!parameter)
01418     {
01419         for (i = 0; i < This->parameter_count; ++i)
01420         {
01421             temp_param = get_parameter_struct(This->parameter_handles[i]);
01422 
01423             if (!temp_param->semantic)
01424             {
01425                 if (!semantic)
01426                 {
01427                     //TRACE("Returning parameter %p\n", This->parameter_handles[i]);
01428                     return This->parameter_handles[i];
01429                 }
01430                 continue;
01431             }
01432 
01433             if (!strcasecmp(temp_param->semantic, semantic))
01434             {
01435                 //TRACE("Returning parameter %p\n", This->parameter_handles[i]);
01436                 return This->parameter_handles[i];
01437             }
01438         }
01439     }
01440     else if (param)
01441     {
01442         for (i = 0; i < param->member_count; ++i)
01443         {
01444             temp_param = get_parameter_struct(param->member_handles[i]);
01445 
01446             if (!temp_param->semantic)
01447             {
01448                 if (!semantic)
01449                 {
01450                     //TRACE("Returning parameter %p\n", param->member_handles[i]);
01451                     return param->member_handles[i];
01452                 }
01453                 continue;
01454             }
01455 
01456             if (!strcasecmp(temp_param->semantic, semantic))
01457             {
01458                 //TRACE("Returning parameter %p\n", param->member_handles[i]);
01459                 return param->member_handles[i];
01460             }
01461         }
01462     }
01463 
01464     //WARN("Invalid argument specified\n");
01465 
01466     return NULL;
01467 }
01468 
01469 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetParameterElement(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT index)
01470 {
01471     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01472     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01473 
01474     //TRACE("iface %p, parameter %p, index %u\n", This, parameter, index);
01475 
01476     if (!param)
01477     {
01478         if (index < This->parameter_count)
01479         {
01480             //TRACE("Returning parameter %p\n", This->parameter_handles[index]);
01481             return This->parameter_handles[index];
01482         }
01483     }
01484     else
01485     {
01486         if (index < param->element_count)
01487         {
01488             //TRACE("Returning parameter %p\n", param->member_handles[index]);
01489             return param->member_handles[index];
01490         }
01491     }
01492 
01493     //WARN("Invalid argument specified\n");
01494 
01495     return NULL;
01496 }
01497 
01498 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechnique(ID3DXBaseEffect *iface, UINT index)
01499 {
01500     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01501 
01502     //TRACE("iface %p, index %u\n", This, index);
01503 
01504     if (index >= This->technique_count)
01505     {
01506         //WARN("Invalid argument specified.\n");
01507         return NULL;
01508     }
01509 
01510     //TRACE("Returning technique %p\n", This->technique_handles[index]);
01511 
01512     return This->technique_handles[index];
01513 }
01514 
01515 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetTechniqueByName(ID3DXBaseEffect *iface, LPCSTR name)
01516 {
01517     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01518     struct d3dx_technique *tech = get_technique_by_name(This, name);
01519 
01520     //TRACE("iface %p, name %s stub\n", This, debugstr_a(name));
01521 
01522     if (tech)
01523     {
01524         D3DXHANDLE t = get_technique_handle(tech);
01525         //TRACE("Returning technique %p\n", t);
01526         return t;
01527     }
01528 
01529     //WARN("Invalid argument specified.\n");
01530 
01531     return NULL;
01532 }
01533 
01534 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPass(ID3DXBaseEffect *iface, D3DXHANDLE technique, UINT index)
01535 {
01536     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01537     struct d3dx_technique *tech = is_valid_technique(This, technique);
01538 
01539     //TRACE("iface %p, technique %p, index %u\n", This, technique, index);
01540 
01541     if (tech && index < tech->pass_count)
01542     {
01543         //TRACE("Returning pass %p\n", tech->pass_handles[index]);
01544         return tech->pass_handles[index];
01545     }
01546 
01547     //WARN("Invalid argument specified.\n");
01548 
01549     return NULL;
01550 }
01551 
01552 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetPassByName(ID3DXBaseEffect *iface, D3DXHANDLE technique, LPCSTR name)
01553 {
01554     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01555     struct d3dx_technique *tech = is_valid_technique(This, technique);
01556 
01557     //TRACE("iface %p, technique %p, name %s\n", This, technique, debugstr_a(name));
01558 
01559     if (tech && name)
01560     {
01561         unsigned int i;
01562 
01563         for (i = 0; i < tech->pass_count; ++i)
01564         {
01565             struct d3dx_pass *pass = get_pass_struct(tech->pass_handles[i]);
01566 
01567             if (!strcmp(pass->name, name))
01568             {
01569                 //TRACE("Returning pass %p\n", tech->pass_handles[i]);
01570                 return tech->pass_handles[i];
01571             }
01572         }
01573     }
01574 
01575     //WARN("Invalid argument specified.\n");
01576 
01577     return NULL;
01578 }
01579 
01580 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunction(ID3DXBaseEffect *iface, UINT index)
01581 {
01582     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01583 
01584     //FIXME("iface %p, index %u stub\n", This, index);
01585 
01586     return NULL;
01587 }
01588 
01589 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetFunctionByName(ID3DXBaseEffect *iface, LPCSTR name)
01590 {
01591     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01592 
01593     //FIXME("iface %p, name %s stub\n", This, debugstr_a(name));
01594 
01595     return NULL;
01596 }
01597 
01598 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotation(ID3DXBaseEffect *iface, D3DXHANDLE object, UINT index)
01599 {
01600     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01601     struct d3dx_parameter *param = get_valid_parameter(This, object);
01602     struct d3dx_pass *pass = is_valid_pass(This, object);
01603     struct d3dx_technique *technique = is_valid_technique(This, object);
01604     UINT annotation_count = 0;
01605     D3DXHANDLE *annotation_handles = NULL;
01606 
01607     //TRACE("iface %p, object %p, index %u\n", This, object, index);
01608 
01609     if (pass)
01610     {
01611         annotation_count = pass->annotation_count;
01612         annotation_handles = pass->annotation_handles;
01613     }
01614     else if (technique)
01615     {
01616         annotation_count = technique->annotation_count;
01617         annotation_handles = technique->annotation_handles;
01618     }
01619     else if (param)
01620     {
01621         annotation_count = param->annotation_count;
01622         annotation_handles = param->annotation_handles;
01623     }
01624     else
01625     {
01626         //FIXME("Functions are not handled, yet!\n");
01627     }
01628 
01629     if (index < annotation_count)
01630     {
01631         //TRACE("Returning parameter %p\n", annotation_handles[index]);
01632         return annotation_handles[index];
01633     }
01634 
01635     //WARN("Invalid argument specified\n");
01636 
01637     return NULL;
01638 }
01639 
01640 static D3DXHANDLE WINAPI ID3DXBaseEffectImpl_GetAnnotationByName(ID3DXBaseEffect *iface, D3DXHANDLE object, LPCSTR name)
01641 {
01642     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01643     struct d3dx_parameter *param = get_valid_parameter(This, object);
01644     struct d3dx_pass *pass = is_valid_pass(This, object);
01645     struct d3dx_technique *technique = is_valid_technique(This, object);
01646     struct d3dx_parameter *anno = NULL;
01647     UINT annotation_count = 0;
01648     D3DXHANDLE *annotation_handles = NULL;
01649 
01650     //TRACE("iface %p, object %p, name %s\n", This, object, debugstr_a(name));
01651 
01652     if (!name)
01653     {
01654         //WARN("Invalid argument specified\n");
01655         return NULL;
01656     }
01657 
01658     if (pass)
01659     {
01660         annotation_count = pass->annotation_count;
01661         annotation_handles = pass->annotation_handles;
01662     }
01663     else if (technique)
01664     {
01665         annotation_count = technique->annotation_count;
01666         annotation_handles = technique->annotation_handles;
01667     }
01668     else if (param)
01669     {
01670         annotation_count = param->annotation_count;
01671         annotation_handles = param->annotation_handles;
01672     }
01673     else
01674     {
01675         //FIXME("Functions are not handled, yet!\n");
01676     }
01677 
01678     anno = get_annotation_by_name(annotation_count, annotation_handles, name);
01679     if (anno)
01680     {
01681         //TRACE("Returning parameter %p\n", anno);
01682         return get_parameter_handle(anno);
01683     }
01684 
01685     //WARN("Invalid argument specified\n");
01686 
01687     return NULL;
01688 }
01689 
01690 static HRESULT WINAPI ID3DXBaseEffectImpl_SetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
01691 {
01692     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01693     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01694 
01695     //TRACE("iface %p, parameter %p, data %p, bytes %u\n", This, parameter, data, bytes);
01696 
01697     if (!param)
01698     {
01699         //WARN("Invalid parameter %p specified\n", parameter);
01700         return D3DERR_INVALIDCALL;
01701     }
01702 
01703     /* samplers don't touch data */
01704     if (param->class2 == D3DXPC_OBJECT && (param->type == D3DXPT_SAMPLER
01705             || param->type == D3DXPT_SAMPLER1D || param->type == D3DXPT_SAMPLER2D
01706             || param->type == D3DXPT_SAMPLER3D || param->type == D3DXPT_SAMPLERCUBE))
01707     {
01708         //TRACE("Sampler: returning E_FAIL\n");
01709         return E_FAIL;
01710     }
01711 
01712     if (data && param->bytes <= bytes)
01713     {
01714         switch (param->type)
01715         {
01716             case D3DXPT_VOID:
01717             case D3DXPT_BOOL:
01718             case D3DXPT_INT:
01719             case D3DXPT_FLOAT:
01720                 //TRACE("Copy %u bytes\n", param->bytes);
01721                 memcpy(param->data, data, param->bytes);
01722                 break;
01723 
01724             default:
01725                 //FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
01726                 break;
01727         }
01728 
01729         return D3D_OK;
01730     }
01731 
01732     //WARN("Invalid argument specified\n");
01733 
01734     return D3DERR_INVALIDCALL;
01735 }
01736 
01737 static HRESULT WINAPI ID3DXBaseEffectImpl_GetValue(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
01738 {
01739     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01740     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01741 
01742     //TRACE("iface %p, parameter %p, data %p, bytes %u\n", This, parameter, data, bytes);
01743 
01744     if (!param)
01745     {
01746         //WARN("Invalid parameter %p specified\n", parameter);
01747         return D3DERR_INVALIDCALL;
01748     }
01749 
01750     /* samplers don't touch data */
01751     if (param->class2 == D3DXPC_OBJECT && (param->type == D3DXPT_SAMPLER
01752             || param->type == D3DXPT_SAMPLER1D || param->type == D3DXPT_SAMPLER2D
01753             || param->type == D3DXPT_SAMPLER3D || param->type == D3DXPT_SAMPLERCUBE))
01754     {
01755         //TRACE("Sampler: returning E_FAIL\n");
01756         return E_FAIL;
01757     }
01758 
01759     if (data && param->bytes <= bytes)
01760     {
01761         //TRACE("Type %s\n", debug_d3dxparameter_type(param->type));
01762 
01763         switch (param->type)
01764         {
01765             case D3DXPT_VOID:
01766             case D3DXPT_BOOL:
01767             case D3DXPT_INT:
01768             case D3DXPT_FLOAT:
01769             case D3DXPT_STRING:
01770                 break;
01771 
01772             case D3DXPT_VERTEXSHADER:
01773             case D3DXPT_PIXELSHADER:
01774             case D3DXPT_TEXTURE:
01775             case D3DXPT_TEXTURE1D:
01776             case D3DXPT_TEXTURE2D:
01777             case D3DXPT_TEXTURE3D:
01778             case D3DXPT_TEXTURECUBE:
01779             {
01780                 UINT i;
01781 
01782                 for (i = 0; i < (param->element_count ? param->element_count : 1); ++i)
01783                 {
01784                     IUnknown *unk = ((IUnknown **)param->data)[i];
01785                     if (unk) IUnknown_AddRef(unk);
01786                 }
01787                 break;
01788             }
01789 
01790             default:
01791                 //FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
01792                 break;
01793         }
01794 
01795         //TRACE("Copy %u bytes\n", param->bytes);
01796         memcpy(data, param->data, param->bytes);
01797         return D3D_OK;
01798     }
01799 
01800     //WARN("Invalid argument specified\n");
01801 
01802     return D3DERR_INVALIDCALL;
01803 }
01804 
01805 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL b)
01806 {
01807     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01808     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01809 
01810     //TRACE("iface %p, parameter %p, b %s\n", This, parameter, b ? "TRUE" : "FALSE");
01811 
01812     if (param && !param->element_count && param->rows == 1 && param->columns == 1)
01813     {
01814         set_number(param->data, param->type, &b, D3DXPT_BOOL);
01815         return D3D_OK;
01816     }
01817 
01818     //WARN("Invalid argument specified\n");
01819 
01820     return D3DERR_INVALIDCALL;
01821 }
01822 
01823 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBool(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b)
01824 {
01825     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01826     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01827 
01828     //TRACE("iface %p, parameter %p, b %p\n", This, parameter, b);
01829 
01830     if (b && param && !param->element_count && param->rows == 1 && param->columns == 1)
01831     {
01832         set_number(b, D3DXPT_BOOL, param->data, param->type);
01833         //TRACE("Returning %s\n", *b ? "TRUE" : "FALSE");
01834         return D3D_OK;
01835     }
01836 
01837     //WARN("Invalid argument specified\n");
01838 
01839     return D3DERR_INVALIDCALL;
01840 }
01841 
01842 static HRESULT WINAPI ID3DXBaseEffectImpl_SetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
01843 {
01844     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01845     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01846 
01847     //TRACE("iface %p, parameter %p, b %p, count %u\n", This, parameter, b, count);
01848 
01849     if (param)
01850     {
01851         UINT i, size = min(count, param->bytes / sizeof(DWORD));
01852 
01853         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
01854 
01855         switch (param->class2)
01856         {
01857             case D3DXPC_SCALAR:
01858             case D3DXPC_VECTOR:
01859             case D3DXPC_MATRIX_ROWS:
01860                 for (i = 0; i < size; ++i)
01861                 {
01862                     /* don't crop the input, use D3DXPT_INT instead of D3DXPT_BOOL */
01863                     set_number((DWORD *)param->data + i, param->type, &b[i], D3DXPT_INT);
01864                 }
01865                 return D3D_OK;
01866 
01867             case D3DXPC_OBJECT:
01868             case D3DXPC_STRUCT:
01869                 break;
01870 
01871             default:
01872                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
01873                 break;
01874         }
01875     }
01876 
01877     //WARN("Invalid argument specified\n");
01878 
01879     return D3DERR_INVALIDCALL;
01880 }
01881 
01882 static HRESULT WINAPI ID3DXBaseEffectImpl_GetBoolArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
01883 {
01884     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01885     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01886 
01887     //TRACE("iface %p, parameter %p, b %p, count %u\n", This, parameter, b, count);
01888 
01889     if (b && param && (param->class2 == D3DXPC_SCALAR
01890             || param->class2 == D3DXPC_VECTOR
01891             || param->class2 == D3DXPC_MATRIX_ROWS
01892             || param->class2 == D3DXPC_MATRIX_COLUMNS))
01893     {
01894         UINT i, size = min(count, param->bytes / sizeof(DWORD));
01895 
01896         for (i = 0; i < size; ++i)
01897         {
01898             set_number(&b[i], D3DXPT_BOOL, (DWORD *)param->data + i, param->type);
01899         }
01900         return D3D_OK;
01901     }
01902 
01903     //WARN("Invalid argument specified\n");
01904 
01905     return D3DERR_INVALIDCALL;
01906 }
01907 
01908 static HRESULT WINAPI ID3DXBaseEffectImpl_SetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT n)
01909 {
01910     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01911     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01912 
01913     //TRACE("iface %p, parameter %p, n %i\n", This, parameter, n);
01914 
01915     if (param && !param->element_count)
01916     {
01917         if (param->rows == 1 && param->columns == 1)
01918         {
01919             set_number(param->data, param->type, &n, D3DXPT_INT);
01920             return D3D_OK;
01921         }
01922 
01923         /*
01924          * Split the value, if parameter is a vector with dimension 3 or 4.
01925          */
01926         if (param->type == D3DXPT_FLOAT &&
01927             ((param->class2 == D3DXPC_VECTOR && param->columns != 2) ||
01928             (param->class2 == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
01929         {
01930             //TRACE("Vector fixup\n");
01931 
01932             *(FLOAT *)param->data = ((n & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
01933             ((FLOAT *)param->data)[1] = ((n & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
01934             ((FLOAT *)param->data)[2] = (n & 0xff) * INT_FLOAT_MULTI_INVERSE;
01935             if (param->rows * param->columns > 3)
01936             {
01937                 ((FLOAT *)param->data)[3] = ((n & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
01938             }
01939             return D3D_OK;
01940         }
01941     }
01942 
01943     //WARN("Invalid argument specified\n");
01944 
01945     return D3DERR_INVALIDCALL;
01946 }
01947 
01948 static HRESULT WINAPI ID3DXBaseEffectImpl_GetInt(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n)
01949 {
01950     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01951     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01952 
01953     //TRACE("iface %p, parameter %p, n %p\n", This, parameter, n);
01954 
01955     if (n && param && !param->element_count)
01956     {
01957         if (param->columns == 1 && param->rows == 1)
01958         {
01959             set_number(n, D3DXPT_INT, param->data, param->type);
01960             //TRACE("Returning %i\n", *n);
01961             return D3D_OK;
01962         }
01963 
01964         if (param->type == D3DXPT_FLOAT &&
01965                 ((param->class2 == D3DXPC_VECTOR && param->columns != 2)
01966                 || (param->class2 == D3DXPC_MATRIX_ROWS && param->rows != 2 && param->columns == 1)))
01967         {
01968             //TRACE("Vector fixup\n");
01969 
01970             /* all components (3,4) are clamped (0,255) and put in the INT */
01971             *n = (INT)(min(max(0.0f, *((FLOAT *)param->data + 2)), 1.0f) * INT_FLOAT_MULTI);
01972             *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 1)), 1.0f) * INT_FLOAT_MULTI)) << 8;
01973             *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 0)), 1.0f) * INT_FLOAT_MULTI)) << 16;
01974             if (param->columns * param->rows > 3)
01975             {
01976                 *n += ((INT)(min(max(0.0f, *((FLOAT *)param->data + 3)), 1.0f) * INT_FLOAT_MULTI)) << 24;
01977             }
01978 
01979             //TRACE("Returning %i\n", *n);
01980             return D3D_OK;
01981         }
01982     }
01983 
01984     //WARN("Invalid argument specified\n");
01985 
01986     return D3DERR_INVALIDCALL;
01987 }
01988 
01989 static HRESULT WINAPI ID3DXBaseEffectImpl_SetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
01990 {
01991     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
01992     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
01993 
01994     //TRACE("iface %p, parameter %p, n %p, count %u\n", This, parameter, n, count);
01995 
01996     if (param)
01997     {
01998         UINT i, size = min(count, param->bytes / sizeof(DWORD));
01999 
02000         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02001 
02002         switch (param->class2)
02003         {
02004             case D3DXPC_SCALAR:
02005             case D3DXPC_VECTOR:
02006             case D3DXPC_MATRIX_ROWS:
02007                 for (i = 0; i < size; ++i)
02008                 {
02009                     set_number((DWORD *)param->data + i, param->type, &n[i], D3DXPT_INT);
02010                 }
02011                 return D3D_OK;
02012 
02013             case D3DXPC_OBJECT:
02014             case D3DXPC_STRUCT:
02015                 break;
02016 
02017             default:
02018                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02019                 break;
02020         }
02021     }
02022 
02023     //WARN("Invalid argument specified\n");
02024 
02025     return D3DERR_INVALIDCALL;
02026 }
02027 
02028 static HRESULT WINAPI ID3DXBaseEffectImpl_GetIntArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
02029 {
02030     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02031     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02032 
02033     //TRACE("iface %p, parameter %p, n %p, count %u\n", This, parameter, n, count);
02034 
02035     if (n && param && (param->class2 == D3DXPC_SCALAR
02036             || param->class2 == D3DXPC_VECTOR
02037             || param->class2 == D3DXPC_MATRIX_ROWS
02038             || param->class2 == D3DXPC_MATRIX_COLUMNS))
02039     {
02040         UINT i, size = min(count, param->bytes / sizeof(DWORD));
02041 
02042         for (i = 0; i < size; ++i)
02043         {
02044             set_number(&n[i], D3DXPT_INT, (DWORD *)param->data + i, param->type);
02045         }
02046         return D3D_OK;
02047     }
02048 
02049     //WARN("Invalid argument specified\n");
02050 
02051     return D3DERR_INVALIDCALL;
02052 }
02053 
02054 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT f)
02055 {
02056     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02057     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02058 
02059     //TRACE("iface %p, parameter %p, f %f\n", This, parameter, f);
02060 
02061     if (param && !param->element_count && param->rows == 1 && param->columns == 1)
02062     {
02063         set_number((DWORD *)param->data, param->type, &f, D3DXPT_FLOAT);
02064         return D3D_OK;
02065     }
02066 
02067     //WARN("Invalid argument specified\n");
02068 
02069     return D3DERR_INVALIDCALL;
02070 }
02071 
02072 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloat(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f)
02073 {
02074     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02075     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02076 
02077     //TRACE("iface %p, parameter %p, f %p\n", This, parameter, f);
02078 
02079     if (f && param && !param->element_count && param->columns == 1 && param->rows == 1)
02080     {
02081         set_number(f, D3DXPT_FLOAT, (DWORD *)param->data, param->type);
02082         //TRACE("Returning %f\n", *f);
02083         return D3D_OK;
02084     }
02085 
02086     //WARN("Invalid argument specified\n");
02087 
02088     return D3DERR_INVALIDCALL;
02089 }
02090 
02091 static HRESULT WINAPI ID3DXBaseEffectImpl_SetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
02092 {
02093     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02094     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02095 
02096     //TRACE("iface %p, parameter %p, f %p, count %u\n", This, parameter, f, count);
02097 
02098     if (param)
02099     {
02100         UINT i, size = min(count, param->bytes / sizeof(DWORD));
02101 
02102         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02103 
02104         switch (param->class2)
02105         {
02106             case D3DXPC_SCALAR:
02107             case D3DXPC_VECTOR:
02108             case D3DXPC_MATRIX_ROWS:
02109                 for (i = 0; i < size; ++i)
02110                 {
02111                     set_number((DWORD *)param->data + i, param->type, &f[i], D3DXPT_FLOAT);
02112                 }
02113                 return D3D_OK;
02114 
02115             case D3DXPC_OBJECT:
02116             case D3DXPC_STRUCT:
02117                 break;
02118 
02119             default:
02120                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02121                 break;
02122         }
02123     }
02124 
02125     //WARN("Invalid argument specified\n");
02126 
02127     return D3DERR_INVALIDCALL;
02128 }
02129 
02130 static HRESULT WINAPI ID3DXBaseEffectImpl_GetFloatArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
02131 {
02132     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02133     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02134 
02135     //TRACE("iface %p, parameter %p, f %p, count %u\n", This, parameter, f, count);
02136 
02137     if (f && param && (param->class2 == D3DXPC_SCALAR
02138             || param->class2 == D3DXPC_VECTOR
02139             || param->class2 == D3DXPC_MATRIX_ROWS
02140             || param->class2 == D3DXPC_MATRIX_COLUMNS))
02141     {
02142         UINT i, size = min(count, param->bytes / sizeof(DWORD));
02143 
02144         for (i = 0; i < size; ++i)
02145         {
02146             set_number(&f[i], D3DXPT_FLOAT, (DWORD *)param->data + i, param->type);
02147         }
02148         return D3D_OK;
02149     }
02150 
02151     //WARN("Invalid argument specified\n");
02152 
02153     return D3DERR_INVALIDCALL;
02154 }
02155 
02156 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVector(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
02157 {
02158     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02159     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02160 
02161     //TRACE("iface %p, parameter %p, vector %p\n", This, parameter, vector);
02162 
02163     if (param && !param->element_count)
02164     {
02165         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02166 
02167         switch (param->class2)
02168         {
02169             case D3DXPC_SCALAR:
02170             case D3DXPC_VECTOR:
02171                 if (param->type == D3DXPT_INT && param->bytes == 4)
02172                 {
02173                     DWORD tmp;
02174 
02175                     //TRACE("INT fixup\n");
02176                     tmp = (DWORD)(max(min(vector->z, 1.0f), 0.0f) * INT_FLOAT_MULTI);
02177                     tmp += ((DWORD)(max(min(vector->y, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 8;
02178                     tmp += ((DWORD)(max(min(vector->x, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 16;
02179                     tmp += ((DWORD)(max(min(vector->w, 1.0f), 0.0f) * INT_FLOAT_MULTI)) << 24;
02180 
02181                     *(INT *)param->data = tmp;
02182                     return D3D_OK;
02183                 }
02184                 set_vector(param, vector);
02185                 return D3D_OK;
02186 
02187             case D3DXPC_MATRIX_ROWS:
02188             case D3DXPC_OBJECT:
02189             case D3DXPC_STRUCT:
02190                 break;
02191 
02192             default:
02193                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02194                 break;
02195         }
02196     }
02197 
02198     //WARN("Invalid argument specified\n");
02199 
02200     return D3DERR_INVALIDCALL;
02201 }
02202 
02203 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVector(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
02204 {
02205     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02206     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02207 
02208     //TRACE("iface %p, parameter %p, vector %p\n", This, parameter, vector);
02209 
02210     if (vector && param && !param->element_count)
02211     {
02212         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02213 
02214         switch (param->class2)
02215         {
02216             case D3DXPC_SCALAR:
02217             case D3DXPC_VECTOR:
02218                 if (param->type == D3DXPT_INT && param->bytes == 4)
02219                 {
02220                     //TRACE("INT fixup\n");
02221                     vector->x = (((*(INT *)param->data) & 0xff0000) >> 16) * INT_FLOAT_MULTI_INVERSE;
02222                     vector->y = (((*(INT *)param->data) & 0xff00) >> 8) * INT_FLOAT_MULTI_INVERSE;
02223                     vector->z = ((*(INT *)param->data) & 0xff) * INT_FLOAT_MULTI_INVERSE;
02224                     vector->w = (((*(INT *)param->data) & 0xff000000) >> 24) * INT_FLOAT_MULTI_INVERSE;
02225                     return D3D_OK;
02226                 }
02227                 get_vector(param, vector);
02228                 return D3D_OK;
02229 
02230             case D3DXPC_MATRIX_ROWS:
02231             case D3DXPC_OBJECT:
02232             case D3DXPC_STRUCT:
02233                 break;
02234 
02235             default:
02236                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02237                 break;
02238         }
02239     }
02240 
02241     //WARN("Invalid argument specified\n");
02242 
02243     return D3DERR_INVALIDCALL;
02244 }
02245 
02246 static HRESULT WINAPI ID3DXBaseEffectImpl_SetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
02247 {
02248     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02249     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02250 
02251     //TRACE("iface %p, parameter %p, vector %p, count %u stub\n", This, parameter, vector, count);
02252 
02253     if (param && param->element_count && param->element_count >= count)
02254     {
02255         UINT i;
02256 
02257         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02258 
02259         switch (param->class2)
02260         {
02261             case D3DXPC_VECTOR:
02262                 for (i = 0; i < count; ++i)
02263                 {
02264                     set_vector(get_parameter_struct(param->member_handles[i]), &vector[i]);
02265                 }
02266                 return D3D_OK;
02267 
02268             case D3DXPC_SCALAR:
02269             case D3DXPC_MATRIX_ROWS:
02270             case D3DXPC_OBJECT:
02271             case D3DXPC_STRUCT:
02272                 break;
02273 
02274             default:
02275                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02276                 break;
02277         }
02278     }
02279 
02280     //WARN("Invalid argument specified\n");
02281 
02282     return D3DERR_INVALIDCALL;
02283 }
02284 
02285 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVectorArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
02286 {
02287     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02288     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02289 
02290     //TRACE("iface %p, parameter %p, vector %p, count %u\n", This, parameter, vector, count);
02291 
02292     if (!count) return D3D_OK;
02293 
02294     if (vector && param && count <= param->element_count)
02295     {
02296         UINT i;
02297 
02298         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02299 
02300         switch (param->class2)
02301         {
02302             case D3DXPC_VECTOR:
02303                 for (i = 0; i < count; ++i)
02304                 {
02305                     get_vector(get_parameter_struct(param->member_handles[i]), &vector[i]);
02306                 }
02307                 return D3D_OK;
02308 
02309             case D3DXPC_SCALAR:
02310             case D3DXPC_MATRIX_ROWS:
02311             case D3DXPC_OBJECT:
02312             case D3DXPC_STRUCT:
02313                 break;
02314 
02315             default:
02316                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02317                 break;
02318         }
02319     }
02320 
02321     //WARN("Invalid argument specified\n");
02322 
02323     return D3DERR_INVALIDCALL;
02324 }
02325 
02326 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
02327 {
02328     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02329     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02330 
02331     //TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
02332 
02333     if (param && !param->element_count)
02334     {
02335         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02336 
02337         switch (param->class2)
02338         {
02339             case D3DXPC_MATRIX_ROWS:
02340                 set_matrix(param, matrix, FALSE);
02341                 return D3D_OK;
02342 
02343             case D3DXPC_SCALAR:
02344             case D3DXPC_VECTOR:
02345             case D3DXPC_OBJECT:
02346             case D3DXPC_STRUCT:
02347                 break;
02348 
02349             default:
02350                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02351                 break;
02352         }
02353     }
02354 
02355     //WARN("Invalid argument specified\n");
02356 
02357     return D3DERR_INVALIDCALL;
02358 }
02359 
02360 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrix(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
02361 {
02362     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02363     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02364 
02365     //TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
02366 
02367     if (matrix && param && !param->element_count)
02368     {
02369         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02370 
02371         switch (param->class2)
02372         {
02373             case D3DXPC_MATRIX_ROWS:
02374                 get_matrix(param, matrix, FALSE);
02375                 return D3D_OK;
02376 
02377             case D3DXPC_SCALAR:
02378             case D3DXPC_VECTOR:
02379             case D3DXPC_OBJECT:
02380             case D3DXPC_STRUCT:
02381                 break;
02382 
02383             default:
02384                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02385                 break;
02386         }
02387     }
02388 
02389     //WARN("Invalid argument specified\n");
02390 
02391     return D3DERR_INVALIDCALL;
02392 }
02393 
02394 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
02395 {
02396     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02397     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02398 
02399     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02400 
02401     if (param && param->element_count >= count)
02402     {
02403         UINT i;
02404 
02405         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02406 
02407         switch (param->class2)
02408         {
02409             case D3DXPC_MATRIX_ROWS:
02410                 for (i = 0; i < count; ++i)
02411                 {
02412                     set_matrix(get_parameter_struct(param->member_handles[i]), &matrix[i], FALSE);
02413                 }
02414                 return D3D_OK;
02415 
02416             case D3DXPC_SCALAR:
02417             case D3DXPC_VECTOR:
02418             case D3DXPC_OBJECT:
02419             case D3DXPC_STRUCT:
02420                 break;
02421 
02422             default:
02423                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02424                 break;
02425         }
02426     }
02427 
02428     //WARN("Invalid argument specified\n");
02429 
02430     return D3DERR_INVALIDCALL;
02431 }
02432 
02433 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
02434 {
02435     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02436     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02437 
02438     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02439 
02440     if (!count) return D3D_OK;
02441 
02442     if (matrix && param && count <= param->element_count)
02443     {
02444         UINT i;
02445 
02446         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02447 
02448         switch (param->class2)
02449         {
02450             case D3DXPC_MATRIX_ROWS:
02451                 for (i = 0; i < count; ++i)
02452                 {
02453                     get_matrix(get_parameter_struct(param->member_handles[i]), &matrix[i], FALSE);
02454                 }
02455                 return D3D_OK;
02456 
02457             case D3DXPC_SCALAR:
02458             case D3DXPC_VECTOR:
02459             case D3DXPC_OBJECT:
02460             case D3DXPC_STRUCT:
02461                 break;
02462 
02463             default:
02464                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02465                 break;
02466         }
02467     }
02468 
02469     //WARN("Invalid argument specified\n");
02470 
02471     return D3DERR_INVALIDCALL;
02472 }
02473 
02474 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
02475 {
02476     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02477     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02478 
02479     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02480 
02481     if (param && count <= param->element_count)
02482     {
02483         UINT i;
02484 
02485         switch (param->class2)
02486         {
02487             case D3DXPC_MATRIX_ROWS:
02488                 for (i = 0; i < count; ++i)
02489                 {
02490                     set_matrix(get_parameter_struct(param->member_handles[i]), matrix[i], FALSE);
02491                 }
02492                 return D3D_OK;
02493 
02494             case D3DXPC_SCALAR:
02495             case D3DXPC_VECTOR:
02496             case D3DXPC_OBJECT:
02497                 break;
02498 
02499             default:
02500                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02501                 break;
02502         }
02503     }
02504 
02505     //WARN("Invalid argument specified\n");
02506 
02507     return D3DERR_INVALIDCALL;
02508 }
02509 
02510 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixPointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
02511 {
02512     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02513     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02514 
02515     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02516 
02517     if (!count) return D3D_OK;
02518 
02519     if (param && matrix && count <= param->element_count)
02520     {
02521         UINT i;
02522 
02523         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02524 
02525         switch (param->class2)
02526         {
02527             case D3DXPC_MATRIX_ROWS:
02528                 for (i = 0; i < count; ++i)
02529                 {
02530                     get_matrix(get_parameter_struct(param->member_handles[i]), matrix[i], FALSE);
02531                 }
02532                 return D3D_OK;
02533 
02534             case D3DXPC_SCALAR:
02535             case D3DXPC_VECTOR:
02536             case D3DXPC_OBJECT:
02537                 break;
02538 
02539             default:
02540                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02541                 break;
02542         }
02543     }
02544 
02545     //WARN("Invalid argument specified\n");
02546 
02547     return D3DERR_INVALIDCALL;
02548 }
02549 
02550 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
02551 {
02552     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02553     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02554 
02555     //TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
02556 
02557     if (param && !param->element_count)
02558     {
02559         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02560 
02561         switch (param->class2)
02562         {
02563             case D3DXPC_MATRIX_ROWS:
02564                 set_matrix(param, matrix, TRUE);
02565                 return D3D_OK;
02566 
02567             case D3DXPC_SCALAR:
02568             case D3DXPC_VECTOR:
02569             case D3DXPC_OBJECT:
02570             case D3DXPC_STRUCT:
02571                 break;
02572 
02573             default:
02574                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02575                 break;
02576         }
02577     }
02578 
02579     //WARN("Invalid argument specified\n");
02580 
02581     return D3DERR_INVALIDCALL;
02582 }
02583 
02584 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTranspose(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
02585 {
02586     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02587     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02588 
02589     //TRACE("iface %p, parameter %p, matrix %p\n", This, parameter, matrix);
02590 
02591     if (matrix && param && !param->element_count)
02592     {
02593         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02594 
02595         switch (param->class2)
02596         {
02597             case D3DXPC_SCALAR:
02598             case D3DXPC_VECTOR:
02599                 get_matrix(param, matrix, FALSE);
02600                 return D3D_OK;
02601 
02602             case D3DXPC_MATRIX_ROWS:
02603                 get_matrix(param, matrix, TRUE);
02604                 return D3D_OK;
02605 
02606             case D3DXPC_OBJECT:
02607             case D3DXPC_STRUCT:
02608                 break;
02609 
02610             default:
02611                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02612                 break;
02613         }
02614     }
02615 
02616     //WARN("Invalid argument specified\n");
02617 
02618     return D3DERR_INVALIDCALL;
02619 }
02620 
02621 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
02622 {
02623     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02624     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02625 
02626     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02627 
02628     if (param && param->element_count >= count)
02629     {
02630         UINT i;
02631 
02632         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02633 
02634         switch (param->class2)
02635         {
02636             case D3DXPC_MATRIX_ROWS:
02637                 for (i = 0; i < count; ++i)
02638                 {
02639                     set_matrix(get_parameter_struct(param->member_handles[i]), &matrix[i], TRUE);
02640                 }
02641                 return D3D_OK;
02642 
02643             case D3DXPC_SCALAR:
02644             case D3DXPC_VECTOR:
02645             case D3DXPC_OBJECT:
02646             case D3DXPC_STRUCT:
02647                 break;
02648 
02649             default:
02650                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02651                 break;
02652         }
02653     }
02654 
02655     //WARN("Invalid argument specified\n");
02656 
02657     return D3DERR_INVALIDCALL;
02658 }
02659 
02660 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposeArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
02661 {
02662     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02663     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02664 
02665     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02666 
02667     if (!count) return D3D_OK;
02668 
02669     if (matrix && param && count <= param->element_count)
02670     {
02671         UINT i;
02672 
02673         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02674 
02675         switch (param->class2)
02676         {
02677             case D3DXPC_MATRIX_ROWS:
02678                 for (i = 0; i < count; ++i)
02679                 {
02680                     get_matrix(get_parameter_struct(param->member_handles[i]), &matrix[i], TRUE);
02681                 }
02682                 return D3D_OK;
02683 
02684             case D3DXPC_SCALAR:
02685             case D3DXPC_VECTOR:
02686             case D3DXPC_OBJECT:
02687             case D3DXPC_STRUCT:
02688                 break;
02689 
02690             default:
02691                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02692                 break;
02693         }
02694     }
02695 
02696     //WARN("Invalid argument specified\n");
02697 
02698     return D3DERR_INVALIDCALL;
02699 }
02700 
02701 static HRESULT WINAPI ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
02702 {
02703     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02704     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02705 
02706     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02707 
02708     if (param && count <= param->element_count)
02709     {
02710         UINT i;
02711 
02712         switch (param->class2)
02713         {
02714             case D3DXPC_MATRIX_ROWS:
02715                 for (i = 0; i < count; ++i)
02716                 {
02717                     set_matrix(get_parameter_struct(param->member_handles[i]), matrix[i], TRUE);
02718                 }
02719                 return D3D_OK;
02720 
02721             case D3DXPC_SCALAR:
02722             case D3DXPC_VECTOR:
02723             case D3DXPC_OBJECT:
02724                 break;
02725 
02726             default:
02727                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02728                 break;
02729         }
02730     }
02731 
02732     //WARN("Invalid argument specified\n");
02733 
02734     return D3DERR_INVALIDCALL;
02735 }
02736 
02737 static HRESULT WINAPI ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(ID3DXBaseEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
02738 {
02739     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02740     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02741 
02742     //TRACE("iface %p, parameter %p, matrix %p, count %u\n", This, parameter, matrix, count);
02743 
02744     if (!count) return D3D_OK;
02745 
02746     if (matrix && param && count <= param->element_count)
02747     {
02748         UINT i;
02749 
02750         //TRACE("Class %s\n", debug_d3dxparameter_class(param->class2));
02751 
02752         switch (param->class2)
02753         {
02754             case D3DXPC_MATRIX_ROWS:
02755                 for (i = 0; i < count; ++i)
02756                 {
02757                     get_matrix(get_parameter_struct(param->member_handles[i]), matrix[i], TRUE);
02758                 }
02759                 return D3D_OK;
02760 
02761             case D3DXPC_SCALAR:
02762             case D3DXPC_VECTOR:
02763             case D3DXPC_OBJECT:
02764                 break;
02765 
02766             default:
02767                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
02768                 break;
02769         }
02770     }
02771 
02772     //WARN("Invalid argument specified\n");
02773 
02774     return D3DERR_INVALIDCALL;
02775 }
02776 
02777 static HRESULT WINAPI ID3DXBaseEffectImpl_SetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR string)
02778 {
02779     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02780 
02781     //FIXME("iface %p, parameter %p, string %p stub\n", This, parameter, string);
02782 
02783     return E_NOTIMPL;
02784 }
02785 
02786 static HRESULT WINAPI ID3DXBaseEffectImpl_GetString(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
02787 {
02788     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02789     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02790 
02791     //TRACE("iface %p, parameter %p, string %p\n", This, parameter, string);
02792 
02793     if (string && param && !param->element_count && param->type == D3DXPT_STRING)
02794     {
02795         *string = *(LPCSTR *)param->data;
02796         //TRACE("Returning %s\n", debugstr_a(*string));
02797         return D3D_OK;
02798     }
02799 
02800     //WARN("Invalid argument specified\n");
02801 
02802     return D3DERR_INVALIDCALL;
02803 }
02804 
02805 static HRESULT WINAPI ID3DXBaseEffectImpl_SetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
02806 {
02807     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02808     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02809 
02810     //TRACE("iface %p, parameter %p, texture %p\n", This, parameter, texture);
02811 
02812     if (param && !param->element_count &&
02813             (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
02814             || param->type == D3DXPT_TEXTURE2D || param->type ==  D3DXPT_TEXTURE3D
02815             || param->type == D3DXPT_TEXTURECUBE))
02816     {
02817         LPDIRECT3DBASETEXTURE9 oltexture = *(LPDIRECT3DBASETEXTURE9 *)param->data;
02818 
02819         if (texture) IDirect3DBaseTexture9_AddRef(texture);
02820         if (oltexture) IDirect3DBaseTexture9_Release(oltexture);
02821 
02822         *(LPDIRECT3DBASETEXTURE9 *)param->data = texture;
02823 
02824         return D3D_OK;
02825     }
02826 
02827     //WARN("Invalid argument specified\n");
02828 
02829     return D3DERR_INVALIDCALL;
02830 }
02831 
02832 static HRESULT WINAPI ID3DXBaseEffectImpl_GetTexture(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
02833 {
02834     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02835     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02836 
02837     //TRACE("iface %p, parameter %p, texture %p\n", This, parameter, texture);
02838 
02839     if (texture && param && !param->element_count &&
02840             (param->type == D3DXPT_TEXTURE || param->type == D3DXPT_TEXTURE1D
02841             || param->type == D3DXPT_TEXTURE2D || param->type ==  D3DXPT_TEXTURE3D
02842             || param->type == D3DXPT_TEXTURECUBE))
02843     {
02844         *texture = *(LPDIRECT3DBASETEXTURE9 *)param->data;
02845         if (*texture) IDirect3DBaseTexture9_AddRef(*texture);
02846         //TRACE("Returning %p\n", *texture);
02847         return D3D_OK;
02848     }
02849 
02850     //WARN("Invalid argument specified\n");
02851 
02852     return D3DERR_INVALIDCALL;
02853 }
02854 
02855 static HRESULT WINAPI ID3DXBaseEffectImpl_GetPixelShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
02856 {
02857     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02858     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02859 
02860     //TRACE("iface %p, parameter %p, pshader %p\n", This, parameter, pshader);
02861 
02862     if (pshader && param && !param->element_count && param->type == D3DXPT_PIXELSHADER)
02863     {
02864         *pshader = *(LPDIRECT3DPIXELSHADER9 *)param->data;
02865         if (*pshader) IDirect3DPixelShader9_AddRef(*pshader);
02866         //TRACE("Returning %p\n", *pshader);
02867         return D3D_OK;
02868     }
02869 
02870     //WARN("Invalid argument specified\n");
02871 
02872     return D3DERR_INVALIDCALL;
02873 }
02874 
02875 static HRESULT WINAPI ID3DXBaseEffectImpl_GetVertexShader(ID3DXBaseEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
02876 {
02877     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02878     struct d3dx_parameter *param = get_valid_parameter(This, parameter);
02879 
02880     //TRACE("iface %p, parameter %p, vshader %p\n", This, parameter, vshader);
02881 
02882     if (vshader && param && !param->element_count && param->type == D3DXPT_VERTEXSHADER)
02883     {
02884         *vshader = *(LPDIRECT3DVERTEXSHADER9 *)param->data;
02885         if (*vshader) IDirect3DVertexShader9_AddRef(*vshader);
02886         //TRACE("Returning %p\n", *vshader);
02887         return D3D_OK;
02888     }
02889 
02890     //WARN("Invalid argument specified\n");
02891 
02892     return D3DERR_INVALIDCALL;
02893 }
02894 
02895 static HRESULT WINAPI ID3DXBaseEffectImpl_SetArrayRange(ID3DXBaseEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
02896 {
02897     struct ID3DXBaseEffectImpl *This = impl_from_ID3DXBaseEffect(iface);
02898 
02899     //FIXME("iface %p, parameter %p, start %u, end %u stub\n", This, parameter, start, end);
02900 
02901     return E_NOTIMPL;
02902 }
02903 /*
02904 static const struct ID3DXBaseEffectVtbl ID3DXBaseEffect_Vtbl = {
02905     ID3DXBaseEffectImpl_QueryInterface,
02906     ID3DXBaseEffectImpl_AddRef,
02907     ID3DXBaseEffectImpl_Release,
02908     ID3DXBaseEffectImpl_GetDesc,
02909     ID3DXBaseEffectImpl_GetParameterDesc,
02910     ID3DXBaseEffectImpl_GetTechniqueDesc,
02911     ID3DXBaseEffectImpl_GetPassDesc,
02912     ID3DXBaseEffectImpl_GetFunctionDesc,
02913     ID3DXBaseEffectImpl_GetParameter,
02914     ID3DXBaseEffectImpl_GetParameterByName,
02915     ID3DXBaseEffectImpl_GetParameterBySemantic,
02916     ID3DXBaseEffectImpl_GetParameterElement,
02917     ID3DXBaseEffectImpl_GetTechnique,
02918     ID3DXBaseEffectImpl_GetTechniqueByName,
02919     ID3DXBaseEffectImpl_GetPass,
02920     ID3DXBaseEffectImpl_GetPassByName,
02921     ID3DXBaseEffectImpl_GetFunction,
02922     ID3DXBaseEffectImpl_GetFunctionByName,
02923     ID3DXBaseEffectImpl_GetAnnotation,
02924     ID3DXBaseEffectImpl_GetAnnotationByName,
02925     ID3DXBaseEffectImpl_SetValue,
02926     ID3DXBaseEffectImpl_GetValue,
02927     ID3DXBaseEffectImpl_SetBool,
02928     ID3DXBaseEffectImpl_GetBool,
02929     ID3DXBaseEffectImpl_SetBoolArray,
02930     ID3DXBaseEffectImpl_GetBoolArray,
02931     ID3DXBaseEffectImpl_SetInt,
02932     ID3DXBaseEffectImpl_GetInt,
02933     ID3DXBaseEffectImpl_SetIntArray,
02934     ID3DXBaseEffectImpl_GetIntArray,
02935     ID3DXBaseEffectImpl_SetFloat,
02936     ID3DXBaseEffectImpl_GetFloat,
02937     ID3DXBaseEffectImpl_SetFloatArray,
02938     ID3DXBaseEffectImpl_GetFloatArray,
02939     ID3DXBaseEffectImpl_SetVector,
02940     ID3DXBaseEffectImpl_GetVector,
02941     ID3DXBaseEffectImpl_SetVectorArray,
02942     ID3DXBaseEffectImpl_GetVectorArray,
02943     ID3DXBaseEffectImpl_SetMatrix,
02944     ID3DXBaseEffectImpl_GetMatrix,
02945     ID3DXBaseEffectImpl_SetMatrixArray,
02946     ID3DXBaseEffectImpl_GetMatrixArray,
02947     ID3DXBaseEffectImpl_SetMatrixPointerArray,
02948     ID3DXBaseEffectImpl_GetMatrixPointerArray,
02949     ID3DXBaseEffectImpl_SetMatrixTranspose,
02950     ID3DXBaseEffectImpl_GetMatrixTranspose,
02951     ID3DXBaseEffectImpl_SetMatrixTransposeArray,
02952     ID3DXBaseEffectImpl_GetMatrixTransposeArray,
02953     ID3DXBaseEffectImpl_SetMatrixTransposePointerArray,
02954     ID3DXBaseEffectImpl_GetMatrixTransposePointerArray,
02955     ID3DXBaseEffectImpl_SetString,
02956     ID3DXBaseEffectImpl_GetString,
02957     ID3DXBaseEffectImpl_SetTexture,
02958     ID3DXBaseEffectImpl_GetTexture,
02959     ID3DXBaseEffectImpl_GetPixelShader,
02960     ID3DXBaseEffectImpl_GetVertexShader,
02961     ID3DXBaseEffectImpl_SetArrayRange,
02962 };
02963 */
02964 static inline struct ID3DXEffectImpl *impl_from_ID3DXEffect(ID3DXEffect *iface)
02965 {
02966     return CONTAINING_RECORD(iface, struct ID3DXEffectImpl, ID3DXEffect_iface);
02967 }
02968 
02969 /*** IUnknown methods ***/
02970 static HRESULT WINAPI ID3DXEffectImpl_QueryInterface(ID3DXEffect *iface, REFIID riid, void **object)
02971 {
02972     //TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
02973 
02974     if (IsEqualGUID(riid, (const GUID &)IID_IUnknown) ||
02975         IsEqualGUID(riid, (const GUID &)IID_ID3DXEffect))
02976     {
02977         //iface->lpVtbl->AddRef(iface);
02978                 iface->AddRef();
02979         *object = iface;
02980         return S_OK;
02981     }
02982 
02983     //ERR("Interface %s not found\n", debugstr_guid(riid));
02984 
02985     return E_NOINTERFACE;
02986 }
02987 
02988 static ULONG WINAPI ID3DXEffectImpl_AddRef(ID3DXEffect *iface)
02989 {
02990     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
02991 
02992     //TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
02993 
02994     return InterlockedIncrement(&This->ref);
02995 }
02996 
02997 static ULONG WINAPI ID3DXEffectImpl_Release(ID3DXEffect *iface)
02998 {
02999     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03000     ULONG ref = InterlockedDecrement(&This->ref);
03001 
03002     //TRACE("(%p)->(): Release from %u\n", This, ref + 1);
03003 
03004     if (!ref)
03005     {
03006         free_effect(This);
03007         HeapFree(GetProcessHeap(), 0, This);
03008     }
03009 
03010     return ref;
03011 }
03012 
03013 /*** ID3DXBaseEffect methods ***/
03014 static HRESULT WINAPI ID3DXEffectImpl_GetDesc(ID3DXEffect *iface, D3DXEFFECT_DESC *desc)
03015 {
03016     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03017     ID3DXBaseEffect *base = This->base_effect;
03018 
03019     //TRACE("Forward iface %p, base %p\n", This, base);
03020 
03021     return ID3DXBaseEffectImpl_GetDesc(base, desc);
03022 }
03023 
03024 static HRESULT WINAPI ID3DXEffectImpl_GetParameterDesc(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
03025 {
03026     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03027     ID3DXBaseEffect *base = This->base_effect;
03028 
03029     //TRACE("Forward iface %p, base %p\n", This, base);
03030 
03031     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
03032 }
03033 
03034 static HRESULT WINAPI ID3DXEffectImpl_GetTechniqueDesc(ID3DXEffect *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
03035 {
03036     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03037     ID3DXBaseEffect *base = This->base_effect;
03038 
03039     //TRACE("Forward iface %p, base %p\n", This, base);
03040 
03041     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
03042 }
03043 
03044 static HRESULT WINAPI ID3DXEffectImpl_GetPassDesc(ID3DXEffect *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
03045 {
03046     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03047     ID3DXBaseEffect *base = This->base_effect;
03048 
03049     //TRACE("Forward iface %p, base %p\n", This, base);
03050 
03051     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
03052 }
03053 
03054 static HRESULT WINAPI ID3DXEffectImpl_GetFunctionDesc(ID3DXEffect *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
03055 {
03056     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03057     ID3DXBaseEffect *base = This->base_effect;
03058 
03059     //TRACE("Forward iface %p, base %p\n", This, base);
03060 
03061     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
03062 }
03063 
03064 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameter(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
03065 {
03066     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03067     ID3DXBaseEffect *base = This->base_effect;
03068 
03069     //TRACE("Forward iface %p, base %p\n", This, base);
03070 
03071     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
03072 }
03073 
03074 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterByName(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR name)
03075 {
03076     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03077     ID3DXBaseEffect *base = This->base_effect;
03078 
03079     //TRACE("Forward iface %p, base %p\n", This, base);
03080 
03081     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
03082 }
03083 
03084 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterBySemantic(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR semantic)
03085 {
03086     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03087     ID3DXBaseEffect *base = This->base_effect;
03088 
03089     //TRACE("Forward iface %p, base %p\n", This, base);
03090 
03091     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
03092 }
03093 
03094 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetParameterElement(ID3DXEffect *iface, D3DXHANDLE parameter, UINT index)
03095 {
03096     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03097     ID3DXBaseEffect *base = This->base_effect;
03098 
03099     //TRACE("Forward iface %p, base %p\n", This, base);
03100 
03101     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
03102 }
03103 
03104 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechnique(ID3DXEffect *iface, UINT index)
03105 {
03106     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03107     ID3DXBaseEffect *base = This->base_effect;
03108 
03109     //TRACE("Forward iface %p, base %p\n", This, base);
03110 
03111     return ID3DXBaseEffectImpl_GetTechnique(base, index);
03112 }
03113 
03114 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetTechniqueByName(ID3DXEffect *iface, LPCSTR name)
03115 {
03116     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03117     ID3DXBaseEffect *base = This->base_effect;
03118 
03119     //TRACE("Forward iface %p, base %p\n", This, base);
03120 
03121     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
03122 }
03123 
03124 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPass(ID3DXEffect *iface, D3DXHANDLE technique, UINT index)
03125 {
03126     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03127     ID3DXBaseEffect *base = This->base_effect;
03128 
03129     //TRACE("Forward iface %p, base %p\n", This, base);
03130 
03131     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
03132 }
03133 
03134 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetPassByName(ID3DXEffect *iface, D3DXHANDLE technique, LPCSTR name)
03135 {
03136     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03137     ID3DXBaseEffect *base = This->base_effect;
03138 
03139     //TRACE("Forward iface %p, base %p\n", This, base);
03140 
03141     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
03142 }
03143 
03144 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunction(ID3DXEffect *iface, UINT index)
03145 {
03146     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03147     ID3DXBaseEffect *base = This->base_effect;
03148 
03149     //TRACE("Forward iface %p, base %p\n", This, base);
03150 
03151     return ID3DXBaseEffectImpl_GetFunction(base, index);
03152 }
03153 
03154 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetFunctionByName(ID3DXEffect *iface, LPCSTR name)
03155 {
03156     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03157     ID3DXBaseEffect *base = This->base_effect;
03158 
03159     //TRACE("Forward iface %p, base %p\n", This, base);
03160 
03161     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
03162 }
03163 
03164 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotation(ID3DXEffect *iface, D3DXHANDLE object, UINT index)
03165 {
03166     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03167     ID3DXBaseEffect *base = This->base_effect;
03168 
03169     //TRACE("Forward iface %p, base %p\n", This, base);
03170 
03171     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
03172 }
03173 
03174 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetAnnotationByName(ID3DXEffect *iface, D3DXHANDLE object, LPCSTR name)
03175 {
03176     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03177     ID3DXBaseEffect *base = This->base_effect;
03178 
03179     //TRACE("Forward iface %p, base %p\n", This, base);
03180 
03181     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
03182 }
03183 
03184 static HRESULT WINAPI ID3DXEffectImpl_SetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
03185 {
03186     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03187     ID3DXBaseEffect *base = This->base_effect;
03188 
03189     //TRACE("Forward iface %p, base %p\n", This, base);
03190 
03191     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
03192 }
03193 
03194 static HRESULT WINAPI ID3DXEffectImpl_GetValue(ID3DXEffect *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
03195 {
03196     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03197     ID3DXBaseEffect *base = This->base_effect;
03198 
03199     //TRACE("Forward iface %p, base %p\n", This, base);
03200 
03201     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
03202 }
03203 
03204 static HRESULT WINAPI ID3DXEffectImpl_SetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL b)
03205 {
03206     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03207     ID3DXBaseEffect *base = This->base_effect;
03208 
03209     //TRACE("Forward iface %p, base %p\n", This, base);
03210 
03211     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
03212 }
03213 
03214 static HRESULT WINAPI ID3DXEffectImpl_GetBool(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b)
03215 {
03216     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03217     ID3DXBaseEffect *base = This->base_effect;
03218 
03219     //TRACE("Forward iface %p, base %p\n", This, base);
03220 
03221     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
03222 }
03223 
03224 static HRESULT WINAPI ID3DXEffectImpl_SetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
03225 {
03226     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03227     ID3DXBaseEffect *base = This->base_effect;
03228 
03229     //TRACE("Forward iface %p, base %p\n", This, base);
03230 
03231     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
03232 }
03233 
03234 static HRESULT WINAPI ID3DXEffectImpl_GetBoolArray(ID3DXEffect *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
03235 {
03236     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03237     ID3DXBaseEffect *base = This->base_effect;
03238 
03239     //TRACE("Forward iface %p, base %p\n", This, base);
03240 
03241     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
03242 }
03243 
03244 static HRESULT WINAPI ID3DXEffectImpl_SetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT n)
03245 {
03246     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03247     ID3DXBaseEffect *base = This->base_effect;
03248 
03249     //TRACE("Forward iface %p, base %p\n", This, base);
03250 
03251     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
03252 }
03253 
03254 static HRESULT WINAPI ID3DXEffectImpl_GetInt(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n)
03255 {
03256     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03257     ID3DXBaseEffect *base = This->base_effect;
03258 
03259     //TRACE("Forward iface %p, base %p\n", This, base);
03260 
03261     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
03262 }
03263 
03264 static HRESULT WINAPI ID3DXEffectImpl_SetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
03265 {
03266     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03267     ID3DXBaseEffect *base = This->base_effect;
03268 
03269     //TRACE("Forward iface %p, base %p\n", This, base);
03270 
03271     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
03272 }
03273 
03274 static HRESULT WINAPI ID3DXEffectImpl_GetIntArray(ID3DXEffect *iface, D3DXHANDLE parameter, INT *n, UINT count)
03275 {
03276     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03277     ID3DXBaseEffect *base = This->base_effect;
03278 
03279     //TRACE("Forward iface %p, base %p\n", This, base);
03280 
03281     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
03282 }
03283 
03284 static HRESULT WINAPI ID3DXEffectImpl_SetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT f)
03285 {
03286     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03287     ID3DXBaseEffect *base = This->base_effect;
03288 
03289     //TRACE("Forward iface %p, base %p\n", This, base);
03290 
03291     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
03292 }
03293 
03294 static HRESULT WINAPI ID3DXEffectImpl_GetFloat(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f)
03295 {
03296     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03297     ID3DXBaseEffect *base = This->base_effect;
03298 
03299     //TRACE("Forward iface %p, base %p\n", This, base);
03300 
03301     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
03302 }
03303 
03304 static HRESULT WINAPI ID3DXEffectImpl_SetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
03305 {
03306     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03307     ID3DXBaseEffect *base = This->base_effect;
03308 
03309     //TRACE("Forward iface %p, base %p\n", This, base);
03310 
03311     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
03312 }
03313 
03314 static HRESULT WINAPI ID3DXEffectImpl_GetFloatArray(ID3DXEffect *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
03315 {
03316     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03317     ID3DXBaseEffect *base = This->base_effect;
03318 
03319     //TRACE("Forward iface %p, base %p\n", This, base);
03320 
03321     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
03322 }
03323 
03324 static HRESULT WINAPI ID3DXEffectImpl_SetVector(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
03325 {
03326     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03327     ID3DXBaseEffect *base = This->base_effect;
03328 
03329     //TRACE("Forward iface %p, base %p\n", This, base);
03330 
03331     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
03332 }
03333 
03334 static HRESULT WINAPI ID3DXEffectImpl_GetVector(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
03335 {
03336     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03337     ID3DXBaseEffect *base = This->base_effect;
03338 
03339     //TRACE("Forward iface %p, base %p\n", This, base);
03340 
03341     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
03342 }
03343 
03344 static HRESULT WINAPI ID3DXEffectImpl_SetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
03345 {
03346     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03347     ID3DXBaseEffect *base = This->base_effect;
03348 
03349     //TRACE("Forward iface %p, base %p\n", This, base);
03350 
03351     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
03352 }
03353 
03354 static HRESULT WINAPI ID3DXEffectImpl_GetVectorArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
03355 {
03356     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03357     ID3DXBaseEffect *base = This->base_effect;
03358 
03359     //TRACE("Forward iface %p, base %p\n", This, base);
03360 
03361     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
03362 }
03363 
03364 static HRESULT WINAPI ID3DXEffectImpl_SetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
03365 {
03366     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03367     ID3DXBaseEffect *base = This->base_effect;
03368 
03369     //TRACE("Forward iface %p, base %p\n", This, base);
03370 
03371     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
03372 }
03373 
03374 static HRESULT WINAPI ID3DXEffectImpl_GetMatrix(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
03375 {
03376     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03377     ID3DXBaseEffect *base = This->base_effect;
03378 
03379     //TRACE("Forward iface %p, base %p\n", This, base);
03380 
03381     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
03382 }
03383 
03384 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
03385 {
03386     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03387     ID3DXBaseEffect *base = This->base_effect;
03388 
03389     //TRACE("Forward iface %p, base %p\n", This, base);
03390 
03391     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
03392 }
03393 
03394 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
03395 {
03396     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03397     ID3DXBaseEffect *base = This->base_effect;
03398 
03399     //TRACE("Forward iface %p, base %p\n", This, base);
03400 
03401     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
03402 }
03403 
03404 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
03405 {
03406     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03407     ID3DXBaseEffect *base = This->base_effect;
03408 
03409     //TRACE("Forward iface %p, base %p\n", This, base);
03410 
03411     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
03412 }
03413 
03414 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixPointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
03415 {
03416     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03417     ID3DXBaseEffect *base = This->base_effect;
03418 
03419     //TRACE("Forward iface %p, base %p\n", This, base);
03420 
03421     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
03422 }
03423 
03424 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
03425 {
03426     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03427     ID3DXBaseEffect *base = This->base_effect;
03428 
03429     //TRACE("Forward iface %p, base %p\n", This, base);
03430 
03431     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
03432 }
03433 
03434 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTranspose(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
03435 {
03436     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03437     ID3DXBaseEffect *base = This->base_effect;
03438 
03439     //TRACE("Forward iface %p, base %p\n", This, base);
03440 
03441     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
03442 }
03443 
03444 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
03445 {
03446     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03447     ID3DXBaseEffect *base = This->base_effect;
03448 
03449     //TRACE("Forward iface %p, base %p\n", This, base);
03450 
03451     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
03452 }
03453 
03454 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposeArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
03455 {
03456     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03457     ID3DXBaseEffect *base = This->base_effect;
03458 
03459     //TRACE("Forward iface %p, base %p\n", This, base);
03460 
03461     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
03462 }
03463 
03464 static HRESULT WINAPI ID3DXEffectImpl_SetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
03465 {
03466     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03467     ID3DXBaseEffect *base = This->base_effect;
03468 
03469     //TRACE("Forward iface %p, base %p\n", This, base);
03470 
03471     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
03472 }
03473 
03474 static HRESULT WINAPI ID3DXEffectImpl_GetMatrixTransposePointerArray(ID3DXEffect *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
03475 {
03476     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03477     ID3DXBaseEffect *base = This->base_effect;
03478 
03479     //TRACE("Forward iface %p, base %p\n", This, base);
03480 
03481     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
03482 }
03483 
03484 static HRESULT WINAPI ID3DXEffectImpl_SetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR string)
03485 {
03486     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03487     ID3DXBaseEffect *base = This->base_effect;
03488 
03489     //TRACE("Forward iface %p, base %p\n", This, base);
03490 
03491     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
03492 }
03493 
03494 static HRESULT WINAPI ID3DXEffectImpl_GetString(ID3DXEffect *iface, D3DXHANDLE parameter, LPCSTR *string)
03495 {
03496     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03497     ID3DXBaseEffect *base = This->base_effect;
03498 
03499     //TRACE("Forward iface %p, base %p\n", This, base);
03500 
03501     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
03502 }
03503 
03504 static HRESULT WINAPI ID3DXEffectImpl_SetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
03505 {
03506     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03507     ID3DXBaseEffect *base = This->base_effect;
03508 
03509     //TRACE("Forward iface %p, base %p\n", This, base);
03510 
03511     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
03512 }
03513 
03514 static HRESULT WINAPI ID3DXEffectImpl_GetTexture(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
03515 {
03516     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03517     ID3DXBaseEffect *base = This->base_effect;
03518 
03519     //TRACE("Forward iface %p, base %p\n", This, base);
03520 
03521     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
03522 }
03523 
03524 static HRESULT WINAPI ID3DXEffectImpl_GetPixelShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
03525 {
03526     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03527     ID3DXBaseEffect *base = This->base_effect;
03528 
03529     //TRACE("Forward iface %p, base %p\n", This, base);
03530 
03531     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
03532 }
03533 
03534 static HRESULT WINAPI ID3DXEffectImpl_GetVertexShader(ID3DXEffect *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
03535 {
03536     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03537     ID3DXBaseEffect *base = This->base_effect;
03538 
03539     //TRACE("Forward iface %p, base %p\n", This, base);
03540 
03541     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
03542 }
03543 
03544 static HRESULT WINAPI ID3DXEffectImpl_SetArrayRange(ID3DXEffect *iface, D3DXHANDLE parameter, UINT start, UINT end)
03545 {
03546     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03547     ID3DXBaseEffect *base = This->base_effect;
03548 
03549     //TRACE("Forward iface %p, base %p\n", This, base);
03550 
03551     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
03552 }
03553 
03554 /*** ID3DXEffect methods ***/
03555 static HRESULT WINAPI ID3DXEffectImpl_GetPool(ID3DXEffect *iface, LPD3DXEFFECTPOOL *pool)
03556 {
03557     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03558 
03559     //TRACE("iface %p, pool %p\n", This, pool);
03560 
03561     if (!pool)
03562     {
03563         //WARN("Invalid argument supplied.\n");
03564         return D3DERR_INVALIDCALL;
03565     }
03566 
03567     if (This->pool)
03568     {
03569         //This->pool->lpVtbl->AddRef(This->pool);
03570                 This->pool->AddRef();
03571     }
03572 
03573     *pool = This->pool;
03574 
03575     //TRACE("Returning pool %p\n", *pool);
03576 
03577     return S_OK;
03578 }
03579 
03580 static HRESULT WINAPI ID3DXEffectImpl_SetTechnique(ID3DXEffect *iface, D3DXHANDLE technique)
03581 {
03582     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03583     struct ID3DXBaseEffectImpl *base = impl_from_ID3DXBaseEffect(This->base_effect);
03584     struct d3dx_technique *tech = is_valid_technique(base, technique);
03585 
03586     //TRACE("iface %p, technique %p\n", This, technique);
03587 
03588     if (tech)
03589     {
03590         This->active_technique = get_technique_handle(tech);
03591         //TRACE("Technique %p\n", tech);
03592         return D3D_OK;
03593     }
03594 
03595     //WARN("Invalid argument supplied.\n");
03596 
03597     return D3DERR_INVALIDCALL;
03598 }
03599 
03600 static D3DXHANDLE WINAPI ID3DXEffectImpl_GetCurrentTechnique(ID3DXEffect *iface)
03601 {
03602     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03603 
03604     //TRACE("iface %p\n", This);
03605 
03606     return This->active_technique;
03607 }
03608 
03609 static HRESULT WINAPI ID3DXEffectImpl_ValidateTechnique(ID3DXEffect* iface, D3DXHANDLE technique)
03610 {
03611     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03612 
03613     //FIXME("(%p)->(%p): stub\n", This, technique);
03614 
03615     return D3D_OK;
03616 }
03617 
03618 static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique)
03619 {
03620     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03621 
03622     //FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique);
03623 
03624     return E_NOTIMPL;
03625 }
03626 
03627 static BOOL WINAPI ID3DXEffectImpl_IsParameterUsed(ID3DXEffect* iface, D3DXHANDLE parameter, D3DXHANDLE technique)
03628 {
03629     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03630 
03631     //FIXME("(%p)->(%p, %p): stub\n", This, parameter, technique);
03632 
03633     return FALSE;
03634 }
03635 
03636 static HRESULT WINAPI ID3DXEffectImpl_Begin(ID3DXEffect *iface, UINT *passes, DWORD flags)
03637 {
03638     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03639     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
03640 
03641     //FIXME("iface %p, passes %p, flags %#x partial stub\n", This, passes, flags);
03642 
03643     if (passes && technique)
03644     {
03645         if (This->manager || flags & D3DXFX_DONOTSAVESTATE)
03646         {
03647             //TRACE("State capturing disabled.\n");
03648         }
03649         else
03650         {
03651             //FIXME("State capturing not supported, yet!\n");
03652         }
03653 
03654         *passes = technique->pass_count;
03655 
03656         return D3D_OK;
03657     }
03658 
03659     //WARN("Invalid argument supplied.\n");
03660 
03661     return D3DERR_INVALIDCALL;
03662 }
03663 
03664 static HRESULT WINAPI ID3DXEffectImpl_BeginPass(ID3DXEffect *iface, UINT pass)
03665 {
03666     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03667     struct d3dx_technique *technique = get_technique_struct(This->active_technique);
03668 
03669     //TRACE("iface %p, pass %u\n", This, pass);
03670 
03671     if (technique && pass < technique->pass_count && !This->active_pass)
03672     {
03673         This->active_pass = technique->pass_handles[pass];
03674 
03675         //FIXME("No states applied, yet!\n");
03676 
03677         return D3D_OK;
03678     }
03679 
03680     //WARN("Invalid argument supplied.\n");
03681 
03682     return D3DERR_INVALIDCALL;
03683 }
03684 
03685 static HRESULT WINAPI ID3DXEffectImpl_CommitChanges(ID3DXEffect* iface)
03686 {
03687     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03688 
03689     //FIXME("(%p)->(): stub\n", This);
03690 
03691     return E_NOTIMPL;
03692 }
03693 
03694 static HRESULT WINAPI ID3DXEffectImpl_EndPass(ID3DXEffect *iface)
03695 {
03696     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03697 
03698     //TRACE("iface %p\n", This);
03699 
03700     if (This->active_pass)
03701     {
03702          This->active_pass = NULL;
03703          return D3D_OK;
03704     }
03705 
03706     //WARN("Invalid call.\n");
03707 
03708     return D3DERR_INVALIDCALL;
03709 }
03710 
03711 static HRESULT WINAPI ID3DXEffectImpl_End(ID3DXEffect* iface)
03712 {
03713     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03714 
03715     //FIXME("(%p)->(): stub\n", This);
03716 
03717     return E_NOTIMPL;
03718 }
03719 
03720 static HRESULT WINAPI ID3DXEffectImpl_GetDevice(ID3DXEffect *iface, LPDIRECT3DDEVICE9 *device)
03721 {
03722     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03723 
03724     //TRACE("iface %p, device %p\n", This, device);
03725 
03726     if (!device)
03727     {
03728         //WARN("Invalid argument supplied.\n");
03729         return D3DERR_INVALIDCALL;
03730     }
03731 
03732     IDirect3DDevice9_AddRef(This->device);
03733 
03734     *device = This->device;
03735 
03736     //TRACE("Returning device %p\n", *device);
03737 
03738     return S_OK;
03739 }
03740 
03741 static HRESULT WINAPI ID3DXEffectImpl_OnLostDevice(ID3DXEffect* iface)
03742 {
03743     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03744 
03745     //FIXME("(%p)->(): stub\n", This);
03746 
03747     return E_NOTIMPL;
03748 }
03749 
03750 static HRESULT WINAPI ID3DXEffectImpl_OnResetDevice(ID3DXEffect* iface)
03751 {
03752     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03753 
03754     //FIXME("(%p)->(): stub\n", This);
03755 
03756     return E_NOTIMPL;
03757 }
03758 
03759 static HRESULT WINAPI ID3DXEffectImpl_SetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER manager)
03760 {
03761     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03762 
03763     //TRACE("iface %p, manager %p\n", This, manager);
03764 
03765     if (manager) IUnknown_AddRef(manager);
03766     if (This->manager) IUnknown_Release(This->manager);
03767 
03768     This->manager = manager;
03769 
03770     return D3D_OK;
03771 }
03772 
03773 static HRESULT WINAPI ID3DXEffectImpl_GetStateManager(ID3DXEffect *iface, LPD3DXEFFECTSTATEMANAGER *manager)
03774 {
03775     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03776 
03777     //TRACE("iface %p, manager %p\n", This, manager);
03778 
03779     if (!manager)
03780     {
03781         //WARN("Invalid argument supplied.\n");
03782         return D3DERR_INVALIDCALL;
03783     }
03784 
03785     if (This->manager) IUnknown_AddRef(This->manager);
03786     *manager = This->manager;
03787 
03788     return D3D_OK;
03789 }
03790 
03791 static HRESULT WINAPI ID3DXEffectImpl_BeginParameterBlock(ID3DXEffect* iface)
03792 {
03793     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03794 
03795     //FIXME("(%p)->(): stub\n", This);
03796 
03797     return E_NOTIMPL;
03798 }
03799 
03800 static D3DXHANDLE WINAPI ID3DXEffectImpl_EndParameterBlock(ID3DXEffect* iface)
03801 {
03802     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03803 
03804     //FIXME("(%p)->(): stub\n", This);
03805 
03806     return NULL;
03807 }
03808 
03809 static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
03810 {
03811     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03812 
03813     //FIXME("(%p)->(%p): stub\n", This, parameter_block);
03814 
03815     return E_NOTIMPL;
03816 }
03817 
03818 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block)
03819 {
03820     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03821 
03822     //FIXME("(%p)->(%p): stub\n", This, parameter_block);
03823 
03824     return E_NOTIMPL;
03825 }
03826 
03827 static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect* iface, LPDIRECT3DDEVICE9 device, LPD3DXEFFECT* effect)
03828 {
03829     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03830 
03831     //FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
03832 
03833     return E_NOTIMPL;
03834 }
03835 
03836 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect* iface, D3DXHANDLE parameter, LPCVOID data, UINT byte_offset, UINT bytes)
03837 {
03838     struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface);
03839 
03840     //FIXME("(%p)->(%p, %p, %u, %u): stub\n", This, parameter, data, byte_offset, bytes);
03841 
03842     return E_NOTIMPL;
03843 }
03844 /*
03845 static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl =
03846 {
03847     ID3DXEffectImpl_QueryInterface,
03848     ID3DXEffectImpl_AddRef,
03849     ID3DXEffectImpl_Release,
03850     ID3DXEffectImpl_GetDesc,
03851     ID3DXEffectImpl_GetParameterDesc,
03852     ID3DXEffectImpl_GetTechniqueDesc,
03853     ID3DXEffectImpl_GetPassDesc,
03854     ID3DXEffectImpl_GetFunctionDesc,
03855     ID3DXEffectImpl_GetParameter,
03856     ID3DXEffectImpl_GetParameterByName,
03857     ID3DXEffectImpl_GetParameterBySemantic,
03858     ID3DXEffectImpl_GetParameterElement,
03859     ID3DXEffectImpl_GetTechnique,
03860     ID3DXEffectImpl_GetTechniqueByName,
03861     ID3DXEffectImpl_GetPass,
03862     ID3DXEffectImpl_GetPassByName,
03863     ID3DXEffectImpl_GetFunction,
03864     ID3DXEffectImpl_GetFunctionByName,
03865     ID3DXEffectImpl_GetAnnotation,
03866     ID3DXEffectImpl_GetAnnotationByName,
03867     ID3DXEffectImpl_SetValue,
03868     ID3DXEffectImpl_GetValue,
03869     ID3DXEffectImpl_SetBool,
03870     ID3DXEffectImpl_GetBool,
03871     ID3DXEffectImpl_SetBoolArray,
03872     ID3DXEffectImpl_GetBoolArray,
03873     ID3DXEffectImpl_SetInt,
03874     ID3DXEffectImpl_GetInt,
03875     ID3DXEffectImpl_SetIntArray,
03876     ID3DXEffectImpl_GetIntArray,
03877     ID3DXEffectImpl_SetFloat,
03878     ID3DXEffectImpl_GetFloat,
03879     ID3DXEffectImpl_SetFloatArray,
03880     ID3DXEffectImpl_GetFloatArray,
03881     ID3DXEffectImpl_SetVector,
03882     ID3DXEffectImpl_GetVector,
03883     ID3DXEffectImpl_SetVectorArray,
03884     ID3DXEffectImpl_GetVectorArray,
03885     ID3DXEffectImpl_SetMatrix,
03886     ID3DXEffectImpl_GetMatrix,
03887     ID3DXEffectImpl_SetMatrixArray,
03888     ID3DXEffectImpl_GetMatrixArray,
03889     ID3DXEffectImpl_SetMatrixPointerArray,
03890     ID3DXEffectImpl_GetMatrixPointerArray,
03891     ID3DXEffectImpl_SetMatrixTranspose,
03892     ID3DXEffectImpl_GetMatrixTranspose,
03893     ID3DXEffectImpl_SetMatrixTransposeArray,
03894     ID3DXEffectImpl_GetMatrixTransposeArray,
03895     ID3DXEffectImpl_SetMatrixTransposePointerArray,
03896     ID3DXEffectImpl_GetMatrixTransposePointerArray,
03897     ID3DXEffectImpl_SetString,
03898     ID3DXEffectImpl_GetString,
03899     ID3DXEffectImpl_SetTexture,
03900     ID3DXEffectImpl_GetTexture,
03901     ID3DXEffectImpl_GetPixelShader,
03902     ID3DXEffectImpl_GetVertexShader,
03903     ID3DXEffectImpl_SetArrayRange,
03904     ID3DXEffectImpl_GetPool,
03905     ID3DXEffectImpl_SetTechnique,
03906     ID3DXEffectImpl_GetCurrentTechnique,
03907     ID3DXEffectImpl_ValidateTechnique,
03908     ID3DXEffectImpl_FindNextValidTechnique,
03909     ID3DXEffectImpl_IsParameterUsed,
03910     ID3DXEffectImpl_Begin,
03911     ID3DXEffectImpl_BeginPass,
03912     ID3DXEffectImpl_CommitChanges,
03913     ID3DXEffectImpl_EndPass,
03914     ID3DXEffectImpl_End,
03915     ID3DXEffectImpl_GetDevice,
03916     ID3DXEffectImpl_OnLostDevice,
03917     ID3DXEffectImpl_OnResetDevice,
03918     ID3DXEffectImpl_SetStateManager,
03919     ID3DXEffectImpl_GetStateManager,
03920     ID3DXEffectImpl_BeginParameterBlock,
03921     ID3DXEffectImpl_EndParameterBlock,
03922     ID3DXEffectImpl_ApplyParameterBlock,
03923     ID3DXEffectImpl_DeleteParameterBlock,
03924     ID3DXEffectImpl_CloneEffect,
03925     ID3DXEffectImpl_SetRawValue
03926 };
03927 */
03928 static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface)
03929 {
03930     return CONTAINING_RECORD(iface, struct ID3DXEffectCompilerImpl, ID3DXEffectCompiler_iface);
03931 }
03932 
03933 /*** IUnknown methods ***/
03934 static HRESULT WINAPI ID3DXEffectCompilerImpl_QueryInterface(ID3DXEffectCompiler *iface, REFIID riid, void **object)
03935 {
03936     //TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(riid), object);
03937 
03938     if (IsEqualGUID(riid, (const GUID &)IID_IUnknown) ||
03939         IsEqualGUID(riid, (const GUID &)IID_ID3DXEffectCompiler))
03940     {
03941         //iface->lpVtbl->AddRef(iface);
03942                 iface->AddRef();
03943         *object = iface;
03944         return S_OK;
03945     }
03946 
03947     //ERR("Interface %s not found\n", debugstr_guid(riid));
03948 
03949     return E_NOINTERFACE;
03950 }
03951 
03952 static ULONG WINAPI ID3DXEffectCompilerImpl_AddRef(ID3DXEffectCompiler *iface)
03953 {
03954     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
03955 
03956     //TRACE("iface %p: AddRef from %u\n", iface, This->ref);
03957 
03958     return InterlockedIncrement(&This->ref);
03959 }
03960 
03961 static ULONG WINAPI ID3DXEffectCompilerImpl_Release(ID3DXEffectCompiler *iface)
03962 {
03963     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
03964     ULONG ref = InterlockedDecrement(&This->ref);
03965 
03966     //TRACE("iface %p: Release from %u\n", iface, ref + 1);
03967 
03968     if (!ref)
03969     {
03970         free_effect_compiler(This);
03971         HeapFree(GetProcessHeap(), 0, This);
03972     }
03973 
03974     return ref;
03975 }
03976 
03977 /*** ID3DXBaseEffect methods ***/
03978 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetDesc(ID3DXEffectCompiler *iface, D3DXEFFECT_DESC *desc)
03979 {
03980     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
03981     ID3DXBaseEffect *base = This->base_effect;
03982 
03983     //TRACE("Forward iface %p, base %p\n", This, base);
03984 
03985     return ID3DXBaseEffectImpl_GetDesc(base, desc);
03986 }
03987 
03988 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetParameterDesc(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXPARAMETER_DESC *desc)
03989 {
03990     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
03991     ID3DXBaseEffect *base = This->base_effect;
03992 
03993     //TRACE("Forward iface %p, base %p\n", This, base);
03994 
03995     return ID3DXBaseEffectImpl_GetParameterDesc(base, parameter, desc);
03996 }
03997 
03998 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTechniqueDesc(ID3DXEffectCompiler *iface, D3DXHANDLE technique, D3DXTECHNIQUE_DESC *desc)
03999 {
04000     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04001     ID3DXBaseEffect *base = This->base_effect;
04002 
04003     //TRACE("Forward iface %p, base %p\n", This, base);
04004 
04005     return ID3DXBaseEffectImpl_GetTechniqueDesc(base, technique, desc);
04006 }
04007 
04008 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPassDesc(ID3DXEffectCompiler *iface, D3DXHANDLE pass, D3DXPASS_DESC *desc)
04009 {
04010     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04011     ID3DXBaseEffect *base = This->base_effect;
04012 
04013     //TRACE("Forward iface %p, base %p\n", This, base);
04014 
04015     return ID3DXBaseEffectImpl_GetPassDesc(base, pass, desc);
04016 }
04017 
04018 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFunctionDesc(ID3DXEffectCompiler *iface, D3DXHANDLE shader, D3DXFUNCTION_DESC *desc)
04019 {
04020     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04021     ID3DXBaseEffect *base = This->base_effect;
04022 
04023     //TRACE("Forward iface %p, base %p\n", This, base);
04024 
04025     return ID3DXBaseEffectImpl_GetFunctionDesc(base, shader, desc);
04026 }
04027 
04028 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameter(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
04029 {
04030     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04031     ID3DXBaseEffect *base = This->base_effect;
04032 
04033     //TRACE("Forward iface %p, base %p\n", This, base);
04034 
04035     return ID3DXBaseEffectImpl_GetParameter(base, parameter, index);
04036 }
04037 
04038 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterByName(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR name)
04039 {
04040     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04041     ID3DXBaseEffect *base = This->base_effect;
04042 
04043     //TRACE("Forward iface %p, base %p\n", This, base);
04044 
04045     return ID3DXBaseEffectImpl_GetParameterByName(base, parameter, name);
04046 }
04047 
04048 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterBySemantic(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR semantic)
04049 {
04050     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04051     ID3DXBaseEffect *base = This->base_effect;
04052 
04053     //TRACE("Forward iface %p, base %p\n", This, base);
04054 
04055     return ID3DXBaseEffectImpl_GetParameterBySemantic(base, parameter, semantic);
04056 }
04057 
04058 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetParameterElement(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT index)
04059 {
04060     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04061     ID3DXBaseEffect *base = This->base_effect;
04062 
04063     //TRACE("Forward iface %p, base %p\n", This, base);
04064 
04065     return ID3DXBaseEffectImpl_GetParameterElement(base, parameter, index);
04066 }
04067 
04068 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechnique(ID3DXEffectCompiler *iface, UINT index)
04069 {
04070     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04071     ID3DXBaseEffect *base = This->base_effect;
04072 
04073     //TRACE("Forward iface %p, base %p\n", This, base);
04074 
04075     return ID3DXBaseEffectImpl_GetTechnique(base, index);
04076 }
04077 
04078 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetTechniqueByName(ID3DXEffectCompiler *iface, LPCSTR name)
04079 {
04080     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04081     ID3DXBaseEffect *base = This->base_effect;
04082 
04083     //TRACE("Forward iface %p, base %p\n", This, base);
04084 
04085     return ID3DXBaseEffectImpl_GetTechniqueByName(base, name);
04086 }
04087 
04088 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPass(ID3DXEffectCompiler *iface, D3DXHANDLE technique, UINT index)
04089 {
04090     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04091     ID3DXBaseEffect *base = This->base_effect;
04092 
04093     //TRACE("Forward iface %p, base %p\n", This, base);
04094 
04095     return ID3DXBaseEffectImpl_GetPass(base, technique, index);
04096 }
04097 
04098 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetPassByName(ID3DXEffectCompiler *iface, D3DXHANDLE technique, LPCSTR name)
04099 {
04100     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04101     ID3DXBaseEffect *base = This->base_effect;
04102 
04103     //TRACE("Forward iface %p, base %p\n", This, base);
04104 
04105     return ID3DXBaseEffectImpl_GetPassByName(base, technique, name);
04106 }
04107 
04108 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunction(ID3DXEffectCompiler *iface, UINT index)
04109 {
04110     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04111     ID3DXBaseEffect *base = This->base_effect;
04112 
04113     //TRACE("Forward iface %p, base %p\n", This, base);
04114 
04115     return ID3DXBaseEffectImpl_GetFunction(base, index);
04116 }
04117 
04118 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetFunctionByName(ID3DXEffectCompiler *iface, LPCSTR name)
04119 {
04120     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04121     ID3DXBaseEffect *base = This->base_effect;
04122 
04123     //TRACE("Forward iface %p, base %p\n", This, base);
04124 
04125     return ID3DXBaseEffectImpl_GetFunctionByName(base, name);
04126 }
04127 
04128 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotation(ID3DXEffectCompiler *iface, D3DXHANDLE object, UINT index)
04129 {
04130     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04131     ID3DXBaseEffect *base = This->base_effect;
04132 
04133     //TRACE("Forward iface %p, base %p\n", This, base);
04134 
04135     return ID3DXBaseEffectImpl_GetAnnotation(base, object, index);
04136 }
04137 
04138 static D3DXHANDLE WINAPI ID3DXEffectCompilerImpl_GetAnnotationByName(ID3DXEffectCompiler *iface, D3DXHANDLE object, LPCSTR name)
04139 {
04140     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04141     ID3DXBaseEffect *base = This->base_effect;
04142 
04143     //TRACE("Forward iface %p, base %p\n", This, base);
04144 
04145     return ID3DXBaseEffectImpl_GetAnnotationByName(base, object, name);
04146 }
04147 
04148 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCVOID data, UINT bytes)
04149 {
04150     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04151     ID3DXBaseEffect *base = This->base_effect;
04152 
04153     //TRACE("Forward iface %p, base %p\n", This, base);
04154 
04155     return ID3DXBaseEffectImpl_SetValue(base, parameter, data, bytes);
04156 }
04157 
04158 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetValue(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPVOID data, UINT bytes)
04159 {
04160     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04161     ID3DXBaseEffect *base = This->base_effect;
04162 
04163     //TRACE("Forward iface %p, base %p\n", This, base);
04164 
04165     return ID3DXBaseEffectImpl_GetValue(base, parameter, data, bytes);
04166 }
04167 
04168 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL b)
04169 {
04170     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04171     ID3DXBaseEffect *base = This->base_effect;
04172 
04173     //TRACE("Forward iface %p, base %p\n", This, base);
04174 
04175     return ID3DXBaseEffectImpl_SetBool(base, parameter, b);
04176 }
04177 
04178 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBool(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b)
04179 {
04180     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04181     ID3DXBaseEffect *base = This->base_effect;
04182 
04183     //TRACE("Forward iface %p, base %p\n", This, base);
04184 
04185     return ID3DXBaseEffectImpl_GetBool(base, parameter, b);
04186 }
04187 
04188 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST BOOL *b, UINT count)
04189 {
04190     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04191     ID3DXBaseEffect *base = This->base_effect;
04192 
04193     //TRACE("Forward iface %p, base %p\n", This, base);
04194 
04195     return ID3DXBaseEffectImpl_SetBoolArray(base, parameter, b, count);
04196 }
04197 
04198 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetBoolArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *b, UINT count)
04199 {
04200     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04201     ID3DXBaseEffect *base = This->base_effect;
04202 
04203     //TRACE("Forward iface %p, base %p\n", This, base);
04204 
04205     return ID3DXBaseEffectImpl_GetBoolArray(base, parameter, b, count);
04206 }
04207 
04208 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT n)
04209 {
04210     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04211     ID3DXBaseEffect *base = This->base_effect;
04212 
04213     //TRACE("Forward iface %p, base %p\n", This, base);
04214 
04215     return ID3DXBaseEffectImpl_SetInt(base, parameter, n);
04216 }
04217 
04218 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetInt(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n)
04219 {
04220     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04221     ID3DXBaseEffect *base = This->base_effect;
04222 
04223     //TRACE("Forward iface %p, base %p\n", This, base);
04224 
04225     return ID3DXBaseEffectImpl_GetInt(base, parameter, n);
04226 }
04227 
04228 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST INT *n, UINT count)
04229 {
04230     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04231     ID3DXBaseEffect *base = This->base_effect;
04232 
04233     //TRACE("Forward iface %p, base %p\n", This, base);
04234 
04235     return ID3DXBaseEffectImpl_SetIntArray(base, parameter, n, count);
04236 }
04237 
04238 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetIntArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, INT *n, UINT count)
04239 {
04240     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04241     ID3DXBaseEffect *base = This->base_effect;
04242 
04243     //TRACE("Forward iface %p, base %p\n", This, base);
04244 
04245     return ID3DXBaseEffectImpl_GetIntArray(base, parameter, n, count);
04246 }
04247 
04248 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT f)
04249 {
04250     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04251     ID3DXBaseEffect *base = This->base_effect;
04252 
04253     //TRACE("Forward iface %p, base %p\n", This, base);
04254 
04255     return ID3DXBaseEffectImpl_SetFloat(base, parameter, f);
04256 }
04257 
04258 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloat(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f)
04259 {
04260     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04261     ID3DXBaseEffect *base = This->base_effect;
04262 
04263     //TRACE("Forward iface %p, base %p\n", This, base);
04264 
04265     return ID3DXBaseEffectImpl_GetFloat(base, parameter, f);
04266 }
04267 
04268 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST FLOAT *f, UINT count)
04269 {
04270     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04271     ID3DXBaseEffect *base = This->base_effect;
04272 
04273     //TRACE("Forward iface %p, base %p\n", This, base);
04274 
04275     return ID3DXBaseEffectImpl_SetFloatArray(base, parameter, f, count);
04276 }
04277 
04278 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetFloatArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, FLOAT *f, UINT count)
04279 {
04280     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04281     ID3DXBaseEffect *base = This->base_effect;
04282 
04283     //TRACE("Forward iface %p, base %p\n", This, base);
04284 
04285     return ID3DXBaseEffectImpl_GetFloatArray(base, parameter, f, count);
04286 }
04287 
04288 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector)
04289 {
04290     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04291     ID3DXBaseEffect *base = This->base_effect;
04292 
04293     //TRACE("Forward iface %p, base %p\n", This, base);
04294 
04295     return ID3DXBaseEffectImpl_SetVector(base, parameter, vector);
04296 }
04297 
04298 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVector(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector)
04299 {
04300     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04301     ID3DXBaseEffect *base = This->base_effect;
04302 
04303     //TRACE("Forward iface %p, base %p\n", This, base);
04304 
04305     return ID3DXBaseEffectImpl_GetVector(base, parameter, vector);
04306 }
04307 
04308 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXVECTOR4 *vector, UINT count)
04309 {
04310     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04311     ID3DXBaseEffect *base = This->base_effect;
04312 
04313     //TRACE("Forward iface %p, base %p\n", This, base);
04314 
04315     return ID3DXBaseEffectImpl_SetVectorArray(base, parameter, vector, count);
04316 }
04317 
04318 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVectorArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXVECTOR4 *vector, UINT count)
04319 {
04320     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04321     ID3DXBaseEffect *base = This->base_effect;
04322 
04323     //TRACE("Forward iface %p, base %p\n", This, base);
04324 
04325     return ID3DXBaseEffectImpl_GetVectorArray(base, parameter, vector, count);
04326 }
04327 
04328 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
04329 {
04330     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04331     ID3DXBaseEffect *base = This->base_effect;
04332 
04333     //TRACE("Forward iface %p, base %p\n", This, base);
04334 
04335     return ID3DXBaseEffectImpl_SetMatrix(base, parameter, matrix);
04336 }
04337 
04338 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrix(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
04339 {
04340     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04341     ID3DXBaseEffect *base = This->base_effect;
04342 
04343     //TRACE("Forward iface %p, base %p\n", This, base);
04344 
04345     return ID3DXBaseEffectImpl_GetMatrix(base, parameter, matrix);
04346 }
04347 
04348 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
04349 {
04350     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04351     ID3DXBaseEffect *base = This->base_effect;
04352 
04353     //TRACE("Forward iface %p, base %p\n", This, base);
04354 
04355     return ID3DXBaseEffectImpl_SetMatrixArray(base, parameter, matrix, count);
04356 }
04357 
04358 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
04359 {
04360     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04361     ID3DXBaseEffect *base = This->base_effect;
04362 
04363     //TRACE("Forward iface %p, base %p\n", This, base);
04364 
04365     return ID3DXBaseEffectImpl_GetMatrixArray(base, parameter, matrix, count);
04366 }
04367 
04368 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
04369 {
04370     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04371     ID3DXBaseEffect *base = This->base_effect;
04372 
04373     //TRACE("Forward iface %p, base %p\n", This, base);
04374 
04375     return ID3DXBaseEffectImpl_SetMatrixPointerArray(base, parameter, matrix, count);
04376 }
04377 
04378 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixPointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
04379 {
04380     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04381     ID3DXBaseEffect *base = This->base_effect;
04382 
04383     //TRACE("Forward iface %p, base %p\n", This, base);
04384 
04385     return ID3DXBaseEffectImpl_GetMatrixPointerArray(base, parameter, matrix, count);
04386 }
04387 
04388 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix)
04389 {
04390     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04391     ID3DXBaseEffect *base = This->base_effect;
04392 
04393     //TRACE("Forward iface %p, base %p\n", This, base);
04394 
04395     return ID3DXBaseEffectImpl_SetMatrixTranspose(base, parameter, matrix);
04396 }
04397 
04398 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTranspose(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix)
04399 {
04400     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04401     ID3DXBaseEffect *base = This->base_effect;
04402 
04403     //TRACE("Forward iface %p, base %p\n", This, base);
04404 
04405     return ID3DXBaseEffectImpl_GetMatrixTranspose(base, parameter, matrix);
04406 }
04407 
04408 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX *matrix, UINT count)
04409 {
04410     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04411     ID3DXBaseEffect *base = This->base_effect;
04412 
04413     //TRACE("Forward iface %p, base %p\n", This, base);
04414 
04415     return ID3DXBaseEffectImpl_SetMatrixTransposeArray(base, parameter, matrix, count);
04416 }
04417 
04418 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposeArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX *matrix, UINT count)
04419 {
04420     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04421     ID3DXBaseEffect *base = This->base_effect;
04422 
04423     //TRACE("Forward iface %p, base %p\n", This, base);
04424 
04425     return ID3DXBaseEffectImpl_GetMatrixTransposeArray(base, parameter, matrix, count);
04426 }
04427 
04428 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, CONST D3DXMATRIX **matrix, UINT count)
04429 {
04430     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04431     ID3DXBaseEffect *base = This->base_effect;
04432 
04433     //TRACE("Forward iface %p, base %p\n", This, base);
04434 
04435     return ID3DXBaseEffectImpl_SetMatrixTransposePointerArray(base, parameter, matrix, count);
04436 }
04437 
04438 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, D3DXMATRIX **matrix, UINT count)
04439 {
04440     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04441     ID3DXBaseEffect *base = This->base_effect;
04442 
04443     //TRACE("Forward iface %p, base %p\n", This, base);
04444 
04445     return ID3DXBaseEffectImpl_GetMatrixTransposePointerArray(base, parameter, matrix, count);
04446 }
04447 
04448 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR string)
04449 {
04450     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04451     ID3DXBaseEffect *base = This->base_effect;
04452 
04453     //TRACE("Forward iface %p, base %p\n", This, base);
04454 
04455     return ID3DXBaseEffectImpl_SetString(base, parameter, string);
04456 }
04457 
04458 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetString(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPCSTR *string)
04459 {
04460     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04461     ID3DXBaseEffect *base = This->base_effect;
04462 
04463     //TRACE("Forward iface %p, base %p\n", This, base);
04464 
04465     return ID3DXBaseEffectImpl_GetString(base, parameter, string);
04466 }
04467 
04468 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 texture)
04469 {
04470     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04471     ID3DXBaseEffect *base = This->base_effect;
04472 
04473     //TRACE("Forward iface %p, base %p\n", This, base);
04474 
04475     return ID3DXBaseEffectImpl_SetTexture(base, parameter, texture);
04476 }
04477 
04478 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetTexture(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DBASETEXTURE9 *texture)
04479 {
04480     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04481     ID3DXBaseEffect *base = This->base_effect;
04482 
04483     //TRACE("Forward iface %p, base %p\n", This, base);
04484 
04485     return ID3DXBaseEffectImpl_GetTexture(base, parameter, texture);
04486 }
04487 
04488 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetPixelShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DPIXELSHADER9 *pshader)
04489 {
04490     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04491     ID3DXBaseEffect *base = This->base_effect;
04492 
04493     //TRACE("Forward iface %p, base %p\n", This, base);
04494 
04495     return ID3DXBaseEffectImpl_GetPixelShader(base, parameter, pshader);
04496 }
04497 
04498 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetVertexShader(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, LPDIRECT3DVERTEXSHADER9 *vshader)
04499 {
04500     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04501     ID3DXBaseEffect *base = This->base_effect;
04502 
04503     //TRACE("Forward iface %p, base %p\n", This, base);
04504 
04505     return ID3DXBaseEffectImpl_GetVertexShader(base, parameter, vshader);
04506 }
04507 
04508 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetArrayRange(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, UINT start, UINT end)
04509 {
04510     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04511     ID3DXBaseEffect *base = This->base_effect;
04512 
04513     //TRACE("Forward iface %p, base %p\n", This, base);
04514 
04515     return ID3DXBaseEffectImpl_SetArrayRange(base, parameter, start, end);
04516 }
04517 
04518 /*** ID3DXEffectCompiler methods ***/
04519 static HRESULT WINAPI ID3DXEffectCompilerImpl_SetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL literal)
04520 {
04521     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04522 
04523     //FIXME("iface %p, parameter %p, literal %u\n", This, parameter, literal);
04524 
04525     return E_NOTIMPL;
04526 }
04527 
04528 static HRESULT WINAPI ID3DXEffectCompilerImpl_GetLiteral(ID3DXEffectCompiler *iface, D3DXHANDLE parameter, BOOL *literal)
04529 {
04530     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04531 
04532     //FIXME("iface %p, parameter %p, literal %p\n", This, parameter, literal);
04533 
04534     return E_NOTIMPL;
04535 }
04536 
04537 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileEffect(ID3DXEffectCompiler *iface, DWORD flags,
04538         LPD3DXBUFFER *effect, LPD3DXBUFFER *error_msgs)
04539 {
04540     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04541 
04542     //FIXME("iface %p, flags %#x, effect %p, error_msgs %p stub\n", This, flags, effect, error_msgs);
04543 
04544     return E_NOTIMPL;
04545 }
04546 
04547 static HRESULT WINAPI ID3DXEffectCompilerImpl_CompileShader(ID3DXEffectCompiler *iface, D3DXHANDLE function,
04548         LPCSTR target, DWORD flags, LPD3DXBUFFER *shader, LPD3DXBUFFER *error_msgs, LPD3DXCONSTANTTABLE *constant_table)
04549 {
04550     struct ID3DXEffectCompilerImpl *This = impl_from_ID3DXEffectCompiler(iface);
04551 
04552     //FIXME("iface %p, function %p, target %p, flags %#x, shader %p, error_msgs %p, constant_table %p stub\n",
04553     //        This, function, target, flags, shader, error_msgs, constant_table);
04554 
04555     return E_NOTIMPL;
04556 }
04557 /*
04558 static const struct ID3DXEffectCompilerVtbl ID3DXEffectCompiler_Vtbl =
04559 {
04560     ID3DXEffectCompilerImpl_QueryInterface,
04561     ID3DXEffectCompilerImpl_AddRef,
04562     ID3DXEffectCompilerImpl_Release,
04563     ID3DXEffectCompilerImpl_GetDesc,
04564     ID3DXEffectCompilerImpl_GetParameterDesc,
04565     ID3DXEffectCompilerImpl_GetTechniqueDesc,
04566     ID3DXEffectCompilerImpl_GetPassDesc,
04567     ID3DXEffectCompilerImpl_GetFunctionDesc,
04568     ID3DXEffectCompilerImpl_GetParameter,
04569     ID3DXEffectCompilerImpl_GetParameterByName,
04570     ID3DXEffectCompilerImpl_GetParameterBySemantic,
04571     ID3DXEffectCompilerImpl_GetParameterElement,
04572     ID3DXEffectCompilerImpl_GetTechnique,
04573     ID3DXEffectCompilerImpl_GetTechniqueByName,
04574     ID3DXEffectCompilerImpl_GetPass,
04575     ID3DXEffectCompilerImpl_GetPassByName,
04576     ID3DXEffectCompilerImpl_GetFunction,
04577     ID3DXEffectCompilerImpl_GetFunctionByName,
04578     ID3DXEffectCompilerImpl_GetAnnotation,
04579     ID3DXEffectCompilerImpl_GetAnnotationByName,
04580     ID3DXEffectCompilerImpl_SetValue,
04581     ID3DXEffectCompilerImpl_GetValue,
04582     ID3DXEffectCompilerImpl_SetBool,
04583     ID3DXEffectCompilerImpl_GetBool,
04584     ID3DXEffectCompilerImpl_SetBoolArray,
04585     ID3DXEffectCompilerImpl_GetBoolArray,
04586     ID3DXEffectCompilerImpl_SetInt,
04587     ID3DXEffectCompilerImpl_GetInt,
04588     ID3DXEffectCompilerImpl_SetIntArray,
04589     ID3DXEffectCompilerImpl_GetIntArray,
04590     ID3DXEffectCompilerImpl_SetFloat,
04591     ID3DXEffectCompilerImpl_GetFloat,
04592     ID3DXEffectCompilerImpl_SetFloatArray,
04593     ID3DXEffectCompilerImpl_GetFloatArray,
04594     ID3DXEffectCompilerImpl_SetVector,
04595     ID3DXEffectCompilerImpl_GetVector,
04596     ID3DXEffectCompilerImpl_SetVectorArray,
04597     ID3DXEffectCompilerImpl_GetVectorArray,
04598     ID3DXEffectCompilerImpl_SetMatrix,
04599     ID3DXEffectCompilerImpl_GetMatrix,
04600     ID3DXEffectCompilerImpl_SetMatrixArray,
04601     ID3DXEffectCompilerImpl_GetMatrixArray,
04602     ID3DXEffectCompilerImpl_SetMatrixPointerArray,
04603     ID3DXEffectCompilerImpl_GetMatrixPointerArray,
04604     ID3DXEffectCompilerImpl_SetMatrixTranspose,
04605     ID3DXEffectCompilerImpl_GetMatrixTranspose,
04606     ID3DXEffectCompilerImpl_SetMatrixTransposeArray,
04607     ID3DXEffectCompilerImpl_GetMatrixTransposeArray,
04608     ID3DXEffectCompilerImpl_SetMatrixTransposePointerArray,
04609     ID3DXEffectCompilerImpl_GetMatrixTransposePointerArray,
04610     ID3DXEffectCompilerImpl_SetString,
04611     ID3DXEffectCompilerImpl_GetString,
04612     ID3DXEffectCompilerImpl_SetTexture,
04613     ID3DXEffectCompilerImpl_GetTexture,
04614     ID3DXEffectCompilerImpl_GetPixelShader,
04615     ID3DXEffectCompilerImpl_GetVertexShader,
04616     ID3DXEffectCompilerImpl_SetArrayRange,
04617     ID3DXEffectCompilerImpl_SetLiteral,
04618     ID3DXEffectCompilerImpl_GetLiteral,
04619     ID3DXEffectCompilerImpl_CompileEffect,
04620     ID3DXEffectCompilerImpl_CompileShader,
04621 };
04622 */
04623 static HRESULT d3dx9_parse_sampler(struct d3dx_sampler *sampler, const char *data, const char **ptr, D3DXHANDLE *objects)
04624 {
04625     HRESULT hr;
04626     UINT i;
04627     struct d3dx_state *states;
04628 
04629     read_dword(ptr, (DWORD *)&sampler->state_count);
04630     //TRACE("Count: %u\n", sampler->state_count);
04631 
04632     states = (d3dx_state *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * sampler->state_count);
04633     if (!states)
04634     {
04635         //ERR("Out of memory\n");
04636         return E_OUTOFMEMORY;
04637     }
04638 
04639     for (i = 0; i < sampler->state_count; ++i)
04640     {
04641         hr = d3dx9_parse_state(&states[i], data, ptr, objects);
04642         if (hr != D3D_OK)
04643         {
04644             //WARN("Failed to parse state\n");
04645             goto err_out;
04646         }
04647     }
04648 
04649     sampler->states = states;
04650 
04651     return D3D_OK;
04652 
04653 err_out:
04654 
04655     for (i = 0; i < sampler->state_count; ++i)
04656     {
04657         free_state(&states[i]);
04658     }
04659 
04660     HeapFree(GetProcessHeap(), 0, states);
04661 
04662     return hr;
04663 }
04664 
04665 static HRESULT d3dx9_parse_value(struct d3dx_parameter *param, void *value, const char *data, const char **ptr, D3DXHANDLE *objects)
04666 {
04667     unsigned int i;
04668     HRESULT hr;
04669     UINT old_size = 0;
04670     DWORD id;
04671 
04672     if (param->element_count)
04673     {
04674         param->data = value;
04675 
04676         for (i = 0; i < param->element_count; ++i)
04677         {
04678             struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
04679 
04680             hr = d3dx9_parse_value(member, value ? (char *)value + old_size : NULL, data, ptr, objects);
04681             if (hr != D3D_OK)
04682             {
04683                 //WARN("Failed to parse value\n");
04684                 return hr;
04685             }
04686 
04687             old_size += member->bytes;
04688         }
04689 
04690         return D3D_OK;
04691     }
04692 
04693     switch(param->class2)
04694     {
04695         case D3DXPC_SCALAR:
04696         case D3DXPC_VECTOR:
04697         case D3DXPC_MATRIX_ROWS:
04698         case D3DXPC_MATRIX_COLUMNS:
04699             param->data = value;
04700             break;
04701 
04702         case D3DXPC_STRUCT:
04703             param->data = value;
04704 
04705             for (i = 0; i < param->member_count; ++i)
04706             {
04707                 struct d3dx_parameter *member = get_parameter_struct(param->member_handles[i]);
04708 
04709                 hr = d3dx9_parse_value(member, (char *)value + old_size, data, ptr, objects);
04710                 if (hr != D3D_OK)
04711                 {
04712                     //WARN("Failed to parse value\n");
04713                     return hr;
04714                 }
04715 
04716                 old_size += member->bytes;
04717             }
04718             break;
04719 
04720         case D3DXPC_OBJECT:
04721             switch (param->type)
04722             {
04723                 case D3DXPT_STRING:
04724                 case D3DXPT_TEXTURE:
04725                 case D3DXPT_TEXTURE1D:
04726                 case D3DXPT_TEXTURE2D:
04727                 case D3DXPT_TEXTURE3D:
04728                 case D3DXPT_TEXTURECUBE:
04729                 case D3DXPT_PIXELSHADER:
04730                 case D3DXPT_VERTEXSHADER:
04731                     read_dword(ptr, &id);
04732                     //TRACE("Id: %u\n", id);
04733                     objects[id] = get_parameter_handle(param);
04734                     param->data = value;
04735                     break;
04736 
04737                 case D3DXPT_SAMPLER:
04738                 case D3DXPT_SAMPLER1D:
04739                 case D3DXPT_SAMPLER2D:
04740                 case D3DXPT_SAMPLER3D:
04741                 case D3DXPT_SAMPLERCUBE:
04742                 {
04743                     struct d3dx_sampler *sampler;
04744 
04745                     sampler = (d3dx_sampler *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*sampler));
04746                     if (!sampler)
04747                     {
04748                         //ERR("Out of memory\n");
04749                         return E_OUTOFMEMORY;
04750                     }
04751 
04752                     hr = d3dx9_parse_sampler(sampler, data, ptr, objects);
04753                     if (hr != D3D_OK)
04754                     {
04755                         HeapFree(GetProcessHeap(), 0, sampler);
04756                         //WARN("Failed to parse sampler\n");
04757                         return hr;
04758                     }
04759 
04760                     param->data = sampler;
04761                     break;
04762                 }
04763 
04764                 default:
04765                     //FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
04766                     break;
04767             }
04768             break;
04769 
04770         default:
04771             //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
04772             break;
04773     }
04774 
04775     return D3D_OK;
04776 }
04777 
04778 static HRESULT d3dx9_parse_init_value(struct d3dx_parameter *param, const char *data, const char *ptr, D3DXHANDLE *objects)
04779 {
04780     UINT size = param->bytes;
04781     HRESULT hr;
04782     void *value = NULL;
04783 
04784     //TRACE("param size: %u\n", size);
04785 
04786     if (size)
04787     {
04788         value = HeapAlloc(GetProcessHeap(), 0, size);
04789         if (!value)
04790         {
04791             //ERR("Failed to allocate data memory.\n");
04792             return E_OUTOFMEMORY;
04793         }
04794 
04795         //TRACE("Data: %s.\n", debugstr_an(ptr, size));
04796         memcpy(value, ptr, size);
04797     }
04798 
04799     hr = d3dx9_parse_value(param, value, data, &ptr, objects);
04800     if (hr != D3D_OK)
04801     {
04802         //WARN("Failed to parse value\n");
04803         HeapFree(GetProcessHeap(), 0, value);
04804         return hr;
04805     }
04806 
04807     return D3D_OK;
04808 }
04809 
04810 static HRESULT d3dx9_parse_name(char **name, const char *ptr)
04811 {
04812     DWORD size;
04813 
04814     read_dword(&ptr, &size);
04815     //TRACE("Name size: %#x\n", size);
04816 
04817     if (!size)
04818     {
04819         return D3D_OK;
04820     }
04821 
04822     *name = (char *)HeapAlloc(GetProcessHeap(), 0, size);
04823     if (!*name)
04824     {
04825         //ERR("Failed to allocate name memory.\n");
04826         return E_OUTOFMEMORY;
04827     }
04828 
04829     //TRACE("Name: %s.\n", debugstr_an(ptr, size));
04830     memcpy(*name, ptr, size);
04831 
04832     return D3D_OK;
04833 }
04834 
04835 static HRESULT d3dx9_copy_data(char **str, const char **ptr)
04836 {
04837     DWORD size;
04838 
04839     read_dword(ptr, &size);
04840     //TRACE("Data size: %#x\n", size);
04841 
04842     *str = (char *)HeapAlloc(GetProcessHeap(), 0, size);
04843     if (!*str)
04844     {
04845         //ERR("Failed to allocate name memory.\n");
04846         return E_OUTOFMEMORY;
04847     }
04848 
04849     //TRACE("Data: %s.\n", debugstr_an(*ptr, size));
04850     memcpy(*str, *ptr, size);
04851 
04852     *ptr += ((size + 3) & ~3);
04853 
04854     return D3D_OK;
04855 }
04856 
04857 static HRESULT d3dx9_parse_data(struct d3dx_parameter *param, const char **ptr, LPDIRECT3DDEVICE9 device)
04858 {
04859     DWORD size;
04860     HRESULT hr;
04861 
04862     //TRACE("Parse data for parameter %s, type %s\n", debugstr_a(param->name), debug_d3dxparameter_type(param->type));
04863 
04864     read_dword(ptr, &size);
04865     //TRACE("Data size: %#x\n", size);
04866 
04867     if (!size)
04868     {
04869         //TRACE("Size is 0\n");
04870         *(void **)param->data = NULL;
04871         return D3D_OK;
04872     }
04873 
04874     switch (param->type)
04875     {
04876         case D3DXPT_STRING:
04877             /* re-read with size (sizeof(DWORD) = 4) */
04878             hr = d3dx9_parse_name((LPSTR *)param->data, *ptr - 4);
04879             if (hr != D3D_OK)
04880             {
04881                 //WARN("Failed to parse string data\n");
04882                 return hr;
04883             }
04884             break;
04885 
04886         case D3DXPT_VERTEXSHADER:
04887             hr = IDirect3DDevice9_CreateVertexShader(device, (DWORD *)*ptr, (LPDIRECT3DVERTEXSHADER9 *)param->data);
04888             if (hr != D3D_OK)
04889             {
04890                 //WARN("Failed to create vertex shader\n");
04891                 return hr;
04892             }
04893             break;
04894 
04895         case D3DXPT_PIXELSHADER:
04896             hr = IDirect3DDevice9_CreatePixelShader(device, (DWORD *)*ptr, (LPDIRECT3DPIXELSHADER9 *)param->data);
04897             if (hr != D3D_OK)
04898             {
04899                 //WARN("Failed to create pixel shader\n");
04900                 return hr;
04901             }
04902             break;
04903 
04904         default:
04905             //FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
04906             break;
04907     }
04908 
04909 
04910     *ptr += ((size + 3) & ~3);
04911 
04912     return D3D_OK;
04913 }
04914 
04915 static HRESULT d3dx9_parse_effect_typedef(struct d3dx_parameter *param, const char *data, const char **ptr,
04916         struct d3dx_parameter *parent, UINT flags)
04917 {
04918     DWORD offset;
04919     HRESULT hr;
04920     D3DXHANDLE *member_handles = NULL;
04921     UINT i;
04922 
04923     param->flags = flags;
04924 
04925     if (!parent)
04926     {
04927         read_dword(ptr, (DWORD *)&param->type);
04928         //TRACE("Type: %s\n", debug_d3dxparameter_type(param->type));
04929 
04930         read_dword(ptr, (DWORD *)&param->class2);
04931         //TRACE("Class: %s\n", debug_d3dxparameter_class(param->class2));
04932 
04933         read_dword(ptr, &offset);
04934         //TRACE("Type name offset: %#x\n", offset);
04935         hr = d3dx9_parse_name(&param->name, data + offset);
04936         if (hr != D3D_OK)
04937         {
04938             //WARN("Failed to parse name\n");
04939             goto err_out;
04940         }
04941 
04942         read_dword(ptr, &offset);
04943         //TRACE("Type semantic offset: %#x\n", offset);
04944         hr = d3dx9_parse_name(&param->semantic, data + offset);
04945         if (hr != D3D_OK)
04946         {
04947             //WARN("Failed to parse semantic\n");
04948             goto err_out;
04949         }
04950 
04951         read_dword(ptr, (DWORD *)&param->element_count);
04952         //TRACE("Elements: %u\n", param->element_count);
04953 
04954         switch (param->class2)
04955         {
04956             case D3DXPC_VECTOR:
04957                 read_dword(ptr, (DWORD *)&param->columns);
04958                 //TRACE("Columns: %u\n", param->columns);
04959 
04960                 read_dword(ptr, (DWORD *)&param->rows);
04961                 //TRACE("Rows: %u\n", param->rows);
04962 
04963                 /* sizeof(DWORD) * rows * columns */
04964                 param->bytes = 4 * param->rows * param->columns;
04965                 break;
04966 
04967             case D3DXPC_SCALAR:
04968             case D3DXPC_MATRIX_ROWS:
04969             case D3DXPC_MATRIX_COLUMNS:
04970                 read_dword(ptr, (DWORD *)&param->rows);
04971                 //TRACE("Rows: %u\n", param->rows);
04972 
04973                 read_dword(ptr, (DWORD *)&param->columns);
04974                 //TRACE("Columns: %u\n", param->columns);
04975 
04976                 /* sizeof(DWORD) * rows * columns */
04977                 param->bytes = 4 * param->rows * param->columns;
04978                 break;
04979 
04980             case D3DXPC_STRUCT:
04981                 read_dword(ptr, (DWORD *)&param->member_count);
04982                 //TRACE("Members: %u\n", param->member_count);
04983                 break;
04984 
04985             case D3DXPC_OBJECT:
04986                 switch (param->type)
04987                 {
04988                     case D3DXPT_STRING:
04989                         param->bytes = sizeof(LPCSTR);
04990                         break;
04991 
04992                     case D3DXPT_PIXELSHADER:
04993                         param->bytes = sizeof(LPDIRECT3DPIXELSHADER9);
04994                         break;
04995 
04996                     case D3DXPT_VERTEXSHADER:
04997                         param->bytes = sizeof(LPDIRECT3DVERTEXSHADER9);
04998                         break;
04999 
05000                     case D3DXPT_TEXTURE:
05001                     case D3DXPT_TEXTURE1D:
05002                     case D3DXPT_TEXTURE2D:
05003                     case D3DXPT_TEXTURE3D:
05004                     case D3DXPT_TEXTURECUBE:
05005                         param->bytes = sizeof(LPDIRECT3DBASETEXTURE9);
05006                         break;
05007 
05008                     case D3DXPT_SAMPLER:
05009                     case D3DXPT_SAMPLER1D:
05010                     case D3DXPT_SAMPLER2D:
05011                     case D3DXPT_SAMPLER3D:
05012                     case D3DXPT_SAMPLERCUBE:
05013                         param->bytes = 0;
05014                         break;
05015 
05016                     default:
05017                         //FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
05018                         break;
05019                 }
05020                 break;
05021 
05022             default:
05023                 //FIXME("Unhandled class %s\n", debug_d3dxparameter_class(param->class2));
05024                 break;
05025         }
05026     }
05027     else
05028     {
05029         /* elements */
05030         param->type = parent->type;
05031         param->class2 = parent->class2;
05032         param->name = parent->name;
05033         param->semantic = parent->semantic;
05034         param->element_count = 0;
05035         param->annotation_count = 0;
05036         param->member_count = parent->member_count;
05037         param->bytes = parent->bytes;
05038         param->rows = parent->rows;
05039         param->columns = parent->columns;
05040     }
05041 
05042     if (param->element_count)
05043     {
05044         unsigned int param_bytes = 0;
05045         const char *save_ptr = *ptr;
05046 
05047         member_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->element_count);
05048         if (!member_handles)
05049         {
05050             //ERR("Out of memory\n");
05051             hr = E_OUTOFMEMORY;
05052             goto err_out;
05053         }
05054 
05055         for (i = 0; i < param->element_count; ++i)
05056         {
05057             struct d3dx_parameter *member;
05058             *ptr = save_ptr;
05059 
05060             member = (d3dx_parameter *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
05061             if (!member)
05062             {
05063                 //ERR("Out of memory\n");
05064                 hr = E_OUTOFMEMORY;
05065                 goto err_out;
05066             }
05067 
05068             member_handles[i] = get_parameter_handle(member);
05069 
05070             hr = d3dx9_parse_effect_typedef(member, data, ptr, param, flags);
05071             if (hr != D3D_OK)
05072             {
05073                 //WARN("Failed to parse member\n");
05074                 goto err_out;
05075             }
05076 
05077             param_bytes += member->bytes;
05078         }
05079 
05080         param->bytes = param_bytes;
05081     }
05082     else if (param->member_count)
05083     {
05084         member_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member_handles) * param->member_count);
05085         if (!member_handles)
05086         {
05087             //ERR("Out of memory\n");
05088             hr = E_OUTOFMEMORY;
05089             goto err_out;
05090         }
05091 
05092         for (i = 0; i < param->member_count; ++i)
05093         {
05094             struct d3dx_parameter *member;
05095 
05096             member = (d3dx_parameter *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*member));
05097             if (!member)
05098             {
05099                 //ERR("Out of memory\n");
05100                 hr = E_OUTOFMEMORY;
05101                 goto err_out;
05102             }
05103 
05104             member_handles[i] = get_parameter_handle(member);
05105 
05106             hr = d3dx9_parse_effect_typedef(member, data, ptr, NULL, flags);
05107             if (hr != D3D_OK)
05108             {
05109                 //WARN("Failed to parse member\n");
05110                 goto err_out;
05111             }
05112 
05113             param->bytes += member->bytes;
05114         }
05115     }
05116 
05117     param->member_handles = member_handles;
05118 
05119     return D3D_OK;
05120 
05121 err_out:
05122 
05123     if (member_handles)
05124     {
05125         unsigned int count;
05126 
05127         if (param->element_count) count = param->element_count;
05128         else count = param->member_count;
05129 
05130         for (i = 0; i < count; ++i)
05131         {
05132             free_parameter(member_handles[i], param->element_count != 0, TRUE);
05133         }
05134         HeapFree(GetProcessHeap(), 0, member_handles);
05135     }
05136 
05137     if (!parent)
05138     {
05139         HeapFree(GetProcessHeap(), 0, param->name);
05140         HeapFree(GetProcessHeap(), 0, param->semantic);
05141     }
05142     param->name = NULL;
05143     param->semantic = NULL;
05144 
05145     return hr;
05146 }
05147 
05148 static HRESULT d3dx9_parse_effect_annotation(struct d3dx_parameter *anno, const char *data, const char **ptr, D3DXHANDLE *objects)
05149 {
05150     DWORD offset;
05151     const char *ptr2;
05152     HRESULT hr;
05153 
05154     anno->flags = D3DX_PARAMETER_ANNOTATION;
05155 
05156     read_dword(ptr, &offset);
05157     //TRACE("Typedef offset: %#x\n", offset);
05158     ptr2 = data + offset;
05159     hr = d3dx9_parse_effect_typedef(anno, data, &ptr2, NULL, D3DX_PARAMETER_ANNOTATION);
05160     if (hr != D3D_OK)
05161     {
05162         //WARN("Failed to parse type definition\n");
05163         return hr;
05164     }
05165 
05166     read_dword(ptr, &offset);
05167     //TRACE("Value offset: %#x\n", offset);
05168     hr = d3dx9_parse_init_value(anno, data, data + offset, objects);
05169     if (hr != D3D_OK)
05170     {
05171         //WARN("Failed to parse value\n");
05172         return hr;
05173     }
05174 
05175     return D3D_OK;
05176 }
05177 
05178 static HRESULT d3dx9_parse_state(struct d3dx_state *state, const char *data, const char **ptr, D3DXHANDLE *objects)
05179 {
05180     DWORD offset;
05181     const char *ptr2;
05182     HRESULT hr;
05183     struct d3dx_parameter *parameter;
05184 
05185     parameter = (d3dx_parameter *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
05186     if (!parameter)
05187     {
05188         //ERR("Out of memory\n");
05189         return E_OUTOFMEMORY;
05190     }
05191 
05192     state->type = ST_CONSTANT;
05193 
05194     read_dword(ptr, (DWORD *)&state->operation);
05195     //TRACE("Operation: %#x (%s)\n", state->operation, state_table[state->operation].name);
05196 
05197     read_dword(ptr, (DWORD *)&state->index);
05198     //TRACE("Index: %#x\n", state->index);
05199 
05200     read_dword(ptr, &offset);
05201     //TRACE("Typedef offset: %#x\n", offset);
05202     ptr2 = data + offset;
05203     hr = d3dx9_parse_effect_typedef(parameter, data, &ptr2, NULL, 0);
05204     if (hr != D3D_OK)
05205     {
05206         //WARN("Failed to parse type definition\n");
05207         goto err_out;
05208     }
05209 
05210     read_dword(ptr, &offset);
05211     //TRACE("Value offset: %#x\n", offset);
05212     hr = d3dx9_parse_init_value(parameter, data, data + offset, objects);
05213     if (hr != D3D_OK)
05214     {
05215         //WARN("Failed to parse value\n");
05216         goto err_out;
05217     }
05218 
05219     state->parameter = get_parameter_handle(parameter);
05220 
05221     return D3D_OK;
05222 
05223 err_out:
05224 
05225     free_parameter(get_parameter_handle(parameter), FALSE, FALSE);
05226 
05227     return hr;
05228 }
05229 
05230 static HRESULT d3dx9_parse_effect_parameter(struct d3dx_parameter *param, const char *data, const char **ptr, D3DXHANDLE *objects)
05231 {
05232     DWORD offset;
05233     HRESULT hr;
05234     unsigned int i;
05235     D3DXHANDLE *annotation_handles = NULL;
05236     const char *ptr2;
05237 
05238     read_dword(ptr, &offset);
05239     //TRACE("Typedef offset: %#x\n", offset);
05240     ptr2 = data + offset;
05241 
05242     read_dword(ptr, &offset);
05243     //TRACE("Value offset: %#x\n", offset);
05244 
05245     read_dword(ptr, &param->flags);
05246     //TRACE("Flags: %#x\n", param->flags);
05247 
05248     read_dword(ptr, (DWORD *)&param->annotation_count);
05249     //TRACE("Annotation count: %u\n", param->annotation_count);
05250 
05251     hr = d3dx9_parse_effect_typedef(param, data, &ptr2, NULL, param->flags);
05252     if (hr != D3D_OK)
05253     {
05254         //WARN("Failed to parse type definition\n");
05255         return hr;
05256     }
05257 
05258     hr = d3dx9_parse_init_value(param, data, data + offset, objects);
05259     if (hr != D3D_OK)
05260     {
05261         //WARN("Failed to parse value\n");
05262         return hr;
05263     }
05264 
05265     if (param->annotation_count)
05266     {
05267         annotation_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * param->annotation_count);
05268         if (!annotation_handles)
05269         {
05270             //ERR("Out of memory\n");
05271             hr = E_OUTOFMEMORY;
05272             goto err_out;
05273         }
05274 
05275         for (i = 0; i < param->annotation_count; ++i)
05276         {
05277             struct d3dx_parameter *annotation;
05278 
05279             annotation = (d3dx_parameter *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
05280             if (!annotation)
05281             {
05282                 //ERR("Out of memory\n");
05283                 hr = E_OUTOFMEMORY;
05284                 goto err_out;
05285             }
05286 
05287             annotation_handles[i] = get_parameter_handle(annotation);
05288 
05289             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
05290             if (hr != D3D_OK)
05291             {
05292                 //WARN("Failed to parse annotation\n");
05293                 goto err_out;
05294             }
05295         }
05296     }
05297 
05298     param->annotation_handles = annotation_handles;
05299 
05300     return D3D_OK;
05301 
05302 err_out:
05303 
05304     if (annotation_handles)
05305     {
05306         for (i = 0; i < param->annotation_count; ++i)
05307         {
05308             free_parameter(annotation_handles[i], FALSE, FALSE);
05309         }
05310         HeapFree(GetProcessHeap(), 0, annotation_handles);
05311     }
05312 
05313     return hr;
05314 }
05315 
05316 static HRESULT d3dx9_parse_effect_pass(struct d3dx_pass *pass, const char *data, const char **ptr, D3DXHANDLE *objects)
05317 {
05318     DWORD offset;
05319     HRESULT hr;
05320     unsigned int i;
05321     D3DXHANDLE *annotation_handles = NULL;
05322     struct d3dx_state *states = NULL;
05323     char *name = NULL;
05324 
05325     read_dword(ptr, &offset);
05326     //TRACE("Pass name offset: %#x\n", offset);
05327     hr = d3dx9_parse_name(&name, data + offset);
05328     if (hr != D3D_OK)
05329     {
05330         //WARN("Failed to parse name\n");
05331         goto err_out;
05332     }
05333 
05334     read_dword(ptr, (DWORD *)&pass->annotation_count);
05335     //TRACE("Annotation count: %u\n", pass->annotation_count);
05336 
05337     read_dword(ptr, (DWORD *)&pass->state_count);
05338     //TRACE("State count: %u\n", pass->state_count);
05339 
05340     if (pass->annotation_count)
05341     {
05342         annotation_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * pass->annotation_count);
05343         if (!annotation_handles)
05344         {
05345             //ERR("Out of memory\n");
05346             hr = E_OUTOFMEMORY;
05347             goto err_out;
05348         }
05349 
05350         for (i = 0; i < pass->annotation_count; ++i)
05351         {
05352             struct d3dx_parameter *annotation;
05353 
05354             annotation = (d3dx_parameter *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
05355             if (!annotation)
05356             {
05357                 //ERR("Out of memory\n");
05358                 hr = E_OUTOFMEMORY;
05359                 goto err_out;
05360             }
05361 
05362             annotation_handles[i] = get_parameter_handle(annotation);
05363 
05364             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
05365             if (hr != D3D_OK)
05366             {
05367                 //WARN("Failed to parse annotations\n");
05368                 goto err_out;
05369             }
05370         }
05371     }
05372 
05373     if (pass->state_count)
05374     {
05375         states = (d3dx_state *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*states) * pass->state_count);
05376         if (!states)
05377         {
05378             //ERR("Out of memory\n");
05379             hr = E_OUTOFMEMORY;
05380             goto err_out;
05381         }
05382 
05383         for (i = 0; i < pass->state_count; ++i)
05384         {
05385             hr = d3dx9_parse_state(&states[i], data, ptr, objects);
05386             if (hr != D3D_OK)
05387             {
05388                 //WARN("Failed to parse annotations\n");
05389                 goto err_out;
05390             }
05391         }
05392     }
05393 
05394     pass->name = name;
05395     pass->annotation_handles = annotation_handles;
05396     pass->states = states;
05397 
05398     return D3D_OK;
05399 
05400 err_out:
05401 
05402     if (annotation_handles)
05403     {
05404         for (i = 0; i < pass->annotation_count; ++i)
05405         {
05406             free_parameter(annotation_handles[i], FALSE, FALSE);
05407         }
05408         HeapFree(GetProcessHeap(), 0, annotation_handles);
05409     }
05410 
05411     if (states)
05412     {
05413         for (i = 0; i < pass->state_count; ++i)
05414         {
05415             free_state(&states[i]);
05416         }
05417         HeapFree(GetProcessHeap(), 0, states);
05418     }
05419 
05420     HeapFree(GetProcessHeap(), 0, name);
05421 
05422     return hr;
05423 }
05424 
05425 static HRESULT d3dx9_parse_effect_technique(struct d3dx_technique *technique, const char *data, const char **ptr, D3DXHANDLE *objects)
05426 {
05427     DWORD offset;
05428     HRESULT hr;
05429     unsigned int i;
05430     D3DXHANDLE *annotation_handles = NULL;
05431     D3DXHANDLE *pass_handles = NULL;
05432     char *name = NULL;
05433 
05434     read_dword(ptr, &offset);
05435     //TRACE("Technique name offset: %#x\n", offset);
05436     hr = d3dx9_parse_name(&name, data + offset);
05437     if (hr != D3D_OK)
05438     {
05439         //WARN("Failed to parse name\n");
05440         goto err_out;
05441     }
05442 
05443     read_dword(ptr, (DWORD*)&technique->annotation_count);
05444     //TRACE("Annotation count: %u\n", technique->annotation_count);
05445 
05446     read_dword(ptr, (DWORD*)&technique->pass_count);
05447     //TRACE("Pass count: %u\n", technique->pass_count);
05448 
05449     if (technique->annotation_count)
05450     {
05451         annotation_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation_handles) * technique->annotation_count);
05452         if (!annotation_handles)
05453         {
05454             //ERR("Out of memory\n");
05455             hr = E_OUTOFMEMORY;
05456             goto err_out;
05457         }
05458 
05459         for (i = 0; i < technique->annotation_count; ++i)
05460         {
05461             struct d3dx_parameter *annotation;
05462 
05463             annotation = (d3dx_parameter *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*annotation));
05464             if (!annotation)
05465             {
05466                 //ERR("Out of memory\n");
05467                 hr = E_OUTOFMEMORY;
05468                 goto err_out;
05469             }
05470 
05471             annotation_handles[i] = get_parameter_handle(annotation);
05472 
05473             hr = d3dx9_parse_effect_annotation(annotation, data, ptr, objects);
05474             if (hr != D3D_OK)
05475             {
05476                 //WARN("Failed to parse annotations\n");
05477                 goto err_out;
05478             }
05479         }
05480     }
05481 
05482     if (technique->pass_count)
05483     {
05484         pass_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass_handles) * technique->pass_count);
05485         if (!pass_handles)
05486         {
05487             //ERR("Out of memory\n");
05488             hr = E_OUTOFMEMORY;
05489             goto err_out;
05490         }
05491 
05492         for (i = 0; i < technique->pass_count; ++i)
05493         {
05494             struct d3dx_pass *pass;
05495 
05496             pass = (d3dx_pass *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*pass));
05497             if (!pass)
05498             {
05499                 //ERR("Out of memory\n");
05500                 hr = E_OUTOFMEMORY;
05501                 goto err_out;
05502             }
05503 
05504             pass_handles[i] = get_pass_handle(pass);
05505 
05506             hr = d3dx9_parse_effect_pass(pass, data, ptr, objects);
05507             if (hr != D3D_OK)
05508             {
05509                 //WARN("Failed to parse passes\n");
05510                 goto err_out;
05511             }
05512         }
05513     }
05514 
05515     technique->name = name;
05516     technique->pass_handles = pass_handles;
05517     technique->annotation_handles = annotation_handles;
05518 
05519     return D3D_OK;
05520 
05521 err_out:
05522 
05523     if (pass_handles)
05524     {
05525         for (i = 0; i < technique->pass_count; ++i)
05526         {
05527             free_pass(pass_handles[i]);
05528         }
05529         HeapFree(GetProcessHeap(), 0, pass_handles);
05530     }
05531 
05532     if (annotation_handles)
05533     {
05534         for (i = 0; i < technique->annotation_count; ++i)
05535         {
05536             free_parameter(annotation_handles[i], FALSE, FALSE);
05537         }
05538         HeapFree(GetProcessHeap(), 0, annotation_handles);
05539     }
05540 
05541     HeapFree(GetProcessHeap(), 0, name);
05542 
05543     return hr;
05544 }
05545 
05546 static HRESULT d3dx9_parse_resource(struct ID3DXBaseEffectImpl *base, const char *data, const char **ptr)
05547 {
05548     DWORD technique_index;
05549     DWORD index, state_index, usage, element_index;
05550     struct d3dx_state *state;
05551     struct d3dx_parameter *param;
05552     HRESULT hr = E_FAIL;
05553 
05554     read_dword(ptr, &technique_index);
05555     //TRACE("techn: %u\n", technique_index);
05556 
05557     read_dword(ptr, &index);
05558     //TRACE("index: %u\n", index);
05559 
05560     read_dword(ptr, &element_index);
05561     //TRACE("element_index: %u\n", element_index);
05562 
05563     read_dword(ptr, &state_index);
05564     //TRACE("state_index: %u\n", state_index);
05565 
05566     read_dword(ptr, &usage);
05567     //TRACE("usage: %u\n", usage);
05568 
05569     if (technique_index == 0xffffffff)
05570     {
05571         struct d3dx_parameter *parameter;
05572         struct d3dx_sampler *sampler;
05573 
05574         if (index >= base->parameter_count)
05575         {
05576             //FIXME("Index out of bounds: index %u >= parameter_count %u\n", index, base->parameter_count);
05577             return E_FAIL;
05578         }
05579 
05580         parameter = get_parameter_struct(base->parameter_handles[index]);
05581         if (element_index != 0xffffffff)
05582         {
05583             if (element_index >= parameter->element_count && parameter->element_count != 0)
05584             {
05585                 //FIXME("Index out of bounds: element_index %u >= element_count %u\n", element_index, parameter->element_count);
05586                 return E_FAIL;
05587             }
05588 
05589             if (parameter->element_count != 0) parameter = get_parameter_struct(parameter->member_handles[element_index]);
05590         }
05591 
05592         sampler = (d3dx_sampler *)parameter->data;
05593         if (state_index >= sampler->state_count)
05594         {
05595             //FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, sampler->state_count);
05596             return E_FAIL;
05597         }
05598 
05599         state = &sampler->states[state_index];
05600     }
05601     else
05602     {
05603         struct d3dx_technique *technique;
05604         struct d3dx_pass *pass;
05605 
05606         if (technique_index >= base->technique_count)
05607         {
05608             //FIXME("Index out of bounds: technique_index %u >= technique_count %u\n", technique_index, base->technique_count);
05609             return E_FAIL;
05610         }
05611 
05612         technique = get_technique_struct(base->technique_handles[technique_index]);
05613         if (index >= technique->pass_count)
05614         {
05615             //FIXME("Index out of bounds: index %u >= pass_count %u\n", index, technique->pass_count);
05616             return E_FAIL;
05617         }
05618 
05619         pass = get_pass_struct(technique->pass_handles[index]);
05620         if (state_index >= pass->state_count)
05621         {
05622             //FIXME("Index out of bounds: state_index %u >= state_count %u\n", state_index, pass->state_count);
05623             return E_FAIL;
05624         }
05625 
05626         state = &pass->states[state_index];
05627     }
05628 
05629     param = get_parameter_struct(state->parameter);
05630 
05631     switch (usage)
05632     {
05633         case 0:
05634             //TRACE("usage 0: type %s\n", debug_d3dxparameter_type(param->type));
05635             switch (param->type)
05636             {
05637                 case D3DXPT_VERTEXSHADER:
05638                 case D3DXPT_PIXELSHADER:
05639                     state->type = ST_CONSTANT;
05640                     hr = d3dx9_parse_data(param, ptr, base->effect->device);
05641                     break;
05642 
05643                 case D3DXPT_BOOL:
05644                 case D3DXPT_INT:
05645                 case D3DXPT_FLOAT:
05646                 case D3DXPT_STRING:
05647                     state->type = ST_FXLC;
05648                     hr = d3dx9_copy_data((char **)param->data, ptr);
05649                     break;
05650 
05651                 default:
05652                     //FIXME("Unhandled type %s\n", debug_d3dxparameter_type(param->type));
05653                     break;
05654             }
05655             break;
05656 
05657         case 1:
05658             state->type = ST_PARAMETER;
05659             hr = d3dx9_copy_data((char **)param->data, ptr);
05660             if (hr == D3D_OK)
05661             {
05662                 //TRACE("Mapping to parameter %s\n", *(char **)param->data);
05663             }
05664             break;
05665 
05666         default:
05667             //FIXME("Unknown usage %x\n", usage);
05668             break;
05669     }
05670 
05671     return hr;
05672 }
05673 
05674 static HRESULT d3dx9_parse_effect(struct ID3DXBaseEffectImpl *base, const char *data, UINT data_size, DWORD start)
05675 {
05676     const char *ptr = data + start;
05677     D3DXHANDLE *parameter_handles = NULL;
05678     D3DXHANDLE *technique_handles = NULL;
05679     D3DXHANDLE *objects = NULL;
05680     UINT stringcount, objectcount, resourcecount;
05681     HRESULT hr;
05682     UINT i;
05683 
05684     read_dword(&ptr, (DWORD *)&base->parameter_count);
05685     //TRACE("Parameter count: %u\n", base->parameter_count);
05686 
05687     read_dword(&ptr, (DWORD *)&base->technique_count);
05688     //TRACE("Technique count: %u\n", base->technique_count);
05689 
05690     skip_dword_unknown(&ptr, 1);
05691 
05692     read_dword(&ptr, (DWORD *)&objectcount);
05693     //TRACE("Object count: %u\n", objectcount);
05694 
05695     objects = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*objects) * objectcount);
05696     if (!objects)
05697     {
05698         //ERR("Out of memory\n");
05699         hr = E_OUTOFMEMORY;
05700         goto err_out;
05701     }
05702 
05703     if (base->parameter_count)
05704     {
05705         parameter_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter_handles) * base->parameter_count);
05706         if (!parameter_handles)
05707         {
05708             //ERR("Out of memory\n");
05709             hr = E_OUTOFMEMORY;
05710             goto err_out;
05711         }
05712 
05713         for (i = 0; i < base->parameter_count; ++i)
05714         {
05715             struct d3dx_parameter *parameter;
05716 
05717             parameter = (d3dx_parameter *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*parameter));
05718             if (!parameter)
05719             {
05720                 //ERR("Out of memory\n");
05721                 hr = E_OUTOFMEMORY;
05722                 goto err_out;
05723             }
05724 
05725             parameter_handles[i] = get_parameter_handle(parameter);
05726 
05727             hr = d3dx9_parse_effect_parameter(parameter, data, &ptr, objects);
05728             if (hr != D3D_OK)
05729             {
05730                 //WARN("Failed to parse parameter\n");
05731                 goto err_out;
05732             }
05733         }
05734     }
05735 
05736     if (base->technique_count)
05737     {
05738         technique_handles = (D3DXHANDLE *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique_handles) * base->technique_count);
05739         if (!technique_handles)
05740         {
05741             //ERR("Out of memory\n");
05742             hr = E_OUTOFMEMORY;
05743             goto err_out;
05744         }
05745 
05746         for (i = 0; i < base->technique_count; ++i)
05747         {
05748             struct d3dx_technique *technique;
05749 
05750             technique = (d3dx_technique *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*technique));
05751             if (!technique)
05752             {
05753                 //ERR("Out of memory\n");
05754                 hr = E_OUTOFMEMORY;
05755                 goto err_out;
05756             }
05757 
05758             technique_handles[i] = get_technique_handle(technique);
05759 
05760             hr = d3dx9_parse_effect_technique(technique, data, &ptr, objects);
05761             if (hr != D3D_OK)
05762             {
05763                 //WARN("Failed to parse technique\n");
05764                 goto err_out;
05765             }
05766         }
05767     }
05768 
05769     /* needed for further parsing */
05770     base->technique_handles = technique_handles;
05771     base->parameter_handles = parameter_handles;
05772 
05773     read_dword(&ptr, (DWORD *)&stringcount);
05774     //TRACE("String count: %u\n", stringcount);
05775 
05776     read_dword(&ptr, (DWORD *)&resourcecount);
05777     //TRACE("Resource count: %u\n", resourcecount);
05778 
05779     for (i = 0; i < stringcount; ++i)
05780     {
05781         DWORD id;
05782         struct d3dx_parameter *param;
05783 
05784         read_dword(&ptr, &id);
05785         //TRACE("Id: %u\n", id);
05786 
05787         param = get_parameter_struct(objects[id]);
05788 
05789         hr = d3dx9_parse_data(param, &ptr, base->effect->device);
05790         if (hr != D3D_OK)
05791         {
05792             //WARN("Failed to parse data\n");
05793             goto err_out;
05794         }
05795     }
05796 
05797     for (i = 0; i < resourcecount; ++i)
05798     {
05799         //TRACE("parse resource %u\n", i);
05800 
05801         hr = d3dx9_parse_resource(base, data, &ptr);
05802         if (hr != D3D_OK)
05803         {
05804             //WARN("Failed to parse data\n");
05805             goto err_out;
05806         }
05807     }
05808 
05809     HeapFree(GetProcessHeap(), 0, objects);
05810 
05811     return D3D_OK;
05812 
05813 err_out:
05814 
05815     if (technique_handles)
05816     {
05817         for (i = 0; i < base->technique_count; ++i)
05818         {
05819             free_technique(technique_handles[i]);
05820         }
05821         HeapFree(GetProcessHeap(), 0, technique_handles);
05822     }
05823 
05824     if (parameter_handles)
05825     {
05826         for (i = 0; i < base->parameter_count; ++i)
05827         {
05828             free_parameter(parameter_handles[i], FALSE, FALSE);
05829         }
05830         HeapFree(GetProcessHeap(), 0, parameter_handles);
05831     }
05832 
05833     base->technique_handles = NULL;
05834     base->parameter_handles = NULL;
05835 
05836     HeapFree(GetProcessHeap(), 0, objects);
05837 
05838     return hr;
05839 }
05840 
05841 static HRESULT d3dx9_base_effect_init(struct ID3DXBaseEffectImpl *base,
05842         const char *data, SIZE_T data_size, struct ID3DXEffectImpl *effect)
05843 {
05844     DWORD tag, offset;
05845     const char *ptr = data;
05846     HRESULT hr;
05847 
05848     //TRACE("base %p, data %p, data_size %lu, effect %p\n", base, data, data_size, effect);
05849 
05850     //base->ID3DXBaseEffect_iface.lpVtbl = &ID3DXBaseEffect_Vtbl; // dunno
05851     base->ref = 1;
05852     base->effect = effect;
05853 
05854     read_dword(&ptr, &tag);
05855     //TRACE("Tag: %x\n", tag);
05856 
05857     if (tag != d3dx9_effect_version(9, 1))
05858     {
05859         /* todo: compile hlsl ascii code */
05860         //FIXME("HLSL ascii effects not supported, yet\n");
05861 
05862         /* Show the start of the shader for debugging info. */
05863         //TRACE("effect:\n%s\n", debugstr_an(data, data_size > 40 ? 40 : data_size));
05864     }
05865     else
05866     {
05867         read_dword(&ptr, &offset);
05868         //TRACE("Offset: %x\n", offset);
05869 
05870         hr = d3dx9_parse_effect(base, ptr, data_size, offset);
05871         if (hr != D3D_OK)
05872         {
05873             //FIXME("Failed to parse effect.\n");
05874             return hr;
05875         }
05876     }
05877 
05878     return D3D_OK;
05879 }
05880 
05881 static HRESULT d3dx9_effect_init(struct ID3DXEffectImpl *effect, LPDIRECT3DDEVICE9 device,
05882         const char *data, SIZE_T data_size, LPD3DXEFFECTPOOL pool)
05883 {
05884     HRESULT hr;
05885     struct ID3DXBaseEffectImpl *object = NULL;
05886 
05887     //TRACE("effect %p, device %p, data %p, data_size %lu, pool %p\n", effect, device, data, data_size, pool);
05888 
05889     //effect->ID3DXEffect_iface.lpVtbl = &ID3DXEffect_Vtbl; //dunno
05890     effect->ref = 1;
05891 
05892     if (pool) {
05893             //pool->lpVtbl->AddRef(pool);
05894                 pool->AddRef();
05895         }
05896     effect->pool = pool;
05897 
05898     IDirect3DDevice9_AddRef(device);
05899     effect->device = device;
05900 
05901     object = (ID3DXBaseEffectImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
05902     if (!object)
05903     {
05904         //ERR("Out of memory\n");
05905         hr = E_OUTOFMEMORY;
05906         goto err_out;
05907     }
05908 
05909     hr = d3dx9_base_effect_init(object, data, data_size, effect);
05910     if (hr != D3D_OK)
05911     {
05912         //FIXME("Failed to parse effect.\n");
05913         goto err_out;
05914     }
05915 
05916     effect->base_effect = (ID3DXBaseEffect *)&object->ID3DXBaseEffect_iface;
05917 
05918     /* initialize defaults - check because of unsupported ascii effects */
05919     if (object->technique_handles)
05920     {
05921         effect->active_technique = object->technique_handles[0];
05922         effect->active_pass = NULL;
05923     }
05924 
05925     return D3D_OK;
05926 
05927 err_out:
05928 
05929     HeapFree(GetProcessHeap(), 0, object);
05930     free_effect(effect);
05931 
05932     return hr;
05933 }
05934 
05935 HRESULT WINAPI D3DXCreateEffectEx(LPDIRECT3DDEVICE9 device,
05936                                   LPCVOID srcdata,
05937                                   UINT srcdatalen,
05938                                   CONST D3DXMACRO* defines,
05939                                   LPD3DXINCLUDE include,
05940                                   LPCSTR skip_constants,
05941                                   DWORD flags,
05942                                   LPD3DXEFFECTPOOL pool,
05943                                   LPD3DXEFFECT* effect,
05944                                   LPD3DXBUFFER* compilation_errors)
05945 {
05946     struct ID3DXEffectImpl *object;
05947     HRESULT hr;
05948 
05949     //FIXME("(%p, %p, %u, %p, %p, %p, %#x, %p, %p, %p): semi-stub\n", device, srcdata, srcdatalen, defines, include,
05950     //    skip_constants, flags, pool, effect, compilation_errors);
05951 
05952     if (!device || !srcdata)
05953         return D3DERR_INVALIDCALL;
05954 
05955     if (!srcdatalen)
05956         return E_FAIL;
05957 
05958     /* Native dll allows effect to be null so just return D3D_OK after doing basic checks */
05959     if (!effect)
05960         return D3D_OK;
05961 
05962     object = (ID3DXEffectImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
05963     if (!object)
05964     {
05965         //ERR("Out of memory\n");
05966         return E_OUTOFMEMORY;
05967     }
05968 
05969     hr = d3dx9_effect_init(object, device, (const char *)srcdata, srcdatalen, pool);
05970     if (FAILED(hr))
05971     {
05972         //WARN("Failed to initialize shader reflection\n");
05973         HeapFree(GetProcessHeap(), 0, object);
05974         return hr;
05975     }
05976 
05977     *effect = (LPD3DXEFFECT)&object->ID3DXEffect_iface;
05978 
05979     //TRACE("Created ID3DXEffect %p\n", object);
05980 
05981     return D3D_OK;
05982 }
05983 
05984 static HRESULT d3dx9_effect_compiler_init(struct ID3DXEffectCompilerImpl *compiler, const char *data, SIZE_T data_size)
05985 {
05986     HRESULT hr;
05987     struct ID3DXBaseEffectImpl *object = NULL;
05988 
05989     //TRACE("effect %p, data %p, data_size %lu\n", compiler, data, data_size);
05990 
05991     //compiler->ID3DXEffectCompiler_iface.lpVtbl = &ID3DXEffectCompiler_Vtbl; // dunno
05992     compiler->ref = 1;
05993 
05994     object = (ID3DXBaseEffectImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
05995     if (!object)
05996     {
05997         //ERR("Out of memory\n");
05998         hr = E_OUTOFMEMORY;
05999         goto err_out;
06000     }
06001 
06002     hr = d3dx9_base_effect_init(object, data, data_size, NULL);
06003     if (hr != D3D_OK)
06004     {
06005         //FIXME("Failed to parse effect.\n");
06006         goto err_out;
06007     }
06008 
06009     compiler->base_effect = (ID3DXBaseEffect *)&object->ID3DXBaseEffect_iface;
06010 
06011     return D3D_OK;
06012 
06013 err_out:
06014 
06015     HeapFree(GetProcessHeap(), 0, object);
06016     free_effect_compiler(compiler);
06017 
06018     return hr;
06019 }
06020 
06021 HRESULT WINAPI D3DXCreateEffectCompiler(LPCSTR srcdata,
06022                                         UINT srcdatalen,
06023                                         CONST D3DXMACRO *defines,
06024                                         LPD3DXINCLUDE include,
06025                                         DWORD flags,
06026                                         LPD3DXEFFECTCOMPILER *compiler,
06027                                         LPD3DXBUFFER *parse_errors)
06028 {
06029     struct ID3DXEffectCompilerImpl *object;
06030     HRESULT hr;
06031 
06032     //TRACE("srcdata %p, srcdatalen %u, defines %p, include %p, flags %#x, compiler %p, parse_errors %p\n",
06033     //        srcdata, srcdatalen, defines, include, flags, compiler, parse_errors);
06034 
06035     if (!srcdata || !compiler)
06036     {
06037         //WARN("Invalid arguments supplied\n");
06038         return D3DERR_INVALIDCALL;
06039     }
06040 
06041     object = (ID3DXEffectCompilerImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
06042     if (!object)
06043     {
06044         //ERR("Out of memory\n");
06045         return E_OUTOFMEMORY;
06046     }
06047 
06048     hr = d3dx9_effect_compiler_init(object, srcdata, srcdatalen);
06049     if (FAILED(hr))
06050     {
06051         //WARN("Failed to initialize effect compiler\n");
06052         HeapFree(GetProcessHeap(), 0, object);
06053         return hr;
06054     }
06055 
06056     *compiler = (LPD3DXEFFECTCOMPILER)&object->ID3DXEffectCompiler_iface;
06057 
06058     //TRACE("Created ID3DXEffectCompiler %p\n", object);
06059 
06060     return D3D_OK;
06061 }
06062 
06063 struct ID3DXEffectPoolImpl
06064 {
06065     ID3DXEffectPool * ID3DXEffectPool_iface;
06066     LONG ref;
06067 };
06068 
06069 static inline struct ID3DXEffectPoolImpl *impl_from_ID3DXEffectPool(ID3DXEffectPool *iface)
06070 {
06071     return CONTAINING_RECORD(iface, struct ID3DXEffectPoolImpl, ID3DXEffectPool_iface);
06072 }
06073 
06074 /*** IUnknown methods ***/
06075 static HRESULT WINAPI ID3DXEffectPoolImpl_QueryInterface(ID3DXEffectPool *iface, REFIID riid, void **object)
06076 {
06077     //TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), object);
06078 
06079     if (IsEqualGUID(riid, (const GUID &)IID_IUnknown) ||
06080         IsEqualGUID(riid, (const GUID &)IID_ID3DXEffectPool))
06081     {
06082         //iface->lpVtbl->AddRef(iface);
06083                 iface->AddRef();
06084         *object = iface;
06085         return S_OK;
06086     }
06087 
06088     //WARN("Interface %s not found\n", debugstr_guid(riid));
06089 
06090     return E_NOINTERFACE;
06091 }
06092 
06093 static ULONG WINAPI ID3DXEffectPoolImpl_AddRef(ID3DXEffectPool *iface)
06094 {
06095     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
06096 
06097     //TRACE("(%p)->(): AddRef from %u\n", This, This->ref);
06098 
06099     return InterlockedIncrement(&This->ref);
06100 }
06101 
06102 static ULONG WINAPI ID3DXEffectPoolImpl_Release(ID3DXEffectPool *iface)
06103 {
06104     struct ID3DXEffectPoolImpl *This = impl_from_ID3DXEffectPool(iface);
06105     ULONG ref = InterlockedDecrement(&This->ref);
06106 
06107     //TRACE("(%p)->(): Release from %u\n", This, ref + 1);
06108 
06109     if (!ref)
06110         HeapFree(GetProcessHeap(), 0, This);
06111 
06112     return ref;
06113 }
06114 
06115 /*
06116 static const struct ID3DXEffectPoolVtbl ID3DXEffectPool_Vtbl =
06117 {
06118     ID3DXEffectPoolImpl_QueryInterface,
06119     ID3DXEffectPoolImpl_AddRef,
06120     ID3DXEffectPoolImpl_Release
06121 };
06122 */
06123 HRESULT WINAPI D3DXCreateEffectPool(LPD3DXEFFECTPOOL *pool)
06124 {
06125     struct ID3DXEffectPoolImpl *object;
06126 
06127     //TRACE("(%p)\n", pool);
06128 
06129     if (!pool)
06130         return D3DERR_INVALIDCALL;
06131 
06132     object = (ID3DXEffectPoolImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*object));
06133     if (!object)
06134     {
06135         //ERR("Out of memory\n");
06136         return E_OUTOFMEMORY;
06137     }
06138 
06139     // object->ID3DXEffectPool_iface.lpVtbl = &ID3DXEffectPool_Vtbl; // dunno
06140     object->ref = 1;
06141 
06142     *pool = (LPD3DXEFFECTPOOL)&object->ID3DXEffectPool_iface;
06143 
06144     return S_OK;
06145 }
06146 
06147 HRESULT WINAPI D3DXCreateEffectFromFileExW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
06148     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
06149     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06150 {
06151     LPVOID buffer;
06152     HRESULT ret;
06153     DWORD size;
06154 
06155     //TRACE("(%s): relay\n", debugstr_w(srcfile));
06156 
06157     if (!device || !srcfile)
06158         return D3DERR_INVALIDCALL;
06159 
06160     ret = map_view_of_file(srcfile, &buffer, &size);
06161 
06162     if (FAILED(ret))
06163         return D3DXERR_INVALIDDATA;
06164 
06165     ret = D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
06166     UnmapViewOfFile(buffer);
06167 
06168     return ret;
06169 }
06170 
06171 HRESULT WINAPI D3DXCreateEffectFromFileExA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
06172     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
06173     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06174 {
06175     LPWSTR srcfileW;
06176     HRESULT ret;
06177     DWORD len;
06178 
06179     //TRACE("(void): relay\n");
06180 
06181     if (!srcfile)
06182         return D3DERR_INVALIDCALL;
06183 
06184     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
06185     srcfileW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
06186     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
06187 
06188     ret = D3DXCreateEffectFromFileExW(device, srcfileW, defines, include, skipconstants, flags, pool, effect, compilationerrors);
06189     HeapFree(GetProcessHeap(), 0, srcfileW);
06190 
06191     return ret;
06192 }
06193 
06194 HRESULT WINAPI D3DXCreateEffectFromFileW(LPDIRECT3DDEVICE9 device, LPCWSTR srcfile,
06195     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
06196     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06197 {
06198     //TRACE("(void): relay\n");
06199     return D3DXCreateEffectFromFileExW(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
06200 }
06201 
06202 HRESULT WINAPI D3DXCreateEffectFromFileA(LPDIRECT3DDEVICE9 device, LPCSTR srcfile,
06203     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
06204     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06205 {
06206     //TRACE("(void): relay\n");
06207     return D3DXCreateEffectFromFileExA(device, srcfile, defines, include, NULL, flags, pool, effect, compilationerrors);
06208 }
06209 
06210 HRESULT WINAPI D3DXCreateEffectFromResourceExW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
06211     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
06212     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06213 {
06214     HRSRC resinfo;
06215 
06216     //TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
06217 
06218     if (!device)
06219         return D3DERR_INVALIDCALL;
06220 
06221     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
06222 
06223     if (resinfo)
06224     {
06225         LPVOID buffer;
06226         HRESULT ret;
06227         DWORD size;
06228 
06229         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
06230 
06231         if (FAILED(ret))
06232             return D3DXERR_INVALIDDATA;
06233 
06234         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
06235     }
06236 
06237     return D3DXERR_INVALIDDATA;
06238 }
06239 
06240 HRESULT WINAPI D3DXCreateEffectFromResourceExA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
06241     const D3DXMACRO *defines, LPD3DXINCLUDE include, LPCSTR skipconstants, DWORD flags,
06242     LPD3DXEFFECTPOOL pool, LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06243 {
06244     HRSRC resinfo;
06245 
06246     //TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
06247 
06248     if (!device)
06249         return D3DERR_INVALIDCALL;
06250 
06251     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
06252 
06253     if (resinfo)
06254     {
06255         LPVOID buffer;
06256         HRESULT ret;
06257         DWORD size;
06258 
06259         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
06260 
06261         if (FAILED(ret))
06262             return D3DXERR_INVALIDDATA;
06263 
06264         return D3DXCreateEffectEx(device, buffer, size, defines, include, skipconstants, flags, pool, effect, compilationerrors);
06265     }
06266 
06267     return D3DXERR_INVALIDDATA;
06268 }
06269 
06270 HRESULT WINAPI D3DXCreateEffectFromResourceW(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCWSTR srcresource,
06271     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
06272     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06273 {
06274     //TRACE("(void): relay\n");
06275     return D3DXCreateEffectFromResourceExW(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
06276 }
06277 
06278 HRESULT WINAPI D3DXCreateEffectFromResourceA(LPDIRECT3DDEVICE9 device, HMODULE srcmodule, LPCSTR srcresource,
06279     const D3DXMACRO *defines, LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTPOOL pool,
06280     LPD3DXEFFECT *effect, LPD3DXBUFFER *compilationerrors)
06281 {
06282     //TRACE("(void): relay\n");
06283     return D3DXCreateEffectFromResourceExA(device, srcmodule, srcresource, defines, include, NULL, flags, pool, effect, compilationerrors);
06284 }
06285 
06286 HRESULT WINAPI D3DXCreateEffectCompilerFromFileW(LPCWSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
06287     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
06288 {
06289     LPVOID buffer;
06290     HRESULT ret;
06291     DWORD size;
06292 
06293     //TRACE("(%s): relay\n", debugstr_w(srcfile));
06294 
06295     if (!srcfile)
06296         return D3DERR_INVALIDCALL;
06297 
06298     ret = map_view_of_file(srcfile, &buffer, &size);
06299 
06300     if (FAILED(ret))
06301         return D3DXERR_INVALIDDATA;
06302 
06303     ret = D3DXCreateEffectCompiler((LPCSTR)buffer, size, defines, include, flags, effectcompiler, parseerrors);
06304     UnmapViewOfFile(buffer);
06305 
06306     return ret;
06307 }
06308 
06309 HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
06310     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
06311 {
06312     LPWSTR srcfileW;
06313     HRESULT ret;
06314     DWORD len;
06315 
06316     //TRACE("(void): relay\n");
06317 
06318     if (!srcfile)
06319         return D3DERR_INVALIDCALL;
06320 
06321     len = MultiByteToWideChar(CP_ACP, 0, srcfile, -1, NULL, 0);
06322     srcfileW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(*srcfileW));
06323     MultiByteToWideChar(CP_ACP, 0, srcfile, -1, srcfileW, len);
06324 
06325     ret = D3DXCreateEffectCompilerFromFileW(srcfileW, defines, include, flags, effectcompiler, parseerrors);
06326     HeapFree(GetProcessHeap(), 0, srcfileW);
06327 
06328     return ret;
06329 }
06330 
06331 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceA(HMODULE srcmodule, LPCSTR srcresource, const D3DXMACRO *defines,
06332     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
06333 {
06334     HRSRC resinfo;
06335 
06336     //TRACE("(%p, %s): relay\n", srcmodule, debugstr_a(srcresource));
06337 
06338     resinfo = FindResourceA(srcmodule, srcresource, (LPCSTR) RT_RCDATA);
06339 
06340     if (resinfo)
06341     {
06342         LPVOID buffer;
06343         HRESULT ret;
06344         DWORD size;
06345 
06346         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
06347 
06348         if (FAILED(ret))
06349             return D3DXERR_INVALIDDATA;
06350 
06351         return D3DXCreateEffectCompiler((LPCSTR)buffer, size, defines, include, flags, effectcompiler, parseerrors);
06352     }
06353 
06354     return D3DXERR_INVALIDDATA;
06355 }
06356 
06357 HRESULT WINAPI D3DXCreateEffectCompilerFromResourceW(HMODULE srcmodule, LPCWSTR srcresource, const D3DXMACRO *defines,
06358     LPD3DXINCLUDE include, DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors)
06359 {
06360     HRSRC resinfo;
06361 
06362     //TRACE("(%p, %s): relay\n", srcmodule, debugstr_w(srcresource));
06363 
06364     resinfo = FindResourceW(srcmodule, srcresource, (LPCWSTR) RT_RCDATA);
06365 
06366     if (resinfo)
06367     {
06368         LPVOID buffer;
06369         HRESULT ret;
06370         DWORD size;
06371 
06372         ret = load_resource_into_memory(srcmodule, resinfo, &buffer, &size);
06373 
06374         if (FAILED(ret))
06375             return D3DXERR_INVALIDDATA;
06376 
06377         return D3DXCreateEffectCompiler((LPCSTR)buffer, size, defines, include, flags, effectcompiler, parseerrors);
06378     }
06379 
06380     return D3DXERR_INVALIDDATA;
06381 }
06382 
06383 
06384 
06385 
06386 
06387 
06388 
06389 
06390 
06391 
06392 
06393 
06394 
06395 /* Returns TRUE if num is a power of 2, FALSE if not, or if 0 */
06396 
06397 static BOOL is_pow2(UINT num)
06398 {
06399     return !(num & (num - 1));
06400 }
06401 
06402 /* Returns the smallest power of 2 which is greater than or equal to num */
06403 static UINT make_pow2(UINT num)
06404 {
06405     UINT result = 1;
06406 
06407     /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */
06408     if (num >= 0x80000000)
06409         return 0x80000000;
06410 
06411     while (result < num)
06412         result <<= 1;
06413 
06414     return result;
06415 }
06416 
06417 // texture.c
06418 /*
06419 static HRESULT get_surface(D3DRESOURCETYPE type, LPDIRECT3DBASETEXTURE9 tex,
06420                            int face, UINT level, LPDIRECT3DSURFACE9 *surf)
06421 {
06422     switch (type)
06423     {
06424         case D3DRTYPE_TEXTURE:
06425             return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf);
06426         case D3DRTYPE_CUBETEXTURE:
06427             //return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf);
06428             return IDirect3DCubeTexture9_GetCubeMapSurface(((IDirect3DCubeTexture9*) tex, face, level, surf);
06429         default:
06430             //ERR("Unexpected texture type\n");
06431             return E_NOTIMPL;
06432     }
06433 }
06434 */
06435 static void la_from_rgba(const struct vec4 *rgba, struct vec4 *la)
06436 {
06437     la->x = rgba->x * 0.2125f + rgba->y * 0.7154f + rgba->z * 0.0721f;
06438     la->w = rgba->w;
06439 }
06440 
06441 static void la_to_rgba(const struct vec4 *la, struct vec4 *rgba)
06442 {
06443     rgba->x = la->x;
06444     rgba->y = la->x;
06445     rgba->z = la->x;
06446     rgba->w = la->w;
06447 }
06448 
06449 /************************************************************
06450  * pixel format table providing info about number of bytes per pixel,
06451  * number of bits per channel and format type.
06452  *
06453  * Call get_format_info to request information about a specific format.
06454  */
06455 static const struct pixel_format_desc formats[] =
06456 {
06457     /* format            bpc              shifts            bpp blocks   type            from_rgba     to_rgba */
06458     {D3DFMT_R8G8B8,      {0,  8,  8,  8}, { 0, 16,  8,  0}, 3, 1, 1,  3, FORMAT_ARGB,    NULL,         NULL      },
06459     {D3DFMT_A8R8G8B8,    {8,  8,  8,  8}, {24, 16,  8,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
06460     {D3DFMT_X8R8G8B8,    {0,  8,  8,  8}, { 0, 16,  8,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
06461     {D3DFMT_A8B8G8R8,    {8,  8,  8,  8}, {24,  0,  8, 16}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
06462     {D3DFMT_X8B8G8R8,    {0,  8,  8,  8}, { 0,  0,  8, 16}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
06463     {D3DFMT_R5G6B5,      {0,  5,  6,  5}, { 0, 11,  5,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
06464     {D3DFMT_X1R5G5B5,    {0,  5,  5,  5}, { 0, 10,  5,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
06465     {D3DFMT_A1R5G5B5,    {1,  5,  5,  5}, {15, 10,  5,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
06466     {D3DFMT_R3G3B2,      {0,  3,  3,  2}, { 0,  5,  2,  0}, 1, 1, 1,  1, FORMAT_ARGB,    NULL,         NULL      },
06467     {D3DFMT_A8R3G3B2,    {8,  3,  3,  2}, { 8,  5,  2,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
06468     {D3DFMT_A4R4G4B4,    {4,  4,  4,  4}, {12,  8,  4,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
06469     {D3DFMT_X4R4G4B4,    {0,  4,  4,  4}, { 0,  8,  4,  0}, 2, 1, 1,  2, FORMAT_ARGB,    NULL,         NULL      },
06470     {D3DFMT_A2R10G10B10, {2, 10, 10, 10}, {30, 20, 10,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
06471     {D3DFMT_A2B10G10R10, {2, 10, 10, 10}, {30,  0, 10, 20}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
06472     {D3DFMT_G16R16,      {0, 16, 16,  0}, { 0,  0, 16,  0}, 4, 1, 1,  4, FORMAT_ARGB,    NULL,         NULL      },
06473     {D3DFMT_A8,          {8,  0,  0,  0}, { 0,  0,  0,  0}, 1, 1, 1,  1, FORMAT_ARGB,    NULL,         NULL      },
06474     {D3DFMT_A8L8,        {8,  8,  0,  0}, { 8,  0,  0,  0}, 2, 1, 1,  2, FORMAT_ARGB,    la_from_rgba, la_to_rgba},
06475     {D3DFMT_A4L4,        {4,  4,  0,  0}, { 4,  0,  0,  0}, 1, 1, 1,  1, FORMAT_ARGB,    la_from_rgba, la_to_rgba},
06476     {D3DFMT_L8,          {0,  8,  0,  0}, { 0,  0,  0,  0}, 1, 1, 1,  1, FORMAT_ARGB,    la_from_rgba, la_to_rgba},
06477     {D3DFMT_L16,         {0, 16,  0,  0}, { 0,  0,  0,  0}, 2, 1, 1,  2, FORMAT_ARGB,    la_from_rgba, la_to_rgba},
06478     {D3DFMT_DXT1,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4,  8, FORMAT_ARGB,    NULL,         NULL      },
06479     {D3DFMT_DXT2,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
06480     {D3DFMT_DXT3,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
06481     {D3DFMT_DXT4,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
06482     {D3DFMT_DXT5,        {0,  0,  0,  0}, { 0,  0,  0,  0}, 1, 4, 4, 16, FORMAT_ARGB,    NULL,         NULL      },
06483     /* marks last element */
06484     {D3DFMT_UNKNOWN,     {0,  0,  0,  0}, { 0,  0,  0,  0}, 0, 1, 1,  0, FORMAT_UNKNOWN, NULL,         NULL      },
06485 };
06486 
06487 
06488 /************************************************************
06489  * map_view_of_file
06490  *
06491  * Loads a file into buffer and stores the number of read bytes in length.
06492  *
06493  * PARAMS
06494  *   filename [I] name of the file to be loaded
06495  *   buffer   [O] pointer to destination buffer
06496  *   length   [O] size of the obtained data
06497  *
06498  * RETURNS
06499  *   Success: D3D_OK
06500  *   Failure:
06501  *     see error codes for CreateFileW, GetFileSize, CreateFileMapping and MapViewOfFile
06502  *
06503  * NOTES
06504  *   The caller must UnmapViewOfFile when it doesn't need the data anymore
06505  *
06506  */
06507 HRESULT map_view_of_file(LPCWSTR filename, LPVOID *buffer, DWORD *length)
06508 {
06509     HANDLE hfile, hmapping = NULL;
06510 
06511     hfile = CreateFileW(filename, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
06512     if(hfile == INVALID_HANDLE_VALUE) goto error;
06513 
06514     *length = GetFileSize(hfile, NULL);
06515     if(*length == INVALID_FILE_SIZE) goto error;
06516 
06517     hmapping = CreateFileMappingW(hfile, NULL, PAGE_READONLY, 0, 0, NULL);
06518     if(!hmapping) goto error;
06519 
06520     *buffer = MapViewOfFile(hmapping, FILE_MAP_READ, 0, 0, 0);
06521     if(*buffer == NULL) goto error;
06522 
06523     CloseHandle(hmapping);
06524     CloseHandle(hfile);
06525 
06526     return S_OK;
06527 
06528 error:
06529     CloseHandle(hmapping);
06530     CloseHandle(hfile);
06531     return HRESULT_FROM_WIN32(GetLastError());
06532 }
06533 
06534 
06535 const struct pixel_format_desc *get_format_info(D3DFORMAT format)
06536 {
06537     unsigned int i = 0;
06538     while(formats[i].format != format && formats[i].format != D3DFMT_UNKNOWN) i++;
06539     //if (formats[i].format == D3DFMT_UNKNOWN)
06540     //    FIXME("Unknown format %#x (as FOURCC %s).\n", format, debugstr_an((const char *)&format, 4));
06541     return &formats[i];
06542 }
06543 
06544 const struct pixel_format_desc *get_format_info_idx(int idx)
06545 {
06546     if(idx >= sizeof(formats) / sizeof(formats[0]))
06547         return NULL;
06548     if(formats[idx].format == D3DFMT_UNKNOWN)
06549         return NULL;
06550     return &formats[idx];
06551 }
06552 
06553 HRESULT WINAPI D3DXCheckTextureRequirements(LPDIRECT3DDEVICE9 device,
06554                                             UINT* width,
06555                                             UINT* height,
06556                                             UINT* miplevels,
06557                                             DWORD usage,
06558                                             D3DFORMAT* format,
06559                                             D3DPOOL pool)
06560 {
06561     UINT w = (width && *width) ? *width : 1;
06562     UINT h = (height && *height) ? *height : 1;
06563     D3DCAPS9 caps;
06564     D3DDEVICE_CREATION_PARAMETERS params;
06565     IDirect3D9 *d3d = NULL;
06566     D3DDISPLAYMODE mode;
06567     HRESULT hr;
06568     D3DFORMAT usedformat = D3DFMT_UNKNOWN;
06569 
06570     //TRACE("(%p, %p, %p, %p, %u, %p, %u)\n", device, width, height, miplevels, usage, format, pool);
06571 
06572     if (!device)
06573         return D3DERR_INVALIDCALL;
06574 
06575     /* usage */
06576     if (usage == D3DX_DEFAULT)
06577         usage = 0;
06578     if (usage & (D3DUSAGE_WRITEONLY | D3DUSAGE_DONOTCLIP | D3DUSAGE_POINTS | D3DUSAGE_RTPATCHES | D3DUSAGE_NPATCHES))
06579         return D3DERR_INVALIDCALL;
06580 
06581     /* pool */
06582     if ((pool != D3DPOOL_DEFAULT) && (pool != D3DPOOL_MANAGED) && (pool != D3DPOOL_SYSTEMMEM) && (pool != D3DPOOL_SCRATCH))
06583         return D3DERR_INVALIDCALL;
06584 
06585     /* width and height */
06586     if (FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
06587         return D3DERR_INVALIDCALL;
06588 
06589     /* 256 x 256 default width/height */
06590     if ((w == D3DX_DEFAULT) && (h == D3DX_DEFAULT))
06591         w = h = 256;
06592     else if (w == D3DX_DEFAULT)
06593         w = (height ? h : 256);
06594     else if (h == D3DX_DEFAULT)
06595         h = (width ? w : 256);
06596 
06597     /* ensure width/height is power of 2 */
06598     if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w)))
06599         w = make_pow2(w);
06600 
06601     if (w > caps.MaxTextureWidth)
06602         w = caps.MaxTextureWidth;
06603 
06604     if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(h)))
06605         h = make_pow2(h);
06606 
06607     if (h > caps.MaxTextureHeight)
06608         h = caps.MaxTextureHeight;
06609 
06610     /* texture must be square? */
06611     if (caps.TextureCaps & D3DPTEXTURECAPS_SQUAREONLY)
06612     {
06613         if (w > h)
06614             h = w;
06615         else
06616             w = h;
06617     }
06618 
06619     if (width)
06620         *width = w;
06621 
06622     if (height)
06623         *height = h;
06624 
06625     /* miplevels */
06626     if (miplevels && (usage & D3DUSAGE_AUTOGENMIPMAP))
06627     {
06628         if (*miplevels > 1)
06629             *miplevels = 0;
06630     }
06631     else if (miplevels)
06632     {
06633         UINT max_mipmaps = 1;
06634 
06635         if (!width && !height)
06636             max_mipmaps = 9;    /* number of mipmaps in a 256x256 texture */
06637         else
06638         {
06639             UINT max_dimen = max(w, h);
06640 
06641             while (max_dimen > 1)
06642             {
06643                 max_dimen >>= 1;
06644                 max_mipmaps++;
06645             }
06646         }
06647 
06648         if (*miplevels == 0 || *miplevels > max_mipmaps)
06649             *miplevels = max_mipmaps;
06650     }
06651 
06652     /* format */
06653     if (format)
06654     {
06655         //TRACE("Requested format %x\n", *format);
06656         usedformat = *format;
06657     }
06658 
06659     hr = IDirect3DDevice9_GetDirect3D(device, &d3d);
06660 
06661     if (FAILED(hr))
06662         goto cleanup;
06663 
06664     hr = IDirect3DDevice9_GetCreationParameters(device, &params);
06665 
06666     if (FAILED(hr))
06667         goto cleanup;
06668 
06669     hr = IDirect3DDevice9_GetDisplayMode(device, 0, &mode);
06670 
06671     if (FAILED(hr))
06672         goto cleanup;
06673 
06674     if ((usedformat == D3DFMT_UNKNOWN) || (usedformat == D3DX_DEFAULT))
06675         usedformat = D3DFMT_A8R8G8B8;
06676 
06677     hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType, mode.Format,
06678         usage, D3DRTYPE_TEXTURE, usedformat);
06679 
06680     if (FAILED(hr))
06681     {
06682         /* Heuristic to choose the fallback format */
06683         const struct pixel_format_desc *fmt = get_format_info(usedformat);
06684         BOOL allow_24bits;
06685         int bestscore = INT_MIN, i = 0, j;
06686         unsigned int channels;
06687         const struct pixel_format_desc *curfmt;
06688 
06689         if (!fmt)
06690         {
06691             //FIXME("Pixel format %x not handled\n", usedformat);
06692             goto cleanup;
06693         }
06694 
06695         allow_24bits = fmt->bytes_per_pixel == 3;
06696         channels = (fmt->bits[0] ? 1 : 0) + (fmt->bits[1] ? 1 : 0)
06697             + (fmt->bits[2] ? 1 : 0) + (fmt->bits[3] ? 1 : 0);
06698         usedformat = D3DFMT_UNKNOWN;
06699 
06700         while ((curfmt = get_format_info_idx(i)))
06701         {
06702             unsigned int curchannels = (curfmt->bits[0] ? 1 : 0) + (curfmt->bits[1] ? 1 : 0)
06703                 + (curfmt->bits[2] ? 1 : 0) + (curfmt->bits[3] ? 1 : 0);
06704             int score;
06705 
06706             i++;
06707 
06708             if (curchannels < channels)
06709                 continue;
06710             if (curfmt->bytes_per_pixel == 3 && !allow_24bits)
06711                 continue;
06712 
06713             hr = IDirect3D9_CheckDeviceFormat(d3d, params.AdapterOrdinal, params.DeviceType,
06714                 mode.Format, usage, D3DRTYPE_TEXTURE, curfmt->format);
06715             if (FAILED(hr))
06716                 continue;
06717 
06718             /* This format can be used, let's evaluate it.
06719                Weights chosen quite arbitrarily... */
06720             score = 16 - 4 * (curchannels - channels);
06721 
06722             for (j = 0; j < 4; j++)
06723             {
06724                 int diff = curfmt->bits[j] - fmt->bits[j];
06725                 score += 16 - (diff < 0 ? -diff * 4 : diff);
06726             }
06727 
06728             if (score > bestscore)
06729             {
06730                 bestscore = score;
06731                 usedformat = curfmt->format;
06732             }
06733         }
06734         hr = D3D_OK;
06735     }
06736 
06737 cleanup:
06738 
06739     if (d3d)
06740         IDirect3D9_Release(d3d);
06741 
06742     if (FAILED(hr))
06743         return hr;
06744 
06745     if (usedformat == D3DFMT_UNKNOWN)
06746     {
06747         //WARN("Couldn't find a suitable pixel format\n");
06748         return D3DERR_NOTAVAILABLE;
06749     }
06750 
06751     //TRACE("Format chosen: %x\n", usedformat);
06752     if (format)
06753         *format = usedformat;
06754 
06755     return D3D_OK;
06756 }
06757 
06758 HRESULT WINAPI D3DXCheckCubeTextureRequirements(LPDIRECT3DDEVICE9 device,
06759                                                 UINT *size,
06760                                                 UINT *miplevels,
06761                                                 DWORD usage,
06762                                                 D3DFORMAT *format,
06763                                                 D3DPOOL pool)
06764 {
06765     D3DCAPS9 caps;
06766     UINT s = (size && *size) ? *size : 256;
06767     HRESULT hr;
06768 
06769     //TRACE("(%p, %p, %p, %u, %p, %u)\n", device, size, miplevels, usage, format, pool);
06770 
06771     if (s == D3DX_DEFAULT)
06772         s = 256;
06773 
06774     if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
06775         return D3DERR_INVALIDCALL;
06776 
06777     if (!(caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP))
06778         return D3DERR_NOTAVAILABLE;
06779 
06780     /* ensure width/height is power of 2 */
06781     if ((caps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && (!is_pow2(s)))
06782         s = make_pow2(s);
06783 
06784     hr = D3DXCheckTextureRequirements(device, &s, &s, miplevels, usage, format, pool);
06785 
06786     if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPCUBEMAP))
06787     {
06788         if(miplevels)
06789             *miplevels = 1;
06790     }
06791 
06792     if (size)
06793         *size = s;
06794 
06795     return hr;
06796 }
06797 
06798 HRESULT WINAPI D3DXCheckVolumeTextureRequirements(LPDIRECT3DDEVICE9 device,
06799                                                   UINT *width,
06800                                                   UINT *height,
06801                                                   UINT *depth,
06802                                                   UINT *miplevels,
06803                                                   DWORD usage,
06804                                                   D3DFORMAT *format,
06805                                                   D3DPOOL pool)
06806 {
06807     D3DCAPS9 caps;
06808     UINT w = width ? *width : D3DX_DEFAULT;
06809     UINT h = height ? *height : D3DX_DEFAULT;
06810     UINT d = (depth && *depth) ? *depth : 1;
06811     HRESULT hr;
06812 
06813     //TRACE("(%p, %p, %p, %p, %p, %u, %p, %u)\n", device, width, height, depth, miplevels,
06814     //      usage, format, pool);
06815 
06816     if (!device || FAILED(IDirect3DDevice9_GetDeviceCaps(device, &caps)))
06817         return D3DERR_INVALIDCALL;
06818 
06819     if (!(caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP))
06820         return D3DERR_NOTAVAILABLE;
06821 
06822     hr = D3DXCheckTextureRequirements(device, &w, &h, NULL, usage, format, pool);
06823     if (d == D3DX_DEFAULT)
06824         d = 1;
06825 
06826     /* ensure width/height is power of 2 */
06827     if ((caps.TextureCaps & D3DPTEXTURECAPS_VOLUMEMAP_POW2) &&
06828         (!is_pow2(w) || !is_pow2(h) || !is_pow2(d)))
06829     {
06830         w = make_pow2(w);
06831         h = make_pow2(h);
06832         d = make_pow2(d);
06833     }
06834 
06835     if (w > caps.MaxVolumeExtent)
06836         w = caps.MaxVolumeExtent;
06837     if (h > caps.MaxVolumeExtent)
06838         h = caps.MaxVolumeExtent;
06839     if (d > caps.MaxVolumeExtent)
06840         d = caps.MaxVolumeExtent;
06841 
06842     if (miplevels)
06843     {
06844         if (!(caps.TextureCaps & D3DPTEXTURECAPS_MIPVOLUMEMAP))
06845             *miplevels = 1;
06846         else if ((usage & D3DUSAGE_AUTOGENMIPMAP))
06847         {
06848             if (*miplevels > 1)
06849                 *miplevels = 0;
06850         }
06851         else
06852         {
06853             UINT max_mipmaps = 1;
06854             UINT max_dimen = max(max(w, h), d);
06855 
06856             while (max_dimen > 1)
06857             {
06858                 max_dimen >>= 1;
06859                 max_mipmaps++;
06860             }
06861 
06862             if (*miplevels == 0 || *miplevels > max_mipmaps)
06863                 *miplevels = max_mipmaps;
06864         }
06865     }
06866 
06867     if (width)
06868         *width = w;
06869     if (height)
06870         *height = h;
06871     if (depth)
06872         *depth = d;
06873 
06874     return hr;
06875 }
06876 
06877 HRESULT WINAPI D3DXCreateVolumeTexture(LPDIRECT3DDEVICE9 device,
06878                                        UINT width,
06879                                        UINT height,
06880                                        UINT depth,
06881                                        UINT miplevels,
06882                                        DWORD usage,
06883                                        D3DFORMAT format,
06884                                        D3DPOOL pool,
06885                                        LPDIRECT3DVOLUMETEXTURE9 *texture) {
06886     HRESULT hr;
06887 
06888     //TRACE("(%p, %u, %u, %u, %u, %#x, %#x, %#x, %p)\n", device, width, height, depth,
06889     //      miplevels, usage, format, pool, texture);
06890 
06891     if (!device || !texture)
06892         return D3DERR_INVALIDCALL;
06893 
06894     hr = D3DXCheckVolumeTextureRequirements(device, &width, &height, &depth,
06895                                             &miplevels, usage, &format, pool);
06896 
06897     if (FAILED(hr))
06898     {
06899     //    TRACE("D3DXCheckVolumeTextureRequirements failed\n");
06900         return hr;
06901     }
06902 
06903     return IDirect3DDevice9_CreateVolumeTexture(device, width, height, depth, miplevels,
06904                                                 usage, format, pool, texture, NULL);
06905 }
06906 
06907 HRESULT WINAPI D3DXCreateCubeTexture(LPDIRECT3DDEVICE9 device,
06908                                      UINT size,
06909                                      UINT miplevels,
06910                                      DWORD usage,
06911                                     D3DFORMAT format,
06912                                      D3DPOOL pool,
06913                                      LPDIRECT3DCUBETEXTURE9 *texture) {
06914     HRESULT hr;
06915 
06916     //TRACE("(%p, %u, %u, %#x, %#x, %#x, %p)\n", device, size, miplevels, usage, format,
06917     //    pool, texture);
06918 
06919     if (!device || !texture)
06920         return D3DERR_INVALIDCALL;
06921 
06922     hr = D3DXCheckCubeTextureRequirements(device, &size, &miplevels, usage, &format, pool);
06923 
06924     if (FAILED(hr))
06925     {
06926         //TRACE("D3DXCheckCubeTextureRequirements failed\n");
06927         return hr;
06928     }
06929 
06930     return IDirect3DDevice9_CreateCubeTexture(device, size, miplevels, usage, format, pool, texture, NULL);
06931 }
06932 
06933 HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,
06934                                  UINT width,
06935                                  UINT height,
06936                                  UINT miplevels,
06937                                   DWORD usage,
06938                                  D3DFORMAT format,
06939                                   D3DPOOL pool,
06940                                 LPDIRECT3DTEXTURE9 *ppTexture) {
06941     HRESULT hr; 
06942 
06943    // TRACE("(%p, %u, %u, %u, %x, %x, %x, %p)\n", pDevice, width, height, miplevels, usage, format, 
06944     //     pool, ppTexture); 
06945   
06946     if (!pDevice || !ppTexture) 
06947         return D3DERR_INVALIDCALL; 
06948 
06949     hr = D3DXCheckTextureRequirements(pDevice, &width, &height, &miplevels, usage, &format, pool); 
06950  
06951     if (FAILED(hr)) 
06952         return hr; 
06953 
06954      return IDirect3DDevice9_CreateTexture(pDevice, width, height, miplevels, usage, format, pool, ppTexture, NULL); 
06955  } 
06956 
06957 HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
06958                                 LPCVOID srcdata,
06959                                 UINT srcdatalen,
06960                                 CONST D3DXMACRO* defines,
06961                                 LPD3DXINCLUDE include,
06962                                 DWORD flags,
06963                                 LPD3DXEFFECTPOOL pool,
06964                                 LPD3DXEFFECT* effect,
06965                                 LPD3DXBUFFER* compilation_errors)
06966 {
06967     //TRACE("(%p, %p, %u, %p, %p, %#x, %p, %p, %p): Forwarded to D3DXCreateEffectEx\n", device, srcdata, srcdatalen, defines,
06968     //    include, flags, pool, effect, compilation_errors);
06969 
06970     return D3DXCreateEffectEx(device, srcdata, srcdatalen, defines, include, NULL, flags, pool, effect, compilation_errors);
06971 }
06972 
06973 #else
06974 
06975 #include <D3dx9shader.h>
06976 
06977 typedef HRESULT (WINAPI * pD3DXCreateEffect)(LPDIRECT3DDEVICE9 device,
06978                                 LPCVOID srcdata,
06979                                 UINT srcdatalen,
06980                                 CONST D3DXMACRO* defines,
06981                                 LPD3DXINCLUDE include,
06982                                 DWORD flags,
06983                                 LPD3DXEFFECTPOOL pool,
06984                                 LPD3DXEFFECT* effect,
06985                                 LPD3DXBUFFER* compilation_errors);
06986 
06987 /* extern "C" */HRESULT WINAPI D3DXCreateEffect(LPDIRECT3DDEVICE9 device,
06988                                 LPCVOID srcdata,
06989                                 UINT srcdatalen,
06990                                 CONST D3DXMACRO* defines,
06991                                 LPD3DXINCLUDE include,
06992                                 DWORD flags,
06993                                 LPD3DXEFFECTPOOL pool,
06994                                 LPD3DXEFFECT* effect,
06995                                 LPD3DXBUFFER* compilation_errors) {
06996         static pD3DXCreateEffect D3DXCreateEffect_p = NULL;
06997         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
06998         if (mod)
06999                 D3DXCreateEffect_p = (pD3DXCreateEffect) GetProcAddress(mod, "D3DXCreateEffect");
07000         if(NULL != D3DXCreateEffect_p)
07001                 return D3DXCreateEffect_p(device, srcdata, srcdatalen, defines, include, flags, pool, effect, compilation_errors);
07002         else
07003                 return D3DERR_NOTAVAILABLE;
07004 }
07005 
07006 typedef HRESULT (WINAPI * pD3DXCreateEffectCompilerFromFileA)(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
07007     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors);
07008 
07009 /* extern "C" */HRESULT WINAPI D3DXCreateEffectCompilerFromFileA(LPCSTR srcfile, const D3DXMACRO *defines, LPD3DXINCLUDE include,
07010     DWORD flags, LPD3DXEFFECTCOMPILER *effectcompiler, LPD3DXBUFFER *parseerrors) {
07011         static pD3DXCreateEffectCompilerFromFileA D3DXCreateEffectCompilerFromFileA_p = NULL;
07012         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07013         if (mod)
07014                 D3DXCreateEffectCompilerFromFileA_p = (pD3DXCreateEffectCompilerFromFileA) GetProcAddress(mod, "D3DXCreateEffectCompilerFromFileA");
07015         if(NULL != D3DXCreateEffectCompilerFromFileA_p)
07016                 return D3DXCreateEffectCompilerFromFileA_p(srcfile, defines, include, flags, effectcompiler, parseerrors);
07017         else
07018                 return D3DERR_NOTAVAILABLE;
07019 }
07020 
07021 typedef HRESULT (WINAPI * pD3DXCreateTexture)(LPDIRECT3DDEVICE9 pDevice,
07022                                  UINT width,
07023                                  UINT height,
07024                                  UINT miplevels,
07025                                   DWORD usage,
07026                                  D3DFORMAT format,
07027                                   D3DPOOL pool,
07028                                 LPDIRECT3DTEXTURE9 *ppTexture);
07029 
07030 /* extern "C" */HRESULT WINAPI D3DXCreateTexture(LPDIRECT3DDEVICE9 pDevice,
07031                                  UINT width,
07032                                  UINT height,
07033                                  UINT miplevels,
07034                                   DWORD usage,
07035                                  D3DFORMAT format,
07036                                   D3DPOOL pool,
07037                                 LPDIRECT3DTEXTURE9 *ppTexture) {
07038         static pD3DXCreateTexture D3DXCreateTexture_p = NULL;
07039         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07040         if (mod) 
07041                 D3DXCreateTexture_p = (pD3DXCreateTexture) GetProcAddress(mod, "D3DXCreateTexture");
07042         if(NULL != D3DXCreateTexture_p)
07043                 return D3DXCreateTexture_p(pDevice, width, height, miplevels, usage, format, pool, ppTexture);
07044         else
07045                 return D3DERR_NOTAVAILABLE;
07046 }
07047 
07048 typedef HRESULT (WINAPI * pD3DXCreateCubeTexture)(LPDIRECT3DDEVICE9 device,
07049                                      UINT size,
07050                                      UINT miplevels,
07051                                      DWORD usage,
07052                                     D3DFORMAT format,
07053                                      D3DPOOL pool,
07054                                      LPDIRECT3DCUBETEXTURE9 *texture);
07055 
07056 /* extern "C" */HRESULT WINAPI D3DXCreateCubeTexture(LPDIRECT3DDEVICE9 device,
07057                                      UINT size,
07058                                      UINT miplevels,
07059                                      DWORD usage,
07060                                     D3DFORMAT format,
07061                                      D3DPOOL pool,
07062                                      LPDIRECT3DCUBETEXTURE9 *texture) {
07063         static pD3DXCreateCubeTexture D3DXCreateCubeTexture_p = NULL;
07064         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07065         if (mod) 
07066                 D3DXCreateCubeTexture_p = (pD3DXCreateCubeTexture) GetProcAddress(mod, "D3DXCreateCubeTexture");
07067         if(NULL != D3DXCreateCubeTexture_p)
07068                 return D3DXCreateCubeTexture_p(device, size, miplevels, usage, format, pool, texture);
07069         else
07070                 return D3DERR_NOTAVAILABLE;
07071 }
07072 
07073 typedef HRESULT (WINAPI * pD3DXCreateVolumeTexture)(LPDIRECT3DDEVICE9 device,
07074                                        UINT width,
07075                                        UINT height,
07076                                        UINT depth,
07077                                        UINT miplevels,
07078                                        DWORD usage,
07079                                        D3DFORMAT format,
07080                                        D3DPOOL pool,
07081                                        LPDIRECT3DVOLUMETEXTURE9 *texture);
07082 
07083 /* extern "C" */HRESULT WINAPI D3DXCreateVolumeTexture(LPDIRECT3DDEVICE9 device,
07084                                        UINT width,
07085                                        UINT height,
07086                                        UINT depth,
07087                                        UINT miplevels,
07088                                        DWORD usage,
07089                                        D3DFORMAT format,
07090                                        D3DPOOL pool,
07091                                        LPDIRECT3DVOLUMETEXTURE9 *texture) {
07092         static pD3DXCreateVolumeTexture D3DXCreateVolumeTexture_p = NULL;
07093         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07094         if (mod) 
07095                 D3DXCreateVolumeTexture_p = (pD3DXCreateVolumeTexture) GetProcAddress(mod, "D3DXCreateVolumeTexture");
07096         if(NULL != D3DXCreateVolumeTexture_p)
07097                 return D3DXCreateVolumeTexture_p(device, width, height, depth, miplevels, usage, format, pool, texture);
07098         else
07099                 return D3DERR_NOTAVAILABLE;
07100 }
07101 
07102 #endif
07103 
07104 typedef HRESULT (WINAPI * pD3DXFillVolumeTextureTX)(LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture,
07105                                         LPD3DXTEXTURESHADER pTextureShader);
07106 
07107 /* extern "C" */HRESULT WINAPI D3DXFillVolumeTextureTX(LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture,
07108                                         LPD3DXTEXTURESHADER pTextureShader) {
07109         static pD3DXFillVolumeTextureTX D3DXFillVolumeTextureTX_p = NULL;
07110         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07111         if (mod) 
07112                 D3DXFillVolumeTextureTX_p = (pD3DXFillVolumeTextureTX) GetProcAddress(mod, "D3DXFillVolumeTextureTX");
07113         //FreeLibrary(mod);
07114         if(NULL != D3DXFillVolumeTextureTX_p)
07115                 return D3DXFillVolumeTextureTX_p(pVolumeTexture, pTextureShader);
07116         else
07117                 return D3DERR_NOTAVAILABLE;
07118 }
07119 
07120 typedef HRESULT (WINAPI * pD3DXFillCubeTextureTX)(
07121         LPDIRECT3DCUBETEXTURE9    pCubeTexture,
07122         LPD3DXTEXTURESHADER       pTextureShader);
07123 
07124 /* extern "C" */HRESULT WINAPI
07125     D3DXFillCubeTextureTX(
07126         LPDIRECT3DCUBETEXTURE9    pCubeTexture,
07127         LPD3DXTEXTURESHADER       pTextureShader) {
07128         static pD3DXFillCubeTextureTX D3DXFillCubeTextureTX_p = NULL;
07129         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07130         if (mod) 
07131                 D3DXFillCubeTextureTX_p = (pD3DXFillCubeTextureTX) GetProcAddress(mod, "D3DXFillCubeTextureTX");
07132         //FreeLibrary(mod);
07133         if(NULL != D3DXFillCubeTextureTX_p)
07134                 return D3DXFillCubeTextureTX_p(pCubeTexture, pTextureShader);
07135         else
07136                 return D3DERR_NOTAVAILABLE;
07137 }
07138 
07139 typedef HRESULT (WINAPI * pD3DXFillTextureTX)(
07140         LPDIRECT3DTEXTURE9        pTexture,
07141         LPD3DXTEXTURESHADER       pTextureShader);
07142 
07143 /* extern "C" */HRESULT WINAPI 
07144     D3DXFillTextureTX(
07145         LPDIRECT3DTEXTURE9        pTexture,
07146         LPD3DXTEXTURESHADER       pTextureShader) {
07147         static pD3DXFillTextureTX D3DXFillTextureTX_p = NULL;
07148         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07149         //FreeLibrary(mod);
07150         if (mod) 
07151                 D3DXFillTextureTX_p = (pD3DXFillTextureTX) GetProcAddress(mod, "D3DXFillTextureTX");
07152         if(NULL != D3DXFillTextureTX_p)
07153                 return D3DXFillTextureTX_p(pTexture, pTextureShader);
07154         else
07155                 return D3DERR_NOTAVAILABLE;
07156 }
07157 
07158 typedef HRESULT (WINAPI * pD3DXCreateTextureShader)(
07159   const DWORD *pFunction,
07160   LPD3DXTEXTURESHADER *ppTextureShader
07161 );
07162 
07163 /* extern "C" */HRESULT WINAPI D3DXCreateTextureShader(
07164   const DWORD *pFunction,
07165   LPD3DXTEXTURESHADER *ppTextureShader) {
07166         static pD3DXCreateTextureShader D3DXCreateTextureShader_p = NULL;
07167         HMODULE mod = LoadLibrary(_T("D3DX9_43.DLL"));
07168         //FreeLibrary(mod);
07169         if (mod) 
07170                 D3DXCreateTextureShader_p = (pD3DXCreateTextureShader) GetProcAddress(mod, "D3DXCreateTextureShader");
07171         if(NULL != D3DXCreateTextureShader_p)
07172                 return D3DXCreateTextureShader_p(pFunction, ppTextureShader);
07173         else
07174                 return D3DERR_NOTAVAILABLE;
07175 }
07176 
07177 D3DXMATRIX* WINAPI D3DXMatrixMultiply(D3DXMATRIX *pout, CONST D3DXMATRIX *pm1, CONST D3DXMATRIX *pm2) {
07178     int i,j;
07179 
07180     for (i=0; i<4; i++)
07181     {
07182      for (j=0; j<4; j++)
07183      {
07184       pout->m[i][j] = pm1->m[i][0] * pm2->m[0][j] + pm1->m[i][1] * pm2->m[1][j] + pm1->m[i][2] * pm2->m[2][j] + pm1->m[i][3] * pm2->m[3][j];
07185      }
07186     }
07187     return pout;
07188 }
07189 
07190 D3DXMATRIX* WINAPI D3DXMatrixTranslation(D3DXMATRIX *pOut, FLOAT tx, FLOAT ty, FLOAT tz) {
07191     pOut->_11=1.0f;   pOut->_12=0.0f;   pOut->_13=0.0f;  pOut->_14=0.0f;
07192     pOut->_21=0.0f;   pOut->_22=1.0f;   pOut->_23=0.0f;  pOut->_24=0.0f;
07193     pOut->_31=0.0f;   pOut->_32=0.0f;   pOut->_33=1.0f;  pOut->_34=0.0f;
07194     pOut->_41=tx;     pOut->_42=ty;     pOut->_43=tz;    pOut->_44=1.0f;
07195 
07196     return pOut;
07197 }
07198 
07199 D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH(D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf) {
07200     (void)l; (void)b; (void)zn; (void)zf;
07201     pOut->_11=2.0f/r; pOut->_12=0.0f;   pOut->_13=0.0f;  pOut->_14=0.0f;
07202     pOut->_21=0.0f;   pOut->_22=2.0f/t; pOut->_23=0.0f;  pOut->_24=0.0f;
07203     pOut->_31=0.0f;   pOut->_32=0.0f;   pOut->_33=1.0f;  pOut->_34=0.0f;
07204     pOut->_41=-1.0f;  pOut->_42=-1.0f;  pOut->_43=0.0f;  pOut->_44=1.0f;
07205 
07206     return pOut;
07207 }
07208 
07209 D3DXMATRIX* WINAPI D3DXMatrixScaling(D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz) {
07210     pOut->_11=sx;     pOut->_12=0.0f;   pOut->_13=0.0f;  pOut->_14=0.0f;
07211     pOut->_21=0.0f;   pOut->_22=sy;     pOut->_23=0.0f;  pOut->_24=0.0f;
07212     pOut->_31=0.0f;   pOut->_32=0.0f;   pOut->_33=sz;    pOut->_34=0.0f;
07213     pOut->_41=0.0f;   pOut->_42=0.0f;   pOut->_43=0.0f;  pOut->_44=1.0f;
07214 
07215     return pOut;
07216 }