diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c index 6d2dc141ae8..0d6ee149fa1 100644 --- a/dlls/d3drm/frame.c +++ b/dlls/d3drm/frame.c @@ -3348,16 +3348,15 @@ static SIZE_T d3drm_animation_get_insert_position(const struct d3drm_animation_k static const struct d3drm_animation_key *d3drm_animation_get_range(const struct d3drm_animation_keys *keys, D3DVALUE time_min, D3DVALUE time_max, SIZE_T *count) { - SIZE_T min, max; + SIZE_T min; if (!keys->count || time_max < keys->keys[0].time || time_min > keys->keys[keys->count - 1].time) return NULL; min = d3drm_animation_get_index_min(keys->keys, keys->count, time_min); - max = d3drm_animation_get_index_max(&keys->keys[min], keys->count - min, time_max); - - *count = max - min + 1; + if (count) + *count = d3drm_animation_get_index_max(&keys->keys[min], keys->count - min, time_max) - min + 1; return &keys->keys[min]; } @@ -3493,11 +3492,41 @@ static HRESULT WINAPI d3drm_animation1_AddScaleKey(IDirect3DRMAnimation *iface, return d3drm_animation2_AddScaleKey(&animation->IDirect3DRMAnimation2_iface, time, x, y, z); } +static void d3drm_animation_delete_key(struct d3drm_animation_keys *keys, const struct d3drm_animation_key *key) +{ + SIZE_T index = key - keys->keys; + + if (index < keys->count - 1) + memmove(&keys->keys[index], &keys->keys[index + 1], sizeof(*keys->keys) * (keys->count - index - 1)); + --keys->count; +} + +static HRESULT WINAPI d3drm_animation2_DeleteKey(IDirect3DRMAnimation2 *iface, D3DVALUE time) +{ + struct d3drm_animation *animation = impl_from_IDirect3DRMAnimation2(iface); + const struct d3drm_animation_key *key; + + TRACE("iface %p, time %.8e.\n", iface, time); + + if ((key = d3drm_animation_get_range(&animation->rotate, time, time, NULL))) + d3drm_animation_delete_key(&animation->rotate, key); + + if ((key = d3drm_animation_get_range(&animation->position, time, time, NULL))) + d3drm_animation_delete_key(&animation->position, key); + + if ((key = d3drm_animation_get_range(&animation->scale, time, time, NULL))) + d3drm_animation_delete_key(&animation->scale, key); + + return D3DRM_OK; +} + static HRESULT WINAPI d3drm_animation1_DeleteKey(IDirect3DRMAnimation *iface, D3DVALUE time) { - FIXME("iface %p, time %.8e.\n", iface, time); + struct d3drm_animation *animation = impl_from_IDirect3DRMAnimation(iface); - return E_NOTIMPL; + TRACE("iface %p, time %.8e.\n", iface, time); + + return d3drm_animation2_DeleteKey(&animation->IDirect3DRMAnimation2_iface, time); } static HRESULT WINAPI d3drm_animation1_SetFrame(IDirect3DRMAnimation *iface, IDirect3DRMFrame *frame) @@ -3544,13 +3573,6 @@ static D3DRMANIMATIONOPTIONS WINAPI d3drm_animation1_GetOptions(IDirect3DRMAnima return d3drm_animation2_GetOptions(&animation->IDirect3DRMAnimation2_iface); } -static HRESULT WINAPI d3drm_animation2_DeleteKey(IDirect3DRMAnimation2 *iface, D3DVALUE time) -{ - FIXME("iface %p, time %.8e.\n", iface, time); - - return E_NOTIMPL; -} - static HRESULT WINAPI d3drm_animation2_SetFrame(IDirect3DRMAnimation2 *iface, IDirect3DRMFrame3 *frame) { struct d3drm_animation *animation = impl_from_IDirect3DRMAnimation2(iface); diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c index f19558e2484..c59763d602b 100644 --- a/dlls/d3drm/tests/d3drm.c +++ b/dlls/d3drm/tests/d3drm.c @@ -7013,9 +7013,81 @@ static void test_animation(void) memset(&key, 0, sizeof(key)); key.dwSize = sizeof(key); key.dwKeyType = D3DRMANIMATION_POSITIONKEY; + key.dvPositionKey.x = 8.0f; hr = IDirect3DRMAnimation2_AddKey(animation2, &key); ok(SUCCEEDED(hr), "Failed to add key, hr %#x.\n", hr); + /* Delete tests. */ + hr = IDirect3DRMAnimation_AddRotateKey(animation, 0.0f, &q); + ok(SUCCEEDED(hr), "Failed to add rotation key, hr %#.x\n", hr); + + hr = IDirect3DRMAnimation_AddScaleKey(animation, 0.0f, 1.0f, 2.0f, 1.0f); + ok(SUCCEEDED(hr), "Failed to add scale key, hr %#x.\n", hr); + + count = 0; + memset(keys, 0, sizeof(keys)); + hr = IDirect3DRMAnimation2_GetKeys(animation2, -1000.0f, 1000.0f, &count, keys); + ok(SUCCEEDED(hr), "Failed to get key count, hr %#x.\n", hr); + ok(count == 9, "Unexpected key count %u.\n", count); + + ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %u.\n", keys[0].dwKeyType); + ok(keys[1].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %u.\n", keys[1].dwKeyType); + ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[2].dwKeyType); + ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[3].dwKeyType); + ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[4].dwKeyType); + ok(keys[5].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[5].dwKeyType); + ok(keys[6].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[6].dwKeyType); + ok(keys[7].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %u.\n", keys[7].dwKeyType); + ok(keys[8].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %u.\n", keys[8].dwKeyType); + + ok(keys[0].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[0].dvTime); + ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime); + ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime); + ok(keys[3].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[3].dvTime); + ok(keys[4].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[4].dvTime); + ok(keys[5].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[5].dvTime); + ok(keys[6].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[6].dvTime); + ok(keys[7].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[7].dvTime); + ok(keys[8].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[8].dvTime); + + hr = IDirect3DRMAnimation_DeleteKey(animation, -100.0f); + ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr); + + hr = IDirect3DRMAnimation_DeleteKey(animation, 100.0f); + ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr); + + /* Only first Position keys are not removed. */ + hr = IDirect3DRMAnimation_DeleteKey(animation, 0.0f); + ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr); + + count = 0; + memset(keys, 0, sizeof(keys)); + hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, &count, keys); + ok(SUCCEEDED(hr), "Failed to get key count, hr %#x.\n", hr); + ok(count == 6, "Unexpected key count %u.\n", count); + + ok(keys[0].dwKeyType == D3DRMANIMATION_ROTATEKEY, "Unexpected key type %u.\n", keys[0].dwKeyType); + ok(keys[1].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[1].dwKeyType); + ok(keys[2].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[2].dwKeyType); + ok(keys[3].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[3].dwKeyType); + ok(keys[4].dwKeyType == D3DRMANIMATION_POSITIONKEY, "Unexpected key type %u.\n", keys[4].dwKeyType); + ok(keys[5].dwKeyType == D3DRMANIMATION_SCALEKEY, "Unexpected key type %u.\n", keys[5].dwKeyType); + + ok(keys[0].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[0].dvTime); + ok(keys[1].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[1].dvTime); + ok(keys[2].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[2].dvTime); + ok(keys[3].dvTime == 80.0f, "Unexpected key time %.8e.\n", keys[3].dvTime); + ok(keys[4].dvTime == 99.0f, "Unexpected key time %.8e.\n", keys[4].dvTime); + ok(keys[5].dvTime == 0.0f, "Unexpected key time %.8e.\n", keys[5].dvTime); + + hr = IDirect3DRMAnimation_DeleteKey(animation, 0.0f); + ok(SUCCEEDED(hr), "Failed to delete keys, hr %#x.\n", hr); + + count = 0; + hr = IDirect3DRMAnimation2_GetKeys(animation2, 0.0f, 100.0f, &count, NULL); + ok(SUCCEEDED(hr), "Failed to get key count, hr %#x.\n", hr); + ok(count == 3, "Unexpected key count %u.\n", count); + IDirect3DRMAnimation2_Release(animation2); IDirect3DRMAnimation_Release(animation);