https://git.reactos.org/?p=reactos.git;a=commitdiff;h=e5c42da45cb306ee8294de...
commit e5c42da45cb306ee8294de6074927c05c8b6dac4 Author: Amine Khaldi amine.khaldi@reactos.org AuthorDate: Thu Mar 8 13:26:47 2018 +0100 Commit: Amine Khaldi amine.khaldi@reactos.org CommitDate: Thu Mar 8 13:26:47 2018 +0100
[D3DX9_*] Sync with Wine Staging 3.3. CORE-14434 --- dll/directx/wine/d3dx9_36/CMakeLists.txt | 8 +- dll/directx/wine/d3dx9_36/animation.c | 21 +- dll/directx/wine/d3dx9_36/core.c | 7 +- dll/directx/wine/d3dx9_36/d3dx9_36.spec | 8 +- .../{d3dx9_36_private.h => d3dx9_private.h} | 31 +- dll/directx/wine/d3dx9_36/effect.c | 57 +++- dll/directx/wine/d3dx9_36/font.c | 254 ++++++++++++-- dll/directx/wine/d3dx9_36/line.c | 7 +- .../wine/d3dx9_36/{d3dx9_36_main.c => main.c} | 28 +- dll/directx/wine/d3dx9_36/math.c | 41 ++- dll/directx/wine/d3dx9_36/mesh.c | 83 ++++- dll/directx/wine/d3dx9_36/precomp.h | 28 ++ dll/directx/wine/d3dx9_36/preshader.c | 10 +- dll/directx/wine/d3dx9_36/render.c | 7 +- dll/directx/wine/d3dx9_36/shader.c | 372 ++++++++++++++++++++- dll/directx/wine/d3dx9_36/skin.c | 115 ++++++- dll/directx/wine/d3dx9_36/sprite.c | 7 +- dll/directx/wine/d3dx9_36/surface.c | 229 ++++++++++++- dll/directx/wine/d3dx9_36/texture.c | 24 +- dll/directx/wine/d3dx9_36/util.c | 10 +- dll/directx/wine/d3dx9_36/volume.c | 7 +- dll/directx/wine/d3dx9_36/xfile.c | 10 +- media/doc/README.WINE | 2 +- 23 files changed, 1218 insertions(+), 148 deletions(-)
diff --git a/dll/directx/wine/d3dx9_36/CMakeLists.txt b/dll/directx/wine/d3dx9_36/CMakeLists.txt index 1b56e547d4..836ee9c743 100644 --- a/dll/directx/wine/d3dx9_36/CMakeLists.txt +++ b/dll/directx/wine/d3dx9_36/CMakeLists.txt @@ -1,15 +1,15 @@
-add_definitions(-D__WINESRC__ -Dcopysignf=_copysignf -D_D3DX9_VER=36) +add_definitions(-D__WINESRC__ -Dcopysignf=_copysignf -DD3DX_SDK_VERSION=36 -D_D3DX9_VER=36) include_directories(${REACTOS_SOURCE_DIR}/sdk/include/reactos/wine) spec2def(d3dx9_36.dll d3dx9_36.spec ADD_IMPORTLIB)
list(APPEND SOURCE animation.c core.c - d3dx9_36_main.c effect.c font.c line.c + main.c math.c mesh.c preshader.c @@ -22,7 +22,7 @@ list(APPEND SOURCE util.c volume.c xfile.c - d3dx9_36_private.h) + precomp.h)
add_library(d3dx9_36 SHARED ${SOURCE} @@ -35,5 +35,5 @@ set_module_type(d3dx9_36 win32dll) add_dependencies(d3dx9_36 d3d_idl_headers) target_link_libraries(d3dx9_36 dxguid wine) add_importlibs(d3dx9_36 d3dcompiler_43 d3dxof d3dwine user32 ole32 gdi32 msvcrt kernel32 ntdll) -add_pch(d3dx9_36 d3dx9_36_private.h SOURCE) +add_pch(d3dx9_36 precomp.h SOURCE) add_cd_file(TARGET d3dx9_36 DESTINATION reactos/system32 FOR all) diff --git a/dll/directx/wine/d3dx9_36/animation.c b/dll/directx/wine/d3dx9_36/animation.c index e1e895f630..6be2dd6b5a 100644 --- a/dll/directx/wine/d3dx9_36/animation.c +++ b/dll/directx/wine/d3dx9_36/animation.c @@ -18,7 +18,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
struct d3dx9_animation_controller { @@ -392,7 +397,7 @@ static HRESULT WINAPI d3dx9_animation_controller_CloneAnimationController(ID3DXA return E_NOTIMPL; }
-static /* const */ struct ID3DXAnimationControllerVtbl d3dx9_animation_controller_vtbl = +static const struct ID3DXAnimationControllerVtbl d3dx9_animation_controller_vtbl = { d3dx9_animation_controller_QueryInterface, d3dx9_animation_controller_AddRef, @@ -464,3 +469,15 @@ HRESULT WINAPI D3DXCreateAnimationController(UINT max_outputs, UINT max_sets,
return D3D_OK; } + +HRESULT WINAPI D3DXCreateKeyframedAnimationSet(const char *name, double ticks_per_second, + D3DXPLAYBACK_TYPE playback_type, UINT animation_count, UINT callback_key_count, + const D3DXKEY_CALLBACK *callback_keys, ID3DXKeyframedAnimationSet **animation_set) +{ + FIXME("name %s, ticks_per_second %.16e, playback_type %u, animation_count %u, " + "callback_key_count %u, callback_keys %p, animation_set %p stub.\n", + debugstr_a(name), ticks_per_second, playback_type, animation_count, + callback_key_count, callback_keys, animation_set); + + return E_NOTIMPL; +} diff --git a/dll/directx/wine/d3dx9_36/core.c b/dll/directx/wine/d3dx9_36/core.c index e7624f2a21..1eb289ece6 100644 --- a/dll/directx/wine/d3dx9_36/core.c +++ b/dll/directx/wine/d3dx9_36/core.c @@ -17,7 +17,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
struct ID3DXBufferImpl { diff --git a/dll/directx/wine/d3dx9_36/d3dx9_36.spec b/dll/directx/wine/d3dx9_36/d3dx9_36.spec index e487aa12ec..1e035f76c1 100644 --- a/dll/directx/wine/d3dx9_36/d3dx9_36.spec +++ b/dll/directx/wine/d3dx9_36/d3dx9_36.spec @@ -22,9 +22,9 @@ @ stdcall -stub D3DXComputeIMTFromPerVertexSignal(ptr ptr long long long ptr ptr ptr) @ stdcall -stub D3DXComputeIMTFromSignal(ptr long long long long ptr ptr ptr ptr ptr) @ stdcall -stub D3DXComputeIMTFromTexture(ptr ptr long long ptr ptr ptr) -@ stdcall -stub D3DXComputeNormalMap(ptr ptr ptr long long float) +@ stdcall D3DXComputeNormalMap(ptr ptr ptr long long float) @ stdcall D3DXComputeNormals(ptr ptr) -@ stdcall -stub D3DXComputeTangent(ptr long long long long ptr) +@ stdcall D3DXComputeTangent(ptr long long long long ptr) @ stdcall -stub D3DXComputeTangentFrame(ptr long) @ stdcall D3DXComputeTangentFrameEx(ptr long long long long long long long long long ptr float float float ptr ptr) @ stdcall -stub D3DXConcatenateMeshes(ptr long long ptr ptr ptr ptr ptr) @@ -68,7 +68,7 @@ @ stdcall D3DXCreateFontW(ptr long long long long long long long long long wstr ptr) @ stdcall D3DXCreateFragmentLinker(ptr long ptr) @ stdcall D3DXCreateFragmentLinkerEx(ptr long long ptr) -@ stdcall -stub D3DXCreateKeyframedAnimationSet(ptr long long long long ptr ptr) +@ stdcall D3DXCreateKeyframedAnimationSet(str double long long long ptr ptr) @ stdcall D3DXCreateLine(ptr ptr) @ stdcall D3DXCreateMatrixStack(long ptr) @ stdcall D3DXCreateMesh(long long long ptr ptr ptr) @@ -229,7 +229,7 @@ @ stdcall D3DXMatrixTranslation(ptr float float float) @ stdcall D3DXMatrixTranspose(ptr ptr) @ stdcall D3DXOptimizeFaces(ptr long long long ptr) -@ stdcall -stub D3DXOptimizeVertices(ptr long long long ptr) +@ stdcall D3DXOptimizeVertices(ptr long long long ptr) @ stdcall D3DXPlaneFromPointNormal(ptr ptr ptr) @ stdcall D3DXPlaneFromPoints(ptr ptr ptr ptr) @ stdcall D3DXPlaneIntersectLine(ptr ptr ptr ptr) diff --git a/dll/directx/wine/d3dx9_36/d3dx9_36_private.h b/dll/directx/wine/d3dx9_36/d3dx9_private.h similarity index 96% rename from dll/directx/wine/d3dx9_36/d3dx9_36_private.h rename to dll/directx/wine/d3dx9_36/d3dx9_private.h index ddc38225e0..edb7455a5f 100644 --- a/dll/directx/wine/d3dx9_36/d3dx9_36_private.h +++ b/dll/directx/wine/d3dx9_36/d3dx9_private.h @@ -19,33 +19,14 @@ * */
-#ifndef __WINE_D3DX9_36_PRIVATE_H -#define __WINE_D3DX9_36_PRIVATE_H +#ifndef __WINE_D3DX9_PRIVATE_H +#define __WINE_D3DX9_PRIVATE_H
-#include <config.h> -#include <wine/port.h> - -#include <assert.h> -#include <stdarg.h> - -#define WIN32_NO_STATUS -#define _INC_WINDOWS -#define COM_NO_WINDOWS_H - -#define COBJMACROS #define NONAMELESSUNION -#define NONAMELESSSTRUCT +#include "wine/debug.h"
-#include <windef.h> -#include <winbase.h> -#include <wingdi.h> -#include <winuser.h> -#include <d3dx9.h> - -#include <wine/unicode.h> - -#include <wine/debug.h> -WINE_DEFAULT_DEBUG_CHANNEL(d3dx); +#define COBJMACROS +#include "d3dx9.h"
#define ULONG64_MAX (~(ULONG64)0)
@@ -409,4 +390,4 @@ const struct ctab_constant *d3dx_shader_get_ctab_constant(ID3DXConstantTable *if
HRESULT create_dummy_skin(ID3DXSkinInfo **iface) DECLSPEC_HIDDEN;
-#endif /* __WINE_D3DX9_36_PRIVATE_H */ +#endif /* __WINE_D3DX9_PRIVATE_H */ diff --git a/dll/directx/wine/d3dx9_36/effect.c b/dll/directx/wine/d3dx9_36/effect.c index 7a5975a706..e2c0ce3728 100644 --- a/dll/directx/wine/d3dx9_36/effect.c +++ b/dll/directx/wine/d3dx9_36/effect.c @@ -17,9 +17,11 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h"
-#include <d3dcompiler.h> +#include "d3dx9_private.h" +#include "d3dcompiler.h"
/* Constants for special INT/FLOAT conversation */ #define INT_FLOAT_MULTI 255.0f @@ -31,6 +33,8 @@ static const char parameter_magic_string[4] = {'@', '!', '#', '\xFF'};
#define INITIAL_POOL_SIZE 16
+WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + enum STATE_CLASS { SC_LIGHTENABLE, @@ -3980,13 +3984,41 @@ done: return ret; }
-static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect* iface, D3DXHANDLE technique, D3DXHANDLE* next_technique) +static HRESULT WINAPI ID3DXEffectImpl_FindNextValidTechnique(ID3DXEffect *iface, + D3DXHANDLE technique, D3DXHANDLE *next_technique) { struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); + struct d3dx9_base_effect *base_effect = &This->base_effect; + UINT i = 0;
- FIXME("(%p)->(%p, %p): stub\n", This, technique, next_technique); + TRACE("iface %p, technique %p, next_technique %p\n", iface, technique, next_technique);
- return E_NOTIMPL; + if (!next_technique) + return D3DERR_INVALIDCALL; + + if (technique) + { + for (; i < base_effect->technique_count; i++) + { + if (technique == get_technique_handle(&base_effect->techniques[i])) + { + i++; /* Go to next technique */ + break; + } + } + } + + for (; i < base_effect->technique_count; i++) + { + if (SUCCEEDED(iface->lpVtbl->ValidateTechnique(iface, get_technique_handle(&base_effect->techniques[i])))) + { + *next_technique = get_technique_handle(&base_effect->techniques[i]); + return D3D_OK; + } + } + + *next_technique = NULL; + return S_FALSE; }
static BOOL walk_parameter_dep(struct d3dx_parameter *param, walk_parameter_dep_func param_func, @@ -4347,6 +4379,7 @@ static HRESULT WINAPI ID3DXEffectImpl_ApplyParameterBlock(ID3DXEffect* iface, D3 return E_NOTIMPL; }
+#if _D3DX9_VER >= 26 static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D3DXHANDLE parameter_block) { struct ID3DXEffectImpl *This = impl_from_ID3DXEffect(iface); @@ -4355,6 +4388,7 @@ static HRESULT WINAPI ID3DXEffectImpl_DeleteParameterBlock(ID3DXEffect* iface, D
return E_NOTIMPL; } +#endif
static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface, struct IDirect3DDevice9 *device, struct ID3DXEffect **effect) @@ -4363,9 +4397,15 @@ static HRESULT WINAPI ID3DXEffectImpl_CloneEffect(ID3DXEffect *iface,
FIXME("(%p)->(%p, %p): stub\n", This, device, effect);
- return E_NOTIMPL; + if (!effect) + return D3DXERR_INVALIDDATA; + + iface->lpVtbl->AddRef(iface); + *effect = iface; + return S_OK; }
+#if _D3DX9_VER >= 27 static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect *iface, D3DXHANDLE parameter, const void *data, UINT byte_offset, UINT bytes) { @@ -4374,6 +4414,7 @@ static HRESULT WINAPI ID3DXEffectImpl_SetRawValue(ID3DXEffect *iface,
return E_NOTIMPL; } +#endif
static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl = { @@ -4456,9 +4497,13 @@ static const struct ID3DXEffectVtbl ID3DXEffect_Vtbl = ID3DXEffectImpl_BeginParameterBlock, ID3DXEffectImpl_EndParameterBlock, ID3DXEffectImpl_ApplyParameterBlock, +#if _D3DX9_VER >= 26 ID3DXEffectImpl_DeleteParameterBlock, +#endif ID3DXEffectImpl_CloneEffect, +#if _D3DX9_VER >= 27 ID3DXEffectImpl_SetRawValue +#endif };
static inline struct ID3DXEffectCompilerImpl *impl_from_ID3DXEffectCompiler(ID3DXEffectCompiler *iface) diff --git a/dll/directx/wine/d3dx9_36/font.c b/dll/directx/wine/d3dx9_36/font.c index 575e80d0bb..b4b9600320 100644 --- a/dll/directx/wine/d3dx9_36/font.c +++ b/dll/directx/wine/d3dx9_36/font.c @@ -17,7 +17,13 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" +#include "wine/unicode.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
struct d3dx_font { @@ -29,8 +35,29 @@ struct d3dx_font
HDC hdc; HFONT hfont; + + UINT tex_width; + UINT tex_height; + IDirect3DTexture9 *texture; + HBITMAP bitmap; + BYTE *bits; };
+/* Returns the smallest power of 2 which is greater than or equal to num */ +static UINT make_pow2(UINT num) +{ + UINT result = 1; + + /* In the unlikely event somebody passes a large value, make sure we don't enter an infinite loop */ + if (num >= 0x80000000) + return 0x80000000; + + while (result < num) + result <<= 1; + + return result; +} + static inline struct d3dx_font *impl_from_ID3DXFont(ID3DXFont *iface) { return CONTAINING_RECORD(iface, struct d3dx_font, ID3DXFont_iface); @@ -57,19 +84,27 @@ static HRESULT WINAPI ID3DXFontImpl_QueryInterface(ID3DXFont *iface, REFIID riid static ULONG WINAPI ID3DXFontImpl_AddRef(ID3DXFont *iface) { struct d3dx_font *This = impl_from_ID3DXFont(iface); - ULONG ref=InterlockedIncrement(&This->ref); + ULONG ref = InterlockedIncrement(&This->ref); + TRACE("%p increasing refcount to %u\n", iface, ref); + return ref; }
static ULONG WINAPI ID3DXFontImpl_Release(ID3DXFont *iface) { struct d3dx_font *This = impl_from_ID3DXFont(iface); - ULONG ref=InterlockedDecrement(&This->ref); + ULONG ref = InterlockedDecrement(&This->ref);
TRACE("%p decreasing refcount to %u\n", iface, ref);
- if(ref==0) { + if (!ref) + { + if (This->texture) + { + IDirect3DTexture9_Release(This->texture); + DeleteObject(This->bitmap); + } DeleteObject(This->hfont); DeleteDC(This->hdc); IDirect3DDevice9_Release(This->device); @@ -172,17 +207,187 @@ static HRESULT WINAPI ID3DXFontImpl_PreloadTextW(ID3DXFont *iface, const WCHAR * static INT WINAPI ID3DXFontImpl_DrawTextA(ID3DXFont *iface, ID3DXSprite *sprite, const char *string, INT count, RECT *rect, DWORD format, D3DCOLOR color) { - FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x stub!\n", + LPWSTR stringW; + INT countW, ret = 0; + + TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x\n", iface, sprite, debugstr_a(string), count, wine_dbgstr_rect(rect), format, color); - return 1; + + if (!string || count == 0) + return 0; + + if (count < 0) + count = -1; + + countW = MultiByteToWideChar(CP_ACP, 0, string, count, NULL, 0); + stringW = HeapAlloc(GetProcessHeap(), 0, countW * sizeof(WCHAR)); + if (stringW) + { + MultiByteToWideChar(CP_ACP, 0, string, count, stringW, countW); + ret = ID3DXFont_DrawTextW(iface, sprite, stringW, countW, rect, format, color); + HeapFree(GetProcessHeap(), 0, stringW); + } + + return ret; }
static INT WINAPI ID3DXFontImpl_DrawTextW(ID3DXFont *iface, ID3DXSprite *sprite, const WCHAR *string, INT count, RECT *rect, DWORD format, D3DCOLOR color) { - FIXME("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x stub!\n", + struct d3dx_font *This = impl_from_ID3DXFont(iface); + RECT calc_rect; + INT height; + + TRACE("iface %p, sprite %p, string %s, count %d, rect %s, format %#x, color 0x%08x\n", iface, sprite, debugstr_w(string), count, wine_dbgstr_rect(rect), format, color); - return 1; + + if (!string || count == 0) + return 0; + + if (count < 0) + count = lstrlenW(string); + + /* Strip terminating NULL characters */ + while (count > 0 && !string[count-1]) + count--; + + if (rect) + calc_rect = *rect; + + height = DrawTextW(This->hdc, string, count, &calc_rect, format | DT_CALCRECT); + + if (format & DT_CALCRECT) + { + if (rect) + *rect = calc_rect; + return height; + } + + if (format & DT_CENTER) + { + UINT new_width = calc_rect.right - calc_rect.left; + calc_rect.left = (rect->right + rect->left - new_width) / 2; + calc_rect.right = calc_rect.left + new_width; + } + + if (height && (calc_rect.left < calc_rect.right)) + { + D3DLOCKED_RECT locked_rect; + D3DXVECTOR3 position; + UINT text_width, text_height; + RECT text_rect; + ID3DXSprite *target = sprite; + HRESULT hr; + int i, j; + + /* Get rect position and dimensions */ + position.x = calc_rect.left; + position.y = calc_rect.top; + position.z = 0; + text_width = calc_rect.right - calc_rect.left; + text_height = calc_rect.bottom - calc_rect.top; + text_rect.left = 0; + text_rect.top = 0; + text_rect.right = text_width; + text_rect.bottom = text_height; + + /* We need to flush as it seems all draws in the begin/end sequence use only the latest updated texture */ + if (sprite) + ID3DXSprite_Flush(sprite); + + /* Extend texture and DIB section to contain text */ + if ((text_width > This->tex_width) || (text_height > This->tex_height)) + { + BITMAPINFOHEADER header; + + if (text_width > This->tex_width) + This->tex_width = make_pow2(text_width); + if (text_height > This->tex_height) + This->tex_height = make_pow2(text_height); + + if (This->texture) + { + IDirect3DTexture9_Release(This->texture); + DeleteObject(This->bitmap); + } + + hr = D3DXCreateTexture(This->device, This->tex_width, This->tex_height, 1, 0, + D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &This->texture); + if (FAILED(hr)) + { + This->texture = NULL; + return 0; + } + + header.biSize = sizeof(header); + header.biWidth = This->tex_width; + header.biHeight = -This->tex_height; + header.biPlanes = 1; + header.biBitCount = 32; + header.biCompression = BI_RGB; + header.biSizeImage = sizeof(DWORD) * This->tex_width * This->tex_height; + header.biXPelsPerMeter = 0; + header.biYPelsPerMeter = 0; + header.biClrUsed = 0; + header.biClrImportant = 0; + + This->bitmap = CreateDIBSection(This->hdc, (const BITMAPINFO*)&header, + DIB_RGB_COLORS, (void**)&This->bits, NULL, 0); + if (!This->bitmap) + { + IDirect3DTexture9_Release(This->texture); + This->texture = NULL; + return 0; + } + + SelectObject(This->hdc, This->bitmap); + } + + if (FAILED(IDirect3DTexture9_LockRect(This->texture, 0, &locked_rect, &text_rect, D3DLOCK_DISCARD))) + return 0; + + /* Clear rect */ + for (i = 0; i < text_height; i++) + memset(This->bits + i * This->tex_width * sizeof(DWORD), 0, + text_width * sizeof(DWORD)); + + DrawTextW(This->hdc, string, count, &text_rect, format); + + /* All RGB components are equal so take one as alpha and set RGB + * color to white, so it can be modulated with color parameter */ + for (i = 0; i < text_height; i++) + { + DWORD *src = (DWORD *)This->bits + i * This->tex_width; + DWORD *dst = (DWORD *)((BYTE *)locked_rect.pBits + i * locked_rect.Pitch); + for (j = 0; j < text_width; j++) + { + *dst++ = (*src++ << 24) | 0xFFFFFF; + } + } + + IDirect3DTexture9_UnlockRect(This->texture, 0); + + if (!sprite) + { + hr = D3DXCreateSprite(This->device, &target); + if (FAILED(hr)) + return 0; + ID3DXSprite_Begin(target, 0); + } + + hr = target->lpVtbl->Draw(target, This->texture, &text_rect, NULL, &position, color); + + if (!sprite) + { + ID3DXSprite_End(target); + ID3DXSprite_Release(target); + } + + if (FAILED(hr)) + return 0; + } + + return height; }
static HRESULT WINAPI ID3DXFontImpl_OnLostDevice(ID3DXFont *iface) @@ -296,46 +501,55 @@ HRESULT WINAPI D3DXCreateFontIndirectW(IDirect3DDevice9 *device, const D3DXFONT_
TRACE("(%p, %p, %p)\n", device, desc, font);
- if( !device || !desc || !font ) return D3DERR_INVALIDCALL; + if (!device || !desc || !font) return D3DERR_INVALIDCALL;
- /* the device MUST support D3DFMT_A8R8G8B8 */ + TRACE("desc: %d %d %d %d %d %d %d %d %d %s\n", desc->Height, desc->Width, desc->Weight, desc->MipLevels, desc->Italic, + desc->CharSet, desc->OutputPrecision, desc->Quality, desc->PitchAndFamily, debugstr_w(desc->FaceName)); + + /* The device MUST support D3DFMT_A8R8G8B8 */ IDirect3DDevice9_GetDirect3D(device, &d3d); IDirect3DDevice9_GetCreationParameters(device, &cpars); IDirect3DDevice9_GetDisplayMode(device, 0, &mode); hr = IDirect3D9_CheckDeviceFormat(d3d, cpars.AdapterOrdinal, cpars.DeviceType, mode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8R8G8B8); - if(FAILED(hr)) { + if (FAILED(hr)) + { IDirect3D9_Release(d3d); return D3DXERR_INVALIDDATA; } IDirect3D9_Release(d3d);
- object = HeapAlloc(GetProcessHeap(), 0, sizeof(struct d3dx_font)); - if(object==NULL) { - *font=NULL; + object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct d3dx_font)); + if (!object) + { + *font = NULL; return E_OUTOFMEMORY; } object->ID3DXFont_iface.lpVtbl = &D3DXFont_Vtbl; - object->ref=1; - object->device=device; - object->desc=*desc; + object->ref = 1; + object->device = device; + object->desc = *desc;
object->hdc = CreateCompatibleDC(NULL); - if( !object->hdc ) { + if (!object->hdc) + { HeapFree(GetProcessHeap(), 0, object); return D3DXERR_INVALIDDATA; }
object->hfont = CreateFontW(desc->Height, desc->Width, 0, 0, desc->Weight, desc->Italic, FALSE, FALSE, desc->CharSet, desc->OutputPrecision, CLIP_DEFAULT_PRECIS, desc->Quality, desc->PitchAndFamily, desc->FaceName); - if( !object->hfont ) { + if (!object->hfont) + { DeleteDC(object->hdc); HeapFree(GetProcessHeap(), 0, object); return D3DXERR_INVALIDDATA; } SelectObject(object->hdc, object->hfont); + SetTextColor(object->hdc, 0x00ffffff); + SetBkColor(object->hdc, 0x00000000);
IDirect3DDevice9_AddRef(device); - *font=&object->ID3DXFont_iface; + *font = &object->ID3DXFont_iface;
return D3D_OK; } diff --git a/dll/directx/wine/d3dx9_36/line.c b/dll/directx/wine/d3dx9_36/line.c index e1b691a07b..356d54fbd0 100644 --- a/dll/directx/wine/d3dx9_36/line.c +++ b/dll/directx/wine/d3dx9_36/line.c @@ -17,7 +17,12 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
struct d3dx9_line { diff --git a/dll/directx/wine/d3dx9_36/d3dx9_36_main.c b/dll/directx/wine/d3dx9_36/main.c similarity index 71% rename from dll/directx/wine/d3dx9_36/d3dx9_36_main.c rename to dll/directx/wine/d3dx9_36/main.c index 01c5219bf0..a256d42526 100644 --- a/dll/directx/wine/d3dx9_36/d3dx9_36_main.c +++ b/dll/directx/wine/d3dx9_36/main.c @@ -20,11 +20,14 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "initguid.h" +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
-/*********************************************************************** - * DllMain. - */ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) { switch(reason) @@ -38,14 +41,13 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved) return TRUE; }
-/*********************************************************************** - * D3DXCheckVersion - * Checks whether we are compiling against the correct d3d and d3dx library. - */ -BOOL WINAPI D3DXCheckVersion(UINT d3dsdkvers, UINT d3dxsdkvers) +BOOL WINAPI D3DXCheckVersion(UINT d3d_sdk_ver, UINT d3dx_sdk_ver) +{ + return d3d_sdk_ver == D3D_SDK_VERSION && d3dx_sdk_ver == D3DX_SDK_VERSION; +} + +DWORD WINAPI D3DXCpuOptimizations(BOOL enable) { - if(d3dsdkvers==D3D_SDK_VERSION && d3dxsdkvers==36) - return TRUE; - else - return FALSE; + FIXME("%#x - stub\n", enable); + return 0; } diff --git a/dll/directx/wine/d3dx9_36/math.c b/dll/directx/wine/d3dx9_36/math.c index 2f5a473081..856e987cb9 100644 --- a/dll/directx/wine/d3dx9_36/math.c +++ b/dll/directx/wine/d3dx9_36/math.c @@ -22,7 +22,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
struct ID3DXMatrixStackImpl { @@ -2568,27 +2573,27 @@ FLOAT * WINAPI D3DXSHMultiply3(FLOAT *out, const FLOAT *a, const FLOAT *b)
out[0] = 0.28209479f * a[0] * b[0];
- ta = 0.28209479f * a[0] - 0.12615662f * a[6] - 0.21850968f * a[8]; - tb = 0.28209479f * b[0] - 0.12615662f * b[6] - 0.21850968f * b[8]; + ta = 0.28209479f * a[0] - 0.12615663f * a[6] - 0.21850969f * a[8]; + tb = 0.28209479f * b[0] - 0.12615663f * b[6] - 0.21850969f * b[8]; out[1] = ta * b[1] + tb * a[1]; t = a[1] * b[1]; out[0] += 0.28209479f * t; - out[6] = -0.12615662f * t; - out[8] = -0.21850968f * t; + out[6] = -0.12615663f * t; + out[8] = -0.21850969f * t;
- ta = 0.21850968f * a[5]; - tb = 0.21850968f * b[5]; + ta = 0.21850969f * a[5]; + tb = 0.21850969f * b[5]; out[1] += ta * b[2] + tb * a[2]; out[2] = ta * b[1] + tb * a[1]; t = a[1] * b[2] +a[2] * b[1]; - out[5] = 0.21850968f * t; + out[5] = 0.21850969f * t;
- ta = 0.21850968f * a[4]; - tb = 0.21850968f * b[4]; + ta = 0.21850969f * a[4]; + tb = 0.21850969f * b[4]; out[1] += ta * b[3] + tb * a[3]; out[3] = ta * b[1] + tb * a[1]; t = a[1] * b[3] + a[3] * b[1]; - out[4] = 0.21850968f * t; + out[4] = 0.21850969f * t;
ta = 0.28209480f * a[0] + 0.25231326f * a[6]; tb = 0.28209480f * b[0] + 0.25231326f * b[6]; @@ -2624,14 +2629,14 @@ FLOAT * WINAPI D3DXSHMultiply3(FLOAT *out, const FLOAT *a, const FLOAT *b) out[4] += ta * b[5] + tb * a[5]; out[5] += ta * b[4] + tb * a[4]; t = a[4] * b[5] + a[5] * b[4]; - out[7] += 0.15607834f * t; + out[7] += 0.15607835f * t;
- ta = 0.28209479f * a[0] + 0.09011186f * a[6] - 0.15607835f * a[8]; - tb = 0.28209479f * b[0] + 0.09011186f * b[6] - 0.15607835f * b[8]; + ta = 0.28209479f * a[0] + 0.09011188f * a[6] - 0.15607835f * a[8]; + tb = 0.28209479f * b[0] + 0.09011188f * b[6] - 0.15607835f * b[8]; out[5] += ta * b[5] + tb * a[5]; t = a[5] * b[5]; out[0] += 0.28209479f * t; - out[6] += 0.09011186f * t; + out[6] += 0.09011188f * t; out[8] -= 0.15607835f * t;
ta = 0.28209480f * a[0]; @@ -2641,12 +2646,12 @@ FLOAT * WINAPI D3DXSHMultiply3(FLOAT *out, const FLOAT *a, const FLOAT *b) out[0] += 0.28209480f * t; out[6] += 0.18022376f * t;
- ta = 0.28209479f * a[0] + 0.09011186f * a[6] + 0.15607835f * a[8]; - tb = 0.28209479f * b[0] + 0.09011186f * b[6] + 0.15607835f * b[8]; + ta = 0.28209479f * a[0] + 0.09011188f * a[6] + 0.15607835f * a[8]; + tb = 0.28209479f * b[0] + 0.09011188f * b[6] + 0.15607835f * b[8]; out[7] += ta * b[7] + tb * a[7]; t = a[7] * b[7]; out[0] += 0.28209479f * t; - out[6] += 0.09011186f * t; + out[6] += 0.09011188f * t; out[8] += 0.15607835f * t;
ta = 0.28209479f * a[0] - 0.18022375f * a[6]; diff --git a/dll/directx/wine/d3dx9_36/mesh.c b/dll/directx/wine/d3dx9_36/mesh.c index 57b2aeb1a1..3dd881ee1c 100644 --- a/dll/directx/wine/d3dx9_36/mesh.c +++ b/dll/directx/wine/d3dx9_36/mesh.c @@ -24,17 +24,24 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h"
+#include <assert.h> #ifdef HAVE_FLOAT_H # include <float.h> #endif
+#include "d3dx9_private.h" +#undef MAKE_DDHRESULT +#include "dxfile.h" #include "rmxfguid.h" #include "rmxftmpl.h" - +#include "wine/unicode.h" #include "wine/list.h"
+WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + struct d3dx9_mesh { ID3DXMesh ID3DXMesh_iface; @@ -1688,11 +1695,7 @@ static HRESULT WINAPI d3dx9_mesh_OptimizeInplace(ID3DXMesh *iface, DWORD flags, if (FAILED(hr)) goto cleanup; } else if (flags & D3DXMESHOPT_ATTRSORT) { if (!(flags & D3DXMESHOPT_IGNOREVERTS)) - { FIXME("D3DXMESHOPT_ATTRSORT vertex reordering not implemented.\n"); - hr = E_NOTIMPL; - goto cleanup; - }
hr = iface->lpVtbl->LockAttributeBuffer(iface, 0, &attrib_buffer); if (FAILED(hr)) goto cleanup; @@ -2333,7 +2336,7 @@ UINT WINAPI D3DXGetDeclVertexSize(const D3DVERTEXELEMENT9 *decl, DWORD stream_id
if (element->Stream != stream_idx) continue;
- if (element->Type >= sizeof(d3dx_decltype_size) / sizeof(*d3dx_decltype_size)) + if (element->Type >= ARRAY_SIZE(d3dx_decltype_size)) { FIXME("Unhandled element type %#x, size will be incorrect.\n", element->Type); continue; @@ -3325,6 +3328,13 @@ static HRESULT parse_mesh(ID3DXFileData *filedata, struct mesh_data *mesh_data, goto end; }
+ if ((provide_flags & PROVIDE_SKININFO) && !mesh_data->skin_info) + { + hr = create_dummy_skin(&mesh_data->skin_info); + if (FAILED(hr)) + goto end; + } + hr = D3D_OK;
end: @@ -5159,7 +5169,7 @@ HRESULT WINAPI D3DXCreateTeapot(struct IDirect3DDevice9 *device, { FIXME("(%p, %p, %p): stub\n", device, mesh, adjacency);
- return E_NOTIMPL; + return D3DXCreateSphere(device, 1.0f, 4, 4, mesh, adjacency); }
HRESULT WINAPI D3DXCreateTextA(struct IDirect3DDevice9 *device, HDC hdc, const char *text, float deviation, @@ -7177,6 +7187,33 @@ cleanup: return hr; }
+ +/************************************************************************* + * D3DXOptimizeVertices (D3DX9_36.@) + */ +HRESULT WINAPI D3DXOptimizeVertices(const void *indices, UINT num_faces, + UINT num_vertices, BOOL indices_are_32bit, DWORD *vertex_remap) +{ + UINT i; + + FIXME("indices %p, num_faces %u, num_vertices %u, indices_are_32bit %#x, vertex_remap %p semi-stub.\n", + indices, num_faces, num_vertices, indices_are_32bit, vertex_remap); + + if (!vertex_remap) + { + WARN("vertex remap pointer is NULL.\n"); + return D3DERR_INVALIDCALL; + } + + for (i = 0; i < num_vertices; i++) + { + vertex_remap[i] = i; + } + + return D3D_OK; +} + + /************************************************************************* * D3DXOptimizeFaces (D3DX9_36.@) * @@ -7500,6 +7537,24 @@ done: return hr; }
+/************************************************************************* + * D3DXComputeTangent (D3DX9_36.@) + */ +HRESULT WINAPI D3DXComputeTangent(ID3DXMesh *mesh, DWORD stage_idx, DWORD tangent_idx, + DWORD binorm_idx, DWORD wrap, const DWORD *adjacency) +{ + TRACE("mesh %p, stage_idx %d, tangent_idx %d, binorm_idx %d, wrap %d, adjacency %p.\n", + mesh, stage_idx, tangent_idx, binorm_idx, wrap, adjacency); + + return D3DXComputeTangentFrameEx( mesh, D3DDECLUSAGE_TEXCOORD, stage_idx, + ( binorm_idx == D3DX_DEFAULT ) ? D3DX_DEFAULT : D3DDECLUSAGE_BINORMAL, + binorm_idx, + ( tangent_idx == D3DX_DEFAULT ) ? D3DX_DEFAULT : D3DDECLUSAGE_TANGENT, + tangent_idx, D3DX_DEFAULT, 0, + ( wrap ? D3DXTANGENT_WRAP_UV : 0 ) | D3DXTANGENT_GENERATE_IN_PLACE | D3DXTANGENT_ORTHOGONALIZE_FROM_U, + adjacency, -1.01f, -0.01f, -1.01f, NULL, NULL); +} + /************************************************************************* * D3DXComputeNormals (D3DX9_36.@) */ @@ -7519,6 +7574,18 @@ HRESULT WINAPI D3DXComputeNormals(struct ID3DXBaseMesh *mesh, const DWORD *adjac adjacency, -1.01f, -0.01f, -1.01f, NULL, NULL); }
+/************************************************************************* + * D3DXComputeNormalMap (D3DX9_36.@) + */ +HRESULT WINAPI D3DXComputeNormalMap(IDirect3DTexture9 *texture, IDirect3DTexture9 *src_texture, + const PALETTEENTRY *src_palette, DWORD flags, DWORD channel, FLOAT amplitude) +{ + FIXME("texture %p, src_texture %p, src_palette %p, flags %#x, channel %u, amplitude %f stub.\n", + texture, src_texture, src_palette, flags, channel, amplitude); + + return D3D_OK; +} + /************************************************************************* * D3DXIntersect (D3DX9_36.@) */ diff --git a/dll/directx/wine/d3dx9_36/precomp.h b/dll/directx/wine/d3dx9_36/precomp.h new file mode 100644 index 0000000000..30ad1cf918 --- /dev/null +++ b/dll/directx/wine/d3dx9_36/precomp.h @@ -0,0 +1,28 @@ + +#ifndef __WINE_D3DX9_36_PRECOMP_H +#define __WINE_D3DX9_36_PRECOMP_H + +#include <config.h> +#include <wine/port.h> + +#include <assert.h> +#include <stdarg.h> + +#define WIN32_NO_STATUS +#define _INC_WINDOWS +#define COM_NO_WINDOWS_H + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#define COBJMACROS + +#include <windef.h> +#include <winbase.h> +#include <wingdi.h> +#include <winuser.h> + +#include <wine/unicode.h> + +#include "d3dx9_private.h" + +#endif /* __WINE_D3DX9_36_PRECOMP_H */ diff --git a/dll/directx/wine/d3dx9_36/preshader.c b/dll/directx/wine/d3dx9_36/preshader.c index 416f05b15a..ef27149d82 100644 --- a/dll/directx/wine/d3dx9_36/preshader.c +++ b/dll/directx/wine/d3dx9_36/preshader.c @@ -16,7 +16,15 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +#include <float.h> +#include <assert.h> + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
/* ReactOS FIXME: Insect */ #define fmin min diff --git a/dll/directx/wine/d3dx9_36/render.c b/dll/directx/wine/d3dx9_36/render.c index 02e6caa8eb..ad8330784d 100644 --- a/dll/directx/wine/d3dx9_36/render.c +++ b/dll/directx/wine/d3dx9_36/render.c @@ -17,7 +17,12 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
struct device_state { diff --git a/dll/directx/wine/d3dx9_36/shader.c b/dll/directx/wine/d3dx9_36/shader.c index 48e49a2982..2bbc6b79e0 100644 --- a/dll/directx/wine/d3dx9_36/shader.c +++ b/dll/directx/wine/d3dx9_36/shader.c @@ -1,6 +1,7 @@ /* * Copyright 2008 Luis Busquets * Copyright 2009 Matteo Bruni + * Copyright 2010, 2013, 2016 Christian Costa * Copyright 2011 Travis Athougies * * This library is free software; you can redistribute it and/or @@ -18,12 +19,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" - +#include "config.h" +#include "wine/port.h" #include <stdio.h>
+#include "d3dx9_private.h" +#include "d3dcommon.h" #include "d3dcompiler.h"
+WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + /* This function is not declared in the SDK headers yet. */ HRESULT WINAPI D3DAssemble(const void *data, SIZE_T datasize, const char *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, UINT flags, @@ -440,6 +445,41 @@ HRESULT WINAPI D3DXCompileShader(const char *data, UINT length, const D3DXMACRO } }
+ /* Filter out D3DCompile warning messages that are not present with D3DCompileShader */ + if (SUCCEEDED(hr) && error_msgs && *error_msgs) + { + char *messages = ID3DXBuffer_GetBufferPointer(*error_msgs); + DWORD size = ID3DXBuffer_GetBufferSize(*error_msgs); + + /* Ensure messages are null terminated for safe processing */ + if (size) messages[size - 1] = 0; + + while (size > 1) + { + char *prev, *next; + + /* Warning has the form "warning X3206: ... implicit truncation of vector type" + but we only search for "X3206:" in case d3dcompiler_43 has localization */ + prev = next = strstr(messages, "X3206:"); + if (!prev) break; + + /* get pointer to beginning and end of current line */ + while (prev > messages && *(prev - 1) != '\n') prev--; + while (next < messages + size - 1 && *next != '\n') next++; + if (next < messages + size - 1 && *next == '\n') next++; + + memmove(prev, next, messages + size - next); + size -= (next - prev); + } + + /* Only return a buffer if the resulting string is not empty as some apps depend on that */ + if (size <= 1) + { + ID3DXBuffer_Release(*error_msgs); + *error_msgs = NULL; + } + } + return hr; }
@@ -2141,10 +2181,334 @@ HRESULT WINAPI D3DXGetShaderSamplers(const DWORD *byte_code, const char **sample return D3D_OK; }
+ +static const char *decl_usage[] = { "position", "blendweight", "blendindices", "normal", "psize", "texcoord", + "tangent", "binormal", "tessfactor", "positiont", "color" }; + +static const char *tex_type[] = { "", "1d", "2d", "cube", "volume" }; + +static int add_modifier(char *buffer, DWORD param) +{ + char *buf = buffer; + DWORD dst_mod = param & D3DSP_DSTMOD_MASK; + + if (dst_mod & D3DSPDM_SATURATE) + buf += sprintf(buf, "_sat"); + if (dst_mod & D3DSPDM_PARTIALPRECISION) + buf += sprintf(buf, "_pp"); + if (dst_mod & D3DSPDM_MSAMPCENTROID) + buf += sprintf(buf, "_centroid"); + + return buf - buffer; +} + +static int add_register(char *buffer, DWORD param, BOOL dst, BOOL ps) +{ + char *buf = buffer; + DWORD reg_type = ((param & D3DSP_REGTYPE_MASK2) >> D3DSP_REGTYPE_SHIFT2) + | ((param & D3DSP_REGTYPE_MASK) >> D3DSP_REGTYPE_SHIFT); + DWORD reg_num = param & D3DSP_REGNUM_MASK; + + if (reg_type == D3DSPR_INPUT) + buf += sprintf(buf, "v%d", reg_num); + else if (reg_type == D3DSPR_CONST) + buf += sprintf(buf, "c%d", reg_num); + else if (reg_type == D3DSPR_TEMP) + buf += sprintf(buf, "r%d", reg_num); + else if (reg_type == D3DSPR_ADDR) + buf += sprintf(buf, "%s%d", ps ? "t" : "a", reg_num); + else if (reg_type == D3DSPR_SAMPLER) + buf += sprintf(buf, "s%d", reg_num); + else if (reg_type == D3DSPR_RASTOUT) + buf += sprintf(buf, "oPos"); + else if (reg_type == D3DSPR_COLOROUT) + buf += sprintf(buf, "oC%d", reg_num); + else if (reg_type == D3DSPR_TEXCRDOUT) + buf += sprintf(buf, "oT%d", reg_num); + else if (reg_type == D3DSPR_ATTROUT) + buf += sprintf(buf, "oD%d", reg_num); + else + buf += sprintf(buf, "? (%d)", reg_type); + + if (dst) + { + if ((param & D3DSP_WRITEMASK_ALL) != D3DSP_WRITEMASK_ALL) + { + buf += sprintf(buf, ".%s%s%s%s", param & D3DSP_WRITEMASK_0 ? "x" : "", + param & D3DSP_WRITEMASK_1 ? "y" : "", + param & D3DSP_WRITEMASK_2 ? "z" : "", + param & D3DSP_WRITEMASK_3 ? "w" : ""); + } + } + else + { + if ((param & D3DVS_SWIZZLE_MASK) != D3DVS_NOSWIZZLE) + { + if ( ((param & D3DSP_SWIZZLE_MASK) == (D3DVS_X_X | D3DVS_Y_X | D3DVS_Z_X | D3DVS_W_X)) || + ((param & D3DSP_SWIZZLE_MASK) == (D3DVS_X_Y | D3DVS_Y_Y | D3DVS_Z_Y | D3DVS_W_Y)) || + ((param & D3DSP_SWIZZLE_MASK) == (D3DVS_X_Z | D3DVS_Y_Z | D3DVS_Z_Z | D3DVS_W_Z)) || + ((param & D3DSP_SWIZZLE_MASK) == (D3DVS_X_W | D3DVS_Y_W | D3DVS_Z_W | D3DVS_W_W)) ) + buf += sprintf(buf, ".%c", 'w' + (((param >> D3DVS_SWIZZLE_SHIFT) + 1) & 0x3)); + else + buf += sprintf(buf, ".%c%c%c%c", 'w' + (((param >> (D3DVS_SWIZZLE_SHIFT+0)) + 1) & 0x3), + 'w' + (((param >> (D3DVS_SWIZZLE_SHIFT+2)) + 1) & 0x3), + 'w' + (((param >> (D3DVS_SWIZZLE_SHIFT+4)) + 1) & 0x3), + 'w' + (((param >> (D3DVS_SWIZZLE_SHIFT+6)) + 1) & 0x3)); + } + } + + return buf - buffer; +} + +struct instr_info +{ + DWORD opcode; + const char *name; + int length; + int (*function)(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps); + WORD min_version; + WORD max_version; +}; + +static int instr_comment(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) +{ + *ptr += 1 + ((**ptr & D3DSI_COMMENTSIZE_MASK) >> D3DSI_COMMENTSIZE_SHIFT); + return 0; +} + +static int instr_def(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) +{ + int len = sprintf(buffer, " def c%d, %g, %g, %g, %g\n", *(*ptr+1) & D3DSP_REGNUM_MASK, + (double)*(float*)(*ptr+2), (double)*(float*)(*ptr+3), + (double)*(float*)(*ptr+4), (double)*(float*)(*ptr+5)); + *ptr += 6; + return len; +} + +static int instr_dcl(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) +{ + DWORD param1 = *++*ptr; + DWORD param2 = *++*ptr; + DWORD usage = (param1 & D3DSP_DCL_USAGE_MASK) >> D3DSP_DCL_USAGE_SHIFT; + DWORD usage_index = (param1 & D3DSP_DCL_USAGEINDEX_MASK) >> D3DSP_DCL_USAGEINDEX_SHIFT; + char *buf = buffer; + + buf += sprintf(buf, " dcl"); + if (ps) + { + if (param1 & D3DSP_TEXTURETYPE_MASK) + buf += sprintf(buf, "_%s", (usage <= D3DSTT_VOLUME) ? + tex_type[(param1 & D3DSP_TEXTURETYPE_MASK) >> D3DSP_TEXTURETYPE_SHIFT] : "???"); + } + else + { + buf += sprintf(buf, "_%s", (usage <= D3DDECLUSAGE_COLOR) ? decl_usage[usage] : "???"); + if (usage_index) + buf += sprintf(buf, "%d", usage_index); + } + + buf += add_modifier(buf, param2); + buf += sprintf(buf, " "); + buf += add_register(buf, param2, TRUE, TRUE); + buf += sprintf(buf, "\n"); + (*ptr)++; + return buf - buffer; +} + +static int instr_generic(const struct instr_info *info, DWORD **ptr, char *buffer, BOOL ps) +{ + char *buf = buffer; + int j; + + buf += sprintf(buf, " %s", info->name); + (*ptr)++; + + if (info->length) + { + buf += add_modifier(buf, **ptr); + + for (j = 0; j < info->length; j++) + { + buf += sprintf(buf, "%s ", j ? "," : ""); + + if ((j != 0) && ((**ptr & D3DSP_SRCMOD_MASK) != D3DSPSM_NONE)) + { + if ((**ptr & D3DSP_SRCMOD_MASK) == D3DSPSM_NEG) + buf += sprintf(buf, "-"); + else + buf += sprintf(buf, "*"); + } + + buf += add_register(buf, **ptr, j == 0, ps); + + if (*(*ptr)++ & D3DVS_ADDRESSMODE_MASK) + { + buf += sprintf(buf, "["); + buf += add_register(buf, **ptr, FALSE, FALSE); + buf += sprintf(buf, "]"); + (*ptr)++; + } + } + } + buf += sprintf(buf, "\n"); + return buf - buffer; +} + +const struct instr_info instructions[] = +{ + { D3DSIO_NOP, "nop", 0, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_MOV, "mov", 2, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_ADD, "add", 3, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_SUB, "sub", 3, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_MAD, "mad", 4, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_MUL, "mul", 3, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_RCP, "rcp", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_RSQ, "rsq", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_DP3, "dp3", 3, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_DP4, "dp4", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 1.2 for PS */ + { D3DSIO_MIN, "min", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_MAX, "max", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_SLT, "slt", 3, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_SGE, "sge", 3, instr_generic, 0x0100, 0xFFFF }, /* VS only */ + { D3DSIO_EXP, "exp", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_LOG, "log", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_LIT, "lit", 2, instr_generic, 0x0100, 0xFFFF }, /* VS only */ + { D3DSIO_DST, "dst", 3, instr_generic, 0x0100, 0xFFFF }, /* VS only */ + { D3DSIO_LRP, "lrp", 4, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for VS */ + { D3DSIO_FRC, "frc", 2, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_M4x4, "m4x4", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_M4x3, "m4x3", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_M3x4, "m3x4", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_M3x3, "m3x3", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_M3x2, "m3x2", 3, instr_generic, 0x0100, 0xFFFF }, /* >= 2.0 for PS */ + { D3DSIO_CALL, "call", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_CALLNZ, "callnz", 2, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_LOOP, "loop", 2, instr_generic, 0x0200, 0xFFFF }, /* >= 3.0 for PS */ + { D3DSIO_RET, "ret", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_ENDLOOP, "endloop", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 3.0 for PS */ + { D3DSIO_LABEL, "label", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_DCL, "dcl", 1, instr_dcl, 0x0100, 0xFFFF }, + { D3DSIO_POW, "pow", 3, instr_generic, 0x0200, 0xFFFF }, + { D3DSIO_CRS, "crs", 3, instr_generic, 0x0200, 0xFFFF }, + { D3DSIO_SGN, "sgn", 4, instr_generic, 0x0200, 0xFFFF }, /* VS only */ + { D3DSIO_ABS, "abs", 2, instr_generic, 0x0200, 0xFFFF }, + { D3DSIO_NRM, "nrm", 2, instr_generic, 0x0200, 0xFFFF }, + { D3DSIO_SINCOS, "sincos", 4, instr_generic, 0x0200, 0x02FF }, + { D3DSIO_SINCOS, "sincos", 2, instr_generic, 0x0300, 0xFFFF }, + { D3DSIO_REP, "rep", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_ENDREP, "endrep", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_IF, "if", 1, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_IFC, "if_comp", 2, instr_generic, 0x0200, 0xFFFF }, + { D3DSIO_ELSE, "else", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_ENDIF, "endif", 0, instr_generic, 0x0200, 0xFFFF }, /* >= 2.a for PS */ + { D3DSIO_BREAK, "break", 0, instr_generic, 0x0201, 0xFFFF }, + { D3DSIO_BREAKC, "break_comp", 2, instr_generic, 0x0201, 0xFFFF }, + { D3DSIO_MOVA, "mova", 2, instr_generic, 0x0200, 0xFFFF }, /* VS only */ + { D3DSIO_DEFB, "defb", 2, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_DEFI, "defi", 2, instr_generic, 0x0100, 0xFFFF }, + { D3DSIO_TEXCOORD, "texcoord", 1, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXCOORD, "texcrd", 2, instr_generic, 0x0104, 0x0104 }, /* PS only */ + { D3DSIO_TEXKILL, "texkill", 1, instr_generic, 0x0100, 0xFFFF }, /* PS only */ + { D3DSIO_TEX, "tex", 1, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEX, "texld", 2, instr_generic, 0x0104, 0x0104 }, /* PS only */ + { D3DSIO_TEX, "texld", 3, instr_generic, 0x0200, 0xFFFF }, /* PS only */ + { D3DSIO_TEXBEM, "texbem", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXBEML, "texbeml", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXREG2AR, "texreg2ar", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXREG2GB, "texreg2gb", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x2PAD, "texm3x2pad", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x2TEX, "texm3x2tex", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x3PAD, "texm3x3pad", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x3TEX, "texm3x3tex", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x3DIFF, "texm3x3diff", 2, instr_generic, 0x0100, 0xFFFF }, /* PS only - Not documented */ + { D3DSIO_TEXM3x3SPEC, "texm3x3spec", 3, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x3VSPEC, "texm3x3vspec", 2, instr_generic, 0x0100, 0x0103 }, /* PS only */ + { D3DSIO_EXPP, "expp", 2, instr_generic, 0x0100, 0xFFFF }, /* VS only */ + { D3DSIO_LOGP, "logp", 2, instr_generic, 0x0100, 0xFFFF }, /* VS only */ + { D3DSIO_CND, "cnd", 4, instr_generic, 0x0100, 0x0104 }, /* PS only */ + { D3DSIO_DEF, "def", 5, instr_def, 0x0100, 0xFFFF }, + { D3DSIO_TEXREG2RGB, "texreg2rgb", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ + { D3DSIO_TEXDP3TEX, "texdp3tex", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x2DEPTH, "texm3x2depth", 2, instr_generic, 0x0103, 0x0103 }, /* PS only */ + { D3DSIO_TEXDP3, "texdp3", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ + { D3DSIO_TEXM3x3, "texm3x3", 2, instr_generic, 0x0102, 0x0103 }, /* PS only */ + { D3DSIO_TEXDEPTH, "texdepth", 1, instr_generic, 0x0104, 0x0104 }, /* PS only */ + { D3DSIO_CMP, "cmp", 4, instr_generic, 0x0102, 0xFFFF }, /* PS only */ + { D3DSIO_BEM, "bem", 3, instr_generic, 0x0104, 0x0104 }, /* PS only */ + { D3DSIO_DP2ADD, "dp2add", 4, instr_generic, 0x0200, 0xFFFF }, /* PS only */ + { D3DSIO_DSX, "dsx", 2, instr_generic, 0x0201, 0xFFFF }, /* PS only */ + { D3DSIO_DSY, "dsy", 2, instr_generic, 0x0201, 0xFFFF }, /* PS only */ + { D3DSIO_TEXLDD, "texldd", 5, instr_generic, 0x0201, 0xFFFF }, /* PS only - not existing for 2.b */ + { D3DSIO_SETP, "setp_comp", 3, instr_generic, 0x0201, 0xFFFF }, + { D3DSIO_TEXLDL, "texldl", 3, instr_generic, 0x0300, 0xFFFF }, + { D3DSIO_BREAKP, "breakp", 1, instr_generic, 0x0201, 0xFFFF }, + { D3DSIO_PHASE, "phase", 0, instr_generic, 0x0104, 0x0104 }, /* PS only */ + { D3DSIO_COMMENT, "", 0, instr_comment, 0x0100, 0xFFFF } +}; + HRESULT WINAPI D3DXDisassembleShader(const DWORD *shader, BOOL colorcode, const char *comments, ID3DXBuffer **disassembly) { - FIXME("%p %d %s %p: stub\n", shader, colorcode, debugstr_a(comments), disassembly); - return E_OUTOFMEMORY; + DWORD *ptr = (DWORD *)shader; + char *buffer, *buf; + UINT capacity = 4096; + BOOL ps; + WORD version; + HRESULT hr; + + TRACE("%p %d %s %p\n", shader, colorcode, debugstr_a(comments), disassembly); + + if (!shader || !disassembly) + return D3DERR_INVALIDCALL; + + buf = buffer = HeapAlloc(GetProcessHeap(), 0, capacity); + if (!buffer) + return E_OUTOFMEMORY; + + ps = (*ptr >> 16) & 1; + version = *ptr & 0xFFFF; + buf += sprintf(buf, " %s_%d_%d\n", ps ? "ps" : "vs", D3DSHADER_VERSION_MAJOR(*ptr), D3DSHADER_VERSION_MINOR(*ptr)); + ptr++; + + while (*ptr != D3DSIO_END) + { + DWORD index; + + if ((buf - buffer + 128) > capacity) + { + UINT count = buf - buffer; + char *new_buffer = HeapReAlloc(GetProcessHeap(), 0, buffer, capacity * 2); + if (!new_buffer) + { + HeapFree(GetProcessHeap(), 0, buffer); + return E_OUTOFMEMORY; + } + capacity *= 2; + buffer = new_buffer; + buf = buffer + count; + } + + for (index = 0; index < sizeof(instructions)/sizeof(instructions[0]); index++) + if (((*ptr & D3DSI_OPCODE_MASK) == instructions[index].opcode) && + (version >= instructions[index].min_version) && (version <= instructions[index].max_version)) + break; + + if (index != sizeof(instructions)/sizeof(instructions[0])) + { + buf += instructions[index].function(&(instructions[index]), &ptr, buf, ps); + } + else + { + buf += sprintf(buf, " ??? (Unknown opcode %x)\n", *ptr); + while (*++ptr & (1u << 31)); + } + } + + hr = D3DXCreateBuffer(buf - buffer + 1 , disassembly); + if (SUCCEEDED(hr)) + strcpy(ID3DXBuffer_GetBufferPointer(*disassembly), buffer); + HeapFree(GetProcessHeap(), 0, buffer); + + return hr; }
struct d3dx9_texture_shader diff --git a/dll/directx/wine/d3dx9_36/skin.c b/dll/directx/wine/d3dx9_36/skin.c index 309241ccc0..0a305a9923 100644 --- a/dll/directx/wine/d3dx9_36/skin.c +++ b/dll/directx/wine/d3dx9_36/skin.c @@ -2,6 +2,7 @@ * Skin Info operations specific to D3DX9. * * Copyright (C) 2011 Dylan Smith + * Copyright (C) 2013 Christian Costa * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -18,7 +19,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
struct bone { @@ -89,7 +95,7 @@ static ULONG WINAPI d3dx9_skin_info_Release(ID3DXSkinInfo *iface) HeapFree(GetProcessHeap(), 0, skin->bones[i].vertices); HeapFree(GetProcessHeap(), 0, skin->bones[i].weights); } - HeapFree(GetProcessHeap(), 0, skin->bones); + if (skin->bones) HeapFree(GetProcessHeap(), 0, skin->bones); HeapFree(GetProcessHeap(), 0, skin); }
@@ -372,10 +378,89 @@ static HRESULT WINAPI d3dx9_skin_info_GetDeclaration(ID3DXSkinInfo *iface, static HRESULT WINAPI d3dx9_skin_info_UpdateSkinnedMesh(ID3DXSkinInfo *iface, const D3DXMATRIX *bone_transforms, const D3DXMATRIX *bone_inv_transpose_transforms, const void *src_vertices, void *dst_vertices) { - FIXME("iface %p, bone_transforms %p, bone_inv_transpose_transforms %p, src_vertices %p, dst_vertices %p stub!\n", - iface, bone_transforms, bone_inv_transpose_transforms, src_vertices, dst_vertices); + struct d3dx9_skin_info *skin = impl_from_ID3DXSkinInfo(iface); + DWORD size = D3DXGetFVFVertexSize(skin->fvf); + DWORD i, j;
- return E_NOTIMPL; + TRACE("iface %p, bone_transforms %p, bone_inv_transpose_transforms %p, src_vertices %p, dst_vertices %p\n", + skin, bone_transforms, bone_inv_transpose_transforms, src_vertices, dst_vertices); + + if (bone_inv_transpose_transforms) + FIXME("Skinning vertices with two position elements not supported\n"); + + if ((skin->fvf & D3DFVF_POSITION_MASK) != D3DFVF_XYZ) { + FIXME("Vertex type %#x not supported\n", skin->fvf & D3DFVF_POSITION_MASK); + return E_FAIL; + } + + /* Reset all positions */ + for (i = 0; i < skin->num_vertices; i++) { + D3DXVECTOR3 *position = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * i); + position->x = 0.0f; + position->y = 0.0f; + position->z = 0.0f; + } + + /* Update positions that are influenced by bones */ + for (i = 0; i < skin->num_bones; i++) { + D3DXMATRIX bone_inverse, matrix; + + D3DXMatrixInverse(&bone_inverse, NULL, &skin->bones[i].transform); + D3DXMatrixMultiply(&matrix, &bone_transforms[i], &bone_inverse); + D3DXMatrixMultiply(&matrix, &matrix, &skin->bones[i].transform); + + for (j = 0; j < skin->bones[i].num_influences; j++) { + D3DXVECTOR3 position; + D3DXVECTOR3 *position_src = (D3DXVECTOR3*)((BYTE*)src_vertices + size * skin->bones[i].vertices[j]); + D3DXVECTOR3 *position_dest = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * skin->bones[i].vertices[j]); + FLOAT weight = skin->bones[i].weights[j]; + + D3DXVec3TransformCoord(&position, position_src, &matrix); + position_dest->x += weight * position.x; + position_dest->y += weight * position.y; + position_dest->z += weight * position.z; + } + } + + if (skin->fvf & D3DFVF_NORMAL) { + /* Reset all normals */ + for (i = 0; i < skin->num_vertices; i++) { + D3DXVECTOR3 *normal = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * i + sizeof(D3DXVECTOR3)); + normal->x = 0.0f; + normal->y = 0.0f; + normal->z = 0.0f; + } + + /* Update normals that are influenced by bones */ + for (i = 0; i < skin->num_bones; i++) { + D3DXMATRIX bone_inverse, matrix; + + D3DXMatrixInverse(&bone_inverse, NULL, &skin->bones[i].transform); + D3DXMatrixMultiply(&matrix, &skin->bones[i].transform, &bone_transforms[i]); + + for (j = 0; j < skin->bones[i].num_influences; j++) { + D3DXVECTOR3 normal; + D3DXVECTOR3 *normal_src = (D3DXVECTOR3*)((BYTE*)src_vertices + size * skin->bones[i].vertices[j] + sizeof(D3DXVECTOR3)); + D3DXVECTOR3 *normal_dest = (D3DXVECTOR3*)((BYTE*)dst_vertices + size * skin->bones[i].vertices[j] + sizeof(D3DXVECTOR3)); + FLOAT weight = skin->bones[i].weights[j]; + + D3DXVec3TransformNormal(&normal, normal_src, &bone_inverse); + D3DXVec3TransformNormal(&normal, &normal, &matrix); + normal_dest->x += weight * normal.x; + normal_dest->y += weight * normal.y; + normal_dest->z += weight * normal.z; + } + } + + /* Normalize all normals that are influenced by bones*/ + for (i = 0; i < skin->num_vertices; i++) { + D3DXVECTOR3 *normal_dest = (D3DXVECTOR3*)((BYTE*)dst_vertices + (i * size) + sizeof(D3DXVECTOR3)); + if ((normal_dest->x != 0.0f) && (normal_dest->y != 0.0f) && (normal_dest->z != 0.0f)) + D3DXVec3Normalize(normal_dest, normal_dest); + } + } + + return D3D_OK; }
static HRESULT WINAPI d3dx9_skin_info_ConvertToBlendedMesh(ID3DXSkinInfo *iface, ID3DXMesh *mesh_in, @@ -490,3 +575,23 @@ HRESULT WINAPI D3DXCreateSkinInfoFVF(DWORD num_vertices, DWORD fvf, DWORD num_bo
return D3DXCreateSkinInfo(num_vertices, declaration, num_bones, skin_info); } + +HRESULT create_dummy_skin(ID3DXSkinInfo **iface) +{ + static const D3DVERTEXELEMENT9 empty_declaration = D3DDECL_END(); + struct d3dx9_skin_info *object = NULL; + + object = HeapAlloc(GetProcessHeap(), 0, sizeof(*object)); + if (!object) return E_OUTOFMEMORY; + + object->ID3DXSkinInfo_iface.lpVtbl = &d3dx9_skin_info_vtbl; + object->ref = 1; + object->num_vertices = 0; + object->num_bones = 0; + object->vertex_declaration[0] = empty_declaration; + object->fvf = 0; + object->bones = NULL; + + *iface = &object->ID3DXSkinInfo_iface; + return D3D_OK; +} diff --git a/dll/directx/wine/d3dx9_36/sprite.c b/dll/directx/wine/d3dx9_36/sprite.c index ba7181b42e..2ff2b415c8 100644 --- a/dll/directx/wine/d3dx9_36/sprite.c +++ b/dll/directx/wine/d3dx9_36/sprite.c @@ -17,7 +17,12 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
/* the combination of all possible D3DXSPRITE flags */ #define D3DXSPRITE_FLAGLIMIT 511 diff --git a/dll/directx/wine/d3dx9_36/surface.c b/dll/directx/wine/d3dx9_36/surface.c index 321265fbaa..a1e56bda6d 100644 --- a/dll/directx/wine/d3dx9_36/surface.c +++ b/dll/directx/wine/d3dx9_36/surface.c @@ -18,13 +18,19 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h"
-#include <ole2.h> -#include <wine/wined3d.h> +#include "d3dx9_private.h" + +#include "initguid.h" +#include "ole2.h" +#include "wincodec.h" + +#include "wine/wined3d.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
-#include <initguid.h> -#include <wincodec.h>
/* Wine-specific WIC GUIDs */ DEFINE_GUID(GUID_WineContainerFormatTga, 0x0c44fda1,0xa5c5,0x4298,0x96,0x85,0x47,0x3f,0xc1,0x7c,0xd3,0x22); @@ -49,7 +55,7 @@ static D3DFORMAT wic_guid_to_d3dformat(const GUID *guid) { unsigned int i;
- for (i = 0; i < sizeof(wic_pixel_formats) / sizeof(wic_pixel_formats[0]); i++) + for (i = 0; i < ARRAY_SIZE(wic_pixel_formats); i++) { if (IsEqualGUID(wic_pixel_formats[i].wic_guid, guid)) return wic_pixel_formats[i].d3dformat; @@ -62,7 +68,7 @@ static const GUID *d3dformat_to_wic_guid(D3DFORMAT format) { unsigned int i;
- for (i = 0; i < sizeof(wic_pixel_formats) / sizeof(wic_pixel_formats[0]); i++) + for (i = 0; i < ARRAY_SIZE(wic_pixel_formats); i++) { if (wic_pixel_formats[i].d3dformat == format) return wic_pixel_formats[i].wic_guid; @@ -106,6 +112,7 @@ static const GUID *d3dformat_to_wic_guid(D3DFORMAT format) #define DDS_PF_RGB 0x40 #define DDS_PF_YUV 0x200 #define DDS_PF_LUMINANCE 0x20000 +#define DDS_PF_BUMPLUMINANCE 0x40000 #define DDS_PF_BUMPDUDV 0x80000
struct dds_pixel_format @@ -160,7 +167,7 @@ static D3DFORMAT dds_fourcc_to_d3dformat(DWORD fourcc) D3DFMT_A32B32G32R32F, };
- for (i = 0; i < sizeof(known_fourcc) / sizeof(known_fourcc[0]); i++) + for (i = 0; i < ARRAY_SIZE(known_fourcc); i++) { if (known_fourcc[i] == fourcc) return fourcc; @@ -199,7 +206,7 @@ static D3DFORMAT dds_rgb_to_d3dformat(const struct dds_pixel_format *pixel_forma { unsigned int i;
- for (i = 0; i < sizeof(rgb_pixel_formats) / sizeof(rgb_pixel_formats[0]); i++) + for (i = 0; i < ARRAY_SIZE(rgb_pixel_formats); i++) { if (rgb_pixel_formats[i].bpp == pixel_format->bpp && rgb_pixel_formats[i].rmask == pixel_format->rmask @@ -261,6 +268,17 @@ static D3DFORMAT dds_bump_to_d3dformat(const struct dds_pixel_format *pixel_form return D3DFMT_UNKNOWN; }
+static D3DFORMAT dds_bump_luminance_to_d3dformat(const struct dds_pixel_format *pixel_format) +{ + if (pixel_format->bpp == 32 && pixel_format->rmask == 0x000000ff && pixel_format->gmask == 0x0000ff00 + && pixel_format->bmask == 0x00ff0000) + return D3DFMT_X8L8V8U8; + + WARN("Unknown bump pixel format (%u, %#x, %#x, %#x, %#x)\n", pixel_format->bpp, + pixel_format->rmask, pixel_format->gmask, pixel_format->bmask, pixel_format->amask); + return D3DFMT_UNKNOWN; +} + static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pixel_format) { TRACE("pixel_format: size %u, flags %#x, fourcc %#x, bpp %u.\n", pixel_format->size, @@ -278,6 +296,8 @@ static D3DFORMAT dds_pixel_format_to_d3dformat(const struct dds_pixel_format *pi return dds_alpha_to_d3dformat(pixel_format); if (pixel_format->flags & DDS_PF_BUMPDUDV) return dds_bump_to_d3dformat(pixel_format); + if (pixel_format->flags & DDS_PF_BUMPLUMINANCE) + return dds_bump_luminance_to_d3dformat(pixel_format);
WARN("Unknown pixel format (flags %#x, fourcc %#x, bpp %u, r %#x, g %#x, b %#x, a %#x)\n", pixel_format->flags, pixel_format->fourcc, pixel_format->bpp, @@ -293,7 +313,7 @@ static HRESULT d3dformat_to_dds_pixel_format(struct dds_pixel_format *pixel_form
pixel_format->size = sizeof(*pixel_format);
- for (i = 0; i < sizeof(rgb_pixel_formats) / sizeof(rgb_pixel_formats[0]); i++) + for (i = 0; i < ARRAY_SIZE(rgb_pixel_formats); i++) { if (rgb_pixel_formats[i].format == d3dformat) { @@ -308,6 +328,14 @@ static HRESULT d3dformat_to_dds_pixel_format(struct dds_pixel_format *pixel_form } }
+ /* Reuse dds_fourcc_to_d3dformat as D3DFORMAT and FOURCC are DWORD with same values */ + if (dds_fourcc_to_d3dformat(d3dformat) != D3DFMT_UNKNOWN) + { + pixel_format->flags |= DDS_PF_FOURCC; + pixel_format->fourcc = d3dformat; + return D3D_OK; + } + WARN("Unknown pixel format %#x\n", d3dformat); return E_NOTIMPL; } @@ -516,6 +544,68 @@ static HRESULT save_dds_surface_to_memory(ID3DXBuffer **dst_buffer, IDirect3DSur return D3D_OK; }
+static HRESULT get_surface(D3DRESOURCETYPE type, struct IDirect3DBaseTexture9 *tex, + int face, UINT level, struct IDirect3DSurface9 **surf) +{ + switch (type) + { + case D3DRTYPE_TEXTURE: + return IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9*) tex, level, surf); + case D3DRTYPE_CUBETEXTURE: + return IDirect3DCubeTexture9_GetCubeMapSurface((IDirect3DCubeTexture9*) tex, face, level, surf); + default: + ERR("Unexpected texture type\n"); + return E_NOTIMPL; + } +} + +HRESULT save_dds_texture_to_memory(ID3DXBuffer **dst_buffer, IDirect3DBaseTexture9 *src_texture, const PALETTEENTRY *src_palette) +{ + HRESULT hr; + D3DRESOURCETYPE type; + UINT mip_levels; + IDirect3DSurface9 *surface; + + type = IDirect3DBaseTexture9_GetType(src_texture); + + if ((type != D3DRTYPE_TEXTURE) && (type != D3DRTYPE_CUBETEXTURE) && (type != D3DRTYPE_VOLUMETEXTURE)) + return D3DERR_INVALIDCALL; + + if (type == D3DRTYPE_CUBETEXTURE) + { + FIXME("Cube texture not supported yet\n"); + return E_NOTIMPL; + } + else if (type == D3DRTYPE_VOLUMETEXTURE) + { + FIXME("Volume texture not supported yet\n"); + return E_NOTIMPL; + } + + mip_levels = IDirect3DTexture9_GetLevelCount(src_texture); + + if (mip_levels > 1) + { + FIXME("Mipmap not supported yet\n"); + return E_NOTIMPL; + } + + if (src_palette) + { + FIXME("Saving surfaces with palettized pixel formats not implemented yet\n"); + return E_NOTIMPL; + } + + hr = get_surface(type, src_texture, D3DCUBEMAP_FACE_POSITIVE_X, 0, &surface); + + if (SUCCEEDED(hr)) + { + hr = save_dds_surface_to_memory(dst_buffer, surface, NULL); + IDirect3DSurface9_Release(surface); + } + + return hr; +} HRESULT load_volume_from_dds(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, const D3DBOX *dst_box, const void *src_data, const D3DBOX *src_box, DWORD filter, D3DCOLOR color_key, const D3DXIMAGE_INFO *src_info) @@ -883,6 +973,24 @@ HRESULT WINAPI D3DXGetImageInfoFromFileInMemory(const void *data, UINT datasize, } }
+ /* For 32 bpp BMP, windowscodecs.dll never returns a format with alpha while + * d3dx9_xx.dll returns one if at least 1 pixel has a non zero alpha component */ + if (SUCCEEDED(hr) && (info->Format == D3DFMT_X8R8G8B8) && (info->ImageFileFormat == D3DXIFF_BMP)) { + DWORD size = sizeof(DWORD) * info->Width * info->Height; + BYTE *buffer = HeapAlloc(GetProcessHeap(), 0, size); + hr = IWICBitmapFrameDecode_CopyPixels(frame, NULL, sizeof(DWORD) * info->Width, size, buffer); + if (SUCCEEDED(hr)) { + DWORD i; + for (i = 0; i < info->Width * info->Height; i++) { + if (buffer[i*4+3]) { + info->Format = D3DFMT_A8R8G8B8; + break; + } + } + } + HeapFree(GetProcessHeap(), 0, buffer); + } + if (frame) IWICBitmapFrameDecode_Release(frame);
@@ -1711,6 +1819,27 @@ void point_filter_argb_pixels(const BYTE *src, UINT src_row_pitch, UINT src_slic } }
+typedef BOOL (*dxtn_conversion_func)(const BYTE *src, BYTE *dst, DWORD pitch_in, DWORD pitch_out, + enum wined3d_format_id format, unsigned int w, unsigned int h); + +static dxtn_conversion_func get_dxtn_conversion_func(D3DFORMAT format, BOOL encode) +{ + switch (format) + { + case D3DFMT_DXT1: + if (!wined3d_dxtn_supported()) return NULL; + return encode ? wined3d_dxt1_encode : wined3d_dxt1_decode; + case D3DFMT_DXT3: + if (!wined3d_dxtn_supported()) return NULL; + return encode ? wined3d_dxt3_encode : wined3d_dxt3_decode; + case D3DFMT_DXT5: + if (!wined3d_dxtn_supported()) return NULL; + return encode ? wined3d_dxt5_encode : wined3d_dxt5_decode; + default: + return NULL; + } +} + /************************************************************ * D3DXLoadSurfaceFromMemory * @@ -1752,6 +1881,7 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, D3DSURFACE_DESC surfdesc; D3DLOCKED_RECT lockrect; struct volume src_size, dst_size; + HRESULT ret = D3D_OK;
TRACE("(%p, %p, %s, %p, %#x, %u, %p, %s, %#x, 0x%08x)\n", dst_surface, dst_palette, wine_dbgstr_rect(dst_rect), src_memory, src_format, @@ -1833,8 +1963,15 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, } else /* Stretching or format conversion. */ { - if (!is_conversion_from_supported(srcformatdesc) - || !is_conversion_to_supported(destformatdesc)) + dxtn_conversion_func pre_convert, post_convert; + void *tmp_src_memory = NULL, *tmp_dst_memory = NULL; + UINT tmp_src_pitch, tmp_dst_pitch; + + pre_convert = get_dxtn_conversion_func(srcformatdesc->format, FALSE); + post_convert = get_dxtn_conversion_func(destformatdesc->format, TRUE); + + if ((!pre_convert && !is_conversion_from_supported(srcformatdesc)) || + (!post_convert && !is_conversion_to_supported(destformatdesc))) { FIXME("Unsupported format conversion %#x -> %#x.\n", src_format, surfdesc.Format); return E_NOTIMPL; @@ -1843,10 +1980,52 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface, if (FAILED(IDirect3DSurface9_LockRect(dst_surface, &lockrect, dst_rect, 0))) return D3DXERR_INVALIDDATA;
+ /* handle pre-conversion */ + if (pre_convert) + { + tmp_src_memory = HeapAlloc(GetProcessHeap(), 0, src_size.width * src_size.height * sizeof(DWORD)); + if (!tmp_src_memory) + { + ret = E_OUTOFMEMORY; + goto error; + } + tmp_src_pitch = src_size.width * sizeof(DWORD); + if (!pre_convert(src_memory, tmp_src_memory, src_pitch, tmp_src_pitch, + WINED3DFMT_B8G8R8A8_UNORM, src_size.width, src_size.height)) + { + ret = E_FAIL; + goto error; + } + srcformatdesc = get_format_info(D3DFMT_A8R8G8B8); + } + else + { + tmp_src_memory = (void *)src_memory; + tmp_src_pitch = src_pitch; + } + + /* handle post-conversion */ + if (post_convert) + { + tmp_dst_memory = HeapAlloc(GetProcessHeap(), 0, dst_size.width * dst_size.height * sizeof(DWORD)); + if (!tmp_dst_memory) + { + ret = E_OUTOFMEMORY; + goto error; + } + tmp_dst_pitch = dst_size.width * sizeof(DWORD); + destformatdesc = get_format_info(D3DFMT_A8R8G8B8); + } + else + { + tmp_dst_memory = lockrect.pBits; + tmp_dst_pitch = lockrect.Pitch; + } + if ((filter & 0xf) == D3DX_FILTER_NONE) { - convert_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc, - lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette); + convert_argb_pixels(tmp_src_memory, tmp_src_pitch, 0, &src_size, srcformatdesc, + tmp_dst_memory, tmp_dst_pitch, 0, &dst_size, destformatdesc, color_key, src_palette); } else /* if ((filter & 0xf) == D3DX_FILTER_POINT) */ { @@ -1855,14 +2034,30 @@ HRESULT WINAPI D3DXLoadSurfaceFromMemory(IDirect3DSurface9 *dst_surface,
/* Always apply a point filter until D3DX_FILTER_LINEAR, * D3DX_FILTER_TRIANGLE and D3DX_FILTER_BOX are implemented. */ - point_filter_argb_pixels(src_memory, src_pitch, 0, &src_size, srcformatdesc, - lockrect.pBits, lockrect.Pitch, 0, &dst_size, destformatdesc, color_key, src_palette); + point_filter_argb_pixels(tmp_src_memory, tmp_src_pitch, 0, &src_size, srcformatdesc, + tmp_dst_memory, tmp_dst_pitch, 0, &dst_size, destformatdesc, color_key, src_palette); }
+ /* handle post-conversion */ + if (post_convert) + { + if (!post_convert(tmp_dst_memory, lockrect.pBits, tmp_dst_pitch, lockrect.Pitch, + WINED3DFMT_B8G8R8A8_UNORM, dst_size.width, dst_size.height)) + { + ret = E_FAIL; + goto error; + } + } + +error: + if (pre_convert) + HeapFree(GetProcessHeap(), 0, tmp_src_memory); + if (post_convert) + HeapFree(GetProcessHeap(), 0, tmp_dst_memory); IDirect3DSurface9_UnlockRect(dst_surface); }
- return D3D_OK; + return ret; }
/************************************************************ diff --git a/dll/directx/wine/d3dx9_36/texture.c b/dll/directx/wine/d3dx9_36/texture.c index f4e3231483..fa5ccfc66e 100644 --- a/dll/directx/wine/d3dx9_36/texture.c +++ b/dll/directx/wine/d3dx9_36/texture.c @@ -19,7 +19,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
/* Returns TRUE if num is a power of 2, FALSE if not, or if 0 */ static BOOL is_pow2(UINT num) @@ -195,7 +200,7 @@ static D3DFORMAT get_luminance_replacement_format(D3DFORMAT format) }; unsigned int i;
- for (i = 0; i < sizeof(luminance_replacements) / sizeof(luminance_replacements[0]); ++i) + for (i = 0; i < ARRAY_SIZE(luminance_replacements); ++i) if (format == luminance_replacements[i].luminance_format) return luminance_replacements[i].replacement_format; return format; @@ -330,10 +335,10 @@ HRESULT WINAPI D3DXCheckTextureRequirements(struct IDirect3DDevice9 *device, UIN
if (fmt->block_width != 1 || fmt->block_height != 1) { - if (w < fmt->block_width) - w = fmt->block_width; - if (h < fmt->block_height) - h = fmt->block_height; + if (w % fmt->block_width) + w += fmt->block_width - w % fmt->block_width; + if (h % fmt->block_height) + h += fmt->block_height - h % fmt->block_height; }
if ((caps.TextureCaps & D3DPTEXTURECAPS_POW2) && (!is_pow2(w))) @@ -552,7 +557,7 @@ static D3DFORMAT get_alpha_replacement_format(D3DFORMAT format) }; unsigned int i;
- for (i = 0; i < sizeof(replacement_formats) / sizeof(replacement_formats[0]); ++i) + for (i = 0; i < ARRAY_SIZE(replacement_formats); ++i) if (replacement_formats[i].orig_format == format) return replacement_formats[i].replacement_format; return format; @@ -1887,10 +1892,7 @@ HRESULT WINAPI D3DXSaveTextureToFileInMemory(ID3DXBuffer **dst_buffer, D3DXIMAGE if (!dst_buffer || !src_texture) return D3DERR_INVALIDCALL;
if (file_format == D3DXIFF_DDS) - { - FIXME("DDS file format isn't supported yet\n"); - return E_NOTIMPL; - } + return save_dds_texture_to_memory(dst_buffer, src_texture, src_palette);
type = IDirect3DBaseTexture9_GetType(src_texture); switch (type) diff --git a/dll/directx/wine/d3dx9_36/util.c b/dll/directx/wine/d3dx9_36/util.c index 47f9637d83..029e50073c 100644 --- a/dll/directx/wine/d3dx9_36/util.c +++ b/dll/directx/wine/d3dx9_36/util.c @@ -17,7 +17,12 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
static void la_from_rgba(const struct vec4 *rgba, struct vec4 *la) { @@ -85,6 +90,7 @@ static const struct pixel_format_desc formats[] = {D3DFMT_G32R32F, { 0, 32, 32, 0}, { 0, 0, 32, 0}, 8, 1, 1, 8, FORMAT_ARGBF, NULL, NULL }, {D3DFMT_A32B32G32R32F, {32, 32, 32, 32}, {96, 0, 32, 64}, 16, 1, 1, 16, FORMAT_ARGBF, NULL, NULL }, {D3DFMT_P8, { 8, 8, 8, 8}, { 0, 0, 0, 0}, 1, 1, 1, 1, FORMAT_INDEX, NULL, index_to_rgba}, + {D3DFMT_X8L8V8U8, { 0, 8, 8, 8}, { 0, 0, 8, 16}, 4, 1, 1, 4, FORMAT_ARGB, NULL, NULL }, /* marks last element */ {D3DFMT_UNKNOWN, { 0, 0, 0, 0}, { 0, 0, 0, 0}, 0, 1, 1, 0, FORMAT_UNKNOWN, NULL, NULL }, }; @@ -215,7 +221,7 @@ const struct pixel_format_desc *get_format_info(D3DFORMAT format)
const struct pixel_format_desc *get_format_info_idx(int idx) { - if(idx >= sizeof(formats) / sizeof(formats[0])) + if(idx >= ARRAY_SIZE(formats)) return NULL; if(formats[idx].format == D3DFMT_UNKNOWN) return NULL; diff --git a/dll/directx/wine/d3dx9_36/volume.c b/dll/directx/wine/d3dx9_36/volume.c index c72dfc5708..f07e552dbe 100644 --- a/dll/directx/wine/d3dx9_36/volume.c +++ b/dll/directx/wine/d3dx9_36/volume.c @@ -16,7 +16,12 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h" + +#include "d3dx9_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
HRESULT WINAPI D3DXLoadVolumeFromFileA(IDirect3DVolume9 *dst_volume, const PALETTEENTRY *dst_palette, diff --git a/dll/directx/wine/d3dx9_36/xfile.c b/dll/directx/wine/d3dx9_36/xfile.c index 795b7bc3ff..157545482b 100644 --- a/dll/directx/wine/d3dx9_36/xfile.c +++ b/dll/directx/wine/d3dx9_36/xfile.c @@ -17,9 +17,15 @@ * */
-#include "d3dx9_36_private.h" +#include "config.h" +#include "wine/port.h"
-#include <dxfile.h> +#include "d3dx9_private.h" +#include "d3dx9xof.h" +#undef MAKE_DDHRESULT +#include "dxfile.h" + +WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
static HRESULT error_dxfile_to_d3dxfile(HRESULT error) { diff --git a/media/doc/README.WINE b/media/doc/README.WINE index 5e789914d8..1f00297ce1 100644 --- a/media/doc/README.WINE +++ b/media/doc/README.WINE @@ -26,7 +26,7 @@ reactos/dll/directx/wine/d3d8 # Synced to WineStaging-3.3 reactos/dll/directx/wine/d3d9 # Synced to WineStaging-3.3 reactos/dll/directx/wine/d3dcompiler_43 # Synced to WineStaging-3.3 reactos/dll/directx/wine/d3drm # Synced to WineStaging-3.3 -reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to Wine-3.0 +reactos/dll/directx/wine/d3dx9_24 => 43 # Synced to WineStaging-3.3 reactos/dll/directx/wine/d3dxof # Synced to WineStaging-2.9 reactos/dll/directx/wine/ddraw # Synced to WineStaging-3.3 reactos/dll/directx/wine/devenum # Synced to Wine-3.0