[PATCH] d3dx9_36: Implement D3DXCreateKeyframedAnimationSet

Alistair Leslie-Hughes leslie_alistair at hotmail.com
Sun Feb 2 22:54:45 CST 2020


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45481
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair at hotmail.com>
---
 dlls/d3dx9_36/animation.c  | 388 ++++++++++++++++++++++++++++++++++++-
 dlls/d3dx9_36/tests/mesh.c |  27 +++
 2 files changed, 412 insertions(+), 3 deletions(-)

diff --git a/dlls/d3dx9_36/animation.c b/dlls/d3dx9_36/animation.c
index de6d69d383..c916be976b 100644
--- a/dlls/d3dx9_36/animation.c
+++ b/dlls/d3dx9_36/animation.c
@@ -468,14 +468,396 @@ HRESULT WINAPI D3DXCreateAnimationController(UINT max_outputs, UINT max_sets,
     return D3D_OK;
 }
 
+struct d3dx9_animation_frame_set
+{
+    ID3DXKeyframedAnimationSet ID3DXKeyframedAnimationSet_iface;
+    LONG ref;
+
+    char *name;
+    double ticks_per_second;
+    D3DXPLAYBACK_TYPE playback_type;
+    UINT animation_count;
+    UINT callback_key_count;
+    const D3DXKEY_CALLBACK *callback_keys;
+};
+
+static inline struct d3dx9_animation_frame_set *impl_from_ID3DXKeyframedAnimationSet(ID3DXKeyframedAnimationSet *iface)
+{
+    return CONTAINING_RECORD(iface, struct d3dx9_animation_frame_set, ID3DXKeyframedAnimationSet_iface);
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_QueryInterface(ID3DXKeyframedAnimationSet *iface, REFIID riid, void **obj)
+{
+    TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), obj);
+
+    if (IsEqualGUID(riid, &IID_IUnknown) ||
+        IsEqualGUID(riid, &IID_ID3DXAnimationSet) ||
+        IsEqualGUID(riid, &IID_ID3DXKeyframedAnimationSet))
+    {
+        iface->lpVtbl->AddRef(iface);
+        *obj = iface;
+        return D3D_OK;
+    }
+
+    WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
+    *obj = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI d3dx9_animation_framed_AddRef(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    ULONG refcount = InterlockedIncrement(&framed->ref);
+
+    TRACE("%p increasing refcount to %u.\n", framed, refcount);
+
+    return refcount;
+}
+
+static ULONG WINAPI d3dx9_animation_framed_Release(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    ULONG refcount = InterlockedDecrement(&framed->ref);
+
+    TRACE("%p decreasing refcount to %u.\n", framed, refcount);
+
+    if (!refcount)
+    {
+        heap_free(framed->name);
+        HeapFree(GetProcessHeap(), 0, framed);
+    }
+
+    return refcount;
+}
+
+static const char * WINAPI d3dx9_animation_framed_GetName(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    TRACE("framed %p.\n", framed);
+    return framed->name;
+}
+
+static DOUBLE WINAPI d3dx9_animation_framed_GetPeriod(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p stub.\n", framed);
+    return 0.0f;
+}
+
+static DOUBLE WINAPI d3dx9_animation_framed_GetPeriodicPosition(ID3DXKeyframedAnimationSet *iface, DOUBLE position)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p stub.\n", framed);
+    return 0.0f;
+}
+
+static UINT WINAPI d3dx9_animation_framed_GetNumAnimations(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p stub.\n", framed);
+    return 0;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetAnimationNameByIndex(ID3DXKeyframedAnimationSet *iface, UINT index,
+                const char **name)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, name %p stub.\n", framed, name);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetAnimationIndexByName(ID3DXKeyframedAnimationSet *iface,
+                const char *name, UINT *index)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, name %s, index %p stub.\n", framed, debugstr_a(name), index);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetSRT(ID3DXKeyframedAnimationSet *iface, DOUBLE periodic_position,
+                UINT animation, D3DXVECTOR3 *scale,
+        D3DXQUATERNION *rotation, D3DXVECTOR3 *translation)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, periodic_position %f, animation %u, scale %p rotation %p translation %p stub.\n",
+            framed, periodic_position, animation, scale, rotation, translation);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetCallback(ID3DXKeyframedAnimationSet *iface, double position,
+            DWORD flags, double *callback_position, void **callback_data)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, position %f, flags 0x%08x, callback_position %p, callback_data %p stub.\n",
+                framed, position, flags, callback_position, callback_data);
+    return E_NOTIMPL;
+}
+
+static D3DXPLAYBACK_TYPE WINAPI d3dx9_animation_framed_GetPlaybackType(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    TRACE("framed %p.\n", framed);
+    return framed->playback_type;
+}
+
+static DOUBLE WINAPI d3dx9_animation_framed_GetSourceTicksPerSecond(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    TRACE("framed %p.\n", framed);
+    return framed->ticks_per_second;
+}
+
+static UINT WINAPI d3dx9_animation_framed_GetNumScaleKeys(ID3DXKeyframedAnimationSet *iface, UINT keys)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, keys %u stub.\n", framed, keys);
+    return 0;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetScaleKeys(ID3DXKeyframedAnimationSet *iface, UINT animation,
+            D3DXKEY_VECTOR3 *scale_keys)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, scale_keys %p stub.\n", framed, animation, scale_keys);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetScaleKey(ID3DXKeyframedAnimationSet *iface, UINT animation,
+            UINT key, D3DXKEY_VECTOR3 *scale_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u, scale_key %p stub.\n", framed, animation, key, scale_key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_SetScaleKey(ID3DXKeyframedAnimationSet *iface, UINT animation,
+                UINT key, D3DXKEY_VECTOR3 *scale_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u, scale_key %p stub.\n", framed, animation, key, scale_key);
+    return E_NOTIMPL;
+}
+
+static UINT WINAPI d3dx9_animation_framed_GetNumRotationKeys(ID3DXKeyframedAnimationSet *iface, UINT animation)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u stub.\n", framed, animation);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetRotationKeys(ID3DXKeyframedAnimationSet *iface, UINT animation,
+                D3DXKEY_QUATERNION *rotation_keys)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, rotation_keys %p stub.\n", framed, animation, rotation_keys);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetRotationKey(ID3DXKeyframedAnimationSet *iface, UINT animation, UINT key,
+            D3DXKEY_QUATERNION *rotation_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u, rotation_key %p stub.\n", framed, animation, key, rotation_key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_SetRotationKey(ID3DXKeyframedAnimationSet *iface, UINT animation, UINT key,
+            D3DXKEY_QUATERNION *rotation_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u, rotation_key %p stub.\n", framed, animation, key, rotation_key);
+    return E_NOTIMPL;
+}
+
+static UINT WINAPI d3dx9_animation_framed_GetNumTranslationKeys(ID3DXKeyframedAnimationSet *iface, UINT animation)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u stub.\n", framed, animation);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetTranslationKeys(ID3DXKeyframedAnimationSet *iface, UINT animation,
+                D3DXKEY_VECTOR3 *translation_keys)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, rotation_key %p stub.\n", framed, animation, translation_keys);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetTranslationKey(ID3DXKeyframedAnimationSet *iface, UINT animation,
+            UINT key, D3DXKEY_VECTOR3 *translation_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u, translation_key %p stub.\n", framed, animation, key, translation_key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_SetTranslationKey(ID3DXKeyframedAnimationSet *iface, UINT animation,
+                UINT key, D3DXKEY_VECTOR3 *translation_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u, translation_key %p stub.\n", framed, animation, key, translation_key);
+    return E_NOTIMPL;
+}
+
+static UINT WINAPI d3dx9_animation_framed_GetNumCallbackKeys(ID3DXKeyframedAnimationSet *iface)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p stub.\n", framed);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetCallbackKeys(ID3DXKeyframedAnimationSet *iface,
+                D3DXKEY_CALLBACK *callback_keys)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, callback_keys %p stub.\n", framed, callback_keys);
+
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_GetCallbackKey(ID3DXKeyframedAnimationSet *iface, UINT key,
+                D3DXKEY_CALLBACK *callback_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, key %u, callback_key %p stub.\n", framed, key, callback_key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_SetCallbackKey(ID3DXKeyframedAnimationSet *iface, UINT key,
+                D3DXKEY_CALLBACK *callback_key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, key %u, callback_key %p stub.\n", framed, key, callback_key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_UnregisterScaleKey(ID3DXKeyframedAnimationSet *iface,
+                UINT animation, UINT key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u stub.\n", framed, animation, key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_UnregisterRotationKey(ID3DXKeyframedAnimationSet *iface,
+                UINT animation, UINT key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u stub.\n", framed, animation, key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_UnregisterTranslationKey(ID3DXKeyframedAnimationSet *iface,
+                UINT animation, UINT key)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, animation %u, key %u stub.\n", framed, animation, key);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_RegisterAnimationSRTKeys(ID3DXKeyframedAnimationSet *iface,
+                const char *name, UINT num_scale_keys, UINT num_rotation_keys, UINT num_translation_keys,
+                const D3DXKEY_VECTOR3 *scale_keys, const D3DXKEY_QUATERNION *rotation_keys,
+                const D3DXKEY_VECTOR3 *translation_keys, DWORD *animation_index)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, name %s, num_scale_keys %u, num_rotation_keys %u, rotation_keys %p, num_translation_keys %u, "
+          " scale_keys %p, rotation_keys %p, translation_keys %p, animation_index %p stub.\n",
+            framed, debugstr_a(name), num_scale_keys, num_rotation_keys, rotation_keys, num_translation_keys, scale_keys,
+            rotation_keys, translation_keys, animation_index);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_Compress(ID3DXKeyframedAnimationSet *iface, DWORD flags, float lossiness,
+        D3DXFRAME *hierarchy, ID3DXBuffer **compressed_data)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, flags 0x%08x, lossiness %f, hierarchy %p, compressed_data %p stub.\n", framed, flags, lossiness,
+            hierarchy, compressed_data);
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI d3dx9_animation_framed_UnregisterAnimation(ID3DXKeyframedAnimationSet *iface, UINT index)
+{
+    struct d3dx9_animation_frame_set *framed = impl_from_ID3DXKeyframedAnimationSet(iface);
+    FIXME("framed %p, index %u stub.\n", framed, index);
+    return E_NOTIMPL;
+}
+
+static const struct ID3DXKeyframedAnimationSetVtbl d3dx9_animation_framed_vtbl =
+{
+    d3dx9_animation_framed_QueryInterface,
+    d3dx9_animation_framed_AddRef,
+    d3dx9_animation_framed_Release,
+    d3dx9_animation_framed_GetName,
+    d3dx9_animation_framed_GetPeriod,
+    d3dx9_animation_framed_GetPeriodicPosition,
+    d3dx9_animation_framed_GetNumAnimations,
+    d3dx9_animation_framed_GetAnimationNameByIndex,
+    d3dx9_animation_framed_GetAnimationIndexByName,
+    d3dx9_animation_framed_GetSRT,
+    d3dx9_animation_framed_GetCallback,
+    d3dx9_animation_framed_GetPlaybackType,
+    d3dx9_animation_framed_GetSourceTicksPerSecond,
+    d3dx9_animation_framed_GetNumScaleKeys,
+    d3dx9_animation_framed_GetScaleKeys,
+    d3dx9_animation_framed_GetScaleKey,
+    d3dx9_animation_framed_SetScaleKey,
+    d3dx9_animation_framed_GetNumRotationKeys,
+    d3dx9_animation_framed_GetRotationKeys,
+    d3dx9_animation_framed_GetRotationKey,
+    d3dx9_animation_framed_SetRotationKey,
+    d3dx9_animation_framed_GetNumTranslationKeys,
+    d3dx9_animation_framed_GetTranslationKeys,
+    d3dx9_animation_framed_GetTranslationKey,
+    d3dx9_animation_framed_SetTranslationKey,
+    d3dx9_animation_framed_GetNumCallbackKeys,
+    d3dx9_animation_framed_GetCallbackKeys,
+    d3dx9_animation_framed_GetCallbackKey,
+    d3dx9_animation_framed_SetCallbackKey,
+    d3dx9_animation_framed_UnregisterScaleKey,
+    d3dx9_animation_framed_UnregisterRotationKey,
+    d3dx9_animation_framed_UnregisterTranslationKey,
+    d3dx9_animation_framed_RegisterAnimationSRTKeys,
+    d3dx9_animation_framed_Compress,
+    d3dx9_animation_framed_UnregisterAnimation
+};
+
 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",
+    struct d3dx9_animation_frame_set *object;
+
+    TRACE("name %s, ticks_per_second %.16e, playback_type %u, animation_count %u, "
+            "callback_key_count %u, callback_keys %p, animation_set %p.\n",
             debugstr_a(name), ticks_per_second, playback_type, animation_count,
             callback_key_count, callback_keys, animation_set);
 
-    return E_NOTIMPL;
+    if(!animation_count)
+        return D3DERR_INVALIDCALL;
+
+    object = heap_alloc(sizeof(*object));
+    if (!object)
+        return E_OUTOFMEMORY;
+
+    object->ID3DXKeyframedAnimationSet_iface.lpVtbl = &d3dx9_animation_framed_vtbl;
+    object->ref = 1;
+    object->name = heap_alloc( strlen(name)+1 );
+    if(!object->name)
+    {
+        heap_free(object);
+        return E_OUTOFMEMORY;
+    }
+    strcpy(object->name, name);
+    object->ticks_per_second   = ticks_per_second;
+    object->playback_type      = playback_type;
+    object->animation_count    = animation_count;
+    object->callback_key_count = callback_key_count;
+    object->callback_keys      = callback_keys;
+
+    *animation_set = &object->ID3DXKeyframedAnimationSet_iface;
+
+    return D3D_OK;
 }
diff --git a/dlls/d3dx9_36/tests/mesh.c b/dlls/d3dx9_36/tests/mesh.c
index 3882bb404a..fc07ac1228 100644
--- a/dlls/d3dx9_36/tests/mesh.c
+++ b/dlls/d3dx9_36/tests/mesh.c
@@ -11119,6 +11119,32 @@ static void D3DXCreateAnimationControllerTest(void)
     animation->lpVtbl->Release(animation);
 }
 
+static void D3DXCreateKeyframedAnimationSetTest(void)
+{
+    ID3DXKeyframedAnimationSet *framed;
+    HRESULT hr;
+    const char *name;
+    D3DXPLAYBACK_TYPE playtype;
+    UINT count;
+
+    hr = D3DXCreateKeyframedAnimationSet("wine_bottle", 5.0, D3DXPLAY_LOOP, 0, 0, NULL, &framed);
+    ok(hr == D3DERR_INVALIDCALL, "Got unexpected hr returned %#x.\n", hr);
+
+    hr = D3DXCreateKeyframedAnimationSet("wine_bottle", 5.0, D3DXPLAY_LOOP, 10, 0, NULL, &framed);
+    ok(hr == D3D_OK, "Got unexpected hr returned %#x.\n", hr);
+
+    name = framed->lpVtbl->GetName(framed);
+    ok(!strcmp(name, "wine_bottle"), "unexpected name (%s)\n", name);
+
+    playtype = framed->lpVtbl->GetPlaybackType(framed);
+    ok(playtype == D3DXPLAY_LOOP, "unexpected value, got %d\n", playtype);
+
+    count = framed->lpVtbl->GetNumAnimations(framed);
+    ok(count == 0, "unexpected value, got %d\n", count);
+
+    framed->lpVtbl->Release(framed);
+}
+
 static void test_D3DXFrameFind(void)
 {
     static char n1[] = "name1";
@@ -11387,6 +11413,7 @@ START_TEST(mesh)
     D3DXCreateTextTest();
     D3DXCreateTorusTest();
     D3DXCreateAnimationControllerTest();
+    D3DXCreateKeyframedAnimationSetTest();
     test_get_decl_length();
     test_get_decl_vertex_size();
     test_fvf_decl_conversion();
-- 
2.17.1




More information about the wine-devel mailing list