X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=libs%2Foldmik%2Fsrc%2Fload_m15.c;fp=libs%2Foldmik%2Fsrc%2Fload_m15.c;h=6186a03e1c634f042b9cef6975ad292306ca00f4;hp=0000000000000000000000000000000000000000;hb=77db1ca18d5446dcda9e524261399b63c2cd1813;hpb=a714b8c4811627d874934b0a0387b8cb27fc5921 diff --git a/libs/oldmik/src/load_m15.c b/libs/oldmik/src/load_m15.c new file mode 100644 index 0000000..6186a03 --- /dev/null +++ b/libs/oldmik/src/load_m15.c @@ -0,0 +1,323 @@ +/* + +Name: +LOAD_M15.C + +Description: +15 instrument MOD loader + +Portability: +All systems - all compilers (hopefully) + +*/ +#include +#include +#include +#include +#include "mikmod.h" + +/************************************************************************* +*************************************************************************/ + + +typedef struct MSAMPINFO{ /* sample header as it appears in a module */ + char samplename[22]; + UWORD length; + UBYTE finetune; + UBYTE volume; + UWORD reppos; + UWORD replen; +} MSAMPINFO; + + +typedef struct MODULEHEADER{ /* verbatim module header */ + char songname[20]; /* the songname.. */ + MSAMPINFO samples[15]; /* all sampleinfo */ + UBYTE songlength; /* number of patterns used */ + UBYTE magic1; /* should be 127 */ + UBYTE positions[128]; /* which pattern to play at pos */ +} MODULEHEADER; + + +typedef struct MODNOTE{ + UBYTE a,b,c,d; +} MODNOTE; + + +/************************************************************************* +*************************************************************************/ + +static MODULEHEADER *mh; /* raw as-is module header */ +static MODNOTE *patbuf; + + +static BOOL LoadModuleHeader(MODULEHEADER *mh) +{ + int t; + + _mm_read_str(mh->songname,20,modfp); + + for(t=0;t<15;t++){ + MSAMPINFO *s= &mh->samples[t]; + _mm_read_str(s->samplename,22,modfp); + s->length =_mm_read_M_UWORD(modfp); + s->finetune =_mm_read_UBYTE(modfp); + s->volume =_mm_read_UBYTE(modfp); + s->reppos =_mm_read_M_UWORD(modfp); + s->replen =_mm_read_M_UWORD(modfp); + } + + mh->songlength =_mm_read_UBYTE(modfp); + mh->magic1 =_mm_read_UBYTE(modfp); /* should be 127 */ + _mm_read_UBYTES(mh->positions,128,modfp); + + return(!feof(modfp)); +} + + + +BOOL M15_Test(void) +{ + int t; + MODULEHEADER mh; + + if(!LoadModuleHeader(&mh)) return 0; + + for(t=0;t<15;t++){ + + /* all finetunes should be zero */ + if(mh.samples[t].finetune!=0) return 0; + + /* all volumes should be <=64 */ + if(mh.samples[t].volume>64) return 0; + } + if(mh.magic1>127) return 0; /* and magic1 should be <128 */ + + return 1; +} + + +BOOL M15_Init(void) +{ + patbuf=NULL; + if(!(mh=(MODULEHEADER *)MyCalloc(1,sizeof(MODULEHEADER)))) return 0; + return 1; +} + + +void M15_Cleanup(void) +{ + if(mh!=NULL) free(mh); + if(patbuf!=NULL) free(patbuf); +} + + +/* + +Old (amiga) noteinfo: + + _____byte 1_____ byte2_ _____byte 3_____ byte4_ +/ \ / \ / \ / \ +0000 0000-00000000 0000 0000-00000000 + +Upper four 12 bits for Lower four Effect command. +bits of sam- note period. bits of sam- +ple number. ple number. + + +*/ + + +UWORD M15_npertab[60]={ + +/* -> Tuning 0 */ + + 1712,1616,1524,1440,1356,1280,1208,1140,1076,1016,960,906, + 856,808,762,720,678,640,604,570,538,508,480,453, + 428,404,381,360,339,320,302,285,269,254,240,226, + 214,202,190,180,170,160,151,143,135,127,120,113, + 107,101,95,90,85,80,75,71,67,63,60,56 +}; + + +void M15_ConvertNote(MODNOTE *n) +{ + UBYTE instrument,effect,effdat,note; + UWORD period; + + /* extract the various information from the 4 bytes that + make up a single note */ + + instrument=(n->a&0x10)|(n->c>>4); + period=(((UWORD)n->a&0xf)<<8)+n->b; + effect=n->c&0xf; + effdat=n->d; + + /* Convert the period to a note number */ + + note=0; + if(period!=0){ + for(note=0;note<60;note++){ + if(period>=M15_npertab[note]) break; + } + note++; + if(note==61) note=0; + } + + if(instrument!=0){ + UniInstrument(instrument-1); + } + + if(note!=0){ + UniNote(note+23); + } + + UniPTEffect(effect,effdat); +} + + + +UBYTE *M15_ConvertTrack(MODNOTE *n) +{ + int t; + + UniReset(); + for(t=0;t<64;t++){ + M15_ConvertNote(n); + UniNewline(); + n+=of.numchn; + } + return UniDup(); +} + + + +BOOL M15_LoadPatterns(void) +/* + Loads all patterns of a modfile and converts them into the + 3 byte format. +*/ +{ + int t,s,tracks=0; + + if(!AllocPatterns()) return 0; + if(!AllocTracks()) return 0; + + /* Allocate temporary buffer for loading + and converting the patterns */ + + if(!(patbuf=(MODNOTE *)MyCalloc(64U*of.numchn,sizeof(MODNOTE)))) return 0; + + for(t=0;tsongname,20); /* make a cstr of songname */ + of.numpos=mh->songlength; /* copy the songlength */ + memcpy(of.positions,mh->positions,128); /* copy the position array */ + + /* Count the number of patterns */ + + of.numpat=0; + + for(t=0;t<128;t++){ /* <-- BUGFIX... have to check ALL positions */ + if(of.positions[t] > of.numpat){ + of.numpat=of.positions[t]; + } + } + of.numpat++; + of.numtrk=of.numpat*of.numchn; + + /* Finally, init the sampleinfo structures */ + + of.numins=15; + if(!AllocInstruments()) return 0; + + s=mh->samples; /* init source pointer */ + d=of.instruments; /* init dest pointer */ + + for(t=0;tnumsmp=1; + if(!AllocSamples(d)) return 0; + + q=d->samples; + + /* convert the samplename */ + + d->insname=DupStr(s->samplename,22); + + /* init the sampleinfo variables and + convert the size pointers to longword format */ + + q->c2spd=finetune[s->finetune&0xf]; + q->volume=s->volume; + q->loopstart=s->reppos; + q->loopend=q->loopstart+(s->replen<<1); + q->length=s->length<<1; + q->seekpos=0; + + q->flags=SF_SIGNED; + if(s->replen>1) q->flags|=SF_LOOP; + + /* fix replen if repend>length */ + + if(q->loopend>q->length) q->loopend=q->length; + + s++; /* point to next source sampleinfo */ + d++; /* point to next destiny sampleinfo */ + } + + if(!M15_LoadPatterns()) return 0; + return 1; +} + + + +LOADER load_m15={ + NULL, + "15-instrument module", + "Portable MOD-15 loader v0.1", + M15_Init, + M15_Test, + M15_Load, + M15_Cleanup +};