snesgfxdebugger-display OBJ tiles

This commit is contained in:
zeromus 2012-11-23 09:10:18 +00:00
parent 2382781627
commit 608ebc4a99
7 changed files with 225 additions and 25 deletions

View File

@ -196,6 +196,10 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
CGWSEL_COLORSUBMASK = 41,
CGWSEL_ADDSUBMODE = 42,
CGWSEL_DIRECTCOLOR = 43,
//$2101 OBSEL
OBSEL_NAMEBASE = 50,
OBSEL_NAMESEL = 51,
OBSEL_SIZE = 52,
}
public enum SNES_MEMORY : uint

View File

@ -54,6 +54,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
return ret;
}
public static Dimensions[,] ObjSizes = new Dimensions[,]
{
{ new Dimensions(8,8), new Dimensions(16,16) },
{ new Dimensions(8,8), new Dimensions(32,32) },
{ new Dimensions(8,8), new Dimensions(64,64) },
{ new Dimensions(16,16), new Dimensions(32,32) },
{ new Dimensions(16,16), new Dimensions(64,64) },
{ new Dimensions(32,32), new Dimensions(64,64) },
{ new Dimensions(16,32), new Dimensions(32,64) },
{ new Dimensions(16,32), new Dimensions(32,32) }
};
public static Dimensions SizeInBlocksForBGSize(ScreenSize size)
{
switch (size)
@ -176,10 +188,24 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
public int CGWSEL_AddSubMode { private set; get; }
public bool CGWSEL_DirectColor { private set; get; }
public int OBSEL_Size { private set; get; }
public int OBSEL_NameSel { private set; get; }
public int OBSEL_NameBase { private set; get; }
public int OBJTable0Addr { private set; get; }
public int OBJTable1Addr { private set; get; }
public static ScreenInfo GetScreenInfo()
{
var si = new ScreenInfo();
si.OBSEL_Size = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_SIZE);
si.OBSEL_NameSel = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_NAMESEL);
si.OBSEL_NameBase = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.OBSEL_NAMEBASE);
si.OBJTable0Addr = si.OBSEL_NameBase << 14;
si.OBJTable1Addr = (si.OBJTable0Addr + ((si.OBSEL_NameSel + 1) << 13)) & 0xFFFF;
si.SETINI_Mode7ExtBG = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_MODE7_EXTBG) == 1;
si.SETINI_HiRes = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_HIRES) == 1;
si.SETINI_Overscan = LibsnesDll.snes_peek_logical_register(LibsnesDll.SNES_REG.SETINI_OVERSCAN) == 1;
@ -648,7 +674,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
/// we might need 16x16 unscrambling and some other perks here eventually.
/// provide a start color to use as the basis for the palette
/// </summary>
public void RenderTilesToScreen(int* screen, int tilesWide, int tilesTall, int stride, int bpp, int startcolor, int startTile = 0, int numTiles = -1)
public void RenderTilesToScreen(int* screen, int tilesWide, int tilesTall, int stride, int bpp, int startcolor, int startTile = 0, int numTiles = -1, bool descramble16=false)
{
if(numTiles == -1)
numTiles = 8192 / bpp;
@ -656,6 +682,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES
for (int i = 0; i < numTiles; i++)
{
int tnum = startTile + i;
//TODO - mask by possible number of tiles? only in OBJ rendering mode?
int ty = i / tilesWide;
int tx = i % tilesWide;
int dstOfs = (ty * 8) * stride + tx * 8;

View File

@ -153,6 +153,17 @@
this.groupBox6 = new System.Windows.Forms.GroupBox();
this.labelClipboard = new System.Windows.Forms.Label();
this.messagetimer = new System.Windows.Forms.Timer(this.components);
this.label26 = new System.Windows.Forms.Label();
this.txtOBSELSizeDescr = new System.Windows.Forms.TextBox();
this.label28 = new System.Windows.Forms.Label();
this.txtOBSELSizeBits = new System.Windows.Forms.TextBox();
this.groupBox7 = new System.Windows.Forms.GroupBox();
this.txtOBSELBaseBits = new System.Windows.Forms.TextBox();
this.txtOBSELBaseDescr = new System.Windows.Forms.TextBox();
this.label29 = new System.Windows.Forms.Label();
this.txtOBSELT1OfsBits = new System.Windows.Forms.TextBox();
this.txtOBSELT1OfsDescr = new System.Windows.Forms.TextBox();
this.label30 = new System.Windows.Forms.Label();
this.paletteViewer = new BizHawk.MultiClient.SNESGraphicsViewer();
this.viewerTile = new BizHawk.MultiClient.SNESGraphicsViewer();
this.viewer = new BizHawk.MultiClient.SNESGraphicsViewer();
@ -172,6 +183,7 @@
this.tpTile.SuspendLayout();
this.viewerPanel.SuspendLayout();
this.groupBox6.SuspendLayout();
this.groupBox7.SuspendLayout();
this.SuspendLayout();
//
// menuStrip1
@ -268,6 +280,7 @@
//
this.panel1.AutoSize = true;
this.panel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.panel1.Controls.Add(this.groupBox7);
this.panel1.Controls.Add(this.groupBox6);
this.panel1.Controls.Add(this.label24);
this.panel1.Controls.Add(this.pnBackdropColor);
@ -286,7 +299,7 @@
// label24
//
this.label24.AutoSize = true;
this.label24.Location = new System.Drawing.Point(237, 42);
this.label24.Location = new System.Drawing.Point(3, 623);
this.label24.Name = "label24";
this.label24.Size = new System.Drawing.Size(78, 13);
this.label24.TabIndex = 49;
@ -296,7 +309,7 @@
//
this.pnBackdropColor.BackColor = System.Drawing.Color.Red;
this.pnBackdropColor.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.pnBackdropColor.Location = new System.Drawing.Point(240, 7);
this.pnBackdropColor.Location = new System.Drawing.Point(6, 588);
this.pnBackdropColor.Name = "pnBackdropColor";
this.pnBackdropColor.Size = new System.Drawing.Size(32, 32);
this.pnBackdropColor.TabIndex = 48;
@ -305,7 +318,7 @@
// checkBackdropColor
//
this.checkBackdropColor.AutoSize = true;
this.checkBackdropColor.Location = new System.Drawing.Point(278, 25);
this.checkBackdropColor.Location = new System.Drawing.Point(44, 606);
this.checkBackdropColor.Name = "checkBackdropColor";
this.checkBackdropColor.Size = new System.Drawing.Size(15, 14);
this.checkBackdropColor.TabIndex = 47;
@ -413,7 +426,7 @@
this.groupBox2.Controls.Add(this.label5);
this.groupBox2.Location = new System.Drawing.Point(0, 0);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(229, 165);
this.groupBox2.Size = new System.Drawing.Size(307, 165);
this.groupBox2.TabIndex = 16;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Screen";
@ -1155,18 +1168,6 @@
this.comboDisplayType.FormattingEnabled = true;
this.comboDisplayType.IntegralHeight = false;
this.comboDisplayType.ItemHeight = 13;
this.comboDisplayType.Items.AddRange(new object[] {
"BG1",
"BG2",
"BG3",
"BG4",
"OBJ",
"2bpp tiles",
"4bpp tiles",
"8bpp tiles",
"Mode7 tiles",
"Mode7Ext tiles",
"Mode7 tiles (DC)"});
this.comboDisplayType.Location = new System.Drawing.Point(6, 8);
this.comboDisplayType.Name = "comboDisplayType";
this.comboDisplayType.Size = new System.Drawing.Size(107, 21);
@ -1505,7 +1506,7 @@
// groupBox6
//
this.groupBox6.Controls.Add(this.labelClipboard);
this.groupBox6.Location = new System.Drawing.Point(1, 419);
this.groupBox6.Location = new System.Drawing.Point(1, 539);
this.groupBox6.Name = "groupBox6";
this.groupBox6.Size = new System.Drawing.Size(228, 43);
this.groupBox6.TabIndex = 50;
@ -1526,6 +1527,122 @@
this.messagetimer.Interval = 5000;
this.messagetimer.Tick += new System.EventHandler(this.messagetimer_Tick);
//
// label26
//
this.label26.AutoSize = true;
this.label26.Location = new System.Drawing.Point(5, 14);
this.label26.Name = "label26";
this.label26.Size = new System.Drawing.Size(42, 13);
this.label26.TabIndex = 45;
this.label26.Text = "OBSEL";
//
// txtOBSELSizeDescr
//
this.txtOBSELSizeDescr.Location = new System.Drawing.Point(77, 29);
this.txtOBSELSizeDescr.Multiline = true;
this.txtOBSELSizeDescr.Name = "txtOBSELSizeDescr";
this.txtOBSELSizeDescr.ReadOnly = true;
this.txtOBSELSizeDescr.Size = new System.Drawing.Size(80, 18);
this.txtOBSELSizeDescr.TabIndex = 48;
this.txtOBSELSizeDescr.Text = "64x32, 32x32";
//
// label28
//
this.label28.AutoSize = true;
this.label28.Location = new System.Drawing.Point(31, 32);
this.label28.Name = "label28";
this.label28.Size = new System.Drawing.Size(27, 13);
this.label28.TabIndex = 47;
this.label28.Text = "Size";
//
// txtOBSELSizeBits
//
this.txtOBSELSizeBits.BackColor = System.Drawing.Color.LightGreen;
this.txtOBSELSizeBits.Location = new System.Drawing.Point(12, 29);
this.txtOBSELSizeBits.Multiline = true;
this.txtOBSELSizeBits.Name = "txtOBSELSizeBits";
this.txtOBSELSizeBits.ReadOnly = true;
this.txtOBSELSizeBits.Size = new System.Drawing.Size(15, 17);
this.txtOBSELSizeBits.TabIndex = 49;
this.txtOBSELSizeBits.Text = "00";
//
// groupBox7
//
this.groupBox7.Controls.Add(this.txtOBSELT1OfsBits);
this.groupBox7.Controls.Add(this.txtOBSELT1OfsDescr);
this.groupBox7.Controls.Add(this.label30);
this.groupBox7.Controls.Add(this.txtOBSELBaseBits);
this.groupBox7.Controls.Add(this.txtOBSELBaseDescr);
this.groupBox7.Controls.Add(this.label29);
this.groupBox7.Controls.Add(this.txtOBSELSizeBits);
this.groupBox7.Controls.Add(this.label26);
this.groupBox7.Controls.Add(this.txtOBSELSizeDescr);
this.groupBox7.Controls.Add(this.label28);
this.groupBox7.Location = new System.Drawing.Point(1, 419);
this.groupBox7.Name = "groupBox7";
this.groupBox7.Size = new System.Drawing.Size(228, 114);
this.groupBox7.TabIndex = 51;
this.groupBox7.TabStop = false;
this.groupBox7.Text = "OBJ";
//
// txtOBSELBaseBits
//
this.txtOBSELBaseBits.BackColor = System.Drawing.Color.LightGreen;
this.txtOBSELBaseBits.Location = new System.Drawing.Point(12, 51);
this.txtOBSELBaseBits.Multiline = true;
this.txtOBSELBaseBits.Name = "txtOBSELBaseBits";
this.txtOBSELBaseBits.ReadOnly = true;
this.txtOBSELBaseBits.Size = new System.Drawing.Size(15, 17);
this.txtOBSELBaseBits.TabIndex = 52;
this.txtOBSELBaseBits.Text = "00";
//
// txtOBSELBaseDescr
//
this.txtOBSELBaseDescr.Location = new System.Drawing.Point(77, 51);
this.txtOBSELBaseDescr.Multiline = true;
this.txtOBSELBaseDescr.Name = "txtOBSELBaseDescr";
this.txtOBSELBaseDescr.ReadOnly = true;
this.txtOBSELBaseDescr.Size = new System.Drawing.Size(80, 18);
this.txtOBSELBaseDescr.TabIndex = 51;
//
// label29
//
this.label29.AutoSize = true;
this.label29.Location = new System.Drawing.Point(31, 54);
this.label29.Name = "label29";
this.label29.Size = new System.Drawing.Size(47, 13);
this.label29.TabIndex = 50;
this.label29.Text = "TD.Addr";
//
// txtOBSELT1OfsBits
//
this.txtOBSELT1OfsBits.BackColor = System.Drawing.Color.LightGreen;
this.txtOBSELT1OfsBits.Location = new System.Drawing.Point(12, 72);
this.txtOBSELT1OfsBits.Multiline = true;
this.txtOBSELT1OfsBits.Name = "txtOBSELT1OfsBits";
this.txtOBSELT1OfsBits.ReadOnly = true;
this.txtOBSELT1OfsBits.Size = new System.Drawing.Size(15, 17);
this.txtOBSELT1OfsBits.TabIndex = 55;
this.txtOBSELT1OfsBits.Text = "00";
//
// txtOBSELT1OfsDescr
//
this.txtOBSELT1OfsDescr.Location = new System.Drawing.Point(77, 72);
this.txtOBSELT1OfsDescr.Multiline = true;
this.txtOBSELT1OfsDescr.Name = "txtOBSELT1OfsDescr";
this.txtOBSELT1OfsDescr.ReadOnly = true;
this.txtOBSELT1OfsDescr.Size = new System.Drawing.Size(80, 18);
this.txtOBSELT1OfsDescr.TabIndex = 54;
//
// label30
//
this.label30.AutoSize = true;
this.label30.Location = new System.Drawing.Point(31, 75);
this.label30.Name = "label30";
this.label30.Size = new System.Drawing.Size(45, 13);
this.label30.TabIndex = 53;
this.label30.Text = "T1.Addr";
//
// paletteViewer
//
this.paletteViewer.BackColor = System.Drawing.Color.Transparent;
@ -1597,6 +1714,8 @@
this.viewerPanel.ResumeLayout(false);
this.groupBox6.ResumeLayout(false);
this.groupBox6.PerformLayout();
this.groupBox7.ResumeLayout(false);
this.groupBox7.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
@ -1730,5 +1849,16 @@
private System.Windows.Forms.GroupBox groupBox6;
private System.Windows.Forms.Label labelClipboard;
private System.Windows.Forms.Timer messagetimer;
private System.Windows.Forms.GroupBox groupBox7;
private System.Windows.Forms.TextBox txtOBSELT1OfsBits;
private System.Windows.Forms.TextBox txtOBSELT1OfsDescr;
private System.Windows.Forms.Label label30;
private System.Windows.Forms.TextBox txtOBSELBaseBits;
private System.Windows.Forms.TextBox txtOBSELBaseDescr;
private System.Windows.Forms.Label label29;
private System.Windows.Forms.TextBox txtOBSELSizeBits;
private System.Windows.Forms.Label label26;
private System.Windows.Forms.TextBox txtOBSELSizeDescr;
private System.Windows.Forms.Label label28;
}
}

View File

@ -2,6 +2,8 @@
//TODO - overhaul the BG display box if its mode7 or direct color (mode7 more important)
//TODO - draw `1024` label in red if your content is being scaled down.
//TODO - maybe draw a label (in lieu of above, also) showing what scale the content is at: 2x or 1x or 1/2x
//TODO - add eDisplayType for BG1-Tiles, BG2-Tiles, etc. which show the tiles available to a BG. more concise than viewing all tiles and illustrating the relevant accessible areas
// . could this apply to the palette too?
using System;
using System.Collections.Generic;
@ -34,7 +36,7 @@ namespace BizHawk.MultiClient
displayTypeItems.Add(new DisplayTypeItem("BG2",eDisplayType.BG2));
displayTypeItems.Add(new DisplayTypeItem("BG3",eDisplayType.BG3));
displayTypeItems.Add(new DisplayTypeItem("BG4",eDisplayType.BG4));
displayTypeItems.Add(new DisplayTypeItem("OBJ",eDisplayType.OBJ));
displayTypeItems.Add(new DisplayTypeItem("OBJ",eDisplayType.OBJ0));
displayTypeItems.Add(new DisplayTypeItem("2bpp tiles",eDisplayType.Tiles2bpp));
displayTypeItems.Add(new DisplayTypeItem("4bpp tiles",eDisplayType.Tiles4bpp));
displayTypeItems.Add(new DisplayTypeItem("8bpp tiles",eDisplayType.Tiles8bpp));
@ -93,8 +95,11 @@ namespace BizHawk.MultiClient
public void UpdateToolsLoadstate()
{
SyncCore();
RegenerateData();
UpdateValues();
if (this.Visible)
{
RegenerateData();
UpdateValues();
}
}
private void nudScanline_ValueChanged(object sender, EventArgs e)
@ -162,6 +167,13 @@ namespace BizHawk.MultiClient
if (!this.IsHandleCreated || this.IsDisposed) return;
if (currentSnesCore == null) return;
txtOBSELSizeBits.Text = si.OBSEL_Size.ToString();
txtOBSELBaseBits.Text = si.OBSEL_NameBase.ToString();
txtOBSELT1OfsBits.Text = si.OBSEL_NameSel.ToString();
txtOBSELSizeDescr.Text = string.Format("{0}, {1}", SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size,0], SNESGraphicsDecoder.ObjSizes[si.OBSEL_Size,1]);
txtOBSELBaseDescr.Text = FormatVramAddress(si.OBJTable0Addr);
txtOBSELT1OfsDescr.Text = FormatVramAddress(si.OBJTable1Addr);
checkScreenExtbg.Checked = si.SETINI_Mode7ExtBG;
checkScreenHires.Checked = si.SETINI_HiRes;
checkScreenOverscan.Checked = si.SETINI_Overscan;
@ -228,6 +240,15 @@ namespace BizHawk.MultiClient
};
var selection = CurrDisplaySelection;
if (selection == eDisplayType.OBJ0 || selection == eDisplayType.OBJ1)
{
allocate(128, 256);
int startTile;
startTile = si.OBJTable0Addr / 32;
gd.RenderTilesToScreen(pixelptr, 16, 16, stride / 4, 4, currPaletteSelection.start, startTile, 256, true);
startTile = si.OBJTable1Addr / 32;
gd.RenderTilesToScreen(pixelptr + (stride/4*8*16), 16, 16, stride / 4, 4, currPaletteSelection.start, startTile, 256, true);
}
if (selection == eDisplayType.Tiles2bpp)
{
allocate(512, 512);
@ -315,9 +336,10 @@ namespace BizHawk.MultiClient
enum eDisplayType
{
BG1=1, BG2=2, BG3=3, BG4=4, OBJ, Tiles2bpp, Tiles4bpp, Tiles8bpp, TilesMode7, TilesMode7Ext, TilesMode7DC
BG1=1, BG2=2, BG3=3, BG4=4, OBJ0, OBJ1, Tiles2bpp, Tiles4bpp, Tiles8bpp, TilesMode7, TilesMode7Ext, TilesMode7DC
}
static bool IsDisplayTypeBG(eDisplayType type) { return type == eDisplayType.BG1 || type == eDisplayType.BG2 || type == eDisplayType.BG3 || type == eDisplayType.BG4; }
static bool IsDisplayTypeOBJ(eDisplayType type) { return type == eDisplayType.OBJ0 || type == eDisplayType.OBJ1; }
static int DisplayTypeBGNum(eDisplayType type) { if(IsDisplayTypeBG(type)) return (int)type; else return -1; }
class DisplayTypeItem
@ -467,11 +489,13 @@ namespace BizHawk.MultiClient
{
int bpp = 0;
var selection = CurrDisplaySelection;
if (selection == eDisplayType.Tiles2bpp) bpp=2;
if (selection == eDisplayType.Tiles2bpp) bpp = 2;
if (selection == eDisplayType.Tiles4bpp) bpp = 4;
if (selection == eDisplayType.Tiles8bpp) bpp = 8;
if (selection == eDisplayType.TilesMode7) bpp = 8;
if (selection == eDisplayType.TilesMode7Ext) bpp = 7;
if (selection == eDisplayType.OBJ0) bpp = 4;
if (selection == eDisplayType.OBJ1) bpp = 4;
SNESGraphicsDecoder.PaletteSelection ret = new SNESGraphicsDecoder.PaletteSelection();
if(bpp == 0) return ret;
@ -519,11 +543,16 @@ namespace BizHawk.MultiClient
//next, draw the rectangle that advises you which colors could possibly be used for a bg
if (IsDisplayTypeBG(CurrDisplaySelection))
{
var si = gd.ScanScreenInfo();
var ps = si.BG[DisplayTypeBGNum(CurrDisplaySelection)].PaletteSelection;
region = GetPaletteRegion(ps);
DrawPaletteRegion(g, Color.FromArgb(192, 128, 255, 255), region);
}
if (IsDisplayTypeOBJ(CurrDisplaySelection))
{
var ps = new SNESGraphicsDecoder.PaletteSelection(128, 128);
region = GetPaletteRegion(ps);
DrawPaletteRegion(g, Color.FromArgb(192, 128, 255, 255), region);
}
//finally, draw the palette the user has chosen, in case he's viewing tiles
if (currPaletteSelection.size != 0)
{
@ -651,7 +680,8 @@ namespace BizHawk.MultiClient
}
else
{
UpdateViewerMouseover(e.Location);
if(si != null)
UpdateViewerMouseover(e.Location);
}
}

View File

@ -335,6 +335,10 @@ int snes_peek_logical_register(int reg)
case SNES_REG_CGWSEL_COLORSUBMASK: return SNES::ppu.regs.color_mask;
case SNES_REG_CGWSEL_ADDSUBMODE: return SNES::ppu.regs.addsub_mode?1:0;
case SNES_REG_CGWSEL_DIRECTCOLOR: return SNES::ppu.regs.direct_color?1:0;
//$2101 OBSEL
case SNES_REG_OBSEL_NAMEBASE: return SNES::ppu.regs.oam_tdaddr>>14;
case SNES_REG_OBSEL_NAMESEL: return SNES::ppu.regs.oam_nameselect;
case SNES_REG_OBSEL_SIZE: return SNES::ppu.regs.oam_basesize;
}
return 0;
}

View File

@ -185,6 +185,11 @@ void bus_write(unsigned addr, uint8_t val);
#define SNES_REG_CGWSEL_COLORSUBMASK 41
#define SNES_REG_CGWSEL_ADDSUBMODE 42
#define SNES_REG_CGWSEL_DIRECTCOLOR 43
//$2101 OBSEL
#define SNES_REG_OBSEL_NAMEBASE 50
#define SNES_REG_OBSEL_NAMESEL 51
#define SNES_REG_OBSEL_SIZE 52
int snes_peek_logical_register(int reg);