static BOOL STM_Test(void) { char str[9],filetype; _mm_fseek(21,SEEK_SET); _mm_read_str(str,9); _mm_read_str(&filetype,1); if(!memcmp(str,"!SCREAM!",8) || (filetype!=2)) /* STM Module = filetype 2 */ return 0; return 1; }
static BOOL MTM_Test(void) { char id[3]; if(!_mm_read_str(id,3)) return 0; if(!memcmp(id,"MTM",3)) return 1; return 0; }
static BOOL ULT_Test(void) { char id[15]; if(!_mm_read_str((char *)&id,15)) return 0; return(!strncmp(id,"MAS_UTrack_V00",14)); }
static BOOL XM_Test(void) { char id[17]; if(!_mm_read_str(id,17)) return 0; if(!memcmp(id,"Extended Module: ",17)) return 1; return 0; }
static BOOL S3M_Test(void) { char id[4]; _mm_fseek(0x2c,SEEK_SET); if(!_mm_read_str(id,4)) return 0; if(!memcmp(id,"SCRM",4)) return 1; return 0; }
static BOOL MOD_Test(void) { int t; char id[4]; _mm_fseek(MODULEHEADERSIZE-4,SEEK_SET); if(!_mm_read_str(id,4)) return 0; /* find out which ID string */ for(t=0;t<10;t++){ if(!memcmp(id,modtypes[t].id,4)) return 1; } 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; }
void SL_Load(void *buffer, ULONG length) { SBYTE *bptr=(SBYTE *)buffer; SWORD *wptr=(SWORD *)buffer; UWORD stodo; int t; /* compute number of samples to load */ // if (sl_outfmt & SF_16BITS) length>>=1; #ifdef DEBUG if (IsError(sl_buffer == NULL)) ; #endif while (length) { stodo= (length<1024) ? (UWORD)length : 1024; if (sl_infmt&SF_16BITS) { if ( !(sl_infmt&SF_BIG_ENDIAN) ) { SWORD *sp = (SWORD *) sl_buffer; for ( t=0; t < stodo; t++ ) { *sp++ = _mm_read_I_SWORD(); } } else _mm_read_str((char *) sl_buffer,sizeof(SWORD)*stodo); } else { SBYTE *s; SWORD *d; _mm_read_str((char *)sl_buffer,sizeof(SBYTE)*stodo); s=(SBYTE *)sl_buffer; d=sl_buffer; s+=stodo; d+=stodo; for (t=0;t<stodo;t++) { s--; d--; *d=(*s)<<8; } } if (sl_infmt & SF_DELTA) { for (t=0;t<stodo;t++) { sl_buffer[t]+=sl_old; sl_old=sl_buffer[t]; } } if ((sl_infmt^sl_outfmt) & SF_SIGNED) { for (t=0;t<stodo;t++) { sl_buffer[t]^=0x8000; } } if (sl_outfmt & SF_16BITS) { for (t=0;t<stodo;t++) *(wptr++)=sl_buffer[t]; } else { for (t=0;t<stodo;t++) *(bptr++)=sl_buffer[t]>>8; } length-=stodo; } }
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(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 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; }
static BOOL MOD_Load(void) { int t,modtype; INSTRUMENT *d; /* new sampleinfo structure */ SAMPLE *q; MSAMPINFO *s; /* old module sampleinfo */ /* try to read module header */ _mm_read_str((char *)mh_mod->songname,20); for(t=0;t<31;t++){ s=&mh_mod->samples[t]; _mm_read_str(s->samplename,22); s->length =_mm_read_M_UWORD(); s->finetune =_mm_read_UBYTE(); s->volume =_mm_read_UBYTE(); s->reppos =_mm_read_M_UWORD(); s->replen =_mm_read_M_UWORD(); } mh_mod->songlength =_mm_read_UBYTE(); mh_mod->magic1 =_mm_read_UBYTE(); _mm_read_UBYTES(mh_mod->positions,128); _mm_read_UBYTES(mh_mod->magic2,4); if(modpos > modsize){ gModPlayerErrorMessage=ERROR_LOADING_HEADER; return 0; } /* find out which ID string */ for(modtype=0;modtype<10;modtype++){ if(!memcmp(mh_mod->magic2,modtypes[modtype].id,4)) break; } if(modtype==10){ /* unknown modtype */ gModPlayerErrorMessage=ERROR_NOT_A_MODULE; return 0; } /* set module variables */ of.initspeed=6; of.inittempo=125; of.numchn=modtypes[modtype].channels; /* get number of channels */ of.modtype=strdup(modtypes[modtype].name); /* get ascii type of mod */ of.songname=DupStr(mh_mod->songname,20); /* make a cstr of songname */ of.numpos=mh_mod->songlength; /* copy the songlength */ memcpy(of.positions,mh_mod->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=31; if(!AllocInstruments()) return 0; s=mh_mod->samples; /* init source pointer */ d=of.instruments; /* init dest pointer */ for(t=0;t<of.numins;t++){ d->numsmp=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=(ULONG)s->reppos<<1; q->loopend=q->loopstart+((ULONG)s->replen<<1); q->length=(ULONG)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(!ML_LoadPatterns()) return 0; return 1; }