Debugger: GB - Tilemap viewer improvements

-Show tilemap/tile information
-Show overlay option
This commit is contained in:
Sour 2020-06-01 21:42:49 -04:00
parent 2355ef6550
commit 6bccfa874f
8 changed files with 133 additions and 96 deletions

View file

@ -591,14 +591,6 @@ void GbPpu::UpdateStatIrq()
_state.StatIrqFlag = irqFlag;
}
void GbPpu::GetPalette(uint16_t out[4], uint8_t palCfg)
{
out[0] = bwRgbPalette[palCfg & 0x03];
out[1] = bwRgbPalette[(palCfg >> 2) & 0x03];
out[2] = bwRgbPalette[(palCfg >> 4) & 0x03];
out[3] = bwRgbPalette[(palCfg >> 6) & 0x03];
}
uint32_t GbPpu::GetFrameCount()
{
return _state.FrameCount;

View file

@ -78,8 +78,7 @@ public:
GbPpuState GetState();
uint16_t* GetEventViewerBuffer();
uint16_t* GetPreviousEventViewerBuffer();
void GetPalette(uint16_t out[4], uint8_t palCfg);
uint32_t GetFrameCount();
bool IsLcdEnabled();
PpuMode GetMode();

View file

@ -7,9 +7,7 @@
#include "MemoryManager.h"
#include "NotificationManager.h"
#include "DefaultVideoFilter.h"
#include "Gameboy.h"
#include "GbTypes.h"
#include "GbPpu.h"
PpuTools::PpuTools(Console *console, Ppu *ppu)
{
@ -374,16 +372,11 @@ void PpuTools::UpdateViewers(uint16_t scanline, uint16_t cycle)
}
}
void PpuTools::GetGameboyTilemap(uint8_t* vram, uint16_t offset, uint32_t* outBuffer)
void PpuTools::GetGameboyTilemap(uint8_t* vram, GbPpuState& state, uint16_t offset, uint32_t* outBuffer)
{
Gameboy* gameboy = _console->GetCartridge()->GetGameboy();
GbState state = gameboy->GetState();
bool isCgb = state.Type == GbType::Cgb;
bool isCgb = state.CgbEnabled;
uint16_t palette[4];
gameboy->GetPpu()->GetPalette(palette, state.Ppu.BgPalette);
uint16_t baseTile = state.Ppu.BgTileSelect ? 0 : 0x1000;
uint16_t baseTile = state.BgTileSelect ? 0 : 0x1000;
std::fill(outBuffer, outBuffer + 1024*256, 0xFFFFFFFF);
@ -413,11 +406,7 @@ void PpuTools::GetGameboyTilemap(uint8_t* vram, uint16_t offset, uint32_t* outBu
uint8_t shift = hMirror ? (x & 0x07) : (7 - (x & 0x07));
uint8_t color = GetTilePixelColor(vram, vramMask, 2, pixelStart, shift);
if(isCgb) {
outBuffer[((row * 8) + y) * 1024 + column * 8 + x] = DefaultVideoFilter::ToArgb(state.Ppu.CgbBgPalettes[bgPalette + color]);
} else if(color != 0) {
outBuffer[((row * 8) + y) * 1024 + column * 8 + x] = DefaultVideoFilter::ToArgb(palette[color]);
}
outBuffer[((row * 8) + y) * 1024 + column * 8 + x] = DefaultVideoFilter::ToArgb(state.CgbBgPalettes[bgPalette + color]);
}
}
}

View file

@ -4,6 +4,7 @@
class Ppu;
class Console;
struct GbPpuState;
class PpuTools
{
@ -29,5 +30,5 @@ public:
void RemoveViewer(uint32_t viewerId);
void UpdateViewers(uint16_t scanline, uint16_t cycle);
void GetGameboyTilemap(uint8_t* vram, uint16_t offset, uint32_t* outBuffer);
void GetGameboyTilemap(uint8_t* vram, GbPpuState& state, uint16_t offset, uint32_t* outBuffer);
};

View file

@ -92,7 +92,7 @@ extern "C"
DllExport void __stdcall GetSpritePreview(GetSpritePreviewOptions options, PpuState state, uint8_t* vram, uint8_t *oamRam, uint8_t *cgram, uint32_t *buffer) { GetDebugger()->GetPpuTools()->GetSpritePreview(options, state, vram, oamRam, cgram, buffer); }
DllExport void __stdcall SetViewerUpdateTiming(uint32_t viewerId, uint16_t scanline, uint16_t cycle) { GetDebugger()->GetPpuTools()->SetViewerUpdateTiming(viewerId, scanline, cycle); }
DllExport void __stdcall GetGameboyTilemap(uint8_t* vram, uint16_t offset, uint32_t* buffer) { GetDebugger()->GetPpuTools()->GetGameboyTilemap(vram, offset, buffer); }
DllExport void __stdcall GetGameboyTilemap(uint8_t* vram, GbPpuState state, uint16_t offset, uint32_t* buffer) { GetDebugger()->GetPpuTools()->GetGameboyTilemap(vram, state, offset, buffer); }
DllExport void __stdcall GetDebugEvents(DebugEventInfo *infoArray, uint32_t &maxEventCount) { GetDebugger()->GetEventManager()->GetEvents(infoArray, maxEventCount); }
DllExport uint32_t __stdcall GetDebugEventCount(EventViewerDisplayOptions options) { return GetDebugger()->GetEventManager()->GetEventCount(options); }

View file

@ -53,6 +53,8 @@
this.chkVerticalMirror = new System.Windows.Forms.CheckBox();
this.txtMapNumber = new System.Windows.Forms.TextBox();
this.txtValue = new System.Windows.Forms.TextBox();
this.lblTileAddress = new System.Windows.Forms.Label();
this.txtTileAddress = 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();
@ -85,8 +87,6 @@
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuZoomIn = new System.Windows.Forms.ToolStripMenuItem();
this.mnuZoomOut = new System.Windows.Forms.ToolStripMenuItem();
this.lblTileAddress = new System.Windows.Forms.Label();
this.txtTileAddress = new System.Windows.Forms.TextBox();
this.tableLayoutPanel1.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
this.grpTileInfo.SuspendLayout();
@ -252,10 +252,10 @@
this.tableLayoutPanel4.RowCount = 13;
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(System.Windows.Forms.SizeType.Absolute, 5F));
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(System.Windows.Forms.SizeType.Absolute, 5F));
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());
@ -268,7 +268,7 @@
//
// txtPalette
//
this.txtPalette.Location = new System.Drawing.Point(77, 179);
this.txtPalette.Location = new System.Drawing.Point(77, 169);
this.txtPalette.Name = "txtPalette";
this.txtPalette.ReadOnly = true;
this.txtPalette.Size = new System.Drawing.Size(30, 20);
@ -276,18 +276,18 @@
//
// txtTileNumber
//
this.txtTileNumber.Location = new System.Drawing.Point(77, 127);
this.txtTileNumber.Location = new System.Drawing.Point(77, 117);
this.txtTileNumber.Name = "txtTileNumber";
this.txtTileNumber.ReadOnly = true;
this.txtTileNumber.Size = new System.Drawing.Size(42, 20);
this.txtTileNumber.Size = new System.Drawing.Size(52, 20);
this.txtTileNumber.TabIndex = 13;
//
// txtAddress
//
this.txtAddress.Location = new System.Drawing.Point(77, 65);
this.txtAddress.Location = new System.Drawing.Point(77, 60);
this.txtAddress.Name = "txtAddress";
this.txtAddress.ReadOnly = true;
this.txtAddress.Size = new System.Drawing.Size(43, 20);
this.txtAddress.Size = new System.Drawing.Size(52, 20);
this.txtAddress.TabIndex = 11;
//
// txtPosition
@ -322,7 +322,7 @@
//
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
this.lblAddress.Location = new System.Drawing.Point(3, 68);
this.lblAddress.Location = new System.Drawing.Point(3, 63);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(48, 13);
this.lblAddress.TabIndex = 2;
@ -332,7 +332,7 @@
//
this.lblValue.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblValue.AutoSize = true;
this.lblValue.Location = new System.Drawing.Point(3, 94);
this.lblValue.Location = new System.Drawing.Point(3, 89);
this.lblValue.Name = "lblValue";
this.lblValue.Size = new System.Drawing.Size(37, 13);
this.lblValue.TabIndex = 3;
@ -342,7 +342,7 @@
//
this.lblTileNumber.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblTileNumber.AutoSize = true;
this.lblTileNumber.Location = new System.Drawing.Point(3, 130);
this.lblTileNumber.Location = new System.Drawing.Point(3, 120);
this.lblTileNumber.Name = "lblTileNumber";
this.lblTileNumber.Size = new System.Drawing.Size(67, 13);
this.lblTileNumber.TabIndex = 4;
@ -352,7 +352,7 @@
//
this.lblPalette.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblPalette.AutoSize = true;
this.lblPalette.Location = new System.Drawing.Point(3, 182);
this.lblPalette.Location = new System.Drawing.Point(3, 172);
this.lblPalette.Name = "lblPalette";
this.lblPalette.Size = new System.Drawing.Size(43, 13);
this.lblPalette.TabIndex = 5;
@ -363,7 +363,7 @@
this.chkPriorityFlag.AutoCheck = false;
this.chkPriorityFlag.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.chkPriorityFlag, 2);
this.chkPriorityFlag.Location = new System.Drawing.Point(3, 202);
this.chkPriorityFlag.Location = new System.Drawing.Point(3, 192);
this.chkPriorityFlag.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
this.chkPriorityFlag.Name = "chkPriorityFlag";
this.chkPriorityFlag.Size = new System.Drawing.Size(57, 17);
@ -376,7 +376,7 @@
this.chkHorizontalMirror.AutoCheck = false;
this.chkHorizontalMirror.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.chkHorizontalMirror, 2);
this.chkHorizontalMirror.Location = new System.Drawing.Point(3, 219);
this.chkHorizontalMirror.Location = new System.Drawing.Point(3, 209);
this.chkHorizontalMirror.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
this.chkHorizontalMirror.Name = "chkHorizontalMirror";
this.chkHorizontalMirror.Size = new System.Drawing.Size(102, 17);
@ -389,7 +389,7 @@
this.chkVerticalMirror.AutoCheck = false;
this.chkVerticalMirror.AutoSize = true;
this.tableLayoutPanel4.SetColumnSpan(this.chkVerticalMirror, 2);
this.chkVerticalMirror.Location = new System.Drawing.Point(3, 236);
this.chkVerticalMirror.Location = new System.Drawing.Point(3, 226);
this.chkVerticalMirror.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
this.chkVerticalMirror.Name = "chkVerticalMirror";
this.chkVerticalMirror.Size = new System.Drawing.Size(90, 17);
@ -407,12 +407,30 @@
//
// txtValue
//
this.txtValue.Location = new System.Drawing.Point(77, 91);
this.txtValue.Location = new System.Drawing.Point(77, 86);
this.txtValue.Name = "txtValue";
this.txtValue.ReadOnly = true;
this.txtValue.Size = new System.Drawing.Size(43, 20);
this.txtValue.Size = new System.Drawing.Size(52, 20);
this.txtValue.TabIndex = 12;
//
// lblTileAddress
//
this.lblTileAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblTileAddress.AutoSize = true;
this.lblTileAddress.Location = new System.Drawing.Point(3, 146);
this.lblTileAddress.Name = "lblTileAddress";
this.lblTileAddress.Size = new System.Drawing.Size(68, 13);
this.lblTileAddress.TabIndex = 15;
this.lblTileAddress.Text = "Tile Address:";
//
// txtTileAddress
//
this.txtTileAddress.Location = new System.Drawing.Point(77, 143);
this.txtTileAddress.Name = "txtTileAddress";
this.txtTileAddress.ReadOnly = true;
this.txtTileAddress.Size = new System.Drawing.Size(52, 20);
this.txtTileAddress.TabIndex = 16;
//
// grpLayerInfo
//
this.grpLayerInfo.Controls.Add(this.tableLayoutPanel5);
@ -725,24 +743,6 @@
this.mnuZoomOut.Text = "Zoom Out";
this.mnuZoomOut.Click += new System.EventHandler(this.mnuZoomOut_Click);
//
// lblTileAddress
//
this.lblTileAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblTileAddress.AutoSize = true;
this.lblTileAddress.Location = new System.Drawing.Point(3, 156);
this.lblTileAddress.Name = "lblTileAddress";
this.lblTileAddress.Size = new System.Drawing.Size(68, 13);
this.lblTileAddress.TabIndex = 15;
this.lblTileAddress.Text = "Tile Address:";
//
// txtTileAddress
//
this.txtTileAddress.Location = new System.Drawing.Point(77, 153);
this.txtTileAddress.Name = "txtTileAddress";
this.txtTileAddress.ReadOnly = true;
this.txtTileAddress.Size = new System.Drawing.Size(42, 20);
this.txtTileAddress.TabIndex = 16;
//
// frmTilemapViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

View file

@ -20,7 +20,7 @@ namespace Mesen.GUI.Debugger
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 GetTilemapOptions _options;
private PpuState _state;
private DebugState _state;
private byte[] _cgram;
private byte[] _vram;
private byte[] _tilemapData;
@ -105,29 +105,29 @@ namespace Mesen.GUI.Debugger
public void RefreshData()
{
_isGameboyMode = EmuApi.GetRomInfo().CoprocessorType == CoprocessorType.Gameboy;
_state = DebugApi.GetState().Ppu;
_state = DebugApi.GetState();
_vram = DebugApi.GetMemoryState(_isGameboyMode ? SnesMemoryType.GbVideoRam : SnesMemoryType.VideoRam);
_cgram = DebugApi.GetMemoryState(SnesMemoryType.CGRam);
}
private bool IsDoubleWidthScreen
{
get { return _state.HiResMode || _state.BgMode == 5 || _state.BgMode == 6; }
get { return _state.Ppu.HiResMode || _state.Ppu.BgMode == 5 || _state.Ppu.BgMode == 6; }
}
private bool IsDoubleHeightScreen
{
get { return _state.ScreenInterlace || _state.BgMode == 5 || _state.BgMode == 6; }
get { return _state.Ppu.ScreenInterlace || _state.Ppu.BgMode == 5 || _state.Ppu.BgMode == 6; }
}
private bool IsLargeTileWidth
{
get { return _state.Layers[_options.Layer].LargeTiles || _state.BgMode == 5 || _state.BgMode == 6; }
get { return _state.Ppu.Layers[_options.Layer].LargeTiles || _state.Ppu.BgMode == 5 || _state.Ppu.BgMode == 6; }
}
private bool IsLargeTileHeight
{
get { return _state.Layers[_options.Layer].LargeTiles; }
get { return _state.Ppu.Layers[_options.Layer].LargeTiles; }
}
public ctrlScanlineCycleSelect ScanlineCycleSelect
@ -139,12 +139,12 @@ namespace Mesen.GUI.Debugger
{
if(_isGameboyMode) {
return 256;
} else if(_state.BgMode == 7) {
} else if(_state.Ppu.BgMode == 7) {
return 1024;
}
LayerConfig layer = _state.Layers[_options.Layer];
bool largeTileWidth = layer.LargeTiles || _state.BgMode == 5 || _state.BgMode == 6;
LayerConfig layer = _state.Ppu.Layers[_options.Layer];
bool largeTileWidth = layer.LargeTiles || _state.Ppu.BgMode == 5 || _state.Ppu.BgMode == 6;
int width = 256;
if(layer.DoubleWidth) {
@ -160,11 +160,11 @@ namespace Mesen.GUI.Debugger
{
if(_isGameboyMode) {
return 256;
} else if(_state.BgMode == 7) {
} else if(_state.Ppu.BgMode == 7) {
return 1024;
}
LayerConfig layer = _state.Layers[_options.Layer];
LayerConfig layer = _state.Ppu.Layers[_options.Layer];
int height = 256;
if(layer.DoubleHeight) {
@ -178,14 +178,14 @@ namespace Mesen.GUI.Debugger
public void RefreshViewer()
{
if(_layerBpp[_state.BgMode, _options.Layer] == 0) {
if(_layerBpp[_state.Ppu.BgMode, _options.Layer] == 0) {
_options.Layer = 0;
}
if(_isGameboyMode) {
DebugApi.GetGameboyTilemap(_vram, (ushort)(_options.Layer == 0 ? 0x1800 : 0x1C00), _tilemapData);
DebugApi.GetGameboyTilemap(_vram, _state.Gameboy.Ppu, (ushort)(_options.Layer == 0 ? 0x1800 : 0x1C00), _tilemapData);
} else {
DebugApi.GetTilemap(_options, _state, _vram, _cgram, _tilemapData);
DebugApi.GetTilemap(_options, _state.Ppu, _vram, _cgram, _tilemapData);
}
int mapWidth = GetWidth();
@ -206,17 +206,22 @@ namespace Mesen.GUI.Debugger
btnLayer3.BackColor = _options.Layer == 2 ? SystemColors.GradientActiveCaption : Color.Empty;
btnLayer4.BackColor = _options.Layer == 3 ? SystemColors.GradientActiveCaption : Color.Empty;
btnLayer1.Enabled = _layerBpp[_state.BgMode, 0] > 0;
btnLayer2.Enabled = _layerBpp[_state.BgMode, 1] > 0;
btnLayer3.Enabled = _layerBpp[_state.BgMode, 2] > 0;
btnLayer4.Enabled = _layerBpp[_state.BgMode, 3] > 0;
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;
btnLayer1.Text = _isGameboyMode ? "BG" : "1";
btnLayer2.Text = _isGameboyMode ? "Window" : "2";
btnLayer2.Width = _isGameboyMode ? 64 : 32;
grpLayerInfo.Visible = !_isGameboyMode;
grpTileInfo.Visible = !_isGameboyMode;
btnLayer3.Visible = !_isGameboyMode;
btnLayer4.Visible = !_isGameboyMode;
chkShowScrollOverlay.Visible = !_isGameboyMode;
lblMap.Visible = !_isGameboyMode;
txtMapNumber.Visible = !_isGameboyMode;
lblValue.Visible = !_isGameboyMode;
txtValue.Visible = !_isGameboyMode;
ctrlImagePanel.ImageSize = new Size(GetWidth(), GetHeight());
ctrlImagePanel.Selection = new Rectangle(_selectedColumn * 8, _selectedRow * 8, IsLargeTileWidth ? 16 : 8, IsLargeTileHeight ? 16 : 8);
@ -224,25 +229,37 @@ namespace Mesen.GUI.Debugger
ctrlImagePanel.GridSizeX = chkShowTileGrid.Checked ? (IsLargeTileWidth ? 16 : 8): 0;
ctrlImagePanel.GridSizeY = chkShowTileGrid.Checked ? (IsLargeTileHeight ? 16 : 8): 0;
if(!_isGameboyMode && chkShowScrollOverlay.Checked) {
LayerConfig layer = _state.Layers[_options.Layer];
int hScroll = _state.BgMode == 7 ? (int)_state.Mode7.HScroll : layer.HScroll;
int vScroll = _state.BgMode == 7 ? (int)_state.Mode7.VScroll : layer.VScroll;
int height = _state.OverscanMode ? 239 : 224;
ctrlImagePanel.Overlay = new Rectangle(hScroll, vScroll, IsDoubleWidthScreen ? 512 : 256, IsDoubleHeightScreen ? height*2 : height);
if(chkShowScrollOverlay.Checked) {
if(_isGameboyMode) {
if(_options.Layer == 0) {
GbPpuState ppu = _state.Gameboy.Ppu;
ctrlImagePanel.Overlay = new Rectangle(ppu.ScrollX, ppu.ScrollY, 160, 144);
} else {
//Hide for window, doesn't make sense to show this
ctrlImagePanel.Overlay = Rectangle.Empty;
}
} else {
LayerConfig layer = _state.Ppu.Layers[_options.Layer];
int hScroll = _state.Ppu.BgMode == 7 ? (int)_state.Ppu.Mode7.HScroll : layer.HScroll;
int vScroll = _state.Ppu.BgMode == 7 ? (int)_state.Ppu.Mode7.VScroll : layer.VScroll;
int height = _state.Ppu.OverscanMode ? 239 : 224;
ctrlImagePanel.Overlay = new Rectangle(hScroll, vScroll, IsDoubleWidthScreen ? 512 : 256, IsDoubleHeightScreen ? height * 2 : height);
}
} else {
ctrlImagePanel.Overlay = Rectangle.Empty;
}
ctrlImagePanel.Refresh();
if(!_isGameboyMode) {
if(_isGameboyMode) {
UpdateGameboyFields();
} else {
UpdateFields();
}
}
private void UpdateFields()
{
if(_state.BgMode == 7) {
if(_state.Ppu.BgMode == 7) {
//Selected tile
txtMapNumber.Text = "0";
txtPosition.Text = _selectedColumn.ToString() + ", " + _selectedRow.ToString();
@ -268,19 +285,19 @@ namespace Mesen.GUI.Debugger
int row = (IsLargeTileHeight ? _selectedRow / 2 : _selectedRow);
int column = (IsLargeTileWidth ? _selectedColumn / 2 : _selectedColumn);
LayerConfig layer = _state.Layers[_options.Layer];
LayerConfig layer = _state.Ppu.Layers[_options.Layer];
int addrVerticalScrollingOffset = layer.DoubleHeight ? ((row & 0x20) << (layer.DoubleWidth ? 6 : 5)) : 0;
int baseOffset = layer.TilemapAddress + addrVerticalScrollingOffset + ((row & 0x1F) << 5);
int address = ((baseOffset + (column & 0x1F) + (layer.DoubleWidth ? ((column & 0x20) << 5) : 0)) << 1) & 0xFFFF;
int value = _vram[address] | (_vram[address + 1] << 8);
//Selected tile
txtMapNumber.Text = ((column >= 32 ? 1 : 0) + (row >= 32 ? 1 : 0)).ToString();
txtMapNumber.Text = ((column >= 32 ? 1 : 0) + (row >= 32 ? 2 : 0)).ToString();
txtPosition.Text = (column & 0x1F).ToString() + ", " + (row & 0x1F).ToString();
txtAddress.Text = address.ToString("X4");
txtValue.Text = value.ToString("X4");
int bpp = _layerBpp[_state.BgMode, _options.Layer];
int bpp = _layerBpp[_state.Ppu.BgMode, _options.Layer];
int tileNumber = (value & 0x3FF);
txtTileNumber.Text = tileNumber.ToString();
txtTileAddress.Text = ((layer.ChrAddress << 1) + (tileNumber * bpp * 8)).ToString("X4");
@ -299,6 +316,45 @@ namespace Mesen.GUI.Debugger
}
}
private void UpdateGameboyFields()
{
GbPpuState state = _state.Gameboy.Ppu;
bool isGbc = state.CgbEnabled;
bool tilemapSelect = _options.Layer == 1 ? state.WindowTilemapSelect : state.BgTilemapSelect;
int tilemapAddress = tilemapSelect ? 0x1C00 : 0x1800;
int tilesetAddress = state.BgTileSelect ? 0x0000 : 0x1000;
int row = _selectedRow;
int column = _selectedColumn;
int address = tilemapAddress + (row * 32) + column;
byte tileNumber = _vram[address & 0x1FFF];
int attributes = isGbc ? _vram[0x2000 | (address & 0x1FFF)] : 0;
//Selected tile
txtPosition.Text = column.ToString() + ", " + row.ToString();
txtAddress.Text = address.ToString("X4");
txtTileNumber.Text = tileNumber.ToString() + " ($" + tileNumber.ToString("X2") + ")";
int tileAddress = tilesetAddress + (state.BgTileSelect ? tileNumber : (int)(sbyte)tileNumber) * 16;
if((attributes & 0x08) != 0) {
tileAddress |= 0x2000;
}
txtTileAddress.Text = tileAddress.ToString("X4");
txtPalette.Text = (attributes & 0x07).ToString();
chkPriorityFlag.Checked = (attributes & 0x80) != 0;
chkVerticalMirror.Checked = (attributes & 0x40) != 0;
chkHorizontalMirror.Checked = (attributes & 0x20) != 0;
//Tilemap
txtMapSize.Text = "32x32";
txtMapAddress.Text = (0x8000 | tilemapAddress).ToString("X4");
txtTilesetAddress.Text = (0x8000 | tilesetAddress).ToString("X4");
txtTileSize.Text = "8x8";
txtBitDepth.Text = "2";
}
private void btnLayer1_Click(object sender, EventArgs e)
{
_options.Layer = 0;

View file

@ -88,7 +88,7 @@ namespace Mesen.GUI
}
[DllImport(DllPath)] public static extern void GetTilemap(GetTilemapOptions options, PpuState state, byte[] vram, byte[] cgram, [In, Out] byte[] buffer);
[DllImport(DllPath)] public static extern void GetGameboyTilemap(byte[] vram, UInt16 offset, [In, Out] byte[] buffer);
[DllImport(DllPath)] public static extern void GetGameboyTilemap(byte[] vram, GbPpuState state, UInt16 offset, [In, Out] byte[] buffer);
[DllImport(DllPath)] public static extern void GetTileView(GetTileViewOptions options, byte[] source, int srcSize, byte[] cgram, [In, Out] byte[] buffer);
[DllImport(DllPath)] public static extern void GetSpritePreview(GetSpritePreviewOptions options, PpuState state, byte[] vram, byte[] oamRam, byte[] cgram, [In, Out] byte[] buffer);