diff --git a/patches/d3dx9_animation_TrackDesc/0001-d3dx9-Implement-ID3DXAnimationController-RegisterAni.patch b/patches/d3dx9_animation_TrackDesc/0001-d3dx9-Implement-ID3DXAnimationController-RegisterAni.patch new file mode 100644 index 00000000..51e38b08 --- /dev/null +++ b/patches/d3dx9_animation_TrackDesc/0001-d3dx9-Implement-ID3DXAnimationController-RegisterAni.patch @@ -0,0 +1,93 @@ +From 78fcd523dff585ce007405bd75d459aa2c4fb13a Mon Sep 17 00:00:00 2001 +From: Connor McAdams +Date: Wed, 3 Sep 2025 13:04:51 -0400 +Subject: [PATCH] d3dx9: Implement + ID3DXAnimationController::RegisterAnimationSet(). + +Signed-off-by: Connor McAdams +--- + dlls/d3dx9_36/animation.c | 34 ++++++++++++++++++++++++++++++++-- + 1 file changed, 32 insertions(+), 2 deletions(-) + +diff --git a/dlls/d3dx9_36/animation.c b/dlls/d3dx9_36/animation.c +index 8a38c05ed0c..1bb775bc44a 100644 +--- a/dlls/d3dx9_36/animation.c ++++ b/dlls/d3dx9_36/animation.c +@@ -29,8 +29,13 @@ struct d3dx9_animation_controller + LONG ref; + + UINT max_outputs; ++ ++ ID3DXAnimationSet **animation_sets; ++ UINT num_sets; + UINT max_sets; ++ + UINT max_tracks; ++ + UINT max_events; + }; + +@@ -75,6 +80,14 @@ static ULONG WINAPI d3dx9_animation_controller_Release(ID3DXAnimationController + + if (!refcount) + { ++ unsigned int i; ++ ++ for (i = 0; i < animation->max_sets; i++) ++ { ++ if (animation->animation_sets[i]) ++ animation->animation_sets[i]->lpVtbl->Release(animation->animation_sets[i]); ++ } ++ free(animation->animation_sets); + free(animation); + } + +@@ -129,9 +142,17 @@ static HRESULT WINAPI d3dx9_animation_controller_RegisterAnimationOutput(ID3DXAn + static HRESULT WINAPI d3dx9_animation_controller_RegisterAnimationSet(ID3DXAnimationController *iface, + ID3DXAnimationSet *anim_set) + { ++ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); ++ + FIXME("iface %p, anim_set %p stub.\n", iface, anim_set); + +- return E_NOTIMPL; ++ if (!anim_set || animation->num_sets >= animation->max_sets) ++ return D3DERR_INVALIDCALL; ++ ++ animation->animation_sets[animation->num_sets++] = anim_set; ++ anim_set->lpVtbl->AddRef(anim_set); ++ ++ return D3D_OK; + } + + static HRESULT WINAPI d3dx9_animation_controller_UnregisterAnimationSet(ID3DXAnimationController *iface, +@@ -144,9 +165,11 @@ static HRESULT WINAPI d3dx9_animation_controller_UnregisterAnimationSet(ID3DXAni + + static UINT WINAPI d3dx9_animation_controller_GetNumAnimationSets(ID3DXAnimationController *iface) + { ++ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); ++ + FIXME("iface %p stub.\n", iface); + +- return 0; ++ return animation->num_sets; + } + + static HRESULT WINAPI d3dx9_animation_controller_GetAnimationSet(ID3DXAnimationController *iface, +@@ -459,6 +482,13 @@ HRESULT WINAPI D3DXCreateAnimationController(UINT max_outputs, UINT max_sets, + object->ID3DXAnimationController_iface.lpVtbl = &d3dx9_animation_controller_vtbl; + object->ref = 1; + object->max_outputs = max_outputs; ++ ++ object->animation_sets = calloc(max_sets, sizeof(*object->animation_sets)); ++ if (!object->animation_sets) ++ { ++ free(object); ++ return E_OUTOFMEMORY; ++ } + object->max_sets = max_sets; + object->max_tracks = max_tracks; + object->max_events = max_events; +-- +2.50.1 + diff --git a/patches/d3dx9_animation_TrackDesc/0002-d3dx9-Implement-ID3DXAnimationController-Get-Set-Tra.patch b/patches/d3dx9_animation_TrackDesc/0002-d3dx9-Implement-ID3DXAnimationController-Get-Set-Tra.patch new file mode 100644 index 00000000..ff49be93 --- /dev/null +++ b/patches/d3dx9_animation_TrackDesc/0002-d3dx9-Implement-ID3DXAnimationController-Get-Set-Tra.patch @@ -0,0 +1,85 @@ +From ee45504fb838a5e7bfeec350c6a7c5a318400c68 Mon Sep 17 00:00:00 2001 +From: Connor McAdams +Date: Wed, 3 Sep 2025 13:31:04 -0400 +Subject: [PATCH] d3dx9: Implement + ID3DXAnimationController::{Get,Set}TrackDesc(). + +Signed-off-by: Connor McAdams +--- + dlls/d3dx9_36/animation.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/dlls/d3dx9_36/animation.c b/dlls/d3dx9_36/animation.c +index 1bb775bc44a..6ded652930a 100644 +--- a/dlls/d3dx9_36/animation.c ++++ b/dlls/d3dx9_36/animation.c +@@ -23,6 +23,11 @@ + + WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + ++struct d3dx9_track ++{ ++ D3DXTRACK_DESC desc; ++}; ++ + struct d3dx9_animation_controller + { + ID3DXAnimationController ID3DXAnimationController_iface; +@@ -34,6 +39,7 @@ struct d3dx9_animation_controller + UINT num_sets; + UINT max_sets; + ++ struct d3dx9_track *tracks; + UINT max_tracks; + + UINT max_events; +@@ -269,17 +275,29 @@ static HRESULT WINAPI d3dx9_animation_controller_SetTrackEnable(ID3DXAnimationCo + static HRESULT WINAPI d3dx9_animation_controller_SetTrackDesc(ID3DXAnimationController *iface, + UINT track, D3DXTRACK_DESC *desc) + { ++ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); ++ + FIXME("iface %p, track %u, desc %p stub.\n", iface, track, desc); + +- return E_NOTIMPL; ++ if (track > animation->max_tracks || !desc) ++ return D3DERR_INVALIDCALL; ++ ++ animation->tracks[track].desc = *desc; ++ return D3D_OK; + } + + static HRESULT WINAPI d3dx9_animation_controller_GetTrackDesc(ID3DXAnimationController *iface, + UINT track, D3DXTRACK_DESC *desc) + { ++ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); ++ + FIXME("iface %p, track %u, desc %p stub.\n", iface, track, desc); + +- return E_NOTIMPL; ++ if (track > animation->max_tracks || !desc) ++ return D3DERR_INVALIDCALL; ++ ++ *desc = animation->tracks[track].desc; ++ return D3D_OK; + } + + static HRESULT WINAPI d3dx9_animation_controller_SetPriorityBlend(ID3DXAnimationController *iface, +@@ -490,6 +508,14 @@ HRESULT WINAPI D3DXCreateAnimationController(UINT max_outputs, UINT max_sets, + return E_OUTOFMEMORY; + } + object->max_sets = max_sets; ++ ++ object->tracks = calloc(max_tracks, sizeof(*object->tracks)); ++ if (!object->tracks) ++ { ++ free(object->animation_sets); ++ free(object); ++ return E_OUTOFMEMORY; ++ } + object->max_tracks = max_tracks; + object->max_events = max_events; + +-- +2.50.1 + diff --git a/patches/d3dx9_animation_TrackDesc/0003-d3dx9-Implement-ID3DXAnimationController-Get-Set-Tra.patch b/patches/d3dx9_animation_TrackDesc/0003-d3dx9-Implement-ID3DXAnimationController-Get-Set-Tra.patch new file mode 100644 index 00000000..822e6c50 --- /dev/null +++ b/patches/d3dx9_animation_TrackDesc/0003-d3dx9-Implement-ID3DXAnimationController-Get-Set-Tra.patch @@ -0,0 +1,93 @@ +From fa933a9493c8b4a2e9626c1815bb5ef4309627b4 Mon Sep 17 00:00:00 2001 +From: Connor McAdams +Date: Wed, 3 Sep 2025 13:33:16 -0400 +Subject: [PATCH] d3dx9: Implement + ID3DXAnimationController::{Get,Set}TrackAnimationSet(). + +Signed-off-by: Connor McAdams +--- + dlls/d3dx9_36/animation.c | 38 ++++++++++++++++++++++++++++++++++++-- + 1 file changed, 36 insertions(+), 2 deletions(-) + +diff --git a/dlls/d3dx9_36/animation.c b/dlls/d3dx9_36/animation.c +index 6ded652930a..ccd16778c3e 100644 +--- a/dlls/d3dx9_36/animation.c ++++ b/dlls/d3dx9_36/animation.c +@@ -26,6 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3dx); + struct d3dx9_track + { + D3DXTRACK_DESC desc; ++ int set_idx; + }; + + struct d3dx9_animation_controller +@@ -219,17 +220,47 @@ static double WINAPI d3dx9_animation_controller_GetTime(ID3DXAnimationController + static HRESULT WINAPI d3dx9_animation_controller_SetTrackAnimationSet(ID3DXAnimationController *iface, + UINT track, ID3DXAnimationSet *anim_set) + { ++ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); ++ unsigned int i; ++ int idx; ++ + FIXME("iface %p, track %u, anim_set %p stub.\n", iface, track, anim_set); + +- return E_NOTIMPL; ++ if (track > animation->max_tracks || !anim_set || (animation->tracks[track].set_idx >= 0)) ++ return D3DERR_INVALIDCALL; ++ ++ idx = -1; ++ for (i = 0; i < animation->num_sets; i++) ++ { ++ if (animation->animation_sets[i] == anim_set) ++ { ++ idx = i; ++ break; ++ } ++ } ++ ++ animation->tracks[track].set_idx = idx; ++ ++ return idx >= 0 ? D3D_OK : D3DERR_INVALIDCALL; + } + + static HRESULT WINAPI d3dx9_animation_controller_GetTrackAnimationSet(ID3DXAnimationController *iface, + UINT track, ID3DXAnimationSet **anim_set) + { ++ struct d3dx9_animation_controller *animation = impl_from_ID3DXAnimationController(iface); ++ int set_idx; ++ + FIXME("iface %p, track %u, anim_set %p stub.\n", iface, track, anim_set); + +- return E_NOTIMPL; ++ if (track > animation->max_tracks || !anim_set) ++ return D3DERR_INVALIDCALL; ++ ++ set_idx = animation->tracks[track].set_idx; ++ *anim_set = set_idx >= 0 ? animation->animation_sets[set_idx] : NULL; ++ ++ if (*anim_set) ++ (*anim_set)->lpVtbl->AddRef(*anim_set); ++ return D3D_OK; + } + + static HRESULT WINAPI d3dx9_animation_controller_SetTrackPriority(ID3DXAnimationController *iface, +@@ -486,6 +517,7 @@ HRESULT WINAPI D3DXCreateAnimationController(UINT max_outputs, UINT max_sets, + UINT max_tracks, UINT max_events, ID3DXAnimationController **controller) + { + struct d3dx9_animation_controller *object; ++ unsigned int i; + + TRACE("max_outputs %u, max_sets %u, max_tracks %u, max_events %u, controller %p.\n", + max_outputs, max_sets, max_tracks, max_events, controller); +@@ -516,6 +548,8 @@ HRESULT WINAPI D3DXCreateAnimationController(UINT max_outputs, UINT max_sets, + free(object); + return E_OUTOFMEMORY; + } ++ for (i = 0; i < max_tracks; ++i) ++ object->tracks[i].set_idx = -1; + object->max_tracks = max_tracks; + object->max_events = max_events; + +-- +2.50.1 + diff --git a/patches/d3dx9_animation_TrackDesc/definition b/patches/d3dx9_animation_TrackDesc/definition new file mode 100644 index 00000000..7d28aada --- /dev/null +++ b/patches/d3dx9_animation_TrackDesc/definition @@ -0,0 +1 @@ +Fixes: [48598] d3dx9: Improve ID3DXAnimationController Animation set support.