[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