/* Loads all patterns of a modfile and converts them into the 3 byte format. */ static BOOL ML_LoadPatterns(void) { 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 *)MikMod_calloc(64U * of.numchn, sizeof(MODNOTE)))) return 0; /* patterns start here */ _mm_fseek(modreader, 0xA66, SEEK_SET); for (t = 0; t < of.numpat; t++) { /* Load the pattern into the temp buffer and convert it */ for (s = 0; s < (64U * of.numchn); s++) { patbuf[s].a = _mm_read_UBYTE(modreader); patbuf[s].b = _mm_read_UBYTE(modreader); patbuf[s].c = _mm_read_UBYTE(modreader); patbuf[s].d = _mm_read_UBYTE(modreader); } for (s = 0; s < of.numchn; s++) { if (!(of.tracks[tracks++] = ConvertTrack(patbuf + s))) { return 0; } } } return 1; }
BOOL S69_Test(void) { UBYTE buf[0x80]; if(!_mm_read_UBYTES(buf,2,modreader)) return 0; /* look for id */ if(!memcmp(buf,"if",2) || !memcmp(buf,"JN",2)) { int i; /* skip song message */ _mm_fseek(modreader,108,SEEK_CUR); /* sanity checks */ if(_mm_read_UBYTE(modreader) > 64) return 0; if(_mm_read_UBYTE(modreader) > 128) return 0; if(_mm_read_UBYTE(modreader) > 127) return 0; /* check order table */ if(!_mm_read_UBYTES(buf,0x80,modreader)) return 0; for(i=0;i<0x80;i++) if((buf[i]>=0x80)&&(buf[i]!=0xff)) return 0; /* check tempos table */ if(!_mm_read_UBYTES(buf,0x80,modreader)) return 0; for(i=0;i<0x80;i++) if((!buf[i])||(buf[i]>32)) return 0; /* check pattern length table */ if(!_mm_read_UBYTES(buf,0x80,modreader)) return 0; for(i=0;i<0x80;i++) if(buf[i]>0x3f) return 0; } else return 0; return 1; }
static BOOL ML_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;t<of.numpat;t++){ /* Load the pattern into the temp buffer and convert it */ for(s=0;s<(64L * of.numchn);s++){ patbuf[s].a=_mm_read_UBYTE(); patbuf[s].b=_mm_read_UBYTE(); patbuf[s].c=_mm_read_UBYTE(); patbuf[s].d=_mm_read_UBYTE(); } for(s=0;s<of.numchn;s++){ if(!(of.tracks[tracks++]=ConvertTrack(patbuf+s))) return 0; } } return 1; }
UWORD _mm_read_I_UWORD (URL reader) { UWORD result = _mm_read_UBYTE (reader); result |= ((UWORD) _mm_read_UBYTE (reader)) << 8; return result; }
BOOL DSM_ReadPattern(void) { int row=0,flag; DSMNOTE *n; /* clear pattern data */ memset(dsmbuf,255,16*64*sizeof(DSMNOTE)); _mm_read_UBYTE(modfp); _mm_read_UBYTE(modfp); while(row<64) { flag = _mm_read_UBYTE(modfp); if(_mm_feof(modfp)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } if(flag) { n = &dsmbuf[((flag&0xf)*64)+row]; if(flag&0x80) n->note = _mm_read_UBYTE(modfp); if(flag&0x40) n->ins = _mm_read_UBYTE(modfp); if(flag&0x20) n->vol = _mm_read_UBYTE(modfp); if(flag&0x10) { n->cmd = _mm_read_UBYTE(modfp); n->inf = _mm_read_UBYTE(modfp); } } else row++; } return 1; }
/* Read sample information */ static BOOL OKT_doSAMP(int len) { int t; SAMPLE *q; OKTSAMPLE s; of.numins = of.numsmp = (len / 0x20); if (!AllocSamples()) return 0; for (t = 0, q = of.samples; t < of.numins; t++, q++) { _mm_read_UBYTES(s.sampname, 20, modreader); s.len = _mm_read_M_ULONG(modreader); s.loopbeg = _mm_read_M_UWORD(modreader); s.looplen = _mm_read_M_UWORD(modreader); _mm_read_UBYTE(modreader); s.volume = _mm_read_UBYTE(modreader); _mm_read_M_UWORD(modreader); if (_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } if (!s.len) q->seekpos = q->length = q->loopstart = q->loopend = q->flags = 0; else { s.len--; /* sanity checks */ if (s.loopbeg > s.len) s.loopbeg = s.len; if (s.loopbeg + s.looplen > s.len) s.looplen = s.len - s.loopbeg; if (s.looplen < 2) s.looplen = 0; q->length = s.len; q->loopstart = s.loopbeg; q->loopend = s.looplen + q->loopstart; q->volume = s.volume; q->flags = SF_SIGNED; if (s.looplen) q->flags |= SF_LOOP; } q->samplename = DupStr(s.sampname, 20, 1); q->speed = 8363; } return 1; }
static BOOL AMF_Test(void) { UBYTE id[3],ver; if(!_mm_read_UBYTES(id,3,modreader)) return 0; if(memcmp(id,"AMF",3)) return 0; ver=_mm_read_UBYTE(modreader); if((ver>=10)&&(ver<=14)) return 1; return 0; }
static BOOL IT_ReadPattern(UWORD patrows) { int row=0,flag,ch,blah; ITNOTE *itt=itpat,dummy,*n,*l; memset(itt,255,200*64*sizeof(ITNOTE)); do { if((flag=_mm_read_UBYTE(modreader))==EOF) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } if(!flag) { itt=&itt[of.numchn]; row++; } else { ch=remap[(flag-1)&63]; if(ch!=-1) { n=&itt[ch]; l=&last[ch]; } else n=l=&dummy; if(flag&128) mask[ch]=_mm_read_UBYTE(modreader); if(mask[ch]&1) /* convert IT note off to internal note off */ if((l->note=n->note=_mm_read_UBYTE(modreader))==255) l->note=n->note=253; if(mask[ch]&2) l->ins=n->ins=_mm_read_UBYTE(modreader); if(mask[ch]&4) l->volpan=n->volpan=_mm_read_UBYTE(modreader); if(mask[ch]&8) { l->cmd=n->cmd=_mm_read_UBYTE(modreader); l->inf=n->inf=_mm_read_UBYTE(modreader); } if(mask[ch]&16) n->note=l->note; if(mask[ch]&32) n->ins=l->ins; if(mask[ch]&64) n->volpan=l->volpan; if(mask[ch]&128) { n->cmd=l->cmd; n->inf=l->inf; } } } while(row<patrows); for(blah=0;blah<of.numchn;blah++) { if(!(of.tracks[numtrk++]=IT_ConvertTrack(&itpat[blah],patrows))) return 0; } return 1; }
static CHAR *UNI_LoadTitle(void) { UBYTE ver; int posit[3]={304,306,26}; _mm_fseek(modreader,3,SEEK_SET); ver=_mm_read_UBYTE(modreader); if(ver=='N') ver='6'; _mm_fseek(modreader,posit[ver-'4'],SEEK_SET); return readstring(); }
BOOL S3M_Load(BOOL curious) { int t,u,track = 0; SAMPLE *q; UBYTE pan[32]; /* try to read module header */ _mm_read_string(mh->songname,28,modreader); mh->t1a =_mm_read_UBYTE(modreader); mh->type =_mm_read_UBYTE(modreader); _mm_read_UBYTES(mh->unused1,2,modreader); mh->ordnum =_mm_read_I_UWORD(modreader); mh->insnum =_mm_read_I_UWORD(modreader); mh->patnum =_mm_read_I_UWORD(modreader); mh->flags =_mm_read_I_UWORD(modreader); mh->tracker =_mm_read_I_UWORD(modreader); mh->fileformat =_mm_read_I_UWORD(modreader); _mm_read_string(mh->scrm,4,modreader); mh->mastervol =_mm_read_UBYTE(modreader); mh->initspeed =_mm_read_UBYTE(modreader); mh->inittempo =_mm_read_UBYTE(modreader); mh->mastermult =_mm_read_UBYTE(modreader); mh->ultraclick =_mm_read_UBYTE(modreader); mh->pantable =_mm_read_UBYTE(modreader); _mm_read_UBYTES(mh->unused2,8,modreader); mh->special =_mm_read_I_UWORD(modreader); _mm_read_UBYTES(mh->channels,32,modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* then we can decide the module type */ tracker=mh->tracker>>12; if((!tracker)||(tracker>=NUMTRACKERS)) tracker=NUMTRACKERS-1; /* unknown tracker */ else { if(mh->tracker>=0x3217) tracker=NUMTRACKERS+1; /* IT 2.14p4 */ else if(mh->tracker>=0x3216) tracker=NUMTRACKERS; /* IT 2.14p3 */ else tracker--; } of.modtype = strdup(S3M_Version[tracker]); if(tracker<NUMTRACKERS) { of.modtype[numeric[tracker]] = ((mh->tracker>>8) &0xf)+'0'; of.modtype[numeric[tracker]+2] = ((mh->tracker>>4)&0xf)+'0'; of.modtype[numeric[tracker]+3] = ((mh->tracker)&0xf)+'0'; }
static BOOL DSM_ReadPattern(void) { int flag,row=0; SWORD length; DSMNOTE *n; /* clear pattern data */ memset(dsmbuf,255,DSM_MAXCHAN*64*sizeof(DSMNOTE)); length=_mm_read_I_SWORD(modreader); while(row<64) { flag=_mm_read_UBYTE(modreader); if((_mm_eof(modreader))||(--length<0)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } if(flag) { n=&dsmbuf[((flag&0xf)*64)+row]; if(flag&0x80) n->note=_mm_read_UBYTE(modreader); if(flag&0x40) n->ins=_mm_read_UBYTE(modreader); if(flag&0x20) n->vol=_mm_read_UBYTE(modreader); if(flag&0x10) { n->cmd=_mm_read_UBYTE(modreader); n->inf=_mm_read_UBYTE(modreader); } } else row++; } return 1; }
static BOOL S3M_ReadPattern(void) { int row=0,flag,ch; S3MNOTE *n; S3MNOTE dummy; /* clear pattern data */ mod_memset(s3mbuf, (char)255, 16*64*sizeof(S3MNOTE)); while(row<64){ flag=_mm_read_UBYTE(); // if(flag==255) // { // gModPlayerErrorMessage=ERROR_LOADING_PATTERN; // return 0; // } if(flag) { ch=flag&31; if(mh_s3m->channels[ch]<16) { n=&s3mbuf[(64U*remap[ch])+row]; } else { n=&dummy; } if(flag&32) { n->note=_mm_read_UBYTE(); n->ins=_mm_read_UBYTE(); } if(flag&64) { n->vol=_mm_read_UBYTE(); } if(flag&128) { n->cmd=_mm_read_UBYTE(); n->inf=_mm_read_UBYTE(); } } else { row++; } } return 1; }
/* Read order table */ static BOOL OKT_doPATT(void) { int t; if (!of.numpos || !AllocPositions(of.numpos)) return 0; for (t = 0; t < 128; t++) if (t < of.numpos) of.positions[t] = (UWORD)_mm_read_UBYTE(modreader); else break; return 1; }
static BOOL IMF_ReadPattern(SLONG size,UWORD rows) { int row=0,flag,ch; IMFNOTE *n,dummy; /* clear pattern data */ memset(imfpat,255,32*256*sizeof(IMFNOTE)); while((size>0)&&(row<rows)) { flag=_mm_read_UBYTE(modreader);size--; if(_mm_eof(modreader)) { _mm_errno=MMERR_LOADING_PATTERN; return 0; } if(flag) { ch=remap[flag&31]; if(ch!=-1) n=&imfpat[256*ch+row]; else n=&dummy; if(flag&32) { n->note=_mm_read_UBYTE(modreader); if(n->note>=0xa0) n->note=0xa0; /* note off */ n->ins =_mm_read_UBYTE(modreader); size-=2; } if(flag&64) { size-=2; n->eff2=_mm_read_UBYTE(modreader); n->dat2=_mm_read_UBYTE(modreader); } if(flag&128) { n->eff1=_mm_read_UBYTE(modreader); n->dat1=_mm_read_UBYTE(modreader); size-=2; } } else row++; } if((size)||(row!=rows)) { _mm_errno=MMERR_LOADING_PATTERN; return 0; } return 1; }
static UBYTE ReadUltEvent(ULTEVENT* event) { UBYTE flag,rep=1; flag = _mm_read_UBYTE(modreader); if(flag==0xfc) { rep = _mm_read_UBYTE(modreader); event->note =_mm_read_UBYTE(modreader); } else event->note = flag; event->sample =_mm_read_UBYTE(modreader); event->eff =_mm_read_UBYTE(modreader); event->dat1 =_mm_read_UBYTE(modreader); event->dat2 =_mm_read_UBYTE(modreader); return rep; }
/* Because so many IT files have 64 channels as the set number used, but really only use far less (usually from 8 to 24 still), I had to make this function, which determines the number of channels that are actually USED by a pattern. NOTE: You must first seek to the file location of the pattern before calling this procedure. Returns 1 on error */ static BOOL IT_GetNumChannels(UWORD patrows) { int row=0,flag,ch; do { if((flag=_mm_read_UBYTE(modreader))==EOF) { _mm_errno=MMERR_LOADING_PATTERN; return 1; } if(!flag) row++; else { ch=(flag-1)&63; remap[ch]=0; if(flag & 128) mask[ch]=_mm_read_UBYTE(modreader); if(mask[ch]&1) _mm_read_UBYTE(modreader); if(mask[ch]&2) _mm_read_UBYTE(modreader); if(mask[ch]&4) _mm_read_UBYTE(modreader); if(mask[ch]&8) { _mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader); } } } while(row<patrows); return 0; }
static int ReadUltEvent(ULTEVENT *event) { UBYTE flag,rep=1; flag=_mm_read_UBYTE(); if(flag==0xfc){ _mm_read_str((char *)&rep,1); event->note =_mm_read_UBYTE(); } else{ event->note=flag; } event->sample =_mm_read_UBYTE(); event->eff =_mm_read_UBYTE(); event->dat1 =_mm_read_UBYTE(); event->dat2 =_mm_read_UBYTE(); return rep; }
static BOOL S3M_ReadPattern(void) { int row=0,flag,ch; S3MNOTE *n,dummy; /* clear pattern data */ memset(s3mbuf,255,32*64*sizeof(S3MNOTE)); while(row<64) { flag=_mm_read_UBYTE(modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } if(flag) { ch=remap[flag&31]; if(ch!=-1) n=&s3mbuf[(64U*ch)+row]; else n=&dummy; if(flag&32) { n->note=_mm_read_UBYTE(modreader); n->ins=_mm_read_UBYTE(modreader); } if(flag&64) { n->vol=_mm_read_UBYTE(modreader); if (n->vol>64) n->vol=64; } if(flag&128) { n->cmd=_mm_read_UBYTE(modreader); n->inf=_mm_read_UBYTE(modreader); } } else row++; } return 1; }
/* Because so many s3m files have 16 channels as the set number used, but really only use far less (usually 8 to 12 still), I had to make this function, which determines the number of channels that are actually USED by a pattern. For every channel that's used, it sets the appropriate array entry of the global variable 'remap' NOTE: You must first seek to the file location of the pattern before calling this procedure. Returns 1 on fail. */ static BOOL S3M_GetNumChannels(void) { int row=0,flag,ch; while(row<64) { flag=_mm_read_UBYTE(modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_PATTERN; return 1; } if(flag) { ch=flag&31; if(mh->channels[ch]<32) remap[ch] = 0; if(flag&32) {_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);} if(flag&64) _mm_read_UBYTE(modreader); if(flag&128){_mm_read_UBYTE(modreader);_mm_read_UBYTE(modreader);} } else row++; } return 0; }
static BOOL MTM_Load(void) { MTMSAMPLE s; INSTRUMENT *d; SAMPLE *q; int t,u; /* try to read module header */ _mm_read_UBYTES(mh_mtm->id,3); mh_mtm->version =_mm_read_UBYTE(); _mm_read_str(mh_mtm->songname,20); mh_mtm->numtracks =_mm_read_I_UWORD(); mh_mtm->lastpattern =_mm_read_UBYTE(); mh_mtm->lastorder =_mm_read_UBYTE(); mh_mtm->commentsize =_mm_read_I_UWORD(); mh_mtm->numsamples =_mm_read_UBYTE(); mh_mtm->attribute =_mm_read_UBYTE(); mh_mtm->beatspertrack=_mm_read_UBYTE(); mh_mtm->numchannels =_mm_read_UBYTE(); _mm_read_UBYTES(mh_mtm->panpos,32); if(modpos > modsize) { gModPlayerErrorMessage=ERROR_LOADING_HEADER; return 0; } /* set module variables */ of.initspeed=6; of.inittempo=125; of.modtype=strdup(MTM_Version); of.numchn=mh_mtm->numchannels; of.numtrk=mh_mtm->numtracks+1; /* get number of channels */ of.songname=DupStr(mh_mtm->songname,20); /* make a cstr of songname */ of.numpos=mh_mtm->lastorder+1; /* copy the songlength */ of.numpat=mh_mtm->lastpattern+1; for(t=0; t<32; t++) of.panning[t]=mh_mtm->panpos[t]<<4; of.numins=mh_mtm->numsamples; if(!AllocInstruments()) return 0; d=of.instruments; for(t=0; t<of.numins; t++) { d->numsmp=1; if(!AllocSamples(d)) return 0; q=d->samples; /* try to read sample info */ _mm_read_str(s.samplename,22); s.length =_mm_read_I_ULONG(); s.reppos =_mm_read_I_ULONG(); s.repend =_mm_read_I_ULONG(); s.finetune =_mm_read_UBYTE(); s.volume =_mm_read_UBYTE(); s.attribute =_mm_read_UBYTE(); if(modpos > modsize) { gModPlayerErrorMessage=ERROR_LOADING_SAMPLEINFO; return 0; } d->insname=DupStr(s.samplename,22); q->seekpos=0; q->c2spd=finetune[s.finetune]; q->length=s.length; q->loopstart=s.reppos; q->loopend=s.repend; q->volume=s.volume; q->flags=0; if(s.repend-s.reppos>2) q->flags|=SF_LOOP; /* <- 1.00 bugfix */ if(s.attribute&1) { /* If the sample is 16-bits, convert the length and replen byte-values into sample-values */ q->flags|=SF_16BITS; q->length>>=1; q->loopstart>>=1; q->loopend>>=1; } d++; }
static BOOL ULT_Load(BOOL curious) { int t,u,tracks=0; SAMPLE *q; ULTSAMPLE s; ULTHEADER mh; UBYTE nos,noc,nop; /* try to read module header */ _mm_read_string(mh.id,15,modreader); _mm_read_string(mh.songtitle,32,modreader); mh.reserved=_mm_read_UBYTE(modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } ULT_Version[ULT_VERSION_LEN-1]='3'+(mh.id[14]-'1'); of.modtype = DupStr(ULT_Version,ULT_VERSION_LEN,1); of.initspeed = 6; of.inittempo = 125; of.reppos = 0; /* read songtext */ if ((mh.id[14]>'1')&&(mh.reserved)) if(!ReadLinedComment(mh.reserved * 32, 32)) return 0; nos=_mm_read_UBYTE(modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } of.songname=DupStr(mh.songtitle,32,1); of.numins=of.numsmp=nos; if(!AllocSamples()) return 0; q = of.samples; for(t=0; t<nos; t++) { /* try to read sample info */ _mm_read_string(s.samplename,32,modreader); _mm_read_string(s.dosname,12,modreader); s.loopstart =_mm_read_I_ULONG(modreader); s.loopend =_mm_read_I_ULONG(modreader); s.sizestart =_mm_read_I_ULONG(modreader); s.sizeend =_mm_read_I_ULONG(modreader); s.volume =_mm_read_UBYTE(modreader); s.flags =_mm_read_UBYTE(modreader); s.speed =(mh.id[14]>='4')?_mm_read_I_UWORD(modreader):8363; s.finetune =_mm_read_I_SWORD(modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } q->samplename=DupStr(s.samplename,32,1); /* The correct formula for the coefficient would be pow(2,(double)s.finetume/OCTAVE/32768), but to avoid floating point here, we'll use a first order approximation here. 1/567290 == Ln(2)/OCTAVE/32768 */ q->speed=s.speed+s.speed*(((SLONG)s.speed*(SLONG)s.finetune)/567290); q->length = s.sizeend-s.sizestart; q->volume = s.volume>>2; q->loopstart = s.loopstart; q->loopend = s.loopend; q->flags = SF_SIGNED; if(s.flags&ULTS_LOOP) q->flags|=SF_LOOP; if(s.flags&ULTS_16BITS) { s.sizeend+=(s.sizeend-s.sizestart); s.sizestart<<=1; q->flags|=SF_16BITS; q->loopstart>>=1; q->loopend>>=1; } q++; }
static BOOL UNI_Load(BOOL curious) { int t; char *modtype,*oldtype=NULL; INSTRUMENT *d; SAMPLE *q; /* read module header */ _mm_read_UBYTES(mh.id,4,modreader); if(mh.id[3]!='N') universion=mh.id[3]-'0'; else universion=0x100; if(universion>=6) { if (universion==6) { _mm_skip_BYTE(modreader); } else { universion=_mm_read_M_UWORD(modreader); } mh.flags =_mm_read_M_UWORD(modreader); mh.numchn =_mm_read_UBYTE(modreader); mh.numvoices =_mm_read_UBYTE(modreader); mh.numpos =_mm_read_M_UWORD(modreader); mh.numpat =_mm_read_M_UWORD(modreader); mh.numtrk =_mm_read_M_UWORD(modreader); mh.numins =_mm_read_M_UWORD(modreader); mh.numsmp =_mm_read_M_UWORD(modreader); mh.reppos =_mm_read_M_UWORD(modreader); mh.initspeed =_mm_read_UBYTE(modreader); mh.inittempo =_mm_read_UBYTE(modreader); mh.initvolume=_mm_read_UBYTE(modreader); /* I expect this to show up soon in APlayer 1.06 format */ if (universion >= 0x106) mh.bpmlimit=_mm_read_M_UWORD(modreader); else mh.bpmlimit=32; mh.flags &= UF_XMPERIODS | UF_LINEAR | UF_INST | UF_NNA; mh.flags |= UF_PANNING; } else { mh.numchn =_mm_read_UBYTE(modreader); mh.numpos =_mm_read_I_UWORD(modreader); mh.reppos =(universion==5)?_mm_read_I_UWORD(modreader):0; mh.numpat =_mm_read_I_UWORD(modreader); mh.numtrk =_mm_read_I_UWORD(modreader); mh.numins =_mm_read_I_UWORD(modreader); mh.initspeed =_mm_read_UBYTE(modreader); mh.inittempo =_mm_read_UBYTE(modreader); _mm_read_UBYTES(mh.positions,256,modreader); _mm_read_UBYTES(mh.panning,32,modreader); mh.flags =_mm_read_UBYTE(modreader); mh.bpmlimit =32; mh.flags &= UF_XMPERIODS | UF_LINEAR; mh.flags |= UF_INST | UF_NOWRAP | UF_PANNING; } /* set module parameters */ of.flags =mh.flags; of.numchn =mh.numchn; of.numpos =mh.numpos; of.numpat =mh.numpat; of.numtrk =mh.numtrk; of.numins =mh.numins; of.reppos =mh.reppos; of.initspeed =mh.initspeed; of.inittempo =mh.inittempo; if(mh.bpmlimit) of.bpmlimit=mh.bpmlimit; else /* be bug-compatible with older releases */ of.bpmlimit=32; of.songname=readstring(); if(universion<0x102) oldtype=readstring(); if(oldtype) { size_t len=strlen(oldtype)+20; if(!(modtype=(char*)MikMod_malloc(len))) return 0; #ifdef HAVE_SNPRINTF snprintf(modtype,len,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); #else sprintf(modtype,"%s (was %s)",(universion>=0x100)?"APlayer":"MikCvt2",oldtype); #endif } else { if(!(modtype=(char*)MikMod_malloc(10))) return 0; #ifdef HAVE_SNPRINTF snprintf(modtype,10,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); #else sprintf(modtype,"%s",(universion>=0x100)?"APlayer":"MikCvt3"); #endif } of.modtype=MikMod_strdup(modtype); MikMod_free(modtype);MikMod_free(oldtype); of.comment=readstring(); if(universion>=6) { of.numvoices=mh.numvoices; of.initvolume=mh.initvolume; } if(_mm_eof(modreader)) { _mm_errno=MMERR_LOADING_HEADER; return 0; } /* positions */ if(!AllocPositions(of.numpos)) return 0; if(universion>=6) { if(universion>=0x100) _mm_read_M_UWORDS(of.positions,of.numpos,modreader); else for(t=0;t<of.numpos;t++) of.positions[t]=_mm_read_UBYTE(modreader); _mm_read_M_UWORDS(of.panning,of.numchn,modreader); _mm_read_UBYTES(of.chanvol,of.numchn,modreader); } else { if((mh.numpos>256)||(mh.numchn>32)) { _mm_errno=MMERR_LOADING_HEADER; return 0; } for(t=0;t<of.numpos;t++) of.positions[t]=mh.positions[t]; for(t=0;t<of.numchn;t++) of.panning[t]=mh.panning[t]; } /* convert the ``end of song'' pattern code if necessary */ if(universion<0x106) for(t=0;t<of.numpos;t++) if(of.positions[t]==255) of.positions[t]=LAST_PATTERN; /* instruments and samples */ if(universion>=6) { of.numsmp=mh.numsmp; if(!AllocSamples()) return 0; if(!loadsmp6()) return 0; if(of.flags&UF_INST) { if(!AllocInstruments()) return 0; if(!loadinstr6()) return 0; } } else { if(!AllocInstruments()) return 0; if(!loadinstr5()) return 0; if(!AllocSamples()) { MikMod_free(wh);wh=NULL; return 0; } if(!loadsmp5()) return 0; /* check if the original file had no instruments */ if(of.numsmp==of.numins) { for(t=0,d=of.instruments;t<of.numins;t++,d++) { int u; if((d->volpts)||(d->panpts)||(d->globvol!=64)) break; for(u=0;u<96;u++) if((d->samplenumber[u]!=t)||(d->samplenote[u]!=u)) break; if(u!=96) break; } if(t==of.numins) { of.flags&=~UF_INST; of.flags&=~UF_NOWRAP; for(t=0,d=of.instruments,q=of.samples;t<of.numins;t++,d++,q++) { q->samplename=d->insname; d->insname=NULL; } } } } /* patterns */ if(!AllocPatterns()) return 0; if(universion>=6) { _mm_read_M_UWORDS(of.pattrows,of.numpat,modreader); _mm_read_M_UWORDS(of.patterns,of.numpat*of.numchn,modreader); } else { _mm_read_I_UWORDS(of.pattrows,of.numpat,modreader); _mm_read_I_UWORDS(of.patterns,of.numpat*of.numchn,modreader); } /* tracks */ if(!AllocTracks()) return 0; for(t=0;t<of.numtrk;t++) if(!(of.tracks[t]=readtrack())) { _mm_errno=MMERR_LOADING_TRACK; return 0; } return 1; }
BOOL IT_Load(BOOL curious) { int t,u,lp; INSTRUMENT *d; SAMPLE *q; BOOL compressed=0; numtrk=0; filters=0; /* try to read module header */ _mm_read_I_ULONG(modreader); /* kill the 4 byte header */ _mm_read_string(mh->songname,26,modreader); _mm_read_UBYTES(mh->blank01,2,modreader); mh->ordnum =_mm_read_I_UWORD(modreader); mh->insnum =_mm_read_I_UWORD(modreader); mh->smpnum =_mm_read_I_UWORD(modreader); mh->patnum =_mm_read_I_UWORD(modreader); mh->cwt =_mm_read_I_UWORD(modreader); mh->cmwt =_mm_read_I_UWORD(modreader); mh->flags =_mm_read_I_UWORD(modreader); mh->special =_mm_read_I_UWORD(modreader); mh->globvol =_mm_read_UBYTE(modreader); mh->mixvol =_mm_read_UBYTE(modreader); mh->initspeed =_mm_read_UBYTE(modreader); mh->inittempo =_mm_read_UBYTE(modreader); mh->pansep =_mm_read_UBYTE(modreader); mh->zerobyte =_mm_read_UBYTE(modreader); mh->msglength =_mm_read_I_UWORD(modreader); mh->msgoffset =_mm_read_I_ULONG(modreader); _mm_read_UBYTES(mh->blank02,4,modreader); _mm_read_UBYTES(mh->pantable,64,modreader); _mm_read_UBYTES(mh->voltable,64,modreader); if(_mm_eof(modreader)) { _mm_errno=MMERR_LOADING_HEADER; return 0; } /* set module variables */ of.songname = DupStr(mh->songname,26,0); /* make a cstr of songname */ of.reppos = 0; of.numpat = mh->patnum; of.numins = mh->insnum; of.numsmp = mh->smpnum; of.initspeed = mh->initspeed; of.inittempo = mh->inittempo; of.initvolume = mh->globvol; of.flags |= UF_BGSLIDES|UF_ARPMEM; if(mh->songname[25]) { of.numvoices=1+mh->songname[25]; #ifdef MIKMOD_DEBUG fprintf(stderr,"Embedded IT limitation to %d voices\n",of.numvoices); #endif } /* set the module type */ /* 2.17 : IT 2.14p4 */ /* 2.16 : IT 2.14p3 with resonant filters */ /* 2.15 : IT 2.14p3 (improved compression) */ if((mh->cwt<=0x219)&&(mh->cwt>=0x217)) of.modtype=strdup(IT_Version[mh->cmwt<0x214?4:5]); else if (mh->cwt>=0x215) of.modtype=strdup(IT_Version[mh->cmwt<0x214?2:3]); else { of.modtype = strdup(IT_Version[mh->cmwt<0x214?0:1]); of.modtype[mh->cmwt<0x214?15:26] = (mh->cwt>>8)+'0'; of.modtype[mh->cmwt<0x214?17:28] = ((mh->cwt>>4)&0xf)+'0'; of.modtype[mh->cmwt<0x214?18:29] = ((mh->cwt)&0xf)+'0'; } if(mh->flags&8) of.flags|=(UF_XMPERIODS | UF_LINEAR); if((mh->cwt>=0x106)&&(mh->flags&16)) old_effect=1; else old_effect=0; /* set panning positions */ for(t=0;t<64;t++) { mh->pantable[t]&=0x7f; if(mh->pantable[t]<64) of.panning[t]=mh->pantable[t]<<2; else if(mh->pantable[t]==64) of.panning[t]=255; else if(mh->pantable[t]==100) of.panning[t]=PAN_SURROUND; else if(mh->pantable[t]==127) of.panning[t]=PAN_CENTER; else { _mm_errno=MMERR_LOADING_HEADER; return 0; } } /* set channel volumes */ memcpy(of.chanvol,mh->voltable,64); /* read the order data */ if(!AllocPositions(mh->ordnum)) return 0; if(!(origpositions=_mm_calloc(mh->ordnum,sizeof(UWORD)))) return 0; for(t=0;t<mh->ordnum;t++) { origpositions[t]=_mm_read_UBYTE(modreader); if((origpositions[t]>mh->patnum)&&(origpositions[t]<254)) origpositions[t]=255; } if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } poslookupcnt=(UBYTE)mh->ordnum; S3MIT_CreateOrders(curious); if(!(paraptr=(ULONG*)_mm_malloc((mh->insnum+mh->smpnum+of.numpat)* sizeof(ULONG)))) return 0; /* read the instrument, sample, and pattern parapointers */ _mm_read_I_ULONGS(paraptr,mh->insnum+mh->smpnum+of.numpat,modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* Check for and load midi information for resonant filters */ if(mh->cmwt>=0x216) { if(mh->special&8) { IT_LoadMidiConfiguration(modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } } else IT_LoadMidiConfiguration(NULL); filters=1; } /* Check for and load song comment */ if((mh->special&1)&&(mh->cwt>=0x104)&&(mh->msglength)) { _mm_fseek(modreader,(long)(mh->msgoffset),SEEK_SET); if(!ReadComment(mh->msglength)) return 0; } if(!(mh->flags&4)) of.numins=of.numsmp; if(!AllocSamples()) return 0; if(!AllocLinear()) return 0; /* Load all samples */ q = of.samples; for(t=0;t<mh->smpnum;t++) { ITSAMPLE s; /* seek to sample position */ _mm_fseek(modreader,(long)(paraptr[mh->insnum+t]+4),SEEK_SET); /* load sample info */ _mm_read_string(s.filename,12,modreader); s.zerobyte = _mm_read_UBYTE(modreader); s.globvol = _mm_read_UBYTE(modreader); s.flag = _mm_read_UBYTE(modreader); s.volume = _mm_read_UBYTE(modreader); _mm_read_string(s.sampname,26,modreader); s.convert = _mm_read_UBYTE(modreader); s.panning = _mm_read_UBYTE(modreader); s.length = _mm_read_I_ULONG(modreader); s.loopbeg = _mm_read_I_ULONG(modreader); s.loopend = _mm_read_I_ULONG(modreader); s.c5spd = _mm_read_I_ULONG(modreader); s.susbegin = _mm_read_I_ULONG(modreader); s.susend = _mm_read_I_ULONG(modreader); s.sampoffset = _mm_read_I_ULONG(modreader); s.vibspeed = _mm_read_UBYTE(modreader); s.vibdepth = _mm_read_UBYTE(modreader); s.vibrate = _mm_read_UBYTE(modreader); s.vibwave = _mm_read_UBYTE(modreader); /* Generate an error if c5spd is > 512k, or samplelength > 256 megs (nothing would EVER be that high) */ if(_mm_eof(modreader)||(s.c5spd>0x7ffffL)||(s.length>0xfffffffUL)|| (s.loopbeg>0xfffffffUL)||(s.loopend>0xfffffffUL)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } q->samplename = DupStr(s.sampname,26,0); q->speed = s.c5spd / 2; q->panning = ((s.panning&127)==64)?255:(s.panning&127)<<2; q->length = s.length; q->loopstart = s.loopbeg; q->loopend = s.loopend; q->volume = s.volume; q->globvol = s.globvol; q->seekpos = s.sampoffset; /* Convert speed to XM linear finetune */ if(of.flags&UF_LINEAR) q->speed=speed_to_finetune(s.c5spd,t); if(s.panning&128) q->flags|=SF_OWNPAN; if(s.vibrate) { q->vibflags |= AV_IT; q->vibtype = s.vibwave; q->vibsweep = s.vibrate * 2; q->vibdepth = s.vibdepth; q->vibrate = s.vibspeed; } if(s.flag&2) q->flags|=SF_16BITS; if((s.flag&8)&&(mh->cwt>=0x214)) { q->flags|=SF_ITPACKED; compressed=1; } if(s.flag&16) q->flags|=SF_LOOP; if(s.flag&64) q->flags|=SF_BIDI; if(mh->cwt>=0x200) { if(s.convert&1) q->flags|=SF_SIGNED; if(s.convert&4) q->flags|=SF_DELTA; } q++; } /* Load instruments if instrument mode flag enabled */ if(mh->flags&4) { if(!AllocInstruments()) return 0; d=of.instruments; of.flags|=UF_NNA|UF_INST; for(t=0;t<mh->insnum;t++) { ITINSTHEADER ih; /* seek to instrument position */ _mm_fseek(modreader,paraptr[t]+4,SEEK_SET); /* load instrument info */ _mm_read_string(ih.filename,12,modreader); ih.zerobyte = _mm_read_UBYTE(modreader); if(mh->cwt<0x200) { /* load IT 1.xx inst header */ ih.volflg = _mm_read_UBYTE(modreader); ih.volbeg = _mm_read_UBYTE(modreader); ih.volend = _mm_read_UBYTE(modreader); ih.volsusbeg = _mm_read_UBYTE(modreader); ih.volsusend = _mm_read_UBYTE(modreader); _mm_read_I_UWORD(modreader); ih.fadeout = _mm_read_I_UWORD(modreader); ih.nna = _mm_read_UBYTE(modreader); ih.dnc = _mm_read_UBYTE(modreader); } else { /* Read IT200+ header */ ih.nna = _mm_read_UBYTE(modreader); ih.dct = _mm_read_UBYTE(modreader); ih.dca = _mm_read_UBYTE(modreader); ih.fadeout = _mm_read_I_UWORD(modreader); ih.ppsep = _mm_read_UBYTE(modreader); ih.ppcenter = _mm_read_UBYTE(modreader); ih.globvol = _mm_read_UBYTE(modreader); ih.chanpan = _mm_read_UBYTE(modreader); ih.rvolvar = _mm_read_UBYTE(modreader); ih.rpanvar = _mm_read_UBYTE(modreader); } ih.trkvers = _mm_read_I_UWORD(modreader); ih.numsmp = _mm_read_UBYTE(modreader); _mm_read_UBYTE(modreader); _mm_read_string(ih.name,26,modreader); _mm_read_UBYTES(ih.blank01,6,modreader); _mm_read_I_UWORDS(ih.samptable,ITNOTECNT,modreader); if(mh->cwt<0x200) { /* load IT 1xx volume envelope */ _mm_read_UBYTES(ih.volenv,200,modreader); for(lp=0;lp<ITENVCNT;lp++) { ih.oldvoltick[lp] = _mm_read_UBYTE(modreader); ih.volnode[lp] = _mm_read_UBYTE(modreader); } } else { /* load IT 2xx volume, pan and pitch envelopes */ ih.volflg =_mm_read_UBYTE(modreader); ih.volpts =_mm_read_UBYTE(modreader); ih.volbeg =_mm_read_UBYTE(modreader); ih.volend =_mm_read_UBYTE(modreader); ih.volsusbeg=_mm_read_UBYTE(modreader); ih.volsusend=_mm_read_UBYTE(modreader); for(lp=0;lp<ITENVCNT;lp++) { ih.volnode[lp]=_mm_read_UBYTE(modreader); ih.voltick[lp]=_mm_read_I_UWORD(modreader); } _mm_read_UBYTE(modreader); ih.panflg =_mm_read_UBYTE(modreader); ih.panpts =_mm_read_UBYTE(modreader); ih.panbeg =_mm_read_UBYTE(modreader); ih.panend =_mm_read_UBYTE(modreader); ih.pansusbeg=_mm_read_UBYTE(modreader); ih.pansusend=_mm_read_UBYTE(modreader); for(lp=0;lp<ITENVCNT;lp++) { ih.pannode[lp]=_mm_read_SBYTE(modreader); ih.pantick[lp]=_mm_read_I_UWORD(modreader); } _mm_read_UBYTE(modreader); ih.pitflg =_mm_read_UBYTE(modreader); ih.pitpts =_mm_read_UBYTE(modreader); ih.pitbeg =_mm_read_UBYTE(modreader); ih.pitend =_mm_read_UBYTE(modreader); ih.pitsusbeg=_mm_read_UBYTE(modreader); ih.pitsusend=_mm_read_UBYTE(modreader); for(lp=0;lp < ITENVCNT; lp++) { ih.pitnode[lp]=_mm_read_SBYTE(modreader); ih.pittick[lp]=_mm_read_I_UWORD(modreader); } _mm_read_UBYTE(modreader); } if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } d->volflg|=EF_VOLENV; d->insname = DupStr(ih.name,26,0); d->nnatype = ih.nna & NNA_MASK; if(mh->cwt<0x200) { d->volfade=ih.fadeout<< 6; if(ih.dnc) { d->dct=DCT_NOTE; d->dca=DCA_CUT; } if(ih.volflg&1) d->volflg|=EF_ON; if(ih.volflg&2) d->volflg|=EF_LOOP; if(ih.volflg&4) d->volflg|=EF_SUSTAIN; /* XM conversion of IT envelope Array */ d->volbeg = ih.volbeg; d->volend = ih.volend; d->volsusbeg = ih.volsusbeg; d->volsusend = ih.volsusend; if(ih.volflg&1) { for(u=0;u<ITENVCNT;u++) if(ih.oldvoltick[d->volpts]!=0xff) { d->volenv[d->volpts].val=(ih.volnode[d->volpts]<<2); d->volenv[d->volpts].pos=ih.oldvoltick[d->volpts]; d->volpts++; } else break; } } else { d->panning=((ih.chanpan&127)==64)?255:(ih.chanpan&127)<<2; if(!(ih.chanpan&128)) d->flags|=IF_OWNPAN; if(!(ih.ppsep & 128)) { d->pitpansep=ih.ppsep<<2; d->pitpancenter=ih.ppcenter; d->flags|=IF_PITCHPAN; } d->globvol=ih.globvol>>1; d->volfade=ih.fadeout<<5; d->dct =ih.dct; d->dca =ih.dca; if(mh->cwt>=0x204) { d->rvolvar = ih.rvolvar; d->rpanvar = ih.rpanvar; } if(ih.volflg&1) d->volflg|=EF_ON; if(ih.volflg&2) d->volflg|=EF_LOOP; if(ih.volflg&4) d->volflg|=EF_SUSTAIN; d->volpts=ih.volpts; d->volbeg=ih.volbeg; d->volend=ih.volend; d->volsusbeg=ih.volsusbeg; d->volsusend=ih.volsusend; for(u=0;u<ih.volpts;u++) d->volenv[u].pos=ih.voltick[u]; if((d->volflg&EF_ON)&&(d->volpts<2)) d->volflg&=~EF_ON; for(u=0;u<ih.volpts;u++) d->volenv[u].val=(ih.volnode[u]<<2); if(ih.panflg&1) d->panflg|=EF_ON; if(ih.panflg&2) d->panflg|=EF_LOOP; if(ih.panflg&4) d->panflg|=EF_SUSTAIN; d->panpts=ih.panpts; d->panbeg=ih.panbeg; d->panend=ih.panend; d->pansusbeg=ih.pansusbeg; d->pansusend=ih.pansusend; for(u=0;u<ih.panpts;u++) d->panenv[u].pos=ih.pantick[u]; if((d->panflg&EF_ON)&&(d->panpts<2)) d->panflg&=~EF_ON; for(u=0;u<ih.panpts;u++) d->panenv[u].val=ih.pannode[u]==32?255:(ih.pannode[u]+32)<<2; if(ih.pitflg&1) d->pitflg|=EF_ON; if(ih.pitflg&2) d->pitflg|=EF_LOOP; if(ih.pitflg&4) d->pitflg|=EF_SUSTAIN; d->pitpts=ih.pitpts; d->pitbeg=ih.pitbeg; d->pitend=ih.pitend; d->pitsusbeg=ih.pitsusbeg; d->pitsusend=ih.pitsusend; for(u=0;u<ih.pitpts;u++) d->pitenv[u].pos=ih.pittick[u]; if((d->pitflg&EF_ON)&&(d->pitpts<2)) d->pitflg&=~EF_ON; for(u=0;u<ih.pitpts;u++) d->pitenv[u].val=ih.pitnode[u]+32; if(ih.pitflg&0x80) { /* filter envelopes not supported yet */ d->pitflg&=~EF_ON; ih.pitpts=ih.pitbeg=ih.pitend=0; #ifdef MIKMOD_DEBUG { static int warn=0; if(!warn) fputs("\rFilter envelopes not supported yet\n",stderr); warn=1; } #endif } } for(u=0;u<ITNOTECNT;u++) { d->samplenote[u]=(ih.samptable[u]&255); d->samplenumber[u]= (ih.samptable[u]>>8)?((ih.samptable[u]>>8)-1):0xffff; if(d->samplenumber[u]>=of.numsmp) d->samplenote[u]=255; else if (of.flags&UF_LINEAR) { int note=(int)d->samplenote[u]+noteindex[d->samplenumber[u]]; d->samplenote[u]=(note<0)?0:(note>255?255:note); } } d++; } } else if(of.flags & UF_LINEAR) {
static BOOL S3M_Load(void) { int t,u,track=0; INSTRUMENT *d; SAMPLE *q; UBYTE isused[16]; UBYTE pan[32]; /* try to read module header */ _mm_read_str(mh_s3m->songname,28); mh_s3m->t1a =_mm_read_UBYTE(); mh_s3m->type =_mm_read_UBYTE(); _mm_read_UBYTES(mh_s3m->unused1,2); mh_s3m->ordnum =_mm_read_I_UWORD(); mh_s3m->insnum =_mm_read_I_UWORD(); mh_s3m->patnum =_mm_read_I_UWORD(); mh_s3m->flags =_mm_read_I_UWORD(); mh_s3m->tracker =_mm_read_I_UWORD(); mh_s3m->fileformat =_mm_read_I_UWORD(); _mm_read_str(mh_s3m->scrm,4); mh_s3m->mastervol =_mm_read_UBYTE(); mh_s3m->initspeed =_mm_read_UBYTE(); mh_s3m->inittempo =_mm_read_UBYTE(); mh_s3m->mastermult =_mm_read_UBYTE(); mh_s3m->ultraclick =_mm_read_UBYTE(); mh_s3m->pantable =_mm_read_UBYTE(); _mm_read_UBYTES(mh_s3m->unused2,8); mh_s3m->special =_mm_read_I_UWORD(); _mm_read_UBYTES(mh_s3m->channels,32); if(modpos > modsize){ gModPlayerErrorMessage=ERROR_LOADING_HEADER; return 0; } /* set module variables */ of.modtype=strdup(S3M_Version); of.songname=DupStr(mh_s3m->songname,28); /* make a cstr of songname */ of.numpat=mh_s3m->patnum; of.numins=mh_s3m->insnum; of.initspeed=mh_s3m->initspeed; of.inittempo=mh_s3m->inittempo; /* count the number of channels used */ of.numchn=0; /* for(t=0;t<32;t++) printf("%2.2x ",mh_s3m->channels[t]); */ for(t=0;t<32;t++) remap[t]=0; for(t=0;t<16;t++) isused[t]=0; /* set a flag for each channel (1 out of of 16) thats being used: */ for(t=0;t<32;t++){ if(mh_s3m->channels[t]<16){ isused[mh_s3m->channels[t]]=1; } } /* give each of them a different number */ for(t=0;t<16;t++){ if(isused[t]){ isused[t]=of.numchn; of.numchn++; } } /* build the remap array */ for(t=0;t<32;t++){ if(mh_s3m->channels[t]<16){ remap[t]=isused[mh_s3m->channels[t]]; } } /* set panning positions */ for(t=0;t<32;t++){ if(mh_s3m->channels[t]<16){ if(mh_s3m->channels[t]<8){ of.panning[remap[t]]=0x30; } else{ of.panning[remap[t]]=0xc0; } } } of.numtrk=of.numpat*of.numchn; /* printf("Uses %d channels\n",of.numchn); */ /* read the order data */ _mm_read_UBYTES(of.positions,mh_s3m->ordnum); of.numpos=0; for(t=0;t<mh_s3m->ordnum;t++){ of.positions[of.numpos]=of.positions[t]; if(of.positions[t]<254) of.numpos++; } if((paraptr=(UWORD *)MyMalloc((of.numins+of.numpat)*sizeof(UWORD)))==NULL) return 0; /* read the instrument+pattern parapointers */ _mm_read_I_UWORDS(paraptr,of.numins+of.numpat); /* printf("pantab %d\n",mh_s3m->pantable); */ if(mh_s3m->pantable==252){ /* read the panning table */ _mm_read_UBYTES(pan,32); /* set panning positions according to panning table (new for st3.2) */ for(t=0;t<32;t++){ if((pan[t]&0x20) && mh_s3m->channels[t]<16){ of.panning[remap[t]]=(pan[t]&0xf)<<4; } } } /* now is a good time to check if the header was too short :) */ if(modpos > modsize){ gModPlayerErrorMessage=ERROR_LOADING_HEADER; return 0; } if(!AllocInstruments()) return 0; d=of.instruments; for(t=0;t<of.numins;t++){ S3MSAMPLE s; d->numsmp=1; if(!AllocSamples(d)) return 0; q=d->samples; /* seek to instrument position */ _mm_fseek(((long)paraptr[t])<<4,SEEK_SET); /* and load sample info */ s.type =_mm_read_UBYTE(); _mm_read_str(s.filename,12); s.memsegh =_mm_read_UBYTE(); s.memsegl =_mm_read_I_UWORD(); s.length =_mm_read_I_ULONG(); s.loopbeg =_mm_read_I_ULONG(); s.loopend =_mm_read_I_ULONG(); s.volume =_mm_read_UBYTE(); s.dsk =_mm_read_UBYTE(); s.pack =_mm_read_UBYTE(); s.flags =_mm_read_UBYTE(); s.c2spd =_mm_read_I_ULONG(); _mm_read_UBYTES(s.unused,12); _mm_read_str(s.sampname,28); _mm_read_str(s.scrs,4); if(modpos > modsize){ gModPlayerErrorMessage=ERROR_LOADING_HEADER; return 0; } d->insname=DupStr(s.sampname,28); q->c2spd= (unsigned short)s.c2spd; q->length=s.length; q->loopstart=s.loopbeg; q->loopend=s.loopend; q->volume=s.volume; q->seekpos=(((long)s.memsegh)<<16|s.memsegl)<<4; q->flags=0; if(s.flags&1) q->flags|=SF_LOOP; if(s.flags&4) q->flags|=SF_16BITS; if(mh_s3m->fileformat==1) q->flags|=SF_SIGNED; /* DON'T load sample if it doesn't have the SCRS tag */ if(memcmp(s.scrs,"SCRS",4)!=0) q->length=0; /* printf("%s\n",d->insname); */ d++; } if(!AllocTracks()) { gModPlayerErrorMessage=ERROR_ALLOC_STRUCT; return 0; } if(!AllocPatterns()) { gModPlayerErrorMessage=ERROR_ALLOC_STRUCT; return 0; } for(t=0;t<of.numpat;t++) { /* seek to pattern position ( + 2 skip pattern length ) */ _mm_fseek((((long)paraptr[of.numins+t])<<4)+2,SEEK_SET); if(!S3M_ReadPattern()) { gModPlayerErrorMessage = ERROR_LOADING_PATTERN; return 0; } for(u=0;u<of.numchn;u++) { if(!(of.tracks[track++]=S3M_ConvertTrack(&s3mbuf[u*64]))) { gModPlayerErrorMessage = ERROR_LOADING_TRACK; return 0; } } } return 1; }
BOOL DSM_Load (BOOL curious) { int t; DSMINST s; SAMPLE *q; int cursmp = 0, curpat = 0, track = 0; blocklp = 0; blockln = 12; if (!GetBlockHeader ()) return 0; if (memcmp (blockid, SONGID, 4)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } _mm_read_UBYTES (mh->songname, 28, modreader); mh->version = _mm_read_I_UWORD (modreader); mh->flags = _mm_read_I_UWORD (modreader); mh->reserved2 = _mm_read_I_ULONG (modreader); mh->numord = _mm_read_I_UWORD (modreader); mh->numsmp = _mm_read_I_UWORD (modreader); mh->numpat = _mm_read_I_UWORD (modreader); mh->numtrk = _mm_read_I_UWORD (modreader); mh->globalvol = _mm_read_UBYTE (modreader); mh->mastervol = _mm_read_UBYTE (modreader); mh->speed = _mm_read_UBYTE (modreader); mh->bpm = _mm_read_UBYTE (modreader); _mm_read_UBYTES (mh->panpos, DSM_MAXCHAN, modreader); _mm_read_UBYTES (mh->orders, DSM_MAXORDERS, modreader); /* set module variables */ of.initspeed = mh->speed; of.inittempo = mh->bpm; of.modtype = strdup (DSM_Version); of.numchn = mh->numtrk; of.numpat = mh->numpat; of.numtrk = of.numchn * of.numpat; of.songname = DupStr (mh->songname, 28, 1); /* make a cstr of songname */ of.reppos = 0; for (t = 0; t < DSM_MAXCHAN; t++) of.panning[t] = mh->panpos[t] == DSM_SURROUND ? PAN_SURROUND : mh->panpos[t] < 0x80 ? (mh->panpos[t] << 1) : 255; if (!AllocPositions (mh->numord)) return 0; of.numpos = 0; for (t = 0; t < mh->numord; t++) { of.positions[of.numpos] = mh->orders[t]; if (mh->orders[t] < 254) of.numpos++; } of.numins = of.numsmp = mh->numsmp; if (!AllocSamples ()) return 0; if (!AllocTracks ()) return 0; if (!AllocPatterns ()) return 0; while (cursmp < of.numins || curpat < of.numpat) { if (!GetBlockHeader ()) return 0; if (!memcmp (blockid, INSTID, 4) && cursmp < of.numins) { q = &of.samples[cursmp]; /* try to read sample info */ _mm_read_UBYTES (s.filename, 13, modreader); s.flags = _mm_read_I_UWORD (modreader); s.volume = _mm_read_UBYTE (modreader); s.length = _mm_read_I_ULONG (modreader); s.loopstart = _mm_read_I_ULONG (modreader); s.loopend = _mm_read_I_ULONG (modreader); s.reserved1 = _mm_read_I_ULONG (modreader); s.c2spd = _mm_read_I_UWORD (modreader); s.period = _mm_read_I_UWORD (modreader); _mm_read_UBYTES (s.samplename, 28, modreader); q->samplename = DupStr (s.samplename, 28, 1); q->seekpos = _mm_ftell (modreader); q->speed = s.c2spd; q->length = s.length; q->loopstart = s.loopstart; q->loopend = s.loopend; q->volume = s.volume; if (s.flags & 1) q->flags |= SF_LOOP; if (s.flags & 2) q->flags |= SF_SIGNED; /* (s.flags&4) means packed sample, but did they really exist in dsm ? */ cursmp++; } else if (!memcmp (blockid, PATTID, 4) && curpat < of.numpat) { DSM_ReadPattern (); for (t = 0; t < of.numchn; t++) if (!(of.tracks[track++] = DSM_ConvertTrack (&dsmbuf[t * 64]))) return 0; curpat++; } } return 1; }
BOOL FAR_Load (BOOL curious) { int t, u, tracks = 0; SAMPLE *q; FARSAMPLE s; FARNOTE *crow; UBYTE smap[8]; /* try to read module header (first part) */ _mm_read_UBYTES (mh1->id, 4, modreader); _mm_read_SBYTES (mh1->songname, 40, modreader); _mm_read_SBYTES (mh1->blah, 3, modreader); mh1->headerlen = _mm_read_I_UWORD (modreader); mh1->version = _mm_read_UBYTE (modreader); _mm_read_UBYTES (mh1->onoff, 16, modreader); _mm_read_UBYTES (mh1->edit1, 9, modreader); mh1->speed = _mm_read_UBYTE (modreader); _mm_read_UBYTES (mh1->panning, 16, modreader); _mm_read_UBYTES (mh1->edit2, 4, modreader); mh1->stlen = _mm_read_I_UWORD (modreader); /* init modfile data */ of.modtype = strdup (FAR_Version); of.songname = DupStr (mh1->songname, 40, 1); of.numchn = 16; of.initspeed = mh1->speed; of.inittempo = 80; of.reppos = 0; for (t = 0; t < 16; t++) of.panning[t] = mh1->panning[t] << 4; /* read songtext into comment field */ if (mh1->stlen) if (!ReadComment (mh1->stlen)) return 0; /* try to read module header (second part) */ _mm_read_UBYTES (mh2->orders, 256, modreader); mh2->numpat = _mm_read_UBYTE (modreader); mh2->snglen = _mm_read_UBYTE (modreader); mh2->loopto = _mm_read_UBYTE (modreader); _mm_read_I_UWORDS (mh2->patsiz, 256, modreader); of.numpos = mh2->snglen; if (!AllocPositions (of.numpos)) return 0; for (t = 0; t < of.numpos; t++) { if (mh2->orders[t] == 0xff) break; of.positions[t] = mh2->orders[t]; } /* count number of patterns stored in file */ of.numpat = 0; for (t = 0; t < 256; t++) if (mh2->patsiz[t]) if ((t + 1) > of.numpat) of.numpat = t + 1; of.numtrk = of.numpat * of.numchn; /* seek across eventual new data */ _mm_fseek (modreader, mh1->headerlen - (869 + mh1->stlen), SEEK_CUR); /* alloc track and pattern structures */ if (!AllocTracks ()) return 0; if (!AllocPatterns ()) return 0; for (t = 0; t < of.numpat; t++) { UBYTE rows = 0; memset (pat, 0, 256 * 16 * 4 * sizeof (FARNOTE)); if (mh2->patsiz[t]) { rows = _mm_read_UBYTE (modreader); /* tempo = */ _mm_read_UBYTE (modreader); crow = pat; /* file often allocates 64 rows even if there are less in pattern */ if (mh2->patsiz[t] < 2 + (rows * 16 * 4)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } for (u = (mh2->patsiz[t] - 2) / 4; u; u--, crow++) { crow->note = _mm_read_UBYTE (modreader); crow->ins = _mm_read_UBYTE (modreader); crow->vol = _mm_read_UBYTE (modreader); crow->eff = _mm_read_UBYTE (modreader); } if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } crow = pat; of.pattrows[t] = rows; for (u = 16; u; u--, crow++) if (!(of.tracks[tracks++] = FAR_ConvertTrack (crow, rows))) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } } else tracks += 16; } /* read sample map */ if (!_mm_read_UBYTES (smap, 8, modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* count number of samples used */ of.numins = 0; for (t = 0; t < 64; t++) if (smap[t >> 3] & (1 << (t & 7))) of.numins = t + 1; of.numsmp = of.numins; /* alloc sample structs */ if (!AllocSamples ()) return 0; q = of.samples; for (t = 0; t < of.numsmp; t++) { q->speed = 8363; q->flags = SF_SIGNED; if (smap[t >> 3] & (1 << (t & 7))) { _mm_read_SBYTES (s.samplename, 32, modreader); s.length = _mm_read_I_ULONG (modreader); s.finetune = _mm_read_UBYTE (modreader); s.volume = _mm_read_UBYTE (modreader); s.reppos = _mm_read_I_ULONG (modreader); s.repend = _mm_read_I_ULONG (modreader); s.type = _mm_read_UBYTE (modreader); s.loop = _mm_read_UBYTE (modreader); q->samplename = DupStr (s.samplename, 32, 1); q->length = s.length; q->loopstart = s.reppos; q->loopend = s.repend; q->volume = s.volume << 2; if (s.type & 1) q->flags |= SF_16BITS; if (s.loop & 8) q->flags |= SF_LOOP; q->seekpos = _mm_ftell (modreader); _mm_fseek (modreader, q->length, SEEK_CUR); } else q->samplename = DupStr (NULL, 0, 0); q++; }
static int MTM_Load(int curious) { int t,u; MTMSAMPLE s; SAMPLE *q; (void)curious; /* try to read module header */ _mm_read_UBYTES(mh->id,3,modreader); mh->version =_mm_read_UBYTE(modreader); _mm_read_string(mh->songname,20,modreader); mh->numtracks =_mm_read_I_UWORD(modreader); mh->lastpattern =_mm_read_UBYTE(modreader); mh->lastorder =_mm_read_UBYTE(modreader); mh->commentsize =_mm_read_I_UWORD(modreader); mh->numsamples =_mm_read_UBYTE(modreader); mh->attribute =_mm_read_UBYTE(modreader); mh->beatspertrack=_mm_read_UBYTE(modreader); mh->numchannels =_mm_read_UBYTE(modreader); _mm_read_UBYTES(mh->panpos,32,modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* set module variables */ of.initspeed = 6; of.inittempo = 125; of.modtype = StrDup(MTM_Version); of.numchn = mh->numchannels; of.numtrk = mh->numtracks+1; /* get number of channels */ of.songname = DupStr(mh->songname,20,1); /* make a cstr of songname */ of.numpos = mh->lastorder+1; /* copy the songlength */ of.numpat = mh->lastpattern+1; of.reppos = 0; of.flags |= UF_PANNING; for(t=0;t<32;t++) of.panning[t]=mh->panpos[t]<< 4; of.numins=of.numsmp=mh->numsamples; if(!AllocSamples()) return 0; q=of.samples; for(t=0;t<of.numins;t++) { /* try to read sample info */ _mm_read_string(s.samplename,22,modreader); s.length =_mm_read_I_ULONG(modreader); s.reppos =_mm_read_I_ULONG(modreader); s.repend =_mm_read_I_ULONG(modreader); s.finetune =_mm_read_UBYTE(modreader); s.volume =_mm_read_UBYTE(modreader); s.attribute =_mm_read_UBYTE(modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } q->samplename = DupStr(s.samplename,22,1); q->seekpos = 0; q->speed = finetune[s.finetune]; q->length = s.length; q->loopstart = s.reppos; q->loopend = s.repend; q->volume = s.volume; if((s.repend-s.reppos)>2) q->flags |= SF_LOOP; if(s.attribute&1) { /* If the sample is 16-bits, convert the length and replen byte-values into sample-values */ q->flags|=SF_16BITS; q->length>>=1; q->loopstart>>=1; q->loopend>>=1; } q++; }
static BOOL ULT_Load(void) { int t,u,tracks=0; INSTRUMENT *d; SAMPLE *q; ULTSAMPLE s; ULTHEADER mh; UBYTE nos,noc,nop; /* try to read module header */ _mm_read_str(mh.id,15); _mm_read_str(mh.songtitle,32); mh.reserved=_mm_read_UBYTE(); if(modpos > modsize){ gModPlayerErrorMessage=ERROR_LOADING_HEADER; return 0; } if(mh.id[14]<'1' || mh.id[14]>'4'){ //printf("This version is not yet supported\n"); return 0; } of.modtype=strdup(ULT_Version[mh.id[14]-'1']); of.initspeed=6; of.inittempo=125; /* read songtext */ if(!ReadComment((UWORD)(mh.reserved * 32))) return 0; nos=_mm_read_UBYTE(); if(modpos > modsize){ gModPlayerErrorMessage=ERROR_LOADING_HEADER; return 0; } of.songname=DupStr(mh.songtitle,32); of.numins=nos; if(!AllocInstruments()) return 0; d=of.instruments; for(t=0;t<nos;t++){ d->numsmp=1; if(!AllocSamples(d)) return 0; q=d->samples; /* try to read sample info */ _mm_read_str(s.samplename,32); _mm_read_str(s.dosname,12); s.loopstart =_mm_read_I_ULONG(); s.loopend =_mm_read_I_ULONG(); s.sizestart =_mm_read_I_ULONG(); s.sizeend =_mm_read_I_ULONG(); s.volume =_mm_read_UBYTE(); s.flags =_mm_read_UBYTE(); s.finetune =_mm_read_I_SWORD(); if(modpos > modsize){ gModPlayerErrorMessage=ERROR_LOADING_SAMPLEINFO; return 0; } d->insname=DupStr(s.samplename,32); q->seekpos=0; q->c2spd=8363; if(mh.id[14]>='4'){ _mm_read_I_UWORD(); /* read 1.6 extra info(??) word */ q->c2spd=s.finetune; } q->length=s.sizeend-s.sizestart; q->volume=s.volume>>2; q->loopstart=s.loopstart; q->loopend=s.loopend; q->flags=SF_SIGNED; if(s.flags&ULTS_LOOP){ q->flags|=SF_LOOP; } if(s.flags&ULTS_16BITS){ q->flags|=SF_16BITS; q->loopstart>>=1; q->loopend>>=1; } /* printf("Sample %d %s length %ld\n",t,d->samplename,d->length); */ d++; }
static BOOL S69_LoadPatterns(void) { int track,row,channel; UBYTE note,inst,vol,effect,lastfx,lastval; S69NOTE *cur; int tracks=0; if(!AllocPatterns()) return 0; if(!AllocTracks()) return 0; for(track=0;track<of.numpat;track++) { /* set pattern break locations */ of.pattrows[track]=mh->breaks[track]+1; /* load the 669 pattern */ cur=s69pat; for(row=0;row<64;row++) { for(channel=0;channel<8;channel++,cur++) { cur->a = _mm_read_UBYTE(modreader); cur->b = _mm_read_UBYTE(modreader); cur->c = _mm_read_UBYTE(modreader); } } if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } /* translate the pattern */ for(channel=0;channel<8;channel++) { UniReset(); /* set pattern tempo */ UniPTEffect(0xf,78); UniPTEffect(0xf,mh->tempos[track]); lastfx=0xff,lastval=0; for(row=0;row<=mh->breaks[track];row++) { int a,b,c; /* fetch the encoded note */ a=s69pat[(row*8)+channel].a; b=s69pat[(row*8)+channel].b; c=s69pat[(row*8)+channel].c; /* decode it */ note=a>>2; inst=((a&0x3)<<4)|((b&0xf0)>>4); vol=b&0xf; if (a<0xff) { if (a<0xfe) { UniInstrument(inst); UniNote(note+2*OCTAVE); lastfx=0xff; /* reset background effect memory */ } UniPTEffect(0xc,vol<<2); } if ((c!=0xff)||(lastfx!=0xff)) { if(c==0xff) c=lastfx,effect=lastval; else effect=c&0xf; switch(c>>4) { case 0: /* porta up */ UniPTEffect(0x1,effect); lastfx=c,lastval=effect; break; case 1: /* porta down */ UniPTEffect(0x2,effect); lastfx=c,lastval=effect; break; case 2: /* porta to note */ UniPTEffect(0x3,effect); lastfx=c,lastval=effect; break; case 3: /* frequency adjust */ /* DMP converts this effect to S3M FF1. Why not ? */ UniEffect(UNI_S3MEFFECTF,0xf0|effect); break; case 4: /* vibrato */ UniPTEffect(0x4,effect); lastfx=c,lastval=effect; break; case 5: /* set speed */ if (effect) UniPTEffect(0xf,effect); else if(mh->marker[0]!=0x69) { #ifdef MIKMOD_DEBUG fprintf(stderr,"\r669: unsupported super fast tempo at pat=%d row=%d chan=%d\n", track,row,channel); #endif } break; } } UniNewline(); } if(!(of.tracks[tracks++]=UniDup())) return 0; } } return 1; }
BOOL S69_Load(BOOL curious) { int i; SAMPLE *current; S69SAMPLE sample; /* module header */ _mm_read_UBYTES(mh->marker,2,modreader); _mm_read_UBYTES(mh->message,108,modreader); mh->nos=_mm_read_UBYTE(modreader); mh->nop=_mm_read_UBYTE(modreader); mh->looporder=_mm_read_UBYTE(modreader); _mm_read_UBYTES(mh->orders,0x80,modreader); for(i=0;i<0x80;i++) if ((mh->orders[i]>=0x80)&&(mh->orders[i]!=0xff)) { _mm_errno=MMERR_NOT_A_MODULE; return 1; } _mm_read_UBYTES(mh->tempos,0x80,modreader); for(i=0;i<0x80;i++) if ((!mh->tempos[i])||(mh->tempos[i]>32)) { _mm_errno=MMERR_NOT_A_MODULE; return 1; } _mm_read_UBYTES(mh->breaks,0x80,modreader); for(i=0;i<0x80;i++) if (mh->breaks[i]>0x3f) { _mm_errno=MMERR_NOT_A_MODULE; return 1; } /* set module variables */ of.initspeed=4; of.inittempo=78; of.songname=DupStr(mh->message,36,1); 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; for(i= 35;(i>= 0)&&(mh->message[i]==' ');i--) mh->message[i]=0; for(i=36+35;(i>=36+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; for(i=72+35;(i>=72+0)&&(mh->message[i]==' ');i--) mh->message[i]=0; if((mh->message[0])||(mh->message[36])||(mh->message[72])) if((of.comment=(CHAR*)MikMod_malloc(3*(36+1)+1))) { strncpy(of.comment,mh->message,36); strcat(of.comment,"\r"); if (mh->message[36]) strncat(of.comment,mh->message+36,36); strcat(of.comment,"\r"); if (mh->message[72]) strncat(of.comment,mh->message+72,36); strcat(of.comment,"\r"); of.comment[3*(36+1)]=0; } if(!AllocPositions(0x80)) return 0; for(i=0;i<0x80;i++) { if(mh->orders[i]>=mh->nop) break; of.positions[i]=mh->orders[i]; } of.numpos=i; of.reppos=mh->looporder<of.numpos?mh->looporder:0; if(!AllocSamples()) return 0; current=of.samples; for(i=0;i<of.numins;i++) { /* sample information */ _mm_read_UBYTES((UBYTE*)sample.filename,13,modreader); sample.length=_mm_read_I_SLONG(modreader); sample.loopbeg=_mm_read_I_SLONG(modreader); sample.loopend=_mm_read_I_SLONG(modreader); if (sample.loopend==0xfffff) sample.loopend=0; if((sample.length<0)||(sample.loopbeg<-1)||(sample.loopend<-1)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } current->samplename=DupStr(sample.filename,13,1); current->seekpos=0; current->speed=0; current->length=sample.length; current->loopstart=sample.loopbeg; current->loopend=sample.loopend; current->flags=(sample.loopbeg<sample.loopend)?SF_LOOP:0; current->volume=64; current++; } if(!S69_LoadPatterns()) return 0; return 1; }