# HG changeset patch # User Matti Hamalainen # Date 1349244986 -10800 # Node ID d5d27f262227f5315b3828cb11da14fb15eda284 # Parent 7160c1d71ade6700972cc40b6a91f68c1cce62c8 Beging merging of dmsimple2-fork into the main "engine". diff -r 7160c1d71ade -r d5d27f262227 Makefile.gen --- a/Makefile.gen Wed Oct 03 08:30:32 2012 +0300 +++ b/Makefile.gen Wed Oct 03 09:16:26 2012 +0300 @@ -29,6 +29,12 @@ DM_CFLAGS+=-DDM_USE_SIMD endif +# Enable Tremor Ogg Vorbis decoder +ifeq ($(DM_USE_TREMOR),yes) +DM_CFLAGS+=-DDM_USE_TREMOR $(TREMOR_CFLAGS) +DM_LDFLAGS+=$(TREMOR_LDFLAGS) +endif + ### ### Filesystem @@ -103,6 +109,7 @@ ### miniJSS ### ifeq ($(JSS),yes) +DM_CFLAGS+=-DDM_USE_JSS ifeq ($(JSS_LIGHT),yes) DM_CFLAGS+=-DJSS_LIGHT -Os diff -r 7160c1d71ade -r d5d27f262227 dmres.h --- a/dmres.h Wed Oct 03 08:30:32 2012 +0300 +++ b/dmres.h Wed Oct 03 09:16:26 2012 +0300 @@ -82,6 +82,7 @@ typedef struct DMResourceDataOps { + BOOL (*probe)(DMResource *res, const char *fext); int (*load)(DMResource *res); void (*free)(DMResource *res); } DMResourceDataOps; diff -r 7160c1d71ade -r d5d27f262227 dmsimple.c --- a/dmsimple.c Wed Oct 03 08:30:32 2012 +0300 +++ b/dmsimple.c Wed Oct 03 09:16:26 2012 +0300 @@ -1,4 +1,8 @@ #include "dmsimple.h" +#ifdef DM_USE_TREMOR +#include +#include +#endif DMEngineData engine; @@ -100,11 +104,20 @@ 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)); @@ -115,39 +128,151 @@ 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 -static DMResourceDataOps engineResImage = + +#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) { - engineResImageLoad, - engineResImageFree + 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 DMResourceDataOps engineResModule = +static int engineResVorbisLoad(DMResource *res) { - engineResModuleLoad, - engineResModuleFree + 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]); + + static int engineClassifier(DMResource *res) { - DMResourceDataOps *rops = NULL; + int i; char *fext; if (res == NULL) return DMERR_NULLPTR; - if ((fext = strrchr(res->filename, '.')) != NULL) + fext = strrchr(res->filename, '.'); + for (i = 0; i < nengineResOps; i++) { - if (strcasecmp(fext, ".png") == 0 || strcasecmp(fext, ".jpg") == 0) - rops = &engineResImage; - else - if (strcasecmp(fext, ".xm") == 0 || strcasecmp(fext, ".jmod") == 0) - rops = &engineResModule; + DMResourceDataOps *rops = &engineResOps[i]; + if (rops->probe != NULL && rops->probe(res, fext)) + { + res->rops = rops; + return DMERR_OK; + } } - res->rops = rops; - return DMERR_OK; } @@ -165,8 +290,8 @@ } -#ifdef DM_DEBUG -static void engineAudioCallbackStream(void *userdata, Uint8 *stream, int len) +#if defined(DM_DEBUG) && defined(DM_USE_JSS) +static void engineAudioCallbackDebug(void *userdata, Uint8 *stream, int len) { if (engine.paused) { @@ -187,6 +312,8 @@ } } +#endif + void engineAdjustTime(int adj) { if (engine.optDebug) @@ -203,8 +330,6 @@ dmPrint(0, "adj=%d, adjtime=%d\n", adj, engine.adjustTime); } } -#endif - static void engineAudioCallback(void *userdata, Uint8 *stream, int len) { @@ -213,11 +338,24 @@ memset(stream, 0, len); } else +#ifdef DM_USE_JSS { JSSMixer *d = (JSSMixer *) userdata; if (d != NULL) jvmRenderAudio(d, stream, len / jvmGetSampleSize(d)); } +#endif +#ifdef DM_USE_TREMOR + if (engine.audioPos + len >= engine.audio->rdataSize) + { + engine.exitFlag = TRUE; + } + else + { + memcpy(stream, engine.audio->rdata + engine.audioPos, len); + engine.audioPos += len; + } +#endif } @@ -225,9 +363,7 @@ { int err; BOOL initSDL = FALSE; - SDL_AudioSpec afmt; - memset(&afmt, 0, sizeof(afmt)); memset(&frame, 0, sizeof(frame)); memset(&engine, 0, sizeof(engine)); @@ -237,7 +373,7 @@ // Initialize resource subsystem dmPrint(1, "Initializing resources subsystem.\n"); - if ((err = dmres_init("orvellys.dat", NULL, DRF_USE_PACK | DRF_PRELOAD_RES, engineClassifier)) != DMERR_OK) + if ((err = dmres_init(engine.optPackFilename, engine.optDataPath, engine.optResFlags, engineClassifier)) != DMERR_OK) { dmError("Could not initialize resource manager: %d, %s.\n", err, dmErrorStr(err)); goto error_exit; @@ -252,17 +388,27 @@ initSDL = TRUE; // Initialize JSS + engine.optAfmt.freq = 44100; + engine.optAfmt.format = AUDIO_S16SYS; + engine.optAfmt.channels = 2; + engine.optAfmt.samples = 16*1024; + + +#ifdef DM_USE_JSS jssInit(); - afmt.freq = 44100; - afmt.format = AUDIO_S16SYS; - afmt.channels = 2; - afmt.samples = 16*1024; + switch (engine.optAfmt.format) + { + case AUDIO_S16SYS: engine.jss.format = JSS_AUDIO_S16; break; + case AUDIO_U16SYS: engine.jss.format = JSS_AUDIO_U16; break; + case AUDIO_S8: engine.jss.format = JSS_AUDIO_S8; break; + case AUDIO_U8: engine.jss.format = JSS_AUDIO_U8; break; + } - dmPrint(1, "Initializing miniJSS mixer with: %d, %d, %d\n", - JSS_AUDIO_S16, afmt.channels, afmt.freq); + dmPrint(1, "Initializing miniJSS mixer with fmt=%d, chn=%d, freq=%d\n", + engine.jss.format, engine.optAfmt.channels, engine.optAfmt.freq); - if ((engine.dev = jvmInit(JSS_AUDIO_S16, afmt.channels, afmt.freq, JMIX_AUTO)) == NULL) + if ((engine.dev = jvmInit(engine.jss.format, engine.optAfmt.channels, engine.optAfmt.freq, JMIX_AUTO)) == NULL) { dmError("jvmInit() returned NULL, voi perkele.\n"); goto error_exit; @@ -273,25 +419,20 @@ dmError("jmpInit() returned NULL\n"); goto error_exit; } +#endif // Initialize SDL audio - dmPrint(1, "Trying to init SDL audio with: %d, %d, %d\n", - afmt.format, afmt.channels, afmt.freq); + dmPrint(1, "Trying to init SDL audio with: fmt=%d, chn=%d, freq=%d\n", + engine.optAfmt.format, engine.optAfmt.channels, engine.optAfmt.freq); -#ifdef DM_DEBUG +#if defined(DM_DEBUG) && defined(DM_USE_JSS) if (engine.optDebug) - { - afmt.callback = engineAudioCallbackStream; - afmt.userdata = (void *) engine.dev; - } + engine.optAfmt.callback = engineAudioCallbackDebug; else #endif - { - afmt.callback = engineAudioCallback; - afmt.userdata = (void *) engine.dev; - } + engine.optAfmt.callback = engineAudioCallback; - if (SDL_OpenAudio(&afmt, NULL) < 0) + if (SDL_OpenAudio(&engine.optAfmt, NULL) < 0) { dmError("Couldn't open audio: %s\n", SDL_GetError()); goto error_exit; @@ -324,7 +465,7 @@ if ((err = demoInit()) != DMERR_OK) goto error_exit; -#ifdef DM_DEBUG +#if defined(DM_DEBUG) && defined(DM_USE_JSS) if (engine.optDebug) { Uint8 *ptr; @@ -419,7 +560,7 @@ SDL_UnlockSurface(engine.screen); SDL_Flip(engine.screen); - SDL_Delay(20); + SDL_Delay(engine.paused ? 100 : 20); // Get frame time, etc frame.endTime = SDL_GetTicks(); @@ -443,11 +584,13 @@ if (engine.screen) SDL_FreeSurface(engine.screen); +#ifdef DM_USE_JSS SDL_LockAudio(); jmpClose(engine.plr); jvmClose(engine.dev); jssClose(); SDL_UnlockAudio(); +#endif dmres_close(); diff -r 7160c1d71ade -r d5d27f262227 dmsimple.h --- a/dmsimple.h Wed Oct 03 08:30:32 2012 +0300 +++ b/dmsimple.h Wed Oct 03 09:16:26 2012 +0300 @@ -6,10 +6,12 @@ #include "dmres.h" #include "dmimage.h" +#ifdef DM_USE_JSS #include "jss.h" #include "jssmod.h" #include "jssmix.h" #include "jssplr.h" +#endif typedef struct @@ -21,10 +23,19 @@ SDL_Surface *screen; SDL_Event event; - int optScrWidth, optScrHeight, optVFlags, optBitDepth; + SDL_AudioSpec optAfmt; + int optScrWidth, optScrHeight, optVFlags, optBitDepth, optResFlags; + char *optDataPath, *optPackFilename; +#ifdef DM_USE_JSS JSSMixer *dev; JSSPlayer *plr; +#endif + +#ifdef DM_USE_TREMOR + DMResource *audio; + int audioPos; +#endif #ifdef DM_DEBUG BOOL optDebug; diff -r 7160c1d71ade -r d5d27f262227 dmtext.h --- a/dmtext.h Wed Oct 03 08:30:32 2012 +0300 +++ b/dmtext.h Wed Oct 03 09:16:26 2012 +0300 @@ -57,6 +57,15 @@ void dmDrawBMTextConst(SDL_Surface *screen, DMBitmapFont *font, int mode, int xc, int yc, const char *str); void dmDrawBMTextVA(SDL_Surface *screen, DMBitmapFont *font, int mode, int xc, int yc, const char *fmt, va_list ap); void dmDrawBMText(SDL_Surface *screen, DMBitmapFont *font, int mode, int xc, int yc, const char *fmt, ...); + + +static inline SDL_Surface *dmGetBMGlyph(DMBitmapFont *font, int ch) +{ + if (ch < 0 || ch >= font->nglyphs || ch == '\n' || ch == '\r') + ch = 32; + + return font->glyphs[ch]; +} #endif