NES: add CHR ROM tile view to the PPU viewer. i'm not sure how generally useful this is, but it's something i wanted, so there.

This commit is contained in:
goyuken 2014-02-15 16:55:55 +00:00
parent 7acbcd5995
commit 9c071bf45e
3 changed files with 185 additions and 59 deletions

View File

@ -348,6 +348,7 @@ namespace BizHawk.Client.Common
public ToolDialogSettings NesPPUSettings = new ToolDialogSettings();
public bool AutoLoadNESPPU = false;
public int NESPPURefreshRate = 4;
public bool NESPPUChrRomView = false;
// NESDebuger Settings
public bool AutoLoadNESDebugger = false;

View File

@ -104,6 +104,11 @@
this.NesPPUStatusBar = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel1 = new System.Windows.Forms.ToolStripStatusLabel();
this.Messagetimer = new System.Windows.Forms.Timer(this.components);
this.CHRROMGroup = new System.Windows.Forms.GroupBox();
this.CHRROMView = new BizHawk.Client.EmuHawk.PatternViewer();
this.numericUpDownCHRROMBank = new System.Windows.Forms.NumericUpDown();
this.label5 = new System.Windows.Forms.Label();
this.cHRROMTileViewerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.PatternGroup.SuspendLayout();
this.PatternContext.SuspendLayout();
this.PalettesGroup.SuspendLayout();
@ -117,6 +122,8 @@
((System.ComponentModel.ISupportInitialize)(this.RefreshRate)).BeginInit();
this.NesPPUMenu.SuspendLayout();
this.NesPPUStatusBar.SuspendLayout();
this.CHRROMGroup.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownCHRROMBank)).BeginInit();
this.SuspendLayout();
//
// PatternGroup
@ -471,7 +478,7 @@
this.SettingsSubMenu});
this.NesPPUMenu.Location = new System.Drawing.Point(0, 0);
this.NesPPUMenu.Name = "NesPPUMenu";
this.NesPPUMenu.Size = new System.Drawing.Size(574, 24);
this.NesPPUMenu.Size = new System.Drawing.Size(854, 24);
this.NesPPUMenu.TabIndex = 10;
this.NesPPUMenu.Text = "menuStrip1";
//
@ -488,65 +495,65 @@
this.toolStripSeparator2,
this.ExitMenuItem});
this.FileSubMenu.Name = "FileSubMenu";
this.FileSubMenu.Size = new System.Drawing.Size(37, 20);
this.FileSubMenu.Size = new System.Drawing.Size(35, 20);
this.FileSubMenu.Text = "&File";
//
// SavePaletteScreenshotMenuItem
//
this.SavePaletteScreenshotMenuItem.Name = "SavePaletteScreenshotMenuItem";
this.SavePaletteScreenshotMenuItem.Size = new System.Drawing.Size(212, 22);
this.SavePaletteScreenshotMenuItem.Size = new System.Drawing.Size(206, 22);
this.SavePaletteScreenshotMenuItem.Text = "Save Palette Screenshot...";
this.SavePaletteScreenshotMenuItem.Click += new System.EventHandler(this.SavePaletteScreenshotMenuItem_Click);
//
// SavePatternScreenshotMenuItem
//
this.SavePatternScreenshotMenuItem.Name = "SavePatternScreenshotMenuItem";
this.SavePatternScreenshotMenuItem.Size = new System.Drawing.Size(212, 22);
this.SavePatternScreenshotMenuItem.Size = new System.Drawing.Size(206, 22);
this.SavePatternScreenshotMenuItem.Text = "Save Pattern Screenshot...";
this.SavePatternScreenshotMenuItem.Click += new System.EventHandler(this.SavePatternScreenshotMenuItem_Click);
//
// SaveSpriteScreenshotMenuItem
//
this.SaveSpriteScreenshotMenuItem.Name = "SaveSpriteScreenshotMenuItem";
this.SaveSpriteScreenshotMenuItem.Size = new System.Drawing.Size(212, 22);
this.SaveSpriteScreenshotMenuItem.Size = new System.Drawing.Size(206, 22);
this.SaveSpriteScreenshotMenuItem.Text = "Save Sprite Screenshot...";
this.SaveSpriteScreenshotMenuItem.Click += new System.EventHandler(this.SaveSpriteScreenshotMenuItem_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
this.toolStripSeparator1.Size = new System.Drawing.Size(209, 6);
this.toolStripSeparator1.Size = new System.Drawing.Size(203, 6);
//
// CopyPaletteToClipboardMenuItem
//
this.CopyPaletteToClipboardMenuItem.Name = "CopyPaletteToClipboardMenuItem";
this.CopyPaletteToClipboardMenuItem.Size = new System.Drawing.Size(212, 22);
this.CopyPaletteToClipboardMenuItem.Size = new System.Drawing.Size(206, 22);
this.CopyPaletteToClipboardMenuItem.Text = "Copy Palette to Clipboard";
this.CopyPaletteToClipboardMenuItem.Click += new System.EventHandler(this.CopyPaletteToClipboardMenuItem_Click);
//
// CopyPatternToClipboardMenuItem
//
this.CopyPatternToClipboardMenuItem.Name = "CopyPatternToClipboardMenuItem";
this.CopyPatternToClipboardMenuItem.Size = new System.Drawing.Size(212, 22);
this.CopyPatternToClipboardMenuItem.Size = new System.Drawing.Size(206, 22);
this.CopyPatternToClipboardMenuItem.Text = "Copy Pattern to Clipboard";
this.CopyPatternToClipboardMenuItem.Click += new System.EventHandler(this.CopyPatternToClipboardMenuItem_Click);
//
// CopySpriteToClipboardMenuItem
//
this.CopySpriteToClipboardMenuItem.Name = "CopySpriteToClipboardMenuItem";
this.CopySpriteToClipboardMenuItem.Size = new System.Drawing.Size(212, 22);
this.CopySpriteToClipboardMenuItem.Size = new System.Drawing.Size(206, 22);
this.CopySpriteToClipboardMenuItem.Text = "Copy Sprite to Clipboard";
this.CopySpriteToClipboardMenuItem.Click += new System.EventHandler(this.CopySpriteToClipboardMenuItem_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(209, 6);
this.toolStripSeparator2.Size = new System.Drawing.Size(203, 6);
//
// ExitMenuItem
//
this.ExitMenuItem.Name = "ExitMenuItem";
this.ExitMenuItem.Size = new System.Drawing.Size(212, 22);
this.ExitMenuItem.Size = new System.Drawing.Size(206, 22);
this.ExitMenuItem.Text = "E&xit";
this.ExitMenuItem.Click += new System.EventHandler(this.ExitMenuItem_Click);
//
@ -556,7 +563,7 @@
this.Table0PaletteSubMenu,
this.Table1PaletteSubMenu});
this.PatternSubMenu.Name = "PatternSubMenu";
this.PatternSubMenu.Size = new System.Drawing.Size(57, 20);
this.PatternSubMenu.Size = new System.Drawing.Size(55, 20);
this.PatternSubMenu.Text = "&Pattern";
//
// Table0PaletteSubMenu
@ -571,7 +578,7 @@
this.Table0P6MenuItem,
this.Table0P7MenuItem});
this.Table0PaletteSubMenu.Name = "Table0PaletteSubMenu";
this.Table0PaletteSubMenu.Size = new System.Drawing.Size(151, 22);
this.Table0PaletteSubMenu.Size = new System.Drawing.Size(152, 22);
this.Table0PaletteSubMenu.Text = "Table 0 Palette";
this.Table0PaletteSubMenu.DropDownOpened += new System.EventHandler(this.Table0PaletteSubMenu_DropDownOpened);
//
@ -643,7 +650,7 @@
this.Table1P6MenuItem,
this.Table1P7MenuItem});
this.Table1PaletteSubMenu.Name = "Table1PaletteSubMenu";
this.Table1PaletteSubMenu.Size = new System.Drawing.Size(151, 22);
this.Table1PaletteSubMenu.Size = new System.Drawing.Size(152, 22);
this.Table1PaletteSubMenu.Text = "Table 1 Palette";
this.Table1PaletteSubMenu.DropDownOpened += new System.EventHandler(this.Table1PaletteSubMenu_DropDownOpened);
//
@ -709,37 +716,38 @@
this.AutoLoadMenuItem,
this.SaveWindowPositionMenuItem,
this.AlwaysOnTopMenuItem,
this.FloatingWindowMenuItem});
this.FloatingWindowMenuItem,
this.cHRROMTileViewerToolStripMenuItem});
this.SettingsSubMenu.Name = "SettingsSubMenu";
this.SettingsSubMenu.Size = new System.Drawing.Size(61, 20);
this.SettingsSubMenu.Size = new System.Drawing.Size(58, 20);
this.SettingsSubMenu.Text = "&Settings";
this.SettingsSubMenu.DropDownOpened += new System.EventHandler(this.SettingsSubMenu_DropDownOpened);
//
// AutoLoadMenuItem
//
this.AutoLoadMenuItem.Name = "AutoLoadMenuItem";
this.AutoLoadMenuItem.Size = new System.Drawing.Size(191, 22);
this.AutoLoadMenuItem.Size = new System.Drawing.Size(179, 22);
this.AutoLoadMenuItem.Text = "Autoload";
this.AutoLoadMenuItem.Click += new System.EventHandler(this.AutoloadMenuItem_Click);
//
// SaveWindowPositionMenuItem
//
this.SaveWindowPositionMenuItem.Name = "SaveWindowPositionMenuItem";
this.SaveWindowPositionMenuItem.Size = new System.Drawing.Size(191, 22);
this.SaveWindowPositionMenuItem.Size = new System.Drawing.Size(179, 22);
this.SaveWindowPositionMenuItem.Text = "Save Window Position";
this.SaveWindowPositionMenuItem.Click += new System.EventHandler(this.SaveWindowPositionMenuItem_Click);
//
// AlwaysOnTopMenuItem
//
this.AlwaysOnTopMenuItem.Name = "AlwaysOnTopMenuItem";
this.AlwaysOnTopMenuItem.Size = new System.Drawing.Size(191, 22);
this.AlwaysOnTopMenuItem.Size = new System.Drawing.Size(179, 22);
this.AlwaysOnTopMenuItem.Text = "Always On Top";
this.AlwaysOnTopMenuItem.Click += new System.EventHandler(this.AlwaysOnTopMenuItem_Click);
//
// FloatingWindowMenuItem
//
this.FloatingWindowMenuItem.Name = "FloatingWindowMenuItem";
this.FloatingWindowMenuItem.Size = new System.Drawing.Size(191, 22);
this.FloatingWindowMenuItem.Size = new System.Drawing.Size(179, 22);
this.FloatingWindowMenuItem.Text = "Floating Window";
this.FloatingWindowMenuItem.Click += new System.EventHandler(this.FloatingWindowMenuItem_Click);
//
@ -749,7 +757,7 @@
this.toolStripStatusLabel1});
this.NesPPUStatusBar.Location = new System.Drawing.Point(0, 349);
this.NesPPUStatusBar.Name = "NesPPUStatusBar";
this.NesPPUStatusBar.Size = new System.Drawing.Size(574, 22);
this.NesPPUStatusBar.Size = new System.Drawing.Size(854, 22);
this.NesPPUStatusBar.SizingGrip = false;
this.NesPPUStatusBar.TabIndex = 11;
this.NesPPUStatusBar.Text = "statusStrip1";
@ -757,7 +765,7 @@
// toolStripStatusLabel1
//
this.toolStripStatusLabel1.Name = "toolStripStatusLabel1";
this.toolStripStatusLabel1.Size = new System.Drawing.Size(348, 17);
this.toolStripStatusLabel1.Size = new System.Drawing.Size(319, 17);
this.toolStripStatusLabel1.Text = "Use CTRL+C to copy the pane under the mouse to the clipboard.";
//
// Messagetimer
@ -765,11 +773,57 @@
this.Messagetimer.Interval = 5000;
this.Messagetimer.Tick += new System.EventHandler(this.MessageTimer_Tick);
//
// CHRROMGroup
//
this.CHRROMGroup.Controls.Add(this.label5);
this.CHRROMGroup.Controls.Add(this.numericUpDownCHRROMBank);
this.CHRROMGroup.Controls.Add(this.CHRROMView);
this.CHRROMGroup.Location = new System.Drawing.Point(574, 37);
this.CHRROMGroup.Name = "CHRROMGroup";
this.CHRROMGroup.Size = new System.Drawing.Size(272, 299);
this.CHRROMGroup.TabIndex = 12;
this.CHRROMGroup.TabStop = false;
this.CHRROMGroup.Text = "CHR ROM Tiles";
//
// CHRROMView
//
this.CHRROMView.BackColor = System.Drawing.Color.Transparent;
this.CHRROMView.Location = new System.Drawing.Point(7, 20);
this.CHRROMView.Name = "CHRROMView";
this.CHRROMView.Size = new System.Drawing.Size(256, 128);
this.CHRROMView.TabIndex = 0;
this.CHRROMView.Text = "patternViewer1";
//
// numericUpDownCHRROMBank
//
this.numericUpDownCHRROMBank.Location = new System.Drawing.Point(47, 154);
this.numericUpDownCHRROMBank.Name = "numericUpDownCHRROMBank";
this.numericUpDownCHRROMBank.Size = new System.Drawing.Size(120, 20);
this.numericUpDownCHRROMBank.TabIndex = 1;
this.numericUpDownCHRROMBank.ValueChanged += new System.EventHandler(this.numericUpDownCHRROMBank_ValueChanged);
//
// label5
//
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(6, 156);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(35, 13);
this.label5.TabIndex = 2;
this.label5.Text = "Bank:";
//
// cHRROMTileViewerToolStripMenuItem
//
this.cHRROMTileViewerToolStripMenuItem.Name = "cHRROMTileViewerToolStripMenuItem";
this.cHRROMTileViewerToolStripMenuItem.Size = new System.Drawing.Size(179, 22);
this.cHRROMTileViewerToolStripMenuItem.Text = "CHR ROM Tile Viewer";
this.cHRROMTileViewerToolStripMenuItem.Click += new System.EventHandler(this.cHRROMTileViewerToolStripMenuItem_Click);
//
// NesPPU
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(574, 371);
this.ClientSize = new System.Drawing.Size(854, 371);
this.Controls.Add(this.CHRROMGroup);
this.Controls.Add(this.NesPPUStatusBar);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
@ -809,6 +863,9 @@
this.NesPPUMenu.PerformLayout();
this.NesPPUStatusBar.ResumeLayout(false);
this.NesPPUStatusBar.PerformLayout();
this.CHRROMGroup.ResumeLayout(false);
this.CHRROMGroup.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.numericUpDownCHRROMBank)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
@ -890,5 +947,10 @@
private System.Windows.Forms.Timer Messagetimer;
private System.Windows.Forms.ToolStripMenuItem AlwaysOnTopMenuItem;
private System.Windows.Forms.ToolStripMenuItem FloatingWindowMenuItem;
private System.Windows.Forms.GroupBox CHRROMGroup;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.NumericUpDown numericUpDownCHRROMBank;
private PatternViewer CHRROMView;
private System.Windows.Forms.ToolStripMenuItem cHRROMTileViewerToolStripMenuItem;
}
}

View File

@ -5,6 +5,7 @@ using System.Linq;
using System.Windows.Forms;
using BizHawk.Client.Common;
using BizHawk.Emulation.Cores.Nintendo.NES;
using BizHawk.Emulation.Common;
namespace BizHawk.Client.EmuHawk
{
@ -36,6 +37,7 @@ namespace BizHawk.Client.EmuHawk
};
TopMost = Global.Config.NesPPUSettings.TopMost;
_callback.Callback = () => Generate();
CalculateFormSize();
}
private void NesPPU_Load(object sender, EventArgs e)
@ -45,6 +47,7 @@ namespace BizHawk.Client.EmuHawk
ClearDetails();
RefreshRate.Value = Global.Config.NESPPURefreshRate;
Generate(true);
CHRROMViewReload();
}
#region Public API
@ -70,6 +73,7 @@ namespace BizHawk.Client.EmuHawk
{
_nes = Global.Emulator as NES;
Generate(true);
CHRROMViewReload();
}
else
{
@ -123,6 +127,50 @@ namespace BizHawk.Client.EmuHawk
return changed;
}
private unsafe void DrawPatternView(PatternViewer dest, byte[] src)
{
int b0;
int b1;
byte value;
int cvalue;
var bmpdata = dest.pattern.LockBits(
new Rectangle(new Point(0, 0), dest.pattern.Size),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb);
var framebuf = (int*)bmpdata.Scan0.ToPointer();
for (int z = 0; z < 2; z++)
{
int pal;
pal = z == 0 ? PatternView.Pal0 : PatternView.Pal1; // change?
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
int address = (z << 12) + (i << 8) + (j << 4) + y;
b0 = (byte)((src[address] >> (7 - x)) & 1);
b1 = (byte)((src[address + 8] >> (7 - x)) & 1);
value = (byte)(b0 + (b1 << 1));
cvalue = _nes.LookupColor(_nes.ppu.PALRAM[value + (pal << 2)]);
int adr = (x + (j << 3)) + (y + (i << 3)) * (bmpdata.Stride >> 2);
framebuf[adr + (z << 7)] = cvalue;
}
}
}
}
}
dest.pattern.UnlockBits(bmpdata);
dest.Refresh();
}
private unsafe void Generate(bool now = false)
{
if (!IsHandleCreated || IsDisposed)
@ -155,42 +203,7 @@ namespace BizHawk.Client.EmuHawk
PaletteView.Refresh();
}
var bmpdata = PatternView.pattern.LockBits(
new Rectangle(new Point(0, 0), PatternView.pattern.Size),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb
);
var framebuf = (int*)bmpdata.Scan0.ToPointer();
for (int z = 0; z < 2; z++)
{
int pal;
pal = z == 0 ? PatternView.Pal0 : PatternView.Pal1;
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
int address = (z << 12) + (i << 8) + (j << 4) + y;
b0 = (byte)((_ppuBus[address] >> (7 - x)) & 1);
b1 = (byte)((_ppuBus[address + 8] >> (7 - x)) & 1);
value = (byte)(b0 + (b1 << 1));
cvalue = _nes.LookupColor(_nes.ppu.PALRAM[value + (pal << 2)]);
int adr = (x + (j << 3)) + (y + (i << 3)) * (bmpdata.Stride >> 2);
framebuf[adr + (z << 7)] = cvalue;
}
}
}
}
}
PatternView.pattern.UnlockBits(bmpdata);
PatternView.Refresh();
DrawPatternView(PatternView, _ppuBus);
}
var bmpdata2 = SpriteView.sprites.LockBits(new Rectangle(new Point(0, 0), SpriteView.sprites.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
@ -461,6 +474,7 @@ namespace BizHawk.Client.EmuHawk
SaveWindowPositionMenuItem.Checked = Global.Config.NesPPUSettings.SaveWindowPosition;
AlwaysOnTopMenuItem.Checked = Global.Config.NesPPUSettings.TopMost;
FloatingWindowMenuItem.Checked = Global.Config.NesPPUSettings.FloatingWindow;
cHRROMTileViewerToolStripMenuItem.Checked = Global.Config.NESPPUChrRomView;
}
private void AutoloadMenuItem_Click(object sender, EventArgs e)
@ -794,6 +808,55 @@ namespace BizHawk.Client.EmuHawk
#endregion
MemoryDomain CHRROM;
byte[] chrromcache = new byte[8192];
private void cHRROMTileViewerToolStripMenuItem_Click(object sender, EventArgs e)
{
Global.Config.NESPPUChrRomView ^= true;
CalculateFormSize();
}
private void CalculateFormSize()
{
Width = Global.Config.NESPPUChrRomView ? 861 : 580;
}
private void CHRROMViewReload()
{
CHRROM = _nes.MemoryDomains["CHR VROM"];
if (CHRROM == null)
{
numericUpDownCHRROMBank.Enabled = false;
Array.Clear(chrromcache, 0, 8192);
}
else
{
numericUpDownCHRROMBank.Enabled = true;
numericUpDownCHRROMBank.Minimum = 0;
numericUpDownCHRROMBank.Maximum = CHRROM.Size / 8192 - 1;
numericUpDownCHRROMBank.Value = Math.Min(numericUpDownCHRROMBank.Value, numericUpDownCHRROMBank.Maximum);
}
CHRROMViewRefresh();
}
private void CHRROMViewRefresh()
{
if (CHRROM != null)
{
int offs = 8192 * (int)numericUpDownCHRROMBank.Value;
for (int i = 0; i < 8192; i++)
chrromcache[i] = CHRROM.PeekByte(offs + i);
DrawPatternView(CHRROMView, chrromcache);
}
}
#endregion
private void numericUpDownCHRROMBank_ValueChanged(object sender, EventArgs e)
{
CHRROMViewRefresh();
}
}
}