Debugger: CHR Viewer - Added option to show single-color tiles in grayscale

This commit is contained in:
Sour 2018-07-28 15:32:38 -04:00
parent 79b773e65f
commit 13d49fee5b
8 changed files with 83 additions and 42 deletions

View file

@ -409,9 +409,8 @@ void MemoryDumper::GatherChrPaletteInfo()
}
}
void MemoryDumper::GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType, uint32_t* paletteBuffer)
void MemoryDumper::GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType, bool useAutoPalette, bool showSingleColorTilesInGrayscale, uint32_t* paletteBuffer)
{
bool useAutoPalette = (palette & 0x80) == 0x80;
uint8_t paletteBaseAddr = (palette & 0x07) << 2;
uint32_t defaultPalette;
if(palette & 0x08) {
@ -469,46 +468,52 @@ void MemoryDumper::GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t pale
}
auto result = _paletteByTile.find(key);
if(result != _paletteByTile.end()) {
uint32_t lastPalette = result->second;
if(
(lastPalette & 0xFF) != ((lastPalette >> 8) & 0xFF) ||
(lastPalette & 0xFF) != ((lastPalette >> 16) & 0xFF) ||
(lastPalette & 0xFF) != ((lastPalette >> 24) & 0xFF)
) {
//Only use automatic palette if the result contains more than 1 color
paletteData = lastPalette;
} else {
//Use grayscale if auto-palette results in a single color palette
paletteData = 0x2010000F;
}
paletteData = result->second;
}
}
paletteBuffer[tileIndex] = paletteData;
auto outputTile = [=](uint32_t palette) {
paletteBuffer[tileIndex] = palette;
uint16_t tileAddr = tileIndex << 4;
for(uint8_t i = 0; i < 8; i++) {
uint8_t lowByte = chrBuffer[tileAddr + i];
uint8_t highByte = chrBuffer[tileAddr + i + 8];
bool isDrawn = chrIsDrawn[tileAddr + i];
for(uint8_t j = 0; j < 8; j++) {
uint8_t color = ((lowByte >> (7 - j)) & 0x01) | (((highByte >> (7 - j)) & 0x01) << 1);
bool usesSingleColor = true;
int64_t previousColor = -1;
uint16_t tileAddr = tileIndex << 4;
for(uint8_t i = 0; i < 8; i++) {
uint8_t lowByte = chrBuffer[tileAddr + i];
uint8_t highByte = chrBuffer[tileAddr + i + 8];
bool isDrawn = chrIsDrawn[tileAddr + i];
for(uint8_t j = 0; j < 8; j++) {
uint8_t color = ((lowByte >> (7 - j)) & 0x01) | (((highByte >> (7 - j)) & 0x01) << 1);
uint32_t position;
if(largeSprites) {
int tmpX = x / 2 + ((y & 0x01) ? 8 : 0);
int tmpY = (y & 0xFE) + ((x & 0x01) ? 1 : 0);
uint32_t position;
if(largeSprites) {
int tmpX = x / 2 + ((y & 0x01) ? 8 : 0);
int tmpY = (y & 0xFE) + ((x & 0x01) ? 1 : 0);
position = (tmpY << 10) + (tmpX << 3) + (i << 7) + j;
} else {
position = (y << 10) + (x << 3) + (i << 7) + j;
}
position = (tmpY << 10) + (tmpX << 3) + (i << 7) + j;
} else {
position = (y << 10) + (x << 3) + (i << 7) + j;
}
frameBuffer[position] = rgbPalette[(paletteData >> (8 * color)) & 0x3F];
if(highlightType != CdlHighlightType::None && isDrawn == (highlightType != CdlHighlightType::HighlightUsed)) {
frameBuffer[position] &= 0x4FFFFFFF;
uint32_t pixelColor = rgbPalette[(palette >> (8 * color)) & 0x3F];
frameBuffer[position] = pixelColor;
if(previousColor >= 0 && previousColor != pixelColor) {
usesSingleColor = false;
}
previousColor = pixelColor;
if(highlightType != CdlHighlightType::None && isDrawn == (highlightType != CdlHighlightType::HighlightUsed)) {
frameBuffer[position] &= 0x4FFFFFFF;
}
}
}
return !usesSingleColor;
};
if(!outputTile(paletteData) && showSingleColorTilesInGrayscale) {
//Tile is a solid color, redraw it in grayscale
outputTile(0x2010000F);
}
}
}

View file

@ -97,7 +97,7 @@ public:
uint32_t GetMemorySize(DebugMemoryType type);
uint32_t GetMemoryState(DebugMemoryType type, uint8_t *buffer);
void GetNametable(int nametableIndex, bool useGrayscalePalette, uint32_t* frameBuffer, uint8_t* tileData, uint8_t* paletteData);
void GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType, uint32_t* paletteBuffer);
void GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType, bool useAutoPalette, bool showSingleColorTilesInGrayscale, uint32_t* paletteBuffer);
void GetSprites(uint32_t* frameBuffer);
void GetPalette(uint32_t* frameBuffer);

View file

@ -190,6 +190,7 @@ namespace Mesen.GUI.Config
public bool ChrViewerUseAutoPalette = true;
public bool ChrViewerUseLargeSprites = false;
public bool ChrViewerShowSingleColorTilesInGrayscale = false;
public int PpuDisplayCycle = 0;
public int PpuDisplayScanline = 241;

View file

@ -43,7 +43,7 @@ namespace Mesen.GUI.Debugger.Controls
public void GetData()
{
UInt32[] paletteData;
_chrPixelData = InteropEmu.DebugGetChrBank(_chrSelection, 9, false, CdlHighlightType.None, out paletteData);
_chrPixelData = InteropEmu.DebugGetChrBank(_chrSelection, 9, false, CdlHighlightType.None, false, false, out paletteData);
bool isChrRam = InteropEmu.DebugGetMemorySize(DebugMemoryType.ChrRom) == 0;
if(_chrSelection < 2) {

View file

@ -31,6 +31,7 @@
this.tableLayoutPanel3 = new System.Windows.Forms.TableLayoutPanel();
this.grpDisplayOptions = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.chkShowSingleColorTilesInGrayscale = new System.Windows.Forms.CheckBox();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.lblPalette = new System.Windows.Forms.Label();
this.cboPalette = new System.Windows.Forms.ComboBox();
@ -104,7 +105,7 @@
this.grpDisplayOptions.Dock = System.Windows.Forms.DockStyle.Top;
this.grpDisplayOptions.Location = new System.Drawing.Point(269, 300);
this.grpDisplayOptions.Name = "grpDisplayOptions";
this.grpDisplayOptions.Size = new System.Drawing.Size(264, 162);
this.grpDisplayOptions.Size = new System.Drawing.Size(264, 175);
this.grpDisplayOptions.TabIndex = 4;
this.grpDisplayOptions.TabStop = false;
this.grpDisplayOptions.Text = "Display Options";
@ -113,6 +114,7 @@
//
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.chkShowSingleColorTilesInGrayscale, 0, 5);
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.chkLargeSprites, 0, 3);
this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 0, 0);
@ -128,9 +130,20 @@
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
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(258, 143);
this.tableLayoutPanel1.Size = new System.Drawing.Size(258, 156);
this.tableLayoutPanel1.TabIndex = 6;
//
// chkShowSingleColorTilesInGrayscale
//
this.chkShowSingleColorTilesInGrayscale.AutoSize = true;
this.chkShowSingleColorTilesInGrayscale.Location = new System.Drawing.Point(3, 130);
this.chkShowSingleColorTilesInGrayscale.Name = "chkShowSingleColorTilesInGrayscale";
this.chkShowSingleColorTilesInGrayscale.Size = new System.Drawing.Size(241, 17);
this.chkShowSingleColorTilesInGrayscale.TabIndex = 9;
this.chkShowSingleColorTilesInGrayscale.Text = "Show single color tiles using grayscale palette";
this.chkShowSingleColorTilesInGrayscale.UseVisualStyleBackColor = true;
this.chkShowSingleColorTilesInGrayscale.CheckedChanged += new System.EventHandler(this.chkShowSingleColorTilesInGrayscale_CheckedChanged);
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Controls.Add(this.lblPalette);
@ -561,5 +574,6 @@
private ctrlTilePalette ctrlTilePalette;
private System.Windows.Forms.ToolStripMenuItem mnuCopyToClipboard;
private System.Windows.Forms.CheckBox chkAutoPalette;
private System.Windows.Forms.CheckBox chkShowSingleColorTilesInGrayscale;
}
}

View file

@ -22,6 +22,7 @@ namespace Mesen.GUI.Debugger.Controls
private CdlHighlightType _highlightType = CdlHighlightType.None;
private bool _useLargeSprites = false;
private bool _useAutoPalette = false;
private bool _showSingleColorTilesInGrayscale = false;
private Bitmap _tilePreview;
private Bitmap[] _chrBanks = new Bitmap[2];
private HdPackCopyHelper _hdCopyHelper = new HdPackCopyHelper();
@ -58,6 +59,7 @@ namespace Mesen.GUI.Debugger.Controls
this.chkAutoPalette.Checked = ConfigManager.Config.DebugInfo.ChrViewerUseAutoPalette;
this.chkLargeSprites.Checked = ConfigManager.Config.DebugInfo.ChrViewerUseLargeSprites;
this.chkShowSingleColorTilesInGrayscale.Checked = ConfigManager.Config.DebugInfo.ChrViewerShowSingleColorTilesInGrayscale;
}
}
@ -103,7 +105,15 @@ namespace Mesen.GUI.Debugger.Controls
public void GetData()
{
for(int i = 0; i < 2; i++) {
_chrPixelData[i] = InteropEmu.DebugGetChrBank(i + _chrSelection * 2, _selectedPalette + (_useAutoPalette ? 0x80 : 0), _useLargeSprites, _highlightType, out _paletteData[i]);
_chrPixelData[i] = InteropEmu.DebugGetChrBank(
i + _chrSelection * 2,
_selectedPalette,
_useLargeSprites,
_highlightType,
_useAutoPalette,
_showSingleColorTilesInGrayscale,
out _paletteData[i]
);
}
_hdCopyHelper.RefreshData();
}
@ -209,6 +219,17 @@ namespace Mesen.GUI.Debugger.Controls
this.RefreshViewer();
}
private void chkShowSingleColorTilesInGrayscale_CheckedChanged(object sender, EventArgs e)
{
ConfigManager.Config.DebugInfo.ChrViewerShowSingleColorTilesInGrayscale = this.chkShowSingleColorTilesInGrayscale.Checked;
ConfigManager.ApplyChanges();
this._showSingleColorTilesInGrayscale = this.chkShowSingleColorTilesInGrayscale.Checked;
this.GetData();
this.RefreshViewer();
}
private void chkLargeSprites_CheckedChanged(object sender, EventArgs e)
{
ConfigManager.Config.DebugInfo.ChrViewerUseLargeSprites = this.chkLargeSprites.Checked;

View file

@ -424,8 +424,8 @@ namespace Mesen.GUI
}
}
[DllImport(DLLPath, EntryPoint = "DebugGetChrBank")] private static extern void DebugGetChrBankWrapper(UInt32 bankIndex, IntPtr frameBuffer, Byte palette, [MarshalAs(UnmanagedType.I1)]bool largeSprites, CdlHighlightType highlightType, IntPtr paletteBuffer);
public static byte[] DebugGetChrBank(int bankIndex, int palette, bool largeSprites, CdlHighlightType highlightType, out UInt32[] paletteData)
[DllImport(DLLPath, EntryPoint = "DebugGetChrBank")] private static extern void DebugGetChrBankWrapper(UInt32 bankIndex, IntPtr frameBuffer, Byte palette, [MarshalAs(UnmanagedType.I1)]bool largeSprites, CdlHighlightType highlightType, [MarshalAs(UnmanagedType.I1)]bool useAutoPalette, [MarshalAs(UnmanagedType.I1)]bool showSingleColorTilesInGrayscale, IntPtr paletteBuffer);
public static byte[] DebugGetChrBank(int bankIndex, int palette, bool largeSprites, CdlHighlightType highlightType, bool useAutoPalette, bool showSingleColorTilesInGrayscale, out UInt32[] paletteData)
{
byte[] frameData = new byte[128*128*4];
paletteData = new UInt32[16*16];
@ -433,7 +433,7 @@ namespace Mesen.GUI
GCHandle hFrameData = GCHandle.Alloc(frameData, GCHandleType.Pinned);
GCHandle hPaletteData = GCHandle.Alloc(paletteData, GCHandleType.Pinned);
try {
InteropEmu.DebugGetChrBankWrapper((UInt32)bankIndex, hFrameData.AddrOfPinnedObject(), (Byte)palette, largeSprites, highlightType, hPaletteData.AddrOfPinnedObject());
InteropEmu.DebugGetChrBankWrapper((UInt32)bankIndex, hFrameData.AddrOfPinnedObject(), (Byte)palette, largeSprites, highlightType, useAutoPalette, showSingleColorTilesInGrayscale, hPaletteData.AddrOfPinnedObject());
} finally {
hFrameData.Free();
hPaletteData.Free();

View file

@ -74,7 +74,7 @@ extern "C"
DllExport uint32_t __stdcall DebugGetMemorySize(DebugMemoryType type) { return GetDebugger()->GetMemoryDumper()->GetMemorySize(type); }
DllExport uint32_t __stdcall DebugGetMemoryState(DebugMemoryType type, uint8_t *buffer) { return GetDebugger()->GetMemoryDumper()->GetMemoryState(type, buffer); }
DllExport void __stdcall DebugGetNametable(uint32_t nametableIndex, bool useGrayscalePalette, uint32_t *frameBuffer, uint8_t *tileData, uint8_t *attributeData) { GetDebugger()->GetMemoryDumper()->GetNametable(nametableIndex, useGrayscalePalette, frameBuffer, tileData, attributeData); }
DllExport void __stdcall DebugGetChrBank(uint32_t bankIndex, uint32_t *frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType, uint32_t *paletteBuffer) { GetDebugger()->GetMemoryDumper()->GetChrBank(bankIndex, frameBuffer, palette, largeSprites, highlightType, paletteBuffer); }
DllExport void __stdcall DebugGetChrBank(uint32_t bankIndex, uint32_t *frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType, bool useAutoPalette, bool showSingleColorTilesInGrayscale, uint32_t *paletteBuffer) { GetDebugger()->GetMemoryDumper()->GetChrBank(bankIndex, frameBuffer, palette, largeSprites, highlightType, useAutoPalette, showSingleColorTilesInGrayscale, paletteBuffer); }
DllExport void __stdcall DebugGetSprites(uint32_t *frameBuffer) { GetDebugger()->GetMemoryDumper()->GetSprites(frameBuffer); }
DllExport void __stdcall DebugGetPalette(uint32_t *frameBuffer) { GetDebugger()->GetMemoryDumper()->GetPalette(frameBuffer); }