コード例 #1
0
        private void NoteOffMONO(int n)
        {
            //if (cChip == null) return;
            //eChip = Audio.GetChip(EnmChip.YM2612);
            //if (eChip == null) return;
            if (n < 0 || n > 127)
            {
                return;
            }

            if (latestNoteNumberMONO != n)
            {
                return;
            }

            MML mml = MakeMML_NoteOff(n);

            lock (lockObject)
            {
                cChip.SetKeyOff(pw.apg, mml);
            }
        }
コード例 #2
0
        private void NoteOnMONO(int n, int velocity)
        {
            //if (cChip == null) return;
            //eChip = Audio.GetChip(EnmChip.YM2612);
            //if (eChip == null) return;
            if (n < 0 || n > 127)
            {
                return;
            }

            NoteOffMONO(latestNoteNumberMONO);
            MML mml = MakeMML_Octave(n);

            cChip.CmdOctave(pw.apg, mml);
            mml = MakeMML_NoteOn(n);
            lock (lockObject)
            {
                cChip.CmdNote(pw, pw.apg, mml);//TODO:page制御やってない
                cChip.MultiChannelCommand(mml);
            }

            latestNoteNumberMONO = n;
        }
コード例 #3
0
 public AvaloniaTrack(MML mml)
 {
     this.mml      = mml;
     this.channels = mml.Channels.Select(channel => new AvaloniaSound(channel));
 }
コード例 #4
0
ファイル: MMLPrinter.cs プロジェクト: rerrahkr/ConvFMML
        private string GenerateHeader(MML mml, Settings settings)
        {
            string str  = string.Empty;
            bool   flag = false;

            switch (mml.Style)
            {
            case MMLStyle.FMP7:
                if (settings.mmlExpression.TitleEnable == 1 && mml.Title.Length > 0)
                {
                    str += " Title=" + mml.Title + Environment.NewLine;
                    flag = true;
                }
                if (settings.mmlExpression.PrintTimeBase == 1)
                {
                    str += " ClockCount=" + mml.CountsPerWholeNote + Environment.NewLine;
                    flag = true;
                }
                if (settings.outputPart.PrintStyle != 0)
                {
                    var lookUp = mml.PartList.ToLookup(x => x.SoundModule, x => x.Name);
                    if (lookUp[SoundModule.FM].Count() > 0)
                    {
                        string stemp = string.Empty;
                        foreach (string s in lookUp[SoundModule.FM])
                        {
                            if (!string.IsNullOrEmpty(s))
                            {
                                stemp += s.Substring(1);
                            }
                        }
                        if (stemp.Count() > 0)
                        {
                            str  = str + " PartOPNA=" + stemp + Environment.NewLine;
                            flag = true;
                        }
                    }
                    if (lookUp[SoundModule.SSG].Count() > 0)
                    {
                        string stemp = string.Empty;
                        foreach (string s in lookUp[SoundModule.SSG])
                        {
                            if (!string.IsNullOrEmpty(s))
                            {
                                stemp += s.Substring(1);
                            }
                        }
                        if (stemp.Count() > 0)
                        {
                            str  = str + " PartSSG=" + stemp + Environment.NewLine;
                            flag = true;
                        }
                    }
                }
                if (flag)
                {
                    str = "\'{" + Environment.NewLine +
                          str +
                          "}" + Environment.NewLine;
                }
                break;

            case MMLStyle.MXDRV:
                if (settings.mmlExpression.TitleEnable == 1 && mml.Title.Length > 0)
                {
                    str += "#title\t\"" + mml.Title + "\"" + Environment.NewLine;
                    flag = true;
                }
                if (settings.noteRest.OctaveDirection == 1)
                {
                    str  = "#OCTAVE-REV" + Environment.NewLine;
                    flag = true;
                }
                break;

            case MMLStyle.NRTDRV:
                if (settings.mmlExpression.TitleEnable == 1 && mml.Title.Length > 0)
                {
                    str += "#TITLE\t" + mml.Title + Environment.NewLine;
                    flag = true;
                }
                if (settings.mmlExpression.PrintTimeBase == 1)
                {
                    str += "#COUNT\t" + mml.CountsPerWholeNote + Environment.NewLine;
                    flag = true;
                }
                if (settings.noteRest.OctaveDirection == 1)
                {
                    str  = "#OCTAVE_REV" + Environment.NewLine;
                    flag = true;
                }
                if (settings.controlCommand.volume.Enable && settings.controlCommand.volume.CommandNRTDRV == 0)
                {
                    str += "#V_STEP\t" + settings.controlCommand.volume.VStep + Environment.NewLine;
                    flag = true;
                }
                break;

            case MMLStyle.PMD:
                if (settings.mmlExpression.TitleEnable == 1 && mml.Title.Length > 0)
                {
                    str += "#Title\t" + mml.Title + Environment.NewLine;
                    flag = true;
                }
                if (settings.mmlExpression.PrintTimeBasePMD == 1)
                {
                    str += "#Zenlen\t" + mml.CountsPerWholeNote + Environment.NewLine;
                    flag = true;
                }
                if (settings.outputPart.PrintStyle == 1 ||
                    (settings.outputPart.PrintStyle == 2 && settings.outputPart.AutoNamePMD == 2))
                {
                    var lookUp = mml.PartList.ToLookup(x => x.SoundModule, x => x.Name);
                    if (lookUp[SoundModule.FM3ch].Count() > 0)
                    {
                        string stemp = string.Empty;
                        lookUp[SoundModule.FM3ch].ToList().ForEach(x => stemp += x);
                        if (stemp.Count() > 0)
                        {
                            str  = str + "#FM3Extend\t" + stemp + Environment.NewLine;
                            flag = true;
                        }
                    }
                }
                if (settings.noteRest.OctaveDirection == 1)
                {
                    str += "#Octave\tReverse" + Environment.NewLine;
                    flag = true;
                }
                break;

            case MMLStyle.MUCOM88:
                if (settings.mmlExpression.TitleEnable == 1 && mml.Title.Length > 0)
                {
                    str += "#title\t" + mml.Title + Environment.NewLine;
                    flag = true;
                }
                break;

            case MMLStyle.Mml2vgm:
                if (settings.mmlExpression.TitleEnable == 1 && mml.Title.Length > 0)
                {
                    str += " TitleName=" + mml.Title + Environment.NewLine;
                    flag = true;
                }
                if (settings.mmlExpression.PrintTimeBase == 1)
                {
                    str += " ClockCount=" + mml.CountsPerWholeNote + Environment.NewLine;
                    flag = true;
                }
                if (flag)
                {
                    str = "\'{" + Environment.NewLine +
                          str +
                          "}" + Environment.NewLine;
                }
                break;

            default:
                break;
            }

            if (flag)
            {
                str += Environment.NewLine;
            }

            return(str);
        }
コード例 #5
0
ファイル: MMLPrinter.cs プロジェクト: rerrahkr/ConvFMML
        public void Print(MML mml, string path, Settings settings)
        {
            try
            {
                using (var sw = new StreamWriter(path, false, Encoding.GetEncoding(
                                                     (mml.Style == MMLStyle.Mml2vgm) ? "utf-8" : "shift_jis")))
                {
                    string str = GenerateHeader(mml, settings);
                    sw.Write(str);


                    foreach (Part part in mml.PartList)
                    {
                        Note prevNote      = null;
                        bool isNewLineNote = false;
                        bool needPartName  = true;


                        for (int i = 0; i < part.Length; i++)
                        {
                            Bar bar = part.BarList[i];
                            str = string.Empty;


                            if (bar.CommandList.Count > 0)
                            {
                                // Print part name
                                if (needPartName)
                                {
                                    if (settings.outputPart.PrintStyle != 0)
                                    {
                                        str = part.Name + (settings.mmlExpression.UseTabAfterPartName ? "\t" : " ");
                                    }
                                    needPartName = false;

                                    if (i == 0 &&
                                        ((mml.PartList.IndexOf(part) == 0 &&
                                          (mml.Style == MMLStyle.FMP && settings.mmlExpression.PrintTimeBase == 1) ||
                                          (mml.Style == MMLStyle.PMD && settings.mmlExpression.PrintTimeBasePMD == 2)) ||
                                         (mml.Style == MMLStyle.MUCOM88 && settings.mmlExpression.PrintTimeBase == 1)))
                                    {
                                        str += "C" + mml.CountsPerWholeNote + " ";
                                    }
                                }


                                // Print commands a bar
                                foreach (Command c in bar.CommandList)
                                {
                                    if (c is Note)
                                    {
                                        var note = (Note)c;
                                        if (prevNote == null)
                                        {
                                            if (mml.Style == MMLStyle.Custom)
                                            {
                                                str += settings.noteRest.OctaveCommandCustom + note.Octave + " ";
                                            }
                                            else
                                            {
                                                str += "o" + note.Octave + " ";
                                            }
                                        }
                                        else
                                        {
                                            if (!isNewLineNote && settings.noteRest.OctaveInNewLine == 1)
                                            {
                                                if (mml.Style == MMLStyle.Custom)
                                                {
                                                    str += settings.noteRest.OctaveCommandCustom + note.Octave + " ";
                                                }
                                                else
                                                {
                                                    str += "o" + note.Octave + " ";
                                                }
                                            }
                                            else
                                            {
                                                int dif = note.Octave - prevNote.Octave;
                                                if (dif > 0)
                                                {
                                                    for (int j = 0; j < dif; j++)
                                                    {
                                                        switch (mml.Style)
                                                        {
                                                        case MMLStyle.Custom:
                                                        case MMLStyle.MXDRV:
                                                        case MMLStyle.NRTDRV:
                                                        case MMLStyle.PMD:
                                                        case MMLStyle.Mml2vgm:
                                                            str += ((settings.noteRest.OctaveDirection == 0) ? ">" : "<");
                                                            break;

                                                        default:
                                                            str += ">";
                                                            break;
                                                        }
                                                    }
                                                }
                                                else if (dif < 0)
                                                {
                                                    for (int j = 0; j > dif; j--)
                                                    {
                                                        switch (mml.Style)
                                                        {
                                                        case MMLStyle.Custom:
                                                        case MMLStyle.MXDRV:
                                                        case MMLStyle.NRTDRV:
                                                        case MMLStyle.PMD:
                                                        case MMLStyle.Mml2vgm:
                                                            str += ((settings.noteRest.OctaveDirection == 0) ? "<" : ">");
                                                            break;

                                                        default:
                                                            str += "<";
                                                            break;
                                                        }
                                                    }
                                                }
                                            }
                                            isNewLineNote = true;
                                        }
                                        prevNote = note;
                                    }


                                    str += c.ToString(settings, part.SoundModule);


                                    if (bar.CommandList.Last.Value != c)
                                    {
                                        if (c.CommandRelation.HasFlag(MMLCommandRelation.NextControl))
                                        {
                                            str += " ";
                                        }
                                        else if (c is ControlCommand && !c.CommandRelation.HasFlag(MMLCommandRelation.NextControl))
                                        {
                                            str += " ";
                                        }
                                    }
                                }
                            }


                            if (bar == part.BarList.Last())
                            {
                                if (!needPartName)
                                {
                                    str += Environment.NewLine;
                                }
                                str += Environment.NewLine;
                            }
                            else
                            {
                                if (!needPartName)
                                {
                                    str += bar.SeperateSign;
                                    if (bar.SeperateSign == Environment.NewLine)
                                    {
                                        isNewLineNote = false;
                                        needPartName  = true;
                                    }
                                }
                            }


                            sw.Write(str);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format(Resources.ErrorMMLFailed, path), ex);
            }
        }
コード例 #6
0
 public override void SetLfoAtKeyOn(partPage page, MML mml)
 {
 }
コード例 #7
0
 public override void SetVolume(partPage page, MML mml)
 {
 }
コード例 #8
0
 public override void SetKeyOff(partPage page, MML mml)
 {
 }
コード例 #9
0
 public override void SetFNum(partPage page, MML mml)
 {
 }
コード例 #10
0
 public override int GetFNum(partPage page, MML mml, int octave, char cmd, int shift)
 {
     return(0);
 }
コード例 #11
0
 public override void SetToneDoubler(partPage page, MML mml)
 {
 }
コード例 #12
0
 public override void CmdInstrument(partPage page, MML mml)
 {
 }
コード例 #13
0
 public override void CmdLoopExtProc(partPage page, MML mml)
 {
 }
コード例 #14
0
 public override void CmdY(partPage page, MML mml)
 {
 }
コード例 #15
0
        private void saveButton_Click(object sender, EventArgs e)
        {
            try
            {
                using (var sfd = new SaveFileDialog())
                {
                    sfd.Title            = Resources.ExportAs;
                    sfd.FileName         = Path.GetFileName(outputMMLTextBox.Text);
                    sfd.InitialDirectory = Path.GetDirectoryName(outputMMLTextBox.Text);
                    sfd.RestoreDirectory = true;

                    switch (settings.mmlExpression.MMLStyle)
                    {
                    case MMLStyle.Custom:
                        sfd.Filter = "All File (*.*)|*.*";
                        break;

                    case MMLStyle.FMP7:
                        sfd.Filter = "MWI File (*.mwi)|*.mwi";
                        break;

                    case MMLStyle.FMP:
                        sfd.Filter      = "MPI File (*.mpi)|*.mpi|MVI File (*.mvi)|*.mvi|MZI File (*.mzi)|*.mzi";
                        sfd.FilterIndex = settings.mmlExpression.ExtensionFMP;
                        break;

                    case MMLStyle.MXDRV:
                        sfd.Filter = "MUS File (*.mus)|*.mus";
                        break;

                    case MMLStyle.PMD:
                    case MMLStyle.NRTDRV:
                        sfd.Filter = "MML File (*.mml)|*.mml";
                        break;

                    case MMLStyle.MUCOM88:
                        sfd.Filter = "MUC File (*.muc)|*.muc";
                        break;

                    case MMLStyle.Mml2vgm:
                        sfd.Filter = "GWI File (*.gwi)|*.gwi";
                        break;

                    default:
                        break;
                    }

                    if (sfd.ShowDialog() == DialogResult.OK)
                    {
                        outputMMLTextBox.Text = sfd.FileName;

                        if (settings.mmlExpression.MMLStyle == MMLStyle.Custom)
                        {
                            settings.mmlExpression.ExtensionCustom = Path.GetExtension(sfd.FileName);
                        }
                        else if (settings.mmlExpression.MMLStyle == MMLStyle.FMP)
                        {
                            settings.mmlExpression.ExtensionFMP = sfd.FilterIndex;
                        }
                    }
                    else
                    {
                        return;
                    }
                }

                splitContainer2.Enabled = false;

                toolStripStatusLabel1.Text = Resources.StatusBarArrange;
                statusStrip1.Update();
                var modifier = MusicDataModifier.Factory(settings.mmlExpression.MMLStyle);
                List <NotesStatus> statusList = null;
                foreach (TreeNode tn in treeView1.Nodes)
                {
                    if (tn.Tag is OutputPartPanel)
                    {
                        statusList = ((OutputPartPanel)tn.Tag).GetOutputPartSettings();
                        break;
                    }
                }
                Intermediate modMusic = modifier.Modify(modTBMusic, settings, statusList);

                IntermediateToMMLConverter converter = IntermediateToMMLConverter.Factory(settings.mmlExpression.MMLStyle);
                MML mml = converter.Convert(modMusic, settings, statusList);

                toolStripStatusLabel1.Text = Resources.StatusBarExport;
                statusStrip1.Update();
                var printer = new MMLPrinter();
                printer.Print(mml, outputMMLTextBox.Text, settings);

                toolStripStatusLabel1.Text = Resources.StatusBarComplete;
                statusStrip1.Update();
                MessageBox.Show(Resources.SuccessText, Resources.SuccessTitle, MessageBoxButtons.OK, MessageBoxIcon.None);
            }
            catch (Exception ex)
            {
                toolStripStatusLabel1.Text = Resources.StatusBarFailed;
                statusStrip1.Update();
                MessageBox.Show(ex.Message, Resources.FailedTitle, MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            finally
            {
                SetModifiedMusicData();
                toolStripStatusLabel1.Text = Resources.StatusBarReady;
                splitContainer2.Enabled    = true;
            }
        }
コード例 #16
0
        public static async Task Main(string[] args)
        {
            Engine = new FixedTickEngine(144);

#if WinForm
            GameView2D view = new GameView2D(new Drawer2DSystemDrawing(), 240, 160, 4, 4, Color.FromArgb(0, Color.Magenta), 2);
#endif
#if Avalonia
            var        drawer = new Drawer2DAvalonia();
            GameView2D view   = new GameView2D(drawer, 240, 160, 4, 4, Color.FromArgb(0, Color.Transparent));
#endif
            view.ScrollTop     = view.Height / 2;
            view.ScrollBottom  = view.Height / 2 - 16;
            view.ScrollLeft    = view.Width / 2;
            view.ScrollRight   = view.Width / 2 - 16;
            Engine.TickEnd(0) += view.Tick;
            Engine.SetView(0, view);
            Engine.SetLocation(0, Location.Load("GridWalkRPG.Maps.map.dat"));
#if WinForm
            Frame = new GameFrame(new WinFormWindowBuilder(), 0, 0, 240, 160, 4, 4);
#endif
#if Avalonia
            Frame = new GameFrame(
                new AvaloniaWindowBuilder()
                //.TopMost(true)
                //.Decorations(Avalonia.Controls.SystemDecorations.None)
                .Transparency(Avalonia.Controls.WindowTransparencyLevel.Transparent)
                .StartupLocation(Avalonia.Controls.WindowStartupLocation.CenterScreen)
                .CanResize(false)
                .ShowInTaskBar(false),
                0, 0, 240, 160, 4, 4);
#endif
            Engine.DrawEnd(0) += Frame.DrawHandle;
            Frame.Start();

            await Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() =>
            {
                Frame.SetBounds(0, 0, 2560, 1440);
                view.Resize(2560, 1440);
            });

            var frame2 = new GameFrame(
                new AvaloniaWindowBuilder()
                .TopMost(true)
                .StartupLocation(Avalonia.Controls.WindowStartupLocation.CenterScreen),
                0, 0, 240, 160, 4, 4);
            Engine.DrawEnd(0) += (s, v) => frame2.DrawHandle(s, v);
            frame2.Start();

            WindowsKeyController controller = new WindowsKeyController(keymap);
            Engine.AddController(0, controller);

            Frame.Window.Hook(controller);

            DescriptionPlayer dp     = new DescriptionPlayer(new Sprite("circle", "Sprites.circle.png", 16, 16), 48, 48);
            Entity            player = new Entity(dp);
            Guid          playerId   = player.Id;
            PlayerActions pActions   = new PlayerActions(Engine.GetControllerIndex(0, controller));
            Engine.TickEnd(0) += (s, e) => Entity.Entities[playerId].TickAction = pActions.TickAction;
            player.TickAction  = pActions.TickAction;
            Engine.AddEntity(0, player);

#if Avalonia
            //AvaloniaWindowBuilder.MakeTransparent(Frame, true);

            //dp.AddMovementListener(d => AvaloniaWindowBuilder.SetWindowRegion(Frame, d.X - (Engine.View as GameView2D).ViewBounds.X, d.Y - (Engine.View as GameView2D).ViewBounds.Y, d.Width, d.Height));

            var points = new AvaloniaWindowBuilder.Point[] {
                new AvaloniaWindowBuilder.Point {
                },
                new AvaloniaWindowBuilder.Point {
                },
                new AvaloniaWindowBuilder.Point {
                },
                new AvaloniaWindowBuilder.Point {
                },
            };

            //dp.AddMovementListener(d => {
            //    points[0].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X;
            //    points[0].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y;

            //    points[1].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X;
            //    points[1].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y - 10;

            //    points[2].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 10;
            //    points[2].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y - 10;

            //    points[3].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 20;
            //    points[3].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y + 20;

            //    for (int i = 0; i < points.Length; i++)
            //    {
            //        points[i].x *= 4;
            //        points[i].y *= 4;
            //    }

            //    AvaloniaWindowBuilder.SetWindowRegion(Frame, ref points);
            //});

            var pointarray = new AvaloniaWindowBuilder.Point[][] {
                new AvaloniaWindowBuilder.Point[] {
                    new AvaloniaWindowBuilder.Point(),
                    new AvaloniaWindowBuilder.Point(),
                    new AvaloniaWindowBuilder.Point(),
                    new AvaloniaWindowBuilder.Point(),
                },
                new AvaloniaWindowBuilder.Point[] {
                    new AvaloniaWindowBuilder.Point(),
                    new AvaloniaWindowBuilder.Point(),
                    new AvaloniaWindowBuilder.Point(),
                    new AvaloniaWindowBuilder.Point(),
                },
            };

            //dp.AddMovementListener(d =>
            //{
            //    pointarray[0][0].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X;
            //    pointarray[0][0].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y;
            //    pointarray[0][1].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X;
            //    pointarray[0][1].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y - 10;
            //    pointarray[0][2].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 10;
            //    pointarray[0][2].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y - 10;
            //    pointarray[0][3].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 20;
            //    pointarray[0][3].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y + 20;

            //    pointarray[1][0].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 20;
            //    pointarray[1][0].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y + 20;
            //    pointarray[1][1].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 30;
            //    pointarray[1][1].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y + 40;
            //    pointarray[1][2].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 30;
            //    pointarray[1][2].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y + 30;
            //    pointarray[1][3].x = (int)d.X - (Engine.View as GameView2D).ViewBounds.X + 20;
            //    pointarray[1][3].y = (int)d.Y - (Engine.View as GameView2D).ViewBounds.Y + 30;

            //    for (int p = 0; p < pointarray.Length; p++)
            //    {
            //        for (int i = 0; i < pointarray[p].Length; i++)
            //        {
            //            pointarray[p][i].x *= 4;
            //            pointarray[p][i].y *= 4;
            //        }
            //    }

            //    AvaloniaWindowBuilder.SetWindowRegion(Frame, ref pointarray);
            //});

            short prevState = AvaloniaWindowBuilder.GetKeyState(0xA1);
            Engine.TickEnd(0) += (s, e) =>
            {
                short state = AvaloniaWindowBuilder.GetKeyState(0xA1);
                if (prevState != state)
                {
                    Console.WriteLine(state);
                    if (state != 0 && state != 1)
                    {
                        AvaloniaWindowBuilder.MakeTransparent(Frame, false);
                    }
                    else
                    {
                        AvaloniaWindowBuilder.MakeTransparent(Frame, true);
                    }
                }

                prevState = state;
            };
#endif

            view.Follow(player.Description as Description2D);
            Engine.TickEnd(0) += (s, e) => view.Follow(Entity.Entities[playerId].Description as Description2D);


            MML mml = new MML(new string[] {
                ////// Good // https://www.reddit.com/r/archebards/comments/26rjdt/ocarina_of_time/
                ////"r1l8<faaafaaafaaafaaaegggeggcegggeggcfaaafaaafaaafaaaegggeggcegggeggc1",
                ////"r1l8>fab4fab4fab>ed4c-c<bge2&edege2.fab4fab4fab>ed4c-ce<bg2&gbgde1",
                ////"r1l2<ffffccccffffcccc"

                // Very good // https://www.gaiaonline.com/guilds/viewtopic.php?page=1&t=23690909#354075091
                "l16o3f8o4crcrcro3f8o4crcrcro3f8o4crcrcro3f8o4crcro3cre8o4crcrcro3e8o4crcrcro3e8o4crcrcro3e8o4crcro3c8f8o4crcrcro3f8o4crcrcro3f8o4crcrcro3f8o4crcro3cro3e8o4crcrcro3e8o4crcrcro3e8o4crcrcro3e8o4crcrc8o3drardraro2gro3gro2gro3grcro4cro3cro4cro2aro3aro2aro3aro3drardraro2gro3gro2gro3grcro4cro3cro4cro2aro3aro2aro3aro3drardraro2gro3gro2gro3grcro4cro3cro4cro2aro3aro2aro3aro3drararrrdrararrrcrbrbrrrcrbrbrrrerarrrarerarrrarerg#rg#rg#rg#rrre&er",
                "l16o5frarb4frarb4frarbr>erd4<b8>cr<brgre2&e8drergre2&e4frarb4frarb4frarbr>erd4<b8>crer<brg2&g8brgrdre2&e4r1r1frgra4br>crd4e8frg2&g4r1r1<f8era8grb8ar>c8<br>d8cre8drf8er<b>cr<ab1&b2r4e&e&er",
                "l16r1r1r1r1r1r1r1r1o4drerf4grarb4>c8<bre2&e4drerf4grarb4>c8dre2&e4<drerf4grarb4>c8<bre2&e4d8crf8erg8fra8grb8ar>c8<br>d8crefrde1&e2r4"
            });
            //Frame.PlayTrack(new AvaloniaTrack(mml));

            TileMap map = Engine.Location(0).Description as TileMap;

            if (map != null)
            {
                // This is a hack to make the walls spawn where tree tiles are.
                for (int x = 0; x < map.Width; x += 16)
                {
                    for (int y = 0; y < map.Height; y += 16)
                    {
                        switch (map[x / map.Sprite.Width, y / map.Sprite.Height])
                        {
                        case 3:
                        case 4:
                        case 19:
                        case 20:
                            Engine.Location(0).AddEntity(new Entity(new WallDescription(x, y, 16, 16)));
                            break;
                        }
                    }
                }
            }

            watchSecond = new Stopwatch();
            watchSecond.Start();
            watchTickTime = new Stopwatch();

            Engine.TickEnd(0)   += TickInfo;
            Engine.TickStart(0) += TickTimer;
            Engine.TickEnd(0)   += TickTimer;
            Engine.TickEnd(0)   += (s, e) =>
            {
                states.Enqueue(Engine.Serialize());
                if (states.Count > 60)
                {
                    states.Dequeue();
                }
            };

            Engine.Start();

            while (true)
            {
                await Task.Delay(TimeSpan.FromSeconds(1));
            }
        }