+
+
+typedef HRESULT
+(WINAPI *PD3DXASSEMBLESHADER)(
+ LPCSTR pSrcData,
+ UINT SrcDataLen,
+ const D3DXMACRO *pDefines,
+ LPD3DXINCLUDE pInclude,
+ DWORD Flags,
+ LPD3DXBUFFER *ppShader,
+ LPD3DXBUFFER *ppErrorMsgs
+);
+
+DWORD *
+extractShader(LPCSTR pSrcData)
+{
+ static BOOL firsttime = TRUE;
+ static HMODULE hD3DXModule = NULL;
+ static PD3DXASSEMBLESHADER pfnD3DXAssembleShader = NULL;
+
+ if (firsttime) {
+ if (!hD3DXModule) {
+ unsigned release;
+ int version;
+ for (release = 0; release <= 1; ++release) {
+ /* Version 41 corresponds to Mar 2009 version of DirectX Runtime / SDK */
+ for (version = 41; version >= 0; --version) {
+ char filename[256];
+ _snprintf(filename, sizeof(filename),
+ "d3dx9%s%s%u.dll", release ? "" : "d", version ? "_" : "", version);
+ hD3DXModule = LoadLibraryA(filename);
+ if (hD3DXModule)
+ goto found;
+ }
+ }
+found:
+ ;
+ }
+
+ if (hD3DXModule) {
+ if (!pfnD3DXAssembleShader) {
+ pfnD3DXAssembleShader = (PD3DXASSEMBLESHADER)GetProcAddress(hD3DXModule, "D3DXAssembleShader");
+ }
+ }
+
+ firsttime = FALSE;
+ }
+
+ if (pfnD3DXAssembleShader) {
+ LPD3DXBUFFER pTokens = NULL;
+ HRESULT hr;
+
+ hr = pfnD3DXAssembleShader(pSrcData, strlen(pSrcData), NULL, NULL, 0, &pTokens, NULL);
+ if (SUCCEEDED(hr)) {
+ return (DWORD *)pTokens->GetBufferPointer();
+ }
+
+ // FIXME: Don't leak pTokens
+ }
+
+ return NULL;
+}