Debugger: Several tilemap viewer improvements

This commit is contained in:
Sour 2019-03-30 18:17:41 -04:00
parent 1a30ac6fa8
commit 5de1430841
3 changed files with 581 additions and 45 deletions

View file

@ -225,6 +225,8 @@ void PpuTools::GetTilemap(GetTilemapOptions options, uint8_t* vram, uint8_t* cgr
}
}
} else {
int tileHeight = largeTileHeight ? 16 : 8;
int tileWidth = largeTileWidth ? 16 : 8;
for(int row = 0; row < (layer.DoubleHeight ? 64 : 32); row++) {
uint16_t addrVerticalScrollingOffset = layer.DoubleHeight ? ((row & 0x20) << (layer.DoubleWidth ? 6 : 5)) : 0;
uint16_t baseOffset = (layer.TilemapAddress >> 1) + addrVerticalScrollingOffset + ((row & 0x1F) << 5);
@ -234,28 +236,25 @@ void PpuTools::GetTilemap(GetTilemapOptions options, uint8_t* vram, uint8_t* cgr
bool vMirror = (vram[addr + 1] & 0x80) != 0;
bool hMirror = (vram[addr + 1] & 0x40) != 0;
uint16_t tileIndex = ((vram[addr + 1] & 0x03) << 8) | vram[addr];
uint16_t tileStart = layer.ChrAddress + tileIndex * 8 * bpp;
if(largeTileWidth || largeTileHeight) {
tileIndex = (
tileIndex +
(largeTileHeight ? ((row & 0x01) ? (vMirror ? 0 : 16) : (vMirror ? 16 : 0)) : 0) +
(largeTileWidth ? ((column & 0x01) ? (hMirror ? 0 : 1) : (hMirror ? 1 : 0)) : 0)
) & 0x3FF;
}
for(int y = 0; y < tileHeight; y++) {
uint8_t yOffset = vMirror ? (7 - (y & 0x07)) : (y & 0x07);
for(int y = 0; y < 8; y++) {
uint8_t yOffset = vMirror ? (7 - y) : y;
uint16_t pixelStart = tileStart + yOffset * 2;
for(int x = 0; x < tileWidth; x++) {
uint16_t tileOffset = (
(largeTileHeight ? ((y & 0x08) ? (vMirror ? 0 : 16) : (vMirror ? 16 : 0)) : 0) +
(largeTileWidth ? ((x & 0x08) ? (hMirror ? 0 : 1) : (hMirror ? 1 : 0)) : 0)
);
for(int x = 0; x < 8; x++) {
uint8_t shift = hMirror ? x : (7 - x);
uint16_t tileStart = layer.ChrAddress + ((tileIndex + tileOffset) & 0x3FF) * 8 * bpp;
uint16_t pixelStart = tileStart + yOffset * 2;
uint8_t shift = hMirror ? (x & 0x07) : (7 - (x & 0x07));
uint8_t color = GetTilePixelColor(vram, Ppu::VideoRamSize - 1, bpp, pixelStart, shift);
if(color != 0) {
uint8_t palette = bpp == 8 ? 0 : (vram[addr + 1] >> 2) & 0x07;
outBuffer[((row * 8) + y) * 1024 + column * 8 + x] = GetRgbPixelColor(cgram, color, palette, bpp, directColor, basePaletteOffset);
outBuffer[((row * tileHeight) + y) * 1024 + column * tileWidth + x] = GetRgbPixelColor(cgram, color, palette, bpp, directColor, basePaletteOffset);
}
}
}
@ -274,8 +273,25 @@ void PpuTools::GetTilemap(GetTilemapOptions options, uint8_t* vram, uint8_t* cgr
if(options.ShowScrollOverlay) {
constexpr uint32_t overlayColor = 0x40FFFFFF;
int widthMask = options.BgMode == 7 ? 0x3FF : (layer.DoubleWidth ? 0x1FF : 0xFF);
int heightMask = options.BgMode == 7 ? 0x3FF : (layer.DoubleHeight ? 0x1FF : 0xFF);
int widthMask = 0xFF;
int heightMask = 0xFF;
if(options.BgMode == 7) {
widthMask = 0x3FF;
heightMask = 0x3FF;
} else {
if(layer.DoubleWidth && largeTileWidth) {
widthMask = 0x3FF;
} else if(layer.DoubleWidth || largeTileWidth) {
widthMask = 0x1FF;
}
if(layer.DoubleHeight && largeTileHeight) {
heightMask = 0x3FF;
} else if(layer.DoubleHeight || largeTileHeight) {
heightMask = 0x1FF;
}
}
int hScroll = options.BgMode == 7 ? state.Mode7.HScroll : layer.HScroll;
int vScroll = options.BgMode == 7 ? state.Mode7.VScroll : layer.VScroll;
for(int y = 0; y < 240; y++) {

View file

@ -38,6 +38,35 @@
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.chkShowScrollOverlay = new System.Windows.Forms.CheckBox();
this.chkShowTileGrid = new System.Windows.Forms.CheckBox();
this.grpTileInfo = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel4 = new System.Windows.Forms.TableLayoutPanel();
this.txtPalette = new System.Windows.Forms.TextBox();
this.txtTileNumber = new System.Windows.Forms.TextBox();
this.txtAddress = new System.Windows.Forms.TextBox();
this.txtPosition = new System.Windows.Forms.TextBox();
this.lblMap = new System.Windows.Forms.Label();
this.lblPosition = new System.Windows.Forms.Label();
this.lblAddress = new System.Windows.Forms.Label();
this.lblValue = new System.Windows.Forms.Label();
this.lblTileNumber = new System.Windows.Forms.Label();
this.lblPalette = new System.Windows.Forms.Label();
this.chkPriorityFlag = new System.Windows.Forms.CheckBox();
this.chkHorizontalMirror = new System.Windows.Forms.CheckBox();
this.chkVerticalMirror = new System.Windows.Forms.CheckBox();
this.txtMapNumber = new System.Windows.Forms.TextBox();
this.txtValue = new System.Windows.Forms.TextBox();
this.grpLayerInfo = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel5 = new System.Windows.Forms.TableLayoutPanel();
this.lblMapAddress = new System.Windows.Forms.Label();
this.lblMapSize = new System.Windows.Forms.Label();
this.lblBitDepth = new System.Windows.Forms.Label();
this.lblTileSize = new System.Windows.Forms.Label();
this.lblTilesetAddress = new System.Windows.Forms.Label();
this.txtMapSize = new System.Windows.Forms.TextBox();
this.txtMapAddress = new System.Windows.Forms.TextBox();
this.txtTileSize = new System.Windows.Forms.TextBox();
this.txtTilesetAddress = new System.Windows.Forms.TextBox();
this.txtBitDepth = new System.Windows.Forms.TextBox();
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.lblLayer = new System.Windows.Forms.Label();
this.ctrlMesenMenuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
@ -54,6 +83,10 @@
this.pnlTilemap.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.grpTileInfo.SuspendLayout();
this.tableLayoutPanel4.SuspendLayout();
this.grpLayerInfo.SuspendLayout();
this.tableLayoutPanel5.SuspendLayout();
this.tableLayoutPanel3.SuspendLayout();
this.ctrlMesenMenuStrip1.SuspendLayout();
this.SuspendLayout();
@ -63,10 +96,11 @@
this.picTilemap.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
this.picTilemap.Location = new System.Drawing.Point(0, 0);
this.picTilemap.Name = "picTilemap";
this.picTilemap.Size = new System.Drawing.Size(512, 512);
this.picTilemap.Size = new System.Drawing.Size(512, 471);
this.picTilemap.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
this.picTilemap.TabIndex = 0;
this.picTilemap.TabStop = false;
this.picTilemap.MouseClick += new System.Windows.Forms.MouseEventHandler(this.picTilemap_MouseClick);
//
// btnLayer1
//
@ -119,9 +153,9 @@
// ctrlScanlineCycleSelect
//
this.ctrlScanlineCycleSelect.Dock = System.Windows.Forms.DockStyle.Bottom;
this.ctrlScanlineCycleSelect.Location = new System.Drawing.Point(0, 546);
this.ctrlScanlineCycleSelect.Location = new System.Drawing.Point(0, 532);
this.ctrlScanlineCycleSelect.Name = "ctrlScanlineCycleSelect";
this.ctrlScanlineCycleSelect.Size = new System.Drawing.Size(667, 28);
this.ctrlScanlineCycleSelect.Size = new System.Drawing.Size(668, 28);
this.ctrlScanlineCycleSelect.TabIndex = 5;
//
// pnlTilemap
@ -131,7 +165,7 @@
this.pnlTilemap.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlTilemap.Location = new System.Drawing.Point(3, 31);
this.pnlTilemap.Name = "pnlTilemap";
this.pnlTilemap.Size = new System.Drawing.Size(512, 488);
this.pnlTilemap.Size = new System.Drawing.Size(513, 474);
this.pnlTilemap.TabIndex = 6;
//
// tableLayoutPanel1
@ -148,7 +182,7 @@
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(667, 522);
this.tableLayoutPanel1.Size = new System.Drawing.Size(668, 508);
this.tableLayoutPanel1.TabIndex = 7;
//
// tableLayoutPanel2
@ -157,14 +191,19 @@
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Controls.Add(this.chkShowScrollOverlay, 0, 1);
this.tableLayoutPanel2.Controls.Add(this.chkShowTileGrid, 0, 0);
this.tableLayoutPanel2.Location = new System.Drawing.Point(521, 3);
this.tableLayoutPanel2.Controls.Add(this.grpTileInfo, 0, 3);
this.tableLayoutPanel2.Controls.Add(this.grpLayerInfo, 0, 2);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Right;
this.tableLayoutPanel2.Location = new System.Drawing.Point(522, 3);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 3;
this.tableLayoutPanel2.RowCount = 5;
this.tableLayoutPanel1.SetRowSpan(this.tableLayoutPanel2, 2);
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(143, 320);
this.tableLayoutPanel2.Size = new System.Drawing.Size(143, 502);
this.tableLayoutPanel2.TabIndex = 7;
//
// chkShowScrollOverlay
@ -189,6 +228,328 @@
this.chkShowTileGrid.UseVisualStyleBackColor = true;
this.chkShowTileGrid.Click += new System.EventHandler(this.chkShowTileGrid_Click);
//
// grpTileInfo
//
this.grpTileInfo.Controls.Add(this.tableLayoutPanel4);
this.grpTileInfo.Dock = System.Windows.Forms.DockStyle.Fill;
this.grpTileInfo.Location = new System.Drawing.Point(3, 203);
this.grpTileInfo.Name = "grpTileInfo";
this.grpTileInfo.Size = new System.Drawing.Size(137, 268);
this.grpTileInfo.TabIndex = 2;
this.grpTileInfo.TabStop = false;
this.grpTileInfo.Text = "Tile Information";
//
// tableLayoutPanel4
//
this.tableLayoutPanel4.ColumnCount = 2;
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel4.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel4.Controls.Add(this.txtPalette, 1, 7);
this.tableLayoutPanel4.Controls.Add(this.txtTileNumber, 1, 6);
this.tableLayoutPanel4.Controls.Add(this.txtAddress, 1, 3);
this.tableLayoutPanel4.Controls.Add(this.txtPosition, 1, 1);
this.tableLayoutPanel4.Controls.Add(this.lblMap, 0, 0);
this.tableLayoutPanel4.Controls.Add(this.lblPosition, 0, 1);
this.tableLayoutPanel4.Controls.Add(this.lblAddress, 0, 3);
this.tableLayoutPanel4.Controls.Add(this.lblValue, 0, 4);
this.tableLayoutPanel4.Controls.Add(this.lblTileNumber, 0, 6);
this.tableLayoutPanel4.Controls.Add(this.lblPalette, 0, 7);
this.tableLayoutPanel4.Controls.Add(this.chkPriorityFlag, 0, 8);
this.tableLayoutPanel4.Controls.Add(this.chkHorizontalMirror, 0, 9);
this.tableLayoutPanel4.Controls.Add(this.chkVerticalMirror, 0, 10);
this.tableLayoutPanel4.Controls.Add(this.txtMapNumber, 1, 0);
this.tableLayoutPanel4.Controls.Add(this.txtValue, 1, 4);
this.tableLayoutPanel4.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel4.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel4.Name = "tableLayoutPanel4";
this.tableLayoutPanel4.RowCount = 12;
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 10F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 10F));
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel4.Size = new System.Drawing.Size(131, 249);
this.tableLayoutPanel4.TabIndex = 0;
//
// txtPalette
//
this.txtPalette.Location = new System.Drawing.Point(76, 153);
this.txtPalette.Name = "txtPalette";
this.txtPalette.ReadOnly = true;
this.txtPalette.Size = new System.Drawing.Size(30, 20);
this.txtPalette.TabIndex = 14;
//
// txtTileNumber
//
this.txtTileNumber.Location = new System.Drawing.Point(76, 127);
this.txtTileNumber.Name = "txtTileNumber";
this.txtTileNumber.ReadOnly = true;
this.txtTileNumber.Size = new System.Drawing.Size(42, 20);
this.txtTileNumber.TabIndex = 13;
//
// txtAddress
//
this.txtAddress.Location = new System.Drawing.Point(76, 65);
this.txtAddress.Name = "txtAddress";
this.txtAddress.ReadOnly = true;
this.txtAddress.Size = new System.Drawing.Size(43, 20);
this.txtAddress.TabIndex = 11;
//
// txtPosition
//
this.txtPosition.Location = new System.Drawing.Point(76, 29);
this.txtPosition.Name = "txtPosition";
this.txtPosition.ReadOnly = true;
this.txtPosition.Size = new System.Drawing.Size(52, 20);
this.txtPosition.TabIndex = 10;
//
// lblMap
//
this.lblMap.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblMap.AutoSize = true;
this.lblMap.Location = new System.Drawing.Point(3, 6);
this.lblMap.Name = "lblMap";
this.lblMap.Size = new System.Drawing.Size(31, 13);
this.lblMap.TabIndex = 0;
this.lblMap.Text = "Map:";
//
// lblPosition
//
this.lblPosition.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblPosition.AutoSize = true;
this.lblPosition.Location = new System.Drawing.Point(3, 32);
this.lblPosition.Name = "lblPosition";
this.lblPosition.Size = new System.Drawing.Size(47, 13);
this.lblPosition.TabIndex = 1;
this.lblPosition.Text = "Position:";
//
// lblAddress
//
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
this.lblAddress.Location = new System.Drawing.Point(3, 68);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(48, 13);
this.lblAddress.TabIndex = 2;
this.lblAddress.Text = "Address:";
//
// lblValue
//
this.lblValue.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblValue.AutoSize = true;
this.lblValue.Location = new System.Drawing.Point(3, 94);
this.lblValue.Name = "lblValue";
this.lblValue.Size = new System.Drawing.Size(37, 13);
this.lblValue.TabIndex = 3;
this.lblValue.Text = "Value:";
//
// lblTileNumber
//
this.lblTileNumber.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblTileNumber.AutoSize = true;
this.lblTileNumber.Location = new System.Drawing.Point(3, 130);
this.lblTileNumber.Name = "lblTileNumber";
this.lblTileNumber.Size = new System.Drawing.Size(67, 13);
this.lblTileNumber.TabIndex = 4;
this.lblTileNumber.Text = "Tile Number:";
//
// lblPalette
//
this.lblPalette.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblPalette.AutoSize = true;
this.lblPalette.Location = new System.Drawing.Point(3, 156);
this.lblPalette.Name = "lblPalette";
this.lblPalette.Size = new System.Drawing.Size(43, 13);
this.lblPalette.TabIndex = 5;
this.lblPalette.Text = "Palette:";
//
// chkPriorityFlag
//
this.chkPriorityFlag.AutoCheck = false;
this.chkPriorityFlag.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.chkPriorityFlag, 2);
this.chkPriorityFlag.Location = new System.Drawing.Point(3, 179);
this.chkPriorityFlag.Name = "chkPriorityFlag";
this.chkPriorityFlag.Size = new System.Drawing.Size(57, 17);
this.chkPriorityFlag.TabIndex = 6;
this.chkPriorityFlag.Text = "Priority";
this.chkPriorityFlag.UseVisualStyleBackColor = true;
//
// chkHorizontalMirror
//
this.chkHorizontalMirror.AutoCheck = false;
this.chkHorizontalMirror.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.chkHorizontalMirror, 2);
this.chkHorizontalMirror.Location = new System.Drawing.Point(3, 202);
this.chkHorizontalMirror.Name = "chkHorizontalMirror";
this.chkHorizontalMirror.Size = new System.Drawing.Size(102, 17);
this.chkHorizontalMirror.TabIndex = 8;
this.chkHorizontalMirror.Text = "Horizontal Mirror";
this.chkHorizontalMirror.UseVisualStyleBackColor = true;
//
// chkVerticalMirror
//
this.chkVerticalMirror.AutoCheck = false;
this.chkVerticalMirror.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.chkVerticalMirror, 2);
this.chkVerticalMirror.Location = new System.Drawing.Point(3, 225);
this.chkVerticalMirror.Name = "chkVerticalMirror";
this.chkVerticalMirror.Size = new System.Drawing.Size(90, 17);
this.chkVerticalMirror.TabIndex = 7;
this.chkVerticalMirror.Text = "Vertical Mirror";
this.chkVerticalMirror.UseVisualStyleBackColor = true;
//
// txtMapNumber
//
this.txtMapNumber.Location = new System.Drawing.Point(76, 3);
this.txtMapNumber.Name = "txtMapNumber";
this.txtMapNumber.ReadOnly = true;
this.txtMapNumber.Size = new System.Drawing.Size(30, 20);
this.txtMapNumber.TabIndex = 9;
//
// txtValue
//
this.txtValue.Location = new System.Drawing.Point(76, 91);
this.txtValue.Name = "txtValue";
this.txtValue.ReadOnly = true;
this.txtValue.Size = new System.Drawing.Size(43, 20);
this.txtValue.TabIndex = 12;
//
// grpLayerInfo
//
this.grpLayerInfo.Controls.Add(this.tableLayoutPanel5);
this.grpLayerInfo.Location = new System.Drawing.Point(3, 49);
this.grpLayerInfo.Name = "grpLayerInfo";
this.grpLayerInfo.Size = new System.Drawing.Size(137, 148);
this.grpLayerInfo.TabIndex = 3;
this.grpLayerInfo.TabStop = false;
this.grpLayerInfo.Text = "Layer Information";
//
// tableLayoutPanel5
//
this.tableLayoutPanel5.ColumnCount = 2;
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel5.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel5.Controls.Add(this.lblMapAddress, 0, 1);
this.tableLayoutPanel5.Controls.Add(this.lblMapSize, 0, 0);
this.tableLayoutPanel5.Controls.Add(this.lblBitDepth, 0, 4);
this.tableLayoutPanel5.Controls.Add(this.lblTileSize, 0, 2);
this.tableLayoutPanel5.Controls.Add(this.lblTilesetAddress, 0, 3);
this.tableLayoutPanel5.Controls.Add(this.txtMapSize, 1, 0);
this.tableLayoutPanel5.Controls.Add(this.txtMapAddress, 1, 1);
this.tableLayoutPanel5.Controls.Add(this.txtTileSize, 1, 2);
this.tableLayoutPanel5.Controls.Add(this.txtTilesetAddress, 1, 3);
this.tableLayoutPanel5.Controls.Add(this.txtBitDepth, 1, 4);
this.tableLayoutPanel5.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel5.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel5.Name = "tableLayoutPanel5";
this.tableLayoutPanel5.RowCount = 6;
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel5.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel5.Size = new System.Drawing.Size(131, 129);
this.tableLayoutPanel5.TabIndex = 0;
//
// lblMapAddress
//
this.lblMapAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblMapAddress.AutoSize = true;
this.lblMapAddress.Location = new System.Drawing.Point(3, 32);
this.lblMapAddress.Name = "lblMapAddress";
this.lblMapAddress.Size = new System.Drawing.Size(48, 13);
this.lblMapAddress.TabIndex = 2;
this.lblMapAddress.Text = "Address:";
//
// lblMapSize
//
this.lblMapSize.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblMapSize.AutoSize = true;
this.lblMapSize.Location = new System.Drawing.Point(3, 6);
this.lblMapSize.Name = "lblMapSize";
this.lblMapSize.Size = new System.Drawing.Size(30, 13);
this.lblMapSize.TabIndex = 1;
this.lblMapSize.Text = "Size:";
//
// lblBitDepth
//
this.lblBitDepth.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblBitDepth.AutoSize = true;
this.lblBitDepth.Location = new System.Drawing.Point(3, 110);
this.lblBitDepth.Name = "lblBitDepth";
this.lblBitDepth.Size = new System.Drawing.Size(54, 13);
this.lblBitDepth.TabIndex = 3;
this.lblBitDepth.Text = "Bit Depth:";
//
// lblTileSize
//
this.lblTileSize.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblTileSize.AutoSize = true;
this.lblTileSize.Location = new System.Drawing.Point(3, 58);
this.lblTileSize.Name = "lblTileSize";
this.lblTileSize.Size = new System.Drawing.Size(50, 13);
this.lblTileSize.TabIndex = 4;
this.lblTileSize.Text = "Tile Size:";
//
// lblTilesetAddress
//
this.lblTilesetAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblTilesetAddress.AutoSize = true;
this.lblTilesetAddress.Location = new System.Drawing.Point(3, 84);
this.lblTilesetAddress.Name = "lblTilesetAddress";
this.lblTilesetAddress.Size = new System.Drawing.Size(66, 13);
this.lblTilesetAddress.TabIndex = 5;
this.lblTilesetAddress.Text = "Tileset Addr:";
//
// txtMapSize
//
this.txtMapSize.Location = new System.Drawing.Point(75, 3);
this.txtMapSize.Name = "txtMapSize";
this.txtMapSize.ReadOnly = true;
this.txtMapSize.Size = new System.Drawing.Size(52, 20);
this.txtMapSize.TabIndex = 13;
//
// txtMapAddress
//
this.txtMapAddress.Location = new System.Drawing.Point(75, 29);
this.txtMapAddress.Name = "txtMapAddress";
this.txtMapAddress.ReadOnly = true;
this.txtMapAddress.Size = new System.Drawing.Size(43, 20);
this.txtMapAddress.TabIndex = 14;
//
// txtTileSize
//
this.txtTileSize.Location = new System.Drawing.Point(75, 55);
this.txtTileSize.Name = "txtTileSize";
this.txtTileSize.ReadOnly = true;
this.txtTileSize.Size = new System.Drawing.Size(43, 20);
this.txtTileSize.TabIndex = 15;
//
// txtTilesetAddress
//
this.txtTilesetAddress.Location = new System.Drawing.Point(75, 81);
this.txtTilesetAddress.Name = "txtTilesetAddress";
this.txtTilesetAddress.ReadOnly = true;
this.txtTilesetAddress.Size = new System.Drawing.Size(43, 20);
this.txtTilesetAddress.TabIndex = 16;
//
// txtBitDepth
//
this.txtBitDepth.Location = new System.Drawing.Point(75, 107);
this.txtBitDepth.Name = "txtBitDepth";
this.txtBitDepth.ReadOnly = true;
this.txtBitDepth.Size = new System.Drawing.Size(30, 20);
this.txtBitDepth.TabIndex = 17;
//
// tableLayoutPanel3
//
this.tableLayoutPanel3.ColumnCount = 6;
@ -228,7 +589,7 @@
this.mnuView});
this.ctrlMesenMenuStrip1.Location = new System.Drawing.Point(0, 0);
this.ctrlMesenMenuStrip1.Name = "ctrlMesenMenuStrip1";
this.ctrlMesenMenuStrip1.Size = new System.Drawing.Size(667, 24);
this.ctrlMesenMenuStrip1.Size = new System.Drawing.Size(668, 24);
this.ctrlMesenMenuStrip1.TabIndex = 8;
this.ctrlMesenMenuStrip1.Text = "ctrlMesenMenuStrip1";
//
@ -244,7 +605,7 @@
//
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
this.mnuClose.Name = "mnuClose";
this.mnuClose.Size = new System.Drawing.Size(152, 22);
this.mnuClose.Size = new System.Drawing.Size(103, 22);
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
@ -267,38 +628,38 @@
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(152, 22);
this.mnuAutoRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem2.Size = new System.Drawing.Size(138, 6);
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(152, 22);
this.mnuRefresh.Size = new System.Drawing.Size(141, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem1.Size = new System.Drawing.Size(138, 6);
//
// mnuZoomIn
//
this.mnuZoomIn.Name = "mnuZoomIn";
this.mnuZoomIn.Size = new System.Drawing.Size(152, 22);
this.mnuZoomIn.Size = new System.Drawing.Size(141, 22);
this.mnuZoomIn.Text = "Zoom In";
this.mnuZoomIn.Click += new System.EventHandler(this.mnuZoomIn_Click);
//
// mnuZoomOut
//
this.mnuZoomOut.Name = "mnuZoomOut";
this.mnuZoomOut.Size = new System.Drawing.Size(152, 22);
this.mnuZoomOut.Size = new System.Drawing.Size(141, 22);
this.mnuZoomOut.Text = "Zoom Out";
this.mnuZoomOut.Click += new System.EventHandler(this.mnuZoomOut_Click);
//
@ -306,7 +667,7 @@
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(667, 574);
this.ClientSize = new System.Drawing.Size(668, 560);
this.Controls.Add(this.tableLayoutPanel1);
this.Controls.Add(this.ctrlScanlineCycleSelect);
this.Controls.Add(this.ctrlMesenMenuStrip1);
@ -318,6 +679,12 @@
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
this.grpTileInfo.ResumeLayout(false);
this.tableLayoutPanel4.ResumeLayout(false);
this.tableLayoutPanel4.PerformLayout();
this.grpLayerInfo.ResumeLayout(false);
this.tableLayoutPanel5.ResumeLayout(false);
this.tableLayoutPanel5.PerformLayout();
this.tableLayoutPanel3.ResumeLayout(false);
this.tableLayoutPanel3.PerformLayout();
this.ctrlMesenMenuStrip1.ResumeLayout(false);
@ -352,5 +719,34 @@
private System.Windows.Forms.ToolStripMenuItem mnuZoomOut;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem mnuRefresh;
private System.Windows.Forms.GroupBox grpTileInfo;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4;
private System.Windows.Forms.TextBox txtPalette;
private System.Windows.Forms.TextBox txtTileNumber;
private System.Windows.Forms.TextBox txtAddress;
private System.Windows.Forms.TextBox txtPosition;
private System.Windows.Forms.Label lblMap;
private System.Windows.Forms.Label lblPosition;
private System.Windows.Forms.Label lblAddress;
private System.Windows.Forms.Label lblValue;
private System.Windows.Forms.Label lblTileNumber;
private System.Windows.Forms.Label lblPalette;
private System.Windows.Forms.CheckBox chkPriorityFlag;
private System.Windows.Forms.CheckBox chkHorizontalMirror;
private System.Windows.Forms.CheckBox chkVerticalMirror;
private System.Windows.Forms.TextBox txtMapNumber;
private System.Windows.Forms.TextBox txtValue;
private System.Windows.Forms.GroupBox grpLayerInfo;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel5;
private System.Windows.Forms.Label lblMapAddress;
private System.Windows.Forms.Label lblMapSize;
private System.Windows.Forms.Label lblBitDepth;
private System.Windows.Forms.Label lblTileSize;
private System.Windows.Forms.Label lblTilesetAddress;
private System.Windows.Forms.TextBox txtMapSize;
private System.Windows.Forms.TextBox txtMapAddress;
private System.Windows.Forms.TextBox txtTileSize;
private System.Windows.Forms.TextBox txtTilesetAddress;
private System.Windows.Forms.TextBox txtBitDepth;
}
}

View file

@ -16,6 +16,8 @@ namespace Mesen.GUI.Debugger
{
public partial class frmTilemapViewer : BaseForm
{
private int[,] _layerBpp = new int[8, 4] { { 2,2,2,2 }, { 4,4,2,0 }, { 4,4,0,0 }, { 8,4,0,0 }, { 8,2,0,0 }, { 4,2,0,0 }, { 4,0,0,0 }, { 8,0,0,0 } };
private NotificationListener _notifListener;
private GetTilemapOptions _options;
private DebugState _state;
@ -24,6 +26,8 @@ namespace Mesen.GUI.Debugger
private byte[] _tilemapData;
private Bitmap _tilemapImage;
private int _scale = 1;
private int _selectedRow = 0;
private int _selectedColumn = 0;
public frmTilemapViewer()
{
@ -88,18 +92,60 @@ namespace Mesen.GUI.Debugger
_cgram = DebugApi.GetMemoryState(SnesMemoryType.CGRam);
}
private bool IsLargeTileWidth
{
get { return _state.Ppu.Layers[_options.Layer].LargeTiles || _state.Ppu.BgMode == 5 || _state.Ppu.BgMode == 6; }
}
private bool IsLargeTileHeight
{
get { return _state.Ppu.Layers[_options.Layer].LargeTiles; }
}
private int GetWidth()
{
return _state.Ppu.BgMode == 7 ? 1024 : _state.Ppu.Layers[_options.Layer].DoubleWidth ? 512 : 256;
if(_state.Ppu.BgMode == 7) {
return 1024;
}
LayerConfig layer = _state.Ppu.Layers[_options.Layer];
bool largeTileWidth = layer.LargeTiles || _state.Ppu.BgMode == 5 || _state.Ppu.BgMode == 6;
bool largeTileHeight = layer.LargeTiles;
int width = 256;
if(layer.DoubleWidth) {
width *= 2;
}
if(largeTileWidth) {
width *= 2;
}
return width;
}
private int GetHeight()
{
return _state.Ppu.BgMode == 7 ? 1024 : _state.Ppu.Layers[_options.Layer].DoubleHeight ? 512 : 256;
if(_state.Ppu.BgMode == 7) {
return 1024;
}
LayerConfig layer = _state.Ppu.Layers[_options.Layer];
int height = 256;
if(layer.DoubleHeight) {
height *= 2;
}
if(layer.LargeTiles) {
height *= 2;
}
return height;
}
private void RefreshViewer()
{
if(_layerBpp[_state.Ppu.BgMode, _options.Layer] == 0) {
_options.Layer = 0;
}
DebugApi.GetTilemap(_options, _vram, _cgram, _tilemapData);
int mapWidth = GetWidth();
@ -111,20 +157,28 @@ namespace Mesen.GUI.Debugger
using(Graphics g = Graphics.FromImage(_tilemapImage)) {
GCHandle handle = GCHandle.Alloc(_tilemapData, GCHandleType.Pinned);
Bitmap source = new Bitmap(mapWidth, mapHeight, 4 * 1024, PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
try {
g.DrawImage(source, 0, 0);
} finally {
handle.Free();
}
g.DrawImage(source, 0, 0);
g.DrawRectangle(Pens.Gray, _selectedColumn * 8 - 2, _selectedRow * 8 - 2, IsLargeTileWidth ? 19 : 11, IsLargeTileHeight ? 19 : 11);
g.DrawRectangle(Pens.White, _selectedColumn * 8 - 1, _selectedRow * 8 - 1, IsLargeTileWidth ? 17 : 9, IsLargeTileHeight ? 17 : 9);
handle.Free();
}
btnLayer1.BackColor = _options.Layer == 0 ? SystemColors.GradientActiveCaption : SystemColors.ControlLight;
btnLayer2.BackColor = _options.Layer == 1 ? SystemColors.GradientActiveCaption : SystemColors.ControlLight;
btnLayer3.BackColor = _options.Layer == 2 ? SystemColors.GradientActiveCaption : SystemColors.ControlLight;
btnLayer4.BackColor = _options.Layer == 3 ? SystemColors.GradientActiveCaption : SystemColors.ControlLight;
btnLayer1.BackColor = _options.Layer == 0 ? SystemColors.GradientActiveCaption : Color.Empty;
btnLayer2.BackColor = _options.Layer == 1 ? SystemColors.GradientActiveCaption : Color.Empty;
btnLayer3.BackColor = _options.Layer == 2 ? SystemColors.GradientActiveCaption : Color.Empty;
btnLayer4.BackColor = _options.Layer == 3 ? SystemColors.GradientActiveCaption : Color.Empty;
btnLayer1.Enabled = _layerBpp[_state.Ppu.BgMode, 0] > 0;
btnLayer2.Enabled = _layerBpp[_state.Ppu.BgMode, 1] > 0;
btnLayer3.Enabled = _layerBpp[_state.Ppu.BgMode, 2] > 0;
btnLayer4.Enabled = _layerBpp[_state.Ppu.BgMode, 3] > 0;
UpdateMapSize();
picTilemap.Invalidate();
UpdateFields();
}
private void UpdateMapSize()
@ -133,6 +187,59 @@ namespace Mesen.GUI.Debugger
picTilemap.Height = GetHeight() * _scale;
}
private void UpdateFields()
{
if(_state.Ppu.BgMode == 7) {
//Selected tile
txtMapNumber.Text = "0";
txtPosition.Text = _selectedColumn.ToString() + ", " + _selectedRow.ToString();
int address = _selectedRow * 128 + _selectedColumn;
int value = _vram[address] | (_vram[address + 1] << 8);
txtAddress.Text = address.ToString("X4");
txtValue.Text = value.ToString("X4");
txtTileNumber.Text = (value & 0xFF).ToString();
txtPalette.Text = "0";
chkPriorityFlag.Checked = false;
chkHorizontalMirror.Checked = false;
chkVerticalMirror.Checked = false;
//Tilemap
txtMapSize.Text = "128x128";
txtMapAddress.Text = "0000";
txtTilesetAddress.Text = "0000";
txtTileSize.Text = "8x8";
txtBitDepth.Text = "8";
} else {
int row = (IsLargeTileHeight ? _selectedRow / 2 : _selectedRow);
int column = (IsLargeTileWidth ? _selectedColumn / 2 : _selectedColumn);
LayerConfig layer = _state.Ppu.Layers[_options.Layer];
int addrVerticalScrollingOffset = layer.DoubleHeight ? ((row & 0x20) << (layer.DoubleWidth ? 6 : 5)) : 0;
int baseOffset = (layer.TilemapAddress >> 1) + addrVerticalScrollingOffset + ((row & 0x1F) << 5);
int address = (baseOffset + (column & 0x1F) + (layer.DoubleWidth ? ((column & 0x20) << 5) : 0)) << 1;
int value = _vram[address] | (_vram[address + 1] << 8);
//Selected tile
txtMapNumber.Text = ((column >= 32 ? 1 : 0) + (row >= 32 ? 1 : 0)).ToString();
txtPosition.Text = (column & 0x1F).ToString() + ", " + (row & 0x1F).ToString();
txtAddress.Text = address.ToString("X4");
txtValue.Text = value.ToString("X4");
txtTileNumber.Text = (value & 0x3FF).ToString();
txtPalette.Text = ((value >> 10) & 0x07).ToString();
chkPriorityFlag.Checked = (value & 0x2000) != 0;
chkHorizontalMirror.Checked = (value & 0x4000) != 0;
chkVerticalMirror.Checked = (value & 0x8000) != 0;
//Tilemap
txtMapSize.Text = (layer.DoubleWidth ? "64" : "32") + "x" + (layer.DoubleHeight ? "64" : "32");
txtMapAddress.Text = layer.TilemapAddress.ToString("X4");
txtTilesetAddress.Text = layer.ChrAddress.ToString("X4");
txtTileSize.Text = (IsLargeTileWidth ? "16" : "8") + "x" + (IsLargeTileHeight ? "16" : "8");
txtBitDepth.Text = _layerBpp[_state.Ppu.BgMode, _options.Layer].ToString();
}
}
private void btnLayer1_Click(object sender, EventArgs e)
{
_options.Layer = 0;
@ -160,11 +267,13 @@ namespace Mesen.GUI.Debugger
private void chkShowTileGrid_Click(object sender, EventArgs e)
{
_options.ShowTileGrid = chkShowTileGrid.Checked;
RefreshViewer();
}
private void chkShowScrollOverlay_Click(object sender, EventArgs e)
{
_options.ShowScrollOverlay = chkShowScrollOverlay.Checked;
RefreshViewer();
}
private void mnuRefresh_Click(object sender, EventArgs e)
@ -189,5 +298,20 @@ namespace Mesen.GUI.Debugger
{
Close();
}
private void picTilemap_MouseClick(object sender, MouseEventArgs e)
{
_selectedColumn = e.X / (8 * _scale);
_selectedRow = e.Y / (8 * _scale);
if(IsLargeTileWidth) {
_selectedColumn &= 0xFE;
}
if(IsLargeTileHeight) {
_selectedRow &= 0xFE;
}
RefreshViewer();
}
}
}