Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45481 Signed-off-by: Alistair Leslie-Hughes leslie_alistair@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();