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; } }
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; } } }
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; }
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; } }
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; } }
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); }
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); }
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()); }
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; }