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(); }
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++; }