コード例 #1
0
        int XM_ReadNote(ref XMNOTE n)
        {
            byte cmp, result = 1;

            n.Clear();
            cmp = m_Reader.Read_byte();

            if ((cmp & 0x80) != 0)
            {
                if ((cmp & 1) != 0)
                {
                    result++; n.note = m_Reader.Read_byte();
                }
                if ((cmp & 2) != 0)
                {
                    result++; n.ins = m_Reader.Read_byte();
                }
                if ((cmp & 4) != 0)
                {
                    result++; n.vol = m_Reader.Read_byte();
                }
                if ((cmp & 8) != 0)
                {
                    result++; n.eff = m_Reader.Read_byte();
                }
                if ((cmp & 16) != 0)
                {
                    result++; n.dat = m_Reader.Read_byte();
                }
            }
            else
            {
                n.note  = cmp;
                n.ins   = m_Reader.Read_byte();
                n.vol   = m_Reader.Read_byte();
                n.eff   = m_Reader.Read_byte();
                n.dat   = m_Reader.Read_byte();
                result += 4;
            }
            return(result);
        }
コード例 #2
0
        bool LoadPatterns(bool dummypat)
        {
            int t, u, v, numtrk;

            m_Module.AllocTracks();
            m_Module.AllocPatterns();

            numtrk = 0;
            for (t = 0; t < mh.numpat; t++)
            {
                XMPATHEADER ph = new XMPATHEADER();

                ph.size = m_Reader.Read_Intel_uint();
                if (ph.size < (mh.version == 0x0102 ? 8 : 9))
                {
                    m_LoadError = MMERR_LOADING_PATTERN;
                    return(false);
                }
                ph.packing = m_Reader.Read_byte();
                if (ph.packing != 0)
                {
                    m_LoadError = MMERR_LOADING_PATTERN;
                    return(false);
                }
                if (mh.version == 0x0102)
                {
                    ph.numrows = (ushort)(m_Reader.Read_byte() + 1);
                }
                else
                {
                    ph.numrows = m_Reader.Read_Intel_ushort();
                }
                ph.packsize = (short)m_Reader.Read_Intel_ushort();

                ph.size -= (ushort)(mh.version == 0x0102 ? 8 : 9);
                if (ph.size != 0)
                {
                    m_Reader.Seek((int)ph.size, SeekOrigin.Current);
                }

                m_Module.pattrows[t] = ph.numrows;

                if (ph.numrows != 0)
                {
                    xmpat = new XMNOTE[ph.numrows * m_Module.numchn];
                    for (int i = 0; i < xmpat.Length; i++)
                    {
                        xmpat[i] = new XMNOTE();
                    }

                    /* when packsize is 0, don't try to load a pattern.. it's empty. */
                    if (ph.packsize != 0)
                    {
                        for (u = 0; u < ph.numrows; u++)
                        {
                            for (v = 0; v < m_Module.numchn; v++)
                            {
                                if (ph.packsize == 0)
                                {
                                    break;
                                }

                                ph.packsize -= (short)XM_ReadNote(ref xmpat[(v * ph.numrows) + u]);
                                if (ph.packsize < 0)
                                {
                                    m_LoadError = MMERR_LOADING_PATTERN;
                                    return(false);
                                }
                            }
                        }
                    }

                    if (ph.packsize != 0)
                    {
                        m_Reader.Seek(ph.packsize, SeekOrigin.Current);
                    }

                    if (m_Reader.isEOF())
                    {
                        m_LoadError = MMERR_LOADING_PATTERN;
                        return(false);
                    }

                    for (v = 0; v < m_Module.numchn; v++)
                    {
                        m_Module.tracks[numtrk++] = XM_Convert(xmpat, v * ph.numrows, ph.numrows);
                    }

                    xmpat = null;
                }
                else
                {
                    for (v = 0; v < m_Module.numchn; v++)
                    {
                        m_Module.tracks[numtrk++] = XM_Convert(null, 0, ph.numrows);
                    }
                }
            }

            if (dummypat)
            {
                m_Module.pattrows[t] = 64;
                xmpat = new XMNOTE[64 * m_Module.numchn];
                for (int i = 0; i < xmpat.Length; i++)
                {
                    xmpat[i] = new XMNOTE();
                }

                for (v = 0; v < m_Module.numchn; v++)
                {
                    m_Module.tracks[numtrk++] = XM_Convert(xmpat, v * 64, 64);
                }
                xmpat = null;
            }

            return(true);
        }
コード例 #3
0
        byte[] XM_Convert(XMNOTE[] xmtracks, int place, ushort rows)
        {
            int  t;
            byte note, ins, vol, eff, dat;

            UniReset();
            for (t = 0; t < rows; t++)
            {
                XMNOTE xmtrack = xmtracks[place++];
                note = xmtrack.note;
                ins  = xmtrack.ins;
                vol  = xmtrack.vol;
                eff  = xmtrack.eff;
                dat  = xmtrack.dat;

                if (note != 0)
                {
                    if (note > XMNOTECNT)
                    {
                        UniEffect(SharpMikCommon.Commands.UNI_KEYFADE, 0);
                    }
                    else
                    {
                        UniNote(note - 1);
                    }
                }
                if (ins != 0)
                {
                    UniInstrument(ins - 1);
                }

                switch (vol >> 4)
                {
                case 0x6:     /* volslide down */
                    if ((vol & 0xf) != 0)
                    {
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTA, vol & 0xf);
                    }
                    break;

                case 0x7:     /* volslide up */
                    if ((vol & 0xf) != 0)
                    {
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTA, 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 */
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECT4, vol << 4);
                    break;

                case 0xb:     /* vibrato */
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECT4, vol & 0xf);
                    break;

                case 0xc:     /* set panning */
                    UniPTEffect(0x8, vol << 4);
                    break;

                case 0xd:     /* panning slide left (only slide when data not zero) */
                    if ((vol & 0xf) != 0)
                    {
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTP, vol & 0xf);
                    }
                    break;

                case 0xe:     /* panning slide right (only slide when data not zero) */
                    if ((vol & 0xf) != 0)
                    {
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTP, vol << 4);
                    }
                    break;

                case 0xf:     /* tone porta */
                    UniPTEffect(0x3, vol << 4);
                    break;

                default:
                    if ((vol >= 0x10) && (vol <= 0x50))
                    {
                        UniPTEffect(0xc, vol - 0x10);
                    }
                    break;
                }

                switch (eff)
                {
                case 0x4:
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECT4, dat);
                    break;

                case 0x6:
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECT6, dat);
                    break;

                case 0xa:
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTA, dat);
                    break;

                case 0xe:     /* Extended effects */
                    switch (dat >> 4)
                    {
                    case 0x1:         /* XM fine porta up */
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTE1, dat & 0xf);
                        break;

                    case 0x2:         /* XM fine porta down */
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTE2, dat & 0xf);
                        break;

                    case 0xa:         /* XM fine volume up */
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTEA, dat & 0xf);
                        break;

                    case 0xb:         /* XM fine volume down */
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTEB, dat & 0xf);
                        break;

                    default:
                        UniPTEffect(eff, dat);
                        break;
                    }
                    break;

                case 'G' - 55:     /* G - set global volume */
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTG, dat > 64 ? 128 : dat << 1);
                    break;

                case 'H' - 55:     /* H - global volume slide */
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTH, dat);
                    break;

                case 'K' - 55:     /* K - keyOff and KeyFade */
                    UniEffect(SharpMikCommon.Commands.UNI_KEYFADE, dat);
                    break;

                case 'L' - 55:     /* L - set envelope position */
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTL, dat);
                    break;

                case 'P' - 55:     /* P - panning slide */
                    UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTP, dat);
                    break;

                case 'R' - 55:     /* R - multi retrig note */
                    UniEffect(SharpMikCommon.Commands.UNI_S3MEFFECTQ, dat);
                    break;

                case 'T' - 55:     /* T - Tremor */
                    UniEffect(SharpMikCommon.Commands.UNI_S3MEFFECTI, dat);
                    break;

                case 'X' - 55:
                    switch (dat >> 4)
                    {
                    case 1:         /* X1 - Extra Fine Porta up */
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTX1, dat & 0xf);
                        break;

                    case 2:         /* X2 - Extra Fine Porta down */
                        UniEffect(SharpMikCommon.Commands.UNI_XMEFFECTX2, dat & 0xf);
                        break;
                    }
                    break;

                default:
                    if (eff <= 0xf)
                    {
                        /* the pattern jump destination is written in decimal,
                         *                             but it seems some poor tracker software writes them
                         *                             in hexadecimal... (sigh) */
                        if (eff == 0xd)
                        {
                            /* don't change anything if we're sure it's in hexa */
                            if ((((dat & 0xf0) >> 4) <= 9) && ((dat & 0xf) <= 9))
                            {
                                /* otherwise, convert from dec to hex */
                                dat = (byte)((((dat & 0xf0) >> 4) * 10) + (dat & 0xf));
                            }
                        }
                        UniPTEffect(eff, dat);
                    }
                    break;
                }
                UniNewline();
            }
            return(UniDup());
        }