changeset 368:08ea68abb1f8

Work towards re-entrancy.
author Matti Hamalainen <ccr@tnsp.org>
date Wed, 17 Oct 2012 00:01:46 +0300
parents 9875c65029af
children e1c984404b6b
files dmengine.c dmengine.h dmtimeline.c dmtimelinew.c
diffstat 4 files changed, 305 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/dmengine.c	Tue Oct 16 23:31:19 2012 +0300
+++ b/dmengine.c	Wed Oct 17 00:01:46 2012 +0300
@@ -9,6 +9,94 @@
 
 
 DMEngineData engine;
+DMEffect *engineEffects = NULL;
+int nengineEffects = 0, nengineEffectsAlloc = 0;
+
+
+int engineRegisterEffect(const DMEffect *ef)
+{
+    if (ef == NULL)
+        return DMERR_NULLPTR;
+
+    // Allocate more space for effects
+    if (nengineEffects + 1 >= nengineEffectsAlloc)
+    {
+        nengineEffectsAlloc += 16;
+        engineEffects = dmRealloc(engineEffects, sizeof(DMEffect) * nengineEffectsAlloc);
+        if (engineEffects == NULL)
+        {
+            dmError("Could not expand effects structure.\n"); 
+            return DMERR_INIT_FAIL;
+        }
+    }
+
+    // Copy effects structure
+    memcpy(engineEffects + nengineEffects, ef, sizeof(DMEffect));
+    nengineEffects++;
+    
+    return DMERR_OK;
+}
+
+
+int engineInitializeEffects(DMEngineData *engine)
+{
+    int i, res;
+
+    dmFree(engine->effectData);
+    engine->effectData = dmCalloc(nengineEffectsAlloc, sizeof(void *));
+    if (engine->effectData == NULL)
+    {
+        dmError("Could not expand effects data structure.\n"); 
+        return DMERR_INIT_FAIL;
+    }
+
+    for (i = 0; i < nengineEffects; i++)
+    {
+        if (engineEffects[i].init != NULL &&
+            (res = engineEffects[i].init(engine, &engine->effectData[i])) != DMERR_OK)
+            return res;
+    }
+
+    return DMERR_OK;
+}
+
+
+void engineShutdownEffects(DMEngineData *engine)
+{
+    int i;
+    for (i = 0; i < nengineEffects; i++)
+    {
+        if (engineEffects[i].shutdown != NULL)
+            engineEffects[i].shutdown(engine, engine->effectData[i]);
+    }
+    dmFree(engine->effectData);
+    engine->effectData = NULL;
+}
+
+
+DMEffect *engineFindEffect(const char *name, const int nparams)
+{
+    int i;
+    for (i = 0; i < nengineEffects; i++)
+    {
+        if (strcmp(engineEffects[i].name, name) == 0 &&
+            engineEffects[i].nparams == nparams)
+            return &engineEffects[i];
+    }
+    return NULL;
+}
+
+
+DMEffect *engineFindEffectByName(const char *name)
+{
+    int i;
+    for (i = 0; i < nengineEffects; i++)
+    {
+        if (strcmp(engineEffects[i].name, name) == 0)
+            return &engineEffects[i];
+    }
+    return NULL;
+}
 
 
 static int engineResImageLoad(DMResource *res)
--- a/dmengine.h	Tue Oct 16 23:31:19 2012 +0300
+++ b/dmengine.h	Wed Oct 17 00:01:46 2012 +0300
@@ -5,7 +5,7 @@
 #include <SDL_events.h>
 #include <SDL_audio.h>
 #include "dmres.h"
-#include "dmtimeline.h"
+#include "dmvecmat.h"
 
 #ifdef DM_USE_JSS
 #include "jss.h"
@@ -20,9 +20,176 @@
 #endif
 
 
+#define DT_MAGIC_ID           "SDMETLNE"
+#define DT_MAX_EFFECT_PARAMS  16
+#define DT_MAX_NAME_LENGTH    32
+#define DT_FLOAT_STORE_SIZE   16
+
+
+enum
+{
+    EFIT_SET,    // No interpolation, just "set" the value
+    EFIT_LINEAR, // Linear interpolation
+    EFIT_SMOOTH, // Smoothstep interpolation
+};
+
+enum
+{
+    EFPT_INT,
+    EFPT_FLOAT,
+    EFPT_STRING,
+    EFPT_VECTOR,
+    EFPT_MATRIX,
+};
+
+
+typedef struct
+{
+    int type;                // Interpolation type (EFIT_*) between this and next point
+    int time;                // Offsets to event start, -1 == attach to event start, -2 = event end (if event)
+
+    int vint;
+    DMFloat vfloat;
+    DMVector vector;
+    DMMatrix matrix;
+} DMTimelinePoint;
+
+
+typedef struct
+{
+    int npoints, nallocated;
+    DMTimelinePoint *points;
+} DMTimelinePoints;
+
+
+typedef struct
+{
+    char *name;              // Name / description of the parameter
+    int type;                // Type (EFPT_*)
+
+    DMTimelinePoints pts;
+    char *vstr;
+
+    // Current values (interpolated)
+    int vint;
+    DMFloat vfloat;
+    DMVector vvector;
+    DMMatrix vmatrix;
+} DMTimelineEventParam;
+
+
+typedef struct
+{
+    char name[DT_MAX_NAME_LENGTH];
+    Uint32 type;
+} DMFTimelineEventParam;
+
+
+struct DMEngineData;
+
+
+typedef struct
+{
+    char *  name;
+    int     type;
+    
+    int     (*init)(struct DMEngineData *, void **data);
+    void    (*shutdown)(struct DMEngineData *, void *data);
+    int     (*render)(SDL_Surface *screen, void *data, const DMTimelineEventParam *params, const int time);
+
+    int     nparams;
+    DMTimelineEventParam params[DT_MAX_EFFECT_PARAMS];
+} DMEffect;
+
+
+typedef struct
+{
+    Uint32 start, duration;
+    char effectName[DT_MAX_NAME_LENGTH];
+    Uint32 nparams;
+} DMFTimelineEvent;
+
+
+typedef struct
+{
+    int start, duration;
+    DMEffect *effect;
+    int nparams;
+    DMTimelineEventParam *params;
+} DMTimelineEvent;
+
+
+typedef struct
+{
+    BOOL enabled;
+    DMTimelinePoints points;
+} DMTimelineCurve;
+
+
+typedef struct
+{
+    char name[DT_MAX_NAME_LENGTH];
+    Uint8 enabled;
+    Uint32 nevents;
+} DMFTimelineTrack;
+
+
+typedef struct
+{
+    char *name;        // Name of the timeline track
+    BOOL enabled;      // Enabled?
+
+    int nevents, nallocated;    // Number of events
+    DMTimelineEvent **events;   // Events
+
+    DMTimelineCurve composite;  // Composite curve (transparency of the "layer")
+} DMTimelineTrack;
+
+
+typedef struct
+{
+    char   magic[8];
+    char   name[DT_MAX_NAME_LENGTH];
+    Uint32 ntracks;
+    Uint32 duration;
+} DMFTimeline;
+
+
+typedef struct
+{
+    char *name;
+    int ntracks, nallocated, duration;
+    DMTimelineTrack **tracks;
+} DMTimeline;
+
+
+typedef struct
+{
+    DMTimelineTrack *track;
+    DMTimelineEvent *event;
+} DMPreparedEvent;
+
+
+typedef struct _DMPreparedEventGroup
+{
+    int start, end, nevents, nallocated;
+    DMPreparedEvent *events;
+
+    struct _DMPreparedEventGroup *next, *prev;
+} DMPreparedEventGroup;
+
+
+typedef struct
+{
+    int duration, ngroups, pos;
+    DMPreparedEventGroup **groups;
+} DMPreparedTimeline;
+
+
 typedef struct DMEngineData
 {
     DMResourceLib *resources;
+    void **effectData;
 
     DMResource *timeline;
     DMTimeline *tl;
@@ -61,6 +228,49 @@
 } DMEngineData;
 
 
+extern DMEffect *dmEffects;
+extern int ndmEffects, ndmEffectsAlloc;
+extern void **dmEffectData;
+
+
+// Effect registration
+int       engineRegisterEffect(const DMEffect *ef);
+int       engineInitializeEffects();
+void      engineShutdownEffects();
+DMEffect *engineFindEffect(const char *name, const int nparams);
+DMEffect *engineFindEffectByName(const char *name);
+
+
+// Basic timeline handling
+int  dmLoadTimeline(DMResource *res, DMTimeline **tl);
+void dmFreeTimeline(DMTimeline *tl);
+
+void dmFreeTimelinePoints(DMTimelinePoints *points);
+void dmFreeTimelineEventParam(DMTimelineEventParam *param);
+void dmFreeTimelineEvent(DMTimelineEvent *event);
+void dmFreeTimelineTrack(DMTimelineTrack *track);
+
+
+// Execution related
+int  dmPrepareTimeline(DMTimeline *tl, DMPreparedTimeline *ptl);
+void dmFreePreparedTimelineData(DMPreparedTimeline *ptl);
+
+int  dmSeekTimeline(DMPreparedTimeline *tl, int time);
+int  dmExecuteTimeline(DMPreparedTimeline *tl, SDL_Surface *screen, int time);
+
+
+// Editing/saving related functions
+int  dmSaveTimeline(DMResource *res, DMTimeline *tl);
+
+int  dmTimelineNew(DMTimeline **tl, const char *name);
+int  dmTimelineAddTrack(DMTimeline *tl, DMTimelineTrack **track, const char *name);
+int  dmTimelineTrackAddEvent(DMTimelineTrack *track, int start, int duration, DMTimelineEvent **pev);
+int  dmTimelineEventSetEffect(DMTimelineEvent *event, const char *name);
+
+DMTimelineEvent *dmTimelineGetEventAt(DMTimelineTrack *track, int time);
+
+
+// Resource helpers
 #define engineGetResImage(eng, x, name) \
     do { \
         if ((x = (SDL_Surface *) engineGetResource(eng, name)) == NULL) \
@@ -82,6 +292,8 @@
 int    engineGetTimeDTi(DMEngineData *eng);
 int    engineGetTick(DMEngineData *eng);
 float  engineGetTimeDT(DMEngineData *eng);
+
+// Implemented in actual demo code
 int    demoPreInit(DMEngineData *eng);
 
 
--- a/dmtimeline.c	Tue Oct 16 23:31:19 2012 +0300
+++ b/dmtimeline.c	Wed Oct 17 00:01:46 2012 +0300
@@ -1,93 +1,4 @@
-#include "dmtimeline.h"
-
-
-DMEffect *dmEffects = NULL;
-int ndmEffects = 0, ndmEffectsAlloc = 0;
-void **dmEffectData = NULL;
-
-
-int dmRegisterEffect(const DMEffect *ef)
-{
-    if (ef == NULL)
-        return DMERR_NULLPTR;
-
-    // Allocate more space for effects
-    if (ndmEffects + 1 >= ndmEffectsAlloc)
-    {
-        ndmEffectsAlloc += 16;
-        dmEffects = dmRealloc(dmEffects, sizeof(DMEffect) * ndmEffectsAlloc);
-        if (dmEffects == NULL)
-        {
-            dmError("Could not expand effects structure.\n"); 
-            return DMERR_INIT_FAIL;
-        }
-        
-        dmEffectData = dmRealloc(dmEffectData, sizeof(void *) * ndmEffectsAlloc);
-        if (dmEffectData == NULL)
-        {
-            dmError("Could not expand effects data structure.\n"); 
-            return DMERR_INIT_FAIL;
-        }
-    }
-
-    // Copy effects structure
-    memcpy(dmEffects + ndmEffects, ef, sizeof(DMEffect));
-    dmEffectData[ndmEffects] = NULL;
-
-    ndmEffects++;
-    
-    return DMERR_OK;
-}
-
-
-int dmInitializeEffects()
-{
-    int i, res;
-    for (i = 0; i < ndmEffects; i++)
-    {
-        if (dmEffects[i].init != NULL &&
-            (res = dmEffects[i].init(&dmEffectData[i])) != DMERR_OK)
-            return res;
-    }
-
-    return DMERR_OK;
-}
-
-
-void dmShutdownEffects()
-{
-    int i;
-    for (i = 0; i < ndmEffects; i++)
-    {
-        if (dmEffects[i].shutdown != NULL)
-            dmEffects[i].shutdown(dmEffectData[i]);
-    }
-}
-
-
-DMEffect *dmFindEffect(const char *name, const int nparams)
-{
-    int i;
-    for (i = 0; i < ndmEffects; i++)
-    {
-        if (strcmp(dmEffects[i].name, name) == 0 &&
-            dmEffects[i].nparams == nparams)
-            return &dmEffects[i];
-    }
-    return NULL;
-}
-
-
-DMEffect *dmFindEffectByName(const char *name)
-{
-    int i;
-    for (i = 0; i < ndmEffects; i++)
-    {
-        if (strcmp(dmEffects[i].name, name) == 0)
-            return &dmEffects[i];
-    }
-    return NULL;
-}
+#include "dmengine.h"
 
 
 static BOOL dmLoadFloatValue(DMResource *res, DMFloat *val)
@@ -240,7 +151,7 @@
     event->start     = hdr.start;
     event->duration  = hdr.duration;
     event->nparams   = hdr.nparams;
-    event->effect    = dmFindEffect(hdr.effectName, hdr.nparams);
+    event->effect    = engineFindEffect(hdr.effectName, hdr.nparams);
     if (event->effect == NULL)
     {
         dmError("No matching registered effect found for '%s'.\n", hdr.effectName);
--- a/dmtimelinew.c	Tue Oct 16 23:31:19 2012 +0300
+++ b/dmtimelinew.c	Wed Oct 17 00:01:46 2012 +0300
@@ -1,4 +1,4 @@
-#include "dmtimeline.h"
+#include "dmengine.h"
 #include "dmresw.h"
 
 
@@ -264,7 +264,7 @@
     int param;
     DMEffect *ef;
 
-    if ((ef = dmFindEffectByName(name)) == NULL)
+    if ((ef = engineFindEffectByName(name)) == NULL)
         return DMERR_INVALID_DATA;
 
     event->effect = ef;