Mercurial > hg > dmlib
diff dmengine.c @ 342:c6ec970dc3cf
Separate some demo engine parts to two different modules.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 15 Oct 2012 21:25:51 +0300 |
parents | |
children | cac13f180169 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dmengine.c Mon Oct 15 21:25:51 2012 +0300 @@ -0,0 +1,266 @@ +#include "dmengine.h" +#include "dmimage.h" + + +#ifdef DM_USE_TREMOR +#include <tremor/ivorbiscodec.h> +#include <tremor/ivorbisfile.h> +#endif + + +DMEngineData engine; +DMFrameData frame; + + +int engineGetTick() +{ + return (frame.startTime - engine.startTime) + engine.adjustTime; +} + + +float engineGetTimeDT() +{ + return (float) engineGetTick() / 1000.0f; +} + + +int engineGetTimeDTi() +{ + return (float) engineGetTick() / 1000; +} + + +int engineGetTime(int t) +{ + return engineGetTick() - (1000 * t); +} + + +int engineGetDT(int t) +{ + return engineGetTime(t) / 1000; +} + + +static int engineResImageLoad(DMResource *res) +{ + SDL_Surface *img = dmLoadImage(res); + if (res != NULL) + { + res->rdata = img; + return DMERR_OK; + } + else + return dmferror(res); +} + + +static void engineResImageFree(DMResource *res) +{ + SDL_FreeSurface((SDL_Surface *)res->rdata); +} + +static BOOL engineResImageProbe(DMResource *res, const char *fext) +{ + (void) res; + return fext != NULL && (strcasecmp(fext, ".jpg") == 0 || strcasecmp(fext, ".png") == 0); +} + + +#ifdef JSS_SUP_XM +static int engineResModuleLoad(DMResource *res) +{ + return jssLoadXM(res, (JSSModule **) &(res->rdata)); +} + +static void engineResModuleFree(DMResource *res) +{ + jssFreeModule((JSSModule *) res->rdata); +} + +static BOOL engineResModuleProbe(DMResource *res, const char *fext) +{ + (void) res; + return fext != NULL && (strcasecmp(fext, ".xm") == 0 || strcasecmp(fext, ".jmod") == 0); +} +#endif + + +#ifdef DM_USE_TREMOR +static size_t vorbisFileRead(void *ptr, size_t size, size_t nmemb, void *datasource) +{ + return dmfread(ptr, size, nmemb, (DMResource *) datasource); +} + +static int vorbisFileSeek(void *datasource, ogg_int64_t offset, int whence) +{ + return dmfseek((DMResource *) datasource, offset, whence); +} + +static int vorbisFileClose(void *datasource) +{ + (void) datasource; + return 0; +} + +static long vorbisFileTell(void *datasource) +{ + return dmftell((DMResource *) datasource); +} + + +static ov_callbacks vorbisFileCBS = +{ + vorbisFileRead, + vorbisFileSeek, + vorbisFileClose, + vorbisFileTell +}; + +static int engineResVorbisLoad(DMResource *res) +{ + OggVorbis_File vf; + + dmMsg(1, "vorbisfile '%s', %d bytes resource loading\n", + res->filename, res->dataSize); + + if (ov_open_callbacks(res, &vf, NULL, 0, vorbisFileCBS) < 0) + return DMERR_FOPEN; + + res->rdataSize = ov_pcm_total(&vf, -1) * 2 * 2; + if ((res->rdata = dmMalloc(res->rdataSize + 16)) == NULL) + { + ov_clear(&vf); + return DMERR_MALLOC; + } + + dmMsg(1, "rdataSize=%d bytes?\n", res->rdataSize); + + BOOL eof = FALSE; + int left = res->rdataSize; + char *ptr = res->rdata; + int current_section; + while (!eof && left > 0) + { + int ret = ov_read(&vf, ptr, left > 4096 ? 4096 : left, ¤t_section); + if (ret == 0) + eof = TRUE; + else + if (ret < 0) + { + ov_clear(&vf); + return DMERR_INVALID_DATA; + } + else + { + left -= ret; + ptr += ret; + } + } + + ov_clear(&vf); + return DMERR_OK; +} + +static void engineResVorbisFree(DMResource *res) +{ + dmFree(res->rdata); +} + +static BOOL engineResVorbisProbe(DMResource *res, const char *fext) +{ + (void) res; + return fext != NULL && (strcasecmp(fext, ".ogg") == 0); +} +#endif + + +static DMResourceDataOps engineResOps[] = +{ + { + engineResImageProbe, + engineResImageLoad, + engineResImageFree + }, + +#ifdef JSS_SUP_XM + { + engineResModuleProbe, + engineResModuleLoad, + engineResModuleFree + }, +#endif + +#ifdef DM_USE_TREMOR + { + engineResVorbisProbe, + engineResVorbisLoad, + engineResVorbisFree + }, +#endif +}; + +static const int nengineResOps = sizeof(engineResOps) / sizeof(engineResOps[0]); + + +int engineClassifier(DMResource *res) +{ + int i; + char *fext; + + if (res == NULL) + return DMERR_NULLPTR; + + fext = strrchr(res->filename, '.'); + for (i = 0; i < nengineResOps; i++) + { + DMResourceDataOps *rops = &engineResOps[i]; + if (rops->probe != NULL && rops->probe(res, fext)) + { + res->rops = rops; + return DMERR_OK; + } + } + + return DMERR_OK; +} + + +void *engineGetResource(const char *name) +{ + DMResource *res = dmres_find(name); + if (res != NULL && res->rdata != NULL) + return res->rdata; + else + { + dmError("Could not find resource '%s'.\n", name); + return NULL; + } +} + + +#ifdef DM_USE_JSS +void engineGetJSSInfo(BOOL *playing, int *order, JSSPattern **pat, int *npattern, int *row) +{ + JSS_LOCK(engine.plr); + + *playing = engine.plr->isPlaying; + *row = engine.plr->row; + *pat = engine.plr->pattern; + *npattern = engine.plr->npattern; + *order = engine.plr->order; + + JSS_UNLOCK(engine.plr); +} + +void engineGetJSSChannelInfo(const int channel, int *ninst, int *nextInst, int *freq, int *note) +{ + JSS_LOCK(engine.plr); + JSSPlayerChannel *chn = &(engine.plr->channels[channel]); + *ninst = chn->ninstrument; + *nextInst = chn->nextInstrument; + *freq = chn->freq; + *note = chn->note; + JSS_UNLOCK(engine.plr); +} +#endif