* Fixed OBJ layer toggle message

(it was using the flag from BG toggle)

* Added hotkey option for GB Window layer toggle

* Added hotkey option for GB Window layer toggle

* GB object viewer prototype [Gambatte]

GPU Viewer add-on to display sprite tiles on the real position, just like what you have for the bsnes core
Has several issues:
- Drawing is identical to the current sprite display, so it doesn't have the transparency it should have;
- Drawing doesn't take priority into account, so overlapping is usually wrong;
- The drawing flickers, probably the way of refreshing (with `.Clear()`) is bad.
This commit is contained in:
BrunoValads 2020-12-04 17:37:36 -03:00 committed by GitHub
parent 0aea6191ae
commit 81ef9ed88b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 139 additions and 13 deletions

View File

@ -240,6 +240,7 @@ namespace BizHawk.Client.Common
Bind("GB", "GB Toggle BG"),
Bind("GB", "GB Toggle Obj"),
Bind("GB", "GB Toggle Window"),
Bind("Analog", "Y Up Small", toolTip: "For Virtual Pad"),
Bind("Analog", "Y Up Large", toolTip: "For Virtual Pad"),

View File

@ -710,7 +710,17 @@ namespace BizHawk.Client.EmuHawk
var s = gb2.GetSettings();
s.DisplayOBJ ^= true;
gb2.PutSettings(s);
AddOnScreenMessage($"OBJ toggled {(s.DisplayBG ? "on" : "off")}");
AddOnScreenMessage($"OBJ toggled {(s.DisplayOBJ ? "on" : "off")}");
}
break;
case "GB Toggle Window":
if (Emulator is Gameboy gb3)
{
var s = gb3.GetSettings();
s.DisplayWindow ^= true;
gb3.PutSettings(s);
AddOnScreenMessage($"WIN toggled {(s.DisplayWindow ? "on" : "off")}");
}
break;

View File

@ -38,6 +38,8 @@
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.label7 = new BizHawk.WinForms.Controls.LocLabelEx();
this.label8 = new BizHawk.WinForms.Controls.LocLabelEx();
this.label9 = new BizHawk.WinForms.Controls.LocLabelEx();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.groupBox5 = new System.Windows.Forms.GroupBox();
this.hScrollBarScanline = new System.Windows.Forms.HScrollBar();
@ -60,6 +62,7 @@
this.bmpViewMemory = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewDetails = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewOAM = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewOBJ = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewBGPal = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewSPPal = new BizHawk.Client.EmuHawk.BmpView();
this.bmpViewTiles1 = new BizHawk.Client.EmuHawk.BmpView();
@ -159,15 +162,30 @@
this.label7.Name = "label7";
this.label7.Text = "Left-click a palette to use it for drawing the tiles display.";
//
// label8
//
this.label8.Location = new System.Drawing.Point(3, 16);
this.label8.Name = "label8";
this.label8.Text = "Sprites";
//
// label9
//
this.label9.Location = new System.Drawing.Point(3, 52);
this.label9.Name = "label9";
this.label9.Text = "Objects";
//
// groupBox4
//
this.groupBox4.Controls.Add(this.bmpViewOAM);
this.groupBox4.Controls.Add(this.bmpViewOBJ);
this.groupBox4.Controls.Add(this.label8);
this.groupBox4.Controls.Add(this.label9);
this.groupBox4.Location = new System.Drawing.Point(12, 327);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(332, 41);
this.groupBox4.Size = new System.Drawing.Size(332, 331);
this.groupBox4.TabIndex = 19;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Sprites";
this.groupBox4.Text = "OAM";
//
// groupBox5
//
@ -250,9 +268,9 @@
//
this.groupBoxDetails.Controls.Add(this.labelDetails);
this.groupBoxDetails.Controls.Add(this.bmpViewDetails);
this.groupBoxDetails.Location = new System.Drawing.Point(12, 374);
this.groupBoxDetails.Location = new System.Drawing.Point(350, 327);
this.groupBoxDetails.Name = "groupBoxDetails";
this.groupBoxDetails.Size = new System.Drawing.Size(262, 153);
this.groupBoxDetails.Size = new System.Drawing.Size(192, 153);
this.groupBoxDetails.TabIndex = 21;
this.groupBoxDetails.TabStop = false;
this.groupBoxDetails.Text = "Details";
@ -260,7 +278,7 @@
// labelDetails
//
this.labelDetails.Location = new System.Drawing.Point(76, 16);
this.labelDetails.MaximumSize = new System.Drawing.Size(150, 0);
this.labelDetails.MaximumSize = new System.Drawing.Size(115, 0);
this.labelDetails.Name = "labelDetails";
this.labelDetails.Text = "Mouse over an item to see details about it.";
//
@ -268,9 +286,9 @@
//
this.groupBoxMemory.Controls.Add(this.bmpViewMemory);
this.groupBoxMemory.Controls.Add(this.labelMemory);
this.groupBoxMemory.Location = new System.Drawing.Point(280, 374);
this.groupBoxMemory.Location = new System.Drawing.Point(350, 486);
this.groupBoxMemory.Name = "groupBoxMemory";
this.groupBoxMemory.Size = new System.Drawing.Size(262, 153);
this.groupBoxMemory.Size = new System.Drawing.Size(192, 153);
this.groupBoxMemory.TabIndex = 22;
this.groupBoxMemory.TabStop = false;
this.groupBoxMemory.Text = "Details - Memory";
@ -278,7 +296,7 @@
// labelMemory
//
this.labelMemory.Location = new System.Drawing.Point(76, 16);
this.labelMemory.MaximumSize = new System.Drawing.Size(150, 0);
this.labelMemory.MaximumSize = new System.Drawing.Size(115, 0);
this.labelMemory.Name = "labelMemory";
this.labelMemory.Text = "Right-click an item to display it here.";
//
@ -314,7 +332,7 @@
//
this.labelSpriteBackColor.Location = new System.Drawing.Point(67, 24);
this.labelSpriteBackColor.Name = "labelSpriteBackColor";
this.labelSpriteBackColor.Text = "label8";
this.labelSpriteBackColor.Text = "label10";
//
// buttonChangeColor
//
@ -364,7 +382,7 @@
// bmpViewOAM
//
this.bmpViewOAM.BackColor = System.Drawing.Color.Black;
this.bmpViewOAM.Location = new System.Drawing.Point(6, 19);
this.bmpViewOAM.Location = new System.Drawing.Point(6, 32);
this.bmpViewOAM.Name = "bmpViewOAM";
this.bmpViewOAM.Size = new System.Drawing.Size(320, 16);
this.bmpViewOAM.TabIndex = 14;
@ -374,6 +392,19 @@
this.bmpViewOAM.MouseLeave += new System.EventHandler(this.bmpViewOAM_MouseLeave);
this.bmpViewOAM.MouseMove += new System.Windows.Forms.MouseEventHandler(this.bmpViewOAM_MouseMove);
//
// bmpViewOBJ
//
this.bmpViewOBJ.BackColor = System.Drawing.Color.Black;
this.bmpViewOBJ.Location = new System.Drawing.Point(6, 67);
this.bmpViewOBJ.Name = "bmpViewOBJ";
this.bmpViewOBJ.Size = new System.Drawing.Size(256, 256);
this.bmpViewOBJ.TabIndex = 15;
this.bmpViewOBJ.Text = "Objects";
this.bmpViewOBJ.MouseClick += new System.Windows.Forms.MouseEventHandler(this.bmpView_MouseClick);
this.bmpViewOBJ.MouseEnter += new System.EventHandler(this.bmpViewOBJ_MouseEnter);
this.bmpViewOBJ.MouseLeave += new System.EventHandler(this.bmpViewOBJ_MouseLeave);
this.bmpViewOBJ.MouseMove += new System.Windows.Forms.MouseEventHandler(this.bmpViewOBJ_MouseMove);
//
// bmpViewBGPal
//
this.bmpViewBGPal.BackColor = System.Drawing.Color.Black;
@ -456,7 +487,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(834, 593);
this.ClientSize = new System.Drawing.Size(834, 664);
this.Controls.Add(this.groupBox8);
this.Controls.Add(this.groupBox6);
this.Controls.Add(this.groupBoxMemory);
@ -480,6 +511,7 @@
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
this.groupBox4.ResumeLayout(false);
this.groupBox4.PerformLayout();
this.groupBox5.ResumeLayout(false);
this.groupBox5.PerformLayout();
this.groupBoxDetails.ResumeLayout(false);
@ -510,6 +542,7 @@
private BizHawk.WinForms.Controls.LocLabelEx label5;
private BizHawk.WinForms.Controls.LocLabelEx label6;
private BmpView bmpViewOAM;
private BmpView bmpViewOBJ;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox3;
@ -528,6 +561,8 @@
private BizHawk.WinForms.Controls.LocLabelEx labelMemory;
private BmpView bmpViewMemory;
private BizHawk.WinForms.Controls.LocLabelEx label7;
private BizHawk.WinForms.Controls.LocLabelEx label8;
private BizHawk.WinForms.Controls.LocLabelEx label9;
private System.Windows.Forms.GroupBox groupBox6;
private BizHawk.WinForms.Controls.LocLabelEx labelClipboard;
private System.Windows.Forms.GroupBox groupBox8;

View File

@ -67,6 +67,7 @@ namespace BizHawk.Client.EmuHawk
bmpViewBGPal.ChangeBitmapSize(8, 4);
bmpViewSPPal.ChangeBitmapSize(8, 4);
bmpViewOAM.ChangeBitmapSize(320, 16);
bmpViewOBJ.ChangeBitmapSize(256, 256);
bmpViewDetails.ChangeBitmapSize(8, 16);
bmpViewMemory.ChangeBitmapSize(8, 16);
@ -97,6 +98,7 @@ namespace BizHawk.Client.EmuHawk
bmpViewBGPal.Clear();
bmpViewSPPal.Clear();
bmpViewOAM.Clear();
bmpViewOBJ.Clear();
bmpViewDetails.Clear();
bmpViewMemory.Clear();
_cbScanlineEmu = -4; // force refresh
@ -329,6 +331,63 @@ namespace BizHawk.Client.EmuHawk
b.UnlockBits(lockData);
}
/// <summary>
/// draw objects from oam data
/// </summary>
/// <param name="b">bitmap to draw to. should be 320x8 (!tall), 320x16 (tall)</param>
/// <param name="_oam">oam data, 4 * 40 bytes</param>
/// <param name="_tiles">base tiledata location. cgb: second bank tiledata assumed to be @+8k</param>
/// <param name="_pal">2 (dmg) or 8 (cgb) palettes</param>
/// <param name="tall">true for 8x16 sprites; else 8x8</param>
/// <param name="cgb">true for cgb (more palettes, second bank tiles)</param>
private static unsafe void DrawObj(Bitmap b, IntPtr _oam, IntPtr _tiles, IntPtr _pal, bool tall, bool cgb)
{
var lockData = b.LockBits(new Rectangle(0, 0, 256, 256), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
int* dest = (int*)lockData.Scan0;
int pitch = lockData.Stride / sizeof(int);
int* pal = (int*)_pal;
byte* oam = (byte*)_oam;
for (int s = 0; s < 40; s++)
{
int yPos = *oam++;
int xPos = *oam++;
dest += xPos + yPos * pitch;
int tileIndex = *oam++;
int flags = *oam++;
bool vFlip = flags.Bit(6);
bool hFlip = flags.Bit(5);
if (tall)
{
// i assume 8x16 vFlip flips the whole thing, not just each tile?
if (vFlip)
{
tileIndex |= 1;
}
else
{
tileIndex &= 0xfe;
}
}
byte* tile = (byte*)(_tiles + tileIndex * 16);
int* thisPal = pal + 4 * (cgb ? flags & 7 : flags >> 4 & 1);
if (cgb && flags.Bit(3))
tile += 8192;
DrawTileHv(tile, dest, pitch, thisPal, hFlip, vFlip);
if (tall)
{
DrawTileHv(tile + 16, dest + pitch * 8, pitch, thisPal, hFlip, vFlip);
}
dest -= xPos + yPos * pitch;
}
b.UnlockBits(lockData);
}
/// <summary>
/// draw a palette directly
/// </summary>
@ -455,7 +514,7 @@ namespace BizHawk.Client.EmuHawk
bmpViewBGPal.Refresh();
bmpViewSPPal.Refresh();
// oam
// oam (sprites)
if (lcdc.Bit(2)) // 8x16
{
bmpViewOAM.ChangeBitmapSize(320, 16);
@ -470,6 +529,11 @@ namespace BizHawk.Client.EmuHawk
}
DrawOam(bmpViewOAM.Bmp, oam, vram, spPal, lcdc.Bit(2), _cgb);
bmpViewOAM.Refresh();
// oam (objects)
bmpViewOBJ.Clear();
DrawObj(bmpViewOBJ.Bmp, oam, vram, spPal, lcdc.Bit(2), _cgb);
bmpViewOBJ.Refresh();
}
// try to run the current mouseover, to refresh if the mouse is being held over a pane while the emulator runs
// this doesn't really work well; the update rate seems to be throttled
@ -887,6 +951,22 @@ namespace BizHawk.Client.EmuHawk
SpriteMouseover(e.X, e.Y);
}
private void bmpViewOBJ_MouseEnter(object sender, EventArgs e)
{
SaveDetails();
groupBoxDetails.Text = "Details - Objects";
}
private void bmpViewOBJ_MouseLeave(object sender, EventArgs e)
{
LoadDetails();
}
private void bmpViewOBJ_MouseMove(object sender, MouseEventArgs e)
{
SpriteMouseover(e.X, e.Y);
}
private void bmpView_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)