Exemple #1
0
        private void SetupFormat(AssemblyFormat format)
        {
            switch (format)
            {
            case AssemblyFormat.NESASM:
                db = ".db";
                dw = ".dw";
                ll = ".";
                lo = "LOW";
                hi = "HIGH";
                break;

            case AssemblyFormat.CA65:
                db = ".byte";
                dw = ".word";
                ll = "@";
                lo = ".lobyte";
                hi = ".hibyte";
                break;

            case AssemblyFormat.ASM6:
                db = "db";
                dw = "dw";
                ll = "@";
                lo = "<";
                hi = ">";
                break;
            }
        }
Exemple #2
0
        private void ExportFamiTone2Music(bool famiStudio)
        {
            if (!canExportToSoundEngine)
            {
                return;
            }

            var props = dialog.GetPropertyPage(famiStudio ? (int)ExportFormat.FamiStudioMusic : (int)ExportFormat.FamiTone2Music);

            var separate        = props.GetPropertyValue <bool>(1);
            var songIds         = GetSongIds(props.GetPropertyValue <bool[]>(5));
            var kernel          = famiStudio ? FamiToneKernel.FamiStudio : FamiToneKernel.FamiTone2;
            var exportFormat    = AssemblyFormat.GetValueForName(props.GetPropertyValue <string>(0));
            var ext             = exportFormat == AssemblyFormat.CA65 ? "s" : "asm";
            var songNamePattern = props.GetPropertyValue <string>(2);
            var dpcmNamePattern = props.GetPropertyValue <string>(3);
            var generateInclude = props.GetPropertyValue <bool>(4);

            if (separate)
            {
                var folder = lastExportFilename != null ? lastExportFilename : PlatformUtils.ShowBrowseFolderDialog("Select the export folder", ref Settings.LastExportFolder);

                if (folder != null)
                {
                    foreach (var songId in songIds)
                    {
                        var song = project.GetSong(songId);
                        var formattedSongName = songNamePattern.Replace("{project}", project.Name).Replace("{song}", song.Name);
                        var formattedDpcmName = dpcmNamePattern.Replace("{project}", project.Name).Replace("{song}", song.Name);
                        var songFilename      = Path.Combine(folder, Utils.MakeNiceAsmName(formattedSongName) + "." + ext);
                        var dpcmFilename      = Path.Combine(folder, Utils.MakeNiceAsmName(formattedDpcmName) + ".dmc");
                        var includeFilename   = generateInclude ? Path.ChangeExtension(songFilename, null) + "_songlist.inc" : null;

                        Log.LogMessage(LogSeverity.Info, $"Exporting song '{song.Name}' as separate assembly files.");

                        FamitoneMusicFile f = new FamitoneMusicFile(kernel, true);
                        f.Save(project, new int[] { songId }, exportFormat, true, songFilename, dpcmFilename, includeFilename, MachineType.Dual);
                    }

                    lastExportFilename = folder;
                }
            }
            else
            {
                var engineName = famiStudio ? "FamiStudio" : "FamiTone2";
                var filename   = lastExportFilename != null ? lastExportFilename : PlatformUtils.ShowSaveFileDialog($"Export {engineName} Assembly Code", $"{engineName} Assembly File (*.{ext})|*.{ext}", ref Settings.LastExportFolder);
                if (filename != null)
                {
                    var includeFilename = generateInclude ? Path.ChangeExtension(filename, null) + "_songlist.inc" : null;

                    Log.LogMessage(LogSeverity.Info, $"Exporting all songs to a single assembly file.");

                    FamitoneMusicFile f = new FamitoneMusicFile(kernel, true);
                    f.Save(project, songIds, exportFormat, false, filename, Path.ChangeExtension(filename, ".dmc"), includeFilename, MachineType.Dual);

                    lastExportFilename = filename;
                }
            }
        }
Exemple #3
0
        public void Reset()
        {
            ObjectFiles = new List <string>();
            Archives    = new List <string>();
            ZinniaFiles = new List <string>();
            Assemblies  = new List <AssemblyPath>();
            IncBins     = new List <IncBinReference>();

            Dir      = ZinniaLib = Entry = OutFile = null;
            Arch     = null;
            Language = null;
            State    = null;
            Format   = AssemblyFormat.Unknown;
        }
Exemple #4
0
        public bool Save(Project originalProject, int[] songIds, AssemblyFormat format, bool separateSongs, string filename, string dmcFilename, MachineType machine)
        {
            this.machine = machine;
            SetupProject(originalProject, songIds);
            SetupFormat(format);
            CleanupEnvelopes();
            OutputHeader(separateSongs);
            OutputInstruments();
            OutputTempoEnvelopes();
            OutputSamples(filename, dmcFilename);

            for (int i = 0; i < project.Songs.Count; i++)
            {
                ProcessAndOutputSong(i);
            }

            File.WriteAllLines(filename, lines);

            return(true);
        }
        private void ExportFamiTone2Sfx(bool famiStudio)
        {
            var props           = dialog.GetPropertyPage(famiStudio ? (int)ExportFormat.FamiStudioSfx : (int)ExportFormat.FamiTone2Sfx);
            var exportFormat    = AssemblyFormat.GetValueForName(props.GetPropertyValue <string>(0));
            var ext             = exportFormat == AssemblyFormat.CA65 ? "s" : "asm";
            var mode            = MachineType.GetValueForName(props.GetPropertyValue <string>(1));
            var engineName      = famiStudio ? "FamiStudio" : "FamiTone2";
            var generateInclude = props.GetPropertyValue <bool>(2);
            var songIds         = GetSongIds(props.GetPropertyValue <bool[]>(3));

            var filename = lastExportFilename != null ? lastExportFilename : PlatformUtils.ShowSaveFileDialog($"Export {engineName} Code", $"{engineName} Assembly File (*.{ext})|*.{ext}", ref Settings.LastExportFolder);

            if (filename != null)
            {
                var includeFilename = generateInclude ? Path.ChangeExtension(filename, null) + "_sfxlist.inc" : null;

                FamitoneSoundEffectFile f = new FamitoneSoundEffectFile();
                f.Save(project, songIds, exportFormat, mode, famiStudio ? FamiToneKernel.FamiStudio : FamiToneKernel.FamiTone2, filename, includeFilename);
                lastExportFilename = filename;
            }
        }
Exemple #6
0
        private void SetupFormat(AssemblyFormat format)
        {
            switch (format)
            {
            case AssemblyFormat.NESASM:
                db = ".db";
                dw = ".dw";
                ll = ".";
                break;

            case AssemblyFormat.CA65:
                db = ".byte";
                dw = ".word";
                ll = "@";
                break;

            case AssemblyFormat.ASM6:
                db = "db";
                dw = "dw";
                ll = "@";
                break;
            }
        }
Exemple #7
0
        public bool Save(Project project, int[] songIds, AssemblyFormat format, MachineType mode, string filename)
        {
            SetupFormat(format);

            var modeStrings = new List <string>();

            if (mode == MachineType.NTSC || mode == MachineType.Dual)
            {
                modeStrings.Add("ntsc");
            }
            if (mode == MachineType.PAL || mode == MachineType.Dual)
            {
                modeStrings.Add("pal");
            }

            var lines = new List <string>();

            lines.Add($";this file for FamiTone2 libary generated by FamiStudio\n");
            lines.Add($"sounds:");

            lines.Add($"\t{dw} {ll}{modeStrings[0]}");
            lines.Add($"\t{dw} {ll}{modeStrings[1 % modeStrings.Count]}");

            foreach (var str in modeStrings)
            {
                lines.Add($"{ll}{str}:");
                foreach (var songId in songIds)
                {
                    var song = project.GetSong(songId);
                    lines.Add($"\t{dw} {ll}sfx_{str}_{Utils.MakeNiceAsmName(song.Name)}");
                }
                lines.Add("");
            }

            foreach (var str in modeStrings)
            {
                foreach (var songId in songIds)
                {
                    var song = project.GetSong(songId);

                    var regPlayer = new RegisterPlayer();
                    var writes    = regPlayer.GetRegisterValues(song, str == "pal");

                    var lastChangeFrame   = 0;
                    var lastZeroVolumeIdx = -1;
                    var volumeAllZero     = true;
                    var volume            = new int[4];
                    var regs   = new int[32];
                    var effect = new List <byte>();

                    for (int i = 0; i < regs.Length; i++)
                    {
                        regs[i] = -1;
                    }

                    regs[0x00] = 0x30;
                    regs[0x04] = 0x30;
                    regs[0x08] = 0x00;
                    regs[0x0c] = 0x30;

                    foreach (var reg in writes)
                    {
                        if (reg.Register == NesApu.APU_PL1_VOL ||
                            reg.Register == NesApu.APU_PL1_LO ||
                            reg.Register == NesApu.APU_PL1_HI ||
                            reg.Register == NesApu.APU_PL2_VOL ||
                            reg.Register == NesApu.APU_PL2_LO ||
                            reg.Register == NesApu.APU_PL2_HI ||
                            reg.Register == NesApu.APU_TRI_LINEAR ||
                            reg.Register == NesApu.APU_TRI_LO ||
                            reg.Register == NesApu.APU_TRI_HI ||
                            reg.Register == NesApu.APU_NOISE_VOL ||
                            reg.Register == NesApu.APU_NOISE_LO)
                        {
                            if (regs[reg.Register - 0x4000] != reg.Value)
                            {
                                if (reg.FrameNumber != lastChangeFrame)
                                {
                                    int numEmptyFrames = reg.FrameNumber - lastChangeFrame;

                                    while (numEmptyFrames >= 0)
                                    {
                                        effect.Add((byte)(Math.Min(numEmptyFrames, 127)));
                                        numEmptyFrames -= 127;
                                    }
                                }

                                switch (reg.Register)
                                {
                                case 0x4000: volume[0] = reg.Value & 0x0f; break;

                                case 0x4004: volume[1] = reg.Value & 0x0f; break;

                                case 0x4008: volume[2] = reg.Value & 0x7f; break;

                                case 0x400c: volume[3] = reg.Value & 0x0f; break;
                                }

                                if (!volumeAllZero)
                                {
                                    if (volume[0] == 0 && volume[1] == 0 && volume[2] == 0 && volume[3] == 0)
                                    {
                                        volumeAllZero     = true;
                                        lastZeroVolumeIdx = effect.Count();
                                    }
                                }
                                else
                                {
                                    if (volume[0] != 0 || volume[1] != 0 || volume[2] != 0 || volume[3] != 0)
                                    {
                                        volumeAllZero = false;
                                    }
                                }

                                effect.Add(RegisterMap[reg.Register - 0x4000]);
                                effect.Add((byte)reg.Value);

                                regs[reg.Register - 0x4000] = reg.Value;

                                lastChangeFrame = reg.FrameNumber;
                            }
                        }
                    }

                    if (!volumeAllZero)
                    {
                        int numEmptyFrames = writes[writes.Length - 1].FrameNumber - lastChangeFrame;

                        while (numEmptyFrames > 0)
                        {
                            effect.Add((byte)(Math.Min(numEmptyFrames, 127)));
                            numEmptyFrames -= 127;
                        }
                    }
                    else
                    {
                        effect.RemoveRange(lastZeroVolumeIdx, effect.Count - lastZeroVolumeIdx);
                    }

                    // TODO: Error management!
                    if (effect.Count > 255)
                    {
                        effect.RemoveRange(lastZeroVolumeIdx, effect.Count - 255);
                    }

                    effect.Add(0);

                    lines.Add($"{ll}sfx_{str}_{Utils.MakeNiceAsmName(song.Name)}:");

                    for (int i = 0; i < (effect.Count + 15) / 16; i++)
                    {
                        lines.Add($"\t{db} {string.Join(",", effect.Skip(i * 16).Take(Math.Min(16, effect.Count - i * 16)).Select(x => $"${x:x2}"))}");
                    }
                }
            }

            File.WriteAllLines(filename, lines.ToArray());

            return(true);
        }
Exemple #8
0
        public bool AdjustSettings()
        {
            if (Language == null)
            {
                Language = new Languages.Zinnia.ZinniaLanguage();
            }
            if (Arch == null)
            {
                Arch = new x86.x86Architecture();
            }
            if (Format == AssemblyFormat.Unknown)
            {
                Format = AssemblyFormat.Application;
            }
            if (Format == AssemblyFormat.Application && Entry == null)
            {
                Entry = "Main";
            }

            if (DefaultLibs)
            {
                Assemblies.Add(new AssemblyPath("ZinniaCore", true));
                Assemblies.Add(new AssemblyPath("BlitzMax", true));
            }

            if (Dir == null)
            {
                if (OutFile == null)
                {
                    Dir = Directory.GetCurrentDirectory();
                }
                else
                {
                    Dir = Path.GetDirectoryName(Path.GetFullPath(OutFile));
                }
            }

            if (State == null)
            {
                State = new CompilerState(this, Arch, Language);
            }
            else
            {
                State.Messages.Messages.Clear();
                State.Arch     = Arch;
                State.Language = Language;
            }

            State.Entry  = Entry;
            State.Format = ImageFormat.MSCoff;

            OutDir = Path.Combine(Dir, ".zinnia");
            if (!Directory.Exists(OutDir))
            {
                Directory.CreateDirectory(OutDir);
            }

            if (OutFile == null)
            {
                if (Format == AssemblyFormat.Object)
                {
                    OutFile = Path.Combine(OutDir, "Assembly.o");
                }
                else if (Format == AssemblyFormat.Archive)
                {
                    OutFile = Path.Combine(OutDir, "Assembly.a");
                }
                else if (Format == AssemblyFormat.Application)
                {
                    OutFile = Path.Combine(OutDir, "Assembly.exe");
                }
                else
                {
                    throw new ApplicationException();
                }
            }

            if (ZinniaLib == null)
            {
                ZinniaLib = Path.Combine(OutDir, "Assembly.zlib");
            }
            if (AsmFile == null)
            {
                AsmFile = Path.Combine(OutDir, "Assembly.s");
            }

            if (ObjFile == null)
            {
                if (Format == AssemblyFormat.Object)
                {
                    ObjFile = OutFile;
                }
                else
                {
                    ObjFile = Path.Combine(OutDir, "Assembly.o");
                }
            }

            return(true);
        }
Exemple #9
0
        public bool ProcessArgs(string[] Args)
        {
            ExecuteApp = false;

            for (var i = 0; i < Args.Length; i++)
            {
                if (Args[i] != null && Args[i].Length > 1 && (Args[i][0] == '-' || Args[i][0] == '/'))
                {
                    var Str = Args[i].Substring(1);
                    Args[i] = null;

                    if (Str[0] == 'l')
                    {
                        Assemblies.Add(new AssemblyPath(Str.Substring(1), true));
                    }
                    else if (Str == "incbin")
                    {
                        if (i + 2 >= Args.Length || Args[i + 2][0] == '-')
                        {
                            var File = GetString(Args, i + 1);
                            if (File == null)
                            {
                                return(false);
                            }

                            var Name = Path.GetFileNameWithoutExtension(File);
                            IncBins.Add(new IncBinReference(Name, File));
                        }
                        else
                        {
                            var Name = GetString(Args, i + 1);
                            if (Name == null)
                            {
                                return(false);
                            }

                            var File = GetString(Args, i + 2);
                            if (File == null)
                            {
                                return(false);
                            }

                            IncBins.Add(new IncBinReference(Name, File));
                        }
                    }
                    else if (Str == "nodefaultlib")
                    {
                        DefaultLibs = false;
                    }
                    else if (Str == "x")
                    {
                        ExecuteApp = true;
                    }
                    else if (Str == "zlib")
                    {
                        if ((ZinniaLib = GetString(Args, i + 1)) == null)
                        {
                            return(false);
                        }
                    }
                    else if (Str == "entry")
                    {
                        if ((Entry = GetString(Args, i + 1)) == null)
                        {
                            return(false);
                        }
                    }
                    else if (Str == "out")
                    {
                        if ((OutFile = GetString(Args, i + 1)) == null)
                        {
                            return(false);
                        }
                    }
                    else if (Str == "dir")
                    {
                        if ((Dir = GetString(Args, i + 1)) == null)
                        {
                            return(false);
                        }
                    }
                    else if (Str == "x86")
                    {
                        Arch = new x86.x86Architecture();
                    }
                    else if (Str == "x86_64")
                    {
                        Arch = new x86.x86Architecture(x86.x86Extensions.Default64);
                    }
                    else if (Str == "zinnialang")
                    {
                        Language = new Languages.Zinnia.ZinniaLanguage();
                    }                    /*
                                          * else if (Str == "cslang")
                                          * {
                                          *     Language = new Languages.CSharp.CSharpLanguage();
                                          * }*/
                    else if (Str == "format")
                    {
                        if (Format != AssemblyFormat.Unknown)
                        {
                            Console.WriteLine("Format is specified multiple");
                            return(false);
                        }

                        var S = GetString(Args, i + 1);
                        if (S == null)
                        {
                            return(false);
                        }
                        else if (S == "app")
                        {
                            Format = AssemblyFormat.Application;
                        }
                        else if (S == "arc")
                        {
                            Format = AssemblyFormat.Archive;
                        }
                        else if (S == "obj")
                        {
                            Format = AssemblyFormat.Object;
                        }

                        if (Format == AssemblyFormat.Unknown)
                        {
                            Console.WriteLine("Unknown assembly format: " + S);
                            return(false);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Unknown argument: " + Str);
                        return(false);
                    }
                }
            }

            return(AdjustSettings());
        }
Exemple #10
0
        public async Task <ProcessResult> ObjCopy(IConsole console, IProject project, LinkResult linkResult, AssemblyFormat format)
        {
            var result = new ProcessResult();

            var commandName = Path.Combine(BinDirectory, $"{SizePrefix}objcopy" + Platform.ExecutableExtension);

            if (PlatformSupport.CheckExecutableAvailability(commandName, BinDirectory))
            {
                string formatArg = "binary";

                switch (format)
                {
                case AssemblyFormat.Binary:
                    formatArg = "binary";
                    break;

                case AssemblyFormat.IntelHex:
                    formatArg = "ihex";
                    break;
                }

                string outputExtension = ".bin";

                switch (format)
                {
                case AssemblyFormat.Binary:
                    outputExtension = ".bin";
                    break;

                case AssemblyFormat.IntelHex:
                    outputExtension = ".hex";
                    break;

                case AssemblyFormat.Elf32:
                    outputExtension = ".elf";
                    break;
                }

                var arguments = $"-O {formatArg} {linkResult.Executable} {Path.GetDirectoryName(linkResult.Executable)}{Platform.DirectorySeperator}{Path.GetFileNameWithoutExtension(linkResult.Executable)}{outputExtension}";

                console.WriteLine($"Converting to {format.ToString()}");

                result.ExitCode = PlatformSupport.ExecuteShellCommand(commandName, arguments, (s, e) => console.WriteLine(e.Data), (s, e) => console.WriteLine(e.Data), false, string.Empty, false);
            }
            else
            {
                console.WriteLine("Unable to find tool (" + commandName + ") check project compiler settings.");
                result.ExitCode = -1;
            }

            return(result);
        }
        public async Task<ProcessResult> ObjCopy(IConsole console, IProject project, LinkResult linkResult, AssemblyFormat format)
        {
            var result = new ProcessResult();

            var commandName = Path.Combine(BinDirectory, $"{SizePrefix}objcopy" + Platform.ExecutableExtension);

            if(PlatformSupport.CheckExecutableAvailability(commandName, BinDirectory))
            {
                string formatArg = "binary";

                switch (format)
                {
                    case AssemblyFormat.Binary:
                        formatArg = "binary";
                        break;

                    case AssemblyFormat.IntelHex:
                        formatArg = "ihex";
                        break;
                }

                string outputExtension = ".bin";

                switch (format)
                {
                    case AssemblyFormat.Binary:
                        outputExtension = ".bin";
                        break;

                    case AssemblyFormat.IntelHex:
                        outputExtension = ".hex";
                        break;

                    case AssemblyFormat.Elf32:
                        outputExtension = ".elf";
                        break;
                }

                var arguments = $"-O {formatArg} {linkResult.Executable} {Path.GetDirectoryName(linkResult.Executable)}{Platform.DirectorySeperator}{Path.GetFileNameWithoutExtension(linkResult.Executable)}{outputExtension}";

                console.WriteLine($"Converting to {format.ToString()}");

                result.ExitCode = PlatformSupport.ExecuteShellCommand(commandName, arguments, (s, e) => console.WriteLine(e.Data), (s, e) => console.WriteLine(e.Data), false, string.Empty, false);
            }
            else
            {
                console.WriteLine("Unable to find tool (" + commandName + ") check project compiler settings.");
                result.ExitCode = -1;
            }

            return result;
        }