home *** CD-ROM | disk | FTP | other *** search
- /*
- MIKMOD.C Programmed by MikMak of Unicorn Design
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <string.h>
- #include <alloc.h>
- #include <conio.h>
- #include <ctype.h>
-
- #include "modload.h"
- #include "modplay.h"
- #include "mytypes.h"
- #include "forte.h"
- #include "gf1proto.h"
- #include "extern.h"
- #include "ultraerr.h"
- #include "ultraext.h"
-
- #include "wildfile.h"
- #include "getopt.h"
-
- extern ULTRA_CFG config;
-
- #define MAXHANDLE 31
-
- /* this example only loads 1 module
- at a time, so 31 handles are enough */
-
- ULONG Ultra[MAXHANDLE];
-
- /* Ultra[] holds the sample dram adresses
- of the 31 samples of a module */
-
-
-
- void SetBPM(int bpm)
- {
- /* The player routine has to be called (bpm*50)/125 times a second,
- so the interval between calls takes 125/(bpm*50) seconds (amazing!).
-
- The Timer1 handler has a resolution of 160 microseconds.
-
- So the timer value to program:
-
- (125/(bpm*50)) / 1.6e-4 = 15625/bpm
- */
-
- UltraStartTimer(1,15625/bpm);
- }
-
-
-
- #pragma argsused
-
- void GusPlay(int voice,AUDTMP *aud,MODFILE *mf)
- /*
- Callback routine for playing the samples on a GUS. (this routine is
- called each tick, for each voice)
- */
- {
- UWORD period,vol,frq;
- ULONG base;
-
- /* get sample period and volume */
-
- period=aud->period;
-
- if(period<50) period=50; // limit the period value
- if(period>1814) period=1814;
-
- vol=((UWORD)mp_mainvol*aud->volume)/0xd;
- frq=3579546UL/period;
-
- // Check if the sample has to be restarted
-
- if(aud->kick){
-
- // Get sample dram address
-
- base=Ultra[aud->handle];
-
- /* When the previous sample still is active, ramp down the volume
- and wait until the ramping is done */
-
- if (!UltraVoiceStopped(voice)) {
- UltraVectorLinearVolume(voice,0,0x3f,0);
- while (!UltraVolumeStopped(voice)) ;
- UltraStopVoice(voice);
- }
-
- UltraSetFrequency(voice,frq);
-
- if(aud->loop<aud->size){
-
- // Start a looping sample
-
- UltraStartVoice(voice,
- base+aud->start,
- base+aud->loop,
- base+aud->size,0x8);
- }
- else{
-
- // Start a one-shot sample
-
- UltraStartVoice(voice,
- base+aud->start,
- base+aud->start,
- base+aud->size,0);
- }
- aud->kick=0;
- }
- else{
- /* Voice doesn't have to be restarted, so
- just update the period */
-
- UltraSetFrequency(voice,frq);
- }
-
- // and update volume
-
- UltraVectorLinearVolume(voice,vol,0x3f,0);
- }
-
-
-
-
- void HandleTimer1()
- {
- static int odd=0;
-
- /* Do not service the odd calls to this handler .. This
- effectively makes this a 2*80=160 microsecond handler */
-
- if(odd^=1) return;
-
- MP_HandleTick(); // Call the player routine
- SetBPM(mp_bpm); // Update beats-per-minute
- }
-
-
-
-
-
-
- int GusLoad(FILE *fp,SAMPLEINFO *smp)
- /*
- callback routine for the MODLOAD module.
-
- fp :file ptr to that sample
- smp :Sampleinfo of the sample that is being loaded.
-
- returns: -1 on error
- or
- >=0 samplehandle
- */
- {
- int handle;
-
- // Find empty slot to put sample address in
-
- for(handle=0;handle<MAXHANDLE;handle++){
- if(Ultra[handle]==0) break;
- }
- if(handle==MAXHANDLE) return -1;
-
- // Allocate GUS dram and store the address in Ultra[handle]
- // Alloc 1 byte more for anticlick measures. see below.
-
- if(UltraMemAlloc(smp->length+1,&Ultra[handle])!=ULTRA_OK)
- return -1;
-
- // Load the sample
-
- if(UltraFileload(fp,DMA_8|DMA_NO_CVT,Ultra[handle],smp->length)==0) return -1;
-
- if(smp->replen>2){ // looping sample ?
-
- /* Anticlick for looping samples:
- Copy the first byte in the loop
- one place beyond the end of the loop */
-
- UltraPoke(Ultra[handle]+smp->reppos+smp->replen,
- UltraPeek(Ultra[handle]+smp->reppos));
- }
- else{
-
- /* Anticlick for one-shot samples:
- Zero the byte beyond the end of the sample.
- */
-
- UltraPoke(Ultra[handle]+smp->length,0);
- }
- return handle;
- }
-
-
-
- void GusUnLoad(int handle,SAMPLEINFO *smp)
- /*
- callback routine to unload samples
-
- handle :Sample-handle that is being freed
- smp :sampleinfo of sample that is being freed
- */
- {
- UltraMemFree(smp->length+1,Ultra[handle]);
- Ultra[handle]=0;
- }
-
-
- int PlayModule(char *file)
- {
- char c;
- int t;
- MODFILE *mf;
-
- printf("\nFile : %s\n",file);
-
- if((mf=ML_Open(file,NULL))==NULL){
- printf("MikMod Error: %s\n",ML_Error());
- return 0;
- }
-
- printf("Title : %s\n"
- "ModType : %s %d channels\n"
- "Patterns : %d\n"
- "Songlength: %d\n",
- mf->songname,
- mf->modtype,
- mf->numchn,
- mf->numpat,
- mf->songlength);
-
- if(!ML_Load(mf)){
- printf("MikMod Error: %s\n",ML_Error());
- ML_Free(mf);
- return 0;
- }
-
- MP_Init(mf);
-
- for(t=0;t<mf->numchn;t++) UltraSetBalance(t,7+t-(mf->numchn>>1));
-
- // Let's make some noise !
-
- UltraEnableOutput();
- delay(30);
- SetBPM(125); // Kickstart the timer
-
- puts("Press space to continue, ESC to quit..");
-
- // You might want to do something more useful here
-
- do c=getch(); while(c!=' ' && c!=0x1b);
-
- UltraStopTimer(1);
- for(t=0;t<mf->numchn;t++) UltraVoiceOff(t,0);
-
- UltraDisableOutput();
-
- ML_Free(mf);
-
- return(c!=0x1b);
- }
-
-
-
- int PlayWildModule(char *wildname)
- /*
- Plays all modules that correspond to the wildcard filename 'wildname'
- */
- {
- int ok;
- char *name;
-
- if((name=GetFirstName(wildname))==NULL){
- printf("Could not find %s\n",wildname);
- return 0;
- }
- do{
- ok=PlayModule(name);
- } while(ok && (name=GetNextName())!=NULL);
-
- return ok;
- }
-
-
- int breakhandler(void)
- {
- return 1;
- }
-
-
-
- int main(int argc,char *argv[])
- {
- int t;
- char opt,*arg;
- int argcount=0; // counts number of 'real' arguments
- int cmderr=0; // error in commandline flag
- int morehelp=0; // set if user wants more help
-
- printf("MIKMOD v0.43 or how to make a modplayer using the GUS SDK Toolkit v2.10\n"
- "Programmed by MikMak of Unicorn Design. This is SOURCEWARE/PUBLIC DOMAIN\n"
- "So you may use my routines as long as you mention my name :)\n"
- "E-Mail: mikmak@stack.urc.tue.nl\n\n");
-
- /* init the option scanner to look
- for the options /? /H /L /X and /V */
-
- InitOpt(argc,argv,"?hHlLxXv:V:");
-
- while((t=GetOpt(&opt,&arg))!=GO_EOF && !cmderr){
-
- switch(t){
-
- case GO_OPT:
-
- switch(tolower(opt)){
-
- case 'l':
- ML_Load15(1);
- break;
-
- case 'x':
- MP_ExtSpd(0);
- break;
-
- case 'v':
- MP_MainVol(atoi(arg));
- break;
-
- case '?':
- case 'h':
- morehelp=1;
- cmderr=1;
- break;
- }
- break;
-
- case GO_ARG:
- argcount++; // count the number of "real" arguments
- break;
-
- case GO_UNKNOWN_SWITCH:
- printf("\07Unknown switch - '%c'\n\n",opt);
- cmderr=1;
- break;
-
- case GO_SWITCH_NEEDS_ARG:
- printf("\07Switch needs an argument - '%c'\n\n",opt);
- cmderr=1;
- break;
- }
- }
-
- if(cmderr || argcount==0){
-
- puts("Usage: MIKMOD <fletch.mod> [spacedb.mod] ... [/X] [/L] [/Vxx] [/?] [/H]\n");
-
- if(morehelp)
- puts("- /L enables loading old 15-instrument modules\n"
- "- /X disables protracker extended speed\n"
- "- /Vxx Sets volume from 0 (silence) to 100 (mayhem). Default=80\n"
- "- Wildcards are allowed\n"
- "- Options can be placed anywhere on the commandline\n"
- "- Options can be combined behind a single switch char: /XV 100\n\n"
- "Examples:\n\n"
- "MIKMOD teardrop.mod /L /V50\tPlays 15-instr. module at 50% volume\n"
- "MIKMOD /X klisjepa.mod /V100\tPlays klisjepa.mod without ext. spd at max vol.\n"
- "MIKMOD x*.mod y*.mod \t\tPlays all modules starting with 'x' and 'y'\n");
- else
- puts("Type MIKMOD /? or MIKMOD /h for more help.");
-
- return -1;
- }
-
- /* disable control-break by
- installing a custom handler */
-
- ctrlbrk(breakhandler);
-
- /* Get the ULTRASND environment string parameters */
-
- if(!UltraGetCfg(&config)){
- puts("Ultrasound env. string not found..");
- return -1;
- }
-
- /* Set up 14 channels */
-
- if(UltraOpen(&config,14)==NO_ULTRA){
- puts("No ultrasound card found");
- return -1;
- }
-
- /* Report size of GUS DRAM */
-
- printf("This GUS has %dK of Dram\n",UltraSizeDram());
-
- /* Grab the 80 microsecond timer handler */
-
- UltraTimer1Handler(HandleTimer1);
-
- /* Make MODLOAD and MODPLAY use the gus-
- specific load,unload and play routines */
-
- ML_RegisterLoader(GusLoad);
- ML_RegisterUnLoader(GusUnLoad);
- MP_RegisterPlayer(GusPlay);
-
-
- /* Then try to load and play each module yeah */
-
- InitOpt(argc,argv,"?hHlLxXv:V:");
-
- while((t=GetOpt(&opt,&arg))!=GO_EOF){
- if(t==GO_ARG){
- if(!PlayWildModule(arg)) break;
- }
- }
-
- /* Shut sound down & re-init hardware ... */
-
- UltraClose();
- return 0;
- }
-