From 3a9c8f923616d5340a5e2bad9d283bdef239fb07 Mon Sep 17 00:00:00 2001 From: Souryo Date: Mon, 5 Sep 2016 12:09:14 -0400 Subject: [PATCH] Debugger: Ability to view all of CHR in chr viewer + Added mask option (based on CDL file) --- Core/BaseMapper.cpp | 4 + Core/BaseMapper.h | 4 + Core/Debugger.cpp | 42 +++- Core/Debugger.h | 9 +- .../Controls/ctrlChrViewer.Designer.cs | 203 ++++++++++++++---- GUI.NET/Debugger/Controls/ctrlChrViewer.cs | 47 +++- GUI.NET/InteropEmu.cs | 17 +- InteropDLL/DebugWrapper.cpp | 2 +- 8 files changed, 277 insertions(+), 51 deletions(-) diff --git a/Core/BaseMapper.cpp b/Core/BaseMapper.cpp index 009b943c..d2e91a44 100644 --- a/Core/BaseMapper.cpp +++ b/Core/BaseMapper.cpp @@ -811,6 +811,10 @@ CartridgeState BaseMapper::GetState() { CartridgeState state; + state.PrgRomSize = _prgSize; + state.ChrRomSize = _chrRomSize; + state.ChrRamSize = _chrRamSize; + state.PrgPageCount = GetPRGPageCount(); state.PrgPageSize = InternalGetPrgPageSize(); state.ChrPageCount = GetCHRPageCount(); diff --git a/Core/BaseMapper.h b/Core/BaseMapper.h index f2190ce7..5fa6f07a 100644 --- a/Core/BaseMapper.h +++ b/Core/BaseMapper.h @@ -40,6 +40,10 @@ enum ChrSpecialPage struct CartridgeState { + uint32_t PrgRomSize; + uint32_t ChrRomSize; + uint32_t ChrRamSize; + uint32_t PrgPageCount; uint32_t PrgPageSize; uint32_t PrgSelectedPages[4]; diff --git a/Core/Debugger.cpp b/Core/Debugger.cpp index bde1eea8..f64325e6 100644 --- a/Core/Debugger.cpp +++ b/Core/Debugger.cpp @@ -653,18 +653,41 @@ void Debugger::GetNametable(int nametableIndex, uint32_t* frameBuffer, uint8_t* delete[] screenBuffer; } -void Debugger::GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites) +void Debugger::GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType) { uint16_t *screenBuffer = new uint16_t[128 * 128]; - uint16_t bgAddr = bankIndex == 0 ? 0x0000 : 0x1000; + uint8_t chrBuffer[0x1000]; + bool chrIsDrawn[0x1000]; + bool tileUsed[0x4000]; + if(bankIndex == 0 || bankIndex == 1) { + uint16_t baseAddr = bankIndex == 0 ? 0x0000 : 0x1000; + for(int i = 0; i < 0x1000; i++) { + chrBuffer[i] = _mapper->ReadVRAM(baseAddr + i); + chrIsDrawn[i] = _codeDataLogger->IsDrawn(_mapper->ToAbsoluteChrAddress(baseAddr + i)); + } + } else { + int bank = bankIndex - 2; + uint32_t baseAddr = bank * 0x1000; + bool useChrRam = _mapper->GetChrSize(false) == 0; + uint32_t chrSize = _mapper->GetChrSize(useChrRam); + vector chrData(chrSize, 0); + _mapper->CopyMemory(useChrRam ? DebugMemoryType::ChrRam : DebugMemoryType::ChrRom, chrData.data()); + + for(int i = 0; i < 0x1000; i++) { + chrBuffer[i] = chrData[baseAddr + i]; + chrIsDrawn[i] = _codeDataLogger->IsDrawn(baseAddr + i); + } + } + for(uint8_t y = 0; y < 16; y++) { for(uint8_t x = 0; x < 16; x++) { uint8_t tileIndex = y * 16 + x; uint8_t paletteBaseAddr = palette << 2; - uint16_t tileAddr = bgAddr + (tileIndex << 4); + uint16_t tileAddr = tileIndex << 4; for(uint8_t i = 0; i < 8; i++) { - uint8_t lowByte = _mapper->ReadVRAM(tileAddr + i); - uint8_t highByte = _mapper->ReadVRAM(tileAddr + i + 8); + 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); @@ -679,6 +702,7 @@ void Debugger::GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, } screenBuffer[position] = color == 0 ? _ppu->ReadPaletteRAM(0) : _ppu->ReadPaletteRAM(paletteBaseAddr + color); + tileUsed[position] = isDrawn; } } } @@ -686,6 +710,14 @@ void Debugger::GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, VideoDecoder::GetInstance()->DebugDecodeFrame(screenBuffer, frameBuffer, 128*128); + if(highlightType != CdlHighlightType::None) { + for(int i = 0; i < 0x4000; i++) { + if(tileUsed[i] == (highlightType != CdlHighlightType::HighlightUsed)) { + frameBuffer[i] &= 0x4FFFFFFF; + } + } + } + delete[] screenBuffer; } diff --git a/Core/Debugger.h b/Core/Debugger.h index 667d395a..c597ca69 100644 --- a/Core/Debugger.h +++ b/Core/Debugger.h @@ -38,6 +38,13 @@ enum class DebuggerFlags PpuPartialDraw = 1 }; +enum class CdlHighlightType +{ + None = 0, + HighlightUsed = 1, + HighlightUnused = 2, +}; + class Debugger { private: @@ -110,7 +117,7 @@ public: uint32_t GetMemoryState(DebugMemoryType type, uint8_t *buffer); void GetNametable(int nametableIndex, uint32_t* frameBuffer, uint8_t* tileData, uint8_t* paletteData); - void GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites); + void GetChrBank(int bankIndex, uint32_t* frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType); void GetSprites(uint32_t* frameBuffer); void GetPalette(uint32_t* frameBuffer); diff --git a/GUI.NET/Debugger/Controls/ctrlChrViewer.Designer.cs b/GUI.NET/Debugger/Controls/ctrlChrViewer.Designer.cs index 54dbf2ba..ac9f100b 100644 --- a/GUI.NET/Debugger/Controls/ctrlChrViewer.Designer.cs +++ b/GUI.NET/Debugger/Controls/ctrlChrViewer.Designer.cs @@ -37,49 +37,56 @@ this.txtTileIndex = new System.Windows.Forms.TextBox(); this.picTile = new System.Windows.Forms.PictureBox(); this.picChrBank1 = new System.Windows.Forms.PictureBox(); + this.picChrBank2 = new System.Windows.Forms.PictureBox(); + this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel(); this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel(); this.lblPalette = new System.Windows.Forms.Label(); this.cboPalette = new System.Windows.Forms.ComboBox(); - this.picChrBank2 = new System.Windows.Forms.PictureBox(); this.chkLargeSprites = new System.Windows.Forms.CheckBox(); + this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel(); + this.lblChrSelection = new System.Windows.Forms.Label(); + this.cboChrSelection = new System.Windows.Forms.ComboBox(); + this.flowLayoutPanel3 = new System.Windows.Forms.FlowLayoutPanel(); + this.lblMask = new System.Windows.Forms.Label(); + this.cboHighlightType = new System.Windows.Forms.ComboBox(); + this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel(); this.tableLayoutPanel3.SuspendLayout(); this.grpTileInfo.SuspendLayout(); this.tableLayoutPanel4.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picTile)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.picChrBank1)).BeginInit(); - this.flowLayoutPanel1.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.picChrBank2)).BeginInit(); + this.tableLayoutPanel1.SuspendLayout(); + this.flowLayoutPanel1.SuspendLayout(); + this.flowLayoutPanel2.SuspendLayout(); + this.flowLayoutPanel3.SuspendLayout(); + this.tableLayoutPanel2.SuspendLayout(); this.SuspendLayout(); // // tableLayoutPanel3 // - this.tableLayoutPanel3.ColumnCount = 3; + this.tableLayoutPanel3.ColumnCount = 2; this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle()); - this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel3.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); + this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel1, 1, 0); this.tableLayoutPanel3.Controls.Add(this.grpTileInfo, 1, 1); - this.tableLayoutPanel3.Controls.Add(this.picChrBank1, 0, 0); - this.tableLayoutPanel3.Controls.Add(this.flowLayoutPanel1, 1, 0); - this.tableLayoutPanel3.Controls.Add(this.picChrBank2, 0, 2); + this.tableLayoutPanel3.Controls.Add(this.tableLayoutPanel2, 0, 0); this.tableLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; this.tableLayoutPanel3.Location = new System.Drawing.Point(0, 0); this.tableLayoutPanel3.Name = "tableLayoutPanel3"; - this.tableLayoutPanel3.RowCount = 3; + this.tableLayoutPanel3.RowCount = 2; this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle()); - this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); - this.tableLayoutPanel3.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel3.Size = new System.Drawing.Size(446, 522); + this.tableLayoutPanel3.Size = new System.Drawing.Size(506, 525); this.tableLayoutPanel3.TabIndex = 3; // // grpTileInfo // this.grpTileInfo.Controls.Add(this.tableLayoutPanel4); - this.grpTileInfo.Dock = System.Windows.Forms.DockStyle.Fill; - this.grpTileInfo.Location = new System.Drawing.Point(263, 56); + this.grpTileInfo.Location = new System.Drawing.Point(267, 109); this.grpTileInfo.Name = "grpTileInfo"; - this.tableLayoutPanel3.SetRowSpan(this.grpTileInfo, 2); - this.grpTileInfo.Size = new System.Drawing.Size(180, 463); + this.grpTileInfo.Size = new System.Drawing.Size(180, 142); this.grpTileInfo.TabIndex = 4; this.grpTileInfo.TabStop = false; this.grpTileInfo.Text = "Tile Info"; @@ -106,7 +113,7 @@ this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.tableLayoutPanel4.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); - this.tableLayoutPanel4.Size = new System.Drawing.Size(174, 444); + this.tableLayoutPanel4.Size = new System.Drawing.Size(174, 123); this.tableLayoutPanel4.TabIndex = 0; // // txtTileAddress @@ -170,21 +177,51 @@ this.picChrBank1.Location = new System.Drawing.Point(1, 1); this.picChrBank1.Margin = new System.Windows.Forms.Padding(1); this.picChrBank1.Name = "picChrBank1"; - this.tableLayoutPanel3.SetRowSpan(this.picChrBank1, 2); - this.picChrBank1.Size = new System.Drawing.Size(258, 258); + this.picChrBank1.Size = new System.Drawing.Size(256, 257); this.picChrBank1.TabIndex = 0; this.picChrBank1.TabStop = false; this.picChrBank1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picChrBank_MouseMove); // + // picChrBank2 + // + this.picChrBank2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; + this.picChrBank2.Location = new System.Drawing.Point(1, 260); + this.picChrBank2.Margin = new System.Windows.Forms.Padding(1); + this.picChrBank2.Name = "picChrBank2"; + this.picChrBank2.Size = new System.Drawing.Size(256, 257); + this.picChrBank2.TabIndex = 1; + this.picChrBank2.TabStop = false; + this.picChrBank2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picChrBank_MouseMove); + // + // tableLayoutPanel1 + // + this.tableLayoutPanel1.ColumnCount = 1; + this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 0, 1); + this.tableLayoutPanel1.Controls.Add(this.chkLargeSprites, 0, 3); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 0, 0); + this.tableLayoutPanel1.Controls.Add(this.flowLayoutPanel3, 0, 2); + this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.tableLayoutPanel1.Location = new System.Drawing.Point(267, 3); + this.tableLayoutPanel1.Name = "tableLayoutPanel1"; + this.tableLayoutPanel1.RowCount = 5; + 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()); + 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(236, 100); + this.tableLayoutPanel1.TabIndex = 6; + // // flowLayoutPanel1 // this.flowLayoutPanel1.Controls.Add(this.lblPalette); this.flowLayoutPanel1.Controls.Add(this.cboPalette); - this.flowLayoutPanel1.Controls.Add(this.chkLargeSprites); - this.flowLayoutPanel1.Location = new System.Drawing.Point(260, 0); + this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 27); this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0); this.flowLayoutPanel1.Name = "flowLayoutPanel1"; - this.flowLayoutPanel1.Size = new System.Drawing.Size(180, 53); + this.flowLayoutPanel1.Size = new System.Drawing.Size(236, 27); this.flowLayoutPanel1.TabIndex = 5; // // lblPalette @@ -216,21 +253,10 @@ this.cboPalette.TabIndex = 1; this.cboPalette.SelectedIndexChanged += new System.EventHandler(this.cboPalette_SelectedIndexChanged); // - // picChrBank2 - // - this.picChrBank2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; - this.picChrBank2.Location = new System.Drawing.Point(1, 261); - this.picChrBank2.Margin = new System.Windows.Forms.Padding(1); - this.picChrBank2.Name = "picChrBank2"; - this.picChrBank2.Size = new System.Drawing.Size(258, 258); - this.picChrBank2.TabIndex = 1; - this.picChrBank2.TabStop = false; - this.picChrBank2.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picChrBank_MouseMove); - // // chkLargeSprites // this.chkLargeSprites.AutoSize = true; - this.chkLargeSprites.Location = new System.Drawing.Point(3, 30); + this.chkLargeSprites.Location = new System.Drawing.Point(3, 84); this.chkLargeSprites.Name = "chkLargeSprites"; this.chkLargeSprites.Size = new System.Drawing.Size(133, 17); this.chkLargeSprites.TabIndex = 2; @@ -238,22 +264,111 @@ this.chkLargeSprites.UseVisualStyleBackColor = true; this.chkLargeSprites.Click += new System.EventHandler(this.chkLargeSprites_Click); // + // flowLayoutPanel2 + // + this.flowLayoutPanel2.Controls.Add(this.lblChrSelection); + this.flowLayoutPanel2.Controls.Add(this.cboChrSelection); + this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel2.Location = new System.Drawing.Point(0, 0); + this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutPanel2.Name = "flowLayoutPanel2"; + this.flowLayoutPanel2.Size = new System.Drawing.Size(236, 27); + this.flowLayoutPanel2.TabIndex = 6; + // + // lblChrSelection + // + this.lblChrSelection.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblChrSelection.AutoSize = true; + this.lblChrSelection.Location = new System.Drawing.Point(3, 7); + this.lblChrSelection.Name = "lblChrSelection"; + this.lblChrSelection.Size = new System.Drawing.Size(73, 13); + this.lblChrSelection.TabIndex = 0; + this.lblChrSelection.Text = "Chr Selection:"; + // + // cboChrSelection + // + this.cboChrSelection.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboChrSelection.FormattingEnabled = true; + this.cboChrSelection.Location = new System.Drawing.Point(82, 3); + this.cboChrSelection.Name = "cboChrSelection"; + this.cboChrSelection.Size = new System.Drawing.Size(150, 21); + this.cboChrSelection.TabIndex = 1; + this.cboChrSelection.DropDown += new System.EventHandler(this.cboChrSelection_DropDown); + this.cboChrSelection.SelectionChangeCommitted += new System.EventHandler(this.cboChrSelection_SelectionChangeCommitted); + // + // flowLayoutPanel3 + // + this.flowLayoutPanel3.Controls.Add(this.lblMask); + this.flowLayoutPanel3.Controls.Add(this.cboHighlightType); + this.flowLayoutPanel3.Dock = System.Windows.Forms.DockStyle.Fill; + this.flowLayoutPanel3.Location = new System.Drawing.Point(0, 54); + this.flowLayoutPanel3.Margin = new System.Windows.Forms.Padding(0); + this.flowLayoutPanel3.Name = "flowLayoutPanel3"; + this.flowLayoutPanel3.Size = new System.Drawing.Size(236, 27); + this.flowLayoutPanel3.TabIndex = 7; + // + // lblMask + // + this.lblMask.Anchor = System.Windows.Forms.AnchorStyles.Left; + this.lblMask.AutoSize = true; + this.lblMask.Location = new System.Drawing.Point(3, 7); + this.lblMask.Name = "lblMask"; + this.lblMask.Size = new System.Drawing.Size(36, 13); + this.lblMask.TabIndex = 0; + this.lblMask.Text = "Mask:"; + // + // cboHighlightType + // + this.cboHighlightType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList; + this.cboHighlightType.FormattingEnabled = true; + this.cboHighlightType.Items.AddRange(new object[] { + "None", + "Unused Tiles", + "Used Tiles"}); + this.cboHighlightType.Location = new System.Drawing.Point(45, 3); + this.cboHighlightType.Name = "cboHighlightType"; + this.cboHighlightType.Size = new System.Drawing.Size(92, 21); + this.cboHighlightType.TabIndex = 1; + this.cboHighlightType.SelectedIndexChanged += new System.EventHandler(this.cboHighlightType_SelectedIndexChanged); + // + // tableLayoutPanel2 + // + this.tableLayoutPanel2.ColumnCount = 1; + this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel2.Controls.Add(this.picChrBank1, 0, 0); + this.tableLayoutPanel2.Controls.Add(this.picChrBank2, 0, 1); + this.tableLayoutPanel2.Location = new System.Drawing.Point(3, 3); + this.tableLayoutPanel2.Name = "tableLayoutPanel2"; + this.tableLayoutPanel2.RowCount = 2; + this.tableLayoutPanel3.SetRowSpan(this.tableLayoutPanel2, 2); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F)); + this.tableLayoutPanel2.Size = new System.Drawing.Size(258, 519); + this.tableLayoutPanel2.TabIndex = 7; + // // ctrlChrViewer // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.Controls.Add(this.tableLayoutPanel3); this.Name = "ctrlChrViewer"; - this.Size = new System.Drawing.Size(446, 522); + this.Size = new System.Drawing.Size(506, 525); this.tableLayoutPanel3.ResumeLayout(false); this.grpTileInfo.ResumeLayout(false); this.tableLayoutPanel4.ResumeLayout(false); this.tableLayoutPanel4.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.picTile)).EndInit(); ((System.ComponentModel.ISupportInitialize)(this.picChrBank1)).EndInit(); + ((System.ComponentModel.ISupportInitialize)(this.picChrBank2)).EndInit(); + this.tableLayoutPanel1.ResumeLayout(false); + this.tableLayoutPanel1.PerformLayout(); this.flowLayoutPanel1.ResumeLayout(false); this.flowLayoutPanel1.PerformLayout(); - ((System.ComponentModel.ISupportInitialize)(this.picChrBank2)).EndInit(); + this.flowLayoutPanel2.ResumeLayout(false); + this.flowLayoutPanel2.PerformLayout(); + this.flowLayoutPanel3.ResumeLayout(false); + this.flowLayoutPanel3.PerformLayout(); + this.tableLayoutPanel2.ResumeLayout(false); this.ResumeLayout(false); } @@ -261,8 +376,18 @@ #endregion private System.Windows.Forms.TableLayoutPanel tableLayoutPanel3; - private System.Windows.Forms.PictureBox picChrBank2; private System.Windows.Forms.PictureBox picChrBank1; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; + private System.Windows.Forms.Label lblPalette; + private System.Windows.Forms.ComboBox cboPalette; + private System.Windows.Forms.CheckBox chkLargeSprites; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2; + private System.Windows.Forms.Label lblChrSelection; + private System.Windows.Forms.ComboBox cboChrSelection; + private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel3; + private System.Windows.Forms.Label lblMask; + private System.Windows.Forms.ComboBox cboHighlightType; private System.Windows.Forms.GroupBox grpTileInfo; private System.Windows.Forms.TableLayoutPanel tableLayoutPanel4; private System.Windows.Forms.TextBox txtTileAddress; @@ -271,9 +396,7 @@ private System.Windows.Forms.Label label6; private System.Windows.Forms.TextBox txtTileIndex; private System.Windows.Forms.PictureBox picTile; - private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1; - private System.Windows.Forms.Label lblPalette; - private System.Windows.Forms.ComboBox cboPalette; - private System.Windows.Forms.CheckBox chkLargeSprites; + private System.Windows.Forms.PictureBox picChrBank2; + private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2; } } diff --git a/GUI.NET/Debugger/Controls/ctrlChrViewer.cs b/GUI.NET/Debugger/Controls/ctrlChrViewer.cs index cc0bd4c9..6c3d6adf 100644 --- a/GUI.NET/Debugger/Controls/ctrlChrViewer.cs +++ b/GUI.NET/Debugger/Controls/ctrlChrViewer.cs @@ -21,6 +21,8 @@ namespace Mesen.GUI.Debugger.Controls { base.OnLoad(e); if(!this.DesignMode) { + this.UpdateDropdown(); + this.cboHighlightType.SelectedIndex = 0; this.cboPalette.SelectedIndex = 0; } } @@ -29,8 +31,10 @@ namespace Mesen.GUI.Debugger.Controls { PictureBox[] chrBanks = new PictureBox[] { this.picChrBank1, this.picChrBank2 }; + UpdateDropdown(); + for(int i = 0; i < 2; i++) { - byte[] pixelData = InteropEmu.DebugGetChrBank(i, this.cboPalette.SelectedIndex, this.chkLargeSprites.Checked); + byte[] pixelData = InteropEmu.DebugGetChrBank(i + this.cboChrSelection.SelectedIndex * 2, this.cboPalette.SelectedIndex, this.chkLargeSprites.Checked, (CdlHighlightType)this.cboHighlightType.SelectedIndex); GCHandle handle = GCHandle.Alloc(pixelData, GCHandleType.Pinned); try { @@ -41,6 +45,7 @@ namespace Mesen.GUI.Debugger.Controls g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None; g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half; + g.Clear(Color.Black); g.DrawImage(source, new Rectangle(0, 0, 256, 256), new Rectangle(0, 0, 128, 128), GraphicsUnit.Pixel); } chrBanks[i].Image = target; @@ -50,6 +55,33 @@ namespace Mesen.GUI.Debugger.Controls } } + private UInt32 _chrSize; + private void UpdateDropdown() + { + DebugState state = new DebugState(); + InteropEmu.DebugGetState(ref state); + + UInt32 chrSize = state.Cartridge.ChrRomSize == 0 ? state.Cartridge.ChrRamSize : state.Cartridge.ChrRomSize; + + if(chrSize != _chrSize) { + _chrSize = chrSize; + + int index = this.cboChrSelection.SelectedIndex; + this.cboChrSelection.Items.Clear(); + this.cboChrSelection.Items.Add("PPU: $0000 - $1FFF"); + for(int i = 0; i < _chrSize / 0x2000; i++) { + this.cboChrSelection.Items.Add("CHR: $" + (i * 0x2000).ToString("X4") + " - $" + (i * 0x2000 + 0x1FFF).ToString("X4")); + } + + this.cboChrSelection.SelectedIndex = this.cboChrSelection.Items.Count > index && index >= 0 ? index : 0; + } + } + + private void cboChrSelection_DropDown(object sender, EventArgs e) + { + UpdateDropdown(); + } + private void cboPalette_SelectedIndexChanged(object sender, EventArgs e) { this.RefreshViewer(); @@ -60,11 +92,24 @@ namespace Mesen.GUI.Debugger.Controls this.RefreshViewer(); } + private void cboHighlightType_SelectedIndexChanged(object sender, EventArgs e) + { + this.RefreshViewer(); + } + + private void cboChrSelection_SelectionChangeCommitted(object sender, EventArgs e) + { + this.RefreshViewer(); + } + private void picChrBank_MouseMove(object sender, MouseEventArgs e) { List chrBanks = new List() { this.picChrBank1, this.picChrBank2 }; int bankIndex = chrBanks.IndexOf((PictureBox)sender); int baseAddress = bankIndex == 0 ? 0x0000 : 0x1000; + if(this.cboChrSelection.SelectedIndex > 1) { + baseAddress += (this.cboChrSelection.SelectedIndex - 1) * 0x2000; + } int tileX = Math.Min(e.X / 16, 15); int tileY = Math.Min(e.Y / 16, 15); diff --git a/GUI.NET/InteropEmu.cs b/GUI.NET/InteropEmu.cs index 40f92a71..1659e33c 100644 --- a/GUI.NET/InteropEmu.cs +++ b/GUI.NET/InteropEmu.cs @@ -241,14 +241,14 @@ namespace Mesen.GUI } } - [DllImport(DLLPath, EntryPoint="DebugGetChrBank")] private static extern void DebugGetChrBankWrapper(UInt32 bankIndex, IntPtr frameBuffer, Byte palette, [MarshalAs(UnmanagedType.I1)]bool largeSprites); - public static byte[] DebugGetChrBank(int bankIndex, int palette, bool largeSprites) + [DllImport(DLLPath, EntryPoint="DebugGetChrBank")] private static extern void DebugGetChrBankWrapper(UInt32 bankIndex, IntPtr frameBuffer, Byte palette, [MarshalAs(UnmanagedType.I1)]bool largeSprites, CdlHighlightType highlightType); + public static byte[] DebugGetChrBank(int bankIndex, int palette, bool largeSprites, CdlHighlightType highlightType) { byte[] frameData = new byte[128*128*4]; GCHandle hFrameData = GCHandle.Alloc(frameData, GCHandleType.Pinned); try { - InteropEmu.DebugGetChrBankWrapper((UInt32)bankIndex, hFrameData.AddrOfPinnedObject(), (Byte)palette, largeSprites); + InteropEmu.DebugGetChrBankWrapper((UInt32)bankIndex, hFrameData.AddrOfPinnedObject(), (Byte)palette, largeSprites, highlightType); } finally { hFrameData.Free(); } @@ -538,6 +538,13 @@ namespace Mesen.GUI public float ChrDrawnRatio; } + public enum CdlHighlightType + { + None = 0, + HighlightUsed = 1, + HighlightUnused = 2 + } + public struct DebugState { public CPUState CPU; @@ -547,6 +554,10 @@ namespace Mesen.GUI public struct CartridgeState { + public UInt32 PrgRomSize; + public UInt32 ChrRomSize; + public UInt32 ChrRamSize; + public UInt32 PrgPageCount; public UInt32 PrgPageSize; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)] diff --git a/InteropDLL/DebugWrapper.cpp b/InteropDLL/DebugWrapper.cpp index 500b4314..a38917e0 100644 --- a/InteropDLL/DebugWrapper.cpp +++ b/InteropDLL/DebugWrapper.cpp @@ -46,7 +46,7 @@ extern "C" DllExport uint32_t __stdcall DebugGetMemoryState(uint32_t type, uint8_t *buffer) { return GetDebugger()->GetMemoryState((DebugMemoryType)type, buffer); } DllExport void __stdcall DebugGetNametable(uint32_t nametableIndex, uint32_t *frameBuffer, uint8_t *tileData, uint8_t *attributeData) { GetDebugger()->GetNametable(nametableIndex, frameBuffer, tileData, attributeData); } - DllExport void __stdcall DebugGetChrBank(uint32_t bankIndex, uint32_t *frameBuffer, uint8_t palette, bool largeSprites) { GetDebugger()->GetChrBank(bankIndex, frameBuffer, palette, largeSprites); } + DllExport void __stdcall DebugGetChrBank(uint32_t bankIndex, uint32_t *frameBuffer, uint8_t palette, bool largeSprites, CdlHighlightType highlightType) { GetDebugger()->GetChrBank(bankIndex, frameBuffer, palette, largeSprites, highlightType); } DllExport void __stdcall DebugGetSprites(uint32_t *frameBuffer) { GetDebugger()->GetSprites(frameBuffer); } DllExport void __stdcall DebugGetPalette(uint32_t *frameBuffer) { GetDebugger()->GetPalette(frameBuffer); }