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) {
/* handles S3M and IT effects */ void S3MIT_ProcessCmd(UBYTE cmd,UBYTE inf,BOOL oldeffect) { UBYTE hi,lo; lo=inf&0xf; hi=inf>>4; /* process S3M / IT specific command structure */ if(cmd!=255) { switch(cmd) { case 1: /* Axx set speed to xx */ UniEffect(UNI_S3MEFFECTA,inf); break; case 2: /* Bxx position jump */ if (inf<poslookupcnt) { /* switch to curious mode if necessary, for example sympex.it, deep joy.it */ if(((SBYTE)poslookup[inf]<0)&&(origpositions[inf]!=255)) S3MIT_CreateOrders(1); if(!((SBYTE)poslookup[inf]<0)) UniPTEffect(0xb,poslookup[inf]); } break; case 3: /* Cxx patternbreak to row xx */ if(oldeffect==1) UniPTEffect(0xd,(inf>>4)*10+(inf&0xf)); else UniPTEffect(0xd,inf); break; case 4: /* Dxy volumeslide */ UniEffect(UNI_S3MEFFECTD,inf); break; case 5: /* Exy toneslide down */ UniEffect(UNI_S3MEFFECTE,inf); break; case 6: /* Fxy toneslide up */ UniEffect(UNI_S3MEFFECTF,inf); break; case 7: /* Gxx Tone portamento, speed xx */ UniEffect(UNI_ITEFFECTG,inf); break; case 8: /* Hxy vibrato */ if(oldeffect&1) UniPTEffect(0x4,inf); else UniEffect(UNI_ITEFFECTH,inf); break; case 9: /* Ixy tremor, ontime x, offtime y */ if(oldeffect&1) UniEffect(UNI_S3MEFFECTI,inf); else UniEffect(UNI_ITEFFECTI,inf); break; case 0xa: /* Jxy arpeggio */ UniPTEffect(0x0,inf); break; case 0xb: /* Kxy Dual command H00 & Dxy */ if(oldeffect&1) UniPTEffect(0x4,0); else UniEffect(UNI_ITEFFECTH,0); UniEffect(UNI_S3MEFFECTD,inf); break; case 0xc: /* Lxy Dual command G00 & Dxy */ if(oldeffect&1) UniPTEffect(0x3,0); else UniEffect(UNI_ITEFFECTG,0); UniEffect(UNI_S3MEFFECTD,inf); break; case 0xd: /* Mxx Set Channel Volume */ UniEffect(UNI_ITEFFECTM,inf); break; case 0xe: /* Nxy Slide Channel Volume */ UniEffect(UNI_ITEFFECTN,inf); break; case 0xf: /* Oxx set sampleoffset xx00h */ UniPTEffect(0x9,inf); break; case 0x10: /* Pxy Slide Panning Commands */ UniEffect(UNI_ITEFFECTP,inf); break; case 0x11: /* Qxy Retrig (+volumeslide) */ UniWriteByte(UNI_S3MEFFECTQ); if(inf && !lo && !(oldeffect&1)) UniWriteByte(1); else UniWriteByte(inf); break; case 0x12: /* Rxy tremolo speed x, depth y */ UniEffect(UNI_S3MEFFECTR,inf); break; case 0x13: /* Sxx special commands */ if (inf>=0xf0) { /* change resonant filter settings if necessary */ if((filters)&&((inf&0xf)!=activemacro)) { activemacro=inf&0xf; for(inf=0;inf<0x80;inf++) filtersettings[inf].filter=filtermacros[activemacro]; } } else UniEffect(UNI_ITEFFECTS0,inf); break; case 0x14: /* Txx tempo */ if(inf>=0x20) UniEffect(UNI_S3MEFFECTT,inf); else { if(!(oldeffect&1)) /* IT Tempo slide */ UniEffect(UNI_ITEFFECTT,inf); } break; case 0x15: /* Uxy Fine Vibrato speed x, depth y */ if(oldeffect&1) UniEffect(UNI_S3MEFFECTU,inf); else UniEffect(UNI_ITEFFECTU,inf); break; case 0x16: /* Vxx Set Global Volume */ UniEffect(UNI_XMEFFECTG,inf); break; case 0x17: /* Wxy Global Volume Slide */ UniEffect(UNI_ITEFFECTW,inf); break; case 0x18: /* Xxx amiga command 8xx */ if(oldeffect&1) { if(inf>128) UniEffect(UNI_ITEFFECTS0,0x91); /* surround */ else UniPTEffect(0x8,(inf==128)?255:(inf<<1)); } else UniPTEffect(0x8,inf); break; case 0x19: /* Yxy Panbrello speed x, depth y */ UniEffect(UNI_ITEFFECTY,inf); break; case 0x1a: /* Zxx midi/resonant filters */ if(filtersettings[inf].filter) { UniWriteByte(UNI_ITEFFECTZ); UniWriteByte(filtersettings[inf].filter); UniWriteByte(filtersettings[inf].inf); } break; } }
/* handles S3M and IT effects */ void S3MIT_ProcessCmd(u8 cmd, u8 inf, /*unsigned int*/u8 flags)//MM_BOOL oldeffect) { u8 hi, lo; lo = inf&0x0f; hi = inf>>4; /* process S3M / IT specific command structure */ if (cmd!=255) { switch (cmd) { case 1: /* Axx set speed to xx */ UniEffect(U231_ICODE_0x30_S3MEFFECTA,inf); break; case 2: /* Bxx position jump */ if (inf<mmff.mm_midi_position_look_up_counter) { /* switch to curious mode if necessary, for example sympex.it, deep joy.it */ if (((s8)mm_position_look_up[inf]<0)&&(origpositions[inf]!=255)) { S3MIT_CreateOrders(1);} if (!((s8)mm_position_look_up[inf]<0)) { UniPTEffect(0xb,mm_position_look_up[inf]);} } break; case 3: /* Cxx patternbreak to row xx */ // if (oldeffect==1) // if ((flags & S3MIT_OLDSTYLE) && !(flags & S3MIT_IT)) if ( (S3MIT_OLDSTYLE) == (flags & (S3MIT_IT|S3MIT_OLDSTYLE)) ) { UniPTEffect(0xd,(inf>>4)*10+(inf&0xf));} else { UniPTEffect(0xd,inf);} break; case 4: /* Dxy volumeslide */ UniEffect(U231_ICODE_0x31_S3MEFFECTD,inf); break; case 5: /* Exy toneslide down */ UniEffect(U231_ICODE_0x32_S3MEFFECTE,inf); break; case 6: /* Fxy toneslide up */ UniEffect(U231_ICODE_0x33_S3MEFFECTF,inf); break; case 7: /* Gxx Tone portamento, speed xx */ if (flags & S3MIT_OLDSTYLE) { UniPTEffect(0x3,inf);} else { UniEffect(U231_ICODE_0x04_ITEFFECTG,inf);} break; case 8: /* Hxy vibrato */ if (flags & S3MIT_OLDSTYLE) { UniPTEffect(0x04,inf);} else { UniEffect(U231_ICODE_0x05_ITEFFECTH,inf);} break; case 9: /* Ixy tremor, ontime x, offtime y */ if (flags & S3MIT_OLDSTYLE) { UniEffect(U231_ICODE_0x34_S3MEFFECTI,inf);} else { UniEffect(U231_ICODE_0x06_ITEFFECTI,inf);} break; case 0xa: /* Jxy arpeggio */ UniPTEffect(0x00,inf); break; case 0xb: /* Kxy Dual command H00 & Dxy */ if (flags & S3MIT_OLDSTYLE) { UniPTEffect(0x04,0);} else { UniEffect(U231_ICODE_0x05_ITEFFECTH,0);} UniEffect(U231_ICODE_0x31_S3MEFFECTD,inf); break; case 0xc: /* Lxy Dual command G00 & Dxy */ if (flags & S3MIT_OLDSTYLE) { UniPTEffect(0x03,0);} else { UniEffect(U231_ICODE_0x04_ITEFFECTG,0);} UniEffect(U231_ICODE_0x31_S3MEFFECTD,inf); break; case 0xd: /* Mxx Set Channel Volume */ UniEffect(U231_ICODE_0x07_ITEFFECTM,inf); break; case 0xe: /* Nxy Slide Channel Volume */ UniEffect(U231_ICODE_0x08_ITEFFECTN,inf); break; case 0xf: /* Oxx set sampleoffset xx00h */ UniPTEffect(0x09,inf); break; case 0x10: /* Pxy Slide Panning Commands */ UniEffect(U231_ICODE_0x09_ITEFFECTP,inf); break; case 0x11: /* Qxy Retrig (+volumeslide) */ UniWriteByte(U231_ICODE_0x35_S3MEFFECTQ); if (inf && !lo && !(flags & S3MIT_OLDSTYLE)) UniWriteByte(1); else UniWriteByte(inf); break; case 0x12: /* Rxy tremolo speed x, depth y */ UniEffect(U231_ICODE_0x36_S3MEFFECTR,inf); break; case 0x13: /* Sxx special commands */ if (inf >= 0xf0)/* 0xf0 ... 0xff はmidi fliter 切り替えコマンド */ { #if (1==USE_ITZ_ZXX_MIDI_RESONANT_FILTERS) /* do if filter enables only. */ if (mmff.mm_midi_use_resonant_filters)/* filter 有効の場合のみ */ { /* change resonant filter settings if necessary */ if (((inf&0x0f) != mmff.mm_midi_active_macro))/* filter が実際に切り替わった場合のみ */ { mmff.mm_midi_active_macro = (inf & 0x0f);/* 現在有効の midi fliter番号を保存。 */ /* midi fliter 切り替え処理 */ for (inf=0; inf<0x80; inf++) { filtersettings[inf].filter = mm_filter_macros[mmff.mm_midi_active_macro]; } } } #endif /*(USE_ITZ_ZXX_MIDI_RESONANT_FILTERS)*/ } else { /* Scream Tracker does not have samples larger than 64 Kb, thus doesn't need the SAx effect */ // if ((flags & S3MIT_SCREAM) && ((inf & 0xf0) == 0xa0)) // break; UniEffect(U231_ICODE_0x0f_ITEFFECTS0,inf); } break; case 0x14: /* Txx tempo */ if (inf>=0x20) UniEffect(U231_ICODE_0x37_S3MEFFECTT,inf); else { if (!(flags & S3MIT_OLDSTYLE)) /* IT Tempo slide */ { UniEffect(U231_ICODE_0x0a_ITEFFECTT,inf);} } break; case 0x15: /* Uxy Fine Vibrato speed x, depth y */ if (flags & S3MIT_OLDSTYLE) { UniEffect(U231_ICODE_0x38_S3MEFFECTU,inf);} else { UniEffect(U231_ICODE_0x0b_ITEFFECTU,inf);} break; case 0x16: /* Vxx Set Global Volume */ UniEffect(U231_ICODE_0x28_XMEFFECTG,inf); break; case 0x17: /* Wxy Global Volume Slide */ UniEffect(U231_ICODE_0x0c_ITEFFECTW,inf); break; case 0x18: /* Xxx amiga command 8xx */ if (flags & S3MIT_OLDSTYLE) { if (inf>128) { UniEffect(U231_ICODE_0x0f_ITEFFECTS0,0x91); }/* surround */ else { UniPTEffect(0x8,(inf==128)?255:(inf<<1));} } else { UniPTEffect(0x8,inf);} break; case 0x19: /* Yxy Panbrello speed x, depth y */ UniEffect(U231_ICODE_0x0d_ITEFFECTY,inf); break; case 0x1a: /* Zxx midi/resonant filters */ #if (1==USE_ITZ_ZXX_MIDI_RESONANT_FILTERS) if (filtersettings[inf].filter) { UniWriteByte(U231_ICODE_0x0e_ITEFFECTZ); UniWriteByte(filtersettings[inf].filter); UniWriteByte(filtersettings[inf].inf); } #endif /*(USE_ITZ_ZXX_MIDI_RESONANT_FILTERS)*/ break; }
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; } /* set module variables */ of.songname = DupStr(mh->songname,28,0); of.numpat = mh->patnum; of.reppos = 0; of.numins = of.numsmp = mh->insnum; of.initspeed = mh->initspeed; of.inittempo = mh->inittempo; of.initvolume = mh->mastervol<<1; of.flags |= UF_ARPMEM; if((mh->tracker==0x1300)||(mh->flags&64)) of.flags|=UF_S3MSLIDES; /* 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/*mh->patnum-1*/; } if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } poslookupcnt=(UBYTE)mh->ordnum; S3MIT_CreateOrders(curious); if(!(paraptr=(UWORD*)_mm_malloc((of.numins+of.numpat)*sizeof(UWORD)))) return 0; /* read the instrument+pattern parapointers */ _mm_read_I_UWORDS(paraptr,of.numins+of.numpat,modreader); if(mh->pantable==252) { /* read the panning table (ST 3.2 addition. See below for further portions of channel panning [past reampper]). */ _mm_read_UBYTES(pan,32,modreader); } if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_HEADER; return 0; } /* load samples */ if(!AllocSamples()) return 0; q = of.samples; for(t=0;t<of.numins;t++) { S3MSAMPLE s; /* seek to instrument position */ _mm_fseek(modreader,((long)paraptr[t])<<4,SEEK_SET); /* and load sample info */ s.type =_mm_read_UBYTE(modreader); _mm_read_string(s.filename,12,modreader); s.memsegh =_mm_read_UBYTE(modreader); s.memsegl =_mm_read_I_UWORD(modreader); s.length =_mm_read_I_ULONG(modreader); s.loopbeg =_mm_read_I_ULONG(modreader); s.loopend =_mm_read_I_ULONG(modreader); s.volume =_mm_read_UBYTE(modreader); s.dsk =_mm_read_UBYTE(modreader); s.pack =_mm_read_UBYTE(modreader); s.flags =_mm_read_UBYTE(modreader); s.c2spd =_mm_read_I_ULONG(modreader); _mm_read_UBYTES(s.unused,12,modreader); _mm_read_string(s.sampname,28,modreader); _mm_read_string(s.scrs,4,modreader); if(_mm_eof(modreader)) { _mm_errno = MMERR_LOADING_SAMPLEINFO; return 0; } q->samplename = DupStr(s.sampname,28,0); q->speed = s.c2spd; q->length = s.length; q->loopstart = s.loopbeg>s.length?s.length:s.loopbeg; q->loopend = s.loopend>s.length?s.length:s.loopend; q->volume = s.volume; q->seekpos = (((long)s.memsegh)<<16|s.memsegl)<<4; if(s.flags&1) q->flags |= SF_LOOP; if(s.flags&4) q->flags |= SF_16BITS; if(mh->fileformat==1) q->flags |= SF_SIGNED; /* don't load sample if it doesn't have the SCRS tag */ if(memcmp(s.scrs,"SCRS",4)) q->length = 0; q++; } /* determine the number of channels actually used. */ of.numchn = 0; memset(remap,-1,32*sizeof(UBYTE)); for(t=0;t<of.numpat;t++) { /* seek to pattern position (+2 skip pattern length) */ _mm_fseek(modreader,(long)((paraptr[of.numins+t])<<4)+2,SEEK_SET); if(S3M_GetNumChannels()) return 0; } /* then we can decide the module type */ t=mh->tracker>>12; if((!t)||(t>3)) t=NUMTRACKERS-1; /* unknown tracker */ else { if(mh->tracker>=0x3217) t=NUMTRACKERS+1; /* IT 2.14p4 */ else if(mh->tracker>=0x3216) t=NUMTRACKERS; /* IT 2.14p3 */ else t--; } of.modtype = strdup(S3M_Version[t]); if(t<NUMTRACKERS) { of.modtype[numeric[t]] = ((mh->tracker>>8) &0xf)+'0'; of.modtype[numeric[t]+2] = ((mh->tracker>>4)&0xf)+'0'; of.modtype[numeric[t]+3] = ((mh->tracker)&0xf)+'0'; }