Index: quarks ================================================================== --- quarks +++ quarks @@ -24,16 +24,16 @@ ! 'r' = RESIZABLE ! 'y' = ASYNCBLIT ! 'z' = NOPARACHUTE ! Audio -sfxVolume -audioBuffer -audioRate -audioFormat -musicVolume -musicFile +audio +rate +buffer +mmlVolume +waveVolume +standardSounds ! Keyboard keyRepeat editKey gameKey Index: quarks.h ================================================================== --- quarks.h +++ quarks.h @@ -7,16 +7,16 @@ #define Q_altImage 8 #define Q_editTitle 9 #define Q_gameTitle 10 #define Q_gamma 11 #define Q_screenFlags 12 -#define Q_sfxVolume 13 -#define Q_audioBuffer 14 -#define Q_audioRate 15 -#define Q_audioFormat 16 -#define Q_musicVolume 17 -#define Q_musicFile 18 +#define Q_audio 13 +#define Q_rate 14 +#define Q_buffer 15 +#define Q_mmlVolume 16 +#define Q_waveVolume 17 +#define Q_standardSounds 18 #define Q_keyRepeat 19 #define Q_editKey 20 #define Q_gameKey 21 #define Q_backspace 22 #define Q_tab 23 @@ -194,16 +194,16 @@ "altImage", "editTitle", "gameTitle", "gamma", "screenFlags", - "sfxVolume", - "audioBuffer", - "audioRate", - "audioFormat", - "musicVolume", - "musicFile", + "audio", + "rate", + "buffer", + "mmlVolume", + "waveVolume", + "standardSounds", "keyRepeat", "editKey", "gameKey", "backspace", "tab", ADDED sound.c Index: sound.c ================================================================== --- sound.c +++ sound.c @@ -0,0 +1,175 @@ +#if 0 +gcc ${CFLAGS:--s -O2} -c -Wno-unused-result sound.c `sdl-config --cflags` +exit +#endif + +#include "SDL.h" +#include +#include +#include +#include +#include "sqlite3.h" +#include "smallxrm.h" +#include "quarks.h" +#include "heromesh.h" + +typedef struct { + Uint8*data; + Uint32 len; // length in bytes +} WaveSound; + +static Uint8 sound_on; +static Sint16 mmlvolume=32767; +static SDL_AudioSpec spec; +static WaveSound*standardsounds; +static Uint16 nstandardsounds; +static WaveSound*usersounds; +static Uint16 nusersounds; +static FILE*l_fp; +static long l_offset,l_size; +static float wavevolume=1.0; +static Uint8 needs_amplify=0; + +static Uint8*volatile wavesound; +static volatile Uint32 wavelen; + +static void audio_callback(void*userdata,Uint8*stream,int len) { + if(wavesound) { + if(wavelenftell(l_fp)+l_size) maxnum=(ftell(l_fp)-l_offset)/size; + return fread(ptr,size,maxnum,l_fp); +} + +static int my_close(SDL_RWops*cxt) { + return 0; +} + +static SDL_RWops my_rwops={ + .seek=my_seek, + .read=my_read, + .close=my_close, +}; + +static void amplify_wave_sound(const WaveSound*ws) { + Uint32 n; + Sint16*b=(Sint16*)ws->data; + Uint32 m=ws->len/sizeof(Sint16); + if(!needs_amplify || !b) return; + for(n=0;ndata=0; + ws->len=0; + l_fp=fp; + l_offset=offset; + l_size=size; + if(!SDL_LoadWAV_RW(&my_rwops,0,&src,&buf,&len)) { + //fprintf(stderr,"[Cannot load wave audio at %ld (%ld bytes): %s]\n",offset,size,SDL_GetError()); + return; + } + memset(&cvt,0,sizeof(SDL_AudioCVT)); + if(SDL_BuildAudioCVT(&cvt,src.format,src.channels,src.freq,spec.format,spec.channels,spec.freq)<0) goto fail; + cvt.buf=malloc(len*cvt.len_mult); + cvt.len=len; + if(!cvt.buf) goto fail; + memcpy(cvt.buf,buf,len); + if(SDL_ConvertAudio(&cvt)) goto fail; + SDL_FreeWAV(buf); + ws->data=cvt.buf; + ws->len=cvt.len; + amplify_wave_sound(ws); + return; + fail: + //fprintf(stderr,"[Failed to convert wave audio at %ld (%ld bytes)]\n",offset,size); + SDL_FreeWAV(buf); +} + +void init_sound(void) { + const char*v; + optionquery[1]=Q_audio; + optionquery[2]=Q_rate; + v=xrm_get_resource(resourcedb,optionquery,optionquery,3); + if(!v) return; + spec.freq=strtol(v,0,10); + optionquery[2]=Q_buffer; + v=xrm_get_resource(resourcedb,optionquery,optionquery,3); + if(!v) return; + spec.samples=strtol(v,0,10); + if(!spec.freq || !spec.samples) return; + fprintf(stderr,"Initializing audio...\n"); + spec.channels=1; + spec.format=AUDIO_S16SYS; + spec.callback=audio_callback; + if(SDL_InitSubSystem(SDL_INIT_AUDIO)) { + fprintf(stderr,"Cannot initalize audio subsystem.\n"); + return; + } + if(SDL_OpenAudio(&spec,0)) { + fprintf(stderr,"Cannot open audio device.\n"); + return; + } + optionquery[2]=Q_waveVolume; + if(v=xrm_get_resource(resourcedb,optionquery,optionquery,3)) { + needs_amplify=1; + wavevolume=strtod(v,0); + } + + fprintf(stderr,"Done.\n"); + wavesound=0; + SDL_PauseAudio(0); + sound_on=1; +} + +void set_sound_effect(Value v1,Value v2) { + if(!sound_on) return; + if(!v2.t && !v2.u && wavesound) return; + SDL_LockAudio(); + wavesound=0; + switch(v1.t) { + case TY_SOUND: + if(v1.u