[NES] specify scanlines in PPU/NT viewers
This commit is contained in:
parent
40b7827798
commit
51367f58c7
|
@ -13,6 +13,16 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
{
|
||||
public partial class PPU
|
||||
{
|
||||
public class DebugCallback
|
||||
{
|
||||
public int Scanline;
|
||||
//public int Dot; //not supported
|
||||
public Action Callback;
|
||||
}
|
||||
|
||||
public DebugCallback NTViewCallback;
|
||||
public DebugCallback PPUViewCallback;
|
||||
|
||||
public MemoryDomain.FreezeData[] ppubus_freeze = new MemoryDomain.FreezeData[16384];
|
||||
|
||||
//when the ppu issues a write it goes through here and into the game board
|
||||
|
|
|
@ -130,6 +130,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo
|
|||
int yp = sl - 1;
|
||||
ppuphase = PPUPHASE.BG;
|
||||
|
||||
if (NTViewCallback != null && yp == NTViewCallback.Scanline) NTViewCallback.Callback();
|
||||
if (PPUViewCallback != null && yp == PPUViewCallback.Scanline) PPUViewCallback.Callback();
|
||||
|
||||
//twiddle the oam buffers
|
||||
int scanslot = oamslot ^ 1;
|
||||
int renderslot = oamslot;
|
||||
|
|
|
@ -29,13 +29,15 @@
|
|||
private void InitializeComponent()
|
||||
{
|
||||
this.groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
this.NameTableView = new BizHawk.MultiClient.NameTableViewer();
|
||||
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
|
||||
this.optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.autoloadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.saveWindowPositionToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.txtScanline = new System.Windows.Forms.TextBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.NameTableView = new BizHawk.MultiClient.NameTableViewer();
|
||||
this.groupBox1.SuspendLayout();
|
||||
this.menuStrip1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
|
@ -49,21 +51,13 @@
|
|||
this.groupBox1.TabIndex = 0;
|
||||
this.groupBox1.TabStop = false;
|
||||
//
|
||||
// NameTableView
|
||||
//
|
||||
this.NameTableView.BackColor = System.Drawing.Color.White;
|
||||
this.NameTableView.Location = new System.Drawing.Point(17, 19);
|
||||
this.NameTableView.Name = "NameTableView";
|
||||
this.NameTableView.Size = new System.Drawing.Size(512, 480);
|
||||
this.NameTableView.TabIndex = 0;
|
||||
//
|
||||
// menuStrip1
|
||||
//
|
||||
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.optionsToolStripMenuItem});
|
||||
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
|
||||
this.menuStrip1.Name = "menuStrip1";
|
||||
this.menuStrip1.Size = new System.Drawing.Size(572, 24);
|
||||
this.menuStrip1.Size = new System.Drawing.Size(668, 24);
|
||||
this.menuStrip1.TabIndex = 1;
|
||||
this.menuStrip1.Text = "menuStrip1";
|
||||
//
|
||||
|
@ -106,17 +100,46 @@
|
|||
this.exitToolStripMenuItem.Text = "E&xit";
|
||||
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
|
||||
//
|
||||
// txtScanline
|
||||
//
|
||||
this.txtScanline.Location = new System.Drawing.Point(563, 64);
|
||||
this.txtScanline.Name = "txtScanline";
|
||||
this.txtScanline.Size = new System.Drawing.Size(60, 20);
|
||||
this.txtScanline.TabIndex = 2;
|
||||
this.txtScanline.Text = "0";
|
||||
this.txtScanline.TextChanged += new System.EventHandler(this.txtScanline_TextChanged);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(564, 45);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(48, 13);
|
||||
this.label1.TabIndex = 3;
|
||||
this.label1.Text = "Scanline";
|
||||
//
|
||||
// NameTableView
|
||||
//
|
||||
this.NameTableView.BackColor = System.Drawing.Color.White;
|
||||
this.NameTableView.Location = new System.Drawing.Point(17, 19);
|
||||
this.NameTableView.Name = "NameTableView";
|
||||
this.NameTableView.Size = new System.Drawing.Size(512, 480);
|
||||
this.NameTableView.TabIndex = 0;
|
||||
//
|
||||
// NESNameTableViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(572, 561);
|
||||
this.ClientSize = new System.Drawing.Size(668, 561);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.txtScanline);
|
||||
this.Controls.Add(this.groupBox1);
|
||||
this.Controls.Add(this.menuStrip1);
|
||||
this.MainMenuStrip = this.menuStrip1;
|
||||
this.Name = "NESNameTableViewer";
|
||||
this.Text = "NESNameTableViewer";
|
||||
this.Text = "NES Nametable Viewer";
|
||||
this.Load += new System.EventHandler(this.NESNameTableViewer_Load);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.NESNameTableViewer_FormClosed);
|
||||
this.groupBox1.ResumeLayout(false);
|
||||
this.menuStrip1.ResumeLayout(false);
|
||||
this.menuStrip1.PerformLayout();
|
||||
|
@ -135,5 +158,7 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem saveWindowPositionToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
|
||||
private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
|
||||
private System.Windows.Forms.TextBox txtScanline;
|
||||
private System.Windows.Forms.Label label1;
|
||||
}
|
||||
}
|
|
@ -17,10 +17,14 @@ namespace BizHawk.MultiClient
|
|||
int defaultHeight;
|
||||
NES Nes;
|
||||
|
||||
NES.PPU.DebugCallback Callback = new NES.PPU.DebugCallback();
|
||||
|
||||
|
||||
public NESNameTableViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
Closing += (o, e) => SaveConfigSettings();
|
||||
Callback.Callback = () => Generate();
|
||||
}
|
||||
|
||||
private void SaveConfigSettings()
|
||||
|
@ -29,20 +33,22 @@ namespace BizHawk.MultiClient
|
|||
Global.Config.NESNameTableWndy = this.Location.Y;
|
||||
}
|
||||
|
||||
public unsafe void UpdateValues()
|
||||
unsafe void Generate()
|
||||
{
|
||||
if (!(Global.Emulator is NES)) return;
|
||||
if (!this.IsHandleCreated || this.IsDisposed) return;
|
||||
NES.PPU ppu = (Global.Emulator as NES).ppu;
|
||||
if (Nes == null) return;
|
||||
|
||||
NES.PPU ppu = Nes.ppu;
|
||||
if (!this.IsHandleCreated || this.IsDisposed) return;
|
||||
BitmapData bmpdata = NameTableView.nametables.LockBits(new Rectangle(0, 0, 512, 480), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
int* dptr = (int*)bmpdata.Scan0.ToPointer();
|
||||
int pitch = bmpdata.Stride / 4;
|
||||
int pt_add = ppu.reg_2000.bg_pattern_hi ? 0x1000 : 0;
|
||||
|
||||
//TODO - buffer all the data from the ppu, because it will be read multiple times and that is slow
|
||||
|
||||
int ytable = 0, yline=0;
|
||||
int ytable = 0, yline = 0;
|
||||
for (int y = 0; y < 480; y++)
|
||||
{
|
||||
if (y == 240)
|
||||
|
@ -56,15 +62,15 @@ namespace BizHawk.MultiClient
|
|||
int ntaddr = (table << 10);
|
||||
int px = x & 255;
|
||||
int py = y - yline;
|
||||
int tx = px>>3;
|
||||
int ty = py>>3;
|
||||
int tx = px >> 3;
|
||||
int ty = py >> 3;
|
||||
int ntbyte_ptr = ntaddr + (ty * 32) + tx;
|
||||
int atbyte_ptr = ntaddr + 0x3C0 + ((ty >> 2) << 3) + (tx >> 2);
|
||||
int nt = ppu.ppubus_peek(ntbyte_ptr + 0x2000);
|
||||
|
||||
int at = ppu.ppubus_peek(atbyte_ptr + 0x2000);
|
||||
if((ty&2)!=0) at >>= 4;
|
||||
if((tx&2)!=0) at >>= 2;
|
||||
if ((ty & 2) != 0) at >>= 4;
|
||||
if ((tx & 2) != 0) at >>= 2;
|
||||
at &= 0x03;
|
||||
at <<= 2;
|
||||
|
||||
|
@ -77,7 +83,7 @@ namespace BizHawk.MultiClient
|
|||
|
||||
//if the pixel is transparent, draw the backdrop color
|
||||
//TODO - consider making this optional? nintendulator does it and fceux doesnt need to do it due to buggy palette logic which creates the same effect
|
||||
if(pixel!=0)
|
||||
if (pixel != 0)
|
||||
pixel |= at;
|
||||
|
||||
pixel = ppu.PALRAM[pixel];
|
||||
|
@ -92,10 +98,16 @@ namespace BizHawk.MultiClient
|
|||
NameTableView.Refresh();
|
||||
}
|
||||
|
||||
public void UpdateValues()
|
||||
{
|
||||
if (!(Global.Emulator is NES)) return;
|
||||
NES.PPU ppu = (Global.Emulator as NES).ppu;
|
||||
ppu.NTViewCallback = Callback;
|
||||
}
|
||||
|
||||
public void Restart()
|
||||
{
|
||||
if (!(Global.Emulator is NES)) this.Close();
|
||||
if (!this.IsHandleCreated || this.IsDisposed) return;
|
||||
Nes = Global.Emulator as NES;
|
||||
}
|
||||
|
||||
|
@ -130,5 +142,21 @@ namespace BizHawk.MultiClient
|
|||
autoloadToolStripMenuItem.Checked = Global.Config.AutoLoadNESNameTable;
|
||||
saveWindowPositionToolStripMenuItem.Checked = Global.Config.NESNameTableSaveWindowPosition;
|
||||
}
|
||||
|
||||
private void txtScanline_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
int temp=0;
|
||||
if (int.TryParse(txtScanline.Text, out temp))
|
||||
{
|
||||
Callback.Scanline = temp;
|
||||
}
|
||||
}
|
||||
|
||||
private void NESNameTableViewer_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
if (Nes == null) return;
|
||||
if (Nes.ppu.NTViewCallback == Callback)
|
||||
Nes.ppu.NTViewCallback = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,8 @@
|
|||
this.SpriteView = new BizHawk.MultiClient.SpriteViewer();
|
||||
this.PaletteView = new BizHawk.MultiClient.PaletteViewer();
|
||||
this.PatternView = new BizHawk.MultiClient.PatternViewer();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.txtScanline = new System.Windows.Forms.TextBox();
|
||||
this.PatternGroup.SuspendLayout();
|
||||
this.PalettesGroup.SuspendLayout();
|
||||
this.DetailsBox.SuspendLayout();
|
||||
|
@ -395,11 +397,31 @@
|
|||
this.PatternView.MouseClick += new System.Windows.Forms.MouseEventHandler(this.PatternView_Click);
|
||||
this.PatternView.MouseEnter += new System.EventHandler(this.PatternView_MouseEnter);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(502, 204);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(48, 13);
|
||||
this.label1.TabIndex = 7;
|
||||
this.label1.Text = "Scanline";
|
||||
//
|
||||
// txtScanline
|
||||
//
|
||||
this.txtScanline.Location = new System.Drawing.Point(501, 223);
|
||||
this.txtScanline.Name = "txtScanline";
|
||||
this.txtScanline.Size = new System.Drawing.Size(60, 20);
|
||||
this.txtScanline.TabIndex = 6;
|
||||
this.txtScanline.Text = "0";
|
||||
this.txtScanline.TextChanged += new System.EventHandler(this.txtScanline_TextChanged);
|
||||
//
|
||||
// NESPPU
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(587, 317);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.txtScanline);
|
||||
this.Controls.Add(this.SpriteViewerBox);
|
||||
this.Controls.Add(this.toolStrip1);
|
||||
this.Controls.Add(this.DetailsBox);
|
||||
|
@ -407,8 +429,9 @@
|
|||
this.Controls.Add(this.PatternGroup);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
|
||||
this.Name = "NESPPU";
|
||||
this.Text = "PPU Viewer";
|
||||
this.Text = "NES PPU Viewer";
|
||||
this.Load += new System.EventHandler(this.NESPPU_Load);
|
||||
this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.NESPPU_FormClosed);
|
||||
this.PatternGroup.ResumeLayout(false);
|
||||
this.PatternGroup.PerformLayout();
|
||||
this.PalettesGroup.ResumeLayout(false);
|
||||
|
@ -460,5 +483,7 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem Table1P7;
|
||||
private System.Windows.Forms.GroupBox SpriteViewerBox;
|
||||
private SpriteViewer SpriteView;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.TextBox txtScanline;
|
||||
}
|
||||
}
|
|
@ -26,10 +26,13 @@ namespace BizHawk.MultiClient
|
|||
int defaultHeight;
|
||||
NES Nes;
|
||||
|
||||
NES.PPU.DebugCallback Callback = new NES.PPU.DebugCallback();
|
||||
|
||||
public NESPPU()
|
||||
{
|
||||
InitializeComponent();
|
||||
Closing += (o, e) => SaveConfigSettings();
|
||||
Callback.Callback = () => Generate();
|
||||
}
|
||||
|
||||
private void SaveConfigSettings()
|
||||
|
@ -60,9 +63,8 @@ namespace BizHawk.MultiClient
|
|||
return (byte)(((value >> (7 - bit)) & 1));
|
||||
}
|
||||
|
||||
public unsafe void UpdateValues()
|
||||
unsafe void Generate()
|
||||
{
|
||||
if (!(Global.Emulator is NES)) return;
|
||||
if (!this.IsHandleCreated || this.IsDisposed) return;
|
||||
|
||||
//Pattern Viewer
|
||||
|
@ -97,8 +99,8 @@ namespace BizHawk.MultiClient
|
|||
{
|
||||
for (int y = 0; y < 8; y++)
|
||||
{
|
||||
b0 = GetBit((z*0x1000) + (i * 256) + (j * 16) + y + 0 * 8, x);
|
||||
b1 = GetBit((z*0x1000) + (i * 256) + (j * 16) + y + 1 * 8, x);
|
||||
b0 = GetBit((z * 0x1000) + (i * 256) + (j * 16) + y + 0 * 8, x);
|
||||
b1 = GetBit((z * 0x1000) + (i * 256) + (j * 16) + y + 1 * 8, x);
|
||||
|
||||
value = (byte)(b0 + (b1 << 1));
|
||||
|
||||
|
@ -107,7 +109,7 @@ namespace BizHawk.MultiClient
|
|||
Color color = Color.FromArgb(cvalue);
|
||||
|
||||
int adr = (x + (j * 8)) + (y + (i * 8)) * (bmpdata.Stride / 4);
|
||||
framebuf[adr + (z*128)] = color.ToArgb();
|
||||
framebuf[adr + (z * 128)] = color.ToArgb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +119,13 @@ namespace BizHawk.MultiClient
|
|||
PatternView.Refresh();
|
||||
}
|
||||
|
||||
public unsafe void UpdateValues()
|
||||
{
|
||||
if (!(Global.Emulator is NES)) return;
|
||||
NES.PPU ppu = (Global.Emulator as NES).ppu;
|
||||
ppu.PPUViewCallback = Callback;
|
||||
}
|
||||
|
||||
private void NESPPU_Load(object sender, EventArgs e)
|
||||
{
|
||||
LoadConfigSettings();
|
||||
|
@ -338,5 +347,21 @@ namespace BizHawk.MultiClient
|
|||
|
||||
UpdateTableLabels();
|
||||
}
|
||||
|
||||
private void txtScanline_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
int temp = 0;
|
||||
if (int.TryParse(txtScanline.Text, out temp))
|
||||
{
|
||||
Callback.Scanline = temp;
|
||||
}
|
||||
}
|
||||
|
||||
private void NESPPU_FormClosed(object sender, FormClosedEventArgs e)
|
||||
{
|
||||
if (Nes == null) return;
|
||||
if (Nes.ppu.PPUViewCallback == Callback)
|
||||
Nes.ppu.PPUViewCallback = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue