diff --git a/UI/Debugger/Labels/BassLabelFile.cs b/UI/Debugger/Integration/BassLabelFile.cs similarity index 99% rename from UI/Debugger/Labels/BassLabelFile.cs rename to UI/Debugger/Integration/BassLabelFile.cs index 16c4a6a..24d15b5 100644 --- a/UI/Debugger/Labels/BassLabelFile.cs +++ b/UI/Debugger/Integration/BassLabelFile.cs @@ -25,6 +25,7 @@ namespace Mesen.GUI.Debugger if(!UInt32.TryParse(lineData.Substring(0, splitIndex), NumberStyles.HexNumber, null, out address)) { errorCount++; + continue; } AddressInfo absAddress = DebugApi.GetAbsoluteAddress(new AddressInfo() { Address = (int)address, Type = SnesMemoryType.CpuMemory }); diff --git a/UI/Debugger/Integration/RgbdsSymbolFile.cs b/UI/Debugger/Integration/RgbdsSymbolFile.cs new file mode 100644 index 0000000..0b7e35f --- /dev/null +++ b/UI/Debugger/Integration/RgbdsSymbolFile.cs @@ -0,0 +1,135 @@ +using Mesen.GUI.Config; +using Mesen.GUI.Debugger.Labels; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows.Forms; + +namespace Mesen.GUI.Debugger +{ + public class RgbdsSymbolFile + { + private static bool IsValidRow(string row) + { + return GetBankAddressLabel(row, out _, out _, out _); + } + + public static bool IsValidFile(string path, bool silent = false) + { + string[] content = File.ReadAllLines(path, Encoding.UTF8); + int errorCount = 0; + for(int i = 0; i < 20 && i < content.Length; i++) { + if(!IsValidRow(content[i])) { + errorCount++; + } + } + return errorCount < 5; + } + + private static bool GetBankAddressLabel(string row, out UInt32 address, out UInt32 bank, out string labelName) + { + address = 0; + bank = 0; + labelName = null; + + string lineData = row; + int commentIndex = lineData.IndexOf(';'); + if(commentIndex >= 0) { + lineData = lineData.Substring(0, commentIndex); + } + lineData = lineData.Trim(); + if(lineData.Length == 0) { + return true; + } + + int splitIndex = lineData.IndexOf(' '); + if(splitIndex < 0) { + return false; + } + + string[] bankAddressStr = lineData.Substring(0, splitIndex).Split(':'); + if(bankAddressStr.Length != 2) { + return false; + } + + if(!UInt32.TryParse(bankAddressStr[0], NumberStyles.HexNumber, null, out bank)) { + return false; + } + + if(!UInt32.TryParse(bankAddressStr[1], NumberStyles.HexNumber, null, out address)) { + return false; + } + + labelName = lineData.Substring(splitIndex + 1).Replace('.', '_'); + if(string.IsNullOrEmpty(labelName) || !LabelManager.LabelRegex.IsMatch(labelName)) { + return false; + } + return true; + } + + public static void Import(string path, bool silent = false) + { + const int prgBankSize = 0x4000; + const int wramBankSize = 0x1000; + const int sramBankSize = 0x2000; + + List labels = new List(1000); + + int errorCount = 0; + foreach(string row in File.ReadAllLines(path, Encoding.UTF8)) { + UInt32 address; + UInt32 bank; + string labelName; + + if(!GetBankAddressLabel(row, out address, out bank, out labelName)) { + errorCount++; + continue; + } else if(labelName == null) { + //Empty line/comment + continue; + } + + UInt32 fullAddress = 0; + AddressInfo absAddress; + if(address <= 0x7FFF) { + fullAddress = bank * prgBankSize + (address & (prgBankSize - 1)); + absAddress = new AddressInfo() { Address = (int)fullAddress, Type = SnesMemoryType.GbPrgRom }; + } else if(address >= 0xA000 && address <= 0xCFFF) { + fullAddress = bank * sramBankSize + (address & (sramBankSize - 1)); + absAddress = new AddressInfo() { Address = (int)fullAddress, Type = SnesMemoryType.GbCartRam }; + } else if(address >= 0xC000 && address <= 0xDFFF) { + fullAddress = bank * wramBankSize + (address & (wramBankSize - 1)); + absAddress = new AddressInfo() { Address = (int)fullAddress, Type = SnesMemoryType.GbWorkRam }; + } else { + absAddress = DebugApi.GetAbsoluteAddress(new AddressInfo() { Address = (int)address, Type = SnesMemoryType.GameboyMemory }); + } + + if(absAddress.Address >= 0) { + CodeLabel label = new CodeLabel(); + label.Address = (UInt32)absAddress.Address; + label.MemoryType = absAddress.Type; + label.Comment = ""; + label.Label = labelName; + labels.Add(label); + } else { + errorCount++; + } + } + + LabelManager.SetLabels(labels); + + if(!silent) { + string message = $"Import completed with {labels.Count} labels imported"; + if(errorCount > 0) { + message += $" and {errorCount} error(s)"; + } + MessageBox.Show(message, "Mesen-S", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + } +} diff --git a/UI/Debugger/Workspace/DebugWorkspaceManager.cs b/UI/Debugger/Workspace/DebugWorkspaceManager.cs index 9e0a99f..c21223f 100644 --- a/UI/Debugger/Workspace/DebugWorkspaceManager.cs +++ b/UI/Debugger/Workspace/DebugWorkspaceManager.cs @@ -154,7 +154,16 @@ namespace Mesen.GUI.Debugger.Workspace //Assume WLA-DX symbol files new WlaDxImporter().Import(symPath, silent); } else { - BassLabelFile.Import(symPath, silent); + RomInfo romInfo = EmuApi.GetRomInfo(); + if(romInfo.CoprocessorType == CoprocessorType.Gameboy) { + if(RgbdsSymbolFile.IsValidFile(symPath)) { + RgbdsSymbolFile.Import(symPath, silent); + } else { + BassLabelFile.Import(symPath, silent); + } + } else { + BassLabelFile.Import(symPath, silent); + } } LabelManager.RefreshLabels(); } diff --git a/UI/UI.csproj b/UI/UI.csproj index a79a1ed..ea08a8e 100644 --- a/UI/UI.csproj +++ b/UI/UI.csproj @@ -309,7 +309,8 @@ ctrlGameboyStatus.cs - + + UserControl