Mercurial > ~darius > hgwebdir.cgi > mikmod
view playercode/load_669.c @ 11:d5cb2cfc8eca
Initial revision
author | darius |
---|---|
date | Fri, 23 Jan 1998 16:05:11 +0000 |
parents | 5d614bcc4287 |
children |
line wrap: on
line source
/* Name: LOAD_669.C Description: Tran's 669 module loader Portability: All systems - all compilers (hopefully) If this module is found to not be portable to any particular platform, please contact Jake Stine at dracoirs@epix.net (see MIKMOD.TXT for more information on contacting the author). */ #include <string.h> #include "mikmod.h" // Raw 669 header struct: typedef struct S69HEADER { UBYTE marker[2]; CHAR message[108]; UBYTE nos; UBYTE nop; UBYTE looporder; UBYTE orders[0x80]; UBYTE tempos[0x80]; UBYTE breaks[0x80]; } S69HEADER; // Raw 669 sampleinfo struct: typedef struct S69SAMPLE { CHAR filename[13]; SLONG length; SLONG loopbeg; SLONG loopend; } S69SAMPLE; // Raw 669 Note struct typedef struct S69NOTE { UBYTE a,b,c; } S69NOTE; static S69NOTE *s69pat = NULL; static S69HEADER *mh = NULL; static CHAR *S69_Version[] = { "669", "Extended 669" }; BOOL S69_Test(void) { UBYTE id[2]; if(!_mm_read_UBYTES(id,2,modfp)) return 0; if(!memcmp(id,"if",2) || !memcmp(id,"JN",2)) { _mm_fseek(modfp,108,SEEK_CUR); if(_mm_read_UBYTE(modfp) > 64) return 0; if(_mm_read_UBYTE(modfp) > 128) return 0; if(_mm_read_UBYTE(modfp) > 120) return 0; return 1; } return 0; } BOOL S69_Init(void) { if(!(s69pat=(S69NOTE *)_mm_malloc(64*8*sizeof(S69NOTE)))) return 0; if(!(mh=(S69HEADER *)_mm_calloc(1,sizeof(S69HEADER)))) return 0; return 1; } void S69_Cleanup(void) { if(s69pat!=NULL) free(s69pat); if(mh!=NULL) free(mh); mh = NULL; s69pat = NULL; } BOOL S69_LoadPatterns(void) { int t,s,q,tracks=0,t2,t3; UBYTE note,inst,vol,a,b,c, lo; S69NOTE *cur; if(!AllocPatterns()) return 0; if(!AllocTracks()) return 0; for(t=0; t<of.numpat; t++) { of.pattrows[t] = mh->breaks[t]+1; // Load the pattern into the temp buffer // and convert it into the 3-byte format cur = s69pat; for(t2=64; t2; t2--) { for(t3=8; t3; t3--, cur++) { cur->a = _mm_read_UBYTE(modfp); cur->b = _mm_read_UBYTE(modfp); cur->c = _mm_read_UBYTE(modfp); } } if(feof(modfp)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } for(s=0; s<8; s++) { UniReset(); UniPTEffect(0xf,75); // was 78 UniPTEffect(0xf,3); for(q=0; q<64; q++) { a = s69pat[(q*8)+s].a; b = s69pat[(q*8)+s].b; c = s69pat[(q*8)+s].c; note = a >> 2; inst = ((a & 0x3) << 4) | ((b & 0xf0) >> 4); vol = b & 0xf; if(note < 0x3e) { UniInstrument(inst); UniNote(note+24); } if(note < 0x3f) UniPTEffect(0xc,vol<<2); lo = c & 0xf; switch(c >> 4) { case 0: UniPTEffect(0x1,lo); break; case 1: UniPTEffect(0x2,lo); break; case 2: UniPTEffect(0x3,lo); break; case 4: UniPTEffect(0x4,lo); break; } UniNewline(); } if(!(of.tracks[tracks++]=UniDup())) return 0; } } return 1; } BOOL S69_Load(void) { int t; S69SAMPLE s; SAMPLE *q; // try to read module header _mm_read_UBYTES(mh->marker,2,modfp); _mm_read_UBYTES((UBYTE *)mh->message,108,modfp); mh->nos = _mm_read_UBYTE(modfp); mh->nop = _mm_read_UBYTE(modfp); mh->looporder = _mm_read_UBYTE(modfp); _mm_read_UBYTES(mh->orders,0x80,modfp); _mm_read_UBYTES(mh->tempos,0x80,modfp); _mm_read_UBYTES(mh->breaks,0x80,modfp); // set module variables of.initspeed = 6; of.inittempo = 125; of.songname = DupStr(mh->message,108); of.modtype = strdup(S69_Version[memcmp(mh->marker,"JN",2)==0]); of.numchn = 8; of.numpat = mh->nop; of.numins = of.numsmp = mh->nos; of.numtrk = of.numchn*of.numpat; of.flags = UF_XMPERIODS; // | UF_LINEAR; if(!AllocPositions(0x80)) return 0; for(t=0; t<0x80; t++) { if(mh->orders[t]==0xff) break; of.positions[t] = mh->orders[t]; } of.numpos = t; if(!AllocSamples()) return 0; q = of.samples; for(t=0; t<of.numins; t++) { // try to read sample info _mm_read_UBYTES((UBYTE *)s.filename,13,modfp); s.length = _mm_read_I_SLONG(modfp); s.loopbeg = _mm_read_I_SLONG(modfp); s.loopend = _mm_read_I_SLONG(modfp); if((s.length < 0) || (s.loopbeg < -1) || (s.loopend < -1)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } q->samplename = DupStr(s.filename,13); q->seekpos = 0; q->speed = 0; q->length = s.length; q->loopstart = s.loopbeg; q->loopend = (s.loopend<s.length) ? s.loopend : s.length; q->flags = (s.loopbeg<s.loopend) ? SF_LOOP : 0; q->volume = 64; q++; } if(!S69_LoadPatterns()) return 0; return 1; } MLOADER load_669 = { NULL, "669", "Portable 669 loader v0.1", S69_Init, S69_Test, S69_Load, S69_Cleanup, NULL };