diff --git a/game/enemy.c b/game/enemy.c index 487ddb1..b4868ed 100644 --- a/game/enemy.c +++ b/game/enemy.c @@ -265,7 +265,7 @@ static void register_mob_sounds(int hlptr,word *sounds) z=sounds[i]; if (z) { - def_handle(hlptr,sound_table[z-1],wav_load,SR_ZVUKY); + def_handle(hlptr,sound_table[z-1],soundfx_load,SR_ZVUKY); } hlptr++; } diff --git a/game/globals.h b/game/globals.h index 415eaaf..17670a4 100644 --- a/game/globals.h +++ b/game/globals.h @@ -650,7 +650,7 @@ const void *pcx_8bit_decomp(const void *p, int32_t *s, int h); const void *hi_8bit_correct(const void *p, int32_t *s, int h); const void *pcx_8bit_nopal(const void *p, int32_t *s, int h); const void *set_background(const void *p, int32_t *s, int h); -const void *wav_load(const void *p, int32_t *s, int h); +const void *soundfx_load(const void *p, int32_t *s, int h); const void *load_mob_legacy_format_direct(const void *p, int32_t *s, int h); const void *load_mob_legacy_format(const void *p, int32_t *s, int h); const void *load_spells_legacy_format(const void *p, int32_t *s, int h); diff --git a/game/inv.c b/game/inv.c index 7ab5763..9292e4b 100644 --- a/game/inv.c +++ b/game/inv.c @@ -206,7 +206,7 @@ void load_items() break; case SV_SNDLIST: hs=hl_ptr; - prepare_graphics(&hl_ptr,(char *)p,size,wav_load,SR_ZVUKY); + prepare_graphics(&hl_ptr,(char *)p,size,soundfx_load,SR_ZVUKY); sound_handle=hs-1; free(p); break; diff --git a/game/kouzla.c b/game/kouzla.c index db728c1..8b55312 100644 --- a/game/kouzla.c +++ b/game/kouzla.c @@ -362,9 +362,9 @@ void spell_anim(char *name) void spell_sound(char *name) { int i; - i=find_handle(name,wav_load); + i=find_handle(name,soundfx_load); if (i==-1) i=end_ptr++; - def_handle(i,name,wav_load,SR_ZVUKY); + def_handle(i,name,soundfx_load,SR_ZVUKY); play_sample_at_channel(i,0,100); } diff --git a/game/skeldal.c b/game/skeldal.c index ced4e62..0aa5264 100644 --- a/game/skeldal.c +++ b/game/skeldal.c @@ -159,24 +159,24 @@ TDREGISTERS registred[]= {H_POWERLED,"powerled.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_POSTAVY_DAT,"postavy.dat",NULL,SR_MAP}, {H_SOUND_DAT,"sound.dat",NULL,SR_MAP}, - {H_SND_SWHIT1,"swd_hit0.wav",wav_load,SR_ZVUKY}, - {H_SND_SWHIT2,"swd_hit1.wav",wav_load,SR_ZVUKY}, - {H_SND_SWMISS1,"swd_mis0.wav",wav_load,SR_ZVUKY}, - {H_SND_SWMISS2,"swd_mis1.wav",wav_load,SR_ZVUKY}, - {H_SND_SIP1,"sip2.wav",wav_load,SR_ZVUKY}, - {H_SND_SIP2,"sip1.wav",wav_load,SR_ZVUKY}, - {H_SND_KNIHA,"kniha.wav",wav_load,SR_ZVUKY}, - {H_SND_OBCHOD,"obchod.wav",wav_load,SR_ZVUKY}, - {H_SND_LEKTVAR,"lektvar.wav",wav_load,SR_ZVUKY}, - {H_SND_TELEPIN,"telepin.wav",wav_load,SR_ZVUKY}, - {H_SND_TELEPOUT,"telepout.wav",wav_load,SR_ZVUKY}, - {H_SND_HEK1M,"jauu1m.wav",wav_load,SR_ZVUKY}, - {H_SND_HEK2M,"jauu2m.wav",wav_load,SR_ZVUKY}, - {H_SND_HEK1F,"jauu1f.wav",wav_load,SR_ZVUKY}, - {H_SND_HEK2F,"jauu2f.wav",wav_load,SR_ZVUKY}, - {H_SND_EAT,"jidlo.wav",wav_load,SR_ZVUKY}, - {H_SND_WEAR,"obleci.wav",wav_load,SR_ZVUKY}, - {H_SND_PUTINV,"put_inv.wav",wav_load,SR_ZVUKY}, + {H_SND_SWHIT1,"swd_hit0.wav",soundfx_load,SR_ZVUKY}, + {H_SND_SWHIT2,"swd_hit1.wav",soundfx_load,SR_ZVUKY}, + {H_SND_SWMISS1,"swd_mis0.wav",soundfx_load,SR_ZVUKY}, + {H_SND_SWMISS2,"swd_mis1.wav",soundfx_load,SR_ZVUKY}, + {H_SND_SIP1,"sip2.wav",soundfx_load,SR_ZVUKY}, + {H_SND_SIP2,"sip1.wav",soundfx_load,SR_ZVUKY}, + {H_SND_KNIHA,"kniha.wav",soundfx_load,SR_ZVUKY}, + {H_SND_OBCHOD,"obchod.wav",soundfx_load,SR_ZVUKY}, + {H_SND_LEKTVAR,"lektvar.wav",soundfx_load,SR_ZVUKY}, + {H_SND_TELEPIN,"telepin.wav",soundfx_load,SR_ZVUKY}, + {H_SND_TELEPOUT,"telepout.wav",soundfx_load,SR_ZVUKY}, + {H_SND_HEK1M,"jauu1m.wav",soundfx_load,SR_ZVUKY}, + {H_SND_HEK2M,"jauu2m.wav",soundfx_load,SR_ZVUKY}, + {H_SND_HEK1F,"jauu1f.wav",soundfx_load,SR_ZVUKY}, + {H_SND_HEK2F,"jauu2f.wav",soundfx_load,SR_ZVUKY}, + {H_SND_EAT,"jidlo.wav",soundfx_load,SR_ZVUKY}, + {H_SND_WEAR,"obleci.wav",soundfx_load,SR_ZVUKY}, + {H_SND_PUTINV,"put_inv.wav",soundfx_load,SR_ZVUKY}, {H_RUNEBAR1,"r_ohen.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_RUNEBAR2,"r_voda.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_RUNEBAR3,"r_zeme.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, @@ -206,17 +206,17 @@ TDREGISTERS registred[]= {H_LODKA5,"lesda26a.pcx",pcx_fade_decomp,SR_GRAFIKA}, {H_LODKA6,"lesda27a.pcx",pcx_fade_decomp,SR_GRAFIKA}, {H_LODKA7,"lesda28a.pcx",pcx_fade_decomp,SR_GRAFIKA}, - {H_FLETNA,"fletna.wav",wav_load,SR_ZVUKY}, + {H_FLETNA,"fletna.wav",soundfx_load,SR_ZVUKY}, {H_FLETNA_BAR,"stupnice.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_FLETNA_MASK,"stupni_m.pcx",pcx_8bit_nopal,SR_BGRAFIKA}, - {H_SND_SEVER,"sever.wav",wav_load,SR_ZVUKY}, - {H_SND_VYCHOD,"vychod.wav",wav_load,SR_ZVUKY}, - {H_SND_JIH,"jih.wav",wav_load,SR_ZVUKY}, - {H_SND_ZAPAD,"zapad.wav",wav_load,SR_ZVUKY}, - {H_SND_RAND1,"random1.wav",wav_load,SR_ZVUKY}, - {H_SND_RAND2,"random2.wav",wav_load,SR_ZVUKY}, - {H_SND_RAND3,"random3.wav",wav_load,SR_ZVUKY}, - {H_SND_RAND4,"random4.wav",wav_load,SR_ZVUKY}, + {H_SND_SEVER,"sever.wav",soundfx_load,SR_ZVUKY}, + {H_SND_VYCHOD,"vychod.wav",soundfx_load,SR_ZVUKY}, + {H_SND_JIH,"jih.wav",soundfx_load,SR_ZVUKY}, + {H_SND_ZAPAD,"zapad.wav",soundfx_load,SR_ZVUKY}, + {H_SND_RAND1,"random1.wav",soundfx_load,SR_ZVUKY}, + {H_SND_RAND2,"random2.wav",soundfx_load,SR_ZVUKY}, + {H_SND_RAND3,"random3.wav",soundfx_load,SR_ZVUKY}, + {H_SND_RAND4,"random4.wav",soundfx_load,SR_ZVUKY}, {H_CHARGEN,"chargen.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_CHARGENB,"chargenb.pcx",pcx_8bit_decomp,SR_BGRAFIKA}, {H_CHARGENM,"chargenm.pcx",pcx_8bit_nopal,SR_BGRAFIKA}, diff --git a/game/sndandmus.c b/game/sndandmus.c index e6535de..1399d4f 100644 --- a/game/sndandmus.c +++ b/game/sndandmus.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "globals.h" #include @@ -227,45 +228,25 @@ int set_channel_volume_from_sector(int channel, } -/*int calcul_volume(int chan,int x,int y,int side,int volume) - { - int lv,rv; - int ds,bal,i; - - if (side==-1) side=viewdir; - side&=3; - ds=calc_volume(&x,&y,side); - if (ds<=0) - { - release_channel(chan); - return -1; - } - for(i=0;ifreq = 1000; + hdr->chans = 1; + hdr->bps = 1000; + hdr->wav_mode = 1; + *sz = 1000; + for (int i = 0; i < 1000; ++i) { + data[i] = (i & 8)?64:192; } - y=abs(y); - if (abs(x)>y) - if (x>0) bal=100-y*50/x;else bal=-100-y*50/x; - else bal=50*x/y; - ds=ds*volume/100; - if (bal<0) - { - lv=ds*(100+bal)/100;rv=ds; - } - else - { - rv=ds*(100-bal)/100;lv=ds; - } - lv=(lv*sample_volume)>>8; - rv=(rv*sample_volume)>>8; - set_channel_volume(chan,lv,rv); - return 0; - } -*/ -const void *wav_load(const void *p, int32_t *s, int h) + return d; +} + + +static const void *wav_load(const void *p, int32_t *s, int h) { const char *sr; char *tg; @@ -273,10 +254,12 @@ const void *wav_load(const void *p, int32_t *s, int h) struct t_wave x[3]; sr=p; - sr=find_chunk(sr,WAV_FMT); + sr=find_chunk(sr,WAV_FMT, sr + *s); + if (sr == NULL) return err_sound_load(p, s, h); read_chunk(sr,&x); sr=p; - sr=find_chunk(sr,WAV_DATA); + sr=find_chunk(sr,WAV_DATA, sr+*s); + if (sr == NULL) return err_sound_load(p, s, h); *s=get_chunk_size(sr); tgr=tg=getmem(*s+sizeof(struct t_wave)+4); memcpy(tgr,x,sizeof(struct t_wave)); @@ -289,6 +272,75 @@ const void *wav_load(const void *p, int32_t *s, int h) return tgr; } +static const void *mp3_load(const void *p, int32_t *s, int h) { + const uint8_t *ptr = (const uint8_t *)p; + size_t count_samples = 0; + size_t sz = *s; + size_t ofs = 0; + mp3dec_t decoder; + mp3d_sample_t pcm[MINIMP3_MAX_SAMPLES_PER_FRAME]; + mp3dec_frame_info_t frame; + + mp3dec_init(&decoder); + while (ofsbps = frame.hz * 2; + hdr->chans = 1; + hdr->freq = frame.hz; + hdr->wav_mode = 1; + uint32_t *len = (uint32_t *)(hdr+1); + *len = count_samples * 2; + uint16_t *data = (uint16_t *)(len+1); + mp3dec_init(&decoder); + ofs = 0; + int wrofs = 0; + while (ofs < sz) { + int samples = mp3dec_decode_frame(&decoder, ptr+ofs, sz - ofs, pcm, &frame); + if (samples == 0) { + ++ofs; + } else { + ofs += frame.frame_bytes; + for (int i = 0; i < samples; i+=frame.channels) { + if (frame.channels == 1) { + data[wrofs] = pcm[i]; + } else if (frame.channels> 1) { //only mono are supported, downgrade + data[wrofs] = (pcm[i] + pcm[i+1]) / 2; + } + ++wrofs; + } + + } + } + return trg; +} + +const void *soundfx_load(const void *p, int32_t *s, int h) { + if (*s >= 12) { + const char *hdr =(const char *)p; + if (hdr[0] == 'R' && hdr[1] == 'I' && hdr[2] == 'F' && hdr[3] == 'F') { + return wav_load(p,s,h); + } + if ((hdr[0] == 'I' && hdr[1] == 'D' && hdr[2] == '3') + || (hdr[0]==0xFF && (hdr[1] & 0xE0))) { + return mp3_load(p,s,h); + } + } + return err_sound_load(p, s, h);; +} + + void play_effekt(int x,int y,int xd,int yd,int sector,int side,const TMA_SOUND *p) { int chan; diff --git a/libs/wav_mem.c b/libs/wav_mem.c index 81513f9..bbd8aeb 100644 --- a/libs/wav_mem.c +++ b/libs/wav_mem.c @@ -3,19 +3,19 @@ #include #include "wav_mem.h" -const char *find_chunk(const char *wav,char *name) //TODO improve +const char *find_chunk(const char *wav,char *name, const char *wav_end) //TODO improve { int32_t next; wav+=12; - do + while (wav < wav_end) { if (!strncmp(name,wav,4)) return wav+4; wav+=4; memcpy(&next,wav,4); wav+=next+4; } - while (1); + return NULL; } int get_chunk_size(const char *wav) diff --git a/libs/wav_mem.h b/libs/wav_mem.h index c4083b1..6589802 100644 --- a/libs/wav_mem.h +++ b/libs/wav_mem.h @@ -15,7 +15,7 @@ typedef struct t_wave int32_t freq,bps; }T_WAVE; -const char *find_chunk(const char *wav,char *name); +const char *find_chunk(const char *wav,char *name, const char *wav_end); int get_chunk_size(const char *wav); int read_chunk(const char *wav,void *mem);