예제 #1
0
 public Note(SPCCommand command)
 {
     this.Command    = command;
     this.Octave     = 6;
     this.Percussive = false;
     this.Sample     = 0;
 }
예제 #2
0
 // constructors
 public Note(SPCCommand command, int octave, bool percussive, int sample)
 {
     this.Command    = command;
     this.Octave     = percussive ? 5 : octave;
     this.Percussive = percussive;
     this.Sample     = sample;
 }
예제 #3
0
        private void RepeatLoop(int c, ref int i, int start, int count, ref int octave, ref bool percussive, ref int sample)
        {
            int end        = i;
            int thisOctave = octave;

            while (count > 0 && i < channels[c].Count)
            {
                SPCCommand ssc = channels[c][i++];
                // 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++; break;

                case 0xC5: thisOctave--; break;

                case 0xC6: thisOctave = ssc.Param1; break;

                case 0xD4:
                    RepeatLoop(c, ref i, i, ssc.Param1, ref thisOctave, ref percussive, ref sample);
                    break;

                case 0xD5:
                    end = i;
                    count--;
                    if (count > 0)
                    {
                        i          = start;
                        thisOctave = octave;
                    }
                    break;

                case 0xD6: break;

                case 0xDE: sample = ssc.Param1; goto default;

                case 0xEE: percussive = true; goto default;

                case 0xEF: percussive = false; goto default;

                default:
                    if (ssc.Opcode < 0xC4 || ssc.Opcode == 0xD7 || ssc.Opcode == 0xDE || ssc.Opcode == 0xEE || ssc.Opcode == 0xEF)
                    {
                        notes[c].Add(new Note(ssc, thisOctave, percussive, sample));
                    }
                    break;
                }
            }
            octave = thisOctave;
        }
예제 #4
0
        // notation functions
        public override void CreateNotes()
        {
            notes = new List <Note> [8];
            for (int c = 0; c < notes.Length; c++)
            {
                if (channels[c] == null)
                {
                    continue;
                }
                notes[c] = new List <Note>();
                int  i          = 0;
                int  thisOctave = 6;
                int  sample     = 0;
                bool percussive = false;
                while (i < channels[c].Count)
                {
                    SPCCommand ssc = channels[c][i++];
                    switch (ssc.Opcode)
                    {
                    case 0xC4: thisOctave++; break;

                    case 0xC5: thisOctave--; break;

                    case 0xC6: thisOctave = ssc.Param1; break;

                    case 0xD4:
                        RepeatLoop(c, ref i, i, ssc.Param1, 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:
                        if (ssc.Opcode < 0xC4 || ssc.Opcode == 0xD7 || ssc.Opcode == 0xDE || ssc.Opcode == 0xEE || ssc.Opcode == 0xEF)
                        {
                            notes[c].Add(new Note(ssc, thisOctave, percussive, sample));
                        }
                        break;
                    }
                }
            }
        }
예제 #5
0
        private void DecompToMMLLoop(ref List <SPCCommand>[] 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]];
                }
                SPCCommand 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 SPCCommand(new byte[] { 0xC6, (byte)thisOctave }, this, c));
                    DecompToMMLLoop(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;
        }
예제 #6
0
        // conversion functions
        public List <SPCCommand>[] DecompToMML(NativeSPC nativeFormat)
        {
            List <SPCCommand>[] commands = new List <SPCCommand> [8];
            for (int c = 0; c < commands.Length; c++)
            {
                if (channels[c] == null)
                {
                    continue;
                }
                commands[c] = new List <SPCCommand>();
                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]];
                    }
                    SPCCommand 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(ssc);
                        commands[c].Add(new SPCCommand(new byte[] { 0xC6, (byte)thisOctave }, this, c));
                        DecompToMMLLoop(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);
        }
예제 #7
0
        // class functions
        public int Length()
        {
            int length = 0;

            // first make sure each channel ends with a termination command
            for (int i = 0; i < 2; i++)
            {
                if (channels[i] != null && channels[i].Count > 0)
                {
                    SPCCommand lastSSC = channels[i][channels[i].Count - 1];
                    if (lastSSC.Opcode != 0xD0 && lastSSC.Opcode != 0xCD && lastSSC.Opcode != 0xCE)
                    {
                        length++;
                    }
                }
            }
            //
            int channelSize1 = 0;
            int channelSize2 = 0;

            if (channels[0] != null && activeChannels[0])
            {
                foreach (SPCCommand ssc in channels[0])
                {
                    channelSize1 += ssc.Length;
                }
            }
            if (channels[1] != null && activeChannels[1])
            {
                foreach (SPCCommand ssc in channels[1])
                {
                    channelSize2 += ssc.Length;
                }
            }
            //
            bool channel2in1 = true;

            if (channels[0] != null && channels[1] != null &&
                activeChannels[0] && activeChannels[1] &&
                channelSize2 <= channelSize1)
            {
                for (int a = channels[0].Count - 1, b = channels[1].Count - 1; a >= 0 && b >= 0; a--, b--)
                {
                    if (!Bits.Compare(channels[0][a].CommandData, channels[1][b].CommandData))
                    {
                        channel2in1 = false;
                    }
                }
            }
            else
            {
                channel2in1 = false;
            }
            //
            if (channel2in1)
            {
                length += channelSize1;
            }
            else
            {
                length += channelSize1 + channelSize2;
            }
            return(length);
        }
예제 #8
0
        public void Assemble(ref int offset)
        {
            // first make sure each channel ends with a termination command
            for (int i = 0; i < 2; i++)
            {
                if (channels[i] != null && channels[i].Count > 0)
                {
                    SPCCommand lastSSC = channels[i][channels[i].Count - 1];
                    if (lastSSC.Opcode != 0xD0 && lastSSC.Opcode != 0xCD && lastSSC.Opcode != 0xCE)
                    {
                        channels[i].Add(new SPCCommand(new byte[] { 0xD0 }, this, 0));
                    }
                }
            }
            //
            int channelSize1 = 0;
            int channelSize2 = 0;

            if (channels[0] != null && activeChannels[0])
            {
                foreach (SPCCommand ssc in channels[0])
                {
                    channelSize1 += ssc.Length;
                }
            }
            if (channels[1] != null && activeChannels[1])
            {
                foreach (SPCCommand ssc in channels[1])
                {
                    channelSize2 += ssc.Length;
                }
            }
            //
            int offsetStart1 = offset;
            int offsetStart2 = offset + channelSize1;

            if (channels[0] == null || !activeChannels[0])
            {
                offsetStart1 = 0;
            }
            if (channels[1] == null || !activeChannels[1])
            {
                offsetStart2 = 0;
            }
            //
            bool channel2in1 = true;

            if (offsetStart1 != 0 && offsetStart2 != 0 && channelSize2 <= channelSize1)
            {
                for (int a = channels[0].Count - 1, b = channels[1].Count - 1; a >= 0 && b >= 0; a--, b--)
                {
                    if (!Bits.Compare(channels[0][a].CommandData, channels[1][b].CommandData))
                    {
                        channel2in1 = false;
                    }
                }
            }
            else
            {
                channel2in1 = false;
            }
            if (channel2in1)
            {
                offsetStart2 -= channelSize2;
            }
            //
            if (type == 0)
            {
                if (offsetStart1 == 0)
                {
                    Bits.SetShort(rom, index * 4 + 0x042826, 0);
                }
                else
                {
                    Bits.SetShort(rom, index * 4 + 0x042826, offsetStart1 - 0x042C26 + 0x3400);
                }
                if (offsetStart2 == 0)
                {
                    Bits.SetShort(rom, index * 4 + 0x042826 + 2, 0);
                }
                else
                {
                    Bits.SetShort(rom, index * 4 + 0x042826 + 2, offsetStart2 - 0x042C26 + 0x3400);
                }
            }
            else
            {
                if (offsetStart1 == 0)
                {
                    Bits.SetShort(rom, index * 4 + 0x043E26, 0);
                }
                else
                {
                    Bits.SetShort(rom, index * 4 + 0x043E26, offsetStart1 - 0x044226 + 0x3400);
                }
                if (offsetStart2 == 0)
                {
                    Bits.SetShort(rom, index * 4 + 0x043E26 + 2, 0);
                }
                else
                {
                    Bits.SetShort(rom, index * 4 + 0x043E26 + 2, offsetStart2 - 0x044226 + 0x3400);
                }
            }
            if (channels[0] != null && activeChannels[0])
            {
                foreach (SPCCommand ssc in channels[0])
                {
                    Bits.SetBytes(rom, offsetStart1, ssc.CommandData);
                    offsetStart1 += ssc.Length;
                }
            }
            if (channels[1] != null && activeChannels[1])
            {
                foreach (SPCCommand ssc in channels[1])
                {
                    Bits.SetBytes(rom, offsetStart2, ssc.CommandData);
                    offsetStart2 += ssc.Length;
                }
            }
            if (channel2in1)
            {
                offset += channelSize1;
            }
            else
            {
                offset += channelSize1 + channelSize2;
            }
        }