From 646996c580cd660a09c9b27fe6e337021043453a Mon Sep 17 00:00:00 2001 From: Sour Date: Sat, 30 Mar 2019 13:42:44 -0400 Subject: [PATCH] Debugger: Added color information to palette viewer --- UI/Debugger/PpuViewer/ctrlPaletteViewer.cs | 45 +++-- .../ctrlScanlineCycleSelect.designer.cs | 22 +-- .../PpuViewer/frmPaletteViewer.Designer.cs | 180 +++++++++++++++++- UI/Debugger/PpuViewer/frmPaletteViewer.cs | 19 ++ 4 files changed, 239 insertions(+), 27 deletions(-) diff --git a/UI/Debugger/PpuViewer/ctrlPaletteViewer.cs b/UI/Debugger/PpuViewer/ctrlPaletteViewer.cs index 86b6835..2e8d5b0 100644 --- a/UI/Debugger/PpuViewer/ctrlPaletteViewer.cs +++ b/UI/Debugger/PpuViewer/ctrlPaletteViewer.cs @@ -16,6 +16,9 @@ namespace Mesen.GUI.Debugger { public partial class ctrlPaletteViewer : BaseControl { + public delegate void SelectionChangedHandler(); + public event SelectionChangedHandler SelectionChanged; + private byte[] _cgRam; private Bitmap _paletteImage; @@ -34,25 +37,34 @@ namespace Mesen.GUI.Debugger picPalette.Image = _paletteImage; } + public byte[] CgRam + { + get { return _cgRam; } + } + public void RefreshData() { _cgRam = DebugApi.GetMemoryState(SnesMemoryType.CGRam); } + private uint To8Bit(int color) + { + return (uint)((color << 3) + (color >> 2)); + } + + public uint ToArgb(int rgb555) { + uint b = To8Bit(rgb555 >> 10); + uint g = To8Bit((rgb555 >> 5) & 0x1F); + uint r = To8Bit(rgb555 & 0x1F); + + return (0xFF000000 | (r << 16) | (g << 8) | b); + } + public void RefreshViewer() { - Func to8Bit = (int color) => { return (uint)((color << 3) + (color >> 2)); }; - Func toArgb = (int rgb555) => { - uint b = to8Bit(rgb555 >> 10); - uint g = to8Bit((rgb555 >> 5) & 0x1F); - uint r = to8Bit(rgb555 & 0x1F); - - return (0xFF000000 | (r << 16) | (g << 8) | b); - }; - UInt32[] argbPalette = new UInt32[256]; for(int i = 0; i < 256; i++) { - argbPalette[i] = toArgb(_cgRam[i * 2] | _cgRam[i * 2 + 1] << 8); + argbPalette[i] = ToArgb(_cgRam[i * 2] | _cgRam[i * 2 + 1] << 8); } using(Graphics g = Graphics.FromImage(_paletteImage)) { @@ -69,7 +81,9 @@ namespace Mesen.GUI.Debugger g.ResetTransform(); using(Pen pen = new Pen(Color.LightGray, 2)) { pen.DashStyle = DashStyle.Dash; - if(SelectionMode == PaletteSelectionMode.FourColors) { + if(SelectionMode == PaletteSelectionMode.SingleColor) { + g.DrawRectangle(pen, (SelectedPalette & 0x0F) * PaletteScale, (SelectedPalette / 16) * PaletteScale, PaletteScale, PaletteScale); + } else if(SelectionMode == PaletteSelectionMode.FourColors) { g.DrawRectangle(pen, (SelectedPalette & 0x03) * PaletteScale * 4, (SelectedPalette / 4) * PaletteScale, PaletteScale * 4, PaletteScale); } else if(SelectionMode == PaletteSelectionMode.SixteenColors) { g.DrawRectangle(pen, 0, SelectedPalette * PaletteScale, PaletteScale * 16, PaletteScale); @@ -87,19 +101,26 @@ namespace Mesen.GUI.Debugger private void picPalette_MouseClick(object sender, MouseEventArgs e) { int paletteIndex = 0; - if(SelectionMode == PaletteSelectionMode.FourColors) { + if(SelectionMode == PaletteSelectionMode.SingleColor) { + paletteIndex = (e.Y / PaletteScale) * 16 + (e.X / PaletteScale); + } else if(SelectionMode == PaletteSelectionMode.FourColors) { paletteIndex += e.X / (4 * PaletteScale); paletteIndex += (e.Y / PaletteScale) * 4; } else if(SelectionMode == PaletteSelectionMode.SixteenColors) { paletteIndex = (e.Y / PaletteScale); } SelectedPalette = paletteIndex; + + SelectionChanged?.Invoke(); + + RefreshViewer(); } } public enum PaletteSelectionMode { None, + SingleColor, FourColors, SixteenColors } diff --git a/UI/Debugger/PpuViewer/ctrlScanlineCycleSelect.designer.cs b/UI/Debugger/PpuViewer/ctrlScanlineCycleSelect.designer.cs index f8b4dd0..f99a1a2 100644 --- a/UI/Debugger/PpuViewer/ctrlScanlineCycleSelect.designer.cs +++ b/UI/Debugger/PpuViewer/ctrlScanlineCycleSelect.designer.cs @@ -46,7 +46,7 @@ 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(399, 28); + this.flpRefreshTiming.Size = new System.Drawing.Size(317, 28); this.flpRefreshTiming.TabIndex = 5; // // lblShowFrameAt @@ -55,9 +55,9 @@ this.lblShowFrameAt.AutoSize = true; this.lblShowFrameAt.Location = new System.Drawing.Point(3, 8); this.lblShowFrameAt.Name = "lblShowFrameAt"; - this.lblShowFrameAt.Size = new System.Drawing.Size(135, 13); + this.lblShowFrameAt.Size = new System.Drawing.Size(101, 13); this.lblShowFrameAt.TabIndex = 0; - this.lblShowFrameAt.Text = "Refresh viewer on scanline"; + this.lblShowFrameAt.Text = "Refresh on scanline"; // // nudScanline // @@ -68,7 +68,7 @@ 0, 0, 0}); - this.nudScanline.Location = new System.Drawing.Point(144, 4); + this.nudScanline.Location = new System.Drawing.Point(110, 4); this.nudScanline.Maximum = new decimal(new int[] { 312, 0, @@ -82,7 +82,7 @@ 0}); this.nudScanline.MinimumSize = new System.Drawing.Size(0, 21); this.nudScanline.Name = "nudScanline"; - this.nudScanline.Size = new System.Drawing.Size(52, 21); + this.nudScanline.Size = new System.Drawing.Size(42, 21); this.nudScanline.TabIndex = 5; this.nudScanline.Value = new decimal(new int[] { 241, @@ -95,7 +95,7 @@ // this.lblCycle.Anchor = System.Windows.Forms.AnchorStyles.Left; this.lblCycle.AutoSize = true; - this.lblCycle.Location = new System.Drawing.Point(202, 8); + this.lblCycle.Location = new System.Drawing.Point(158, 8); this.lblCycle.Name = "lblCycle"; this.lblCycle.Size = new System.Drawing.Size(53, 13); this.lblCycle.TabIndex = 5; @@ -110,7 +110,7 @@ 0, 0, 0}); - this.nudCycle.Location = new System.Drawing.Point(261, 4); + this.nudCycle.Location = new System.Drawing.Point(217, 4); this.nudCycle.Maximum = new decimal(new int[] { 340, 0, @@ -124,7 +124,7 @@ 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.Size = new System.Drawing.Size(42, 21); this.nudCycle.TabIndex = 6; this.nudCycle.Value = new decimal(new int[] { 0, @@ -135,9 +135,9 @@ // // btnReset // - this.btnReset.Location = new System.Drawing.Point(319, 3); + this.btnReset.Location = new System.Drawing.Point(265, 3); this.btnReset.Name = "btnReset"; - this.btnReset.Size = new System.Drawing.Size(75, 23); + this.btnReset.Size = new System.Drawing.Size(49, 23); this.btnReset.TabIndex = 7; this.btnReset.Text = "Reset"; this.btnReset.UseVisualStyleBackColor = true; @@ -149,7 +149,7 @@ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.flpRefreshTiming); this.Name = "ctrlScanlineCycleSelect"; - this.Size = new System.Drawing.Size(399, 28); + this.Size = new System.Drawing.Size(317, 28); this.flpRefreshTiming.ResumeLayout(false); this.flpRefreshTiming.PerformLayout(); this.ResumeLayout(false); diff --git a/UI/Debugger/PpuViewer/frmPaletteViewer.Designer.cs b/UI/Debugger/PpuViewer/frmPaletteViewer.Designer.cs index b2dcafc..759077a 100644 --- a/UI/Debugger/PpuViewer/frmPaletteViewer.Designer.cs +++ b/UI/Debugger/PpuViewer/frmPaletteViewer.Designer.cs @@ -30,7 +30,21 @@ this.ctrlScanlineCycleSelect = new Mesen.GUI.Debugger.Controls.ctrlScanlineCycleSelect(); this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.ctrlPaletteViewer = new Mesen.GUI.Debugger.ctrlPaletteViewer(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); + this.txtR = new System.Windows.Forms.TextBox(); + this.txtValue = new System.Windows.Forms.TextBox(); + this.lblIndex = new System.Windows.Forms.Label(); + this.lblValue = new System.Windows.Forms.Label(); + this.lblR = new System.Windows.Forms.Label(); + this.lblG = new System.Windows.Forms.Label(); + this.lblB = new System.Windows.Forms.Label(); + this.lblRgb = new System.Windows.Forms.Label(); + this.txtIndex = new System.Windows.Forms.TextBox(); + this.txtG = new System.Windows.Forms.TextBox(); + this.txtB = new System.Windows.Forms.TextBox(); + this.txtRgb = new System.Windows.Forms.TextBox(); this.tableLayoutPanel1.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); this.SuspendLayout(); // // ctrlScanlineCycleSelect @@ -38,7 +52,7 @@ this.ctrlScanlineCycleSelect.Dock = System.Windows.Forms.DockStyle.Bottom; this.ctrlScanlineCycleSelect.Location = new System.Drawing.Point(0, 263); this.ctrlScanlineCycleSelect.Name = "ctrlScanlineCycleSelect"; - this.ctrlScanlineCycleSelect.Size = new System.Drawing.Size(485, 28); + this.ctrlScanlineCycleSelect.Size = new System.Drawing.Size(398, 28); this.ctrlScanlineCycleSelect.TabIndex = 5; // // tableLayoutPanel1 @@ -47,32 +61,177 @@ this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel1.Controls.Add(this.ctrlPaletteViewer, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 1); 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.Size = new System.Drawing.Size(485, 263); + this.tableLayoutPanel1.Size = new System.Drawing.Size(398, 263); this.tableLayoutPanel1.TabIndex = 7; // - // ctrlPaletteViewer1 + // ctrlPaletteViewer // this.ctrlPaletteViewer.Location = new System.Drawing.Point(3, 3); this.ctrlPaletteViewer.Name = "ctrlPaletteViewer"; + this.ctrlPaletteViewer.PaletteScale = 16; + this.ctrlPaletteViewer.SelectionMode = Mesen.GUI.Debugger.PaletteSelectionMode.SingleColor; this.ctrlPaletteViewer.Size = new System.Drawing.Size(256, 256); this.ctrlPaletteViewer.TabIndex = 0; + this.ctrlPaletteViewer.SelectionChanged += new Mesen.GUI.Debugger.ctrlPaletteViewer.SelectionChangedHandler(this.ctrlPaletteViewer_SelectionChanged); + // + // 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.txtR, 1, 2); + this.tableLayoutPanel2.Controls.Add(this.txtValue, 1, 1); + this.tableLayoutPanel2.Controls.Add(this.lblIndex, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.lblValue, 0, 1); + this.tableLayoutPanel2.Controls.Add(this.lblR, 0, 2); + this.tableLayoutPanel2.Controls.Add(this.lblG, 0, 3); + this.tableLayoutPanel2.Controls.Add(this.lblB, 0, 4); + this.tableLayoutPanel2.Controls.Add(this.lblRgb, 0, 5); + this.tableLayoutPanel2.Controls.Add(this.txtIndex, 1, 0); + this.tableLayoutPanel2.Controls.Add(this.txtG, 1, 3); + this.tableLayoutPanel2.Controls.Add(this.txtB, 1, 4); + this.tableLayoutPanel2.Controls.Add(this.txtRgb, 1, 5); + this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel2.Location = new System.Drawing.Point(265, 3); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 7; + 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()); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(130, 257); + this.tableLayoutPanel2.TabIndex = 1; + // + // txtR + // + this.txtR.Location = new System.Drawing.Point(71, 55); + this.txtR.Name = "txtR"; + this.txtR.ReadOnly = true; + this.txtR.Size = new System.Drawing.Size(42, 20); + this.txtR.TabIndex = 11; + // + // txtValue + // + this.txtValue.Location = new System.Drawing.Point(71, 29); + this.txtValue.Name = "txtValue"; + this.txtValue.ReadOnly = true; + this.txtValue.Size = new System.Drawing.Size(42, 20); + this.txtValue.TabIndex = 7; + // + // lblIndex + // + this.lblIndex.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblIndex.AutoSize = true; + this.lblIndex.Location = new System.Drawing.Point(3, 6); + this.lblIndex.Name = "lblIndex"; + this.lblIndex.Size = new System.Drawing.Size(36, 13); + this.lblIndex.TabIndex = 0; + this.lblIndex.Text = "Index:"; + // + // lblValue + // + this.lblValue.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblValue.AutoSize = true; + this.lblValue.Location = new System.Drawing.Point(3, 32); + this.lblValue.Name = "lblValue"; + this.lblValue.Size = new System.Drawing.Size(37, 13); + this.lblValue.TabIndex = 1; + this.lblValue.Text = "Value:"; + // + // lblR + // + this.lblR.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblR.AutoSize = true; + this.lblR.Location = new System.Drawing.Point(3, 58); + this.lblR.Name = "lblR"; + this.lblR.Size = new System.Drawing.Size(18, 13); + this.lblR.TabIndex = 2; + this.lblR.Text = "R:"; + // + // lblG + // + this.lblG.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblG.AutoSize = true; + this.lblG.Location = new System.Drawing.Point(3, 84); + this.lblG.Name = "lblG"; + this.lblG.Size = new System.Drawing.Size(18, 13); + this.lblG.TabIndex = 3; + this.lblG.Text = "G:"; + // + // lblB + // + this.lblB.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblB.AutoSize = true; + this.lblB.Location = new System.Drawing.Point(3, 110); + this.lblB.Name = "lblB"; + this.lblB.Size = new System.Drawing.Size(17, 13); + this.lblB.TabIndex = 4; + this.lblB.Text = "B:"; + // + // lblRgb + // + this.lblRgb.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblRgb.AutoSize = true; + this.lblRgb.Location = new System.Drawing.Point(3, 136); + this.lblRgb.Name = "lblRgb"; + this.lblRgb.Size = new System.Drawing.Size(62, 13); + this.lblRgb.TabIndex = 5; + this.lblRgb.Text = "24-bit RGB:"; + // + // txtIndex + // + this.txtIndex.Location = new System.Drawing.Point(71, 3); + this.txtIndex.Name = "txtIndex"; + this.txtIndex.ReadOnly = true; + this.txtIndex.Size = new System.Drawing.Size(42, 20); + this.txtIndex.TabIndex = 6; + // + // txtG + // + this.txtG.Location = new System.Drawing.Point(71, 81); + this.txtG.Name = "txtG"; + this.txtG.ReadOnly = true; + this.txtG.Size = new System.Drawing.Size(42, 20); + this.txtG.TabIndex = 8; + // + // txtB + // + this.txtB.Location = new System.Drawing.Point(71, 107); + this.txtB.Name = "txtB"; + this.txtB.ReadOnly = true; + this.txtB.Size = new System.Drawing.Size(42, 20); + this.txtB.TabIndex = 9; + // + // txtRgb + // + this.txtRgb.Location = new System.Drawing.Point(71, 133); + this.txtRgb.Name = "txtRgb"; + this.txtRgb.ReadOnly = true; + this.txtRgb.Size = new System.Drawing.Size(56, 20); + this.txtRgb.TabIndex = 10; // // frmPaletteViewer // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(485, 291); + this.ClientSize = new System.Drawing.Size(398, 291); this.Controls.Add(this.tableLayoutPanel1); this.Controls.Add(this.ctrlScanlineCycleSelect); this.Name = "frmPaletteViewer"; this.Text = "Palette Viewer"; this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel2.ResumeLayout(false); + this.tableLayoutPanel2.PerformLayout(); this.ResumeLayout(false); } @@ -81,5 +240,18 @@ private Controls.ctrlScanlineCycleSelect ctrlScanlineCycleSelect; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; private ctrlPaletteViewer ctrlPaletteViewer; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; + private System.Windows.Forms.TextBox txtR; + private System.Windows.Forms.TextBox txtValue; + private System.Windows.Forms.Label lblIndex; + private System.Windows.Forms.Label lblValue; + private System.Windows.Forms.Label lblR; + private System.Windows.Forms.Label lblG; + private System.Windows.Forms.Label lblB; + private System.Windows.Forms.Label lblRgb; + private System.Windows.Forms.TextBox txtIndex; + private System.Windows.Forms.TextBox txtG; + private System.Windows.Forms.TextBox txtB; + private System.Windows.Forms.TextBox txtRgb; } } \ No newline at end of file diff --git a/UI/Debugger/PpuViewer/frmPaletteViewer.cs b/UI/Debugger/PpuViewer/frmPaletteViewer.cs index 6bad33b..8a1e079 100644 --- a/UI/Debugger/PpuViewer/frmPaletteViewer.cs +++ b/UI/Debugger/PpuViewer/frmPaletteViewer.cs @@ -29,6 +29,19 @@ namespace Mesen.GUI.Debugger ctrlPaletteViewer.RefreshViewer(); } + private void UpdateFields() + { + int index = ctrlPaletteViewer.SelectedPalette; + byte[] cgram = ctrlPaletteViewer.CgRam; + int color = (cgram[index * 2] | (cgram[index * 2 + 1] << 8)); + txtIndex.Text = index.ToString(); + txtValue.Text = color.ToString("X4"); + txtR.Text = (color & 0x1F).ToString(); + txtG.Text = ((color >> 5) & 0x1F).ToString(); + txtB.Text = ((color >> 10) & 0x1F).ToString(); + txtRgb.Text = (ctrlPaletteViewer.ToArgb(color) & 0xFFFFFF).ToString("X6"); + } + protected override void OnFormClosed(FormClosedEventArgs e) { base.OnFormClosed(e); @@ -43,10 +56,16 @@ namespace Mesen.GUI.Debugger ctrlPaletteViewer.RefreshData(); this.BeginInvoke((Action)(() => { ctrlPaletteViewer.RefreshViewer(); + UpdateFields(); })); } break; } } + + private void ctrlPaletteViewer_SelectionChanged() + { + UpdateFields(); + } } } \ No newline at end of file