Mercurial > hg > dmlib
view dmengine.c @ 570:a26636faa6b7
Update copyright.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 05 Jan 2013 19:58:23 +0200 |
parents | a7ee3567f718 |
children | 14640d0688d3 |
line wrap: on
line source
#include "dmengine.h" #include "dmimage.h" #ifdef DM_USE_TREMOR #include <tremor/ivorbiscodec.h> #include <tremor/ivorbisfile.h> #endif 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) { if (engine != NULL && engine->effectData != NULL) { 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) { 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(DMEngineData *eng, const char *name) { DMResource *res; if (eng != NULL && (res = dmres_find(eng->resources, name)) != NULL && res->rdata != NULL) return res->rdata; else { dmError("Could not find resource '%s'.\n", name); return NULL; } } #ifdef DM_USE_JSS void engineGetJSSInfo(DMEngineData *eng, BOOL *playing, int *order, JSSPattern **pat, int *npattern, int *row) { JSS_LOCK(eng->plr); *playing = eng->plr->isPlaying; *row = eng->plr->row; *pat = eng->plr->pattern; *npattern = eng->plr->npattern; *order = eng->plr->order; JSS_UNLOCK(eng->plr); } void engineGetJSSChannelInfo(DMEngineData *eng, const int channel, int *ninst, int *nextInst, int *freq, int *note) { JSS_LOCK(eng->plr); JSSPlayerChannel *chn = &(eng->plr->channels[channel]); *ninst = chn->ninstrument; *nextInst = chn->nextInstrument; *freq = chn->freq; *note = chn->note; JSS_UNLOCK(eng->plr); } #endif int engineGetTick(DMEngineData *engine) { return engine->frameTime - engine->startTime; } float engineGetTimeDT(DMEngineData *engine) { return (float) engineGetTick(engine) / 1000.0f; } int engineGetTimeDTi(DMEngineData *engine) { return (float) engineGetTick(engine) / 1000; } int engineGetTime(DMEngineData *engine, int t) { return engineGetTick(engine) - (1000 * t); } int engineGetDT(DMEngineData *engine, int t) { return engineGetTime(engine, t) / 1000; }