Mesen-X/GUI.NET/Debugger/Controls/ctrlCharacterMappings.cs
2018-06-23 18:29:48 -04:00

139 lines
4.2 KiB
C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using Mesen.GUI.Controls;
using Mesen.GUI.Config;
using System.Collections.Concurrent;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlCharacterMappings : BaseControl
{
private UInt32 _chrSize;
private byte[] _chrPixelData;
private int _chrSelection = 0;
private ctrlCharacterMapping[] _mappings = new ctrlCharacterMapping[16];
private byte[] _chrData = new byte[16*16*16];
public ctrlCharacterMappings()
{
InitializeComponent();
tlpTileMappings.SuspendLayout();
for(int y = 0; y < 8; y++) {
for(int x = 0; x < 2; x++) {
ctrlCharacterMapping mapping = new ctrlCharacterMapping();
tlpTileMappings.Controls.Add(mapping);
tlpTileMappings.SetColumn(mapping, x);
tlpTileMappings.SetRow(mapping, y + 1);
mapping.picTiles.Image = new Bitmap(416, 20);
_mappings[(y << 1) + x] = mapping;
}
}
tlpTileMappings.ResumeLayout();
}
public void GetData()
{
UInt32[] paletteData;
_chrPixelData = InteropEmu.DebugGetChrBank(_chrSelection, 9, false, CdlHighlightType.None, out paletteData);
bool isChrRam = InteropEmu.DebugGetMemorySize(DebugMemoryType.ChrRom) == 0;
if(_chrSelection < 2) {
byte[] chrData = InteropEmu.DebugGetMemoryState(DebugMemoryType.PpuMemory);
Array.Copy(chrData, _chrSelection * 0x1000, _chrData, 0, 0x1000);
} else {
byte[] chrData = InteropEmu.DebugGetMemoryState(isChrRam ? DebugMemoryType.ChrRam : DebugMemoryType.ChrRom);
int startIndex = (_chrSelection - 2) * 0x1000;
if(startIndex >= chrData.Length) {
//Can occur when switching games
startIndex = 0;
}
Array.Copy(chrData, startIndex, _chrData, 0, 0x1000);
}
}
public void RefreshViewer(bool refreshPreview = false)
{
UpdateChrBankDropdown();
GCHandle handle = GCHandle.Alloc(_chrPixelData, GCHandleType.Pinned);
try {
Bitmap source = new Bitmap(128, 128, 4*128, System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
for(int y = 0; y < 16; y++) {
using(Graphics g = Graphics.FromImage(_mappings[y].picTiles.Image)) {
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
g.TranslateTransform(1, 0);
for(int x = 0; x < 16; x++) {
g.FillRectangle(Brushes.DarkGreen, 3 + x * 26, 1, 18, 18);
}
g.ScaleTransform(2, 2);
for(int x = 0; x < 16; x++) {
g.DrawImage(source, new Rectangle(2 + x * 13, 1, 8, 8), x * 8, y * 8, 8, 8, GraphicsUnit.Pixel);
}
}
_mappings[y].picTiles.Invalidate();
_mappings[y].UpdateData(_chrData, y);
}
} finally {
handle.Free();
}
}
public void SetCharacterMappings(ConcurrentDictionary<string, string> charMappings)
{
for(int i = 0; i < 16; i++) {
_mappings[i].SetCharacterMappings(charMappings);
}
}
private void UpdateChrBankDropdown()
{
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");
this.cboChrSelection.Items.Add("PPU: $1000");
for(int i = 0; i < _chrSize / 0x1000; i++) {
this.cboChrSelection.Items.Add("CHR: $" + (i * 0x1000).ToString("X4"));
}
this.cboChrSelection.SelectedIndex = this.cboChrSelection.Items.Count > index && index >= 0 ? index : 0;
this._chrSelection = this.cboChrSelection.SelectedIndex;
}
}
private void cboChrSelection_DropDown(object sender, EventArgs e)
{
UpdateChrBankDropdown();
}
private void cboChrSelection_SelectedIndexChanged(object sender, EventArgs e)
{
this._chrSelection = this.cboChrSelection.SelectedIndex;
this.GetData();
this.RefreshViewer();
}
}
}