X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fglut%2Faudio.c;fp=src%2Fglut%2Faudio.c;h=c776d3bb0c2123feb46af70373d115d93f7349c2;hp=0000000000000000000000000000000000000000;hb=09e214b94e007964189222cca1e655f3aaefaf90;hpb=b2c24e9d5b637bb78d18a377d9957c07d0759030 diff --git a/src/glut/audio.c b/src/glut/audio.c new file mode 100644 index 0000000..c776d3b --- /dev/null +++ b/src/glut/audio.c @@ -0,0 +1,237 @@ +#include +#include +#include +#include +#if defined(__WATCOMC__) || defined(_WIN32) || defined(__DJGPP__) +#include +#else +#include +#endif +#include "mikmod.h" +#include "audio.h" + +#ifdef _WIN32 +#include +#else +#include +#include +#endif + +#define SET_MUS_VOL(vol) \ + do { \ + int mv = (vol) * vol_master >> 9; \ + Player_SetVolume(mv ? mv + 1 : 0); \ + } while(0) + +static struct au_module *curmod; +static int vol_master, vol_mus, vol_sfx; + +#ifdef _WIN32 +static DWORD WINAPI upd_thread(void *cls); +#else +static void *update(void *cls); +#endif + +int au_init(void) +{ + curmod = 0; + vol_master = vol_mus = vol_sfx = 255; + +#if defined(__linux__) + MikMod_RegisterDriver(&drv_alsa); +#elif defined(__FreeBSD__) + MikMod_RegisterDriver(&drv_oss); +#elif defined(__sgi__) + MikMod_RegisterDriver(&drv_sgi); +#elif defined(_WIN32) + MikMod_RegisterDriver(&drv_ds); +#else + MikMod_RegisterDriver(&drv_nos); +#endif + + MikMod_RegisterLoader(&load_it); + MikMod_RegisterLoader(&load_mod); + MikMod_RegisterLoader(&load_s3m); + MikMod_RegisterLoader(&load_xm); + + if(MikMod_Init("")) { + fprintf(stderr, "failed ot initialize mikmod: %s\n", MikMod_strerror(MikMod_errno)); + return -1; + } + MikMod_InitThreads(); + + { +#ifdef _WIN32 + HANDLE thr; + if((thr = CreateThread(0, 0, update, 0, 0, 0))) { + CloseHandle(thr); + } +#else + pthread_t upd_thread; + if(pthread_create(&upd_thread, 0, update, 0) == 0) { + pthread_detach(upd_thread); + } +#endif + } + return 0; +} + +void au_shutdown(void) +{ + curmod = 0; + MikMod_Exit(); +} + +struct au_module *au_load_module(const char *fname) +{ + struct au_module *mod; + MODULE *mikmod; + char *name = 0, *end; + + if(!(mod = malloc(sizeof *mod))) { + fprintf(stderr, "au_load_module: failed to allocate module\n"); + return 0; + } + + if(!(mikmod = Player_Load(fname, 128, 0))) { + fprintf(stderr, "au_load_module: failed to load module: %s: %s\n", + fname, MikMod_strerror(MikMod_errno)); + free(mod); + return 0; + } + mod->impl = mikmod; + + if(mikmod->songname && *mikmod->songname) { + name = alloca(strlen(mikmod->songname) + 1); + strcpy(name, mikmod->songname); + + end = name + strlen(name) - 1; + while(end >= name && isspace(*end)) { + *end-- = 0; + } + if(!*name) name = 0; + } + + if(!name) { + /* fallback to using the filename */ + if((name = strrchr(fname, '/')) || (name = strrchr(fname, '\\'))) { + name++; + } else { + name = (char*)fname; + } + } + + if(!(mod->name = malloc(strlen(name) + 1))) { + fprintf(stderr, "au_load_module: mod->name malloc failed\n"); + Player_Free(mod->impl); + free(mod); + return 0; + } + strcpy(mod->name, name); + + printf("loaded module \"%s\" (%s)\n", name, fname); + return mod; +} + +void au_free_module(struct au_module *mod) +{ + if(!mod) return; + + if(mod == curmod) { + au_stop_module(curmod); + } + Player_Free(mod->impl); + free(mod->name); + free(mod); +} + +int au_play_module(struct au_module *mod) +{ + if(curmod) { + if(curmod == mod) return 0; + au_stop_module(curmod); + } + + Player_Start(mod->impl); + SET_MUS_VOL(vol_mus); + curmod = mod; + return 0; +} + +void au_update(void) +{ + if(!curmod) return; + + if(!Player_Active()) { + Player_Stop(); + curmod = 0; + } +} + +#ifdef _WIN32 +static DWORD WINAPI upd_thread(void *cls); +#else +static void *update(void *cls) +#endif +{ + for(;;) { + if(Player_Active()) { + MikMod_Update(); + } +#ifdef _WIN32 + Sleep(10); +#else + usleep(10000); +#endif + } + return 0; +} + +int au_stop_module(struct au_module *mod) +{ + if(mod && curmod != mod) return -1; + if(!curmod) return -1; + + Player_Stop(); + curmod = 0; + return 0; +} + +int au_module_state(struct au_module *mod) +{ + if(mod) { + return curmod == mod ? AU_PLAYING : AU_STOPPED; + } + return curmod ? AU_PLAYING : AU_STOPPED; +} + +int au_volume(int vol) +{ + AU_VOLADJ(vol_master, vol); + if(vol != vol_master) { + vol_master = vol; + + au_sfx_volume(vol_sfx); + au_music_volume(vol_mus); + } + return vol_master; +} + +int au_sfx_volume(int vol) +{ + AU_VOLADJ(vol_sfx, vol); + vol_sfx = vol; + /* TODO */ + return vol_sfx; +} + +int au_music_volume(int vol) +{ + AU_VOLADJ(vol_mus, vol); + vol_mus = vol; + + if(curmod) { + SET_MUS_VOL(vol); + } + return vol_mus; +}