#include #include "yxm.h" /* --------------------------------------------------------------------- // Function: SetYXMVolume // Purpose: Set the volume of the current used voices according // to globvol */ void SetYXMVolume(YXM_MODDATA *yxmdata) { unsigned short volL,volR,newvolL,newvolR; short i; volL = yxmdata->yxmd_globvolL; volR = yxmdata->yxmd_globvolR; for(i=0; i < yxmdata->yxmd_channels; i++) { if (yxmdata->yxmd_channel[i].voice != -1) { newvolL = (yxmdata->yxmd_channel[i].vol_l * volL); newvolR = (yxmdata->yxmd_channel[i].vol_r * volR); newvolL = newvolL >> 7; newvolR = newvolR >> 7; SsUtSetVVol(yxmdata->yxmd_channel[i].voice, newvolL, newvolR); } } } /* --------------------------------------------------------------------- // Function: StopYXM // Purpose: Stop playing tune and set Keys OFF */ unsigned short StopYXM(YXM_MODDATA *yxmdata) { SsUtAllKeyOff(0); yxmdata->yxmd_playflag = -1; return(yxmdata->yxmd_songpos); } /* --------------------------------------------------------------------- // Function: ResetYXM // Purpose: Reset Module to play from begining */ void ResetYXM(YXM_MODDATA *yxmdata, unsigned short oldpos) { short i; unsigned long *ptr; unsigned short *patptr; yxmdata->yxmd_count = 0; yxmdata->yxmd_songpos = oldpos; yxmdata->yxmd_row = 0; yxmdata->yxmd_rows = 0; yxmdata->yxmd_patternpos = 0; ptr = yxmdata->yxmd_patternOT; ptr+=oldpos; yxmdata->yxmd_patternpos = (unsigned char *) *ptr; patptr = (unsigned short *)yxmdata->yxmd_patternpos; yxmdata->yxmd_rows = *(patptr+1); patptr+=2; yxmdata->yxmd_patternpos = (unsigned char *) patptr; // ==== Clear Channel Data for (i=0; i < 15; i++) { yxmdata->yxmd_channel[i].note = 0; yxmdata->yxmd_channel[i].vag = 0; yxmdata->yxmd_channel[i].volcol = 0; yxmdata->yxmd_channel[i].effect = 0; yxmdata->yxmd_channel[i].effpar = 0; yxmdata->yxmd_channel[i].vol_l = 0; yxmdata->yxmd_channel[i].vol_r = 0; yxmdata->yxmd_channel[i].voice = -1; } yxmdata->yxmd_playflag = 0; } /* --------------------------------------------------------------------- // Function: Init_YXM // Purpose: Initialize Module ** IN: VH / VAB Header file ** VB / VAB Voice Bank ** YXM / Module Data ** YXMPLAY / Structure for player */ extern short InitYXM(unsigned char *VH, unsigned char *VB, unsigned char *YXM, YXM_MODDATA *yxmdata) { YXM_HEADER *yxmhead; unsigned long *ptr; unsigned short *patptr; short i; short ret=0; yxmhead=(YXM_HEADER *)YXM; if (!(strncmp(yxmhead->yxm_id,"YXM!",4))) { // ==== Set MODDATA yxmdata->yxmd_tempo = yxmhead->yxm_tempo; yxmdata->yxmd_songlength = yxmhead->yxm_songlength; yxmdata->yxmd_restartpos = yxmhead->yxm_restartpos; yxmdata->yxmd_channels = yxmhead->yxm_channels; yxmdata->yxmd_patternOT = &yxmhead->yxm_patternOT[0]; yxmdata->yxmd_count = 0; yxmdata->yxmd_songpos = 0; yxmdata->yxmd_row = 0; yxmdata->yxmd_rows = 0; yxmdata->yxmd_patternpos = 0; yxmdata->yxmd_globvolL = 127; yxmdata->yxmd_globvolR = 127; yxmdata->yxmd_patternloopflag = 0; // ==== Calc Real Pattern Address ptr = &yxmdata->yxmd_patternOT[0]; for (i=0; i < yxmdata->yxmd_songlength; i++, ptr++) { *ptr+=(unsigned long)yxmhead; } // ==== Set Pattern ptr = yxmdata->yxmd_patternOT; yxmdata->yxmd_patternpos = (unsigned char *) *ptr; patptr = (unsigned short *)yxmdata->yxmd_patternpos; yxmdata->yxmd_rows = *(patptr+1); patptr+=2; yxmdata->yxmd_patternpos = (unsigned char *) patptr; // ==== Set Instrument Data Pointer yxmdata->yxmd_instrumentdata = (short *)&yxmhead->yxm_instrumentinfo[0]; // ==== Clear Channel Data for (i=0; i < 15; i++) { yxmdata->yxmd_channel[i].note = 0; yxmdata->yxmd_channel[i].vag = 0; yxmdata->yxmd_channel[i].volcol = 0; yxmdata->yxmd_channel[i].effect = 0; yxmdata->yxmd_channel[i].effpar = 0; yxmdata->yxmd_channel[i].vol_l = 0; yxmdata->yxmd_channel[i].vol_r = 0; yxmdata->yxmd_channel[i].voice = -1; } // ==== Load Sample Into Sample Buffer yxmdata->yxmd_vabid = SsVabTransfer(VH, VB,-1,1); /* if(yxmdata->yxmd_vabid < 0) { printf(" vab:%d", yxmdata->yxmd_vabid); return(1); } */ SsSetMVol(yxmdata->yxmd_globvolL,yxmdata->yxmd_globvolR); } else ret=1; return(ret); } /* --------------------------------------------------------------------- // Function: RemoveYXM // Purpose: Remove the VAB from sound buffer ** YXM_MODDATA / Structure for player */ void RemoveYXM(YXM_MODDATA *yxmdata) { yxmdata->yxmd_playflag = -1; SsUtAllKeyOff(0); SsVabClose(yxmdata->yxmd_vabid); } /* --------------------------------------------------------------------- // Function: PlayYXM // Purpose: Play Module */ inline PlayYXM(YXM_MODDATA *mod) { typedef YXM_MODDATA Y; typedef YXM_PATTERN_HEADER PH; typedef YXM_CHANNEL C; typedef YXM_INSTRUMENT I; // .set reorder asm (" addiu $29,$29,-68 sw $31,28($29) sw $16,32($29) sw $17,36($29) sw $18,40($29) sw $19,44($29) sw $20,48($29) sw $21,52($29) sw $22,56($29) sw $23,60($29) move $16,$4 lhu $8,44($16) nop bne $8,$0,yxm_exit nop lh $8,24($16) nop addi $8,$8, -1 move $9,$8 bgtz $8,yxm_0 nop lh $8,0($16) nop yxm_0: sh $8,24($16) bgtz $9,yxm_do_effects nop lh $8,28($16) lh $9,30($16) nop bne $8,$9,yxm_do_channels nop sh $0,28($16) lw $8,16($16) lh $9,26($16) lh $10,2($16) addiu $9,$9,1 bne $9,$10,yxm_1 nop lhu $9,4($16) nop yxm_1: sh $9,26($16) sll $9,$9,2 addu $8,$8,$9 lw $9,0($8) nop lhu $10,2($9) addiu $9,$9,4 sh $10,30($16) sw $9,32($16) yxm_do_channels: lh $8,6($16) sh $8,64($29) lw $17,32($16) nop addiu $18,$16,48 yxm_channel_loop: lbu $19,0($17) lbu $20,1($17) lbu $21,2($17) lbu $22,3($17) lbu $23,4($17) addi $20,$20,-1 beq $19,$0,yxm_get_effects nop lh $9,14($18) li $3,-1 beq $9,$3,yxm_play_voice nop lh $8,0($18) lh $7,2($18) move $6,$0 lh $5,8($16) move $4,$9 sw $8,16($29) jal SsUtKeyOff nop li $3, -1 sh $3,14($18) sh $0,0($18) yxm_play_voice: li $3,97-15 beq $19,$3,yxm_get_effects nop li $3, -1 bne $20,$3,yxm_pv_0 nop lh $20,2($18) yxm_pv_0: move $7,$19 move $6,$20 move $5,$0 lh $4,8($16) sh $19,0($18) sh $20,2($18) lw $8,20($16) nop sll $9,$6,2 addu $8,$8,$9 lhu $9,2($8) lhu $10,0($8) li $3,0xC bne $3,$22,yxm_pv_volcol nop move $10,$23 move $22,$0 move $23,$0 j yxmc2 yxm_pv_volcol: beq $21,$0,yxmc1 li $11,0x51 sltu $3,$21,$11 beq $3,$0,yxmc1 nop addi $10,$21,-16 move $21,$0 yxmc2: addu $10,$10,$10 beq $10,$0,yxmc1 nop addi $10,$10,-1 yxmc1: lhu $24,10($16) nop bne $24,$0,yxmc5 nop move $10,$0 j yxmc4 yxmc5: addiu $25,$10,1 multu $24,$25 nop nop mflo $25 srl $24,$25,7 andi $10,$24,0x7F yxmc4: sw $9,16($29) sw $10,20($29) sw $10,24($29) sh $10,10($18) sh $10,12($18) jal SsUtKeyOn nop sh $2,14($18) yxm_get_effects: sh $21,4($18) sh $22,6($18) beq $23,$0, yxmc3 nop sh $23,8($18) yxmc3: addiu $18,$18,16 addiu $17,$17,5 lh $8,64($29) nop addi $8,$8,-1 sh $8,64($29) bne $8,$0,yxm_channel_loop nop sw $17,32($16) lh $8,28($16) nop addiu $8,$8, 1 sh $8,28($16) yxm_do_effects: addiu $17,$16, 48 lh $18,6($16) li $19,-1 yxm_de_loop: lh $20,14($17) lh $9,4($17) beq $20,$19,yxm_do_next_channel_effect nop beq $9,$0,yxm_EFFECTS nop li $10,0x51 sltu $3,$9,$10 beq $3,$0,yxm_EFFECTS addi $8,$9,-16 addu $8,$8,$8 beq $8,$0,yxm_volcol_0 nop addi $8,$8,-1 yxm_volcol_0: sh $8,10($17) sh $8,12($17) move $4,$20 move $6,$8 move $5,$8 jal SsUtSetVVol nop sh $0,4($17) yxm_EFFECTS: lh $8,6($17) nop beq $8, $0, yxm_do_next_channel_effect nop li $3,0x14 beq $8,$3,yxm_effect_KEY_OFF nop li $3,0xC beq $8,$3,yxm_effect_VOLUME nop li $3,0xD beq $8,$3,yxm_effect_PATTERN_BREAK nop li $3,0xF beq $8,$3,yxm_effect_TEMPO nop li $3,0x10 beq $8,$3,yxm_effect_GLOBAL_VOLUME nop li $3, 0xE beq $8,$3,yxm_effect_E nop j yxm_do_next_channel_effect yxm_effect_KEY_OFF: lh $8,0($17) lh $7,2($17) move $6,$0 lh $5,8($16) move $4,$20 sw $8,16($29) jal SsUtKeyOff nop li $3,-1 sh $3,14($17) sh $0,6($17) sh $0,8($17) j yxm_do_next_channel_effect yxm_effect_VOLUME: lhu $8,8($17) addu $8,$8, $8 beq $8,$0,yxm_effvol_0 nop addi $8,$8, -1 yxm_effvol_0: sh $8,10($17) sh $8,12($17) move $4,$20 move $5,$8 move $6,$8 jal SsUtSetVVol nop sh $0,6($17) sh $0,8($17) j yxm_do_next_channel_effect yxm_effect_PATTERN_BREAK: lhu $8,8($17) lhu $9,26($16) lhu $10,2($16) addiu $9,$9,1 bne $9,$10,yxm_eff_PB nop lhu $9,4($16) yxm_eff_PB: sh $9,26($16) lw $10,16($16) sll $9,$9,2 addu $10,$10,$9 lw $11,0($10) nop lhu $12,2($11) addiu $11,$11,4 beq $8,$0,yxm_eff_PB_1 nop lhu $3,6($16) nop multu $8,$3 move $12,$8 nop mflo $13 sll $14,$13,2 addu $14,$14,$13 addu $11,$11,$14 yxm_eff_PB_1: sh $12,30($16) sw $11,32($16) sh $0,6($17) sh $0,8($17) j yxm_do_next_channel_effect yxm_effect_TEMPO: lhu $8,8($17) bne $8,$0, yxm_eff_T nop li $8,1 yxm_eff_T: sh $8,0($16) sh $8,24($16) sh $0,6($17) sh $0,8($17) j yxm_do_next_channel_effect yxm_effect_GLOBAL_VOLUME: lhu $8,8($17) addu $8,$8,$8 beq $8,$0,yxm_eff_GV addi $8,$8, -1 yxm_eff_GV: sh $8,10($16) sh $8,12($16) sh $0,6($17) sh $0,8($17) j yxm_do_next_channel_effect yxm_effect_E: lhu $8,8($17) andi $9,$8,0xF andi $8,$8,0xF0 li $3,0x60 beq $3,$8,yxm_eeff_PATTERN_LOOP j yxm_do_next_channel_effect yxm_eeff_PATTERN_LOOP: bne $9,$0,yxm_eeff_PL_0 lh $3,40($16) bne $3,$0,yxm_do_next_channel_effect lhu $8,6($16) li $3,5 multu $3,$8 lw $10,32($16) nop mflo $8 subu $9,$10,$8 sw $9,36($16) li $3,-1 sh $3,40($16) move $9,$0 j yxm_eeff_PL_1 yxm_eeff_PL_0: lh $8,40($16) beq $8,$0,yxm_eeff_PL_1 move $9,$0 yxm_eeff_PL_1: sh $9,42($16) sh $0,6($17) sh $0,8($17) yxm_do_next_channel_effect: addiu $17,$17,16 addi $18,$18,-1 bne $18,$0,yxm_de_loop yxm_exit: lw $31, 28($29) lw $16, 32($29) lw $17, 36($29) lw $18, 40($29) lw $19, 44($29) lw $20, 48($29) lw $21, 52($29) lw $22, 56($29) lw $23, 60($29) addi $29, $29, 68 "); // jr ra }