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; }
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 void pat_read_waveheader(MMSTREAM *mmpat, WaveHeader *hw, int layer) { long int pos, bestpos=0; LayerHeader hl; ULONG bestfreq, freqdist; int i; // read the very first and maybe only sample pat_read_layerheader(mmpat, &hl); if( hl.samples > 1 ) { if( layer ) { if( layer > hl.samples ) layer = hl.samples; // you don't fool me.... for( i=1; i<layer; i++ ) { _mm_read_UBYTES((BYTE *)hw, sizeof(WaveHeader), mmpat); _mm_fseek(mmpat, hw->wave_size, SEEK_CUR); } } else { bestfreq = C4mHz * 1000; // big enough for( i=0; i<hl.samples; i++ ) { pos = _mm_ftell(mmpat); _mm_read_UBYTES((BYTE *)hw, sizeof(WaveHeader), mmpat); if( hw->root_frequency > C4mHz ) freqdist = hw->root_frequency - C4mHz; else freqdist = 2 * (C4mHz - hw->root_frequency); if( freqdist < bestfreq ) { bestfreq = freqdist; bestpos = pos; } _mm_fseek(mmpat, hw->wave_size, SEEK_CUR); } // if invalid bestpos, assume the start. if( bestpos < 0 ) bestpos = 0; _mm_fseek(mmpat, bestpos, SEEK_SET); } } _mm_read_UBYTES((BYTE *)hw, sizeof(WaveHeader), mmpat); strncpy(hw->reserved, hl.reserved, 32); hw->reserved[31] = 0; if( hw->start_loop >= hw->wave_size ) { hw->start_loop = 0; hw->end_loop = 0; hw->modes &= ~PAT_LOOP; // mask off loop indicator } if( hw->end_loop > hw->wave_size ) hw->end_loop = hw->wave_size; }
static BOOL GetBlockHeader (void) { /* make sure we're at the right position for reading the next riff block, no matter how many bytes read */ _mm_fseek (modreader, blocklp + blockln, SEEK_SET); while (1) { _mm_read_UBYTES (blockid, 4, modreader); blockln = _mm_read_I_ULONG (modreader); if (_mm_eof (modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } if (memcmp (blockid, SONGID, 4) && memcmp (blockid, INSTID, 4) && memcmp (blockid, PATTID, 4)) { #ifdef MIKMOD_DEBUG fprintf (stderr, "\rDSM: Skipping unknown block type %4.4s\n", blockid); #endif _mm_fseek (modreader, blockln, SEEK_CUR); } else break; } blocklp = _mm_ftell (modreader); return 1; }
static int MTM_Test(void) { UBYTE id[3]; if(!_mm_read_UBYTES(id,3,modreader)) return 0; if(!memcmp(id,"MTM",3)) return 1; return 0; }
BOOL IT_Test(void) { UBYTE id[4]; if(!_mm_read_UBYTES(id,4,modreader)) return 0; if(!memcmp(id,"IMPM",4)) return 1; return 0; }
BOOL FAR_Test(void) { UBYTE id[47]; if(!_mm_read_UBYTES(id,47,modreader)) return 0; if((memcmp(id,FARSIG,4))||(memcmp(id+44,FARSIG+4,3))) return 0; return 1; }
static BOOL STX_Test(void) { UBYTE id[8]; int t; _mm_fseek(modreader,0x3C,SEEK_SET); if(!_mm_read_UBYTES(id,4,modreader)) return 0; if(memcmp(id,"SCRM",4)) return 0; _mm_fseek(modreader,0x14,SEEK_SET); if(!_mm_read_UBYTES(id,8,modreader)) return 0; for(t=0;t<STM_NTRACKERS;t++) if(!memcmp(id,STM_Signatures[t],8)) return 1; return 0; }
BOOL DSM_Test(void) { UBYTE id[12]; if(_mm_read_UBYTES((UBYTE *)id,12,modfp)) return 0; if(!memcmp(id,"RIFF",4) && !memcmp(&id[8],"DSMF",4)) return 1; return 0; }
BOOL DSM_Test(void) { UBYTE id[12]; if(!_mm_read_UBYTES(id,12,modreader)) return 0; if(!memcmp(id,DSMSIG,4) && !memcmp(id+8,DSMSIG+4,4)) return 1; return 0; }
static CHAR *STX_LoadTitle(void) { CHAR s[28]; _mm_fseek(modreader,0,SEEK_SET); if(!_mm_read_UBYTES(s,20,modreader)) return NULL; return(DupStr(s,28,1)); }
CHAR *S69_LoadTitle(void) { CHAR s[36]; _mm_fseek(modreader,2,SEEK_SET); if(!_mm_read_UBYTES(s,36,modreader)) return NULL; return(DupStr(s,36,1)); }
CHAR *DSM_LoadTitle(void) { CHAR s[28]; _mm_fseek(modreader,12,SEEK_SET); if(!_mm_read_UBYTES(s,28,modreader)) return NULL; return(DupStr(s,28,1)); }
static BOOL IMF_Test(void) { UBYTE id[4]; _mm_fseek(modreader,0x3c,SEEK_SET); if(!_mm_read_UBYTES(id,4,modreader)) return 0; if(!memcmp(id,"IM10",4)) return 1; return 0; }
BOOL S3M_Test(void) { UBYTE id[4]; _mm_fseek(modreader,0x2c,SEEK_SET); if(!_mm_read_UBYTES(id,4,modreader)) return 0; if(!memcmp(id,"SCRM",4)) return 1; return 0; }
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 GT2_Test(void) { UBYTE magic[3]; _mm_fseek(modreader, 0, SEEK_SET); if (!_mm_read_UBYTES(magic, 3, modreader)) return 0; if (magic[0] == 'G' && magic[1] == 'T' && magic[2] == '2') { return 1; } return 0; }
static CHAR *GT2_LoadTitle(void) { CHAR title[33]; _mm_fseek(modreader, 8, SEEK_SET); if (!_mm_read_UBYTES(title, 32, modreader)) return NULL; title[32] = 0; return (DupStr(title, 32, 1)); }
BOOL OKT_Test(void) { CHAR id[8]; if (!_mm_read_UBYTES(id, 8, modreader)) return 0; if (!memcmp(id, "OKTASONG", 8)) return 1; return 0; }
static char* readstring(void) { char *s=NULL; UWORD len; len=_mm_read_I_UWORD(modreader); if(len) { s=_mm_malloc(len+1); _mm_read_UBYTES(s,len,modreader); s[len]=0; } return s; }
static char * readstring(void) { char *str=NULL; UWORD len; len=_mm_read_I_UWORD(modreader); if(len) { str=(char *) MikMod_malloc(len+1); _mm_read_UBYTES(str,len,modreader); str[len]=0; } return str; }
static void LoadMidiString(MREADER* modreader,CHAR* dest) { CHAR *cur,*last; _mm_read_UBYTES(dest,32,modreader); cur=last=dest; /* remove blanks and uppercase all */ while(*last) { if(isalnum((int)*last)) *(cur++)=toupper((int)*last); last++; } *cur=0; }
/* 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 ASY_Test(void) { UBYTE namestring[24], numchn; CHAR *descr; /* Read the magic string */ _mm_fseek(modreader, 0, SEEK_SET); if (!_mm_read_UBYTES(namestring, 24, modreader)) return 0; /* Test if the string is what we expect */ if (ASY_CheckType(namestring, &numchn, &descr)) return 1; return 0; }
static BOOL UNI_Test(void) { char id[6]; if(!_mm_read_UBYTES(id,6,modreader)) return 0; /* UNIMod created by MikCvt */ if(!(memcmp(id,"UN0",3))) { if((id[3]>='4')&&(id[3]<='6')) return 1; } /* UNIMod created by APlayer */ if(!(memcmp(id,"APUN\01",5))) { if((id[5]>=1)&&(id[5]<=6)) return 1; } return 0; }
BOOL ReadLinedComment(UWORD len,UWORD linelen) { CHAR *tempcomment,*line,*storage; UWORD total=0,t,lines; int i; lines = (len + linelen - 1) / linelen; if (len) { if(!(tempcomment=(CHAR*)_mm_malloc(len+1))) return 0; if(!(storage=(CHAR*)_mm_malloc(linelen+1))) { free(tempcomment); return 0; } memset(tempcomment, ' ', len); _mm_read_UBYTES(tempcomment,len,modreader); /* compute message length */ for(line=tempcomment,total=t=0;t<lines;t++,line+=linelen) { for(i=linelen;(i>=0)&&(line[i]==' ');i--) line[i]=0; for(i=0;i<linelen;i++) if (!line[i]) break; total+=1+i; } if(total>lines) { if(!(of.comment=(CHAR*)_mm_malloc(total+1))) { free(storage); free(tempcomment); return 0; } /* convert message */ for(line=tempcomment,t=0;t<lines;t++,line+=linelen) { for(i=0;i<linelen;i++) if(!(storage[i]=line[i])) break; storage[i]=0; /* if (i==linelen) */ strcat(of.comment,storage);strcat(of.comment,"\r"); } free(storage); free(tempcomment); } } return 1; }
BOOL ReadComment(UWORD len) { if(len) { int i; if(!(of.comment=(CHAR*)_mm_malloc(len+1))) return 0; _mm_read_UBYTES(of.comment,len,modreader); /* translate IT linefeeds */ for(i=0;i<len;i++) if(of.comment[i]=='\r') of.comment[i]='\n'; of.comment[len]=0; /* just in case */ } if(!of.comment[0]) { free(of.comment); of.comment=NULL; } return 1; }
static BOOL OKT_doPBOD(int patnum) { char *patbuf; int rows, i; int u; if (!patnum) { of.numtrk = of.numpat * of.numchn; if (!AllocTracks() || !AllocPatterns()) return 0; } /* Read pattern */ of.pattrows[patnum] = rows = _mm_read_M_UWORD(modreader); if (!(okttrk = (OKTNOTE *) _mm_calloc(rows, sizeof(OKTNOTE))) || !(patbuf = (char *)_mm_calloc(rows * of.numchn, sizeof(OKTNOTE)))) return 0; _mm_read_UBYTES(patbuf, rows * of.numchn * sizeof(OKTNOTE), modreader); if (_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_PATTERN; return 0; } for (i = 0; i < of.numchn; i++) { for (u = 0; u < rows; u++) { okttrk[u].note = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE)]; okttrk[u].ins = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 1]; okttrk[u].eff = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 2]; okttrk[u].dat = patbuf[(u * of.numchn + i) * sizeof(OKTNOTE) + 3]; } if (!(of.tracks[patnum * of.numchn + i] = OKT_ConvertTrack(rows))) return 0; } _mm_free(patbuf); _mm_free(okttrk); return 1; }
BOOL GetBlockHeader(void) { /* make sure we're at the right position for reading the */ /* next riff block, no matter how many bytes read */ _mm_fseek(modfp, blocklp+blockln, SEEK_SET); while(1) { _mm_read_UBYTES(blockid,4,modfp); blockln = _mm_read_I_ULONG(modfp); if(_mm_feof(modfp)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } if(memcmp(blockid,SONGID,4) && memcmp(blockid,INSTID,4) && memcmp(blockid,PATTID,4)) { /*printf("Skipping unknown block type %4.4s\n",&blockid); */ _mm_fseek(modfp, blockln, SEEK_CUR); } else break; } blocklp = _mm_ftell(modfp); return 1; }
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++; }