From 3cf93b92fcb2c0043bd0df9178e4402f33ec5938 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Fri, 31 Oct 2014 15:05:38 +0100 Subject: [PATCH] Added patch to implement D3DXCreatePolygon. --- README.md | 3 +- debian/changelog | 1 + patches/Makefile | 24 ++- ...d3dx9_36-Implement-D3DXCreatePolygon.patch | 141 +++++++++++++ ...ests-Add-tests-for-D3DXCreatePolygon.patch | 185 ++++++++++++++++++ patches/d3dx9_36-CreatePolygon/definition | 4 + .../d3dx9_36-GetShaderSemantics/definition | 2 +- 7 files changed, 356 insertions(+), 4 deletions(-) create mode 100644 patches/d3dx9_36-CreatePolygon/0001-d3dx9_36-Implement-D3DXCreatePolygon.patch create mode 100644 patches/d3dx9_36-CreatePolygon/0002-d3dx9_36-tests-Add-tests-for-D3DXCreatePolygon.patch create mode 100644 patches/d3dx9_36-CreatePolygon/definition diff --git a/README.md b/README.md index e0eb33a4..4af8e6fd 100644 --- a/README.md +++ b/README.md @@ -35,11 +35,12 @@ Wine. All those differences are also documented on the Included bugfixes and improvements ================================== -**Bugfixes and features included in the next upcoming release [7]:** +**Bugfixes and features included in the next upcoming release [8]:** * Cinema 4D needs NotifyIpInterfaceChange ([Wine Bug #34573](http://bugs.winehq.org/show_bug.cgi?id=34573)) * D3DCompileShader should filter specific warning messages ([Wine Bug #33770](http://bugs.winehq.org/show_bug.cgi?id=33770)) * Emulate write to CR4 register ([Wine Bug #30220](http://bugs.winehq.org/show_bug.cgi?id=30220)) +* Support for D3DXCreatePolygon ([Wine Bug #13632](http://bugs.winehq.org/show_bug.cgi?id=13632)) * Support for GdipCreateRegionRgnData ([Wine Bug #34843](http://bugs.winehq.org/show_bug.cgi?id=34843)) * Support for RtlDecompressBuffer ([Wine Bug #37449](http://bugs.winehq.org/show_bug.cgi?id=37449)) * Support for pasting HTML from Unix applications ([Wine Bug #7372](http://bugs.winehq.org/show_bug.cgi?id=7372)) diff --git a/debian/changelog b/debian/changelog index b5c80cbf..4c845d46 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ wine-compholio (1.7.30) UNRELEASED; urgency=low * Added patch to implement RtlDecompressBuffer. * Added patch to emulate write to CR4 register. * Added patch for implementation of GdipCreateRegionRgnData. + * Added patch for implementation of D3DXCreatePolygon. * Removed patch to avoid Clang compiler warning because of unused Vtable (accepted upstream). * Removed patch for additional ATL thunks (accepted upstream). * Removed patch to ímplement IRichEditOle and ITextDocument support for ITextServices (accepted upstream). diff --git a/patches/Makefile b/patches/Makefile index a612ba9a..a8dcb8fd 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -26,6 +26,7 @@ PATCHLIST := \ comctl32-LoadIconMetric.ok \ configure-Absolute_RPATH.ok \ configure-Detect_Gnutls.ok \ + d3dx9_36-CreatePolygon.ok \ d3dx9_36-Filter_Warnings.ok \ d3dx9_36-GetShaderSemantics.ok \ d3dx9_36-UpdateSkinnedMesh.ok \ @@ -303,6 +304,25 @@ configure-Detect_Gnutls.ok: echo '+ { "configure-Detect_Gnutls", "Sebastian Lackner", "Fix detection of gnutls on Ubuntu 14.10. [rev 3]" },'; \ ) > configure-Detect_Gnutls.ok +# Patchset d3dx9_36-CreatePolygon +# | +# | Included patches: +# | * Implement D3DXCreatePolygon. [by Sebastian Lackner] +# | +# | This patchset fixes the following Wine bugs: +# | * [#13632] Support for D3DXCreatePolygon +# | +# | Modified files: +# | * dlls/d3dx9_36/d3dx9_36.spec, dlls/d3dx9_36/mesh.c, dlls/d3dx9_36/tests/mesh.c, include/d3dx9shape.h +# | +.INTERMEDIATE: d3dx9_36-CreatePolygon.ok +d3dx9_36-CreatePolygon.ok: + $(call APPLY_FILE,d3dx9_36-CreatePolygon/0001-d3dx9_36-Implement-D3DXCreatePolygon.patch) + $(call APPLY_FILE,d3dx9_36-CreatePolygon/0002-d3dx9_36-tests-Add-tests-for-D3DXCreatePolygon.patch) + @( \ + echo '+ { "d3dx9_36-CreatePolygon", "Sebastian Lackner", "Implement D3DXCreatePolygon." },'; \ + ) > d3dx9_36-CreatePolygon.ok + # Patchset d3dx9_36-Filter_Warnings # | # | Included patches: @@ -324,7 +344,7 @@ d3dx9_36-Filter_Warnings.ok: # Patchset d3dx9_36-GetShaderSemantics # | # | Included patches: -# | * Implement D3DXGetShaderInputSemantics [by Christian Costa] +# | * Implement D3DXGetShaderInputSemantics. [by Christian Costa] # | # | This patchset fixes the following Wine bugs: # | * [#22682] Support for D3DXGetShaderInputSemantics @@ -336,7 +356,7 @@ d3dx9_36-Filter_Warnings.ok: d3dx9_36-GetShaderSemantics.ok: $(call APPLY_FILE,d3dx9_36-GetShaderSemantics/0001-d3dx9_36-Implement-D3DXGetShaderInputSemantics-tests.patch) @( \ - echo '+ { "d3dx9_36-GetShaderSemantics", "Christian Costa", "Implement D3DXGetShaderInputSemantics" },'; \ + echo '+ { "d3dx9_36-GetShaderSemantics", "Christian Costa", "Implement D3DXGetShaderInputSemantics." },'; \ ) > d3dx9_36-GetShaderSemantics.ok # Patchset d3dx9_36-UpdateSkinnedMesh diff --git a/patches/d3dx9_36-CreatePolygon/0001-d3dx9_36-Implement-D3DXCreatePolygon.patch b/patches/d3dx9_36-CreatePolygon/0001-d3dx9_36-Implement-D3DXCreatePolygon.patch new file mode 100644 index 00000000..d2f210a8 --- /dev/null +++ b/patches/d3dx9_36-CreatePolygon/0001-d3dx9_36-Implement-D3DXCreatePolygon.patch @@ -0,0 +1,141 @@ +From 0daaeab7e4e9b36cafbeb3fe296a1d62cd79c20b Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Fri, 31 Oct 2014 09:43:40 +0100 +Subject: d3dx9_36: Implement D3DXCreatePolygon. + +Based on a patch by David Adam. +--- + dlls/d3dx9_36/d3dx9_36.spec | 2 +- + dlls/d3dx9_36/mesh.c | 89 +++++++++++++++++++++++++++++++++++++++++++++ + include/d3dx9shape.h | 2 + + 3 files changed, 92 insertions(+), 1 deletion(-) + +diff --git a/dlls/d3dx9_36/d3dx9_36.spec b/dlls/d3dx9_36/d3dx9_36.spec +index 4c72dc2..ebe46dc 100644 +--- a/dlls/d3dx9_36/d3dx9_36.spec ++++ b/dlls/d3dx9_36/d3dx9_36.spec +@@ -76,7 +76,7 @@ + @ stub D3DXCreateNPatchMesh(ptr ptr) + @ stub D3DXCreatePMeshFromStream(ptr long ptr ptr ptr ptr ptr) + @ stub D3DXCreatePatchMesh(ptr long long long ptr ptr ptr) +-@ stub D3DXCreatePolygon(ptr long long ptr ptr) ++@ stdcall D3DXCreatePolygon(ptr long long ptr ptr) + @ stub D3DXCreatePRTBuffer(long long long ptr) + @ stub D3DXCreatePRTBufferTex(long long long long ptr) + @ stub D3DXCreatePRTCompBuffer(long long long ptr ptr ptr ptr) +diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c +index aecb45d..9bd24e4 100644 +--- a/dlls/d3dx9_36/mesh.c ++++ b/dlls/d3dx9_36/mesh.c +@@ -4555,6 +4555,95 @@ struct vertex + D3DXVECTOR3 normal; + }; + ++HRESULT WINAPI D3DXCreatePolygon(struct IDirect3DDevice9 *device, float length, UINT sides, ++ struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency) ++{ ++ HRESULT hr; ++ ID3DXMesh *polygon; ++ struct vertex *vertices; ++ WORD (*faces)[3]; ++ DWORD (*adjacency_buf)[3]; ++ float scale; ++ unsigned int i; ++ ++ TRACE("(%p, %f, %u, %p, %p)\n", device, length, sides, mesh, adjacency); ++ ++ if (!device || length < 0.0f || sides == 0 || !mesh) ++ { ++ return D3DERR_INVALIDCALL; ++ } ++ ++ if (FAILED(hr = D3DXCreateMeshFVF(sides, sides + 1, D3DXMESH_MANAGED, ++ D3DFVF_XYZ | D3DFVF_NORMAL,device, &polygon))) ++ { ++ return hr; ++ } ++ ++ if (FAILED(hr = polygon->lpVtbl->LockVertexBuffer(polygon, 0, (void **)&vertices))) ++ { ++ polygon->lpVtbl->Release(polygon); ++ return hr; ++ } ++ ++ if (FAILED(hr = polygon->lpVtbl->LockIndexBuffer(polygon, 0, (void **)&faces))) ++ { ++ polygon->lpVtbl->UnlockVertexBuffer(polygon); ++ polygon->lpVtbl->Release(polygon); ++ return hr; ++ } ++ ++ scale = 0.5f * length / sin(D3DX_PI / sides); ++ ++ vertices[0].position.x = 0.0f; ++ vertices[0].position.y = 0.0f; ++ vertices[0].position.z = 0.0f; ++ vertices[0].normal.x = 0.0f; ++ vertices[0].normal.y = 0.0f; ++ vertices[0].normal.z = 1.0f; ++ ++ for (i = 0; i < sides; i++) ++ { ++ vertices[i + 1].position.x = cos(2.0f * D3DX_PI * i / sides) * scale; ++ vertices[i + 1].position.y = sin(2.0f * D3DX_PI * i / sides) * scale; ++ vertices[i + 1].position.z = 0.0f; ++ vertices[i + 1].normal.x = 0.0f; ++ vertices[i + 1].normal.y = 0.0f; ++ vertices[i + 1].normal.z = 1.0f; ++ ++ faces[i][0] = 0; ++ faces[i][1] = i + 1; ++ faces[i][2] = i + 2; ++ } ++ ++ faces[sides - 1][2] = 1; ++ ++ polygon->lpVtbl->UnlockVertexBuffer(polygon); ++ polygon->lpVtbl->UnlockIndexBuffer(polygon); ++ ++ if (adjacency) ++ { ++ if (FAILED(hr = D3DXCreateBuffer(sides * sizeof(DWORD) * 3, adjacency))) ++ { ++ polygon->lpVtbl->Release(polygon); ++ return hr; ++ } ++ ++ adjacency_buf = ID3DXBuffer_GetBufferPointer(*adjacency); ++ for (i = 0; i < sides; i++) ++ { ++ adjacency_buf[i][0] = i - 1; ++ adjacency_buf[i][1] = -1; ++ adjacency_buf[i][2] = i + 1; ++ } ++ adjacency_buf[0][0] = sides - 1; ++ adjacency_buf[sides - 1][2] = 0; ++ } ++ ++ *mesh = polygon; ++ ++ return D3D_OK; ++} ++ + HRESULT WINAPI D3DXCreateBox(struct IDirect3DDevice9 *device, float width, float height, + float depth, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency) + { +diff --git a/include/d3dx9shape.h b/include/d3dx9shape.h +index 0d24032..af49bb4 100644 +--- a/include/d3dx9shape.h ++++ b/include/d3dx9shape.h +@@ -29,6 +29,8 @@ HRESULT WINAPI D3DXCreateBox(struct IDirect3DDevice9 *device, float width, float + float depth, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency); + HRESULT WINAPI D3DXCreateCylinder(struct IDirect3DDevice9 *device, float radius1, float radius2, + float length, UINT slices, UINT stacks, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency); ++HRESULT WINAPI D3DXCreatePolygon(struct IDirect3DDevice9 *device, float length, UINT sides, struct ID3DXMesh **mesh, ++ ID3DXBuffer **adjacency); + HRESULT WINAPI D3DXCreateSphere(struct IDirect3DDevice9 *device, float radius, UINT slices, + UINT stacks, struct ID3DXMesh **mesh, struct ID3DXBuffer **adjacency); + HRESULT WINAPI D3DXCreateTeapot(struct IDirect3DDevice9 *device, +-- +2.1.2 + diff --git a/patches/d3dx9_36-CreatePolygon/0002-d3dx9_36-tests-Add-tests-for-D3DXCreatePolygon.patch b/patches/d3dx9_36-CreatePolygon/0002-d3dx9_36-tests-Add-tests-for-D3DXCreatePolygon.patch new file mode 100644 index 00000000..d85eb0e0 --- /dev/null +++ b/patches/d3dx9_36-CreatePolygon/0002-d3dx9_36-tests-Add-tests-for-D3DXCreatePolygon.patch @@ -0,0 +1,185 @@ +From 362624947b13048efb0577a980aa3f5306200fdc Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Fri, 31 Oct 2014 10:56:42 +0100 +Subject: d3dx9_36/tests: Add tests for D3DXCreatePolygon. + +Based on a patch by David Adam. +--- + dlls/d3dx9_36/tests/mesh.c | 154 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 154 insertions(+) + +diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c +index 17c5d9c..9e4938c 100644 +--- a/dlls/d3dx9_36/tests/mesh.c ++++ b/dlls/d3dx9_36/tests/mesh.c +@@ -2600,6 +2600,159 @@ end: + DestroyWindow(wnd); + } + ++static BOOL compute_polygon(struct mesh *mesh, float length, UINT sides) ++{ ++ unsigned int i; ++ float scale; ++ ++ if (!new_mesh(mesh, sides + 1, sides)) ++ return FALSE; ++ ++ scale = 0.5f * length / sin(D3DX_PI / sides); ++ ++ mesh->vertices[0].position.x = 0.0f; ++ mesh->vertices[0].position.y = 0.0f; ++ mesh->vertices[0].position.z = 0.0f; ++ mesh->vertices[0].normal.x = 0.0f; ++ mesh->vertices[0].normal.y = 0.0f; ++ mesh->vertices[0].normal.z = 1.0f; ++ ++ for (i = 0; i < sides; i++) ++ { ++ mesh->vertices[i + 1].position.x = cos(2.0f * D3DX_PI * i / sides) * scale; ++ mesh->vertices[i + 1].position.y = sin(2.0f * D3DX_PI * i / sides) * scale; ++ mesh->vertices[i + 1].position.z = 0.0f; ++ mesh->vertices[i + 1].normal.x = 0.0f; ++ mesh->vertices[i + 1].normal.y = 0.0f; ++ mesh->vertices[i + 1].normal.z = 1.0f; ++ ++ mesh->faces[i][0] = 0; ++ mesh->faces[i][1] = i + 1; ++ mesh->faces[i][2] = i + 2; ++ } ++ ++ mesh->faces[sides - 1][2] = 1; ++ ++ return TRUE; ++} ++ ++static void test_polygon(IDirect3DDevice9 *device, float length, UINT sides) ++{ ++ HRESULT hr; ++ ID3DXMesh *polygon; ++ struct mesh mesh; ++ char name[256]; ++ ++ hr = D3DXCreatePolygon(device, length, sides, &polygon, NULL); ++ ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr); ++ if (hr != D3D_OK) ++ { ++ skip("Couldn't create box\n"); ++ return; ++ } ++ ++ if (!compute_polygon(&mesh, length, sides)) ++ { ++ skip("Couldn't create mesh\n"); ++ polygon->lpVtbl->Release(polygon); ++ return; ++ } ++ ++ mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL; ++ ++ sprintf(name, "polygon (%g, %d)", length, sides); ++ compare_mesh(name, polygon, &mesh); ++ ++ free_mesh(&mesh); ++ ++ polygon->lpVtbl->Release(polygon); ++} ++ ++static void D3DXCreatePolygonTest(void) ++{ ++ HRESULT hr; ++ HWND wnd; ++ IDirect3D9* d3d; ++ IDirect3DDevice9* device; ++ D3DPRESENT_PARAMETERS d3dpp; ++ ID3DXMesh* polygon; ++ ID3DXBuffer* ppBuffer; ++ DWORD (*buffer)[3], buffer_size; ++ unsigned int i; ++ ++ if (!(wnd = CreateWindowA("static", "d3dx9_test", WS_OVERLAPPEDWINDOW, 0, 0, ++ 640, 480, NULL, NULL, NULL, NULL))) ++ { ++ skip("Couldn't create application window\n"); ++ return; ++ } ++ if (!(d3d = Direct3DCreate9(D3D_SDK_VERSION))) ++ { ++ skip("Couldn't create IDirect3D9 object\n"); ++ DestroyWindow(wnd); ++ return; ++ } ++ ++ memset(&d3dpp, 0, sizeof(d3dpp)); ++ d3dpp.Windowed = TRUE; ++ d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; ++ hr = IDirect3D9_CreateDevice(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, wnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &device); ++ if (FAILED(hr)) ++ { ++ skip("Failed to create IDirect3DDevice9 object %#x\n", hr); ++ IDirect3D9_Release(d3d); ++ DestroyWindow(wnd); ++ return; ++ } ++ ++ hr = D3DXCreatePolygon(device, 2.0f, 11, NULL, &ppBuffer); ++ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr); ++ ++ hr = D3DXCreatePolygon(NULL, 2.0f, 11, &polygon, &ppBuffer); ++ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr); ++ ++ hr = D3DXCreatePolygon(device, -2.0f, 11, &polygon, &ppBuffer); ++ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr); ++ ++ hr = D3DXCreatePolygon(device, 2.0f, 0, &polygon, &ppBuffer); ++ ok(hr == D3DERR_INVALIDCALL, "Expected D3DERR_INVALIDCALL, received %#x\n", hr); ++ ++ ppBuffer = NULL; ++ hr = D3DXCreatePolygon(device, 3.0f, 11, &polygon, &ppBuffer); ++ ok(hr == D3D_OK, "Expected D3D_OK, received %#x\n", hr); ++ ++ if (FAILED(hr)) ++ { ++ skip("D3DXCreatePolygon failed\n"); ++ goto end; ++ } ++ ++ buffer_size = ID3DXBuffer_GetBufferSize(ppBuffer); ++ ok(buffer_size == 33 * sizeof(DWORD), "expected size %d, received %d\n", ++ 33 * sizeof(DWORD), buffer_size); ++ ++ buffer = ID3DXBuffer_GetBufferPointer(ppBuffer); ++ for (i = 0; i < 11; i++) ++ { ++ ok(buffer[i][0] == (i + 10) % 11, "wrong adjacency[%d][0] = %d\n", i, buffer[i][0]); ++ ok(buffer[i][1] == -1, "wrong adjacency[%d][1] = %d\n", i, buffer[i][1]); ++ ok(buffer[i][2] == (i + 1) % 11, "wrong adjacency[%d][2] = %d\n", i, buffer[i][2]); ++ } ++ ++ polygon->lpVtbl->Release(polygon); ++ ++ test_polygon(device, 10.0f, 3); ++ test_polygon(device, 10.0f, 5); ++ test_polygon(device, 10.0f, 10); ++ test_polygon(device, 20.0f, 10); ++ ++end: ++ IDirect3DDevice9_Release(device); ++ IDirect3D9_Release(d3d); ++ if (ppBuffer) ID3DXBuffer_Release(ppBuffer); ++ DestroyWindow(wnd); ++} ++ + struct sincos_table + { + float *sin; +@@ -10458,6 +10611,7 @@ START_TEST(mesh) + D3DXCreateMeshFVFTest(); + D3DXLoadMeshTest(); + D3DXCreateBoxTest(); ++ D3DXCreatePolygonTest(); + D3DXCreateSphereTest(); + D3DXCreateCylinderTest(); + D3DXCreateTextTest(); +-- +2.1.2 + diff --git a/patches/d3dx9_36-CreatePolygon/definition b/patches/d3dx9_36-CreatePolygon/definition new file mode 100644 index 00000000..b29b283b --- /dev/null +++ b/patches/d3dx9_36-CreatePolygon/definition @@ -0,0 +1,4 @@ +Author: Sebastian Lackner +Subject: Implement D3DXCreatePolygon. +Revision: 1 +Fixes: [13632] Support for D3DXCreatePolygon diff --git a/patches/d3dx9_36-GetShaderSemantics/definition b/patches/d3dx9_36-GetShaderSemantics/definition index 6489ce4c..2238e44e 100644 --- a/patches/d3dx9_36-GetShaderSemantics/definition +++ b/patches/d3dx9_36-GetShaderSemantics/definition @@ -1,4 +1,4 @@ Author: Christian Costa -Subject: Implement D3DXGetShaderInputSemantics +Subject: Implement D3DXGetShaderInputSemantics. Revision: 1 Fixes: [22682] Support for D3DXGetShaderInputSemantics