[PATCH 5/5] d3drm: Assign animation key ids
Nikolay Sivov
nsivov at codeweavers.com
Mon Jul 10 05:40:50 CDT 2017
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/d3drm/d3drm_private.h | 5 ++++
dlls/d3drm/frame.c | 63 +++++++++++++++++++++++++++++++++++++++++++---
dlls/d3drm/tests/d3drm.c | 3 ---
3 files changed, 65 insertions(+), 6 deletions(-)
diff --git a/dlls/d3drm/d3drm_private.h b/dlls/d3drm/d3drm_private.h
index 65e0016a18..9f0b451a03 100644
--- a/dlls/d3drm/d3drm_private.h
+++ b/dlls/d3drm/d3drm_private.h
@@ -211,6 +211,7 @@ struct d3drm_material
struct d3drm_animation_key
{
D3DVALUE time;
+ DWORD id;
union
{
D3DVECTOR position;
@@ -224,6 +225,10 @@ struct d3drm_animation_keys
struct d3drm_animation_key *keys;
SIZE_T count;
SIZE_T size;
+ DWORD first_id;
+ DWORD last_id;
+ DWORD next_free;
+ DWORD next_unused;
};
struct d3drm_animation
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c
index aa7633b07c..14fffc6750 100644
--- a/dlls/d3drm/frame.c
+++ b/dlls/d3drm/frame.c
@@ -3304,11 +3304,42 @@ static const struct d3drm_animation_key *d3drm_animation_get_range(const struct
return &keys->keys[min];
}
+static BOOL d3drm_animation_get_next_key_id(struct d3drm_animation_keys *keys, DWORD *id)
+{
+ DWORD i;
+
+ if (keys->next_unused <= keys->last_id)
+ {
+ *id = keys->next_unused++;
+ return TRUE;
+ }
+
+ if (keys->next_free <= keys->last_id)
+ {
+ *id = keys->next_free;
+ keys->next_free = ~0u;
+ return TRUE;
+ }
+
+ if (keys->count == keys->last_id - keys->first_id + 1)
+ return FALSE;
+
+ /* Worst case, look for the spot from the beginning. */
+ for (i = 0, *id = keys->first_id; i < keys->count; i++, ++*id)
+ {
+ if (*id != keys->keys[i].id)
+ break;
+ }
+
+ return TRUE;
+}
+
static HRESULT WINAPI d3drm_animation2_AddKey(IDirect3DRMAnimation2 *iface, D3DRMANIMATIONKEY *key)
{
struct d3drm_animation *animation = impl_from_IDirect3DRMAnimation2(iface);
struct d3drm_animation_keys *keys;
SIZE_T index;
+ DWORD id;
TRACE("iface %p, key %p.\n", iface, key);
@@ -3335,9 +3366,13 @@ static HRESULT WINAPI d3drm_animation2_AddKey(IDirect3DRMAnimation2 *iface, D3DR
if (!d3drm_array_reserve((void **)&keys->keys, &keys->size, keys->count + 1, sizeof(*keys->keys)))
return E_OUTOFMEMORY;
+ if (!d3drm_animation_get_next_key_id(keys, &id))
+ return E_FAIL;
+
if (index < keys->count)
memmove(&keys->keys[index + 1], &keys->keys[index], sizeof(*keys->keys) * (keys->count - index));
keys->keys[index].time = key->dvTime;
+ keys->keys[index].id = id;
switch (key->dwKeyType)
{
case D3DRMANIMATION_POSITIONKEY:
@@ -3439,9 +3474,15 @@ static void d3drm_animation_delete_key(struct d3drm_animation_keys *keys, const
{
SIZE_T index = key - keys->keys;
+ if (keys->next_free == ~0u)
+ keys->next_free = key->id;
+
if (index < keys->count - 1)
memmove(&keys->keys[index], &keys->keys[index + 1], sizeof(*keys->keys) * (keys->count - index - 1));
--keys->count;
+
+ if (keys->next_unused > keys->last_id && keys->count == 0)
+ keys->next_unused = keys->first_id;
}
static HRESULT WINAPI d3drm_animation2_DeleteKey(IDirect3DRMAnimation2 *iface, D3DVALUE time)
@@ -3588,7 +3629,7 @@ static HRESULT WINAPI d3drm_animation2_GetKeys(IDirect3DRMAnimation2 *iface, D3D
keys[i].dwSize = sizeof(*keys);
keys[i].dwKeyType = D3DRMANIMATION_ROTATEKEY;
keys[i].dvTime = key[i].time;
- keys[i].dwID = 0; /* FIXME */
+ keys[i].dwID = key[i].id;
keys[i].u.dqRotateKey = key[i].u.rotate;
}
keys += count;
@@ -3605,7 +3646,7 @@ static HRESULT WINAPI d3drm_animation2_GetKeys(IDirect3DRMAnimation2 *iface, D3D
keys[i].dwSize = sizeof(*keys);
keys[i].dwKeyType = D3DRMANIMATION_POSITIONKEY;
keys[i].dvTime = key[i].time;
- keys[i].dwID = 0; /* FIXME */
+ keys[i].dwID = key[i].id;
keys[i].u.dvPositionKey = key[i].u.position;
}
keys += count;
@@ -3622,7 +3663,7 @@ static HRESULT WINAPI d3drm_animation2_GetKeys(IDirect3DRMAnimation2 *iface, D3D
keys[i].dwSize = sizeof(*keys);
keys[i].dwKeyType = D3DRMANIMATION_SCALEKEY;
keys[i].dvTime = key[i].time;
- keys[i].dwID = 0; /* FIXME */
+ keys[i].dwID = key[i].id;
keys[i].u.dvScaleKey = key[i].u.scale;
}
keys += count;
@@ -3684,8 +3725,20 @@ static const struct IDirect3DRMAnimation2Vtbl d3drm_animation2_vtbl =
d3drm_animation2_GetKeys,
};
+static void d3drm_animation_init_keys(struct d3drm_animation_keys *keys, DWORD first_id, DWORD last_id)
+{
+ keys->first_id = keys->next_free = keys->next_unused = first_id;
+ keys->last_id = last_id;
+}
+
HRESULT d3drm_animation_create(struct d3drm_animation **animation, IDirect3DRM *d3drm)
{
+ static const DWORD rotate_key_start_id = 0x40000000;
+ static const DWORD rotate_key_last_id = 0x7fffffff;
+ static const DWORD position_key_start_id = 0x80000000;
+ static const DWORD position_key_last_id = 0xbfffffff;
+ static const DWORD scale_key_start_id = 0xc0000000;
+ static const DWORD scale_key_last_id = 0xfffffffe;
static const char classname[] = "Animation";
struct d3drm_animation *object;
HRESULT hr = D3DRM_OK;
@@ -3701,6 +3754,10 @@ HRESULT d3drm_animation_create(struct d3drm_animation **animation, IDirect3DRM *
object->ref = 1;
object->options = D3DRMANIMATION_CLOSED | D3DRMANIMATION_LINEARPOSITION;
+ d3drm_animation_init_keys(&object->rotate, rotate_key_start_id, rotate_key_last_id);
+ d3drm_animation_init_keys(&object->position, position_key_start_id, position_key_last_id);
+ d3drm_animation_init_keys(&object->scale, scale_key_start_id, scale_key_last_id);
+
d3drm_object_init(&object->obj, classname);
IDirect3DRM_AddRef(object->d3drm);
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index c59763d602..1f600c4aba 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -6937,8 +6937,6 @@ static void test_animation(void)
{
ok(keys[i].dwSize == sizeof(*keys), "%u: unexpected dwSize value %u.\n", i, keys[i].dwSize);
- todo_wine
- {
switch (keys[i].dwKeyType)
{
case D3DRMANIMATION_ROTATEKEY:
@@ -6954,7 +6952,6 @@ static void test_animation(void)
ok(0, "%u: unknown key type %d.\n", i, keys[i].dwKeyType);
}
}
- }
/* No keys in this range. */
count = 10;
--
2.13.2
More information about the wine-patches
mailing list