WIP of a simple general purpose animation framework for the menu. uncomment those...
authoresteel <esteel@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Mon, 22 Feb 2010 08:15:41 +0000 (08:15 +0000)
committeresteel <esteel@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Mon, 22 Feb 2010 08:15:41 +0000 (08:15 +0000)
git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8658 f962a42d-fe04-0410-a3ab-8c8b0445ebaa

data/qcsrc/menu/anim/animation.c [new file with mode: 0644]
data/qcsrc/menu/anim/animhost.c [new file with mode: 0644]
data/qcsrc/menu/classes.c
data/qcsrc/menu/menu.qc
data/qcsrc/menu/menu.qh
data/qcsrc/menu/nexuiz/slider.c

diff --git a/data/qcsrc/menu/anim/animation.c b/data/qcsrc/menu/anim/animation.c
new file mode 100644 (file)
index 0000000..3a6f46f
--- /dev/null
@@ -0,0 +1,110 @@
+#ifdef INTERFACE
+CLASS(Animation) EXTENDS(Object)
+       METHOD(Animation, setTimeStartEnd, void(entity, float, float))
+       METHOD(Animation, setTimeStartDuration, void(entity, float, float))
+       METHOD(Animation, setValueStartEnd, void(entity, float, float))
+       METHOD(Animation, setValueStartDelta, void(entity, float, float))
+       METHOD(Animation, setObjectSetter, void(entity, entity, void(entity, float)))
+       METHOD(Animation, tick, void(entity, float))
+       METHOD(Animation, isFinished, float(entity))
+       METHOD(Animation, stopAnim, void(entity))
+       METHOD(Animation, finishAnim, void(entity))
+       ATTRIB(Animation, object, entity, NULL)
+       ATTRIB(Animation, setter, void(entity, float), setterDummy)
+       ATTRIB(Animation, math, float(float, float, float, float), linear)
+       ATTRIB(Animation, value, float, 0)
+       ATTRIB(Animation, startTime, float, 0)
+       ATTRIB(Animation, duration, float, 0)
+       ATTRIB(Animation, startValue, float, 0)
+       ATTRIB(Animation, delta, float, 0)
+       ATTRIB(Animation, finished, float, FALSE)
+ENDCLASS(Animation)
+entity makeHostedAnimation(entity, void(entity, float), float, float, float);
+entity makeAnimation(entity, void(entity, float), float, float, float);
+float linear(float, float, float, float);
+void setterDummy(entity, float);
+#endif
+
+#ifdef IMPLEMENTATION
+entity makeHostedAnimation(entity obj, void(entity, float) setter, float duration, float start, float end)
+{
+       entity me;
+       me = makeAnimation(obj, setter, duration, start, end);
+       anim.addAnim(anim, me);
+       return me;
+}
+
+entity makeAnimation(entity obj, void(entity, float) setter, float duration, float start, float end)
+{
+       entity me;
+       me = spawnAnimation();
+       me.setObjectSetter(me, obj, setter);
+       me.setTimeStartDuration(me, time, duration);
+       me.setValueStartEnd(me, start, end);
+       return me;
+}
+
+void setTimeStartEndAnimation(entity me, float s, float e)
+{
+       me.startTime = s;
+       me.duration = e - s;
+}
+
+void setTimeStartDurationAnimation(entity me, float s, float d)
+{
+       me.startTime = s;
+       me.duration = d;
+}
+
+void setValueStartEndAnimation(entity me, float s, float e)
+{
+       me.startValue = s;
+       me.delta = e - s;
+}
+
+void setValueStartDeltaAnimation(entity me, float s, float d)
+{
+       me.startValue = s;
+       me.delta = d;
+}
+
+void setObjectSetterAnimation(entity me, entity o, void(entity, float) s)
+{
+       me.object = o;
+       me.setter = s;
+}
+
+void tickAnimation(entity me, float time)
+{
+       me.value = me.math((time - me.startTime), me.duration, me.startValue, me.delta);
+       me.setter(me.object, me.value);
+       if (time > (me.startTime + me.duration))
+               me.finishAnim(me);
+}
+
+float isFinishedAnimation(entity me)
+{
+       return me.finished;
+}
+
+void stopAnimAnimation(entity me)
+{
+}
+
+void finishAnimAnimation(entity me)
+{
+       me.finished = TRUE;
+}
+
+float linear(float time, float duration, float start, float delta)
+{
+       if (time > duration)
+               return delta + start;
+       return (delta * (time / duration)) + start;
+}
+
+void setterDummy(entity object, float value)
+{
+}
+
+#endif
diff --git a/data/qcsrc/menu/anim/animhost.c b/data/qcsrc/menu/anim/animhost.c
new file mode 100644 (file)
index 0000000..b50e9a8
--- /dev/null
@@ -0,0 +1,103 @@
+#ifdef INTERFACE
+CLASS(AnimHost) EXTENDS(Object)
+       METHOD(AnimHost, addAnim, void(entity, entity))
+       METHOD(AnimHost, removeAnim, void(entity, entity))
+       METHOD(AnimHost, stopAllAnim, void(entity))
+       METHOD(AnimHost, finishAllAnim, void(entity))
+       METHOD(AnimHost, tickAll, void(entity))
+       ATTRIB(AnimHost, firstChild, entity, NULL)
+       ATTRIB(AnimHost, lastChild, entity, NULL)
+ENDCLASS(AnimHost)
+.entity nextSibling;
+.entity prevSibling;
+#endif
+
+#ifdef IMPLEMENTATION
+void addAnimAnimHost(entity me, entity other)
+{
+       if(other.parent)
+               error("Can't add already added anim!");
+
+       if(other.isFinished(other))
+               error("Can't add finished anim!");
+
+       other.parent = me;
+
+       entity f, l;
+       f = me.firstChild;
+       l = me.lastChild;
+
+       if(l)
+               l.nextSibling = other;
+       else
+               me.firstChild = other;
+
+       other.prevSibling = l;
+       other.nextSibling = NULL;
+       me.lastChild = other;
+}
+
+void removeAnimAnimHost(entity me, entity other)
+{
+       if(other.parent != me)
+               error("Can't remove from wrong AnimHost!");
+
+       other.parent = NULL;
+
+       entity n, p, f, l;
+       f = me.firstChild;
+       l = me.lastChild;
+       n = other.nextSibling;
+       p = other.prevSibling;
+
+       if(p)
+               p.nextSibling = n;
+       else
+               me.firstChild = n;
+
+       if(n)
+               n.prevSibling = p;
+       else
+               me.lastChild = p;
+}
+
+void stopAllAnimAnimHost(entity me)
+{
+       entity e;
+       for(e = me.firstChild; e; e = e.nextSibling)
+       {
+               me.removeAnim(me, e);
+               e.stopAnim(e);
+       }
+}
+
+void finishAllAnimAnimHost(entity me)
+{
+       entity e;
+       for(e = me.firstChild; e; e = e.nextSibling)
+       {
+               me.removeAnim(me, e);
+               e.finishAnim(e);
+       }
+}
+
+void tickAllAnimHost(entity me)
+{
+       entity e;
+       for(e = me.firstChild; e; e = e.nextSibling)
+       {
+               e.tick(e, time);
+       }
+       for(e = me.firstChild; e; e = e.nextSibling)
+       {
+               entity tmp;
+               if (e.isFinished(e))
+               {
+                       tmp = e;
+                       e = tmp.prevSibling;
+                       me.removeAnim(me, tmp);
+                       remove(tmp);
+               }
+       }
+}
+#endif
index 0ac9943..6cdf856 100644 (file)
@@ -1,3 +1,5 @@
+#include "anim/animhost.c"
+#include "anim/animation.c"
 #include "item.c"
 #include "item/container.c"
 #include "item/inputcontainer.c"
index bec77b4..462337c 100644 (file)
@@ -150,6 +150,7 @@ void() m_init_delayed =
        draw_setMousePointer(SKINGFX_CURSOR, SKINSIZE_CURSOR, SKINOFFSET_CURSOR);
 
        loadTooltips();
+       anim = spawnAnimHost();
        main = spawnMainWindow(); main.configureMainWindow(main);
        unloadTooltips();
 
@@ -539,6 +540,9 @@ void() m_draw =
 
        menuMouseMode = cvar("menu_mouse_absolute");
 
+       if (anim)
+               anim.tickAll(anim);
+
        if(main)
                UpdateConWidthHeight();
 
index 8cee5fd..0ee4e91 100644 (file)
@@ -25,6 +25,7 @@ const float S_ALT = 4;
 float frametime;
 float time;
 
+entity anim;
 entity main;
 void m_hide();
 void m_display();
index 3b9a575..7fbde97 100644 (file)
@@ -53,8 +53,10 @@ void setValueNexuizSlider(entity me, float val)
 {
        if(val != me.value)
        {
+               //float oldValue = me.value;
                me.value = val;
                me.saveCvars(me);
+               //makeHostedAnimation(me, setValueSlider, 1, oldValue, val);
        }
 }
 void loadCvarsNexuizSlider(entity me)