DOOM64-RE

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

n64cmd.c (29059B)


      1 
      2 /* ULTRA64 LIBRARIES */
      3 #include <ultra64.h>
      4 #include "ultratypes.h"
      5 #include <libaudio.h>
      6 
      7 #include "wessseq.h"
      8 
      9 #include "graph.h"//debug
     10 
     11 #define _ALIGN8_ 1
     12 
     13 #ifndef NOUSEWESSCODE
     14 
     15 extern ALVoice     *voice;         //800B40E0
     16 
     17 void wess_set_mute_release(int millisec);
     18 f32 WessCents2Ratio(s32 cents);
     19 void TriggerN64Voice(voice_status *voice_stat/*, unsigned char keynum, unsigned char velnum*/);
     20 
     21 void N64_DriverInit (track_status *ptk_stat);//(master_status_structure *pm_stat);
     22 void N64_DriverExit (track_status *ptk_stat);
     23 void N64_DriverEntry1 (track_status *ptk_stat);
     24 void N64_DriverEntry2(track_status *ptk_stat);
     25 void N64_DriverEntry3(track_status *ptk_stat);
     26 void N64_TrkOff(track_status *ptk_stat);
     27 void N64_TrkMute(track_status *ptk_stat);
     28 void N64_PatchChg(track_status *ptk_stat);
     29 void N64_PatchMod(track_status *ptk_stat);
     30 void N64_PitchMod(track_status *ptk_stat);
     31 void N64_ZeroMod(track_status *ptk_stat);
     32 void N64_ModuMod(track_status *ptk_stat);
     33 void N64_VolumeMod(track_status *ptk_stat);
     34 void N64_PanMod(track_status *ptk_stat);
     35 void N64_PedalMod(track_status *ptk_stat);
     36 void N64_ReverbMod(track_status *ptk_stat);
     37 void N64_ChorusMod(track_status *ptk_stat);
     38 void N64_voiceon(voice_status *voice_stat, track_status *ptk_stat,
     39 	           patchmaps_header *patchmaps, patchinfo_header *patchinfo,
     40 	           unsigned char keynum, unsigned char velnum);
     41 void N64_voiceparmoff(voice_status *voice_stat);
     42 void N64_voicemuterelease(voice_status *voice_stat, int muterelease);
     43 void N64_voicerelease(voice_status *voice_stat);
     44 void N64_voicedecay(voice_status *voice_stat);
     45 void N64_voicenote(track_status *ptk_stat,
     46 	           patchmaps_header *patchmap, patchinfo_header *patchinfo,
     47 	           unsigned char keynum, unsigned char velnum);
     48 void N64_NoteOn(track_status *ptk_stat);
     49 void N64_NoteOff(track_status *ptk_stat);
     50 
     51 void(*drv_cmds[19])(track_status *) =
     52 {
     53 	N64_DriverInit,         //0x0
     54 	N64_DriverExit,         //0x1
     55 	N64_DriverEntry1,       //0x2
     56 	N64_DriverEntry2,       //0x3
     57 	N64_DriverEntry3,       //0x4
     58 	N64_TrkOff,             //0x5
     59 	N64_TrkMute,            //0x6
     60 	N64_PatchChg,           //0x7
     61 	N64_PatchMod,           //0x8
     62 	N64_PitchMod,           //0x9
     63 	N64_ZeroMod,            //0xA
     64 	N64_ModuMod,            //0xB
     65 	N64_VolumeMod,          //0xC
     66 	N64_PanMod,             //0xD
     67 	N64_PedalMod,           //0xE
     68 	N64_ReverbMod,          //0xF
     69 	N64_ChorusMod,          //0x10
     70 	N64_NoteOn,             //0x11
     71 	N64_NoteOff             //0x12
     72 };
     73 
     74 extern unsigned char	master_sfx_volume;
     75 extern unsigned char	master_mus_volume;
     76 extern unsigned char	pan_status;
     77 extern int	            enabledecay;
     78 
     79 typedef struct NoteData
     80 {
     81 	short	seq_num;				//*8
     82 	short	track;					//*10
     83 	char	keynum;					//*12
     84 	char	velnum;					//*13
     85 	patchmaps_header *patchmap;		//*16 mapptr
     86 	patchinfo_header *patchinfo;	//*20 sampptr
     87 }NoteData;
     88 
     89 typedef struct NoteState
     90 {
     91 	int			numnotes;	//*
     92 	int			remember;	//*4
     93 	NoteData	nd[32];		//*8
     94 }NoteState;//Final Size 520
     95 int i = sizeof(NoteState);
     96 
     97 int							N64_mute_release = 250;	// 8005DB48
     98 master_status_structure		*pmsbase;				// 800B66F0
     99 sequence_status				*pssbase;				// 800B66F4
    100 track_status				*ptsbase;				// 800B66F8
    101 voice_status				*pvsbase;				// 800B66FC
    102 unsigned long				nvss;					// 800B6700
    103 patch_group_data			*ppgd;					// 800B6704
    104 unsigned long				*pcurabstime;			// 800B6708
    105 patches_header				*patchesbase;			// 800B670C
    106 patchmaps_header			*patchmapsbase;			// 800B6710
    107 patchinfo_header			*samplesbase;			// 800B6714
    108 char						*drummapsbase;			// 800B6718
    109 loopinfo_header				*samplesinfochunk;		// 800B671C
    110 ALRawLoop2					*samplesrawloopbase;	// 800B6720
    111 ALADPCMloop2				*samplescmploopbase;	// 800B6724
    112 ALADPCMBook2				*samplescmphdrbase;		// 800B6728
    113 ALRawLoop2					rawloop;				// 800B6730
    114 ALADPCMloop2				cmploop;				// 800B6740
    115 NoteState					*pns = 0;				// 8005DB4C
    116 NoteState					pnotestate;				// 800B6770
    117 s32                         g_wddloc;				// 800B6978
    118 f32							wess_output_ratio = 1.0;// 8005DB50
    119 
    120 enum Snd_Type {Snd_Music, Snd_Sfx};
    121 
    122 extern void (**CmdFuncArr[10])(track_status *);
    123 extern void(*DrvFunctions[36])(track_status *);
    124 
    125 //-----------------------------------------------------------
    126 // Sound System
    127 //-----------------------------------------------------------
    128 
    129 f32 sample_rate = 22050.0;  // 80061A70
    130 void N64_set_output_rate(u32 rate) // 80037750
    131 {
    132 	f32 out_rate;
    133 
    134 	out_rate = (f32)rate;
    135 	if ((s32)rate < 0)
    136 	{
    137 		out_rate += 4.2949673e9;
    138 	}
    139 	wess_output_ratio = (f32)(sample_rate / out_rate);
    140 }
    141 
    142 void N64_wdd_location(char *wdd_location) // 80037788
    143 {
    144 	g_wddloc = (s32)wdd_location;
    145 }
    146 
    147 void start_record_music_mute(int remember) // 80037794
    148 {
    149     if ((int)&pnotestate)
    150 	{
    151 		pnotestate.numnotes = 0;
    152 		pnotestate.remember = remember;
    153 	}
    154 	pns = (NoteState *)&pnotestate;
    155 }
    156 
    157 void end_record_music_mute(void) // 800377C4
    158 {
    159 	pns = (NoteState *)0;
    160 }
    161 
    162 #define REMEMBER_MUSIC   (0x1L<< 0)//1
    163 #define REMEMBER_SNDFX   (0x1L<< 1)//2
    164 
    165 void do_record_music_unmute(int seq_num, int track, track_status *ptk_stat) // 800377D0
    166 {
    167 	int i;
    168 	NoteData *notestate;
    169 
    170 	for(i = 0; i < pnotestate.numnotes; i++)
    171 	{
    172 		notestate = &pnotestate.nd[i];
    173 
    174 		if ((notestate->track == track) && (notestate->seq_num == seq_num) && (notestate->patchmap != 0))
    175 		{
    176 			N64_voicenote(ptk_stat, notestate->patchmap, notestate->patchinfo, notestate->keynum, notestate->velnum);
    177 			notestate->patchmap = (patchmaps_header *)0;
    178 		}
    179 	}
    180 }
    181 
    182 void add_music_mute_note(track_status *ptk_stat,
    183                          unsigned short seq_num,  unsigned short track,
    184                          unsigned char keynum,  unsigned char velnum,
    185                          patchmaps_header *patchmap,
    186                          patchinfo_header *patchinfo) // 800378A8
    187 {
    188 
    189     seq_num = (seq_num << 16) >> 16;
    190     track = (track << 16) >> 16;
    191 
    192 	if (pns != 0)
    193 	{
    194 		if (((ptk_stat->sndclass == MUSIC_CLASS) && (pns->remember & REMEMBER_MUSIC)) ||
    195 			((ptk_stat->sndclass == SNDFX_CLASS) && (pns->remember & REMEMBER_SNDFX)))
    196 		{
    197 			if (pns->numnotes < 32)
    198 			{
    199 				pns->nd[pns->numnotes].seq_num = seq_num;
    200 				pns->nd[pns->numnotes].track = track;
    201 				pns->nd[pns->numnotes].keynum = keynum;
    202 				pns->nd[pns->numnotes].velnum = velnum;
    203 				pns->nd[pns->numnotes].patchmap = patchmap;
    204 				pns->nd[pns->numnotes].patchinfo = patchinfo;
    205 				pns->numnotes++;
    206 			}
    207 		}
    208 	}
    209 }
    210 
    211 void wess_set_mute_release(int millisec) // 800379E4
    212 {
    213 	N64_mute_release = millisec;
    214 }
    215 
    216 int wess_get_mute_release(void) // 800379F0
    217 {
    218 	return N64_mute_release;
    219 }
    220 
    221 f32 WessCents2Ratio(s32 cents) // 80037A00
    222 {
    223 	f32 x;
    224 	f32 ratio = 1.0f;
    225 
    226 	if (cents >= 0) {
    227 		x = 1.00057779f;         /* 2^(1/1200) */ //rate1
    228 	}
    229 	else {
    230 		x = 0.9994225441f;       /* 2^(-1/1200) */ //rate2
    231 		cents = -cents;
    232 	}
    233 
    234 	while (cents) {
    235 		if (cents & 1)
    236 			ratio *= x;
    237 		x *= x;
    238 		cents >>= 1;
    239 	}
    240 
    241 	return ratio * wess_output_ratio;
    242 }
    243 
    244 /*extern unsigned long				drv_pitch1;				//L8007EEB8
    245 extern unsigned long				drv_pitch2;				//L8007EEBC
    246 extern unsigned long				drv_pitch3;				//L8007EEC0
    247 extern unsigned long				drv_volume_1;			//L8007EEC4
    248 extern track_status				    *drv_ptrk_stat;			//L8007EEC8
    249 extern short				        drv_pan_1;				//L8007EECC*/
    250 
    251 void TriggerN64Voice(voice_status *voice_stat) // 80037A64
    252 {
    253 	static track_status		*pts;	  //800B697C
    254 	static long				adjvol;	  //800B6980
    255 	static short			adjpan;	  //800B6984
    256 	static long				adjpitch; //800B6988
    257 	static ALVoiceConfig	config;	  //800b698c
    258 	static float			pitch;	  //800B6994
    259 	static long				deltatime;//800B6998
    260 
    261 	u32 volume;
    262 	s32 priority;
    263 	double fpitch;
    264 
    265 	pts = (ptsbase + voice_stat->track);
    266 
    267 	if (pan_status != 0)
    268 	{
    269 		adjpan = (s32)(((pts->pan_cntrl + voice_stat->patchmaps->pan) - 0x40) << 16) >> 16;
    270 
    271 		if (adjpan < 0)     adjpan = 0;
    272 		if (adjpan > 0x7F)	adjpan = 0x7f;
    273 	}
    274 	else
    275 	{
    276 		adjpan = 0x40;
    277 	}
    278 
    279 	//Volume
    280 	if (pts->sndclass == SNDFX_CLASS)
    281 	{
    282 		volume = voice_stat->velnum * voice_stat->patchmaps->volume * pts->volume_cntrl * master_sfx_volume;
    283 	}
    284 	else
    285 	{
    286 		volume = voice_stat->velnum * voice_stat->patchmaps->volume * pts->volume_cntrl * master_mus_volume;
    287 	}
    288 
    289 	adjvol = voice_stat->patchmaps->attack_level * (volume >> 0xd) >> 7;
    290 
    291 	//Pitch
    292 	if (pts->pitch_cntrl == 0)
    293 	{
    294 		adjpitch = 0;
    295 	}
    296 	else
    297 	{
    298 		if (pts->pitch_cntrl < 1)
    299 		{
    300 			adjpitch = (s32)((f64)(voice_stat->patchmaps->pitchstep_min * pts->pitch_cntrl) * (f64)0.0122);
    301 		}
    302 		else
    303 		{
    304 			adjpitch = (s32)((f64)(voice_stat->patchmaps->pitchstep_max * pts->pitch_cntrl) * (f64)0.0122);
    305 		}
    306 	}
    307 
    308 	//Voice Priority
    309 	priority = voice_stat->priority & 255;
    310 
    311 	if((priority >= 0) && (priority < 128))
    312     {
    313         config.priority = priority;
    314     }
    315     else
    316 	{
    317 		config.priority = 0x7f;
    318 	}
    319 
    320 	config.fxBus = (u16)0;
    321 	config.unityPitch = (u8)0;
    322 
    323 	//PRINTF_D2(WHITE,0,10,"voice_stat->refindx %d   ", voice_stat->refindx);
    324 
    325 	alSynAllocVoice(&alGlobals->drvr, &voice[voice_stat->refindx], &config);
    326 
    327 	pitch = (f32)WessCents2Ratio((voice_stat->patchinfo->pitch + adjpitch + (voice_stat->keynum - voice_stat->patchmaps->root_key) * 100) - voice_stat->patchmaps->fine_adj);
    328 	deltatime = voice_stat->patchmaps->attack_time * 1000;
    329 
    330 	alSynStartVoiceParams(&alGlobals->drvr, &voice[voice_stat->refindx], (ALWaveTable *)&voice_stat->patchinfo->wave, (f32)pitch, (s16)adjvol, (ALPan)adjpan, (u8)pts->reverb, (ALMicroTime)deltatime);
    331 }
    332 //-----------------------------------------------------------
    333 // Driver System
    334 //-----------------------------------------------------------
    335 
    336 void N64_DriverInit (track_status *ptk_stat) // 80037DA8
    337 {
    338     static int vt, mi; //800B699C
    339 
    340 	char *pmem;
    341 	patchinfo_header *sample;
    342 	master_status_structure *pm_stat;
    343 
    344 	pm_stat = (master_status_structure*)ptk_stat;
    345 
    346 	//PRINTF_D2(WHITE,0,7,"N64_DriverInit");
    347 	pmsbase = pm_stat;
    348 
    349 	pcurabstime = pm_stat->pabstime;
    350 	pssbase = pm_stat->pseqstattbl;
    351 	ptsbase = pm_stat->ptrkstattbl;
    352 	pvsbase = pm_stat->pvoicestattbl;
    353 	ppgd = pm_stat->ppat_info;
    354 	nvss = wess_driver_voices;
    355 
    356     //PRINTF_D(WHITE,"pmsbase %x",pmsbase);
    357 	//PRINTF_D(WHITE,"pcurabstime %d",*pcurabstime);
    358 	//PRINTF_D(WHITE,"pssbase %x",pssbase);
    359 	//PRINTF_D(WHITE,"ptsbase %x",ptsbase);
    360 	//PRINTF_D(WHITE,"pvsbase %x",pvsbase);
    361 	//PRINTF_D(WHITE,"ppgd %x",ppgd);
    362 	//PRINTF_D(WHITE,"nvss %d",nvss);
    363 
    364 	pmem = ppgd->ppat_data; /* pointer math temp */
    365 
    366 	patchesbase = (patches_header *)pmem;
    367 	pmem += (unsigned int)(ppgd->pat_grp_hdr.patches * sizeof(patches_header));
    368 	//pmem = ((unsigned int)pmem + 7) & ~7;	/* phrase align everything */
    369 #if _ALIGN8_ == 1
    370 	//force align to word boundary because previous size adjust
    371 	//may wind up with odd address
    372 	pmem += (unsigned int)pmem & 1;
    373 	pmem += (unsigned int)pmem & 2;
    374 	pmem += (unsigned int)pmem & 4;
    375 #endif
    376     //PRINTF_D(WHITE,"patchesbase %d",(ppgd->pat_grp_hdr.patches));//588
    377 
    378 	patchmapsbase = (patchmaps_header *)pmem;
    379 	pmem += (unsigned int)(ppgd->pat_grp_hdr.patchmaps * sizeof(patchmaps_header));
    380 	//pmem = ((unsigned int)pmem + 7) & ~7;	/* phrase align everything */
    381 #if _ALIGN8_ == 1
    382 	//force align to word boundary because previous size adjust
    383 	//may wind up with odd address
    384 	pmem += (unsigned int)pmem & 1;
    385 	pmem += (unsigned int)pmem & 2;
    386 	pmem += (unsigned int)pmem & 4;
    387 #endif
    388     //PRINTF_D(WHITE,"patchmapsbase %d",(ppgd->pat_grp_hdr.patchmaps));//10100
    389 
    390 	samplesbase = (patchinfo_header *)pmem;
    391 	pmem += (unsigned int)(ppgd->pat_grp_hdr.patchinfo * sizeof(patchinfo_header));
    392 	//pmem = ((unsigned int)pmem + 7) & ~7;	/* phrase align everything */
    393 #if _ALIGN8_ == 1
    394 	//force align to word boundary because previous size adjust
    395 	//may wind up with odd address
    396 	pmem += (unsigned int)pmem & 1;
    397 	pmem += (unsigned int)pmem & 2;
    398 	pmem += (unsigned int)pmem & 4;
    399 #endif
    400     //PRINTF_D(WHITE,"samplesbase %d",(ppgd->pat_grp_hdr.patchinfo));//2976
    401 
    402 	drummapsbase = (char *)pmem;
    403 	pmem += (unsigned int)(ppgd->pat_grp_hdr.drummaps * sizeof(char *));
    404 	//pmem = ((unsigned int)pmem + 7) & ~7;	/* phrase align everything */
    405 #if _ALIGN8_ == 1
    406 	//force align to word boundary because previous size adjust
    407 	//may wind up with odd address
    408 	pmem += (unsigned int)pmem & 1;
    409 	pmem += (unsigned int)pmem & 2;
    410 	pmem += (unsigned int)pmem & 4;
    411 #endif
    412     //PRINTF_D(WHITE,"drummapsbase %d",(ppgd->pat_grp_hdr.drummaps * sizeof(char *)));
    413 
    414 	samplesinfochunk = (loopinfo_header *)pmem;
    415 	pmem += sizeof(loopinfo_header);
    416 
    417 	samplesrawloopbase = (ALRawLoop2 *)pmem;
    418 	pmem += (samplesinfochunk->rawcount * sizeof(ALRawLoop2));
    419 
    420 	samplescmploopbase = (ALADPCMloop2 *)pmem;
    421 	pmem += (samplesinfochunk->adpcmcount * sizeof(ALADPCMloop2));
    422 
    423 	samplescmphdrbase = (ALADPCMBook2 *)pmem;//264
    424 
    425 	//PRINTF_D(WHITE,"ppgd->pat_grp_hdr.patchinfo %d",ppgd->pat_grp_hdr.patchinfo);
    426 
    427 	//PRINTF_D(WHITE,"ALADPCMBook %d",sizeof(ALADPCMBook));
    428 	//PRINTF_D(WHITE,"ALADPCMBook2 %d",sizeof(ALADPCMBook2));
    429 	//PRINTF_D(WHITE,"ALADPCMloop %d",sizeof(ALADPCMloop));
    430 	//PRINTF_D(WHITE,"ALADPCMloop2 %d",sizeof(ALADPCMloop2));
    431 
    432 	//PRINTF_D(WHITE,"ALRawLoop %d",sizeof(ALRawLoop));
    433 	//PRINTF_D(WHITE,"ALRawLoop2 %d",sizeof(ALRawLoop2));
    434 
    435 	for (vt = 0; vt < ppgd->pat_grp_hdr.patchinfo; vt++)
    436 	{
    437 		sample = (samplesbase + vt); /* pointer math */
    438 
    439 		sample->wave.base += g_wddloc; //Offset of (or pointer to) the start of the raw or ADPCM compressed.
    440 		sample->wave.flags = 1;        //If the base field contains an offset, [flags = 0]. If ifcontains an pointer, [flags = 1].
    441 
    442 		sample->pitch = (s32)(sample->wave.loop);//move pitch value
    443 
    444 		if (sample->wave.type == AL_RAW16_WAVE)
    445 		{
    446 			if ((s32)(sample->wave.book) != -1) // index id for loop table
    447 			{
    448 				sample->wave.loop = &samplesrawloopbase[(u32)(sample->wave.book)];
    449 			}
    450 			else
    451 			{
    452 				sample->wave.loop = &rawloop;
    453 			}
    454 		}
    455 		else//AL_ADPCM_WAVE
    456 		{
    457 			if ((s32)(sample->wave.book) != -1) // index id for loop table
    458 			{
    459 				sample->wave.loop = &samplescmploopbase[(u32)(sample->wave.book)];
    460 			}
    461 			else
    462 			{
    463 				sample->wave.loop = &cmploop;
    464 			}
    465 
    466 			sample->wave.book = &samplescmphdrbase[vt];
    467 		}
    468 	}
    469 }
    470 
    471 void N64_DriverExit (track_status *ptk_stat) // 8003806C
    472 {
    473     //PRINTF_D2(WHITE,0,7,"N64_DriverExit");
    474 }
    475 
    476 void N64_DriverEntry1 (track_status *ptk_stat) // 80038074
    477 {
    478     static unsigned long	vn;		//800B69A0
    479 	static unsigned long	vi;		//800B69A4
    480 	static voice_status		*pvs;	//800B69A8
    481 
    482 	//printf("N64_DriverEntry1\n");
    483 
    484 	//PRINTF_D2(WHITE,0,7,"N64_DriverEntry1");
    485 
    486 	vn = pmsbase->voices_active;
    487 	//PRINTF_D2(WHITE,0,8,"vn %d",vn);
    488 
    489 	if (vn != 0)
    490 	{
    491 		pvs = pvsbase;
    492 		vi = nvss;
    493 
    494 		while (vi--)
    495 		{
    496 			if (pvs->flags & VOICE_ACTIVE)
    497 			{
    498 				if ((pvs->flags & VOICE_RELEASE) && (pvs->pabstime < *pcurabstime))
    499 				{
    500 					N64_voiceparmoff(pvs);
    501 				}
    502 				else if ((pvs->flags & VOICE_DECAY) && ((pvs->pabstime + pvs->patchmaps->attack_time) < *pcurabstime))
    503 				{
    504 					N64_voicedecay(pvs);
    505 				}
    506 
    507 				if (!--vn) break;
    508 			}
    509 
    510 			pvs++;
    511 		}
    512 	}
    513 }
    514 
    515 void N64_DriverEntry2(track_status *ptk_stat) // 800381AC
    516 {
    517     //PRINTF_D2(WHITE,0,7,"N64_DriverEntry2");
    518 }
    519 
    520 void N64_DriverEntry3(track_status *ptk_stat) // 800381B4
    521 {
    522     //PRINTF_D2(WHITE,0,7,"N64_DriverEntry3");
    523 }
    524 
    525 void N64_TrkOff(track_status *ptk_stat) // 800381BC
    526 {
    527     static sequence_status	*pss;	//800B69AC
    528 
    529     //PRINTF_D2(WHITE,0,7,"N64_TrkOff");
    530 
    531 	pss = pssbase + ptk_stat->seq_owner;
    532 	N64_TrkMute(ptk_stat);
    533 
    534 	if (ptk_stat->voices_active)
    535 	{
    536 		ptk_stat->flags |= TRK_STOPPED;
    537 
    538 		if (!--pss->tracks_playing)
    539 			pss->playmode = SEQ_STATE_STOPPED;
    540 	}
    541 	else
    542 	{
    543 		Eng_TrkOff(ptk_stat);
    544 	}
    545 }
    546 
    547 void N64_TrkMute(track_status *ptk_stat) // 80038254
    548 {
    549 	static unsigned long	vn;		//800B69B0
    550 	static unsigned long	vi;		//800B69B4
    551 	static voice_status	    *pvs;	//800B69B8
    552 	static sequence_status	*pss;	//800B69BC
    553 
    554 	//PRINTF_D2(WHITE,0,7,"N64_TrkMute");
    555 	vn = ptk_stat->voices_active;
    556 
    557 	if (vn != 0)
    558 	{
    559 		pvs = pvsbase;
    560 		vi = nvss;
    561 
    562 		while (vi--)
    563 		{
    564 			if ((pvs->flags & VOICE_ACTIVE) && (pvs->track == ptk_stat->refindx))
    565 			{
    566 				if (pns != 0 && (!(pvs->flags & VOICE_RELEASE) && (pvs->sndtype == Snd_Music)))
    567 				{
    568 					pss = (pssbase + ptk_stat->seq_owner);
    569 
    570 					add_music_mute_note(ptk_stat,
    571 						pss->seq_num,
    572 						pvs->track,
    573 						pvs->keynum,
    574 						pvs->velnum,
    575 						pvs->patchmaps,
    576 						pvs->patchinfo);
    577 				}
    578 
    579 				N64_voicemuterelease(pvs, N64_mute_release);
    580 				if (!--vn) break;
    581 			}
    582 
    583 			pvs++;
    584 		}
    585 	}
    586 }
    587 
    588 void N64_PatchChg(track_status *ptk_stat) // 800383F8
    589 {
    590 	static unsigned short	thepatch;	//800B69C0
    591 
    592 	//PRINTF_D2(WHITE,0,7,"N64_PatchChg");
    593 	thepatch = (*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
    594 	ptk_stat->patchnum = thepatch;
    595 }
    596 
    597 void N64_PatchMod(track_status *ptk_stat) // 8003841C
    598 {
    599     //PRINTF_D2(WHITE,0,7,"N64_PatchMod");
    600 }
    601 
    602 void N64_PitchMod(track_status *ptk_stat) // 80038424
    603 {
    604 	static unsigned long	vn;				//800B69C4
    605 	static unsigned long	vi;				//800B69C8
    606 	static voice_status		*pvs;			//800B69CC
    607 	static short			thepitchmod;	//800B69D0
    608 	static f32				pitch;			//800B69D4
    609 	static unsigned long	adjpitch;		//800B69D8
    610 
    611 	//PRINTF_D2(WHITE,0,7,"N64_PitchMod");
    612 
    613 	thepitchmod = (*(ptk_stat->ppos + 1) | (*(ptk_stat->ppos + 2) << 8));
    614 	if (ptk_stat->pitch_cntrl != thepitchmod)
    615 	{
    616 		ptk_stat->pitch_cntrl = thepitchmod;
    617 		vn = ptk_stat->voices_active;
    618 
    619 		if (vn != 0)
    620 		{
    621 			pvs = pvsbase;
    622 			vi = nvss;
    623 
    624 			while (vi--)
    625 			{
    626 				if ((pvs->flags & VOICE_ACTIVE) && (pvs->track == ptk_stat->refindx))
    627 				{
    628                     //Pitch
    629                     if (ptk_stat->pitch_cntrl != 0)
    630                     {
    631                         if (ptk_stat->pitch_cntrl < 1)
    632                         {
    633                             adjpitch = (s32)((f64)(pvs->patchmaps->pitchstep_min * ptk_stat->pitch_cntrl) * (f64)0.0122);
    634                         }
    635                         else
    636                         {
    637                             adjpitch = (s32)((f64)(pvs->patchmaps->pitchstep_max * ptk_stat->pitch_cntrl) * (f64)0.0122);
    638                         }
    639                     }
    640                     else
    641                     {
    642                         adjpitch = 0;
    643                     }
    644 
    645                     pitch = (f32)WessCents2Ratio((pvs->patchinfo->pitch + adjpitch + (pvs->keynum - pvs->patchmaps->root_key) * 100) - pvs->patchmaps->fine_adj);
    646                     alSynSetPitch(&alGlobals->drvr, &voice[pvs->refindx], (f32)pitch);
    647 
    648                     if (!--vn) break;
    649 				}
    650 
    651 				pvs++;
    652 			}
    653 		}
    654 	}
    655 }
    656 
    657 void N64_ZeroMod(track_status *ptk_stat) // 800386C8
    658 {
    659     //PRINTF_D2(WHITE,0,7,"N64_ZeroMod");
    660 }
    661 
    662 void N64_ModuMod(track_status *ptk_stat) // 800386D0
    663 {
    664     //PRINTF_D2(WHITE,0,7,"N64_ModuMod");
    665 }
    666 
    667 void N64_VolumeMod(track_status *ptk_stat) // 800386D8
    668 {
    669 	static unsigned long	vn;		//800B69DC
    670 	static unsigned long	vi;		//800B69E0
    671 	static unsigned long	adjvol;				//800B69E4
    672 	static voice_status		*pvs;			//800B69E8
    673 	static unsigned char	thevolmod;			//800B69EC
    674 
    675 	u32 volume;
    676 	ALMicroTime deltaTime;
    677 
    678 	//PRINTF_D2(WHITE,0,7,"N64_VolumeMod");
    679 
    680 	thevolmod = *(ptk_stat->ppos + 1);
    681 	if (thevolmod != ptk_stat->volume_cntrl)
    682 	{
    683 		ptk_stat->volume_cntrl = thevolmod;
    684 		vn = ptk_stat->voices_active;
    685 
    686 		if (vn != 0)
    687 		{
    688 			pvs = pvsbase;
    689 			vi = nvss;
    690 
    691 			while (vi--)
    692 			{
    693                 if ((pvs->flags & VOICE_ACTIVE) && (pvs->track == ptk_stat->refindx))
    694 				{
    695 					if (ptk_stat->sndclass == SNDFX_CLASS)
    696 					{
    697 						volume = pvs->velnum * pvs->patchmaps->volume * ptk_stat->volume_cntrl * master_sfx_volume;
    698 					}
    699 					else//MUSIC_CLASS
    700 					{
    701 						volume = pvs->velnum * pvs->patchmaps->volume * ptk_stat->volume_cntrl * master_mus_volume;
    702 					}
    703 
    704 					adjvol = volume >> 0xd;
    705 					deltaTime = 1000;
    706 
    707 					alSynSetVol(&alGlobals->drvr, &voice[pvs->refindx], (s16)adjvol, (ALMicroTime)deltaTime);
    708 
    709 					if (!--vn) break;
    710 				}
    711 
    712 				pvs++;
    713 			}
    714 		}
    715 	}
    716 }
    717 
    718 void N64_PanMod(track_status *ptk_stat) // 800388FC
    719 {
    720 	static unsigned long	vn;			//800B69F0
    721 	static unsigned long	vi;			//800B69F4
    722 	static voice_status		*pvs;		//800B69F8
    723 	static short			adjpan;		//800B69FC
    724 	static unsigned char	thepanmod;	//800B69FE
    725 
    726 	//PRINTF_D2(WHITE,0,7,"N64_PanMod");
    727 
    728 	thepanmod = *(ptk_stat->ppos + 1);
    729 	if (thepanmod != ptk_stat->pan_cntrl)
    730 	{
    731 		ptk_stat->pan_cntrl = thepanmod;
    732 
    733 		if (pan_status != 0)
    734 		{
    735 			vn = ptk_stat->voices_active;
    736 
    737 			if (vn != 0)
    738 			{
    739 				pvs = pvsbase;
    740 				vi = nvss;
    741 
    742 				while (vi--)
    743 				{
    744 					if ((pvs->flags & VOICE_ACTIVE) && (pvs->track == ptk_stat->refindx))
    745 					{
    746 						adjpan = (s32)(((ptk_stat->pan_cntrl + pvs->patchmaps->pan) - 0x40) << 16) >> 16;
    747 						if (adjpan < 0)    adjpan = 0;
    748 						if (adjpan > 0x7f)	adjpan = 0x7f;
    749 
    750 						alSynSetPan(&alGlobals->drvr, &voice[pvs->refindx], (ALPan)adjpan);
    751 
    752 						if (!--vn) break;
    753 					}
    754 
    755 					pvs++;
    756 				}
    757 			}
    758 		}
    759 	}
    760 }
    761 
    762 //N64_PedalMod
    763 void N64_PedalMod(track_status *ptk_stat) // 80038AA0
    764 {
    765     static unsigned char	vn;		//800B69FF
    766 	static unsigned char	vi;		//800B6A00
    767 	static voice_status		*pvs;	//800B6A04
    768 
    769 	//PRINTF_D2(WHITE,0,7,"N64_PedalMod");
    770 
    771 	if (*(ptk_stat->ppos + 1) == 0)
    772 	{
    773 		ptk_stat->flags |= TRK_OFF;
    774 
    775 		vn = ptk_stat->voices_active;
    776 
    777 		if (vn != 0)
    778 		{
    779 			pvs = pvsbase;
    780 			vi = nvss;
    781 
    782 			while (vi--)
    783 			{
    784 				if ((pvs->flags & VOICE_ACTIVE) && !(pvs->flags & VOICE_RELEASE) && (pvs->track == ptk_stat->refindx))
    785 				{
    786 					if (pvs->sndtype != Snd_Music)
    787 					{
    788 						pvs->sndtype = Snd_Music;
    789 						N64_voicerelease(pvs);
    790 						if (!--vn) break;
    791 					}
    792 				}
    793 
    794 				pvs++;
    795 			}
    796 		}
    797 	}
    798 	else
    799 	{
    800 		ptk_stat->flags &= ~TRK_OFF;
    801 	}
    802 }
    803 
    804 //N64_ReverbMod
    805 void N64_ReverbMod(track_status *ptk_stat) // 80038BD8
    806 {
    807     static unsigned char	vn;			    //800B6A08
    808 	static unsigned char	vi;			    //800B6A0C
    809 	static voice_status		*pvs;		    //800B6A10
    810 	static unsigned char	thereverbmod;   //800B6A14
    811 
    812 	//PRINTF_D2(WHITE,0,7,"N64_ReverbMod");
    813 
    814 	thereverbmod = *(ptk_stat->ppos + 1);
    815 	if (thereverbmod != ptk_stat->reverb)
    816 	{
    817 		ptk_stat->reverb = thereverbmod;
    818 		vn = ptk_stat->voices_active;
    819 
    820 		if (vn != 0)
    821 		{
    822 			pvs = pvsbase;
    823 			vi = nvss;
    824 
    825 			while (vi--)
    826 			{
    827 				if ((pvs->flags & VOICE_ACTIVE) && (pvs->track == ptk_stat->refindx))
    828 				{
    829 					alSynSetPan(&alGlobals->drvr, &voice[pvs->refindx], (ALPan)thereverbmod);
    830 
    831 					if (!--vn) break;
    832 				}
    833 
    834 				pvs++;
    835 			}
    836 		}
    837 	}
    838 }
    839 
    840 //N64_ChorusMod
    841 void N64_ChorusMod(track_status *ptk_stat) // 80038D2C
    842 {
    843     //PRINTF_D2(WHITE,0,7,"N64_ChorusMod");
    844 }
    845 
    846 void N64_voiceon(voice_status *voice_stat, track_status *ptk_stat,
    847 	           patchmaps_header *patchmaps, patchinfo_header *patchinfo,
    848 	           unsigned char keynum, unsigned char velnum) // 80038D34
    849 {
    850 	//PRINTF_D2(WHITE,0,17,"N64_voiceon");
    851 	voice_stat->flags = (voice_stat->flags | VOICE_ACTIVE | VOICE_DECAY) & ~VOICE_RELEASE;
    852 	voice_stat->track = ptk_stat->refindx;
    853 	voice_stat->priority = patchmaps->priority;
    854 	voice_stat->keynum = keynum;
    855 	voice_stat->sndtype = Snd_Music;
    856 	voice_stat->patchmaps = patchmaps;
    857 	voice_stat->patchinfo = patchinfo;
    858 	voice_stat->velnum = velnum;
    859 	voice_stat->pabstime = *pcurabstime;
    860 
    861 	ptk_stat->voices_active++;
    862 	pmsbase->voices_active++;
    863 
    864 	TriggerN64Voice(voice_stat);
    865 }
    866 
    867 void N64_voiceparmoff(voice_status *voice_stat) // 80038DE4
    868 {
    869 	static track_status	*ptrack;	//800B6A18
    870 	//PRINTF_D2(WHITE,0,7,"N64_voiceparmoff");
    871 
    872 	alSynStopVoice(&alGlobals->drvr, &voice[voice_stat->refindx]);
    873 	alSynFreeVoice(&alGlobals->drvr, &voice[voice_stat->refindx]);
    874 
    875 	ptrack = (ptsbase + voice_stat->track);
    876 	pmsbase->voices_active--;
    877 
    878 	if (!--ptrack->voices_active)
    879 	{
    880 		if ((ptrack->flags & TRK_STOPPED) && !(ptrack->flags & TRK_MUTE))
    881 		{
    882 			Eng_TrkOff(ptrack);
    883 		}
    884 	}
    885 
    886 	voice_stat->flags &= ~(VOICE_ACTIVE | VOICE_RELEASE | VOICE_DECAY);
    887 }
    888 
    889 void N64_voicemuterelease(voice_status *voice_stat, int muterelease) // 80038EF8
    890 {
    891 	ALMicroTime deltaTime;
    892 
    893 	//PRINTF_D2(WHITE,0,7,"N64_voicemuterelease");
    894 
    895 	deltaTime = muterelease * 1000;
    896 	alSynSetPriority(&alGlobals->drvr, &voice[voice_stat->refindx], 0); /* make candidate for stealing */
    897 	alSynSetVol(&alGlobals->drvr, &voice[voice_stat->refindx], 0, deltaTime);
    898 
    899 	voice_stat->flags = (voice_stat->flags | VOICE_RELEASE) & ~VOICE_DECAY;
    900 	voice_stat->pabstime = *pcurabstime + muterelease;
    901 }
    902 
    903 void N64_voicerelease(voice_status *voice_stat) // 80038FBC
    904 {
    905 	ALMicroTime deltaTime;
    906 
    907 	//PRINTF_D2(WHITE,0,7,"N64_voicerelease");
    908 
    909 	deltaTime = voice_stat->patchmaps->release_time * 1000;
    910 	alSynSetPriority(&alGlobals->drvr, &voice[voice_stat->refindx], 0); /* make candidate for stealing */
    911 	alSynSetVol(&alGlobals->drvr, &voice[voice_stat->refindx], 0, deltaTime);
    912 
    913 	voice_stat->flags = (voice_stat->flags | VOICE_RELEASE) & ~VOICE_DECAY;
    914 	voice_stat->pabstime = *pcurabstime + (unsigned long)voice_stat->patchmaps->release_time;
    915 }
    916 
    917 void N64_voicedecay(voice_status *voice_stat) // 80039084
    918 {
    919 	static unsigned long	adjvol;	//800B6A1C
    920 	static track_status		*pts;	//800B6A20
    921 
    922 	u32 volume;
    923 	ALMicroTime deltaTime;
    924 
    925 	//PRINTF_D2(WHITE,0,7,"N64_voicedecay");
    926 
    927 	pts = (ptsbase + voice_stat->track);
    928 
    929 	//sndclass
    930 	if (pts->sndclass == SNDFX_CLASS)
    931 	{
    932 		volume = voice_stat->velnum * voice_stat->patchmaps->volume * pts->volume_cntrl * master_sfx_volume;
    933 	}
    934 	else
    935 	{
    936 		volume = voice_stat->velnum * voice_stat->patchmaps->volume * pts->volume_cntrl * master_mus_volume;
    937 	}
    938 
    939 	adjvol = voice_stat->patchmaps->decay_level * (volume >> 0xd) >> 7;
    940 
    941 	if (enabledecay)
    942 	{
    943 		deltaTime = voice_stat->patchmaps->decay_time * 1000;
    944 		alSynSetVol(&alGlobals->drvr, &voice[voice_stat->refindx], (s16)adjvol, deltaTime);
    945 	}
    946 
    947 	voice_stat->flags &= ~VOICE_DECAY;
    948 }
    949 
    950 void N64_voicenote(track_status *ptk_stat,
    951 	           patchmaps_header *patchmap, patchinfo_header *patchinfo,
    952 	           unsigned char keynum, unsigned char velnum) // 800391F8
    953 {
    954 	static unsigned long	vi;				//800B6A24
    955 	static unsigned long	found_one;		//800B6A28
    956 	static voice_status		*pvs;			//800B6A2C
    957 	static voice_status		*pvsact;		//800B6A30
    958 	static unsigned long	lowprio;		//800B6A34
    959 	static unsigned long	lowtime;		//800B6A38
    960 
    961 
    962 	unsigned int pabstime_tmp;
    963 	unsigned int priority_tmp;
    964 	voice_status *voice_tmp;
    965 
    966 	//PRINTF_D2(WHITE,0,15,"N64_voicenote");
    967 
    968 	found_one = 0;
    969 
    970 	pvsact = voice_tmp = (voice_status *)0x0;
    971 	lowprio = priority_tmp = 0x100;
    972 	lowtime = pabstime_tmp = 0xFFFFFFFF;
    973 
    974 	pvs = pvsbase;
    975 	vi = nvss;
    976 
    977 	while (vi--)
    978 	{
    979 		if (!(pvs->flags & VOICE_ACTIVE))
    980 		{
    981 			pvsact = voice_tmp;
    982 			lowprio = priority_tmp;
    983 			lowtime = pabstime_tmp;
    984 			N64_voiceon(pvs, ptk_stat, patchmap, patchinfo, keynum, velnum);
    985 			found_one = 0;
    986 			break;
    987 		}
    988 
    989 		if (pvs->priority <= patchmap->priority)
    990 		{
    991 			if (pvs->priority < lowprio)
    992 			{
    993 				found_one = 1;
    994                 pabstime_tmp = pvs->pabstime;
    995                 priority_tmp = pvs->priority;
    996                 voice_tmp = pvs;
    997 			}
    998 			else
    999 			{
   1000 			    if(pvs->flags & VOICE_RELEASE)
   1001                 {
   1002                     if(pvsact->flags & VOICE_RELEASE)
   1003                     {
   1004                         if (pvs->pabstime < lowtime)
   1005 						{
   1006 							found_one = 1;
   1007                             pabstime_tmp = pvs->pabstime;
   1008                             priority_tmp = pvs->priority;
   1009                             voice_tmp = pvs;
   1010 						}
   1011                     }
   1012                     else
   1013                     {
   1014                         found_one = 1;
   1015                         pabstime_tmp = pvs->pabstime;
   1016                         priority_tmp = pvs->priority;
   1017                         voice_tmp = pvs;
   1018                     }
   1019                 }
   1020                 else if(!(pvsact->flags & VOICE_RELEASE))
   1021                 {
   1022                     if (pvs->pabstime < lowtime)
   1023                     {
   1024                         found_one = 1;
   1025                         pabstime_tmp = pvs->pabstime;
   1026                         priority_tmp = pvs->priority;
   1027                         voice_tmp = pvs;
   1028                     }
   1029                 }
   1030 			}
   1031 		}
   1032 
   1033 		pvs++;
   1034 		pvsact = voice_tmp;
   1035 		lowprio = priority_tmp;
   1036 		lowtime = pabstime_tmp;
   1037 	}
   1038 
   1039 	if (found_one != 0)
   1040 	{
   1041 		N64_voiceparmoff(pvsact);
   1042 		N64_voiceon(pvsact, ptk_stat, patchmap, patchinfo, keynum, velnum);
   1043 	}
   1044 }
   1045 
   1046 void N64_NoteOn(track_status *ptk_stat) // 80039434
   1047 {
   1048 	static unsigned long	i;			//800B6A3C
   1049 	static unsigned char	note;		//800B6A40
   1050 	static unsigned char	vel;		//800B6A41
   1051 	static unsigned char	mapcount;	//800B6A42
   1052 	static patches_header	*samp_pat;	//800B6A44
   1053 	static patchmaps_header	*mapdat;	//800B6A48
   1054 	static patchinfo_header	*sampdat;	//800B6A4C
   1055 
   1056 	//PRINTF_D2(WHITE,0,16,"N64_NoteOn");
   1057 
   1058 	note = *(ptk_stat->ppos + 1);
   1059 	vel = *(ptk_stat->ppos + 2);
   1060 
   1061 	samp_pat = patchesbase + ptk_stat->patchnum;
   1062 	mapcount = samp_pat->patchmap_cnt;
   1063 
   1064 	//PRINTF_D2(WHITE,15,14,"note %d",note);
   1065 	//PRINTF_D2(WHITE,15,15,"vel %d",vel);
   1066 	//PRINTF_D2(WHITE,15,16,"mapcount %d",mapcount);
   1067 
   1068 	i = 0;
   1069 	while (mapcount--)
   1070 	{
   1071 		mapdat = patchmapsbase + (samp_pat->patchmap_idx + i);
   1072 		sampdat = samplesbase + mapdat->sample_id;
   1073 
   1074 		if ((mapdat->note_min <= note) && (note <= mapdat->note_max))
   1075 		{
   1076 			N64_voicenote(ptk_stat, mapdat, sampdat, note, vel);
   1077 		}
   1078 		i += 1;
   1079 	}
   1080 }
   1081 
   1082 void N64_NoteOff(track_status *ptk_stat) // 800395B4
   1083 {
   1084 	static unsigned long	vi;		//800B6A50
   1085 	static voice_status		*pvs;	//800B6A54
   1086 
   1087 	//PRINTF_D2(WHITE,0,7,"N64_NoteOff");
   1088 	pvs = pvsbase;
   1089 	vi = nvss;
   1090 
   1091 	while (vi--)
   1092 	{
   1093 		if (((pvs->flags & (VOICE_ACTIVE | VOICE_RELEASE)) == VOICE_ACTIVE) &&
   1094 			(pvs->keynum == *(ptk_stat->ppos + 1)) &&
   1095 			(pvs->track == ptk_stat->refindx))
   1096 		{
   1097 			if ((ptk_stat->flags & TRK_OFF) == 0) {
   1098 				pvs->sndtype = Snd_Sfx;
   1099 			}
   1100 			else {
   1101 				N64_voicerelease(pvs);
   1102 			}
   1103 		}
   1104 
   1105 		pvs++;
   1106 	}
   1107 }
   1108 
   1109 #endif