view src/dmengine.h @ 2298:b5abfff07ca9

Add new DMGrowBuf helper functions dmGrowBufCopyOffsSize() and dmGrowBufConstCopyOffsSize().
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 04 Jul 2019 10:54:16 +0300
parents 78a0f44aa8b5
children 9807ae37ad69
line wrap: on
line source

/*
 * dmlib
 * -- Demo engine / editor common code and definitions
 * Programmed and designed by Matti 'ccr' Hamalainen
 * (C) Copyright 2012-2015 Tecnic Software productions (TNSP)
 */
#ifndef DMENGINE_H
#define DMENGINE_H

#include "dmlib.h"
#include <SDL_events.h>
#include <SDL_audio.h>
#include "dmres.h"
#include "dmvecmat.h"
#include "dmcurves.h"

#ifdef DM_USE_JSS
#include "jss.h"
#include "jssmod.h"
#include "jssmix.h"
#include "jssplr.h"
#endif


#ifdef __cplusplus
extern "C" {
#endif

// Video setup window size
#define DM_VSETUP_WIDTH       640
#define DM_VSETUP_HEIGHT      480


// Video setup type
enum
{
    DM_VSETUP_NONE    = 0x00,  // No video setup, just set window/screen to what demo specifies
    DM_VSETUP_ASPECT  = 0x01,  // Only modes that match the optVidAspect aspect ratio are ok
    DM_VSETUP_ANY     = 0x02,  // Any available mode is okay, the code can adapt
};

// Audio setup type
enum
{
    DM_ASETUP_NONE    = 0,
    DM_ASETUP_JSS     = 1,
    DM_ASETUP_TREMOR  = 2,
};



#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 _DMEffect
{
    char *  name;
    int     type;

    // init() - called at demo start/loading phase
    int     (*init)(struct DMEngineData *, const struct _DMEffect *eff, void **data);

    // shutdown() - called at demo shutdown
    void    (*shutdown)(struct DMEngineData *, const struct _DMEffect *eff, void *data);

    // called to render a frame
    int     (*render)(struct DMEngineData *, const struct _DMEffect *eff, void *data, const DMTimelineEventParam *params, const int time);

    int     nparams;
    DMTimelineEventParam params[DT_MAX_EFFECT_PARAMS];
} DMEffect;


#ifdef DM_USE_TIMELINE


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
{
    Uint32 index, layer;
    char name[DT_MAX_NAME_LENGTH];
    Uint8 enabled;
    Uint32 nevents;
} DMFTimelineTrack;


typedef struct
{
    int index;         // Track index
    int layer;         // Render order / layer
    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;

#endif


typedef struct DMEngineData
{
    DMResourceLib *resources;
    void **effectData;

#ifdef DM_USE_TIMELINE
    DMResource *timeline;
    DMTimeline *tl;
    DMPreparedTimeline *ptl;
#endif

    int frameTime, frameCount,
        startTime, endTime,
        startTimeAudio, offsetTime,
        pauseTime;

    BOOL pauseFlag, paused, exitFlag;

    // Rendering
    SDL_Window *window;
    SDL_Renderer *renderer;

    // Software rendering
    SDL_Surface *screen;
    SDL_Texture *texture;

    // Events
    SDL_Event event;

    // Setup information
    int optVidWidth, optVidHeight,
        optVidDepth, optVFlags,
        optVidAspect, optVidSetup;
    BOOL optVidNative;

    int optResFlags;
    char *optPackFilename;

    // Audio related
    SDL_AudioSpec optAfmt;
    int optAudioSetup;

    int audioStatus;            // Current status of audio output (SDL_AUDIO_PLAYING, etc.)
    DMMutex *audioStreamMutex;
    Uint8 * audioStreamBuf;
    size_t audioStreamLen;      // Length in samples
    Uint32 audioTimePos;        // Approximate audio time (in milliseconds)
    int audioSampleSize;        // Size of one audio sample in bytes (incl. all channels)

    // No-sound audio simulation thread stuff
    SDL_Thread *audioSimThread;
    Uint8 * audioSimBuf;
    size_t audioSimBufSize;
    BOOL audioSimDone;
    int  audioSimDelay;

#ifdef DM_USE_JSS
    JSSMixer *jssDev;
    JSSPlayer *jssPlr;
    int jssFormat;
#endif

#ifdef DM_USE_TREMOR
    DMResource *audioRes;
    size_t audioPos;
#endif

    int    (*demoInit)(struct DMEngineData *);
    int    (*demoInitPreVideo)(struct DMEngineData *);
    int    (*demoInitPostVideo)(struct DMEngineData *);
    int    (*demoRender)(struct DMEngineData *);
    void   (*demoShutdown)(struct DMEngineData *);
    void   (*demoQuit)(struct DMEngineData *);
} DMEngineData;


extern DMEffect *engineEffects;
extern int nengineEffects, nengineEffectsAlloc;


// Effect registration
int       engineRegisterEffect(const DMEffect *ef);
int       engineInitializeEffects(DMEngineData *);
void      engineShutdownEffects(DMEngineData *);
DMEffect *engineFindEffect(const char *name, const int nparams);
DMEffect *engineFindEffectByName(const char *name);


#ifdef DM_USE_TIMELINE
// 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, DMEngineData *engine, int time);


// Editing/saving related functions
int  dmCopyTimelinePoints(const DMTimelinePoints *src, DMTimelinePoints *dst);
int  dmCopyTimelineEventParam(const DMTimelineEventParam *src, DMTimelineEventParam *dst);
int  dmCopyTimelineEvent(const DMTimelineEvent *src, DMTimelineEvent **pdst);
int  dmCopyTimelineCurve(const DMTimelineCurve *src, DMTimelineCurve *dst);
int  dmCopyTimelineTrack(const DMTimelineTrack *src, DMTimelineTrack **pdst);
int  dmCopyTimeline(const DMTimeline *src, DMTimeline **pdst);

int  dmSaveTimeline(DMResource *res, const 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, DMEffect *ef);
int  dmTimelineEventSetEffectByIndex(DMTimelineEvent *event, const int index);
int  dmTimelineEventSetEffectByName(DMTimelineEvent *event, const char *name);

#endif // DM_USE_TIMELINE


// Resource helpers
#define engineGetResImage(eng, x, name) \
    do { \
        if ((x = (SDL_Surface *) engineGetResource(eng, name)) == NULL) \
            return DMERR_INIT_FAIL; \
    } while (0)

#define engineGetResModule(eng, x, name) \
    do { \
        if ((x = (JSSModule *) engineGetResource(eng, name)) == NULL) \
            return DMERR_INIT_FAIL; \
    } while (0)

#define engineFindResource(eng, name) dmResourceFind((eng)->resources, name)


int    engineClassifier(DMResource *res);
void * engineGetResource(DMEngineData *eng, const char *name);
int    engineGetTime(DMEngineData *eng, int t);
int    engineGetTimeDTi(DMEngineData *eng);
int    engineGetTick(DMEngineData *eng);
float  engineGetTimeDT(DMEngineData *eng);

int    engineInitAudioParts(DMEngineData *engine);
void   engineAudioCallback(void *userdata, Uint8 *stream, int len);
void   enginePauseAudio(DMEngineData *engine, int status);
int    engineGetVideoAspect(int width, int height);


// Implemented in actual demo code
int    demoPreInit(DMEngineData *eng);


#ifdef __cplusplus
}
#endif

#endif // DMENGINE_H