#include #include #include "mtypes.h" #include "forte.h" #include "gf1proto.h" #include "gf1hware.h" #include "extern.h" #include "ultraerr.h" #include "ultraext.h" #include "mdriver.h" extern ULTRA_CFG config; #define MAXHANDLE 125 // should be enough for now ULONG Ultra[MAXHANDLE]; ULONG Ultrs[MAXHANDLE]; /* Ultra[] holds the sample dram adresses of the samples of a module */ extern UNIMOD *pf; void SetOther(UBYTE voice,ULONG frq,UBYTE ivol,UBYTE pan) { UltraSetFrequency(voice,frq); UltraVectorLinearVolume(voice,6U*ivol,0x3f,0); UltraSetBalance(voice,pan>>4); } void HandleVolume(int voice) { UWORD vol; ULONG base,start,size,reppos,repend; GHOLD *aud; aud=&ghld[voice]; if(aud->kick){ aud->kick=0; base=Ultra[aud->handle]; start=aud->start; reppos=aud->reppos; repend=aud->repend; size=aud->size; if(aud->flags&SF_16BITS){ start<<=1; reppos<<=1; repend<<=1; size<<=1; } /* Stop current sample and start a new one */ UltraStopVoice(voice); SetOther(voice,aud->frq,aud->vol,aud->pan); if(aud->flags&SF_LOOP){ // Start a looping sample UltraStartVoice(voice, base+start, base+reppos, base+repend,0x8|((aud->flags&SF_16BITS)?4:0)| ((aud->flags&SF_BIDI)?16:0)); } else{ // Start a one-shot sample UltraStartVoice(voice, base+start, base+start, base+size+2,(aud->flags&SF_16BITS)?4:0); } } } void GUS_Update(void) { int t; GHOLD *aud; for(t=0;tkick){ if(UltraReadVolume(t)<100){ HandleVolume(t); } else{ UltraVectorLinearVolume(t,0,0x3f,VL_WAVE_IRQ); } } else{ SetOther(t,aud->frq,aud->vol,aud->pan); } } } WORD GUS_Load(FILE *fp,ULONG length,ULONG loopstart,ULONG loopend,UWORD flags) /* callback routine for the MODLOAD module. fp :file ptr to that sample smp :Sampleinfo of the sample that is being loaded. */ { int handle,t; long p,l; SL_Init(fp,flags,flags|SF_SIGNED); // Find empty slot to put sample address in for(handle=0;handle0){ char buffer[512]; long todo; todo=(l>512) ? 512 : l; SL_Load(buffer,todo); UltraDownload(buffer,0,p,todo+8,TRUE); p+=todo; l-=todo; } if(flags&SF_LOOP && !(flags&SF_BIDI)){ // looping sample ? /* Anticlick for looping samples: Copy the first bytes in the loop beyond the end of the loop */ for(t=0;t<8;t++){ UltraPoke(Ultra[handle]+loopend+t, UltraPeek(Ultra[handle]+loopstart+t)); } } else{ /* Anticlick for one-shot samples: Zero the bytes beyond the end of the sample. */ for(t=0;t<8;t++){ UltraPoke(Ultra[handle]+length+t,0); } } return handle; } void GUS_UnLoad(WORD handle) /* callback routine to unload samples smp :sampleinfo of sample that is being freed */ { UltraMemFree(Ultrs[handle],Ultra[handle]); Ultra[handle]=0; } BOOL GUS_Init(void) { if(!(md_mode&DMODE_16BITS)){ md_mode|=DMODE_16BITS; // gus can't do 8 bit mixing } if(!(md_mode&DMODE_STEREO)){ md_mode|=DMODE_STEREO; // gus can't do mono mixing } /* get gus config */ if(!UltraGetCfg(&config)){ myerr="Ultrasound env. string not found.."; return 0; } /* Set up 14 channels */ if(UltraOpen(&config,14)==NO_ULTRA){ myerr="No ultrasound card found"; return 0; } /* Grab the 80 microsecond timer handler */ UltraVolumeHandler(HandleVolume); return 1; } void GUS_Exit(void) { UltraClose(); } void GUS_PlayStart(void) { // init number of voices UltraNumVoices((md_numchn<14)?14:md_numchn); md_mixfreq=(md_numchn<=14) ? 44100 : (617400L/md_numchn); // Let's make some noise ! UltraEnableOutput(); } void GUS_PlayStop(void) { UltraDisableOutput(); } BOOL GUS_IsThere(void) { return(getenv("ULTRASND")!=NULL); } DRIVER gusdriver={ NULL, "Gravis Ultrasound", "MikMod GUS Driver v0.2 (uses the GUS-SDK 2.11)", GUS_IsThere, GUS_Load, GUS_UnLoad, GUS_Init, GUS_Exit, GUS_PlayStart, GUS_PlayStop, GUS_Update };