static UBYTE* MTM_Convert(void) { int t; UBYTE a,b,inst,note,eff,dat; UniReset(); for(t=0;t<64;t++) { a=mtmtrk[t].a; b=mtmtrk[t].b; inst=((a&0x3)<<4)|(b>>4); note=a>>2; eff=b&0xf; dat=mtmtrk[t].c; if(inst) UniInstrument(inst-1); if(note) UniNote(note+2*OCTAVE); /* MTM bug workaround : when the effect is volslide, slide-up *always* overrides slide-down. */ if(eff==0xa && (dat&0xf0)) dat&=0xf0; /* Convert pattern jump from Dec to Hex */ if(eff==0xd) dat=(((dat&0xf0)>>4)*10)+(dat&0xf); UniPTEffect(eff,dat); UniNewline(); } return UniDup(); }
static UBYTE* S3M_ConvertTrack(S3MNOTE* tr) { int t; UniReset(); for(t=0;t<64;t++) { UBYTE note,ins,vol; note=tr[t].note; ins=tr[t].ins; vol=tr[t].vol; if((ins)&&(ins!=255)) UniInstrument(ins-1); if(note!=255) { if(note==254) { UniPTEffect(0xc,0); /* note cut command */ vol=255; } else UniNote(((note>>4)*OCTAVE)+(note&0xf)); /* normal note */ } if(vol<255) UniPTEffect(0xc,vol); S3MIT_ProcessCmd(tr[t].cmd,tr[t].inf, tracker == 1 ? S3MIT_OLDSTYLE | S3MIT_SCREAM : S3MIT_OLDSTYLE); UniNewline(); } return UniDup(); }
static UBYTE *ConvertTrack(MODNOTE *n) { int t; UniReset(); for (t = 0; t < 64; t++) { ConvertNote(n); UniNewline(); n += of.numchn; } return UniDup(); }
static UBYTE * DSM_ConvertTrack (DSMNOTE * tr) { int t; UBYTE note, ins, vol, cmd, inf; UniReset (); for (t = 0; t < 64; t++) { note = tr[t].note; ins = tr[t].ins; vol = tr[t].vol; cmd = tr[t].cmd; inf = tr[t].inf; if (ins != 0 && ins != 255) UniInstrument (ins - 1); if (note != 255) UniNote (note - 1); /* normal note */ if (vol < 65) UniPTEffect (0xc, vol); if (cmd != 255) { if (cmd == 0x8) { if (inf == DSM_SURROUND) UniEffect (UNI_ITEFFECTS0, 0x91); else if (inf <= 0x80) { inf = (inf < 0x80) ? inf << 1 : 255; UniPTEffect (cmd, inf); } } else if (cmd == 0xb) { if (inf <= 0x7f) UniPTEffect (cmd, inf); } else { /* Convert pattern jump from Dec to Hex */ if (cmd == 0xd) inf = (((inf & 0xf0) >> 4) * 10) + (inf & 0xf); UniPTEffect (cmd, inf); } } UniNewline (); } return UniDup (); }
static UBYTE *FAR_ConvertTrack(FARNOTE* n,int rows) { int t,vibdepth=1; UniReset(); for(t=0;t<rows;t++) { if(n->note) { UniInstrument(n->ins); UniNote(n->note+3*OCTAVE-1); } if (n->vol&0xf) UniPTEffect(0xc,(n->vol&0xf)<<2); if (n->eff) switch(n->eff>>4) { case 0x3: /* porta to note */ UniPTEffect(0x3,(n->eff&0xf)<<4); break; case 0x4: /* retrigger */ UniPTEffect(0x0e, 0x90 | (n->eff & 0x0f)); break; case 0x5: /* set vibrato depth */ vibdepth=n->eff&0xf; break; case 0x6: /* vibrato */ UniPTEffect(0x4,((n->eff&0xf)<<4)|vibdepth); break; case 0x7: /* volume slide up */ UniPTEffect(0xa,(n->eff&0xf)<<4); break; case 0x8: /* volume slide down */ UniPTEffect(0xa,n->eff&0xf); break; case 0xb: /* panning */ UniPTEffect(0xe,0x80|(n->eff&0xf)); break; case 0xf: /* set speed */ UniPTEffect(0xf,n->eff&0xf); break; /* others not yet implemented */ default: #ifdef MIKMOD_DEBUG fprintf(stderr,"\rFAR: unsupported effect %02X\n",n->eff); #endif break; } UniNewline(); n+=16; } return UniDup(); }
static UBYTE *MTM_Convert(void) { int t; UBYTE a,b,c,inst,note,eff,dat; UniReset(); for(t=0; t<64; t++) { a=mtmtrk[t].a; b=mtmtrk[t].b; c=mtmtrk[t].c; inst=((a&0x3)<<4)|(b>>4); note=a>>2; eff=b&0xf; dat=c; if(inst!=0) { UniInstrument((UBYTE)(inst - 1)); } if(note!=0) { UniNote((UBYTE)(note + 24)); } /* mtm bug bugfix: when the effect is volslide, slide-up _always_ overrides slide-dn. */ if(eff==0xa && dat&0xf0) dat&=0xf0; UniPTEffect(eff,dat); UniNewline(); } return UniDup(); }
static UBYTE* IT_ConvertTrack(ITNOTE* tr,UWORD numrows) { int t; UBYTE note,ins,volpan; UniReset(); for(t=0;t<numrows;t++) { note=tr[t*of.numchn].note; ins=tr[t*of.numchn].ins; volpan=tr[t*of.numchn].volpan; if(note!=255) { if(note==253) UniWriteByte(UNI_KEYOFF); else if(note==254) { UniPTEffect(0xc,-1); /* note cut command */ volpan=255; } else UniNote(note); } if((ins)&&(ins<100)) UniInstrument(ins-1); else if(ins==253) UniWriteByte(UNI_KEYOFF); else if(ins!=255) { /* crap */ _mm_errno=MMERR_LOADING_PATTERN; return NULL; } /* process volume / panning column volume / panning effects do NOT all share the same memory address yet. */ if(volpan<=64) UniVolEffect(VOL_VOLUME,volpan); else if(volpan<=74) /* fine volume slide up (65-74) */ UniVolEffect(VOL_VOLSLIDE,0x0f+((volpan-65)<<4)); else if(volpan<=84) /* fine volume slide down (75-84) */ UniVolEffect(VOL_VOLSLIDE,0xf0+(volpan-75)); else if(volpan<=94) /* volume slide up (85-94) */ UniVolEffect(VOL_VOLSLIDE,((volpan-85)<<4)); else if(volpan<=104)/* volume slide down (95-104) */ UniVolEffect(VOL_VOLSLIDE,(volpan-95)); else if(volpan<=114)/* pitch slide down (105-114) */ UniVolEffect(VOL_PITCHSLIDEDN,(volpan-105)); else if(volpan<=124)/* pitch slide up (115-124) */ UniVolEffect(VOL_PITCHSLIDEUP,(volpan-115)); else if(volpan<=127) { /* crap */ _mm_errno=MMERR_LOADING_PATTERN; return NULL; } else if(volpan<=192) UniVolEffect(VOL_PANNING,((volpan-128)==64)?255:((volpan-128)<<2)); else if(volpan<=202)/* portamento to note */ UniVolEffect(VOL_PORTAMENTO,portatable[volpan-193]); else if(volpan<=212)/* vibrato */ UniVolEffect(VOL_VIBRATO,(volpan-203)); else if((volpan!=239)&&(volpan!=255)) { /* crap */ _mm_errno=MMERR_LOADING_PATTERN; return NULL; } S3MIT_ProcessCmd(tr[t*of.numchn].cmd,tr[t*of.numchn].inf,old_effect|2); UniNewline(); } return UniDup(); }
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; }
static UBYTE *S3M_ConvertTrack(S3MNOTE *tr) { int t; UBYTE note,ins,vol,cmd,inf,lo,hi; UniReset(); for(t=0;t<64;t++){ note=tr[t].note; ins=tr[t].ins; vol=tr[t].vol; cmd=tr[t].cmd; inf=tr[t].inf; lo=inf&0xf; hi=inf>>4; if(ins!=0 && ins!=255){ UniInstrument((UBYTE)(ins - 1)); } if(note!=255){ if(note==254) UniPTEffect(0xc,0); /* <- note off command */ else UniNote((UBYTE)(((note>>4)*12)+(note&0xf))); /* <- normal note */ } if(vol<255){ UniPTEffect(0xc,vol); // UniWrite(UNI_S3MVOLUME); // UniWrite(vol); } if(cmd!=255){ switch(cmd){ case 1: /* Axx set speed to xx */ UniWrite(UNI_S3MEFFECTA); UniWrite(inf); break; case 2: /* Bxx position jump */ UniPTEffect(0xb,inf); break; case 3: /* Cxx patternbreak to row xx */ UniPTEffect(0xd,inf); break; case 4: /* Dxy volumeslide */ UniWrite(UNI_S3MEFFECTD); UniWrite(inf); break; case 5: /* Exy toneslide down */ UniWrite(UNI_S3MEFFECTE); UniWrite(inf); break; case 6: /* Fxy toneslide up */ UniWrite(UNI_S3MEFFECTF); UniWrite(inf); break; case 7: /* Gxx Tone portamento,speed xx */ UniPTEffect(0x3,inf); break; case 8: /* Hxy vibrato */ UniPTEffect(0x4,inf); break; case 9: /* Ixy tremor, ontime x, offtime y */ UniWrite(UNI_S3MEFFECTI); UniWrite(inf); break; case 0xa: /* Jxy arpeggio */ UniPTEffect(0x0,inf); break; case 0xb: /* Kxy Dual command H00 & Dxy */ UniPTEffect(0x4,0); UniWrite(UNI_S3MEFFECTD); UniWrite(inf); break; case 0xc: /* Lxy Dual command G00 & Dxy */ UniPTEffect(0x3,0); UniWrite(UNI_S3MEFFECTD); UniWrite(inf); break; case 0xf: /* Oxx set sampleoffset xx00h */ UniPTEffect(0x9,inf); break; case 0x11: /* Qxy Retrig (+volumeslide) */ UniWrite(UNI_S3MEFFECTQ); UniWrite(inf); break; case 0x12: /* Rxy tremolo speed x, depth y */ UniPTEffect(0x6,inf); break; case 0x13: /* Sxx special commands */ switch(hi){ case 0: /* S0x set filter */ UniPTEffect(0xe, (UBYTE)(0x00|lo)); break; case 1: /* S1x set glissando control */ UniPTEffect(0xe, (UBYTE)(0x30|lo)); break; case 2: /* S2x set finetune */ UniPTEffect(0xe, (UBYTE)(0x50|lo)); break; case 3: /* S3x set vibrato waveform */ UniPTEffect(0xe, (UBYTE)(0x40|lo)); break; case 4: /* S4x set tremolo waveform */ UniPTEffect(0xe, (UBYTE)(0x70|lo)); break; case 8: /* S8x set panning position */ UniPTEffect(0xe, (UBYTE)(0x80|lo)); break; case 0xb: /* SBx pattern loop */ UniPTEffect(0xe, (UBYTE)(0x60|lo)); break; case 0xc: /* SCx notecut */ UniPTEffect(0xe,(UBYTE)(0xC0|lo)); break; case 0xd: /* SDx notedelay */ UniPTEffect(0xe, (UBYTE)(0xD0|lo)); break; case 0xe: /* SDx patterndelay */ UniPTEffect(0xe, (UBYTE)(0xE0|lo)); break; } break; case 0x14: /* Txx tempo */ if(inf>0x20){ UniWrite(UNI_S3MEFFECTT); UniWrite(inf); } break; case 0x18: /* Xxx amiga command 8xx */ UniPTEffect(0x8,inf); break; } } UniNewline(); } return UniDup(); }
/* Pattern analysis routine. Effects not implemented (yet) : (in decimal) 11 Arpeggio 4: Change note every 50Hz tick between N,H,N,L 12 Arpeggio 5: Change note every 50Hz tick between H,H,N N = normal note being played in this channel (1-36) L = normal note number minus upper four bits of 'data'. H = normal note number plus lower four bits of 'data'. 13 Decrease note number by 'data' once per tick. 17 Increase note number by 'data' once per tick. 21 Decrease note number by 'data' once per line. 30 Increase note number by 'data' once per line. */ static UBYTE *OKT_ConvertTrack(UBYTE patrows) { int t; UBYTE ins, note, eff, dat; UniReset(); for (t = 0; t < patrows; t++) { note = okttrk[t].note; ins = okttrk[t].ins; eff = okttrk[t].eff; dat = okttrk[t].dat; if (note) { UniNote(note + 3*OCTAVE - 1); UniInstrument(ins); } if (eff) switch (eff) { case 1: /* Porta Up */ UniPTEffect(0x1, dat); break; case 2: /* Portamento Down */ UniPTEffect(0x2, dat); break; case 10: /* Arpeggio 3 supported */ UniPTEffect(0x0, dat); break; case 15: /* Amiga filter toggle, ignored */ break; case 25: /* Pattern Jump */ UniPTEffect(0xb, dat); break; case 27: /* Release - similar to Keyoff */ UniWriteByte(UNI_KEYOFF); break; case 28: /* Set Tempo */ UniPTEffect(0xf, dat); break; case 31: /* volume Control */ if (dat <= 0x40) UniPTEffect(0xc, dat); else if (dat <= 0x50) UniEffect(UNI_XMEFFECTA, (dat - 0x40)); /* fast fade out */ else if (dat <= 0x60) UniEffect(UNI_XMEFFECTA, (dat - 0x50) << 4); /* fast fade in */ else if (dat <= 0x70) UniEffect(UNI_XMEFFECTEB, (dat - 0x60)); /* slow fade out */ else if (dat <= 0x80) UniEffect(UNI_XMEFFECTEA, (dat - 0x70)); /* slow fade in */ break; #ifdef MIKMOD_DEBUG default: fprintf(stderr, "\rUnimplemented effect (%02d,%02x)\n", eff, dat); #endif } UniNewline(); } return UniDup(); }
static UBYTE *XM_Convert(XMNOTE *xmtrack,UWORD rows) { int t; UBYTE note,ins,vol,eff,dat; UniReset(); for(t=0;t<rows;t++){ note=xmtrack->note; ins=xmtrack->ins; vol=xmtrack->vol; eff=xmtrack->eff; dat=xmtrack->dat; if(note!=0) UniNote(note-1); if(ins!=0) UniInstrument(ins-1); /* printf("Vol:%d\n",vol); */ switch(vol>>4){ case 0x6: /* volslide down */ if(vol&0xf){ UniWrite(UNI_XMEFFECTA); UniWrite(vol&0xf); } break; case 0x7: /* volslide up */ if(vol&0xf){ UniWrite(UNI_XMEFFECTA); UniWrite(vol<<4); } break; /* volume-row fine volume slide is compatible with protracker EBx and EAx effects i.e. a zero nibble means DO NOT SLIDE, as opposed to 'take the last sliding value'. */ case 0x8: /* finevol down */ UniPTEffect(0xe,0xb0 | (vol&0xf)); break; case 0x9: /* finevol up */ UniPTEffect(0xe,0xa0 | (vol&0xf)); break; case 0xa: /* set vibrato speed */ UniPTEffect(0x4,vol<<4); break; case 0xb: /* vibrato */ UniPTEffect(0x4,vol&0xf); break; case 0xc: /* set panning */ UniPTEffect(0x8,vol<<4); break; case 0xd: /* panning slide left */ /* only slide when data nibble not zero: */ if(vol&0xf){ UniWrite(UNI_XMEFFECTP); UniWrite(vol&0xf); } break; case 0xe: /* panning slide right */ /* only slide when data nibble not zero: */ if(vol&0xf){ UniWrite(UNI_XMEFFECTP); UniWrite(vol<<4); } break; case 0xf: /* tone porta */ UniPTEffect(0x3,vol<<4); break; default: if(vol>=0x10 && vol<=0x50){ UniPTEffect(0xc,vol-0x10); } } /* if(eff>0xf) printf("Effect %d",eff); */ switch(eff){ case 'G'-55: /* G - set global volume */ if(dat>64) dat=64; UniWrite(UNI_XMEFFECTG); UniWrite(dat); break; case 'H'-55: /* H - global volume slide */ UniWrite(UNI_XMEFFECTH); UniWrite(dat); break; case 'K'-55: /* K - keyoff */ UniNote(96); break; case 'L'-55: /* L - set envelope position */ break; case 'P'-55: /* P - panning slide */ UniWrite(UNI_XMEFFECTP); UniWrite(dat); break; case 'R'-55: /* R - multi retrig note */ UniWrite(UNI_S3MEFFECTQ); UniWrite(dat); break; case 'T'-55: /* T - Tremor !! (== S3M effect I) */ UniWrite(UNI_S3MEFFECTI); UniWrite(dat); break; case 'X'-55: if((dat>>4)==1){ /* X1 extra fine porta up */ } else{ /* X2 extra fine porta down */ } break; default: if(eff==0xa){ UniWrite(UNI_XMEFFECTA); UniWrite(dat); } else if(eff<=0xf) UniPTEffect(eff,dat); break; } UniNewline(); xmtrack++; }
static UBYTE* STX_ConvertTrack(STXNOTE* tr) { int t; UniReset(); for(t=0;t<64;t++) { UBYTE note,ins,vol,cmd,inf; note=tr[t].note; ins=tr[t].ins; vol=tr[t].vol; cmd=tr[t].cmd; inf=tr[t].inf; if((ins)&&(ins!=255)) UniInstrument(ins-1); if((note)&&(note!=255)) { if(note==254) { UniPTEffect(0xc,0); /* note cut command */ vol=255; } else UniNote(24+((note>>4)*OCTAVE)+(note&0xf)); /* normal note */ } if(vol<255) UniPTEffect(0xc,vol); if(cmd<255) switch(cmd) { case 1: /* Axx set speed to xx */ UniPTEffect(0xf,inf>>4); break; case 2: /* Bxx position jump */ UniPTEffect(0xb,inf); break; case 3: /* Cxx patternbreak to row xx */ UniPTEffect(0xd,(((inf&0xf0)>>4)*10)+(inf&0xf)); 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 */ UniPTEffect(0x3,inf); break; case 8: /* Hxy vibrato */ UniPTEffect(0x4,inf); break; case 9: /* Ixy tremor, ontime x, offtime y */ UniEffect(UNI_S3MEFFECTI,inf); break; case 0: /* protracker arpeggio */ if(!inf) break; /* fall through */ case 0xa: /* Jxy arpeggio */ UniPTEffect(0x0,inf); break; case 0xb: /* Kxy Dual command H00 & Dxy */ UniPTEffect(0x4,0); UniEffect(UNI_S3MEFFECTD,inf); break; case 0xc: /* Lxy Dual command G00 & Dxy */ UniPTEffect(0x3,0); UniEffect(UNI_S3MEFFECTD,inf); break; /* Support all these above, since ST2 can LOAD these values but can actually only play up to J - and J is only half-way implemented in ST2 */ case 0x18: /* Xxx amiga panning command 8xx */ UniPTEffect(0x8,inf); of.flags |= UF_PANNING; break; } UniNewline(); } return UniDup(); }