view src/dmengine.h @ 2576:812b16ee49db

I had been living under apparent false impression that "realfft.c" on which the FFT implementation in DMLIB was basically copied from was released in public domain at some point, but it could very well be that it never was. Correct license is (or seems to be) GNU GPL. Thus I removing the code from DMLIB, and profusely apologize to the author, Philip Van Baren. It was never my intention to distribute code based on his original work under a more liberal license than originally intended.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 11 Mar 2022 16:32:50 +0200
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