Debugger: Double-click on tile in nametable/sprite viewers to show it in chr viewer
This commit is contained in:
parent
a169e538ae
commit
77bbe2e1da
7 changed files with 160 additions and 27 deletions
|
@ -54,21 +54,34 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
}
|
||||
}
|
||||
|
||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public int SelectedTileIndex
|
||||
{
|
||||
get { return cboChrSelection.SelectedIndex == 0 ? (_tileIndex + (_bottomBank ? 256 : 0)) : -1; }
|
||||
set
|
||||
{
|
||||
|
||||
_bottomBank = value >= 256 ? true : false;
|
||||
if(chkLargeSprites.Checked) {
|
||||
int y = (value % 256) / 16;
|
||||
int x = value % 16;
|
||||
int tmpX = x / 2 + ((y & 0x01) == 0x01 ? 8 : 0);
|
||||
int tmpY = (y & 0xFE) + ((x & 0x01) == 0x01 ? 1 : 0);
|
||||
_tileIndex = tmpY * 16 + tmpX;
|
||||
} else {
|
||||
_tileIndex = value % 256;
|
||||
}
|
||||
cboChrSelection.SelectedIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
||||
public int SelectedPaletteIndex
|
||||
{
|
||||
get { return cboPalette.SelectedIndex; }
|
||||
set
|
||||
{
|
||||
|
||||
cboPalette.SelectedIndex = value;
|
||||
this.RefreshPreview(_tileIndex, _bottomBank);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -58,6 +58,8 @@
|
|||
this.chkShowTileGrid = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowAttributeGrid = new System.Windows.Forms.CheckBox();
|
||||
this.chkHighlightChrTile = new System.Windows.Forms.CheckBox();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuShowInChrViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picNametable)).BeginInit();
|
||||
this.ctxMenu.SuspendLayout();
|
||||
|
@ -96,14 +98,17 @@
|
|||
this.picNametable.Size = new System.Drawing.Size(514, 482);
|
||||
this.picNametable.TabIndex = 0;
|
||||
this.picNametable.TabStop = false;
|
||||
this.picNametable.DoubleClick += new System.EventHandler(this.picNametable_DoubleClick);
|
||||
this.picNametable.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picNametable_MouseMove);
|
||||
//
|
||||
// ctxMenu
|
||||
//
|
||||
this.ctxMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuShowInChrViewer,
|
||||
this.toolStripMenuItem1,
|
||||
this.mnuCopyHdPack});
|
||||
this.ctxMenu.Name = "ctxMenu";
|
||||
this.ctxMenu.Size = new System.Drawing.Size(222, 26);
|
||||
this.ctxMenu.Size = new System.Drawing.Size(222, 76);
|
||||
this.ctxMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ctxMenu_Opening);
|
||||
//
|
||||
// mnuCopyHdPack
|
||||
|
@ -403,6 +408,18 @@
|
|||
this.chkHighlightChrTile.UseVisualStyleBackColor = true;
|
||||
this.chkHighlightChrTile.Click += new System.EventHandler(this.chkHighlightChrTile_Click);
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(218, 6);
|
||||
//
|
||||
// mnuShowInChrViewer
|
||||
//
|
||||
this.mnuShowInChrViewer.Name = "mnuShowInChrViewer";
|
||||
this.mnuShowInChrViewer.Size = new System.Drawing.Size(221, 22);
|
||||
this.mnuShowInChrViewer.Text = "Show in CHR viewer";
|
||||
this.mnuShowInChrViewer.Click += new System.EventHandler(this.mnuShowInChrViewer_Click);
|
||||
//
|
||||
// ctrlNametableViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -455,5 +472,7 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuCopyHdPack;
|
||||
private ctrlTilePalette ctrlTilePalette;
|
||||
private System.Windows.Forms.CheckBox chkHighlightChrTile;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowInChrViewer;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
{
|
||||
public partial class ctrlNametableViewer : BaseControl
|
||||
{
|
||||
public event EventHandler OnSelectChrTile;
|
||||
|
||||
private byte[][] _nametablePixelData = new byte[4][];
|
||||
private byte[][] _tileData = new byte[4][];
|
||||
private byte[][] _attributeData = new byte[4][];
|
||||
|
@ -70,13 +72,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
GCHandle handle = GCHandle.Alloc(_nametablePixelData[i], GCHandleType.Pinned);
|
||||
Bitmap source = new Bitmap(256, 240, 4*256, System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
|
||||
try {
|
||||
int xOffset = i % 2 == 0 ? 0 : 256;
|
||||
int yOffset = i <= 1 ? 0 : 240;
|
||||
gNametable.DrawImage(source, new Rectangle(xOffset, yOffset, 256, 240), new Rectangle(0, 0, 256, 240), GraphicsUnit.Pixel);
|
||||
|
||||
if(_chrViewer.SelectedTileIndex >= 0 && this.chkHighlightChrTile.Checked) {
|
||||
HighlightChrViewerTile(tileIndexOffset, gNametable, i, xOffset, yOffset);
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
@ -107,6 +103,12 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
using(Graphics g = Graphics.FromImage(target)) {
|
||||
g.DrawImage(_nametableImage, 0, 0);
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
if(_chrViewer.SelectedTileIndex >= 0 && this.chkHighlightChrTile.Checked) {
|
||||
HighlightChrViewerTile(tileIndexOffset, g, i);
|
||||
}
|
||||
}
|
||||
|
||||
if(this._gridOverlay != null) {
|
||||
g.DrawImage(this._gridOverlay, 0, 0);
|
||||
}
|
||||
|
@ -119,12 +121,15 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
this.picNametable.Image = target;
|
||||
}
|
||||
|
||||
private void HighlightChrViewerTile(int tileIndexOffset, Graphics gNametable, int i, int xOffset, int yOffset)
|
||||
private void HighlightChrViewerTile(int tileIndexOffset, Graphics dest, int nametableIndex)
|
||||
{
|
||||
int xOffset = nametableIndex % 2 == 0 ? 0 : 256;
|
||||
int yOffset = nametableIndex <= 1 ? 0 : 240;
|
||||
|
||||
using(Pen pen = new Pen(Color.Red, 2)) {
|
||||
for(int j = 0; j < 960; j++) {
|
||||
if(_tileData[i][j] + tileIndexOffset == _chrViewer.SelectedTileIndex) {
|
||||
gNametable.DrawRectangle(pen, new Rectangle(xOffset + (j%32)*8-1, yOffset + (j/32)*8-1, 10, 10));
|
||||
if(_tileData[nametableIndex][j] + tileIndexOffset == _chrViewer.SelectedTileIndex) {
|
||||
dest.DrawRectangle(pen, new Rectangle(xOffset + (j%32)*8-1, yOffset + (j/32)*8-1, 10, 10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,5 +303,31 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
_copyData = sb.ToString();
|
||||
}
|
||||
|
||||
private void ShowInChrViewer()
|
||||
{
|
||||
int tileIndex = _tileData[_nametableIndex][_tileY*32+_tileX];
|
||||
int attributeData = _attributeData[_nametableIndex][_tileY*32+_tileX];
|
||||
int shift = (_tileX & 0x02) | ((_tileY & 0x02) << 1);
|
||||
int paletteIndex = ((attributeData >> shift) & 0x03);
|
||||
|
||||
DebugState state = new DebugState();
|
||||
InteropEmu.DebugGetState(ref state);
|
||||
int tileIndexOffset = state.PPU.ControlFlags.BackgroundPatternAddr == 0x1000 ? 256 : 0;
|
||||
|
||||
_chrViewer.SelectedPaletteIndex = paletteIndex;
|
||||
_chrViewer.SelectedTileIndex = tileIndex + tileIndexOffset;
|
||||
OnSelectChrTile?.Invoke(null, EventArgs.Empty);
|
||||
}
|
||||
|
||||
private void picNametable_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
ShowInChrViewer();
|
||||
}
|
||||
|
||||
private void mnuShowInChrViewer_Click(object sender, EventArgs e)
|
||||
{
|
||||
ShowInChrViewer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,8 @@
|
|||
this.picSprites = new System.Windows.Forms.PictureBox();
|
||||
this.ctxMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
|
||||
this.mnuCopyHdPack = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuShowInChrViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.tableLayoutPanel3.SuspendLayout();
|
||||
this.grpSpriteInfo.SuspendLayout();
|
||||
this.tableLayoutPanel4.SuspendLayout();
|
||||
|
@ -163,11 +165,13 @@
|
|||
this.picPreview.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;
|
||||
this.picPreview.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.tableLayoutPanel4.SetColumnSpan(this.picPreview, 3);
|
||||
this.picPreview.ContextMenuStrip = this.ctxMenu;
|
||||
this.picPreview.Location = new System.Drawing.Point(94, 257);
|
||||
this.picPreview.Name = "picPreview";
|
||||
this.picPreview.Size = new System.Drawing.Size(258, 231);
|
||||
this.picPreview.TabIndex = 21;
|
||||
this.picPreview.TabStop = false;
|
||||
this.picPreview.DoubleClick += new System.EventHandler(this.picSprites_DoubleClick);
|
||||
this.picPreview.MouseLeave += new System.EventHandler(this.picPreview_MouseLeave);
|
||||
this.picPreview.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picPreview_MouseMove);
|
||||
//
|
||||
|
@ -351,15 +355,18 @@
|
|||
this.picSprites.Size = new System.Drawing.Size(258, 514);
|
||||
this.picSprites.TabIndex = 0;
|
||||
this.picSprites.TabStop = false;
|
||||
this.picSprites.DoubleClick += new System.EventHandler(this.picSprites_DoubleClick);
|
||||
this.picSprites.MouseLeave += new System.EventHandler(this.picSprites_MouseLeave);
|
||||
this.picSprites.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picSprites_MouseMove);
|
||||
//
|
||||
// ctxMenu
|
||||
//
|
||||
this.ctxMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.mnuShowInChrViewer,
|
||||
this.toolStripMenuItem1,
|
||||
this.mnuCopyHdPack});
|
||||
this.ctxMenu.Name = "ctxMenu";
|
||||
this.ctxMenu.Size = new System.Drawing.Size(222, 26);
|
||||
this.ctxMenu.Size = new System.Drawing.Size(222, 76);
|
||||
this.ctxMenu.Opening += new System.ComponentModel.CancelEventHandler(this.ctxMenu_Opening);
|
||||
//
|
||||
// mnuCopyHdPack
|
||||
|
@ -369,6 +376,18 @@
|
|||
this.mnuCopyHdPack.Text = "Copy Tile (HD Pack Format)";
|
||||
this.mnuCopyHdPack.Click += new System.EventHandler(this.mnuCopyHdPack_Click);
|
||||
//
|
||||
// toolStripMenuItem1
|
||||
//
|
||||
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(218, 6);
|
||||
//
|
||||
// mnuShowInChrViewer
|
||||
//
|
||||
this.mnuShowInChrViewer.Name = "mnuShowInChrViewer";
|
||||
this.mnuShowInChrViewer.Size = new System.Drawing.Size(221, 22);
|
||||
this.mnuShowInChrViewer.Text = "Show in CHR viewer";
|
||||
this.mnuShowInChrViewer.Click += new System.EventHandler(this.mnuShowInChrViewer_Click);
|
||||
//
|
||||
// ctrlSpriteViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -418,5 +437,7 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuCopyHdPack;
|
||||
private System.Windows.Forms.Label lblPalette;
|
||||
private ctrlTilePalette ctrlTilePalette;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuShowInChrViewer;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
{
|
||||
public partial class ctrlSpriteViewer : BaseControl
|
||||
{
|
||||
public delegate void SelectTilePaletteHandler(int tileIndex, int paletteIndex);
|
||||
public event SelectTilePaletteHandler OnSelectTilePalette;
|
||||
private byte[] _spriteRam;
|
||||
private byte[] _spritePixelData;
|
||||
private int _selectedSprite = -1;
|
||||
|
@ -26,11 +28,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
}
|
||||
|
||||
|
||||
public void GetData()
|
||||
{
|
||||
DebugState state = new DebugState();
|
||||
|
@ -67,8 +65,6 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
if(_previewMousePosition.HasValue) {
|
||||
SelectSpriteUnderCursor();
|
||||
} else {
|
||||
_selectedSprite = -1;
|
||||
}
|
||||
CreateScreenPreview();
|
||||
}
|
||||
|
@ -120,6 +116,8 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void picSprites_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
_previewMousePosition = null;
|
||||
|
||||
int tileX = Math.Min(e.X / 32, 31);
|
||||
int tileY = Math.Min(e.Y / 64, 63);
|
||||
int ramAddr = ((tileY << 3) + tileX) << 2;
|
||||
|
@ -198,6 +196,10 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void ctxMenu_Opening(object sender, CancelEventArgs e)
|
||||
{
|
||||
if(_selectedSprite < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ramAddr = _selectedSprite * 4;
|
||||
int spriteY = _spriteRam[ramAddr];
|
||||
int tileIndex = _spriteRam[ramAddr + 1];
|
||||
|
@ -262,9 +264,42 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
|
||||
private void picPreview_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
_previewMousePosition = null;
|
||||
_selectedSprite = -1;
|
||||
CreateScreenPreview();
|
||||
}
|
||||
|
||||
private void ShowInChrViewer()
|
||||
{
|
||||
if(_selectedSprite < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int ramAddr = _selectedSprite * 4;
|
||||
int tileIndex = _spriteRam[ramAddr + 1];
|
||||
int palette = (_spriteRam[ramAddr + 2] & 0x03) + 4;
|
||||
|
||||
DebugState state = new DebugState();
|
||||
InteropEmu.DebugGetState(ref state);
|
||||
|
||||
if(_largeSprites) {
|
||||
if(tileIndex % 2 == 1) {
|
||||
tileIndex += 256;
|
||||
tileIndex--;
|
||||
}
|
||||
OnSelectTilePalette?.Invoke(tileIndex, palette);
|
||||
} else {
|
||||
int tileIndexOffset = state.PPU.ControlFlags.SpritePatternAddr == 0x1000 ? 256 : 0;
|
||||
OnSelectTilePalette?.Invoke(tileIndex+tileIndexOffset, palette);
|
||||
}
|
||||
}
|
||||
|
||||
private void picSprites_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
ShowInChrViewer();
|
||||
}
|
||||
|
||||
private void mnuShowInChrViewer_Click(object sender, EventArgs e)
|
||||
{
|
||||
ShowInChrViewer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
10
GUI.NET/Debugger/frmPpuViewer.Designer.cs
generated
10
GUI.NET/Debugger/frmPpuViewer.Designer.cs
generated
|
@ -87,7 +87,7 @@
|
|||
//
|
||||
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
|
||||
this.mnuClose.Name = "mnuClose";
|
||||
this.mnuClose.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuClose.Size = new System.Drawing.Size(103, 22);
|
||||
this.mnuClose.Text = "Close";
|
||||
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
|
||||
//
|
||||
|
@ -106,14 +106,14 @@
|
|||
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Reset;
|
||||
this.mnuRefresh.Name = "mnuRefresh";
|
||||
this.mnuRefresh.ShortcutKeys = System.Windows.Forms.Keys.F5;
|
||||
this.mnuRefresh.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuRefresh.Size = new System.Drawing.Size(141, 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(149, 6);
|
||||
this.toolStripMenuItem1.Size = new System.Drawing.Size(138, 6);
|
||||
//
|
||||
// mnuAutoRefresh
|
||||
//
|
||||
|
@ -121,7 +121,7 @@
|
|||
this.mnuAutoRefresh.CheckOnClick = true;
|
||||
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
|
||||
this.mnuAutoRefresh.Size = new System.Drawing.Size(152, 22);
|
||||
this.mnuAutoRefresh.Size = new System.Drawing.Size(141, 22);
|
||||
this.mnuAutoRefresh.Text = "Auto-refresh";
|
||||
this.mnuAutoRefresh.Click += new System.EventHandler(this.mnuAutoRefresh_Click);
|
||||
//
|
||||
|
@ -157,6 +157,7 @@
|
|||
this.ctrlNametableViewer.Name = "ctrlNametableViewer";
|
||||
this.ctrlNametableViewer.Size = new System.Drawing.Size(695, 520);
|
||||
this.ctrlNametableViewer.TabIndex = 0;
|
||||
this.ctrlNametableViewer.OnSelectChrTile += new System.EventHandler(this.ctrlNametableViewer_OnSelectChrTile);
|
||||
//
|
||||
// tpgChrViewer
|
||||
//
|
||||
|
@ -194,6 +195,7 @@
|
|||
this.ctrlSpriteViewer.Name = "ctrlSpriteViewer";
|
||||
this.ctrlSpriteViewer.Size = new System.Drawing.Size(701, 526);
|
||||
this.ctrlSpriteViewer.TabIndex = 0;
|
||||
this.ctrlSpriteViewer.OnSelectTilePalette += new Mesen.GUI.Debugger.Controls.ctrlSpriteViewer.SelectTilePaletteHandler(this.ctrlSpriteViewer_OnSelectTilePalette);
|
||||
//
|
||||
// tpgPaletteViewer
|
||||
//
|
||||
|
|
|
@ -167,5 +167,17 @@ namespace Mesen.GUI.Debugger
|
|||
}
|
||||
return base.ProcessCmdKey(ref msg, keyData);
|
||||
}
|
||||
|
||||
private void ctrlNametableViewer_OnSelectChrTile(object sender, EventArgs e)
|
||||
{
|
||||
tabMain.SelectTab(tpgChrViewer);
|
||||
}
|
||||
|
||||
private void ctrlSpriteViewer_OnSelectTilePalette(int tileIndex, int paletteIndex)
|
||||
{
|
||||
ctrlChrViewer.SelectedTileIndex = tileIndex;
|
||||
ctrlChrViewer.SelectedPaletteIndex = paletteIndex;
|
||||
tabMain.SelectTab(tpgChrViewer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue