DOOM64-RE

DOOM 64 Reverse Engineering
Log | Files | Refs | README | LICENSE

s_sound.c (6992B)


      1 /* s_sound.c */
      2 #include "doomdef.h"
      3 #include "p_local.h"
      4 #include "r_local.h"
      5 
      6 #define AUDIO_HEAP_SIZE	(0x44800)
      7 extern u64 audio_heap[AUDIO_HEAP_SIZE / sizeof(u64)];//80325800
      8 
      9 extern char _doom64_wmdSegmentRomStart[], _doom64_wmdSegmentRomEnd[];
     10 extern char _doom64_wsdSegmentRomStart[], _doom64_wsdSegmentRomEnd[];
     11 extern char _doom64_wddSegmentRomStart[], _doom64_wddSegmentRomEnd[];
     12 
     13 #define SYS_FRAMES_PER_SEC 30
     14 
     15 void S_Error_Callback_Routine(char *errstring, int errnum1, int errnum2) // 80029580
     16 {
     17     I_Error(errstring, errnum1, errnum2);
     18 }
     19 
     20 extern int SfxVolume;
     21 extern int MusVolume;
     22 
     23 extern void wess_set_tweaks2(WessTweakAttr *attr);
     24 extern void wess_get_tweaks2(WessTweakAttr *attr);
     25 
     26 void S_Init(void) // 80029590
     27 {
     28 	int audioHeapEnd;
     29 	int wmdlength;
     30 	int loaded;
     31 	int modulesize;
     32 	int seqsize, seqtblsize;
     33 	char *moduleptr;
     34 	char *seqptr, *seqtblptr;
     35 	u32 old_ovmemptr;
     36 	void *tempram;
     37 
     38 	WessTweakAttr tweak;
     39 	WessConfig wess_config;
     40 	ALHeap sys_aheap;
     41 
     42 	//PRINTF_D(WHITE, "S_Init: Start");
     43 
     44 	alHeapInit(&sys_aheap, (u8 *)audio_heap, AUDIO_HEAP_SIZE);
     45 
     46 	//PRINTF_D(WHITE, "base %x", (int)&sys_aheap.base);
     47 	//PRINTF_D(WHITE, "cur %x", (int)&sys_aheap.cur);
     48 	//PRINTF_D(WHITE, "len %d", sys_aheap.len);
     49 	//PRINTF_D(WHITE, "count %d", sys_aheap.count);
     50 
     51 	wess_set_error_callback(S_Error_Callback_Routine);
     52 
     53 	/* tweak audio */
     54 	wess_get_tweaks(&tweak);
     55 
     56 	tweak.mask = TWEAK_DMA_BUFFERS | TWEAK_DMA_MESSAGES | TWEAK_DMA_BUFFER_LENGTH;
     57 	tweak.dma_buffers = 40;
     58 	tweak.dma_messages = 56;
     59 	tweak.dma_buffer_length = 0x600;
     60 	wess_set_tweaks(&tweak);
     61 
     62 	/* init audio */
     63 	wess_config.heap_ptr = &sys_aheap;
     64 	wess_config.outputsamplerate = 22050;
     65 	wess_config.maxACMDSize = 1024 * 3;
     66 	wess_config.wdd_location = _doom64_wddSegmentRomStart;
     67 	wess_config.reverb_id = WESS_REVERB_BIGROOM;
     68 	wess_config.revtbl_ptr = 0;
     69 	wess_config.audioframerate = (f32)SYS_FRAMES_PER_SEC;
     70 
     71 	wess_init(&wess_config);
     72 
     73 	//PRINTF_D(WHITE, "heap_ptr %x", (int)&wess_config.heap_ptr);
     74 	//PRINTF_D(WHITE, "outputsamplerate %d", wess_config.outputsamplerate);
     75 	//PRINTF_D(WHITE, "maxACMDSize %d", wess_config.maxACMDSize);
     76 	//PRINTF_D(WHITE, "wdd_location %x", (int)&wess_config.wdd_location);
     77 	//PRINTF_D(WHITE, "reverb_id %d", wess_config.reverb_id);
     78 	//PRINTF_D(WHITE, "revtbl_ptr %d", wess_config.revtbl_ptr);
     79 	//PRINTF_D(WHITE, "audioframerate %f", (f32)wess_config.audioframerate);
     80 
     81 	// now we load the .wmd image into a temporary ram space
     82 	modulesize = wess_size_module(_doom64_wmdSegmentRomStart);
     83 	modulesize = (modulesize + 15 & ~15);
     84 	moduleptr = alHeapAlloc(&sys_aheap, 1, modulesize);
     85 	//PRINTF_D(WHITE, "modulesize %d", modulesize);
     86 	//PRINTF_D(WHITE, "moduleptr %x", (int)&moduleptr);
     87 
     88 	loaded = wess_load_module(_doom64_wmdSegmentRomStart, moduleptr, modulesize);
     89 	//PRINTF_D(WHITE, "loaded %d", loaded);
     90 
     91 
     92 	seqtblsize = wess_seq_loader_sizeof(wess_get_master_status(), _doom64_wsdSegmentRomStart);
     93 	seqtblsize = (seqtblsize + 15 & ~15);
     94 	seqtblptr = alHeapAlloc(&sys_aheap, 1, seqtblsize);
     95 	//PRINTF_D(WHITE, "seqtblsize %d", seqtblsize);
     96 	//PRINTF_D(WHITE, "seqtblptr %x", (int)&seqtblptr);
     97 
     98 	//this call may result in decompression callbacks
     99 	wess_seq_loader_init(wess_get_master_status(), _doom64_wsdSegmentRomStart, NoOpenSeqHandle, seqtblptr, seqtblsize);
    100 
    101 	seqsize = wess_seq_range_sizeof(0, wess_seq_loader_count());
    102 	seqtblsize = (seqsize + 15 & ~15);
    103 	seqptr = alHeapAlloc(&sys_aheap, 1, seqsize);
    104 
    105 	//PRINTF_D(WHITE, "seqsize %d", seqsize);
    106 	//PRINTF_D(WHITE, "seqptr %x", (int)&seqptr);
    107 
    108 	//this call may result in decompression callbacks
    109 	wess_seq_range_load(0, wess_seq_loader_count(), seqptr);
    110 
    111 	audioHeapEnd = (int)alHeapAlloc(&sys_aheap, 1, 4) - (int)&audio_heap;
    112 	audioHeapEnd += 16;
    113 
    114 	//PRINTF_D(WHITE, "audioHeapEnd %x", audioHeapEnd);
    115 
    116 	if (audioHeapEnd > AUDIO_HEAP_SIZE)
    117 		I_Error("S_Init: Audio heap overflow");
    118 
    119 	S_SetSoundVolume(SfxVolume);
    120 	S_SetMusicVolume(MusVolume);
    121 
    122 	//PRINTF_D(WHITE, "S_Init: End");
    123 
    124 	//while(1){}
    125 }
    126 
    127 void S_SetSoundVolume(int volume) // 800297A8
    128 {
    129   wess_master_sfx_vol_set((char)((volume * 85) / 100));
    130 }
    131 
    132 void S_SetMusicVolume(int volume) // 800297F4
    133 {
    134   wess_master_mus_vol_set((char)((volume * 110) / 100));
    135 }
    136 
    137 int music_sequence; // 8005b250
    138 
    139 void S_StartMusic(int mus_seq) // 8002983C
    140 {
    141     if (disabledrawing == false)
    142     {
    143         wess_seq_trigger(mus_seq);
    144         music_sequence = mus_seq;
    145     }
    146 }
    147 
    148 void S_StopMusic(void) // 80029878
    149 {
    150     wess_seq_stop(music_sequence);
    151     music_sequence = 0;
    152 }
    153 
    154 void S_PauseSound(void) // 800298A4
    155 {
    156     wess_seq_pauseall(YesMute, (REMEMBER_MUSIC|REMEMBER_SNDFX));
    157 }
    158 
    159 void S_ResumeSound(void) // 800298C8
    160 {
    161     wess_seq_restartall(YesVoiceRestart);
    162 }
    163 
    164 void S_StopSound(mobj_t *origin,int seqnum) // 800298E8
    165 {
    166     if (!origin)
    167         wess_seq_stop(seqnum);
    168     else
    169         wess_seq_stoptype((int)origin);
    170 }
    171 
    172 void S_StopAll(void) // 8002991C
    173 {
    174     wess_seq_stopall();
    175 }
    176 
    177 #define SND_INACTIVE 0
    178 #define SND_PLAYING 1
    179 
    180 int S_SoundStatus(int seqnum) // 8002993C
    181 {
    182     if (wess_seq_status(seqnum) == SEQUENCE_PLAYING)
    183         return SND_PLAYING;
    184     else
    185         return SND_INACTIVE;
    186 }
    187 
    188 void S_StartSound(mobj_t *origin, int sound_id) // 80029970
    189 {
    190 	int flags;
    191 	int vol;
    192 	int pan;
    193 	TriggerPlayAttr attr;
    194 
    195 	if (disabledrawing == false)
    196 	{
    197 		if (origin && (origin != cameratarget))
    198 		{
    199 			if (!S_AdjustSoundParams(cameratarget, origin, &vol, &pan))
    200 			{
    201 				return;
    202 			}
    203 		}
    204 		else
    205 		{
    206 			vol = 127;
    207 			pan = 64;
    208 		}
    209 
    210 		attr.mask = (TRIGGER_VOLUME | TRIGGER_PAN | TRIGGER_REVERB);
    211 		attr.volume = (char)vol;
    212 		attr.pan = (char)pan;
    213 
    214 		attr.reverb = 0;
    215 
    216 		if (origin)
    217 		{
    218 			flags = origin->subsector->sector->flags;
    219 
    220 			if (flags & MS_REVERB) {
    221 				attr.reverb = 16;
    222 			}
    223 			else if (flags & MS_REVERBHEAVY) {
    224 				attr.reverb = 32;
    225 			}
    226 		}
    227 
    228 		wess_seq_trigger_type_special(sound_id, (unsigned long)origin, &attr);
    229 	}
    230 }
    231 
    232 #define S_CLIPPING_DIST     (1700)
    233 #define S_MAX_DIST          (127 * S_CLIPPING_DIST)
    234 #define S_CLOSE_DIST        (200)
    235 #define S_ATTENUATOR        (S_CLIPPING_DIST - S_CLOSE_DIST)
    236 #define S_STEREO_SWING      (96)
    237 
    238 int S_AdjustSoundParams(mobj_t *listener, mobj_t *origin, int* vol, int* pan) // 80029A48
    239 {
    240 	fixed_t approx_dist;
    241 	angle_t angle;
    242 
    243 	approx_dist = P_AproxDistance(listener->x - origin->x, listener->y - origin->y);
    244 	approx_dist >>= FRACBITS;
    245 
    246 	if (approx_dist > S_CLIPPING_DIST) {
    247 		return 0;
    248 	}
    249 
    250 	if (listener->x != origin->x || listener->y != origin->y)
    251 	{
    252 		/* angle of source to listener */
    253 		angle = R_PointToAngle2(listener->x, listener->y, origin->x, origin->y);
    254 
    255 		if (angle <= listener->angle) {
    256 			angle += 0xffffffff;
    257 		}
    258 		angle -= listener->angle;
    259 
    260 		/* stereo separation */
    261 		*pan = (128 - ((finesine[angle >> ANGLETOFINESHIFT] * S_STEREO_SWING) >> FRACBITS)) >> 1;
    262 	}
    263 	else
    264 	{
    265 		*pan = 64;
    266 	}
    267 
    268 	/* volume calculation */
    269 	if (approx_dist < S_CLOSE_DIST)
    270 	{
    271 		*vol = 127;
    272 	}
    273 	else
    274 	{
    275 		/* distance effect */
    276 		approx_dist = -approx_dist; /* set neg */
    277 		*vol = (((approx_dist << 7) - approx_dist) + S_MAX_DIST) / S_ATTENUATOR;
    278 	}
    279 
    280 	return (*vol > 0);
    281 }