2 Copyright (c) 2002,2003, Christian Nowak <chnowak@web.de>
5 Modified by Francisco Mu�oz 'Hermes' MAY 2008
7 Redistribution and use in source and binary forms, with or without modification, are
8 permitted provided that the following conditions are met:
10 - Redistributions of source code must retain the above copyright notice, this list of
11 conditions and the following disclaimer.
12 - Redistributions in binary form must reproduce the above copyright notice, this list
13 of conditions and the following disclaimer in the documentation and/or other
14 materials provided with the distribution.
15 - The names of the contributors may not be used to endorse or promote products derived
16 from this software without specific prior written permission.
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
19 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
26 THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #include "semitonetab.h"
46 volatile long* lcdcon1 = (long*)0x14a00000;
47 #define VLINE ((*lcdcon1 >> 18) & 0x1ff)
48 extern int deltavline;
55 static u32
*inc_tabs
[2] = {NULL
,NULL
};
56 static u32
*bpm_tabs
[2] = {NULL
,NULL
};
61 #define MEM_CPY(a,b,c) gm_memcpy(a,b,c)
62 #define MEM_SET(a,b,c) gm_memset(a,b,c)
63 /*#define MEM_CMP(a,b,c) gm_memcmp(a,b,c)*/
64 static s32
MEM_CMP ( void * a
, void * b
, s32 l
)
69 if (((u8
*)a
)[i
]!=((u8
*)b
)[i
])
74 #define MEM_CPY(a,b,c) memcpy(a,b,c)
75 #define MEM_SET(a,b,c) memset(a,b,c)
76 #define MEM_CMP(a,b,c) memcmp(a,b,c)
83 #define MINI(a,b) ((a)<(b)?(a):(b))
84 #define MAXI(a,b) ((a)>(b)?(a):(b))
88 0,8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,
89 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
95 (s16
)0, (s16
)24, (s16
)49, (s16
)74, (s16
)97, (s16
)120, (s16
)141, (s16
)161,
96 (s16
)180, (s16
)197, (s16
)212, (s16
)224, (s16
)235, (s16
)244, (s16
)250, (s16
)253,
97 (s16
)255, (s16
)253, (s16
)250, (s16
)244, (s16
)235, (s16
)224, (s16
)212, (s16
)197,
98 (s16
)180, (s16
)161, (s16
)141, (s16
)120, (s16
)97, (s16
)74, (s16
)49, (s16
)24,
99 (s16
)0, (s16
)-24, (s16
)-49, (s16
)-74, (s16
)-97, (s16
)-120,(s16
)-141,(s16
)-161,
100 (s16
)-180,(s16
)-197,(s16
)-212,(s16
)-224,(s16
)-235,(s16
)-244,(s16
)-250,(s16
)-253,
101 (s16
)-255,(s16
)-253,(s16
)-250,(s16
)-244,(s16
)-235,(s16
)-224,(s16
)-212,(s16
)-197,
102 (s16
)-180,(s16
)-161,(s16
)-141,(s16
)-120,(s16
)-97, (s16
)-74, (s16
)-49, (s16
)-24
105 (s16
)255, (s16
)247, (s16
)239, (s16
)231, (s16
)223, (s16
)215, (s16
)207, (s16
)199,
106 (s16
)191, (s16
)183, (s16
)175, (s16
)167, (s16
)159, (s16
)151, (s16
)143, (s16
)135,
107 (s16
)127, (s16
)119, (s16
)111, (s16
)103, (s16
)95, (s16
)87, (s16
)79, (s16
)71,
108 (s16
)63, (s16
)55, (s16
)47, (s16
)39, (s16
)31, (s16
)23, (s16
)15, (s16
)7,
109 (s16
)-1, (s16
)-9, (s16
)-17, (s16
)-25, (s16
)-33, (s16
)-41, (s16
)-49, (s16
)-57,
110 (s16
)-65, (s16
)-73, (s16
)-81, (s16
)-89, (s16
)-97, (s16
)-105,(s16
)-113,(s16
)-121,
111 (s16
)-129,(s16
)-137,(s16
)-145,(s16
)-153,(s16
)-161,(s16
)-169,(s16
)-177,(s16
)-185,
112 (s16
)-193,(s16
)-201,(s16
)-209,(s16
)-217,(s16
)-225,(s16
)-233,(s16
)-241,(s16
)-249
115 (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255,
116 (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255,
117 (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255,
118 (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255, (s16
)255,
119 (s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,
120 (s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,
121 (s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,
122 (s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255,(s16
)-255
125 (s16
)-26, (s16
)-251,(s16
)-198,(s16
)-46, (s16
)-96, (s16
)198, (s16
)168, (s16
)228,
126 (s16
)-49, (s16
)-153,(s16
)-236,(s16
)-174,(s16
)-37, (s16
)61, (s16
)187, (s16
)120,
127 (s16
)56, (s16
)-197,(s16
)248, (s16
)-58, (s16
)-204,(s16
)172, (s16
)58, (s16
)253,
128 (s16
)-155,(s16
)57, (s16
)62, (s16
)-62, (s16
)60, (s16
)-137,(s16
)-101,(s16
)-184,
129 (s16
)66, (s16
)-160,(s16
)160, (s16
)-29, (s16
)-91, (s16
)243, (s16
)175, (s16
)-175,
130 (s16
)149, (s16
)97, (s16
)3, (s16
)-113,(s16
)7, (s16
)249, (s16
)-241,(s16
)-247,
131 (s16
)110, (s16
)-180,(s16
)-139,(s16
)-20, (s16
)246, (s16
)-86, (s16
)-80, (s16
)-134,
132 (s16
)219, (s16
)117, (s16
)-143,(s16
)-226,(s16
)-166,(s16
)120, (s16
)-47, (s16
)29
137 static u32
* modplay_getinctab(s32 freq
)
140 u32 i
,curr_tab
,*inc_tab
= NULL
;
141 f32 rfreq
,fval
,fdivid
;
143 if(freq
==32000) curr_tab
= 0;
146 if(inc_tabs
[curr_tab
]) return inc_tabs
[curr_tab
];
148 tv
= VIDEO_GetCurrentTvMode();
149 if(tv
==VI_PAL
) fdivid
= 7093789.2/2.0F
;
150 else fdivid
= 7159090.5/2.0F
;
152 inc_tab
= (u32
*)malloc(sizeof(u32
)*4096);
154 inc_tabs
[curr_tab
] = inc_tab
;
155 for(i
=0;i
<4096;i
++) {
156 rfreq
= (fdivid
/(f32
)i
);
157 fval
= (rfreq
/(f32
)freq
)*262144.0F
;
158 inc_tab
[i
] = (u32
)fval
;
166 static u32
* modplay_getbpmtab(s32 freq
)
168 u32 i
,curr_tab
,*bpm_tab
= NULL
;
171 if(freq
==32000) curr_tab
= 0;
174 if(bpm_tabs
[curr_tab
]) return bpm_tabs
[curr_tab
];
176 bpm_tab
= (u32
*)malloc(sizeof(u32
)*224);
178 bpm_tabs
[curr_tab
] = bpm_tab
;
180 fval
= ((f32
)freq
/((f32
)(i
+32)*0.4F
));
181 bpm_tab
[i
] = (u32
)fval
;
191 static s32
fsize ( s8
* fname
)
195 if (GpFileGetSize(fname
,&s
)!=SM_OK
)
200 #elif defined(DREAMCAST)
201 static s32
fsize ( s8
* fname
)
206 if ((f
=fs_open(fname
, O_RDONLY
))==0)
209 fs_seek ( f
, 0, SEEK_END
);
215 #elif defined(GAMECUBE)
216 static s32
fsize(s8
*fname
)
221 static s32
fsize ( const char * fname
)
226 f
= fopen (fname
,"rb");
230 fseek(f
, 0, SEEK_END
);
238 s32
MOD_AllocSFXChannels ( MOD
* mod
, s32 sfxchans
)
240 if (mod
->modraw
==NULL
)
243 if (mod
->num_voices
+sfxchans
>32)
244 mod
->num_channels
= mod
->num_voices
;
246 mod
->num_channels
= mod
->num_voices
+sfxchans
;
247 mod
->shiftval
= shiftvals
[mod
->num_channels
];
249 return (mod
->num_voices
+sfxchans
>32)?-1:0;
253 void MOD_Free ( MOD
* mod
)
258 if (mod
->modraw
!=NULL
)
259 gm_free ( mod
->modraw
);
261 MEM_SET ( mod
, 0, sizeof(MOD
) );
266 void MOD_Free ( MOD
* mod
)
273 if (mod
->modraw
!=NULL
)
274 free ( mod
->modraw
);
276 MEM_SET ( mod
, 0, sizeof(MOD
) );
282 s32
MOD_SetMOD ( MOD
* mod
, u8
* mem
)
287 MEM_SET ( mod
, 0, sizeof(MOD
) );
289 mod
->musicvolume
= mod
->sfxvolume
= 0x40;
293 MEM_CPY ( mod
->id
, &mem
[1080], 4 );
295 if ( (MEM_CMP(mod
->id
, "M.K.", 4)==0) ||
296 (MEM_CMP(mod
->id
, "FLT4", 4)==0) )
299 if ( MEM_CMP(mod
->id
, "2CHN", 4)==0 )
302 if ( MEM_CMP(mod
->id
, "6CHN", 4)==0 )
305 if ( MEM_CMP(mod
->id
, "8CHN", 4)==0 )
308 if ( MEM_CMP(mod
->id
, "10CH", 4)==0 )
309 mod
->num_voices
= 10;
311 if ( MEM_CMP(mod
->id
, "12CH", 4)==0 )
312 mod
->num_voices
= 12;
314 if ( MEM_CMP(mod
->id
, "14CH", 4)==0 )
315 mod
->num_voices
= 14;
317 if ( MEM_CMP(mod
->id
, "16CH", 4)==0 )
318 mod
->num_voices
= 16;
320 if ( MEM_CMP(mod
->id
, "18CH", 4)==0 )
321 mod
->num_voices
= 18;
323 if ( MEM_CMP(mod
->id
, "20CH", 4)==0 )
324 mod
->num_voices
= 20;
326 if ( MEM_CMP(mod
->id
, "22CH", 4)==0 )
327 mod
->num_voices
= 22;
329 if ( MEM_CMP(mod
->id
, "24CH", 4)==0 )
330 mod
->num_voices
= 24;
332 if ( MEM_CMP(mod
->id
, "26CH", 4)==0 )
333 mod
->num_voices
= 26;
335 if ( MEM_CMP(mod
->id
, "28CH", 4)==0 )
336 mod
->num_voices
= 28;
338 if ( MEM_CMP(mod
->id
, "30CH", 4)==0 )
339 mod
->num_voices
= 30;
341 if ( MEM_CMP(mod
->id
, "32CH", 4)==0 )
342 mod
->num_voices
= 32;
350 MEM_CPY ( mod
->name
, &mem
[ofs
], 20 ); ofs
+=20;
351 mod
->name
[20] = '\0';
352 /* Read instruments */
353 for (i
=0;i
<mod
->num_instr
;i
++)
358 MEM_CPY ( &mod
->instrument
[i
].name
, &mem
[ofs
], 22 ); ofs
+=22;
359 mod
->instrument
[i
].name
[22] = '\0';
361 while ( mod
->instrument
[i
].name
[j
]==' ' && j
>=0 )
363 mod
->instrument
[i
].name
[j
] = '\0';
367 mod
->instrument
[i
].length
= (mem
[ofs
+1] | (mem
[ofs
]<<8))<<1; ofs
+=2;
369 mod
->instrument
[i
].finetune
= mem
[ofs
++];
370 mod
->instrument
[i
].finetune
+= 8;
371 mod
->instrument
[i
].finetune
&= 15;
373 mod
->instrument
[i
].volume
= mem
[ofs
++];
374 if (mod
->instrument
[i
].volume
> 0x40)
375 mod
->instrument
[i
].volume
= 0x40;
377 mod
->instrument
[i
].loop_start
= (mem
[ofs
+1] | (mem
[ofs
]<<8))<<1; ofs
+=2;
379 tmp
= (mem
[ofs
+1] | (mem
[ofs
]<<8))<<1; ofs
+=2;
380 mod
->instrument
[i
].loop_end
= tmp
+ mod
->instrument
[i
].loop_start
;
382 /* Is the sample looped ? */
383 mod
->instrument
[i
].looped
= TRUE
;
386 mod
->instrument
[i
].looped
= FALSE
;
387 mod
->instrument
[i
].loop_start
= mod
->instrument
[i
].loop_end
=
388 mod
->instrument
[i
].length
;
390 mod
->instrument
[i
].loop_length
= mod
->instrument
[i
].loop_end
- mod
->instrument
[i
].loop_start
;
393 mod
->song_length
= mem
[ofs
++];
395 mod
->ciaa
= mem
[ofs
++];
397 MEM_CPY ( mod
->song
, &mem
[ofs
], 128 ); ofs
+=128;
398 mod
->num_patterns
= 0;
401 if ( (mod
->song
[i
] &= 63) > mod
->num_patterns
)
402 mod
->num_patterns
= mod
->song
[i
];
406 if (mod
->num_instr
!=15)
409 MOD_AllocSFXChannels ( mod
, 0 );
412 mod
->patterndata
= &mem
[ofs
];
413 ofs
+= 4*64*mod
->num_voices
*mod
->num_patterns
;
415 for (i
=0;i
<mod
->num_instr
;i
++)
417 mod
->instrument
[i
].data
= NULL
;
418 if (mod
->instrument
[i
].length
!=0)
420 mod
->instrument
[i
].data
= (s8
*)&mem
[ofs
];
421 ofs
+= mod
->instrument
[i
].length
;
430 s32
MOD_Load ( MOD
* mod
, const char * fname
)
435 #elif defined(DREAMCAST)
437 #elif defined(GAMECUBE)
450 if (GpFileOpen(fname
, OPEN_R
, &fh
)!=SM_OK
)
453 if ((mem
=gm_calloc(1,fs
))==NULL
)
459 GpFileRead ( fh
, mem
, fs
, &tmp
);
461 #elif defined(DREAMCAST)
462 if ((fh
=fs_open(fname
, O_RDONLY
))==0)
465 if ((mem
=calloc(1,fs
))==NULL
)
471 fs_read ( fh
, mem
, fs
);
473 #elif defined(GAMECUBE)
476 if ((fh
=fopen(fname
,"rb"))==NULL
)
479 if ((mem
=calloc(1,fs
))==NULL
)
484 fread ( mem
, fs
, 1, fh
);
488 if ( MOD_SetMOD ( mod
, mem
) < 0 )
498 u8
* getCurPatternData ( MOD
* mod
, s32 patternline
, s32 channel
)
500 return (&mod
->patterndata
[(((s32
)mod
->song
[mod
->songpos
])*mod
->num_voices
*4*64) + ((patternline
&63)*4*mod
->num_voices
) + (channel
*4)]);
503 u16
getNote ( MOD
* mod
, s32 patternline
, s32 channel
)
505 u8
* data
= getCurPatternData(mod
, patternline
, channel
);
506 return (((data
[0]&0x0f)<<8) | data
[1]);
509 u8
getInstr ( MOD
* mod
, s32 patternline
, s32 channel
)
511 u8
* data
= getCurPatternData(mod
, patternline
, channel
);
512 return ((data
[0]&0xf0) | ((data
[2]>>4)&0x0f));
515 u8
getEffect ( MOD
* mod
, s32 patternline
, s32 channel
)
517 u8
* data
= getCurPatternData(mod
, patternline
, channel
);
518 return (data
[2]&0x0f);
521 u8
getEffectOp ( MOD
* mod
, s32 patternline
, s32 channel
)
523 u8
* data
= getCurPatternData(mod
, patternline
, channel
);
527 BOOL
triggerNote ( MOD
* mod
, s32 i
, u8 instrument
, u16 note
, u8 effect
)
530 if ((instrument
!=0) && (note
!=0) && (effect
!=3) && (effect
!=5))
533 mod
->instnum
[i
] = instrument
-1;
534 mod
->sintabpos
[i
] = 0;
540 mod
->channote
[i
] = note
;
541 if ((effect
==3) || (effect
==5))
542 mod
->portamento_to
[i
] = note
;
545 if ((effect
==4) || (effect
==6))
546 mod
->vib_basefreq
[i
] = note
;
548 mod
->chanfreq
[i
] = note
;
554 mod
->volume
[i
] = mod
->instrument
[mod
->instnum
[i
]].volume
;
559 /* Handle effect which must be on handled every tick */
560 u32
effect_handler ( MOD
* mod
)
565 if (mod
->speedcounter
==0)
567 mod
->arp_counter
= 0;
571 if (mod
->arp_counter
>3)
572 mod
->arp_counter
= 1;
575 for (i
=0;i
<mod
->num_voices
;i
++)
577 if ( mod
->effect
[i
] < 0x10 ) /* Any effect ? */
579 switch ( mod
->effect
[i
] )
581 case 0x00: /* Arpeggio */
582 if (mod
->speedcounter
!=0)
584 if (mod
->effectop
[i
] != 0)
586 if (mod
->arp_counter
==1)
588 mod
->chanfreq
[i
] = freqtab
[mod
->channote
[i
]]+((mod
->effectop
[i
]>>4)&0x0f);
590 if (mod
->arp_counter
==2)
592 mod
->chanfreq
[i
] = freqtab
[mod
->channote
[i
]]+(mod
->effectop
[i
]&0x0f);
594 if (mod
->arp_counter
==3)
596 mod
->chanfreq
[i
] = freqtab
[mod
->channote
[i
]];
601 case 0x01: /* Slide up */
602 if (mod
->speedcounter
!=0)
604 mod
->chanfreq
[i
] -= mod
->effectop
[i
];
605 if (mod
->chanfreq
[i
] & 0x8000)
606 mod
->chanfreq
[i
] = 0;
609 case 0x02: /* Slide down */
610 if (mod
->speedcounter
!=0)
612 mod
->chanfreq
[i
] += mod
->effectop
[i
];
613 if (mod
->chanfreq
[i
] > 4095)
614 mod
->chanfreq
[i
] = 4095;
617 case 0x03: /* Slide to */
618 if (mod
->speedcounter
!=0)
620 if ( mod
->chanfreq
[i
] < mod
->portamento_to
[i
] )
622 if ( (mod
->portamento_to
[i
] - mod
->chanfreq
[i
]) > mod
->porta_speed
[i
] )
623 mod
->chanfreq
[i
] += mod
->porta_speed
[i
];
625 mod
->chanfreq
[i
] = mod
->portamento_to
[i
];
627 if ( mod
->chanfreq
[i
] > mod
->portamento_to
[i
] )
629 if ( (mod
->chanfreq
[i
] - mod
->portamento_to
[i
]) > mod
->porta_speed
[i
] )
630 mod
->chanfreq
[i
] -= mod
->porta_speed
[i
];
632 mod
->chanfreq
[i
] = mod
->portamento_to
[i
];
635 mod
->channote
[i
] = mod
->chanfreq
[i
];
639 case 0x04: /* Vibrato */
640 if (mod
->speedcounter
!=0)
642 mod
->chanfreq
[i
] = (((s32
)((s32
)wavetab
[mod
->vib_wave
[i
]&3][mod
->sintabpos
[i
]]*(u32
)mod
->vib_depth
[i
]))>>7) + mod
->vib_basefreq
[i
];
643 mod
->sintabpos
[i
] += mod
->vib_freq
[i
];
644 mod
->sintabpos
[i
] &= 63;
647 case 0x05: /* Slide to & Volume siding */
648 if (mod
->speedcounter
!=0)
651 if ( mod
->chanfreq
[i
] < mod
->portamento_to
[i
] )
653 if ( (mod
->portamento_to
[i
] - mod
->chanfreq
[i
]) > mod
->porta_speed
[i
] )
654 mod
->chanfreq
[i
] += mod
->porta_speed
[i
];
656 mod
->chanfreq
[i
] = mod
->portamento_to
[i
];
658 if ( mod
->chanfreq
[i
] > mod
->portamento_to
[i
] )
660 if ( (mod
->chanfreq
[i
] - mod
->portamento_to
[i
]) > mod
->porta_speed
[i
] )
661 mod
->chanfreq
[i
] -= mod
->porta_speed
[i
];
663 mod
->chanfreq
[i
] = mod
->portamento_to
[i
];
666 mod
->channote
[i
] = mod
->chanfreq
[i
];
669 /* Do volume sliding */
670 if (mod
->effectop
[i
]&0xf0) /* Increase volume */
672 mod
->volume
[i
] += (mod
->effectop
[i
]>>4)&0x0f;
673 if (mod
->volume
[i
]>64)
676 if (mod
->effectop
[i
]&0x0f) /* Decrease volume */
678 mod
->volume
[i
] -= mod
->effectop
[i
]&0x0f;
679 if (mod
->volume
[i
]&0x80) /* <0 ? */
684 case 0x06: /* Vibrato & Volume slide */
685 if (mod
->speedcounter
!=0)
687 mod
->chanfreq
[i
] = (((s32
)((s32
)wavetab
[mod
->vib_wave
[i
]&3][mod
->sintabpos
[i
]]*(u32
)mod
->vib_depth
[i
]))>>7) + mod
->vib_basefreq
[i
];
688 mod
->sintabpos
[i
] += mod
->vib_freq
[i
];
689 mod
->sintabpos
[i
] &= 63;
691 if (mod
->effectop
[i
]&0xf0) /* Increase volume */
693 mod
->volume
[i
] += (mod
->effectop
[i
]>>4)&0x0f;
694 if (mod
->volume
[i
]>64)
697 if (mod
->effectop
[i
]&0x0f) /* Decrease volume */
699 mod
->volume
[i
] -= mod
->effectop
[i
]&0x0f;
700 if (mod
->volume
[i
]&0x80) /* <0 ? */
705 case 0x07: /* Tremolo */
706 if (mod
->speedcounter
!=0)
708 s16 v
= mod
->trem_basevol
[i
];
709 v
+= ((s32
)((s32
)wavetab
[mod
->trem_wave
[i
]&3][mod
->sintabpos
[i
]]*(s32
)mod
->trem_depth
[i
]))>>6;
715 mod
->sintabpos
[i
] += mod
->trem_freq
[i
];
716 mod
->sintabpos
[i
] &= 63;
721 case 0x0a: /* Volume slide */
722 if (mod
->speedcounter
!=0)
724 if (mod
->effectop
[i
]&0xf0) /* Increase volume */
726 mod
->volume
[i
] += (mod
->effectop
[i
]>>4)&0x0f;
727 if (mod
->volume
[i
]>64)
730 if (mod
->effectop
[i
]&0x0f) /* Decrease volume */
732 mod
->volume
[i
] -= mod
->effectop
[i
]&0x0f;
733 if (mod
->volume
[i
]&0x80) /* <0 ? */
738 case 0x0e: /* Sub commands */
739 switch ( (mod
->effectop
[i
]>>4)&0x0f )
741 case 0x09: /* Retrigger sample */
742 if (mod
->speedcounter
!=0)
744 if (++mod
->retrigger_counter
[i
] >= (mod
->effectop
[i
]&0x0f))
746 mod
->retrigger_counter
[i
] = 0;
748 mod
->channel_active
[i
] = TRUE
;
753 case 0x0c: /* Cut note */
754 if (mod
->speedcounter
!=0)
756 if ( (mod
->effectop
[i
]&0x0f) == mod
->speedcounter
)
760 case 0x0d: /* Delay note */
761 if (mod
->speedcounter
!=0)
763 if (mod
->speedcounter
== (mod
->effectop
[i
]&0x0f))
765 triggerNote ( mod
, i
, mod
->nextinstr
[i
], mod
->nextnote
[i
], mod
->effect
[i
] );
766 mod
->channel_active
[i
] = TRUE
;
778 u32
process ( MOD
* mod
)
782 BOOL doPatternBreak
=FALSE
;
783 BOOL doPatternLoop
=FALSE
;
784 u8
* patternData
= getCurPatternData ( mod
, mod
->patternline
, 0 );
786 for (i
=0;i
<mod
->num_voices
;++i
)
788 u16 note
= ((patternData
[0]<<8)&0x0f00) | patternData
[1];
789 u8 instrument
= (patternData
[0]&0xf0) | ((patternData
[2]>>4)&0x0f);
790 u8 effect
= patternData
[2]&0x0f;
791 u8 effect_operand
= patternData
[3];
795 if ( ((mod
->last_effect
[i
]==0x04)||(mod
->last_effect
[i
]==0x06)) &&
796 ((effect
!=0x04) && (effect
!=0x06)) )
798 mod
->chanfreq
[i
] = mod
->vib_basefreq
[i
];
800 if ( (mod
->last_effect
[i
]==0x07) && (effect
!=0x07) )
802 mod
->volume
[i
] = mod
->trem_basevol
[i
];
805 if ( mod
->effect
[i
]==0x00 && mod
->effectop
[i
]!=0)
807 if (effect
!=0 || effect_operand
==0)
808 mod
->chanfreq
[i
] = mod
->channote
[i
];
811 mod
->nextinstr
[i
] = instrument
;
812 mod
->nextnote
[i
] = note
;
814 if ( !( (effect
==0x0e) && ((effect_operand
&0xf0)==0xd0)) )
816 if (triggerNote ( mod
, i
, mod
->nextinstr
[i
], mod
->nextnote
[i
], effect
))
819 mod
->channel_active
[i
] = TRUE
;
823 mod
->effect
[i
] = 0xff;
828 mod
->effect
[i
] = effect
;
829 mod
->effectop
[i
] = effect_operand
;
830 if ( mod
->effectop
[i
] != 0 )
831 mod
->porta_speed
[i
] = mod
->effectop
[i
];
834 if (!((mod
->last_effect
[i
]==0x04)||(mod
->last_effect
[i
]==0x06)))
835 mod
->vib_basefreq
[i
] = mod
->chanfreq
[i
];
837 if (effect_operand
&0xf0)
838 mod
->vib_freq
[i
] = (effect_operand
>>4)&0x0f;
839 if (effect_operand
&0x0f)
840 mod
->vib_depth
[i
] = effect_operand
&0x0f;
841 mod
->effect
[i
] = effect
;
842 mod
->effectop
[i
] = effect_operand
;
845 mod
->effect
[i
] = effect
;
846 mod
->effectop
[i
] = effect_operand
;
847 if ( mod
->effectop
[i
] != 0 )
848 mod
->porta_speed
[i
] = mod
->effectop
[i
];
851 if (!((mod
->last_effect
[i
]==0x04)||(mod
->last_effect
[i
]==0x06)))
852 mod
->vib_basefreq
[i
] = mod
->chanfreq
[i
];
854 mod
->effect
[i
] = effect
;
855 mod
->effectop
[i
] = effect_operand
;
858 if ( mod
->last_effect
[i
]!=0x07 )
859 mod
->trem_basevol
[i
] = mod
->volume
[i
];
861 if (effect_operand
&0xf0)
862 mod
->trem_freq
[i
] = (effect_operand
>>4)&0x0f;
863 if (effect_operand
&0x0f)
864 mod
->trem_depth
[i
] = effect_operand
&0x0f;
865 mod
->effect
[i
] = effect
;
866 mod
->effectop
[i
] = effect_operand
;
870 u32 ofs
= effect_operand
<<8;
871 if (ofs
>mod
->instrument
[mod
->instnum
[i
]].length
)
872 mod
->playpos
[i
] = mod
->instrument
[mod
->instnum
[i
]].length
<< 16;
874 mod
->playpos
[i
] = ofs
<< 16;
878 if (effect_operand
<128)
880 if(mod
->notify
) *mod
->notify
= TRUE
;
881 mod
->songpos
= effect_operand
;
882 mod
->patternline
= 0;
887 if (effect_operand
>64)
889 mod
->volume
[i
] = effect_operand
;
895 switch ( (effect_operand
>>4)&0x0f )
898 mod
->chanfreq
[i
] -= effect_operand
&0x0f;
899 if (mod
->chanfreq
[i
]&0x8000)
900 mod
->chanfreq
[i
] = 0;
903 mod
->chanfreq
[i
] += effect_operand
&0x0f;
904 if (mod
->chanfreq
[i
]>4095)
905 mod
->chanfreq
[i
] = 4095;
908 if ( (effect_operand
&0x0f) == 0x00 )
909 mod
->glissando
[i
] = FALSE
;
911 if ( (effect_operand
&0x0f) == 0x01 )
912 mod
->glissando
[i
] = TRUE
;
915 if ( (effect_operand
&0x0f) < 8 )
916 mod
->vib_wave
[i
] = effect_operand
& 0x07;
919 mod
->instrument
[mod
->instnum
[i
]].finetune
= (effect_operand
+8)&15;
922 if ((effect_operand
&0x0f)==0)
923 mod
->patternline_jumpto
= mod
->patternline
;
926 doPatternLoop
= TRUE
;
927 if (mod
->patternline_jumpcount
==0)
929 mod
->patternline_jumpcount
= effect_operand
&0x0f;
932 if (--mod
->patternline_jumpcount
==0)
933 doPatternLoop
= FALSE
;
938 if ( (effect_operand
&0x0f) < 8 )
939 mod
->trem_wave
[i
] = effect_operand
& 0x07;
942 mod
->retrigger_counter
[i
] = 0;
943 mod
->effect
[i
] = effect
;
944 mod
->effectop
[i
] = effect_operand
;
947 mod
->volume
[i
] += effect_operand
&0x0f;
948 if (mod
->volume
[i
]>64)
952 mod
->volume
[i
] -= effect_operand
&0x0f;
953 if (mod
->volume
[i
]&0x80)
957 mod
->effect
[i
] = effect
;
958 mod
->effectop
[i
] = effect_operand
;
961 mod
->patterndelay
= mod
->speed
*(effect_operand
&0x0f);
966 if ( effect_operand
<32 )
967 mod
->speed
= effect_operand
;
970 mod
->bpm
=effect_operand
;
971 mod
->samplespertick
= mod
->bpmtab
[effect_operand
-32];
976 mod
->effect
[i
] = effect
;
977 mod
->effectop
[i
] = effect_operand
;
980 mod
->last_effect
[i
] = effect
;
986 mod
->patternline
= 0;
987 if (mod
->songpos
>=mod
->song_length
)
989 if(mod
->notify
) *mod
->notify
= TRUE
;
991 mod
->patternline
= 0;
993 mod
->patternline_jumpto
= 0;
994 mod
->patternline_jumpcount
= 0;
998 mod
->patternline
= mod
->patternline_jumpto
;
1002 if (mod
->patternline
>63)
1006 mod
->patternline_jumpto
= 0;
1007 mod
->patternline_jumpcount
= 0;
1009 if (mod
->songpos
>=mod
->song_length
)
1011 if(mod
->notify
) *mod
->notify
= TRUE
;
1013 mod
->patternline
= 0;
1020 void MOD_Start ( MOD
* mod
)
1024 for (i
=MAX_VOICES
-1;i
>=0;--i
)
1027 mod
->playpos
[i
] = 0;
1028 mod
->chanfreq
[i
] = 0;
1029 mod
->instnum
[i
] = 0;
1030 mod
->channote
[i
] = 0;
1031 mod
->sintabpos
[i
] = 0;
1032 mod
->vib_freq
[i
] = 0;
1033 mod
->vib_depth
[i
] = 0;
1034 mod
->last_effect
[i
] = 0;
1035 mod
->glissando
[i
] = FALSE
;
1036 mod
->trem_wave
[i
] = 0;
1037 mod
->vib_wave
[i
] = 0;
1038 mod
->channel_active
[i
] = FALSE
;
1042 mod
->patternline
= 0;
1045 mod
->speedcounter
= 0;
1047 mod
->patterndelay
= 0;
1048 mod
->patternline_jumpto
= 0;
1049 mod
->patternline_jumpcount
= 0;
1053 mod
->bpmtab
= bpmtab32KHz
;
1054 mod
->inctab
= inctab32KHz
;
1057 mod
->bpmtab
= bpmtab48KHz
;
1058 mod
->inctab
= inctab48KHz
;
1061 mod
->bpmtab
= bpmtab48KHz
;
1062 mod
->inctab
= inctab48KHz
;
1066 if(mod
->freq
==32000 || mod
->freq
==48000) {
1067 mod
->inctab
= modplay_getinctab(mod
->freq
);
1068 mod
->bpmtab
= modplay_getbpmtab(mod
->freq
);
1072 mod
->samplescounter
= 0;
1073 mod
->samplespertick
= mod
->bpmtab
[125-32];
1076 u32
MOD_Player ( MOD
* mod
)
1078 s16
* buf
= (s16
*)mod
->mixingbuf
;
1079 s32 len
= mod
->mixingbuflen
;
1082 if (mod
->musicvolume
>0x40)
1083 mod
->musicvolume
= 0x40;
1084 if (mod
->sfxvolume
>0x40)
1085 mod
->sfxvolume
= 0x40;
1087 if (mod
->bits
== 16)
1090 if (mod
->channels
==1)
1096 s32 tick_remain
= mod
->samplespertick
- mod
->samplescounter
;
1099 res
= mix_mono_16bit ( mod
, &buf
[l
], tick_remain
<=remain
? tick_remain
: remain
);
1103 mod
->samplescounter
+= res
;
1104 if ( mod
->samplescounter
>= mod
->samplespertick
)
1106 mod
->samplescounter
-= mod
->samplespertick
;
1107 mod
->speedcounter
++;
1108 if (mod
->speedcounter
>=(mod
->speed
+mod
->patterndelay
))
1110 mod
->patterndelay
=0;
1111 retval
|= process(mod
);
1112 mod
->speedcounter
= 0;
1114 retval
|= effect_handler(mod
);
1116 } while ( remain
>0 );
1118 if (mod
->channels
==2)
1126 s32 tick_remain
= mod
->samplespertick
- mod
->samplescounter
;
1129 res
= mix_stereo_16bit ( mod
, &buf
[l
<<1], tick_remain
<=remain
? tick_remain
: remain
);
1133 mod
->samplescounter
+= res
;
1134 if ( mod
->samplescounter
>= mod
->samplespertick
)
1136 mod
->samplescounter
-= mod
->samplespertick
;
1137 mod
->speedcounter
++;
1138 if (mod
->speedcounter
>=(mod
->speed
+mod
->patterndelay
))
1140 mod
->patterndelay
=0;
1141 retval
|= process(mod
);
1142 mod
->speedcounter
= 0;
1144 retval
|= effect_handler(mod
);
1146 } while ( remain
>0 );
1150 mod
->notebeats
= retval
;
1151 if (mod
->callback
!=NULL
)
1152 mod
->callback ( mod
);
1157 s32
MOD_TriggerNote ( MOD
* mod
, s32 channel
, u8 instnum
, u16 freq
, u8 vol
)
1162 channel
+= mod
->num_voices
;
1163 if (channel
>=mod
->num_channels
)
1165 if (mod
->instrument
[instnum
].data
==NULL
&& instnum
!=0xff)
1170 mod
->channel_active
[channel
] = TRUE
;
1171 mod
->playpos
[channel
] = 0;
1172 mod
->instnum
[channel
] = instnum
;
1175 mod
->chanfreq
[channel
] = freq
;
1177 mod
->volume
[channel
] = vol
;