Debugger: Added Text Hooker (WIP)

This commit is contained in:
Sour 2018-06-23 18:29:15 -04:00
parent 5e6578a4a0
commit c2e063d5c9
29 changed files with 4061 additions and 210 deletions

View file

@ -325,6 +325,17 @@ namespace Mesen.GUI.Config
public float AssemblerFontSize = BaseControl.DefaultFontSize;
public int AssemblerZoom = 100;
public Point? TextHookerWindowLocation = null;
public bool TextHookerAutoRefresh = true;
public bool TextHookerRefreshOnBreak = true;
public int TextHookerDisplayCycle = 0;
public int TextHookerDisplayScanline = 241;
public List<CharMap> TextHookerCharMappings = new List<CharMap>();
public DakutenMode TextHookerDakutenMode = DakutenMode.OnTop;
public bool TextHookerAdjustViewportScrolling = true;
public bool TextHookerIgnoreMirroredNametables = true;
public bool TextHookerAutoCopyToClipboard = false;
public DebuggerShortcutsConfig Shortcuts = new DebuggerShortcutsConfig();
public DebugImportConfig ImportConfig = new DebugImportConfig();
@ -441,4 +452,19 @@ namespace Mesen.GUI.Config
}
}
}
public class CharMap
{
[XmlAttribute]
public string Key;
[XmlAttribute]
public string Value;
}
public enum DakutenMode
{
Ignore,
OnTheRight,
OnTop
}
}

View file

@ -67,6 +67,8 @@ namespace Mesen.GUI.Config
public XmlKeys OpenScriptWindow = Keys.Control | Keys.N;
[ShortcutName("Open Trace Logger")]
public XmlKeys OpenTraceLogger = Keys.Control | Keys.J;
[ShortcutName("Open Text Hooker")]
public XmlKeys OpenTextHooker = Keys.Control | Keys.H;
//Debugger window
[ShortcutName("Reset")]

View file

@ -0,0 +1,323 @@
namespace Mesen.GUI.Debugger.Controls
{
partial class ctrlCharacterMapping
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tlpTiles = new System.Windows.Forms.TableLayoutPanel();
this.picTiles = new System.Windows.Forms.PictureBox();
this.txtMapping0 = new System.Windows.Forms.TextBox();
this.txtMapping1 = new System.Windows.Forms.TextBox();
this.txtMapping6 = new System.Windows.Forms.TextBox();
this.txtMapping7 = new System.Windows.Forms.TextBox();
this.txtMapping8 = new System.Windows.Forms.TextBox();
this.txtMapping9 = new System.Windows.Forms.TextBox();
this.txtMapping10 = new System.Windows.Forms.TextBox();
this.txtMapping11 = new System.Windows.Forms.TextBox();
this.txtMapping12 = new System.Windows.Forms.TextBox();
this.txtMapping13 = new System.Windows.Forms.TextBox();
this.txtMapping14 = new System.Windows.Forms.TextBox();
this.txtMapping15 = new System.Windows.Forms.TextBox();
this.txtMapping2 = new System.Windows.Forms.TextBox();
this.txtMapping3 = new System.Windows.Forms.TextBox();
this.txtMapping5 = new System.Windows.Forms.TextBox();
this.txtMapping4 = new System.Windows.Forms.TextBox();
this.tlpTiles.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picTiles)).BeginInit();
this.SuspendLayout();
//
// tlpTiles
//
this.tlpTiles.ColumnCount = 17;
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTiles.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpTiles.Controls.Add(this.picTiles, 0, 0);
this.tlpTiles.Controls.Add(this.txtMapping0, 0, 1);
this.tlpTiles.Controls.Add(this.txtMapping1, 1, 1);
this.tlpTiles.Controls.Add(this.txtMapping6, 6, 1);
this.tlpTiles.Controls.Add(this.txtMapping7, 7, 1);
this.tlpTiles.Controls.Add(this.txtMapping8, 8, 1);
this.tlpTiles.Controls.Add(this.txtMapping9, 9, 1);
this.tlpTiles.Controls.Add(this.txtMapping10, 10, 1);
this.tlpTiles.Controls.Add(this.txtMapping11, 11, 1);
this.tlpTiles.Controls.Add(this.txtMapping12, 12, 1);
this.tlpTiles.Controls.Add(this.txtMapping13, 13, 1);
this.tlpTiles.Controls.Add(this.txtMapping14, 14, 1);
this.tlpTiles.Controls.Add(this.txtMapping15, 15, 1);
this.tlpTiles.Controls.Add(this.txtMapping2, 2, 1);
this.tlpTiles.Controls.Add(this.txtMapping3, 3, 1);
this.tlpTiles.Controls.Add(this.txtMapping5, 5, 1);
this.tlpTiles.Controls.Add(this.txtMapping4, 4, 1);
this.tlpTiles.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpTiles.Location = new System.Drawing.Point(0, 0);
this.tlpTiles.Margin = new System.Windows.Forms.Padding(0);
this.tlpTiles.Name = "tlpTiles";
this.tlpTiles.RowCount = 3;
this.tlpTiles.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTiles.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTiles.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpTiles.Size = new System.Drawing.Size(416, 50);
this.tlpTiles.TabIndex = 0;
//
// picTiles
//
this.tlpTiles.SetColumnSpan(this.picTiles, 16);
this.picTiles.Location = new System.Drawing.Point(0, 0);
this.picTiles.Margin = new System.Windows.Forms.Padding(0, 0, 0, 1);
this.picTiles.Name = "picTiles";
this.picTiles.Size = new System.Drawing.Size(416, 20);
this.picTiles.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.picTiles.TabIndex = 0;
this.picTiles.TabStop = false;
//
// txtMapping0
//
this.txtMapping0.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping0.Location = new System.Drawing.Point(2, 21);
this.txtMapping0.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping0.Name = "txtMapping0";
this.txtMapping0.Size = new System.Drawing.Size(22, 20);
this.txtMapping0.TabIndex = 1;
this.txtMapping0.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping0.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping1
//
this.txtMapping1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping1.Location = new System.Drawing.Point(28, 21);
this.txtMapping1.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping1.Name = "txtMapping1";
this.txtMapping1.Size = new System.Drawing.Size(22, 20);
this.txtMapping1.TabIndex = 2;
this.txtMapping1.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping1.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping6
//
this.txtMapping6.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping6.Location = new System.Drawing.Point(158, 21);
this.txtMapping6.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping6.Name = "txtMapping6";
this.txtMapping6.Size = new System.Drawing.Size(22, 20);
this.txtMapping6.TabIndex = 7;
this.txtMapping6.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping6.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping7
//
this.txtMapping7.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping7.Location = new System.Drawing.Point(184, 21);
this.txtMapping7.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping7.Name = "txtMapping7";
this.txtMapping7.Size = new System.Drawing.Size(22, 20);
this.txtMapping7.TabIndex = 8;
this.txtMapping7.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping7.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping8
//
this.txtMapping8.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping8.Location = new System.Drawing.Point(210, 21);
this.txtMapping8.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping8.Name = "txtMapping8";
this.txtMapping8.Size = new System.Drawing.Size(22, 20);
this.txtMapping8.TabIndex = 9;
this.txtMapping8.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping8.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping9
//
this.txtMapping9.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping9.Location = new System.Drawing.Point(236, 21);
this.txtMapping9.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping9.Name = "txtMapping9";
this.txtMapping9.Size = new System.Drawing.Size(22, 20);
this.txtMapping9.TabIndex = 10;
this.txtMapping9.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping9.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping10
//
this.txtMapping10.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping10.Location = new System.Drawing.Point(262, 21);
this.txtMapping10.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping10.Name = "txtMapping10";
this.txtMapping10.Size = new System.Drawing.Size(22, 20);
this.txtMapping10.TabIndex = 11;
this.txtMapping10.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping10.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping11
//
this.txtMapping11.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping11.Location = new System.Drawing.Point(288, 21);
this.txtMapping11.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping11.Name = "txtMapping11";
this.txtMapping11.Size = new System.Drawing.Size(22, 20);
this.txtMapping11.TabIndex = 12;
this.txtMapping11.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping11.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping12
//
this.txtMapping12.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping12.Location = new System.Drawing.Point(314, 21);
this.txtMapping12.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping12.Name = "txtMapping12";
this.txtMapping12.Size = new System.Drawing.Size(22, 20);
this.txtMapping12.TabIndex = 13;
this.txtMapping12.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping12.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping13
//
this.txtMapping13.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping13.Location = new System.Drawing.Point(340, 21);
this.txtMapping13.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping13.Name = "txtMapping13";
this.txtMapping13.Size = new System.Drawing.Size(22, 20);
this.txtMapping13.TabIndex = 14;
this.txtMapping13.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping13.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping14
//
this.txtMapping14.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping14.Location = new System.Drawing.Point(366, 21);
this.txtMapping14.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping14.Name = "txtMapping14";
this.txtMapping14.Size = new System.Drawing.Size(22, 20);
this.txtMapping14.TabIndex = 15;
this.txtMapping14.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping14.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping15
//
this.txtMapping15.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping15.Location = new System.Drawing.Point(392, 21);
this.txtMapping15.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping15.Name = "txtMapping15";
this.txtMapping15.Size = new System.Drawing.Size(22, 20);
this.txtMapping15.TabIndex = 16;
this.txtMapping15.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping15.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping2
//
this.txtMapping2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping2.Location = new System.Drawing.Point(54, 21);
this.txtMapping2.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping2.Name = "txtMapping2";
this.txtMapping2.Size = new System.Drawing.Size(22, 20);
this.txtMapping2.TabIndex = 6;
this.txtMapping2.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping2.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping3
//
this.txtMapping3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping3.Location = new System.Drawing.Point(80, 21);
this.txtMapping3.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping3.Name = "txtMapping3";
this.txtMapping3.Size = new System.Drawing.Size(22, 20);
this.txtMapping3.TabIndex = 3;
this.txtMapping3.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping3.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping5
//
this.txtMapping5.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping5.Location = new System.Drawing.Point(132, 21);
this.txtMapping5.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping5.Name = "txtMapping5";
this.txtMapping5.Size = new System.Drawing.Size(22, 20);
this.txtMapping5.TabIndex = 5;
this.txtMapping5.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping5.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// txtMapping4
//
this.txtMapping4.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.txtMapping4.Location = new System.Drawing.Point(106, 21);
this.txtMapping4.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0);
this.txtMapping4.Name = "txtMapping4";
this.txtMapping4.Size = new System.Drawing.Size(22, 20);
this.txtMapping4.TabIndex = 4;
this.txtMapping4.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;
this.txtMapping4.TextChanged += new System.EventHandler(this.txtMapping_TextChanged);
//
// ctrlCharacterMapping
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tlpTiles);
this.Margin = new System.Windows.Forms.Padding(0);
this.Name = "ctrlCharacterMapping";
this.Size = new System.Drawing.Size(416, 50);
this.tlpTiles.ResumeLayout(false);
this.tlpTiles.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picTiles)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tlpTiles;
private System.Windows.Forms.TextBox txtMapping0;
private System.Windows.Forms.TextBox txtMapping1;
private System.Windows.Forms.TextBox txtMapping3;
private System.Windows.Forms.TextBox txtMapping4;
private System.Windows.Forms.TextBox txtMapping5;
private System.Windows.Forms.TextBox txtMapping2;
private System.Windows.Forms.TextBox txtMapping6;
private System.Windows.Forms.TextBox txtMapping7;
private System.Windows.Forms.TextBox txtMapping8;
private System.Windows.Forms.TextBox txtMapping9;
private System.Windows.Forms.TextBox txtMapping10;
private System.Windows.Forms.TextBox txtMapping11;
private System.Windows.Forms.TextBox txtMapping12;
private System.Windows.Forms.TextBox txtMapping13;
private System.Windows.Forms.TextBox txtMapping14;
private System.Windows.Forms.TextBox txtMapping15;
public System.Windows.Forms.PictureBox picTiles;
}
}

View file

@ -0,0 +1,132 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Concurrent;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlCharacterMapping : UserControl
{
private Color _activeBgColor = Color.FromArgb(180, 250, 200);
private TextBox[] _txtMappings;
private byte[][] _tileData = new byte[16][];
private ConcurrentDictionary<string, string> _charMappings;
private static readonly uint[] _hexLookup = InitializeHexLookup();
public ctrlCharacterMapping()
{
InitializeComponent();
for(int i = 0; i < 16; i++) {
_tileData[i] = new byte[16];
}
_txtMappings = new TextBox[16] {
txtMapping0, txtMapping1, txtMapping2, txtMapping3, txtMapping4, txtMapping5, txtMapping6, txtMapping7,
txtMapping8, txtMapping9, txtMapping10, txtMapping11, txtMapping12, txtMapping13, txtMapping14, txtMapping15
};
if(Program.IsMono) {
this.SuspendLayout();
tlpTiles.SuspendLayout();
//this.picTiles.Margin = new Padding(0, 5, 0, 1);
for(int i = 0; i < 16; i++) {
_txtMappings[i].Width -= 4;
}
this.Width -= 72;
this.Height -= 4;
tlpTiles.ResumeLayout();
this.ResumeLayout();
}
}
private static uint[] InitializeHexLookup()
{
var result = new uint[256];
for(int i = 0; i < 256; i++) {
string s = i.ToString("X2");
result[i] = ((uint)s[0]) + ((uint)s[1] << 16);
}
return result;
}
private static string ToHexString(byte[] bytes)
{
char[] result = new char[bytes.Length * 2];
for(int i = 0; i < bytes.Length; i++) {
var val = _hexLookup[bytes[i]];
result[2 * i] = (char)val;
result[2 * i + 1] = (char)(val >> 16);
}
return new string(result);
}
public static string GetColorIndependentKey(byte[] tileData)
{
sbyte nextColor = 0;
byte[] colorKey = new byte[16];
sbyte[] lookupTable = new sbyte[4] { -1, -1, -1, -1 };
for(int y = 0; y < 8; y++) {
byte lowByte = tileData[y];
byte highByte = tileData[y + 8];
for(int x = 0; x < 8; x++) {
byte color = (byte)((lowByte & 0x01) | ((highByte << 1) & 0x02));
lowByte >>= 1;
highByte >>= 1;
if(lookupTable[color] == -1) {
lookupTable[color] = nextColor;
nextColor++;
}
colorKey[(y << 1) + x / 4] |= (byte)(lookupTable[color] << ((x & 0x03) << 1));
}
}
return ToHexString(colorKey);
}
public void UpdateData(byte[] chrData, int rowIndex)
{
for(int i = 0; i < 16; i++) {
Array.Copy(chrData, rowIndex * 256 + i * 16, _tileData[i], 0, 16);
string key = GetColorIndependentKey(_tileData[i]);
string mapping;
if(_charMappings.TryGetValue(key, out mapping)) {
_txtMappings[i].Text = mapping;
_txtMappings[i].BackColor = _activeBgColor;
} else {
_txtMappings[i].Text = "";
_txtMappings[i].BackColor = Color.White;
}
}
}
private void txtMapping_TextChanged(object sender, EventArgs e)
{
int i = Array.IndexOf(_txtMappings, sender);
string key = GetColorIndependentKey(_tileData[i]);
string text = ((TextBox)sender).Text;
if(string.IsNullOrWhiteSpace(text)) {
_charMappings.TryRemove(key, out text);
((TextBox)sender).BackColor = Color.White;
} else {
_charMappings[key] = text;
((TextBox)sender).BackColor = _activeBgColor;
}
}
public void SetCharacterMappings(ConcurrentDictionary<string, string> charMappings)
{
_charMappings = charMappings;
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -0,0 +1,211 @@
namespace Mesen.GUI.Debugger.Controls
{
partial class ctrlCharacterMappings
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
this.lblChrSelection = new System.Windows.Forms.Label();
this.cboChrSelection = new System.Windows.Forms.ComboBox();
this.grpTileInfo = new System.Windows.Forms.GroupBox();
this.tlpTileMappings = new System.Windows.Forms.TableLayoutPanel();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lblHint = new System.Windows.Forms.Label();
this.picHint = new System.Windows.Forms.PictureBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.tableLayoutPanel3.SuspendLayout();
this.flowLayoutPanel2.SuspendLayout();
this.grpTileInfo.SuspendLayout();
this.tlpTileMappings.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picHint)).BeginInit();
this.SuspendLayout();
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 2;
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.Controls.Add(this.flowLayoutPanel2, 1, 0);
this.tableLayoutPanel3.Controls.Add(this.grpTileInfo, 1, 1);
this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 3;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(816, 492);
this.tableLayoutPanel3.TabIndex = 3;
//
// flowLayoutPanel2
//
this.flowLayoutPanel2.Controls.Add(this.lblChrSelection);
this.flowLayoutPanel2.Controls.Add(this.cboChrSelection);
this.flowLayoutPanel2.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(332, 27);
this.flowLayoutPanel2.TabIndex = 6;
//
// lblChrSelection
//
this.lblChrSelection.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblChrSelection.AutoSize = true;
this.lblChrSelection.Location = new System.Drawing.Point(3, 7);
this.lblChrSelection.Name = "lblChrSelection";
this.lblChrSelection.Size = new System.Drawing.Size(80, 13);
this.lblChrSelection.TabIndex = 0;
this.lblChrSelection.Text = "CHR Selection:";
//
// cboChrSelection
//
this.cboChrSelection.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboChrSelection.FormattingEnabled = true;
this.cboChrSelection.Location = new System.Drawing.Point(89, 3);
this.cboChrSelection.Name = "cboChrSelection";
this.cboChrSelection.Size = new System.Drawing.Size(183, 21);
this.cboChrSelection.TabIndex = 1;
this.cboChrSelection.DropDown += new System.EventHandler(this.cboChrSelection_DropDown);
this.cboChrSelection.SelectedIndexChanged += new System.EventHandler(this.cboChrSelection_SelectedIndexChanged);
//
// grpTileInfo
//
this.grpTileInfo.Controls.Add(this.tlpTileMappings);
this.grpTileInfo.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpTileInfo.Location = new System.Drawing.Point(3, 30);
this.grpTileInfo.Name = "grpTileInfo";
this.grpTileInfo.Size = new System.Drawing.Size(811, 455);
this.grpTileInfo.TabIndex = 4;
this.grpTileInfo.TabStop = false;
this.grpTileInfo.Text = "Tile Mappings";
//
// tlpTileMappings
//
this.tlpTileMappings.ColumnCount = 3;
this.tlpTileMappings.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTileMappings.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tlpTileMappings.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpTileMappings.Controls.Add(this.tableLayoutPanel1, 0, 0);
this.tlpTileMappings.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpTileMappings.Location = new System.Drawing.Point(3, 16);
this.tlpTileMappings.Margin = new System.Windows.Forms.Padding(0);
this.tlpTileMappings.Name = "tlpTileMappings";
this.tlpTileMappings.RowCount = 10;
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpTileMappings.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpTileMappings.Size = new System.Drawing.Size(805, 436);
this.tlpTileMappings.TabIndex = 0;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tlpTileMappings.SetColumnSpan(this.tableLayoutPanel1, 3);
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.lblHint, 1, 0);
this.tableLayoutPanel1.Controls.Add(this.picHint, 0, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 3);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 1;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(799, 26);
this.tableLayoutPanel1.TabIndex = 2;
//
// lblHint
//
this.lblHint.AutoSize = true;
this.lblHint.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblHint.Location = new System.Drawing.Point(25, 0);
this.lblHint.Name = "lblHint";
this.lblHint.Size = new System.Drawing.Size(771, 26);
this.lblHint.TabIndex = 1;
this.lblHint.Text = "Select a CHR page above and then enter the character matching each tile in the te" +
"xtbox below the tile itself.\r\nCharacter mappings are shared between all roms.";
//
// picHint
//
this.picHint.BackgroundImage = global::Mesen.GUI.Properties.Resources.Help;
this.picHint.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Center;
this.picHint.Location = new System.Drawing.Point(3, 5);
this.picHint.Margin = new System.Windows.Forms.Padding(3, 5, 3, 3);
this.picHint.Name = "picHint";
this.picHint.Size = new System.Drawing.Size(16, 16);
this.picHint.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.picHint.TabIndex = 0;
this.picHint.TabStop = false;
//
// toolTip
//
this.toolTip.AutoPopDelay = 32700;
this.toolTip.InitialDelay = 10;
this.toolTip.ReshowDelay = 10;
//
// ctrlCharacterMappings
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel3);
this.Name = "ctrlCharacterMappings";
this.Size = new System.Drawing.Size(816, 492);
this.tableLayoutPanel3.ResumeLayout(false);
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
this.grpTileInfo.ResumeLayout(false);
this.tlpTileMappings.ResumeLayout(false);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picHint)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.ToolTip toolTip;
private System.Windows.Forms.GroupBox grpTileInfo;
private System.Windows.Forms.TableLayoutPanel tlpTileMappings;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.Label lblChrSelection;
private System.Windows.Forms.ComboBox cboChrSelection;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label lblHint;
private System.Windows.Forms.PictureBox picHint;
}
}

View file

@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Mesen.GUI.Controls;
using Mesen.GUI.Config;
using System.Collections.Concurrent;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlCharacterMappings : BaseControl
{
private UInt32 _chrSize;
private byte[] _chrPixelData;
private int _chrSelection = 0;
private ctrlCharacterMapping[] _mappings = new ctrlCharacterMapping[16];
private byte[] _chrData = new byte[16*16*16];
public ctrlCharacterMappings()
{
InitializeComponent();
tlpTileMappings.SuspendLayout();
for(int y = 0; y < 8; y++) {
for(int x = 0; x < 2; x++) {
ctrlCharacterMapping mapping = new ctrlCharacterMapping();
tlpTileMappings.Controls.Add(mapping);
tlpTileMappings.SetColumn(mapping, x);
tlpTileMappings.SetRow(mapping, y + 1);
mapping.picTiles.Image = new Bitmap(416, 20);
_mappings[(y << 1) + x] = mapping;
}
}
tlpTileMappings.ResumeLayout();
}
public void GetData()
{
UInt32[] paletteData;
_chrPixelData = InteropEmu.DebugGetChrBank(_chrSelection, 9, false, CdlHighlightType.None, out paletteData);
bool isChrRam = InteropEmu.DebugGetMemorySize(DebugMemoryType.ChrRom) == 0;
if(_chrSelection < 2) {
byte[] chrData = InteropEmu.DebugGetMemoryState(DebugMemoryType.PpuMemory);
Array.Copy(chrData, _chrSelection * 0x1000, _chrData, 0, 0x1000);
} else {
byte[] chrData = InteropEmu.DebugGetMemoryState(isChrRam ? DebugMemoryType.ChrRam : DebugMemoryType.ChrRom);
int startIndex = (_chrSelection - 2) * 0x1000;
if(startIndex >= chrData.Length) {
//Can occur when switching games
startIndex = 0;
}
Array.Copy(chrData, startIndex, _chrData, 0, 0x1000);
}
}
public void RefreshViewer(bool refreshPreview = false)
{
UpdateChrBankDropdown();
GCHandle handle = GCHandle.Alloc(_chrPixelData, GCHandleType.Pinned);
try {
Bitmap source = new Bitmap(128, 128, 4*128, System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
for(int y = 0; y < 16; y++) {
using(Graphics g = Graphics.FromImage(_mappings[y].picTiles.Image)) {
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
g.TranslateTransform(1, 0);
for(int x = 0; x < 16; x++) {
g.FillRectangle(Brushes.DarkGreen, 3 + x * 26, 1, 18, 18);
}
g.ScaleTransform(2, 2);
for(int x = 0; x < 16; x++) {
g.DrawImage(source, new Rectangle(2 + x * 13, 1, 8, 8), x * 8, y * 8, 8, 8, GraphicsUnit.Pixel);
}
}
_mappings[y].picTiles.Invalidate();
_mappings[y].UpdateData(_chrData, y);
}
} finally {
handle.Free();
}
}
public void SetCharacterMappings(ConcurrentDictionary<string, string> charMappings)
{
for(int i = 0; i < 16; i++) {
_mappings[i].SetCharacterMappings(charMappings);
}
}
private void UpdateChrBankDropdown()
{
DebugState state = new DebugState();
InteropEmu.DebugGetState(ref state);
UInt32 chrSize = state.Cartridge.ChrRomSize == 0 ? state.Cartridge.ChrRamSize : state.Cartridge.ChrRomSize;
if(chrSize != _chrSize) {
_chrSize = chrSize;
int index = this.cboChrSelection.SelectedIndex;
this.cboChrSelection.Items.Clear();
this.cboChrSelection.Items.Add("PPU: $0000");
this.cboChrSelection.Items.Add("PPU: $1000");
for(int i = 0; i < _chrSize / 0x1000; i++) {
this.cboChrSelection.Items.Add("CHR: $" + (i * 0x1000).ToString("X4"));
}
this.cboChrSelection.SelectedIndex = this.cboChrSelection.Items.Count > index && index >= 0 ? index : 0;
this._chrSelection = this.cboChrSelection.SelectedIndex;
}
}
private void cboChrSelection_DropDown(object sender, EventArgs e)
{
UpdateChrBankDropdown();
}
private void cboChrSelection_SelectedIndexChanged(object sender, EventArgs e)
{
this._chrSelection = this.cboChrSelection.SelectedIndex;
this.GetData();
this.RefreshViewer();
}
}
}

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>116, 17</value>
</metadata>
</root>

View file

@ -0,0 +1,168 @@
namespace Mesen.GUI.Debugger.Controls
{
partial class ctrlScanlineCycleSelect
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.flpRefreshTiming = new System.Windows.Forms.FlowLayoutPanel();
this.lblShowFrameAt = new System.Windows.Forms.Label();
this.lblCycle = new System.Windows.Forms.Label();
this.btnReset = new System.Windows.Forms.Button();
this.nudScanline = new Mesen.GUI.Controls.MesenNumericUpDown();
this.nudCycle = new Mesen.GUI.Controls.MesenNumericUpDown();
this.flpRefreshTiming.SuspendLayout();
this.SuspendLayout();
//
// flpRefreshTiming
//
this.flpRefreshTiming.Controls.Add(this.lblShowFrameAt);
this.flpRefreshTiming.Controls.Add(this.nudScanline);
this.flpRefreshTiming.Controls.Add(this.lblCycle);
this.flpRefreshTiming.Controls.Add(this.nudCycle);
this.flpRefreshTiming.Controls.Add(this.btnReset);
this.flpRefreshTiming.Dock = System.Windows.Forms.DockStyle.Fill;
this.flpRefreshTiming.Location = new System.Drawing.Point(0, 0);
this.flpRefreshTiming.Name = "flpRefreshTiming";
this.flpRefreshTiming.Size = new System.Drawing.Size(530, 28);
this.flpRefreshTiming.TabIndex = 5;
//
// lblShowFrameAt
//
this.lblShowFrameAt.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblShowFrameAt.AutoSize = true;
this.lblShowFrameAt.Location = new System.Drawing.Point(3, 8);
this.lblShowFrameAt.Name = "lblShowFrameAt";
this.lblShowFrameAt.Size = new System.Drawing.Size(266, 13);
this.lblShowFrameAt.TabIndex = 0;
this.lblShowFrameAt.Text = "When emulation is running, show PPU data at scanline";
//
// lblCycle
//
this.lblCycle.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblCycle.AutoSize = true;
this.lblCycle.Location = new System.Drawing.Point(333, 8);
this.lblCycle.Name = "lblCycle";
this.lblCycle.Size = new System.Drawing.Size(53, 13);
this.lblCycle.TabIndex = 5;
this.lblCycle.Text = "and cycle";
//
// btnReset
//
this.btnReset.Location = new System.Drawing.Point(450, 3);
this.btnReset.Name = "btnReset";
this.btnReset.Size = new System.Drawing.Size(75, 23);
this.btnReset.TabIndex = 7;
this.btnReset.Text = "Reset";
this.btnReset.UseVisualStyleBackColor = true;
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
//
// nudScanline
//
this.nudScanline.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.nudScanline.DecimalPlaces = 0;
this.nudScanline.Increment = new decimal(new int[] {
1,
0,
0,
0});
this.nudScanline.Location = new System.Drawing.Point(275, 4);
this.nudScanline.Maximum = new decimal(new int[] {
260,
0,
0,
0});
this.nudScanline.MaximumSize = new System.Drawing.Size(10000, 20);
this.nudScanline.Minimum = new decimal(new int[] {
1,
0,
0,
-2147483648});
this.nudScanline.MinimumSize = new System.Drawing.Size(0, 21);
this.nudScanline.Name = "nudScanline";
this.nudScanline.Size = new System.Drawing.Size(52, 21);
this.nudScanline.TabIndex = 5;
this.nudScanline.Value = new decimal(new int[] {
241,
0,
0,
0});
this.nudScanline.ValueChanged += new System.EventHandler(this.nudScanlineCycle_ValueChanged);
//
// nudCycle
//
this.nudCycle.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.nudCycle.DecimalPlaces = 0;
this.nudCycle.Increment = new decimal(new int[] {
1,
0,
0,
0});
this.nudCycle.Location = new System.Drawing.Point(392, 4);
this.nudCycle.Maximum = new decimal(new int[] {
340,
0,
0,
0});
this.nudCycle.MaximumSize = new System.Drawing.Size(10000, 20);
this.nudCycle.Minimum = new decimal(new int[] {
0,
0,
0,
0});
this.nudCycle.MinimumSize = new System.Drawing.Size(0, 21);
this.nudCycle.Name = "nudCycle";
this.nudCycle.Size = new System.Drawing.Size(52, 21);
this.nudCycle.TabIndex = 6;
this.nudCycle.Value = new decimal(new int[] {
0,
0,
0,
0});
this.nudCycle.ValueChanged += new System.EventHandler(this.nudScanlineCycle_ValueChanged);
//
// ctrlScanlineCycleSelect
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.flpRefreshTiming);
this.Name = "ctrlScanlineCycleSelect";
this.Size = new System.Drawing.Size(530, 28);
this.flpRefreshTiming.ResumeLayout(false);
this.flpRefreshTiming.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.FlowLayoutPanel flpRefreshTiming;
private System.Windows.Forms.Label lblShowFrameAt;
private GUI.Controls.MesenNumericUpDown nudScanline;
private System.Windows.Forms.Label lblCycle;
private GUI.Controls.MesenNumericUpDown nudCycle;
private System.Windows.Forms.Button btnReset;
}
}

View file

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlScanlineCycleSelect : UserControl
{
private int _ppuViewerId = 0;
private int _scanline = 241;
private int _cycle = 0;
public int Scanline { get { return _scanline; } }
public int Cycle { get { return _cycle; } }
public ctrlScanlineCycleSelect()
{
InitializeComponent();
}
public void Initialize(int ppuViewerId, int scanline, int cycle)
{
_ppuViewerId = ppuViewerId;
_scanline = scanline;
_cycle = cycle;
this.nudScanline.Value = _scanline;
this.nudCycle.Value = _cycle;
InteropEmu.DebugSetPpuViewerScanlineCycle(_ppuViewerId, _scanline, _cycle);
}
public void RefreshSettings()
{
InteropEmu.DebugSetPpuViewerScanlineCycle(_ppuViewerId, _scanline, _cycle);
}
private void SetUpdateScanlineCycle(int scanline, int cycle)
{
_scanline = scanline;
_cycle = cycle;
RefreshSettings();
}
private void nudScanlineCycle_ValueChanged(object sender, EventArgs e)
{
SetUpdateScanlineCycle((int)this.nudScanline.Value, (int)this.nudCycle.Value);
}
private void btnReset_Click(object sender, EventArgs e)
{
this.nudScanline.Value = 241;
this.nudCycle.Value = 0;
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -0,0 +1,236 @@
namespace Mesen.GUI.Debugger.Controls
{
partial class ctrlTextHooker
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.picNametable = new System.Windows.Forms.PictureBox();
this.grpText = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.chkAutoCopyToClipboard = new System.Windows.Forms.CheckBox();
this.chkIgnoreMirroredNametables = new System.Windows.Forms.CheckBox();
this.btnClearSelection = new System.Windows.Forms.Button();
this.txtSelectedText = new System.Windows.Forms.TextBox();
this.chkUseScrollOffsets = new System.Windows.Forms.CheckBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.lblDakutenMode = new System.Windows.Forms.Label();
this.cboDakutenMode = new System.Windows.Forms.ComboBox();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picNametable)).BeginInit();
this.grpText.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.picNametable, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.grpText, 1, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(923, 491);
this.tableLayoutPanel1.TabIndex = 2;
//
// picNametable
//
this.picNametable.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.picNametable.Location = new System.Drawing.Point(4, 4);
this.picNametable.Margin = new System.Windows.Forms.Padding(4);
this.picNametable.Name = "picNametable";
this.picNametable.Size = new System.Drawing.Size(514, 482);
this.picNametable.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.picNametable.TabIndex = 0;
this.picNametable.TabStop = false;
//
// grpText
//
this.grpText.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.grpText.Controls.Add(this.tableLayoutPanel2);
this.grpText.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpText.Location = new System.Drawing.Point(525, 3);
this.grpText.Name = "grpText";
this.grpText.Size = new System.Drawing.Size(395, 484);
this.grpText.TabIndex = 4;
this.grpText.TabStop = false;
this.grpText.Text = "Text Hooker";
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Controls.Add(this.chkAutoCopyToClipboard, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.chkIgnoreMirroredNametables, 0, 2);
this.tableLayoutPanel2.Controls.Add(this.btnClearSelection, 0, 5);
this.tableLayoutPanel2.Controls.Add(this.txtSelectedText, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.chkUseScrollOffsets, 0, 3);
this.tableLayoutPanel2.Controls.Add(this.tableLayoutPanel3, 0, 4);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 6;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(389, 465);
this.tableLayoutPanel2.TabIndex = 0;
//
// chkAutoCopyToClipboard
//
this.chkAutoCopyToClipboard.AutoSize = true;
this.chkAutoCopyToClipboard.Location = new System.Drawing.Point(3, 342);
this.chkAutoCopyToClipboard.Name = "chkAutoCopyToClipboard";
this.chkAutoCopyToClipboard.Size = new System.Drawing.Size(132, 17);
this.chkAutoCopyToClipboard.TabIndex = 7;
this.chkAutoCopyToClipboard.Text = "Auto-copy to clipboard";
this.chkAutoCopyToClipboard.UseVisualStyleBackColor = true;
//
// chkIgnoreMirroredNametables
//
this.chkIgnoreMirroredNametables.AutoSize = true;
this.chkIgnoreMirroredNametables.Location = new System.Drawing.Point(3, 365);
this.chkIgnoreMirroredNametables.Name = "chkIgnoreMirroredNametables";
this.chkIgnoreMirroredNametables.Size = new System.Drawing.Size(153, 17);
this.chkIgnoreMirroredNametables.TabIndex = 6;
this.chkIgnoreMirroredNametables.Text = "Ignore mirrored nametables";
this.chkIgnoreMirroredNametables.UseVisualStyleBackColor = true;
//
// btnClearSelection
//
this.btnClearSelection.Location = new System.Drawing.Point(3, 437);
this.btnClearSelection.Name = "btnClearSelection";
this.btnClearSelection.Size = new System.Drawing.Size(92, 23);
this.btnClearSelection.TabIndex = 0;
this.btnClearSelection.Text = "Clear Selection";
this.btnClearSelection.UseVisualStyleBackColor = true;
this.btnClearSelection.Visible = false;
//
// txtSelectedText
//
this.txtSelectedText.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.tableLayoutPanel2.SetColumnSpan(this.txtSelectedText, 2);
this.txtSelectedText.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtSelectedText.Location = new System.Drawing.Point(3, 3);
this.txtSelectedText.Multiline = true;
this.txtSelectedText.Name = "txtSelectedText";
this.txtSelectedText.ReadOnly = true;
this.txtSelectedText.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.txtSelectedText.Size = new System.Drawing.Size(383, 333);
this.txtSelectedText.TabIndex = 1;
//
// chkUseScrollOffsets
//
this.chkUseScrollOffsets.AutoSize = true;
this.chkUseScrollOffsets.Location = new System.Drawing.Point(3, 388);
this.chkUseScrollOffsets.Name = "chkUseScrollOffsets";
this.chkUseScrollOffsets.Size = new System.Drawing.Size(187, 17);
this.chkUseScrollOffsets.TabIndex = 2;
this.chkUseScrollOffsets.Text = "Adjust viewport by scrolling offsets";
this.chkUseScrollOffsets.UseVisualStyleBackColor = true;
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 2;
this.tableLayoutPanel2.SetColumnSpan(this.tableLayoutPanel3, 2);
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Controls.Add(this.lblDakutenMode, 0, 0);
this.tableLayoutPanel3.Controls.Add(this.cboDakutenMode, 1, 0);
this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 408);
this.tableLayoutPanel3.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel3.Name = "tableLayoutPanel3";
this.tableLayoutPanel3.RowCount = 1;
this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel3.Size = new System.Drawing.Size(219, 26);
this.tableLayoutPanel3.TabIndex = 5;
//
// lblDakutenMode
//
this.lblDakutenMode.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblDakutenMode.AutoSize = true;
this.lblDakutenMode.Location = new System.Drawing.Point(3, 6);
this.lblDakutenMode.Name = "lblDakutenMode";
this.lblDakutenMode.Size = new System.Drawing.Size(81, 13);
this.lblDakutenMode.TabIndex = 4;
this.lblDakutenMode.Text = "Dakuten Mode:";
//
// cboDakutenMode
//
this.cboDakutenMode.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboDakutenMode.FormattingEnabled = true;
this.cboDakutenMode.Location = new System.Drawing.Point(90, 3);
this.cboDakutenMode.Name = "cboDakutenMode";
this.cboDakutenMode.Size = new System.Drawing.Size(121, 21);
this.cboDakutenMode.TabIndex = 5;
//
// ctrlTextHooker
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "ctrlTextHooker";
this.Size = new System.Drawing.Size(923, 491);
this.tableLayoutPanel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.picNametable)).EndInit();
this.grpText.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.PictureBox picNametable;
private System.Windows.Forms.GroupBox grpText;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.Button btnClearSelection;
private System.Windows.Forms.TextBox txtSelectedText;
private System.Windows.Forms.CheckBox chkUseScrollOffsets;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3;
private System.Windows.Forms.Label lblDakutenMode;
private System.Windows.Forms.ComboBox cboDakutenMode;
private System.Windows.Forms.CheckBox chkAutoCopyToClipboard;
private System.Windows.Forms.CheckBox chkIgnoreMirroredNametables;
}
}

View file

@ -0,0 +1,267 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Mesen.GUI.Config;
using Mesen.GUI.Controls;
using Mesen.GUI.Forms;
using System.Collections.Concurrent;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlTextHooker : BaseControl
{
private byte[][] _nametablePixelData = new byte[4][];
private byte[][] _tileData = new byte[4][];
private byte[][] _attributeData = new byte[4][];
private byte[] _tmpTileData = new byte[16];
private Bitmap _nametableImage = new Bitmap(512, 480);
private Bitmap _outputImage = new Bitmap(512, 480);
private int _xScroll = 0;
private int _yScroll = 0;
private DebugState _state = new DebugState();
private ConcurrentDictionary<string, string> _charMappings;
public ctrlTextHooker()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(!IsDesignMode) {
DebugInfo debugInfo = ConfigManager.Config.DebugInfo;
chkIgnoreMirroredNametables.Checked = debugInfo.TextHookerIgnoreMirroredNametables;
chkUseScrollOffsets.Checked = debugInfo.TextHookerAdjustViewportScrolling;
chkAutoCopyToClipboard.Checked = debugInfo.TextHookerAutoCopyToClipboard;
BaseConfigForm.InitializeComboBox(cboDakutenMode, typeof(DakutenMode));
cboDakutenMode.SetEnumValue(debugInfo.TextHookerDakutenMode);
}
}
protected override void OnHandleDestroyed(EventArgs e)
{
base.OnHandleDestroyed(e);
if(!IsDesignMode) {
DebugInfo debugInfo = ConfigManager.Config.DebugInfo;
debugInfo.TextHookerIgnoreMirroredNametables = chkIgnoreMirroredNametables.Checked;
debugInfo.TextHookerAdjustViewportScrolling = chkUseScrollOffsets.Checked;
debugInfo.TextHookerAutoCopyToClipboard = chkAutoCopyToClipboard.Checked;
debugInfo.TextHookerDakutenMode = cboDakutenMode.GetEnumValue<DakutenMode>();
}
}
public void GetData()
{
InteropEmu.DebugGetPpuScroll(out _xScroll, out _yScroll);
InteropEmu.DebugGetState(ref _state);
for(int i = 0; i < 4; i++) {
InteropEmu.DebugGetNametable(i, ConfigManager.Config.DebugInfo.NtViewerUseGrayscalePalette, out _nametablePixelData[i], out _tileData[i], out _attributeData[i]);
}
InteropEmu.DebugGetPpuScroll(out _xScroll, out _yScroll);
_xScroll &= 0xFFF8;
_yScroll &= 0xFFF8;
}
public void RefreshViewer()
{
using(Graphics gNametable = Graphics.FromImage(_nametableImage)) {
for(int i = 0; i < 4; i++) {
GCHandle handle = GCHandle.Alloc(_nametablePixelData[i], GCHandleType.Pinned);
Bitmap source = new Bitmap(256, 240, 4*256, System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
try {
gNametable.DrawImage(source, new Rectangle(i % 2 == 0 ? 0 : 256, i <= 1 ? 0 : 240, 256, 240), new Rectangle(0, 0, 256, 240), GraphicsUnit.Pixel);
} finally {
handle.Free();
}
}
}
using(Graphics g = Graphics.FromImage(_outputImage)) {
if(chkUseScrollOffsets.Checked) {
g.DrawImage(_nametableImage, -_xScroll, -_yScroll);
g.DrawImage(_nametableImage, -_xScroll + 512, -_yScroll + 480);
g.DrawImage(_nametableImage, -_xScroll + 512, -_yScroll);
g.DrawImage(_nametableImage, -_xScroll, -_yScroll + 480);
} else {
g.DrawImage(_nametableImage, 0, 0);
}
}
picNametable.Image = _outputImage;
DakutenMode dakutenMode = cboDakutenMode.GetEnumValue<DakutenMode>();
StringBuilder output = new StringBuilder();
DakutenType[] previousLineDakutenType = new DakutenType[32];
for(int nt = 0; nt < 4; nt++) {
for(int y = 0; y < 30; y++) {
StringBuilder lineOutput = new StringBuilder();
for(int x = 0; x < 32; x++) {
int outNt, outY, outX;
GetIndexes(nt, y, x, out outNt, out outY, out outX);
if(IgnoreTile(outNt)) {
continue;
}
string key = GetTileKey(outNt, (outY << 5) + outX);
string value = GetMappedCharacter(key);
DakutenType dakutenType = GetDakutenType(value);
if(dakutenType != DakutenType.None) {
previousLineDakutenType[x] = dakutenType;
} else {
DakutenType effectiveDakuten = dakutenMode == DakutenMode.OnTop ? previousLineDakutenType[x] : DakutenType.None;
previousLineDakutenType[x] = DakutenType.None;
if(effectiveDakuten == DakutenType.None && dakutenMode == DakutenMode.OnTheRight) {
GetIndexes(nt, y, x + 1, out outNt, out outY, out outX);
string nextTileKey = GetTileKey(outNt, (outY << 5) + outX);
string nextTileValue = GetMappedCharacter(nextTileKey);
effectiveDakuten = GetDakutenType(nextTileValue);
}
bool isKana = (
(value[0] >= '\x3041' && value[0] <= '\x3096') || //hiragana
(value[0] >= '\x30A1' && value[0] <= '\x30FA') //katakana
);
if(isKana && effectiveDakuten == DakutenType.Dakuten) {
lineOutput.Append((char)(value[0] + 1));
} else if(isKana && effectiveDakuten == DakutenType.Handakuten) {
lineOutput.Append((char)(value[0] + 2));
} else {
lineOutput.Append(value);
}
}
}
string rowString = lineOutput.ToString().Trim();
if(rowString.Length > 0) {
output.AppendLine(rowString);
}
}
}
txtSelectedText.Text = output.ToString();
if(chkAutoCopyToClipboard.Checked) {
Clipboard.SetText(txtSelectedText.Text);
}
}
private string GetMappedCharacter(string key)
{
string value;
if(this._charMappings.TryGetValue(key, out value)) {
return value;
} else {
return " ";
}
}
private DakutenType GetDakutenType(string value)
{
if(value == "daku" || value == "゙") {
return DakutenType.Dakuten;
} else if(value == "han" || value == "゚") {
return DakutenType.Handakuten;
} else {
return DakutenType.None;
}
}
private string GetTileKey(int nametableIndex, int index)
{
byte tileIndex = _tileData[nametableIndex][index];
for(int i = 0; i < 16; i++) {
_tmpTileData[i] = InteropEmu.DebugGetMemoryValue(DebugMemoryType.PpuMemory, (UInt32)(_state.PPU.ControlFlags.BackgroundPatternAddr + tileIndex * 16 + i));
}
return ctrlCharacterMapping.GetColorIndependentKey(_tmpTileData);
}
private bool IgnoreTile(int nametableIndex)
{
if(chkIgnoreMirroredNametables.Checked) {
switch(_state.Cartridge.Mirroring) {
case MirroringType.ScreenAOnly:
case MirroringType.ScreenBOnly:
if(nametableIndex > 0) {
return true;
}
break;
case MirroringType.Horizontal:
if((nametableIndex & 0x01) == 0x01) {
return true;
}
break;
case MirroringType.Vertical:
if((nametableIndex & 0x02) == 0x02) {
return true;
}
break;
}
}
return false;
}
public void SetCharacterMappings(ConcurrentDictionary<string, string> charMappings)
{
_charMappings = charMappings;
}
private void GetIndexes(int inNt, int inY, int inX, out int outNt, out int outY, out int outX)
{
outX = inX;
outY = inY;
outNt = inNt & 0x03;
if(chkUseScrollOffsets.Checked) {
outY += _yScroll / 8;
outX += _xScroll / 8;
}
while(outX < 0) {
outX += 32;
outNt ^= 1;
}
while(outX >= 32) {
outX -= 32;
outNt ^= 1;
}
while(outY >= 30) {
outY -= 30;
outNt ^= 2;
}
while(outY < 0) {
outY += 30;
outNt ^= 2;
}
outNt &= 0x03;
}
}
enum DakutenType {
None = 0,
Dakuten = 1,
Handakuten = 2
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -30,6 +30,7 @@ namespace Mesen.GUI.Debugger
case DebugWindow.ScriptWindow: frm = new frmScript(); break;
case DebugWindow.ApuViewer: frm = new frmApuViewer(); break;
case DebugWindow.EventViewer: frm = new frmEventViewer(); break;
case DebugWindow.TextHooker: frm = new frmTextHooker(); break;
}
_openedWindows.Add(frm);
frm.FormClosed += Debugger_FormClosed;
@ -92,6 +93,7 @@ namespace Mesen.GUI.Debugger
case DebugWindow.Assembler: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmAssembler));
case DebugWindow.Debugger: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmDebugger));
case DebugWindow.ApuViewer: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmApuViewer));
case DebugWindow.TextHooker: return _openedWindows.ToList().Find((form) => form.GetType() == typeof(frmTextHooker));
}
return null;
@ -126,6 +128,7 @@ namespace Mesen.GUI.Debugger
Debugger,
ScriptWindow,
ApuViewer,
EventViewer
EventViewer,
TextHooker,
}
}

View file

@ -44,6 +44,7 @@ namespace Mesen.GUI.Debugger
GetMember(nameof(DebuggerShortcutsConfig.OpenMemoryTools)),
GetMember(nameof(DebuggerShortcutsConfig.OpenPpuViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenScriptWindow)),
GetMember(nameof(DebuggerShortcutsConfig.OpenTextHooker)),
GetMember(nameof(DebuggerShortcutsConfig.OpenTraceLogger))
};

View file

@ -178,6 +178,7 @@ namespace Mesen.GUI.Debugger
this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuScriptWindow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTextHooker = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem13 = new System.Windows.Forms.ToolStripSeparator();
this.mnuEditHeader = new System.Windows.Forms.ToolStripMenuItem();
@ -251,8 +252,8 @@ namespace Mesen.GUI.Debugger
this.splitContainer.Panel2.Controls.Add(this.picWatchHelp);
this.splitContainer.Panel2.Controls.Add(this.tableLayoutPanel10);
this.splitContainer.Panel2MinSize = 100;
this.splitContainer.Size = new System.Drawing.Size(1075, 765);
this.splitContainer.SplitterDistance = 576;
this.splitContainer.Size = new System.Drawing.Size(1075, 570);
this.splitContainer.SplitterDistance = 438;
this.splitContainer.SplitterWidth = 7;
this.splitContainer.TabIndex = 1;
this.splitContainer.TabStop = false;
@ -276,7 +277,7 @@ namespace Mesen.GUI.Debugger
//
this.ctrlSplitContainerTop.Panel2.Controls.Add(this.tlpFunctionLabelLists);
this.ctrlSplitContainerTop.Panel2MinSize = 150;
this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1075, 576);
this.ctrlSplitContainerTop.Size = new System.Drawing.Size(1075, 438);
this.ctrlSplitContainerTop.SplitterDistance = 750;
this.ctrlSplitContainerTop.SplitterWidth = 7;
this.ctrlSplitContainerTop.TabIndex = 3;
@ -297,8 +298,8 @@ namespace Mesen.GUI.Debugger
this.tlpTop.Name = "tlpTop";
this.tlpTop.RowCount = 1;
this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 576F));
this.tlpTop.Size = new System.Drawing.Size(750, 576);
this.tlpTop.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 570F));
this.tlpTop.Size = new System.Drawing.Size(750, 438);
this.tlpTop.TabIndex = 2;
//
// panel1
@ -309,7 +310,7 @@ namespace Mesen.GUI.Debugger
this.panel1.Location = new System.Drawing.Point(3, 0);
this.panel1.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(286, 576);
this.panel1.Size = new System.Drawing.Size(286, 438);
this.panel1.TabIndex = 5;
//
// ctrlSourceViewer
@ -318,7 +319,7 @@ namespace Mesen.GUI.Debugger
this.ctrlSourceViewer.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlSourceViewer.Location = new System.Drawing.Point(0, 0);
this.ctrlSourceViewer.Name = "ctrlSourceViewer";
this.ctrlSourceViewer.Size = new System.Drawing.Size(286, 576);
this.ctrlSourceViewer.Size = new System.Drawing.Size(286, 438);
this.ctrlSourceViewer.SymbolProvider = null;
this.ctrlSourceViewer.TabIndex = 7;
this.ctrlSourceViewer.Visible = false;
@ -332,7 +333,7 @@ namespace Mesen.GUI.Debugger
this.ctrlDebuggerCode.Location = new System.Drawing.Point(0, 0);
this.ctrlDebuggerCode.Name = "ctrlDebuggerCode";
this.ctrlDebuggerCode.ShowMemoryValues = false;
this.ctrlDebuggerCode.Size = new System.Drawing.Size(286, 576);
this.ctrlDebuggerCode.Size = new System.Drawing.Size(286, 438);
this.ctrlDebuggerCode.SymbolProvider = null;
this.ctrlDebuggerCode.TabIndex = 2;
this.ctrlDebuggerCode.OnEditCode += new Mesen.GUI.Debugger.ctrlDebuggerCode.AssemblerEventHandler(this.ctrlDebuggerCode_OnEditCode);
@ -346,7 +347,7 @@ namespace Mesen.GUI.Debugger
this.panel2.Location = new System.Drawing.Point(292, 0);
this.panel2.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(1, 576);
this.panel2.Size = new System.Drawing.Size(1, 438);
this.panel2.TabIndex = 6;
//
// ctrlSourceViewerSplit
@ -355,7 +356,7 @@ namespace Mesen.GUI.Debugger
this.ctrlSourceViewerSplit.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlSourceViewerSplit.Location = new System.Drawing.Point(0, 0);
this.ctrlSourceViewerSplit.Name = "ctrlSourceViewerSplit";
this.ctrlSourceViewerSplit.Size = new System.Drawing.Size(1, 576);
this.ctrlSourceViewerSplit.Size = new System.Drawing.Size(1, 438);
this.ctrlSourceViewerSplit.SymbolProvider = null;
this.ctrlSourceViewerSplit.TabIndex = 8;
this.ctrlSourceViewerSplit.Visible = false;
@ -369,7 +370,7 @@ namespace Mesen.GUI.Debugger
this.ctrlDebuggerCodeSplit.Location = new System.Drawing.Point(0, 0);
this.ctrlDebuggerCodeSplit.Name = "ctrlDebuggerCodeSplit";
this.ctrlDebuggerCodeSplit.ShowMemoryValues = false;
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 576);
this.ctrlDebuggerCodeSplit.Size = new System.Drawing.Size(1, 438);
this.ctrlDebuggerCodeSplit.SymbolProvider = null;
this.ctrlDebuggerCodeSplit.TabIndex = 4;
this.ctrlDebuggerCodeSplit.Visible = false;
@ -389,7 +390,7 @@ namespace Mesen.GUI.Debugger
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(458, 576);
this.tableLayoutPanel1.Size = new System.Drawing.Size(458, 438);
this.tableLayoutPanel1.TabIndex = 7;
//
// ctrlConsoleStatus
@ -413,7 +414,7 @@ namespace Mesen.GUI.Debugger
this.tlpVerticalLayout.Name = "tlpVerticalLayout";
this.tlpVerticalLayout.RowCount = 1;
this.tlpVerticalLayout.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tlpVerticalLayout.Size = new System.Drawing.Size(458, 176);
this.tlpVerticalLayout.Size = new System.Drawing.Size(458, 38);
this.tlpVerticalLayout.TabIndex = 4;
//
// tlpFunctionLabelLists
@ -429,16 +430,16 @@ namespace Mesen.GUI.Debugger
this.tlpFunctionLabelLists.RowCount = 2;
this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tlpFunctionLabelLists.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tlpFunctionLabelLists.Size = new System.Drawing.Size(318, 576);
this.tlpFunctionLabelLists.Size = new System.Drawing.Size(318, 438);
this.tlpFunctionLabelLists.TabIndex = 5;
//
// grpLabels
//
this.grpLabels.Controls.Add(this.ctrlLabelList);
this.grpLabels.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpLabels.Location = new System.Drawing.Point(3, 291);
this.grpLabels.Location = new System.Drawing.Point(3, 222);
this.grpLabels.Name = "grpLabels";
this.grpLabels.Size = new System.Drawing.Size(312, 282);
this.grpLabels.Size = new System.Drawing.Size(312, 213);
this.grpLabels.TabIndex = 6;
this.grpLabels.TabStop = false;
this.grpLabels.Text = "Labels";
@ -448,7 +449,7 @@ namespace Mesen.GUI.Debugger
this.ctrlLabelList.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlLabelList.Location = new System.Drawing.Point(3, 16);
this.ctrlLabelList.Name = "ctrlLabelList";
this.ctrlLabelList.Size = new System.Drawing.Size(306, 263);
this.ctrlLabelList.Size = new System.Drawing.Size(306, 194);
this.ctrlLabelList.TabIndex = 0;
this.ctrlLabelList.OnFindOccurrence += new System.EventHandler(this.ctrlLabelList_OnFindOccurrence);
this.ctrlLabelList.OnLabelSelected += new System.EventHandler(this.ctrlLabelList_OnLabelSelected);
@ -459,7 +460,7 @@ namespace Mesen.GUI.Debugger
this.grpFunctions.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpFunctions.Location = new System.Drawing.Point(3, 3);
this.grpFunctions.Name = "grpFunctions";
this.grpFunctions.Size = new System.Drawing.Size(312, 282);
this.grpFunctions.Size = new System.Drawing.Size(312, 213);
this.grpFunctions.TabIndex = 5;
this.grpFunctions.TabStop = false;
this.grpFunctions.Text = "Functions";
@ -469,7 +470,7 @@ namespace Mesen.GUI.Debugger
this.ctrlFunctionList.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlFunctionList.Location = new System.Drawing.Point(3, 16);
this.ctrlFunctionList.Name = "ctrlFunctionList";
this.ctrlFunctionList.Size = new System.Drawing.Size(306, 263);
this.ctrlFunctionList.Size = new System.Drawing.Size(306, 194);
this.ctrlFunctionList.TabIndex = 0;
this.ctrlFunctionList.OnFindOccurrence += new System.EventHandler(this.ctrlFunctionList_OnFindOccurrence);
this.ctrlFunctionList.OnFunctionSelected += new System.EventHandler(this.ctrlFunctionList_OnFunctionSelected);
@ -500,7 +501,7 @@ namespace Mesen.GUI.Debugger
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel10.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel10.Size = new System.Drawing.Size(1075, 182);
this.tableLayoutPanel10.Size = new System.Drawing.Size(1075, 125);
this.tableLayoutPanel10.TabIndex = 0;
//
// grpWatch
@ -509,7 +510,7 @@ namespace Mesen.GUI.Debugger
this.grpWatch.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpWatch.Location = new System.Drawing.Point(3, 3);
this.grpWatch.Name = "grpWatch";
this.grpWatch.Size = new System.Drawing.Size(352, 176);
this.grpWatch.Size = new System.Drawing.Size(352, 119);
this.grpWatch.TabIndex = 2;
this.grpWatch.TabStop = false;
this.grpWatch.Text = "Watch";
@ -519,7 +520,7 @@ namespace Mesen.GUI.Debugger
this.ctrlWatch.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlWatch.Location = new System.Drawing.Point(3, 16);
this.ctrlWatch.Name = "ctrlWatch";
this.ctrlWatch.Size = new System.Drawing.Size(346, 157);
this.ctrlWatch.Size = new System.Drawing.Size(346, 100);
this.ctrlWatch.TabIndex = 0;
//
// grpBreakpoints
@ -528,7 +529,7 @@ namespace Mesen.GUI.Debugger
this.grpBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpBreakpoints.Location = new System.Drawing.Point(361, 3);
this.grpBreakpoints.Name = "grpBreakpoints";
this.grpBreakpoints.Size = new System.Drawing.Size(352, 176);
this.grpBreakpoints.Size = new System.Drawing.Size(352, 119);
this.grpBreakpoints.TabIndex = 3;
this.grpBreakpoints.TabStop = false;
this.grpBreakpoints.Text = "Breakpoints";
@ -538,7 +539,7 @@ namespace Mesen.GUI.Debugger
this.ctrlBreakpoints.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlBreakpoints.Location = new System.Drawing.Point(3, 16);
this.ctrlBreakpoints.Name = "ctrlBreakpoints";
this.ctrlBreakpoints.Size = new System.Drawing.Size(346, 157);
this.ctrlBreakpoints.Size = new System.Drawing.Size(346, 100);
this.ctrlBreakpoints.TabIndex = 0;
this.ctrlBreakpoints.BreakpointNavigation += new System.EventHandler(this.ctrlBreakpoints_BreakpointNavigation);
//
@ -548,7 +549,7 @@ namespace Mesen.GUI.Debugger
this.grpCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpCallstack.Location = new System.Drawing.Point(719, 3);
this.grpCallstack.Name = "grpCallstack";
this.grpCallstack.Size = new System.Drawing.Size(353, 176);
this.grpCallstack.Size = new System.Drawing.Size(353, 119);
this.grpCallstack.TabIndex = 4;
this.grpCallstack.TabStop = false;
this.grpCallstack.Text = "Call Stack";
@ -558,7 +559,7 @@ namespace Mesen.GUI.Debugger
this.ctrlCallstack.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlCallstack.Location = new System.Drawing.Point(3, 16);
this.ctrlCallstack.Name = "ctrlCallstack";
this.ctrlCallstack.Size = new System.Drawing.Size(347, 157);
this.ctrlCallstack.Size = new System.Drawing.Size(347, 100);
this.ctrlCallstack.TabIndex = 0;
this.ctrlCallstack.FunctionSelected += new System.EventHandler(this.ctrlCallstack_FunctionSelected);
//
@ -1533,6 +1534,7 @@ namespace Mesen.GUI.Debugger
this.mnuMemoryViewer,
this.mnuPpuViewer,
this.mnuScriptWindow,
this.mnuTextHooker,
this.mnuTraceLogger,
this.toolStripMenuItem13,
this.mnuEditHeader,
@ -1590,6 +1592,14 @@ namespace Mesen.GUI.Debugger
this.mnuScriptWindow.Text = "Script Window";
this.mnuScriptWindow.Click += new System.EventHandler(this.mnuScriptWindow_Click);
//
// mnuTextHooker
//
this.mnuTextHooker.Image = global::Mesen.GUI.Properties.Resources.Font;
this.mnuTextHooker.Name = "mnuTextHooker";
this.mnuTextHooker.Size = new System.Drawing.Size(171, 22);
this.mnuTextHooker.Text = "Text Hooker";
this.mnuTextHooker.Click += new System.EventHandler(this.mnuTextHooker_Click);
//
// mnuTraceLogger
//
this.mnuTraceLogger.Image = global::Mesen.GUI.Properties.Resources.LogWindow;
@ -1707,7 +1717,7 @@ namespace Mesen.GUI.Debugger
this.toolStripStatusLabel1,
this.lblCyclesElapsedCount,
this.lblCyclesElapsed});
this.statusStrip.Location = new System.Drawing.Point(0, 855);
this.statusStrip.Location = new System.Drawing.Point(0, 660);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(1075, 24);
this.statusStrip.TabIndex = 3;
@ -1762,7 +1772,7 @@ namespace Mesen.GUI.Debugger
// ctrlPpuMemoryMapping
//
this.ctrlPpuMemoryMapping.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ctrlPpuMemoryMapping.Location = new System.Drawing.Point(0, 822);
this.ctrlPpuMemoryMapping.Location = new System.Drawing.Point(0, 627);
this.ctrlPpuMemoryMapping.Name = "ctrlPpuMemoryMapping";
this.ctrlPpuMemoryMapping.Size = new System.Drawing.Size(1075, 33);
this.ctrlPpuMemoryMapping.TabIndex = 5;
@ -1772,7 +1782,7 @@ namespace Mesen.GUI.Debugger
// ctrlCpuMemoryMapping
//
this.ctrlCpuMemoryMapping.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ctrlCpuMemoryMapping.Location = new System.Drawing.Point(0, 789);
this.ctrlCpuMemoryMapping.Location = new System.Drawing.Point(0, 594);
this.ctrlCpuMemoryMapping.Name = "ctrlCpuMemoryMapping";
this.ctrlCpuMemoryMapping.Size = new System.Drawing.Size(1075, 33);
this.ctrlCpuMemoryMapping.TabIndex = 4;
@ -1792,7 +1802,7 @@ namespace Mesen.GUI.Debugger
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(1075, 879);
this.ClientSize = new System.Drawing.Size(1075, 684);
this.Controls.Add(this.splitContainer);
this.Controls.Add(this.ctrlCpuMemoryMapping);
this.Controls.Add(this.ctrlPpuMemoryMapping);
@ -2007,5 +2017,6 @@ namespace Mesen.GUI.Debugger
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem mnuUseVerticalLayout;
private System.Windows.Forms.ToolStripMenuItem mnuBreakOnUninitMemoryRead;
private System.Windows.Forms.ToolStripMenuItem mnuTextHooker;
}
}

View file

@ -265,6 +265,7 @@ namespace Mesen.GUI.Debugger
mnuPpuViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenPpuViewer));
mnuScriptWindow.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenScriptWindow));
mnuTraceLogger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTraceLogger));
mnuTextHooker.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTextHooker));
}
private void InitToolbar()
@ -277,7 +278,7 @@ namespace Mesen.GUI.Debugger
mnuRunPpuCycle, mnuRunScanline, mnuRunOneFrame, null,
mnuToggleBreakpoint, mnuDisableEnableBreakpoint, null,
mnuFind, mnuFindPrev, mnuFindNext, null,
mnuApuViewer, mnuAssembler, mnuEventViewer, mnuMemoryViewer, mnuPpuViewer, mnuScriptWindow, mnuTraceLogger, null,
mnuApuViewer, mnuAssembler, mnuEventViewer, mnuMemoryViewer, mnuPpuViewer, mnuScriptWindow, mnuTextHooker, mnuTraceLogger, null,
mnuEditHeader, null,
mnuSplitView, mnuUseVerticalLayout, null
);
@ -963,6 +964,11 @@ namespace Mesen.GUI.Debugger
}
}
private void mnuTextHooker_Click(object sender, EventArgs e)
{
DebugWindowManager.OpenDebugWindow(DebugWindow.TextHooker);
}
private void mnuTraceLogger_Click(object sender, EventArgs e)
{
DebugWindowManager.OpenDebugWindow(DebugWindow.TraceLogger);

View file

@ -40,6 +40,7 @@ namespace Mesen.GUI.Debugger
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRefreshOnBreak = new System.Windows.Forms.ToolStripMenuItem();
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgNametableViewer = new System.Windows.Forms.TabPage();
this.ctrlNametableViewer = new Mesen.GUI.Debugger.Controls.ctrlNametableViewer();
@ -49,20 +50,13 @@ namespace Mesen.GUI.Debugger
this.ctrlSpriteViewer = new Mesen.GUI.Debugger.Controls.ctrlSpriteViewer();
this.tpgPaletteViewer = new System.Windows.Forms.TabPage();
this.ctrlPaletteViewer = new Mesen.GUI.Debugger.Controls.ctrlPaletteViewer();
this.flpRefreshTiming = new System.Windows.Forms.FlowLayoutPanel();
this.lblShowFrameAt = new System.Windows.Forms.Label();
this.nudScanline = new Mesen.GUI.Controls.MesenNumericUpDown();
this.lblCycle = new System.Windows.Forms.Label();
this.nudCycle = new Mesen.GUI.Controls.MesenNumericUpDown();
this.btnReset = new System.Windows.Forms.Button();
this.mnuRefreshOnBreak = new System.Windows.Forms.ToolStripMenuItem();
this.ctrlScanlineCycle = new Mesen.GUI.Debugger.Controls.ctrlScanlineCycleSelect();
this.menuStrip1.SuspendLayout();
this.tabMain.SuspendLayout();
this.tpgNametableViewer.SuspendLayout();
this.tpgChrViewer.SuspendLayout();
this.tpgSpriteViewer.SuspendLayout();
this.tpgPaletteViewer.SuspendLayout();
this.flpRefreshTiming.SuspendLayout();
this.SuspendLayout();
//
// menuStrip1
@ -126,6 +120,14 @@ namespace Mesen.GUI.Debugger
this.mnuAutoRefresh.Text = "Auto-refresh";
this.mnuAutoRefresh.Click += new System.EventHandler(this.mnuAutoRefresh_Click);
//
// mnuRefreshOnBreak
//
this.mnuRefreshOnBreak.CheckOnClick = true;
this.mnuRefreshOnBreak.Name = "mnuRefreshOnBreak";
this.mnuRefreshOnBreak.Size = new System.Drawing.Size(198, 22);
this.mnuRefreshOnBreak.Text = "Refresh on pause/break";
this.mnuRefreshOnBreak.Click += new System.EventHandler(this.mnuRefreshOnBreak_Click);
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgNametableViewer);
@ -136,7 +138,7 @@ namespace Mesen.GUI.Debugger
this.tabMain.Location = new System.Drawing.Point(0, 24);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(709, 551);
this.tabMain.Size = new System.Drawing.Size(709, 553);
this.tabMain.TabIndex = 3;
this.tabMain.SelectedIndexChanged += new System.EventHandler(this.tabMain_SelectedIndexChanged);
//
@ -145,7 +147,7 @@ namespace Mesen.GUI.Debugger
this.tpgNametableViewer.Controls.Add(this.ctrlNametableViewer);
this.tpgNametableViewer.Location = new System.Drawing.Point(4, 22);
this.tpgNametableViewer.Name = "tpgNametableViewer";
this.tpgNametableViewer.Size = new System.Drawing.Size(701, 525);
this.tpgNametableViewer.Size = new System.Drawing.Size(701, 527);
this.tpgNametableViewer.TabIndex = 0;
this.tpgNametableViewer.Text = "Nametable Viewer";
this.tpgNametableViewer.UseVisualStyleBackColor = true;
@ -155,7 +157,7 @@ namespace Mesen.GUI.Debugger
this.ctrlNametableViewer.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlNametableViewer.Location = new System.Drawing.Point(0, 0);
this.ctrlNametableViewer.Name = "ctrlNametableViewer";
this.ctrlNametableViewer.Size = new System.Drawing.Size(701, 525);
this.ctrlNametableViewer.Size = new System.Drawing.Size(701, 527);
this.ctrlNametableViewer.TabIndex = 0;
this.ctrlNametableViewer.OnSelectChrTile += new System.EventHandler(this.ctrlNametableViewer_OnSelectChrTile);
//
@ -215,118 +217,13 @@ namespace Mesen.GUI.Debugger
this.ctrlPaletteViewer.Size = new System.Drawing.Size(701, 525);
this.ctrlPaletteViewer.TabIndex = 0;
//
// flpRefreshTiming
// ctrlScanlineCycle
//
this.flpRefreshTiming.Controls.Add(this.lblShowFrameAt);
this.flpRefreshTiming.Controls.Add(this.nudScanline);
this.flpRefreshTiming.Controls.Add(this.lblCycle);
this.flpRefreshTiming.Controls.Add(this.nudCycle);
this.flpRefreshTiming.Controls.Add(this.btnReset);
this.flpRefreshTiming.Dock = System.Windows.Forms.DockStyle.Bottom;
this.flpRefreshTiming.Location = new System.Drawing.Point(0, 575);
this.flpRefreshTiming.Name = "flpRefreshTiming";
this.flpRefreshTiming.Size = new System.Drawing.Size(709, 30);
this.flpRefreshTiming.TabIndex = 4;
//
// lblShowFrameAt
//
this.lblShowFrameAt.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblShowFrameAt.AutoSize = true;
this.lblShowFrameAt.Location = new System.Drawing.Point(3, 8);
this.lblShowFrameAt.Name = "lblShowFrameAt";
this.lblShowFrameAt.Size = new System.Drawing.Size(266, 13);
this.lblShowFrameAt.TabIndex = 0;
this.lblShowFrameAt.Text = "When emulation is running, show PPU data at scanline";
//
// nudScanline
//
this.nudScanline.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.nudScanline.DecimalPlaces = 0;
this.nudScanline.Increment = new decimal(new int[] {
1,
0,
0,
0});
this.nudScanline.Location = new System.Drawing.Point(275, 4);
this.nudScanline.Maximum = new decimal(new int[] {
260,
0,
0,
0});
this.nudScanline.MaximumSize = new System.Drawing.Size(10000, 20);
this.nudScanline.Minimum = new decimal(new int[] {
1,
0,
0,
-2147483648});
this.nudScanline.Name = "nudScanline";
this.nudScanline.Size = new System.Drawing.Size(52, 20);
this.nudScanline.TabIndex = 5;
this.nudScanline.Value = new decimal(new int[] {
241,
0,
0,
0});
this.nudScanline.ValueChanged += new System.EventHandler(this.nudScanlineCycle_ValueChanged);
//
// lblCycle
//
this.lblCycle.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblCycle.AutoSize = true;
this.lblCycle.Location = new System.Drawing.Point(333, 8);
this.lblCycle.Name = "lblCycle";
this.lblCycle.Size = new System.Drawing.Size(53, 13);
this.lblCycle.TabIndex = 5;
this.lblCycle.Text = "and cycle";
//
// nudCycle
//
this.nudCycle.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.nudCycle.DecimalPlaces = 0;
this.nudCycle.Increment = new decimal(new int[] {
1,
0,
0,
0});
this.nudCycle.Location = new System.Drawing.Point(392, 4);
this.nudCycle.Maximum = new decimal(new int[] {
340,
0,
0,
0});
this.nudCycle.MaximumSize = new System.Drawing.Size(10000, 20);
this.nudCycle.Minimum = new decimal(new int[] {
0,
0,
0,
0});
this.nudCycle.Name = "nudCycle";
this.nudCycle.Size = new System.Drawing.Size(52, 20);
this.nudCycle.TabIndex = 6;
this.nudCycle.Value = new decimal(new int[] {
0,
0,
0,
0});
this.nudCycle.ValueChanged += new System.EventHandler(this.nudScanlineCycle_ValueChanged);
//
// btnReset
//
this.btnReset.Location = new System.Drawing.Point(450, 3);
this.btnReset.Name = "btnReset";
this.btnReset.Size = new System.Drawing.Size(75, 23);
this.btnReset.TabIndex = 7;
this.btnReset.Text = "Reset";
this.btnReset.UseVisualStyleBackColor = true;
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
//
// mnuRefreshOnBreak
//
this.mnuRefreshOnBreak.CheckOnClick = true;
this.mnuRefreshOnBreak.Name = "mnuRefreshOnBreak";
this.mnuRefreshOnBreak.Size = new System.Drawing.Size(198, 22);
this.mnuRefreshOnBreak.Text = "Refresh on pause/break";
this.mnuRefreshOnBreak.Click += new System.EventHandler(this.mnuRefreshOnBreak_Click);
this.ctrlScanlineCycle.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ctrlScanlineCycle.Location = new System.Drawing.Point(0, 577);
this.ctrlScanlineCycle.Name = "ctrlScanlineCycle";
this.ctrlScanlineCycle.Size = new System.Drawing.Size(709, 28);
this.ctrlScanlineCycle.TabIndex = 4;
//
// frmPpuViewer
//
@ -335,7 +232,7 @@ namespace Mesen.GUI.Debugger
this.ClientSize = new System.Drawing.Size(709, 605);
this.Controls.Add(this.tabMain);
this.Controls.Add(this.menuStrip1);
this.Controls.Add(this.flpRefreshTiming);
this.Controls.Add(this.ctrlScanlineCycle);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MainMenuStrip = this.menuStrip1;
this.MaximizeBox = false;
@ -350,8 +247,6 @@ namespace Mesen.GUI.Debugger
this.tpgChrViewer.ResumeLayout(false);
this.tpgSpriteViewer.ResumeLayout(false);
this.tpgPaletteViewer.ResumeLayout(false);
this.flpRefreshTiming.ResumeLayout(false);
this.flpRefreshTiming.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
@ -375,12 +270,7 @@ namespace Mesen.GUI.Debugger
private System.Windows.Forms.TabPage tpgPaletteViewer;
private Controls.ctrlPaletteViewer ctrlPaletteViewer;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.FlowLayoutPanel flpRefreshTiming;
private System.Windows.Forms.Label lblShowFrameAt;
private MesenNumericUpDown nudScanline;
private System.Windows.Forms.Label lblCycle;
private MesenNumericUpDown nudCycle;
private System.Windows.Forms.Button btnReset;
private System.Windows.Forms.ToolStripMenuItem mnuRefreshOnBreak;
private Controls.ctrlScanlineCycleSelect ctrlScanlineCycle;
}
}

View file

@ -28,8 +28,7 @@ namespace Mesen.GUI.Debugger
{
InitializeComponent();
_ppuViewerId = _nextPpuViewerId;
_nextPpuViewerId++;
_ppuViewerId = GetNextPpuViewerId();
this._selectedTab = this.tpgNametableViewer;
this.mnuAutoRefresh.Checked = ConfigManager.Config.DebugInfo.PpuAutoRefresh;
@ -42,6 +41,11 @@ namespace Mesen.GUI.Debugger
}
}
public static int GetNextPpuViewerId()
{
return _nextPpuViewerId++;
}
private void InitShortcuts()
{
mnuRefresh.InitShortcut(this, nameof(DebuggerShortcutsConfig.Refresh));
@ -55,10 +59,7 @@ namespace Mesen.GUI.Debugger
this._notifListener = new InteropEmu.NotificationListener();
this._notifListener.OnNotification += this._notifListener_OnNotification;
this.nudScanline.Value = ConfigManager.Config.DebugInfo.PpuDisplayScanline;
this.nudCycle.Value = ConfigManager.Config.DebugInfo.PpuDisplayCycle;
InteropEmu.DebugSetPpuViewerScanlineCycle(_ppuViewerId, (int)this.nudScanline.Value, (int)this.nudCycle.Value);
this.ctrlScanlineCycle.Initialize(_ppuViewerId, ConfigManager.Config.DebugInfo.PpuDisplayScanline, ConfigManager.Config.DebugInfo.PpuDisplayCycle);
this.ctrlNametableViewer.GetData();
this.ctrlChrViewer.GetData();
@ -79,6 +80,8 @@ namespace Mesen.GUI.Debugger
base.OnFormClosing(e);
this._notifListener.OnNotification -= this._notifListener_OnNotification;
ConfigManager.Config.DebugInfo.PpuWindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
ConfigManager.Config.DebugInfo.PpuDisplayScanline = ctrlScanlineCycle.Scanline;
ConfigManager.Config.DebugInfo.PpuDisplayCycle = ctrlScanlineCycle.Cycle;
ConfigManager.ApplyChanges();
InteropEmu.DebugClearPpuViewerSettings(_ppuViewerId);
}
@ -107,7 +110,7 @@ namespace Mesen.GUI.Debugger
case InteropEmu.ConsoleNotificationType.GameLoaded:
//Configuration is lost when debugger is restarted (when switching game or power cycling)
InteropEmu.DebugSetPpuViewerScanlineCycle(_ppuViewerId, ConfigManager.Config.DebugInfo.PpuDisplayScanline, ConfigManager.Config.DebugInfo.PpuDisplayCycle);
ctrlScanlineCycle.RefreshSettings();
break;
}
}
@ -163,22 +166,6 @@ namespace Mesen.GUI.Debugger
ConfigManager.ApplyChanges();
}
private void SetUpdateScanlineCycle(int scanline, int cycle)
{
scanline = Math.Min(260, Math.Max(-1, scanline));
cycle = Math.Min(340, Math.Max(0, cycle));
InteropEmu.DebugSetPpuViewerScanlineCycle(_ppuViewerId, scanline, cycle);
ConfigManager.Config.DebugInfo.PpuDisplayScanline = scanline;
ConfigManager.Config.DebugInfo.PpuDisplayCycle = cycle;
ConfigManager.ApplyChanges();
}
private void nudScanlineCycle_ValueChanged(object sender, EventArgs e)
{
SetUpdateScanlineCycle((int)this.nudScanline.Value, (int)this.nudCycle.Value);
}
private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
{
this._selectedTab = this.tabMain.SelectedTab;
@ -189,15 +176,9 @@ namespace Mesen.GUI.Debugger
}
}
private void btnReset_Click(object sender, EventArgs e)
{
this.nudScanline.Value = 241;
this.nudCycle.Value = 0;
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(!this.nudScanline.ContainsFocus && !this.nudCycle.ContainsFocus) {
if(!this.ctrlScanlineCycle.ContainsFocus) {
if(keyData == ConfigManager.Config.DebugInfo.Shortcuts.Copy) {
if(this.tabMain.SelectedTab == tpgNametableViewer) {
ctrlNametableViewer.CopyToClipboard();

222
GUI.NET/Debugger/frmTextHooker.Designer.cs generated Normal file
View file

@ -0,0 +1,222 @@
using Mesen.GUI.Controls;
namespace Mesen.GUI.Debugger
{
partial class frmTextHooker
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
if(this._notifListener != null) {
this._notifListener.Dispose();
this._notifListener = null;
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.menuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
this.viewToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.mnuRefreshOnBreak = new System.Windows.Forms.ToolStripMenuItem();
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgTextHooker = new System.Windows.Forms.TabPage();
this.ctrlTextHooker = new Mesen.GUI.Debugger.Controls.ctrlTextHooker();
this.tpgCharacterMappings = new System.Windows.Forms.TabPage();
this.ctrlCharacterMappings = new Mesen.GUI.Debugger.Controls.ctrlCharacterMappings();
this.ctrlScanlineCycle = new Mesen.GUI.Debugger.Controls.ctrlScanlineCycleSelect();
this.menuStrip1.SuspendLayout();
this.tabMain.SuspendLayout();
this.tpgTextHooker.SuspendLayout();
this.tpgCharacterMappings.SuspendLayout();
this.SuspendLayout();
//
// menuStrip1
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.viewToolStripMenuItem});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(857, 24);
this.menuStrip1.TabIndex = 2;
this.menuStrip1.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuClose});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
//
// mnuClose
//
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
this.mnuClose.Name = "mnuClose";
this.mnuClose.Size = new System.Drawing.Size(103, 22);
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
// viewToolStripMenuItem
//
this.viewToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuRefresh,
this.toolStripMenuItem1,
this.mnuAutoRefresh,
this.mnuRefreshOnBreak});
this.viewToolStripMenuItem.Name = "viewToolStripMenuItem";
this.viewToolStripMenuItem.Size = new System.Drawing.Size(44, 20);
this.viewToolStripMenuItem.Text = "View";
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Reset;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(198, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(195, 6);
//
// mnuAutoRefresh
//
this.mnuAutoRefresh.Checked = true;
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(198, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
this.mnuAutoRefresh.Click += new System.EventHandler(this.mnuAutoRefresh_Click);
//
// mnuRefreshOnBreak
//
this.mnuRefreshOnBreak.CheckOnClick = true;
this.mnuRefreshOnBreak.Name = "mnuRefreshOnBreak";
this.mnuRefreshOnBreak.Size = new System.Drawing.Size(198, 22);
this.mnuRefreshOnBreak.Text = "Refresh on pause/break";
this.mnuRefreshOnBreak.Click += new System.EventHandler(this.mnuRefreshOnBreak_Click);
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgTextHooker);
this.tabMain.Controls.Add(this.tpgCharacterMappings);
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabMain.Location = new System.Drawing.Point(0, 24);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(857, 515);
this.tabMain.TabIndex = 3;
this.tabMain.SelectedIndexChanged += new System.EventHandler(this.tabMain_SelectedIndexChanged);
//
// tpgTextHooker
//
this.tpgTextHooker.Controls.Add(this.ctrlTextHooker);
this.tpgTextHooker.Location = new System.Drawing.Point(4, 22);
this.tpgTextHooker.Name = "tpgTextHooker";
this.tpgTextHooker.Size = new System.Drawing.Size(849, 489);
this.tpgTextHooker.TabIndex = 0;
this.tpgTextHooker.Text = "Text Hooker";
this.tpgTextHooker.UseVisualStyleBackColor = true;
//
// ctrlTextHooker
//
this.ctrlTextHooker.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlTextHooker.Location = new System.Drawing.Point(0, 0);
this.ctrlTextHooker.Name = "ctrlTextHooker";
this.ctrlTextHooker.Size = new System.Drawing.Size(849, 489);
this.ctrlTextHooker.TabIndex = 0;
//
// tpgCharacterMappings
//
this.tpgCharacterMappings.Controls.Add(this.ctrlCharacterMappings);
this.tpgCharacterMappings.Location = new System.Drawing.Point(4, 22);
this.tpgCharacterMappings.Name = "tpgCharacterMappings";
this.tpgCharacterMappings.Size = new System.Drawing.Size(849, 489);
this.tpgCharacterMappings.TabIndex = 1;
this.tpgCharacterMappings.Text = "Character Mappings";
this.tpgCharacterMappings.UseVisualStyleBackColor = true;
//
// ctrlCharacterMappings
//
this.ctrlCharacterMappings.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlCharacterMappings.Location = new System.Drawing.Point(0, 0);
this.ctrlCharacterMappings.Name = "ctrlCharacterMappings";
this.ctrlCharacterMappings.Size = new System.Drawing.Size(849, 489);
this.ctrlCharacterMappings.TabIndex = 0;
//
// ctrlScanlineCycle
//
this.ctrlScanlineCycle.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ctrlScanlineCycle.Location = new System.Drawing.Point(0, 539);
this.ctrlScanlineCycle.Name = "ctrlScanlineCycle";
this.ctrlScanlineCycle.Size = new System.Drawing.Size(857, 28);
this.ctrlScanlineCycle.TabIndex = 4;
//
// frmTextHooker
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(857, 567);
this.Controls.Add(this.tabMain);
this.Controls.Add(this.ctrlScanlineCycle);
this.Controls.Add(this.menuStrip1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MainMenuStrip = this.menuStrip1;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "frmTextHooker";
this.Text = "Text Hooker";
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.tabMain.ResumeLayout(false);
this.tpgTextHooker.ResumeLayout(false);
this.tpgCharacterMappings.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Mesen.GUI.Controls.ctrlMesenMenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuClose;
private System.Windows.Forms.ToolStripMenuItem viewToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuRefresh;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefresh;
private System.Windows.Forms.TabControl tabMain;
private System.Windows.Forms.TabPage tpgTextHooker;
private System.Windows.Forms.TabPage tpgCharacterMappings;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuRefreshOnBreak;
private Controls.ctrlTextHooker ctrlTextHooker;
private Controls.ctrlCharacterMappings ctrlCharacterMappings;
private Controls.ctrlScanlineCycleSelect ctrlScanlineCycle;
}
}

View file

@ -0,0 +1,202 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmTextHooker : BaseForm
{
private static Dictionary<string, string> _defaultCharMappings = new Dictionary<string, string>();
private ConcurrentDictionary<string, string> _charMappings = new ConcurrentDictionary<string, string>();
private DateTime _lastUpdate = DateTime.MinValue;
private InteropEmu.NotificationListener _notifListener;
private TabPage _selectedTab;
private bool _refreshing = false;
private int _ppuViewerId = 0;
public frmTextHooker()
{
InitializeComponent();
_ppuViewerId = frmPpuViewer.GetNextPpuViewerId();
this._selectedTab = this.tpgTextHooker;
this.mnuAutoRefresh.Checked = ConfigManager.Config.DebugInfo.TextHookerAutoRefresh;
this.mnuRefreshOnBreak.Checked = ConfigManager.Config.DebugInfo.TextHookerRefreshOnBreak;
if(ConfigManager.Config.DebugInfo.TextHookerWindowLocation.HasValue) {
this.StartPosition = FormStartPosition.Manual;
this.Location = ConfigManager.Config.DebugInfo.TextHookerWindowLocation.Value;
}
}
static frmTextHooker()
{
char[] separator = new char[] { ',' };
foreach(string mappingRow in ResourceManager.ReadZippedResource("CharacterMappings.txt").Replace("\r", "").Split('\n')) {
string[] parts = mappingRow.Split(separator, 2);
if(parts.Length == 2) {
_defaultCharMappings[parts[0]] = parts[1];
}
}
}
private void InitShortcuts()
{
mnuRefresh.InitShortcut(this, nameof(DebuggerShortcutsConfig.Refresh));
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(!this.DesignMode) {
this._charMappings = new ConcurrentDictionary<string, string>();
foreach(KeyValuePair<string, string> kvp in _defaultCharMappings) {
this._charMappings[kvp.Key] = kvp.Value;
}
foreach(CharMap mapping in ConfigManager.Config.DebugInfo.TextHookerCharMappings) {
this._charMappings[mapping.Key] = mapping.Value;
}
this.ctrlScanlineCycle.Initialize(_ppuViewerId, ConfigManager.Config.DebugInfo.TextHookerDisplayScanline, ConfigManager.Config.DebugInfo.TextHookerDisplayCycle);
this.ctrlTextHooker.SetCharacterMappings(_charMappings);
this.ctrlCharacterMappings.SetCharacterMappings(_charMappings);
this._notifListener = new InteropEmu.NotificationListener();
this._notifListener.OnNotification += this._notifListener_OnNotification;
this.ctrlTextHooker.GetData();
this.ctrlCharacterMappings.GetData();
this.ctrlTextHooker.RefreshViewer();
this.ctrlCharacterMappings.RefreshViewer();
this.InitShortcuts();
}
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
this._notifListener.OnNotification -= this._notifListener_OnNotification;
InteropEmu.DebugClearPpuViewerSettings(_ppuViewerId);
List<CharMap> mappings = new List<CharMap>();
foreach(KeyValuePair<string, string> kvp in _charMappings) {
if(!string.IsNullOrWhiteSpace(kvp.Value)) {
string defaultMapping;
if(_defaultCharMappings.TryGetValue(kvp.Key, out defaultMapping)) {
if(defaultMapping == kvp.Value) {
//Don't save mapping in user's profile if it matches the built-in mappings
continue;
}
}
mappings.Add(new CharMap() { Key = kvp.Key, Value = kvp.Value });
}
}
ConfigManager.Config.DebugInfo.TextHookerCharMappings = mappings;
ConfigManager.Config.DebugInfo.TextHookerWindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
ConfigManager.Config.DebugInfo.TextHookerDisplayScanline = ctrlScanlineCycle.Scanline;
ConfigManager.Config.DebugInfo.TextHookerDisplayCycle = ctrlScanlineCycle.Cycle;
ConfigManager.ApplyChanges();
}
private void _notifListener_OnNotification(InteropEmu.NotificationEventArgs e)
{
switch(e.NotificationType) {
case InteropEmu.ConsoleNotificationType.CodeBreak:
case InteropEmu.ConsoleNotificationType.GamePaused:
if(ConfigManager.Config.DebugInfo.TextHookerRefreshOnBreak) {
this.GetData();
this.BeginInvoke((MethodInvoker)(() => this.RefreshViewers()));
}
break;
case InteropEmu.ConsoleNotificationType.PpuViewerDisplayFrame:
if(e.Parameter.ToInt32() == _ppuViewerId) {
if(ConfigManager.Config.DebugInfo.TextHookerAutoRefresh && !_refreshing && (DateTime.Now - _lastUpdate).Milliseconds > 66) {
//Update at 15 fps at most
this.GetData();
this.BeginInvoke((MethodInvoker)(() => this.RefreshViewers()));
_lastUpdate = DateTime.Now;
}
}
break;
case InteropEmu.ConsoleNotificationType.GameLoaded:
//Configuration is lost when debugger is restarted (when switching game or power cycling)
ctrlScanlineCycle.RefreshSettings();
break;
}
}
private void GetData()
{
if(_selectedTab == this.tpgTextHooker) {
this.ctrlTextHooker.GetData();
} else if(_selectedTab == this.tpgCharacterMappings) {
this.ctrlCharacterMappings.GetData();
}
}
private void RefreshViewers()
{
_refreshing = true;
if(_selectedTab == this.tpgTextHooker) {
this.ctrlTextHooker.RefreshViewer();
} else if(_selectedTab == this.tpgCharacterMappings) {
this.ctrlCharacterMappings.RefreshViewer();
}
_refreshing = false;
}
private void mnuRefresh_Click(object sender, EventArgs e)
{
this.GetData();
this.RefreshViewers();
}
private void mnuClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void mnuAutoRefresh_Click(object sender, EventArgs e)
{
ConfigManager.Config.DebugInfo.TextHookerAutoRefresh = this.mnuAutoRefresh.Checked;
ConfigManager.ApplyChanges();
}
private void mnuRefreshOnBreak_Click(object sender, EventArgs e)
{
ConfigManager.Config.DebugInfo.TextHookerRefreshOnBreak = this.mnuRefreshOnBreak.Checked;
ConfigManager.ApplyChanges();
}
private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
{
this._selectedTab = this.tabMain.SelectedTab;
if(InteropEmu.DebugIsExecutionStopped()) {
//Refresh data when changing tabs when not running
this.GetData();
this.RefreshViewers();
}
}
}
}

View file

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>
</root>

File diff suppressed because it is too large Load diff

View file

@ -1145,5 +1145,10 @@
<Value ID="Undefined2">Undefined (2)</Value>
<Value ID="Undefined3">Undefined (3)</Value>
</Enum>
<Enum ID="DakutenMode">
<Value ID="Ignore">Ignore</Value>
<Value ID="OnTheRight">On the right</Value>
<Value ID="OnTop">On top</Value>
</Enum>
</Enums>
</Resources>

View file

@ -181,6 +181,8 @@ namespace Mesen.GUI.Forms
this.mnuRunAutomaticTest = new System.Windows.Forms.ToolStripMenuItem();
this.mnuDebugger = new System.Windows.Forms.ToolStripMenuItem();
this.mnuLogWindow = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem27 = new System.Windows.Forms.ToolStripSeparator();
this.mnuInstallHdPack = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHdPackEditor = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuRandomGame = new System.Windows.Forms.ToolStripMenuItem();
@ -193,6 +195,7 @@ namespace Mesen.GUI.Forms
this.mnuMemoryViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPpuViewer = new System.Windows.Forms.ToolStripMenuItem();
this.mnuScriptWindow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTextHooker = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem25 = new System.Windows.Forms.ToolStripSeparator();
this.mnuEditHeader = new System.Windows.Forms.ToolStripMenuItem();
@ -205,8 +208,6 @@ namespace Mesen.GUI.Forms
this.mnuReportBug = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem27 = new System.Windows.Forms.ToolStripSeparator();
this.mnuInstallHdPack = new System.Windows.Forms.ToolStripMenuItem();
this.panelRenderer.SuspendLayout();
this.panelInfo.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picIcon)).BeginInit();
@ -1443,6 +1444,19 @@ namespace Mesen.GUI.Forms
this.mnuLogWindow.Text = "Log Window";
this.mnuLogWindow.Click += new System.EventHandler(this.mnuLogWindow_Click);
//
// toolStripMenuItem27
//
this.toolStripMenuItem27.Name = "toolStripMenuItem27";
this.toolStripMenuItem27.Size = new System.Drawing.Size(179, 6);
//
// mnuInstallHdPack
//
this.mnuInstallHdPack.Image = global::Mesen.GUI.Properties.Resources.Import;
this.mnuInstallHdPack.Name = "mnuInstallHdPack";
this.mnuInstallHdPack.Size = new System.Drawing.Size(182, 22);
this.mnuInstallHdPack.Text = "Install HD Pack";
this.mnuInstallHdPack.Click += new System.EventHandler(this.mnuInstallHdPack_Click);
//
// mnuHdPackEditor
//
this.mnuHdPackEditor.Image = global::Mesen.GUI.Properties.Resources.HdPack;
@ -1480,6 +1494,7 @@ namespace Mesen.GUI.Forms
this.mnuMemoryViewer,
this.mnuPpuViewer,
this.mnuScriptWindow,
this.mnuTextHooker,
this.mnuTraceLogger,
this.toolStripMenuItem25,
this.mnuEditHeader});
@ -1546,6 +1561,14 @@ namespace Mesen.GUI.Forms
this.mnuScriptWindow.Text = "Script Window";
this.mnuScriptWindow.Click += new System.EventHandler(this.mnuScriptWindow_Click);
//
// mnuTextHooker
//
this.mnuTextHooker.Image = global::Mesen.GUI.Properties.Resources.Font;
this.mnuTextHooker.Name = "mnuTextHooker";
this.mnuTextHooker.Size = new System.Drawing.Size(162, 22);
this.mnuTextHooker.Text = "Text Hooker";
this.mnuTextHooker.Click += new System.EventHandler(this.mnuTextHooker_Click);
//
// mnuTraceLogger
//
this.mnuTraceLogger.Image = global::Mesen.GUI.Properties.Resources.LogWindow;
@ -1639,19 +1662,6 @@ namespace Mesen.GUI.Forms
this.mnuAbout.Text = "About";
this.mnuAbout.Click += new System.EventHandler(this.mnuAbout_Click);
//
// toolStripMenuItem27
//
this.toolStripMenuItem27.Name = "toolStripMenuItem27";
this.toolStripMenuItem27.Size = new System.Drawing.Size(179, 6);
//
// mnuInstallHdPack
//
this.mnuInstallHdPack.Image = global::Mesen.GUI.Properties.Resources.Import;
this.mnuInstallHdPack.Name = "mnuInstallHdPack";
this.mnuInstallHdPack.Size = new System.Drawing.Size(182, 22);
this.mnuInstallHdPack.Text = "Install HD Pack";
this.mnuInstallHdPack.Click += new System.EventHandler(this.mnuInstallHdPack_Click);
//
// frmMain
//
this.AllowDrop = true;
@ -1857,6 +1867,7 @@ namespace Mesen.GUI.Forms
private System.Windows.Forms.ToolStripMenuItem mnuLoadLastSession;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem27;
private System.Windows.Forms.ToolStripMenuItem mnuInstallHdPack;
private System.Windows.Forms.ToolStripMenuItem mnuTextHooker;
}
}

View file

@ -341,5 +341,10 @@ namespace Mesen.GUI.Forms
{
DebugWindowManager.OpenDebugWindow(DebugWindow.TraceLogger);
}
private void mnuTextHooker_Click(object sender, EventArgs e)
{
DebugWindowManager.OpenDebugWindow(DebugWindow.TextHooker);
}
}
}

View file

@ -710,6 +710,7 @@ namespace Mesen.GUI.Forms
mnuPpuViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenPpuViewer));
mnuScriptWindow.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenScriptWindow));
mnuTraceLogger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTraceLogger));
mnuTextHooker.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTextHooker));
}
private void BindShortcut(ToolStripMenuItem item, EmulatorShortcut shortcut, Func<bool> isActionEnabled = null)
@ -1041,6 +1042,7 @@ namespace Mesen.GUI.Forms
mnuEventViewer.Enabled = running;
mnuPpuViewer.Enabled = running;
mnuScriptWindow.Enabled = running;
mnuTextHooker.Enabled = running;
mnuTraceLogger.Enabled = running;
mnuInstallHdPack.Enabled = running;

View file

@ -392,6 +392,18 @@
<Compile Include="Debugger\Controls\ctrlAddressList.Designer.cs">
<DependentUpon>ctrlAddressList.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlCharacterMapping.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlCharacterMapping.Designer.cs">
<DependentUpon>ctrlCharacterMapping.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlCharacterMappings.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlCharacterMappings.Designer.cs">
<DependentUpon>ctrlCharacterMappings.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlCodeScrollbar.cs">
<SubType>Component</SubType>
</Compile>
@ -440,6 +452,18 @@
<Compile Include="Debugger\Controls\ctrlEventViewerPpuView.Designer.cs">
<DependentUpon>ctrlEventViewerPpuView.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlScanlineCycleSelect.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlScanlineCycleSelect.Designer.cs">
<DependentUpon>ctrlScanlineCycleSelect.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlTextHooker.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlTextHooker.Designer.cs">
<DependentUpon>ctrlTextHooker.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlProfiler.cs">
<SubType>UserControl</SubType>
</Compile>
@ -747,6 +771,12 @@
<Compile Include="Debugger\frmMemoryViewer.Designer.cs">
<DependentUpon>frmMemoryViewer.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmTextHooker.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmTextHooker.Designer.cs">
<DependentUpon>frmTextHooker.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmPpuViewer.cs">
<SubType>Form</SubType>
</Compile>
@ -1252,6 +1282,12 @@
<EmbeddedResource Include="Debugger\Controls\CodeViewerActions.resx">
<DependentUpon>CodeViewerActions.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlCharacterMapping.resx">
<DependentUpon>ctrlCharacterMapping.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlCharacterMappings.resx">
<DependentUpon>ctrlCharacterMappings.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlDbgShortcuts.resx">
<DependentUpon>ctrlDbgShortcuts.cs</DependentUpon>
</EmbeddedResource>
@ -1267,9 +1303,18 @@
<EmbeddedResource Include="Debugger\Controls\ctrlEventViewerPpuView.resx">
<DependentUpon>ctrlEventViewerPpuView.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlScanlineCycleSelect.resx">
<DependentUpon>ctrlScanlineCycleSelect.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlTextHooker.resx">
<DependentUpon>ctrlTextHooker.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlSourceViewer.resx">
<DependentUpon>ctrlSourceViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmTextHooker.resx">
<DependentUpon>frmTextHooker.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Dependencies\LuaScripts\Example.lua">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource>
@ -1663,6 +1708,9 @@
<None Include="Dependencies\Font.64.spritefont">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<Content Include="Dependencies\CharacterMappings.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Dependencies\PixelFont.ttf">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
@ -1808,7 +1856,6 @@
<EmbeddedResource Include="$(OutputPath)Dependencies.zip">
<Link>Dependencies\Dependencies.zip</Link>
</EmbeddedResource>
<Content Include="D:\Users\Saitoh Hajime\Desktop\Mesen Website\favicon.ico" />
<None Include="Resources\Close.png" />
<None Include="Resources\PreviousArrow.png" />
<None Include="Resources\NextArrow.png" />