private void CompatibilizeMMLLoop(ref List <Command>[] commands, NativeSPC nativeFormat, int c, ref int i, int start, int count, bool nested, ref int octave, ref bool percussive, ref int sample) { int end = i; int thisOctave = octave; while (count > 0 && i < Channels[c].Count) { int maxOctave = 6; if (nativeFormat == NativeSPC.SMWLevel || nativeFormat == NativeSPC.SMWOverworld) { maxOctave = Lists.SMWOctaveLimits[Lists.SMRPGtoSMWSamples[sample]]; } Command ssc = Channels[c][i++].Copy(); // if at last repeat, and first section begins, skip the rest if (ssc.Opcode == 0xD6 && count == 1) { while (i < Channels[c].Count && i < end) { i++; } break; } switch (ssc.Opcode) { case 0xC4: thisOctave++; if (thisOctave > maxOctave) { thisOctave = maxOctave; } else { goto default; } break; case 0xC5: thisOctave--; if (thisOctave < 1) { thisOctave = 1; } else { goto default; } break; case 0xC6: if (ssc.Param1 < 1) { ssc.Param1 = 1; } if (ssc.Param1 > maxOctave) { ssc.Param1 = (byte)maxOctave; } thisOctave = ssc.Param1; goto default; case 0xD4: commands[c].Add(new Command(new byte[] { 0xC6, (byte)thisOctave }, this, c)); CompatibilizeMMLLoop(ref commands, nativeFormat, c, ref i, i, ssc.Param1, true, ref thisOctave, ref percussive, ref sample); break; case 0xD5: end = i; count--; if (nested && count > 0) { i = start; thisOctave = octave; } else if (!nested) { commands[c].Add(ssc); octave = thisOctave; return; } break; case 0xD6: break; case 0xDE: sample = ssc.Param1; goto default; case 0xEE: percussive = true; goto default; case 0xEF: percussive = false; goto default; default: thisOctave = Math.Max(1, Math.Min(6, thisOctave)); commands[c].Add(ssc); break; } } octave = thisOctave; }
/// <summary> /// Creates a command collection from this instance's command data /// having greater compatibility with the universal MML format. /// </summary> /// <param name="nativeFormat"></param> /// <returns></returns> public List <Command>[] CompatibilizeMML(NativeSPC nativeFormat) { List <Command>[] commands = new List <Command> [8]; for (int c = 0; c < commands.Length; c++) { if (Channels[c] == null) { continue; } commands[c] = new List <Command>(); int i = 0; int thisOctave = 6; int sample = 0; bool percussive = false; while (i < Channels[c].Count) { int maxOctave = 6; if (nativeFormat == NativeSPC.SMWLevel || nativeFormat == NativeSPC.SMWOverworld) { maxOctave = Lists.SMWOctaveLimits[Lists.SMRPGtoSMWSamples[sample]]; } Command ssc = Channels[c][i++].Copy(); switch (ssc.Opcode) { case 0xC4: thisOctave++; if (thisOctave > maxOctave) { thisOctave = maxOctave; } else { goto default; } break; case 0xC5: thisOctave--; if (thisOctave < 1) { thisOctave = 1; } else { goto default; } break; case 0xC6: if (ssc.Param1 < 1) { ssc.Param1 = 1; } if (ssc.Param1 > maxOctave) { ssc.Param1 = (byte)maxOctave; } thisOctave = ssc.Param1; goto default; case 0xD4: commands[c].Add(new Command(new byte[] { 0xC6, (byte)thisOctave }, this, c)); CompatibilizeMMLLoop(ref commands, nativeFormat, c, ref i, i, ssc.Param1, false, ref thisOctave, ref percussive, ref sample); break; case 0xD5: break; case 0xDE: sample = ssc.Param1; goto default; case 0xEE: percussive = true; goto default; case 0xEF: percussive = false; goto default; default: thisOctave = Math.Max(1, Math.Min(6, thisOctave)); commands[c].Add(ssc); break; } } } return(commands); }