Debugger: Added tile viewer tool
This commit is contained in:
parent
e227f69662
commit
113d440b3d
19 changed files with 1263 additions and 140 deletions
|
@ -168,4 +168,25 @@ struct GetTilemapOptions
|
|||
|
||||
bool ShowTileGrid;
|
||||
bool ShowScrollOverlay;
|
||||
};
|
||||
|
||||
enum TileFormat
|
||||
{
|
||||
Bpp2,
|
||||
Bpp4,
|
||||
Bpp8,
|
||||
DirectColor,
|
||||
Mode7,
|
||||
Mode7DirectColor,
|
||||
};
|
||||
|
||||
struct GetTileViewOptions
|
||||
{
|
||||
TileFormat Format;
|
||||
int32_t Width;
|
||||
int32_t Palette;
|
||||
SnesMemoryType MemoryType;
|
||||
int32_t AddressOffset;
|
||||
|
||||
bool ShowTileGrid;
|
||||
};
|
|
@ -38,7 +38,7 @@ Debugger::Debugger(shared_ptr<Console> console)
|
|||
_ppuTools.reset(new PpuTools(_console.get(), _ppu.get()));
|
||||
_eventManager.reset(new EventManager(this, _cpu.get(), _ppu.get()));
|
||||
|
||||
_cpuStepCount = 0;
|
||||
_cpuStepCount = -1;
|
||||
_executionStopped = false;
|
||||
_breakRequestCount = 0;
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
#include "Ppu.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "Console.h"
|
||||
#include "BaseCartridge.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "NotificationManager.h"
|
||||
|
||||
PpuTools::PpuTools(Console *console, Ppu *ppu)
|
||||
|
@ -11,27 +13,26 @@ PpuTools::PpuTools(Console *console, Ppu *ppu)
|
|||
_ppu = ppu;
|
||||
}
|
||||
|
||||
uint16_t PpuTools::GetTilePixelColor(const uint8_t bpp, const uint16_t pixelStart, const uint8_t shift)
|
||||
uint8_t PpuTools::GetTilePixelColor(const uint8_t* ram, const uint32_t ramMask, const uint8_t bpp, const uint32_t pixelStart, const uint8_t shift)
|
||||
{
|
||||
uint8_t *vram = _ppu->GetVideoRam();
|
||||
uint16_t color;
|
||||
uint8_t color;
|
||||
if(bpp == 2) {
|
||||
color = (((vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
||||
color |= (((vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
||||
color = (((ram[(pixelStart + 0) & ramMask] >> shift) & 0x01) << 0);
|
||||
color |= (((ram[(pixelStart + 1) & ramMask] >> shift) & 0x01) << 1);
|
||||
} else if(bpp == 4) {
|
||||
color = (((vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
||||
color |= (((vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
||||
color |= (((vram[pixelStart + 16] >> shift) & 0x01) << 2);
|
||||
color |= (((vram[pixelStart + 17] >> shift) & 0x01) << 3);
|
||||
color = (((ram[(pixelStart + 0) & ramMask] >> shift) & 0x01) << 0);
|
||||
color |= (((ram[(pixelStart + 1) & ramMask] >> shift) & 0x01) << 1);
|
||||
color |= (((ram[(pixelStart + 16) & ramMask] >> shift) & 0x01) << 2);
|
||||
color |= (((ram[(pixelStart + 17) & ramMask] >> shift) & 0x01) << 3);
|
||||
} else if(bpp == 8) {
|
||||
color = (((vram[pixelStart + 0] >> shift) & 0x01) << 0);
|
||||
color |= (((vram[pixelStart + 1] >> shift) & 0x01) << 1);
|
||||
color |= (((vram[pixelStart + 16] >> shift) & 0x01) << 2);
|
||||
color |= (((vram[pixelStart + 17] >> shift) & 0x01) << 3);
|
||||
color |= (((vram[pixelStart + 32] >> shift) & 0x01) << 4);
|
||||
color |= (((vram[pixelStart + 33] >> shift) & 0x01) << 5);
|
||||
color |= (((vram[pixelStart + 48] >> shift) & 0x01) << 6);
|
||||
color |= (((vram[pixelStart + 49] >> shift) & 0x01) << 7);
|
||||
color = (((ram[(pixelStart + 0) & ramMask] >> shift) & 0x01) << 0);
|
||||
color |= (((ram[(pixelStart + 1) & ramMask] >> shift) & 0x01) << 1);
|
||||
color |= (((ram[(pixelStart + 16) & ramMask] >> shift) & 0x01) << 2);
|
||||
color |= (((ram[(pixelStart + 17) & ramMask] >> shift) & 0x01) << 3);
|
||||
color |= (((ram[(pixelStart + 32) & ramMask] >> shift) & 0x01) << 4);
|
||||
color |= (((ram[(pixelStart + 33) & ramMask] >> shift) & 0x01) << 5);
|
||||
color |= (((ram[(pixelStart + 48) & ramMask] >> shift) & 0x01) << 6);
|
||||
color |= (((ram[(pixelStart + 49) & ramMask] >> shift) & 0x01) << 7);
|
||||
} else {
|
||||
throw std::runtime_error("unsupported bpp");
|
||||
}
|
||||
|
@ -57,6 +58,137 @@ void PpuTools::BlendColors(uint8_t output[4], uint8_t input[4])
|
|||
output[3] = 0xFF;
|
||||
}
|
||||
|
||||
uint32_t PpuTools::GetRgbPixelColor(uint8_t colorIndex, uint8_t palette, uint8_t bpp, bool directColorMode, uint16_t basePaletteOffset)
|
||||
{
|
||||
uint16_t paletteColor;
|
||||
if(bpp == 8 && directColorMode) {
|
||||
paletteColor = (
|
||||
(((colorIndex & 0x07) | (palette & 0x01)) << 1) |
|
||||
(((colorIndex & 0x38) | ((palette & 0x02) << 1)) << 3) |
|
||||
(((colorIndex & 0xC0) | ((palette & 0x04) << 3)) << 7)
|
||||
);
|
||||
} else {
|
||||
uint8_t* cgram = _ppu->GetCgRam();
|
||||
uint16_t paletteRamOffset = basePaletteOffset + (palette * (1 << bpp) + colorIndex) * 2;
|
||||
paletteColor = cgram[paletteRamOffset] | (cgram[paletteRamOffset + 1] << 8);
|
||||
}
|
||||
return ToArgb(paletteColor);
|
||||
}
|
||||
|
||||
void PpuTools::GetTileView(GetTileViewOptions options, uint32_t *outBuffer)
|
||||
{
|
||||
uint8_t* ram;
|
||||
uint32_t ramMask;
|
||||
uint8_t bpp;
|
||||
|
||||
bool directColor = false;
|
||||
switch(options.Format) {
|
||||
case TileFormat::Bpp2: bpp = 2; break;
|
||||
case TileFormat::Bpp4: bpp = 4; break;
|
||||
|
||||
case TileFormat::DirectColor:
|
||||
directColor = true;
|
||||
bpp = 8;
|
||||
break;
|
||||
|
||||
case TileFormat::Mode7:
|
||||
bpp = 16;
|
||||
break;
|
||||
|
||||
case TileFormat::Mode7DirectColor:
|
||||
directColor = true;
|
||||
bpp = 16;
|
||||
break;
|
||||
|
||||
default: bpp = 8; break;
|
||||
}
|
||||
|
||||
switch(options.MemoryType) {
|
||||
default:
|
||||
case SnesMemoryType::VideoRam:
|
||||
ramMask = Ppu::VideoRamSize - 1;
|
||||
ram = _ppu->GetVideoRam();
|
||||
break;
|
||||
|
||||
case SnesMemoryType::PrgRom:
|
||||
ramMask = _console->GetCartridge()->DebugGetPrgRomSize() - 1;
|
||||
ram = _console->GetCartridge()->DebugGetPrgRom();
|
||||
break;
|
||||
|
||||
case SnesMemoryType::WorkRam:
|
||||
ramMask = MemoryManager::WorkRamSize - 1;
|
||||
ram = _console->GetMemoryManager()->DebugGetWorkRam();
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t* cgram = _ppu->GetCgRam();
|
||||
int bytesPerTile = 64 * bpp / 8;
|
||||
int tileCount = 0x10000 / bytesPerTile;
|
||||
|
||||
uint16_t bgColor = (cgram[1] << 8) | cgram[0];
|
||||
for(int i = 0; i < 512 * 512; i++) {
|
||||
outBuffer[i] = ToArgb(bgColor);
|
||||
}
|
||||
|
||||
int rowCount = tileCount / options.Width;
|
||||
|
||||
if(options.Format == TileFormat::Mode7 || options.Format == TileFormat::Mode7DirectColor) {
|
||||
for(int row = 0; row < rowCount; row++) {
|
||||
uint32_t baseOffset = row * bytesPerTile * options.Width + options.AddressOffset;
|
||||
|
||||
for(int column = 0; column < options.Width; column++) {
|
||||
uint32_t addr = baseOffset + bytesPerTile * column;
|
||||
|
||||
for(int y = 0; y < 8; y++) {
|
||||
uint32_t pixelStart = addr + y * 16;
|
||||
for(int x = 0; x < 8; x++) {
|
||||
uint8_t color = ram[(pixelStart + x * 2 + 1) & ramMask];
|
||||
|
||||
if(color != 0) {
|
||||
uint32_t rgbColor;
|
||||
if(directColor) {
|
||||
rgbColor = ToArgb(((color & 0x07) << 2) | ((color & 0x38) << 4) | ((color & 0xC0) << 7));
|
||||
} else {
|
||||
rgbColor = GetRgbPixelColor(color, 0, 8, false, 0);
|
||||
}
|
||||
outBuffer[((row * 8) + y) * (options.Width * 8) + column * 8 + x] = rgbColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(int row = 0; row < rowCount; row++) {
|
||||
uint32_t baseOffset = row * bytesPerTile * options.Width + options.AddressOffset;
|
||||
|
||||
for(int column = 0; column < options.Width; column++) {
|
||||
uint32_t addr = baseOffset + bytesPerTile * column;
|
||||
|
||||
for(int y = 0; y < 8; y++) {
|
||||
uint32_t pixelStart = addr + y * 2;
|
||||
for(int x = 0; x < 8; x++) {
|
||||
uint8_t color = GetTilePixelColor(ram, ramMask, bpp, pixelStart, 7 - x);
|
||||
if(color != 0) {
|
||||
outBuffer[((row * 8) + y) * (options.Width * 8) + column * 8 + x] = GetRgbPixelColor(color, options.Palette, bpp, directColor, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(options.ShowTileGrid) {
|
||||
constexpr uint32_t gridColor = 0xA0AAAAFF;
|
||||
for(int j = 0; j < rowCount * 8; j++) {
|
||||
for(int i = 0; i < options.Width * 8; i++) {
|
||||
if((i & 0x07) == 0x07 || (j & 0x07) == 0x07) {
|
||||
BlendColors((uint8_t*)&outBuffer[j*options.Width*8+i], (uint8_t*)&gridColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PpuTools::GetTilemap(GetTilemapOptions options, uint32_t* outBuffer)
|
||||
{
|
||||
static constexpr uint8_t layerBpp[8][4] = {
|
||||
|
@ -106,7 +238,7 @@ void PpuTools::GetTilemap(GetTilemapOptions options, uint32_t* outBuffer)
|
|||
tileIndex +
|
||||
(largeTileHeight ? ((row & 0x01) ? (vMirror ? 0 : 16) : (vMirror ? 16 : 0)) : 0) +
|
||||
(largeTileWidth ? ((column & 0x01) ? (hMirror ? 0 : 1) : (hMirror ? 1 : 0)) : 0)
|
||||
) & 0x3FF;
|
||||
) & 0x3FF;
|
||||
}
|
||||
|
||||
for(int y = 0; y < 8; y++) {
|
||||
|
@ -115,23 +247,10 @@ void PpuTools::GetTilemap(GetTilemapOptions options, uint32_t* outBuffer)
|
|||
|
||||
for(int x = 0; x < 8; x++) {
|
||||
uint8_t shift = hMirror ? x : (7 - x);
|
||||
uint16_t color = GetTilePixelColor(bpp, pixelStart, shift);
|
||||
uint8_t color = GetTilePixelColor(vram, Ppu::VideoRamSize - 1, bpp, pixelStart, shift);
|
||||
if(color != 0) {
|
||||
uint16_t paletteColor;
|
||||
/*if(bpp == 8 && directColorMode) {
|
||||
uint8_t palette = (vram[addr + 1] >> 2) & 0x07;
|
||||
paletteColor = (
|
||||
(((color & 0x07) | (palette & 0x01)) << 1) |
|
||||
(((color & 0x38) | ((palette & 0x02) << 1)) << 3) |
|
||||
(((color & 0xC0) | ((palette & 0x04) << 3)) << 7)
|
||||
);
|
||||
} else {*/
|
||||
uint8_t palette = bpp == 8 ? 0 : (vram[addr + 1] >> 2) & 0x07;
|
||||
uint16_t paletteRamOffset = basePaletteOffset + (palette * (1 << bpp) + color) * 2;
|
||||
paletteColor = cgram[paletteRamOffset] | (cgram[paletteRamOffset + 1] << 8);
|
||||
//}
|
||||
|
||||
outBuffer[((row * 8) + y) * 512 + column * 8 + x] = ToArgb(paletteColor);
|
||||
outBuffer[((row * 8) + y) * 512 + column * 8 + x] = GetRgbPixelColor(color, palette, bpp, false, basePaletteOffset);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,7 +258,7 @@ void PpuTools::GetTilemap(GetTilemapOptions options, uint32_t* outBuffer)
|
|||
}
|
||||
|
||||
if(options.ShowTileGrid) {
|
||||
uint32_t gridColor = 0xA0AAAAFF;
|
||||
constexpr uint32_t gridColor = 0xA0AAAAFF;
|
||||
for(int i = 0; i < 512 * 512; i++) {
|
||||
if((i & 0x07) == 0x07 || (i & 0x0E00) == 0x0E00) {
|
||||
BlendColors((uint8_t*)&outBuffer[i], (uint8_t*)&gridColor);
|
||||
|
@ -148,7 +267,7 @@ void PpuTools::GetTilemap(GetTilemapOptions options, uint32_t* outBuffer)
|
|||
}
|
||||
|
||||
if(options.ShowScrollOverlay) {
|
||||
uint32_t overlayColor = 0x40FFFFFF;
|
||||
constexpr uint32_t overlayColor = 0x40FFFFFF;
|
||||
for(int y = 0; y < 240; y++) {
|
||||
for(int x = 0; x < 256; x++) {
|
||||
int xPos = layer.HScroll + x;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "DebugTypes.h"
|
||||
|
||||
class Ppu;
|
||||
class Console;
|
||||
struct GetTilemapOptions;
|
||||
|
||||
class PpuTools
|
||||
{
|
||||
|
@ -12,14 +12,17 @@ private:
|
|||
Console *_console;
|
||||
unordered_map<uint32_t, uint32_t> _updateTimings;
|
||||
|
||||
uint16_t GetTilePixelColor(const uint8_t bpp, const uint16_t pixelStart, const uint8_t shift);
|
||||
uint8_t GetTilePixelColor(const uint8_t* ram, const uint32_t ramMask, const uint8_t bpp, const uint32_t pixelStart, const uint8_t shift);
|
||||
|
||||
uint32_t ToArgb(uint16_t color);
|
||||
void BlendColors(uint8_t output[4], uint8_t input[4]);
|
||||
|
||||
public:
|
||||
PpuTools(Console *console, Ppu* ppu);
|
||||
uint32_t GetRgbPixelColor(uint8_t colorIndex, uint8_t palette, uint8_t bpp, bool directColorMode, uint16_t basePaletteOffset);
|
||||
|
||||
public:
|
||||
PpuTools(Console *console, Ppu *ppu);
|
||||
|
||||
void GetTileView(GetTileViewOptions options, uint32_t *outBuffer);
|
||||
void GetTilemap(GetTilemapOptions options, uint32_t *outBuffer);
|
||||
|
||||
void SetViewerUpdateTiming(uint32_t viewerId, uint16_t scanline, uint16_t cycle);
|
||||
|
|
|
@ -62,6 +62,7 @@ extern "C"
|
|||
DllExport void __stdcall SetMemoryValues(SnesMemoryType type, uint32_t address, uint8_t* data, int32_t length) { return GetDebugger()->GetMemoryDumper()->SetMemoryValues(type, address, data, length); }
|
||||
|
||||
DllExport void __stdcall GetTilemap(GetTilemapOptions options, uint32_t *buffer) { GetDebugger()->GetPpuTools()->GetTilemap(options, buffer); }
|
||||
DllExport void __stdcall GetTileView(GetTileViewOptions options, uint32_t *buffer) { GetDebugger()->GetPpuTools()->GetTileView(options, buffer); }
|
||||
DllExport void __stdcall SetViewerUpdateTiming(uint32_t viewerId, uint16_t scanline, uint16_t cycle) { GetDebugger()->GetPpuTools()->SetViewerUpdateTiming(viewerId, scanline, cycle); }
|
||||
|
||||
DllExport void __stdcall GetDebugEvents(DebugEventInfo *infoArray, uint32_t &maxEventCount, bool getPreviousFrameData) { GetDebugger()->GetEventManager()->GetEvents(infoArray, maxEventCount, getPreviousFrameData); }
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace Mesen.GUI.Debugger
|
|||
case DebugWindow.Debugger: frm = new frmDebugger(); frm.Icon = Properties.Resources.Debugger; break;
|
||||
case DebugWindow.TraceLogger: frm = new frmTraceLogger(); frm.Icon = Properties.Resources.LogWindow; break;
|
||||
case DebugWindow.MemoryTools: frm = new frmMemoryTools(); frm.Icon = Properties.Resources.CheatCode; break;
|
||||
case DebugWindow.TileViewer: frm = new frmTileViewer(); frm.Icon = Properties.Resources.VerticalLayout; break;
|
||||
case DebugWindow.TilemapViewer: frm = new frmTilemapViewer(); frm.Icon = Properties.Resources.VideoOptions; break;
|
||||
case DebugWindow.PaletteViewer: frm = new frmPaletteViewer(); frm.Icon = Properties.Resources.VideoFilter; break;
|
||||
case DebugWindow.EventViewer: frm = new frmEventViewer(); frm.Icon = Properties.Resources.NesEventViewer; break;
|
||||
|
@ -119,6 +120,7 @@ namespace Mesen.GUI.Debugger
|
|||
Debugger,
|
||||
MemoryTools,
|
||||
TraceLogger,
|
||||
TileViewer,
|
||||
TilemapViewer,
|
||||
PaletteViewer,
|
||||
EventViewer
|
||||
|
|
62
UI/Debugger/PpuViewer/ctrlPaletteViewer.Designer.cs
generated
Normal file
62
UI/Debugger/PpuViewer/ctrlPaletteViewer.Designer.cs
generated
Normal file
|
@ -0,0 +1,62 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class ctrlPaletteViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Component Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.picPalette = new Mesen.GUI.Controls.ctrlMesenPictureBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPalette)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// picPalette
|
||||
//
|
||||
this.picPalette.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
this.picPalette.Location = new System.Drawing.Point(0, 0);
|
||||
this.picPalette.MinimumSize = new System.Drawing.Size(256, 256);
|
||||
this.picPalette.Name = "picPalette";
|
||||
this.picPalette.Size = new System.Drawing.Size(256, 256);
|
||||
this.picPalette.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.picPalette.TabIndex = 1;
|
||||
this.picPalette.TabStop = false;
|
||||
this.picPalette.MouseClick += new System.Windows.Forms.MouseEventHandler(this.picPalette_MouseClick);
|
||||
//
|
||||
// ctrlPaletteViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.picPalette);
|
||||
this.Name = "ctrlPaletteViewer";
|
||||
this.Size = new System.Drawing.Size(256, 256);
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPalette)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private GUI.Controls.ctrlMesenPictureBox picPalette;
|
||||
}
|
||||
}
|
106
UI/Debugger/PpuViewer/ctrlPaletteViewer.cs
Normal file
106
UI/Debugger/PpuViewer/ctrlPaletteViewer.cs
Normal file
|
@ -0,0 +1,106 @@
|
|||
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 System.Drawing.Imaging;
|
||||
using System.Drawing.Drawing2D;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class ctrlPaletteViewer : BaseControl
|
||||
{
|
||||
private byte[] _cgRam;
|
||||
private Bitmap _paletteImage;
|
||||
|
||||
public int PaletteScale { get; set; } = 16;
|
||||
public int SelectedPalette { get; private set; } = 0;
|
||||
public PaletteSelectionMode SelectionMode { get; set; } = PaletteSelectionMode.None;
|
||||
|
||||
public ctrlPaletteViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
if(IsDesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
_paletteImage = new Bitmap(PaletteScale * 16, PaletteScale * 16, PixelFormat.Format32bppArgb);
|
||||
picPalette.Image = _paletteImage;
|
||||
}
|
||||
|
||||
public void RefreshData()
|
||||
{
|
||||
_cgRam = DebugApi.GetMemoryState(SnesMemoryType.CGRam);
|
||||
}
|
||||
|
||||
public void RefreshViewer()
|
||||
{
|
||||
Func<int, uint> to8Bit = (int color) => { return (uint)((color << 3) + (color >> 2)); };
|
||||
Func<int, uint> toArgb = (int rgb555) => {
|
||||
uint b = to8Bit(rgb555 >> 10);
|
||||
uint g = to8Bit((rgb555 >> 5) & 0x1F);
|
||||
uint r = to8Bit(rgb555 & 0x1F);
|
||||
|
||||
return (0xFF000000 | (r << 16) | (g << 8) | b);
|
||||
};
|
||||
|
||||
UInt32[] argbPalette = new UInt32[256];
|
||||
for(int i = 0; i < 256; i++) {
|
||||
argbPalette[i] = toArgb(_cgRam[i * 2] | _cgRam[i * 2 + 1] << 8);
|
||||
}
|
||||
|
||||
using(Graphics g = Graphics.FromImage(_paletteImage)) {
|
||||
GCHandle handle = GCHandle.Alloc(argbPalette, GCHandleType.Pinned);
|
||||
Bitmap source = new Bitmap(16, 16, 16 * 4, PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
|
||||
try {
|
||||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
g.SmoothingMode = SmoothingMode.None;
|
||||
g.PixelOffsetMode = PixelOffsetMode.Half;
|
||||
|
||||
g.ScaleTransform(PaletteScale, PaletteScale);
|
||||
g.DrawImage(source, 0, 0);
|
||||
|
||||
g.ResetTransform();
|
||||
using(Pen pen = new Pen(Color.LightGray, 2)) {
|
||||
pen.DashStyle = DashStyle.Dash;
|
||||
if(SelectionMode == PaletteSelectionMode.FourColors) {
|
||||
g.DrawRectangle(pen, (SelectedPalette & 0x03) * PaletteScale * 4, (SelectedPalette / 4) * PaletteScale, PaletteScale * 4, PaletteScale);
|
||||
} else if(SelectionMode == PaletteSelectionMode.SixteenColors) {
|
||||
g.DrawRectangle(pen, 0, SelectedPalette * PaletteScale, PaletteScale * 16, PaletteScale);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
handle.Free();
|
||||
}
|
||||
}
|
||||
|
||||
picPalette.Size = _paletteImage.Size;
|
||||
picPalette.Invalidate();
|
||||
}
|
||||
|
||||
private void picPalette_MouseClick(object sender, MouseEventArgs e)
|
||||
{
|
||||
int paletteIndex = 0;
|
||||
if(SelectionMode == PaletteSelectionMode.FourColors) {
|
||||
paletteIndex += e.X / (4 * PaletteScale);
|
||||
paletteIndex += (e.Y / PaletteScale) * 4;
|
||||
} else if(SelectionMode == PaletteSelectionMode.SixteenColors) {
|
||||
paletteIndex = (e.Y / PaletteScale);
|
||||
}
|
||||
SelectedPalette = paletteIndex;
|
||||
}
|
||||
}
|
||||
|
||||
public enum PaletteSelectionMode
|
||||
{
|
||||
None,
|
||||
FourColors,
|
||||
SixteenColors
|
||||
}
|
||||
}
|
120
UI/Debugger/PpuViewer/ctrlPaletteViewer.resx
Normal file
120
UI/Debugger/PpuViewer/ctrlPaletteViewer.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
29
UI/Debugger/PpuViewer/frmPaletteViewer.Designer.cs
generated
29
UI/Debugger/PpuViewer/frmPaletteViewer.Designer.cs
generated
|
@ -27,24 +27,12 @@
|
|||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.picPalette = new Mesen.GUI.Controls.ctrlMesenPictureBox();
|
||||
this.ctrlScanlineCycleSelect = new Mesen.GUI.Debugger.Controls.ctrlScanlineCycleSelect();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPalette)).BeginInit();
|
||||
this.ctrlPaletteViewer = new Mesen.GUI.Debugger.ctrlPaletteViewer();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// picPalette
|
||||
//
|
||||
this.picPalette.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
this.picPalette.Location = new System.Drawing.Point(3, 3);
|
||||
this.picPalette.MinimumSize = new System.Drawing.Size(256, 256);
|
||||
this.picPalette.Name = "picPalette";
|
||||
this.picPalette.Size = new System.Drawing.Size(256, 256);
|
||||
this.picPalette.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.picPalette.TabIndex = 0;
|
||||
this.picPalette.TabStop = false;
|
||||
//
|
||||
// ctrlScanlineCycleSelect
|
||||
//
|
||||
this.ctrlScanlineCycleSelect.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
|
@ -58,7 +46,7 @@
|
|||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.Controls.Add(this.picPalette, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.ctrlPaletteViewer, 0, 1);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
|
@ -68,6 +56,13 @@
|
|||
this.tableLayoutPanel1.Size = new System.Drawing.Size(485, 263);
|
||||
this.tableLayoutPanel1.TabIndex = 7;
|
||||
//
|
||||
// ctrlPaletteViewer1
|
||||
//
|
||||
this.ctrlPaletteViewer.Location = new System.Drawing.Point(3, 3);
|
||||
this.ctrlPaletteViewer.Name = "ctrlPaletteViewer";
|
||||
this.ctrlPaletteViewer.Size = new System.Drawing.Size(256, 256);
|
||||
this.ctrlPaletteViewer.TabIndex = 0;
|
||||
//
|
||||
// frmPaletteViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
|
@ -76,17 +71,15 @@
|
|||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Controls.Add(this.ctrlScanlineCycleSelect);
|
||||
this.Name = "frmPaletteViewer";
|
||||
this.Text = "Tilemap Viewer";
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPalette)).EndInit();
|
||||
this.Text = "Palette Viewer";
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private GUI.Controls.ctrlMesenPictureBox picPalette;
|
||||
private Controls.ctrlScanlineCycleSelect ctrlScanlineCycleSelect;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private ctrlPaletteViewer ctrlPaletteViewer;
|
||||
}
|
||||
}
|
|
@ -1,15 +1,5 @@
|
|||
using Mesen.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
|
@ -17,8 +7,6 @@ namespace Mesen.GUI.Debugger
|
|||
public partial class frmPaletteViewer : BaseForm
|
||||
{
|
||||
private NotificationListener _notifListener;
|
||||
private byte[] _cgRam;
|
||||
private Bitmap _paletteImage;
|
||||
|
||||
public frmPaletteViewer()
|
||||
{
|
||||
|
@ -35,13 +23,10 @@ namespace Mesen.GUI.Debugger
|
|||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
|
||||
_paletteImage = new Bitmap(256, 256, PixelFormat.Format32bppArgb);
|
||||
picPalette.Image = _paletteImage;
|
||||
|
||||
ctrlScanlineCycleSelect.Initialize(241, 0);
|
||||
|
||||
RefreshData();
|
||||
RefreshViewer();
|
||||
ctrlPaletteViewer.RefreshData();
|
||||
ctrlPaletteViewer.RefreshViewer();
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
|
@ -55,53 +40,13 @@ namespace Mesen.GUI.Debugger
|
|||
switch(e.NotificationType) {
|
||||
case ConsoleNotificationType.ViewerRefresh:
|
||||
if(e.Parameter.ToInt32() == ctrlScanlineCycleSelect.ViewerId) {
|
||||
RefreshData();
|
||||
ctrlPaletteViewer.RefreshData();
|
||||
this.BeginInvoke((Action)(() => {
|
||||
this.RefreshViewer();
|
||||
ctrlPaletteViewer.RefreshViewer();
|
||||
}));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshData()
|
||||
{
|
||||
_cgRam = DebugApi.GetMemoryState(SnesMemoryType.CGRam);
|
||||
}
|
||||
|
||||
private void RefreshViewer()
|
||||
{
|
||||
Func<int, uint> to8Bit = (int color) => { return (uint)((color << 3) + (color >> 2)); };
|
||||
Func<int, uint> toArgb = (int rgb555) => {
|
||||
uint b = to8Bit(rgb555 >> 10);
|
||||
uint g = to8Bit((rgb555 >> 5) & 0x1F);
|
||||
uint r = to8Bit(rgb555 & 0x1F);
|
||||
|
||||
return (0xFF000000 | (r << 16) | (g << 8) | b);
|
||||
};
|
||||
|
||||
|
||||
UInt32[] argbPalette = new UInt32[256];
|
||||
for(int i = 0; i < 256; i++) {
|
||||
argbPalette[i] = toArgb(_cgRam[i * 2] | _cgRam[i * 2 + 1] << 8);
|
||||
}
|
||||
|
||||
using(Graphics g = Graphics.FromImage(_paletteImage)) {
|
||||
GCHandle handle = GCHandle.Alloc(argbPalette, GCHandleType.Pinned);
|
||||
Bitmap source = new Bitmap(16, 16, 16 * 4, PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
|
||||
try {
|
||||
g.InterpolationMode = InterpolationMode.NearestNeighbor;
|
||||
g.SmoothingMode = SmoothingMode.None;
|
||||
g.PixelOffsetMode = PixelOffsetMode.Half;
|
||||
|
||||
g.ScaleTransform(16, 16);
|
||||
g.DrawImage(source, 0, 0);
|
||||
} finally {
|
||||
handle.Free();
|
||||
}
|
||||
}
|
||||
|
||||
picPalette.Invalidate();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
360
UI/Debugger/PpuViewer/frmTileViewer.Designer.cs
generated
Normal file
360
UI/Debugger/PpuViewer/frmTileViewer.Designer.cs
generated
Normal file
|
@ -0,0 +1,360 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class frmTileViewer
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if(disposing && (components != null)) {
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.picTilemap = new Mesen.GUI.Controls.ctrlMesenPictureBox();
|
||||
this.ctrlScanlineCycleSelect = new Mesen.GUI.Debugger.Controls.ctrlScanlineCycleSelect();
|
||||
this.pnlTilemap = new System.Windows.Forms.Panel();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.cboMemoryType = new Mesen.GUI.Debugger.Controls.ComboBoxWithSeparator();
|
||||
this.nudBank = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblBank = new System.Windows.Forms.Label();
|
||||
this.lblSource = new System.Windows.Forms.Label();
|
||||
this.lblColumns = new System.Windows.Forms.Label();
|
||||
this.chkShowTileGrid = new System.Windows.Forms.CheckBox();
|
||||
this.lblBpp = new System.Windows.Forms.Label();
|
||||
this.cboFormat = new System.Windows.Forms.ComboBox();
|
||||
this.nudColumns = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.lblOffset = new System.Windows.Forms.Label();
|
||||
this.nudOffset = new Mesen.GUI.Controls.MesenNumericUpDown();
|
||||
this.ctrlPaletteViewer = new Mesen.GUI.Debugger.ctrlPaletteViewer();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picTilemap)).BeginInit();
|
||||
this.pnlTilemap.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
this.tableLayoutPanel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// picTilemap
|
||||
//
|
||||
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.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
this.picTilemap.TabIndex = 0;
|
||||
this.picTilemap.TabStop = false;
|
||||
this.picTilemap.DoubleClick += new System.EventHandler(this.picTilemap_DoubleClick);
|
||||
//
|
||||
// ctrlScanlineCycleSelect
|
||||
//
|
||||
this.ctrlScanlineCycleSelect.Dock = System.Windows.Forms.DockStyle.Bottom;
|
||||
this.ctrlScanlineCycleSelect.Location = new System.Drawing.Point(0, 546);
|
||||
this.ctrlScanlineCycleSelect.Name = "ctrlScanlineCycleSelect";
|
||||
this.ctrlScanlineCycleSelect.Size = new System.Drawing.Size(737, 28);
|
||||
this.ctrlScanlineCycleSelect.TabIndex = 5;
|
||||
//
|
||||
// pnlTilemap
|
||||
//
|
||||
this.pnlTilemap.AutoScroll = true;
|
||||
this.pnlTilemap.Controls.Add(this.picTilemap);
|
||||
this.pnlTilemap.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pnlTilemap.Location = new System.Drawing.Point(3, 3);
|
||||
this.pnlTilemap.MinimumSize = new System.Drawing.Size(512, 512);
|
||||
this.pnlTilemap.Name = "pnlTilemap";
|
||||
this.pnlTilemap.Size = new System.Drawing.Size(531, 540);
|
||||
this.pnlTilemap.TabIndex = 6;
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 2;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.Controls.Add(this.pnlTilemap, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.tableLayoutPanel2, 1, 0);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 1;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tableLayoutPanel1.Size = new System.Drawing.Size(737, 546);
|
||||
this.tableLayoutPanel1.TabIndex = 7;
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.ColumnCount = 2;
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel2.Controls.Add(this.cboMemoryType, 1, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.nudBank, 1, 3);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblBank, 0, 3);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblSource, 0, 0);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblColumns, 0, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.chkShowTileGrid, 0, 5);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblBpp, 0, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.cboFormat, 1, 1);
|
||||
this.tableLayoutPanel2.Controls.Add(this.nudColumns, 1, 2);
|
||||
this.tableLayoutPanel2.Controls.Add(this.lblOffset, 0, 4);
|
||||
this.tableLayoutPanel2.Controls.Add(this.nudOffset, 1, 4);
|
||||
this.tableLayoutPanel2.Controls.Add(this.ctrlPaletteViewer, 0, 6);
|
||||
this.tableLayoutPanel2.Location = new System.Drawing.Point(540, 3);
|
||||
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
|
||||
this.tableLayoutPanel2.RowCount = 7;
|
||||
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());
|
||||
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(194, 457);
|
||||
this.tableLayoutPanel2.TabIndex = 7;
|
||||
//
|
||||
// cboMemoryType
|
||||
//
|
||||
this.cboMemoryType.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
|
||||
this.cboMemoryType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboMemoryType.FormattingEnabled = true;
|
||||
this.cboMemoryType.Location = new System.Drawing.Point(59, 3);
|
||||
this.cboMemoryType.Name = "cboMemoryType";
|
||||
this.cboMemoryType.Size = new System.Drawing.Size(132, 21);
|
||||
this.cboMemoryType.TabIndex = 11;
|
||||
this.cboMemoryType.SelectedIndexChanged += new System.EventHandler(this.cboMemoryType_SelectedIndexChanged);
|
||||
//
|
||||
// nudBank
|
||||
//
|
||||
this.nudBank.DecimalPlaces = 0;
|
||||
this.nudBank.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudBank.Location = new System.Drawing.Point(59, 84);
|
||||
this.nudBank.Maximum = new decimal(new int[] {
|
||||
63,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudBank.MaximumSize = new System.Drawing.Size(10000, 21);
|
||||
this.nudBank.Minimum = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudBank.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudBank.Name = "nudBank";
|
||||
this.nudBank.Size = new System.Drawing.Size(43, 21);
|
||||
this.nudBank.TabIndex = 10;
|
||||
this.nudBank.Value = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudBank.ValueChanged += new System.EventHandler(this.nudBank_ValueChanged);
|
||||
//
|
||||
// lblBank
|
||||
//
|
||||
this.lblBank.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblBank.AutoSize = true;
|
||||
this.lblBank.Location = new System.Drawing.Point(3, 88);
|
||||
this.lblBank.Name = "lblBank";
|
||||
this.lblBank.Size = new System.Drawing.Size(35, 13);
|
||||
this.lblBank.TabIndex = 9;
|
||||
this.lblBank.Text = "Bank:";
|
||||
//
|
||||
// lblSource
|
||||
//
|
||||
this.lblSource.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblSource.AutoSize = true;
|
||||
this.lblSource.Location = new System.Drawing.Point(3, 7);
|
||||
this.lblSource.Name = "lblSource";
|
||||
this.lblSource.Size = new System.Drawing.Size(44, 13);
|
||||
this.lblSource.TabIndex = 7;
|
||||
this.lblSource.Text = "Source:";
|
||||
//
|
||||
// lblColumns
|
||||
//
|
||||
this.lblColumns.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblColumns.AutoSize = true;
|
||||
this.lblColumns.Location = new System.Drawing.Point(3, 61);
|
||||
this.lblColumns.Name = "lblColumns";
|
||||
this.lblColumns.Size = new System.Drawing.Size(50, 13);
|
||||
this.lblColumns.TabIndex = 3;
|
||||
this.lblColumns.Text = "Columns:";
|
||||
//
|
||||
// chkShowTileGrid
|
||||
//
|
||||
this.chkShowTileGrid.AutoSize = true;
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.chkShowTileGrid, 2);
|
||||
this.chkShowTileGrid.Location = new System.Drawing.Point(3, 138);
|
||||
this.chkShowTileGrid.Name = "chkShowTileGrid";
|
||||
this.chkShowTileGrid.Size = new System.Drawing.Size(89, 17);
|
||||
this.chkShowTileGrid.TabIndex = 0;
|
||||
this.chkShowTileGrid.Text = "Show tile grid";
|
||||
this.chkShowTileGrid.UseVisualStyleBackColor = true;
|
||||
this.chkShowTileGrid.Click += new System.EventHandler(this.chkShowTileGrid_Click);
|
||||
//
|
||||
// lblBpp
|
||||
//
|
||||
this.lblBpp.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblBpp.AutoSize = true;
|
||||
this.lblBpp.Location = new System.Drawing.Point(3, 34);
|
||||
this.lblBpp.Name = "lblBpp";
|
||||
this.lblBpp.Size = new System.Drawing.Size(42, 13);
|
||||
this.lblBpp.TabIndex = 1;
|
||||
this.lblBpp.Text = "Format:";
|
||||
//
|
||||
// cboFormat
|
||||
//
|
||||
this.cboFormat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.cboFormat.FormattingEnabled = true;
|
||||
this.cboFormat.Items.AddRange(new object[] {
|
||||
"2 BPP",
|
||||
"4 BPP",
|
||||
"8 BPP",
|
||||
"8 BPP - Direct Color Mode",
|
||||
"Mode 7",
|
||||
"Mode 7 - Direct Color Mode"});
|
||||
this.cboFormat.Location = new System.Drawing.Point(59, 30);
|
||||
this.cboFormat.Name = "cboFormat";
|
||||
this.cboFormat.Size = new System.Drawing.Size(132, 21);
|
||||
this.cboFormat.TabIndex = 2;
|
||||
this.cboFormat.SelectedIndexChanged += new System.EventHandler(this.cboBpp_SelectedIndexChanged);
|
||||
//
|
||||
// nudColumns
|
||||
//
|
||||
this.nudColumns.DecimalPlaces = 0;
|
||||
this.nudColumns.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudColumns.Location = new System.Drawing.Point(59, 57);
|
||||
this.nudColumns.Maximum = new decimal(new int[] {
|
||||
64,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudColumns.MaximumSize = new System.Drawing.Size(10000, 21);
|
||||
this.nudColumns.Minimum = new decimal(new int[] {
|
||||
8,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudColumns.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudColumns.Name = "nudColumns";
|
||||
this.nudColumns.Size = new System.Drawing.Size(43, 21);
|
||||
this.nudColumns.TabIndex = 4;
|
||||
this.nudColumns.Value = new decimal(new int[] {
|
||||
32,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudColumns.ValueChanged += new System.EventHandler(this.nudColumns_ValueChanged);
|
||||
//
|
||||
// lblOffset
|
||||
//
|
||||
this.lblOffset.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblOffset.AutoSize = true;
|
||||
this.lblOffset.Location = new System.Drawing.Point(3, 115);
|
||||
this.lblOffset.Name = "lblOffset";
|
||||
this.lblOffset.Size = new System.Drawing.Size(38, 13);
|
||||
this.lblOffset.TabIndex = 5;
|
||||
this.lblOffset.Text = "Offset:";
|
||||
//
|
||||
// nudOffset
|
||||
//
|
||||
this.nudOffset.DecimalPlaces = 0;
|
||||
this.nudOffset.Increment = new decimal(new int[] {
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOffset.Location = new System.Drawing.Point(59, 111);
|
||||
this.nudOffset.Maximum = new decimal(new int[] {
|
||||
63,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOffset.MaximumSize = new System.Drawing.Size(10000, 21);
|
||||
this.nudOffset.Minimum = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOffset.MinimumSize = new System.Drawing.Size(0, 21);
|
||||
this.nudOffset.Name = "nudOffset";
|
||||
this.nudOffset.Size = new System.Drawing.Size(43, 21);
|
||||
this.nudOffset.TabIndex = 6;
|
||||
this.nudOffset.Value = new decimal(new int[] {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.nudOffset.ValueChanged += new System.EventHandler(this.nudOffset_ValueChanged);
|
||||
//
|
||||
// ctrlPaletteViewer
|
||||
//
|
||||
this.tableLayoutPanel2.SetColumnSpan(this.ctrlPaletteViewer, 2);
|
||||
this.ctrlPaletteViewer.Location = new System.Drawing.Point(3, 161);
|
||||
this.ctrlPaletteViewer.Name = "ctrlPaletteViewer";
|
||||
this.ctrlPaletteViewer.PaletteScale = 11;
|
||||
this.ctrlPaletteViewer.SelectionMode = Mesen.GUI.Debugger.PaletteSelectionMode.None;
|
||||
this.ctrlPaletteViewer.Size = new System.Drawing.Size(176, 176);
|
||||
this.ctrlPaletteViewer.TabIndex = 12;
|
||||
//
|
||||
// frmTileViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(737, 574);
|
||||
this.Controls.Add(this.tableLayoutPanel1);
|
||||
this.Controls.Add(this.ctrlScanlineCycleSelect);
|
||||
this.Name = "frmTileViewer";
|
||||
this.Text = "Tile Viewer";
|
||||
((System.ComponentModel.ISupportInitialize)(this.picTilemap)).EndInit();
|
||||
this.pnlTilemap.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.ResumeLayout(false);
|
||||
this.tableLayoutPanel2.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private GUI.Controls.ctrlMesenPictureBox picTilemap;
|
||||
private Controls.ctrlScanlineCycleSelect ctrlScanlineCycleSelect;
|
||||
private System.Windows.Forms.Panel pnlTilemap;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.CheckBox chkShowTileGrid;
|
||||
private GUI.Controls.MesenNumericUpDown nudBank;
|
||||
private System.Windows.Forms.Label lblBank;
|
||||
private System.Windows.Forms.Label lblSource;
|
||||
private System.Windows.Forms.Label lblColumns;
|
||||
private System.Windows.Forms.Label lblBpp;
|
||||
private System.Windows.Forms.ComboBox cboFormat;
|
||||
private GUI.Controls.MesenNumericUpDown nudColumns;
|
||||
private System.Windows.Forms.Label lblOffset;
|
||||
private GUI.Controls.MesenNumericUpDown nudOffset;
|
||||
private Controls.ComboBoxWithSeparator cboMemoryType;
|
||||
private ctrlPaletteViewer ctrlPaletteViewer;
|
||||
}
|
||||
}
|
205
UI/Debugger/PpuViewer/frmTileViewer.cs
Normal file
205
UI/Debugger/PpuViewer/frmTileViewer.cs
Normal file
|
@ -0,0 +1,205 @@
|
|||
using Mesen.GUI.Forms;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmTileViewer : BaseForm
|
||||
{
|
||||
private NotificationListener _notifListener;
|
||||
private GetTileViewOptions _options;
|
||||
private byte[] _tileData;
|
||||
private Bitmap _tileImage;
|
||||
private bool _zoomed;
|
||||
|
||||
public frmTileViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
if(DesignMode) {
|
||||
return;
|
||||
}
|
||||
|
||||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
|
||||
BaseConfigForm.InitializeComboBox(cboFormat, typeof(TileFormat));
|
||||
|
||||
_options.Format = TileFormat.Bpp4;
|
||||
_options.Width = 32;
|
||||
cboFormat.SetEnumValue(TileFormat.Bpp4);
|
||||
ctrlPaletteViewer.SelectionMode = PaletteSelectionMode.SixteenColors;
|
||||
|
||||
_tileImage = new Bitmap(512, 512, PixelFormat.Format32bppArgb);
|
||||
picTilemap.Image = _tileImage;
|
||||
|
||||
ctrlScanlineCycleSelect.Initialize(241, 0);
|
||||
|
||||
InitMemoryTypeDropdown();
|
||||
|
||||
RefreshData();
|
||||
RefreshViewer();
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
base.OnFormClosed(e);
|
||||
_notifListener?.Dispose();
|
||||
}
|
||||
|
||||
private void OnNotificationReceived(NotificationEventArgs e)
|
||||
{
|
||||
switch(e.NotificationType) {
|
||||
case ConsoleNotificationType.ViewerRefresh:
|
||||
if(e.Parameter.ToInt32() == ctrlScanlineCycleSelect.ViewerId) {
|
||||
RefreshData();
|
||||
this.BeginInvoke((Action)(() => {
|
||||
this.RefreshViewer();
|
||||
}));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private int GetBytesPerTile()
|
||||
{
|
||||
switch(_options.Format) {
|
||||
case TileFormat.Bpp2: return 16;
|
||||
case TileFormat.Bpp4: return 32;
|
||||
|
||||
default:
|
||||
case TileFormat.Bpp8: return 64;
|
||||
|
||||
case TileFormat.Mode7:
|
||||
case TileFormat.Mode7DirectColor: return 128;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshData()
|
||||
{
|
||||
_options.Palette = ctrlPaletteViewer.SelectedPalette;
|
||||
_tileData = DebugApi.GetTileView(_options);
|
||||
ctrlPaletteViewer.RefreshData();
|
||||
}
|
||||
|
||||
private void RefreshViewer()
|
||||
{
|
||||
int tileCount = 0x10000 / GetBytesPerTile();
|
||||
|
||||
int mapWidth = _options.Width * 8;
|
||||
int mapHeight = tileCount / _options.Width * 8;
|
||||
|
||||
if(_tileImage.Width != mapWidth || _tileImage.Height != mapHeight) {
|
||||
_tileImage = new Bitmap(mapWidth, mapHeight, PixelFormat.Format32bppArgb);
|
||||
picTilemap.Image = _tileImage;
|
||||
}
|
||||
|
||||
using(Graphics g = Graphics.FromImage(_tileImage)) {
|
||||
GCHandle handle = GCHandle.Alloc(_tileData, GCHandleType.Pinned);
|
||||
Bitmap source = new Bitmap(mapWidth, mapHeight, 4 * mapWidth, PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
|
||||
try {
|
||||
g.DrawImage(source, 0, 0);
|
||||
} finally {
|
||||
handle.Free();
|
||||
}
|
||||
}
|
||||
|
||||
UpdateMapSize();
|
||||
picTilemap.Invalidate();
|
||||
|
||||
ctrlPaletteViewer.RefreshViewer();
|
||||
}
|
||||
|
||||
private void UpdateMapSize()
|
||||
{
|
||||
int tileCount = 0x10000 / GetBytesPerTile();
|
||||
int mapWidth = _options.Width * 8;
|
||||
int mapHeight = tileCount / _options.Width * 8;
|
||||
|
||||
picTilemap.Width = _zoomed ? mapWidth * 2 : mapWidth;
|
||||
picTilemap.Height = _zoomed ? mapHeight * 2 : mapHeight;
|
||||
}
|
||||
|
||||
private void InitMemoryTypeDropdown()
|
||||
{
|
||||
cboMemoryType.BeginUpdate();
|
||||
cboMemoryType.Items.Clear();
|
||||
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.VideoRam));
|
||||
cboMemoryType.Items.Add("-");
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.PrgRom));
|
||||
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.WorkRam));
|
||||
|
||||
cboMemoryType.SelectedIndex = 0;
|
||||
cboMemoryType.EndUpdate();
|
||||
}
|
||||
|
||||
private void picTilemap_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
_zoomed = !_zoomed;
|
||||
UpdateMapSize();
|
||||
}
|
||||
|
||||
private void chkShowTileGrid_Click(object sender, EventArgs e)
|
||||
{
|
||||
_options.ShowTileGrid = chkShowTileGrid.Checked;
|
||||
}
|
||||
|
||||
private void cboMemoryType_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
_options.MemoryType = cboMemoryType.GetEnumValue<SnesMemoryType>();
|
||||
|
||||
bool isVram = _options.MemoryType == SnesMemoryType.VideoRam;
|
||||
nudOffset.Visible = !isVram;
|
||||
nudBank.Visible = !isVram;
|
||||
lblOffset.Visible = !isVram;
|
||||
lblBank.Visible = !isVram;
|
||||
if(isVram) {
|
||||
nudBank.Value = 0;
|
||||
nudOffset.Value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
private void cboBpp_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
_options.Format = cboFormat.GetEnumValue<TileFormat>();
|
||||
if(_options.Format == TileFormat.Bpp2) {
|
||||
ctrlPaletteViewer.SelectionMode = PaletteSelectionMode.FourColors;
|
||||
} else if(_options.Format == TileFormat.Bpp4) {
|
||||
ctrlPaletteViewer.SelectionMode = PaletteSelectionMode.SixteenColors;
|
||||
} else {
|
||||
ctrlPaletteViewer.SelectionMode = PaletteSelectionMode.None;
|
||||
}
|
||||
|
||||
_options.Palette = ctrlPaletteViewer.SelectedPalette;
|
||||
}
|
||||
|
||||
private void nudColumns_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
_options.Width = (int)nudColumns.Value;
|
||||
}
|
||||
|
||||
private void nudBank_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
_options.AddressOffset = (int)(nudBank.Value * 0x10000 + nudOffset.Value);
|
||||
}
|
||||
|
||||
private void nudOffset_ValueChanged(object sender, EventArgs e)
|
||||
{
|
||||
_options.AddressOffset = (int)(nudBank.Value * 0x10000 + nudOffset.Value);
|
||||
}
|
||||
}
|
||||
}
|
123
UI/Debugger/PpuViewer/frmTileViewer.resx
Normal file
123
UI/Debugger/PpuViewer/frmTileViewer.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
|
@ -51,7 +51,6 @@
|
|||
//
|
||||
this.picTilemap.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
this.picTilemap.Location = new System.Drawing.Point(0, 0);
|
||||
this.picTilemap.MinimumSize = new System.Drawing.Size(256, 256);
|
||||
this.picTilemap.Name = "picTilemap";
|
||||
this.picTilemap.Size = new System.Drawing.Size(512, 512);
|
||||
this.picTilemap.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom;
|
||||
|
|
53
UI/Forms/frmMain.Designer.cs
generated
53
UI/Forms/frmMain.Designer.cs
generated
|
@ -125,7 +125,11 @@
|
|||
this.mnuDebugger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMemoryTools = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem12 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuTileViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuTilemapViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuPaletteViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem22 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuHelp = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuCheckForUpdates = new System.Windows.Forms.ToolStripMenuItem();
|
||||
|
@ -135,9 +139,6 @@
|
|||
this.mnuAbout = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.pnlRenderer = new System.Windows.Forms.Panel();
|
||||
this.ctrlRecentGames = new Mesen.GUI.Controls.ctrlRecentGames();
|
||||
this.mnuPaletteViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.toolStripMenuItem12 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.toolStripMenuItem22 = new System.Windows.Forms.ToolStripSeparator();
|
||||
this.mnuMain.SuspendLayout();
|
||||
this.pnlRenderer.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
|
@ -852,6 +853,7 @@
|
|||
this.mnuTraceLogger,
|
||||
this.toolStripMenuItem12,
|
||||
this.mnuTilemapViewer,
|
||||
this.mnuTileViewer,
|
||||
this.mnuPaletteViewer,
|
||||
this.toolStripMenuItem22,
|
||||
this.mnuEventViewer});
|
||||
|
@ -883,6 +885,19 @@
|
|||
this.mnuTraceLogger.Text = "Trace Logger";
|
||||
this.mnuTraceLogger.Click += new System.EventHandler(this.mnuTraceLogger_Click);
|
||||
//
|
||||
// toolStripMenuItem12
|
||||
//
|
||||
this.toolStripMenuItem12.Name = "toolStripMenuItem12";
|
||||
this.toolStripMenuItem12.Size = new System.Drawing.Size(152, 6);
|
||||
//
|
||||
// mnuTileViewer
|
||||
//
|
||||
this.mnuTileViewer.Image = global::Mesen.GUI.Properties.Resources.VerticalLayout;
|
||||
this.mnuTileViewer.Name = "mnuTileViewer";
|
||||
this.mnuTileViewer.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuTileViewer.Text = "Tile Viewer";
|
||||
this.mnuTileViewer.Click += new System.EventHandler(this.mnuTileViewer_Click);
|
||||
//
|
||||
// mnuTilemapViewer
|
||||
//
|
||||
this.mnuTilemapViewer.Image = global::Mesen.GUI.Properties.Resources.VideoOptions;
|
||||
|
@ -891,6 +906,19 @@
|
|||
this.mnuTilemapViewer.Text = "Tilemap Viewer";
|
||||
this.mnuTilemapViewer.Click += new System.EventHandler(this.mnuTilemapViewer_Click);
|
||||
//
|
||||
// mnuPaletteViewer
|
||||
//
|
||||
this.mnuPaletteViewer.Image = global::Mesen.GUI.Properties.Resources.VideoFilter;
|
||||
this.mnuPaletteViewer.Name = "mnuPaletteViewer";
|
||||
this.mnuPaletteViewer.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuPaletteViewer.Text = "Palette Viewer";
|
||||
this.mnuPaletteViewer.Click += new System.EventHandler(this.mnuPaletteViewer_Click);
|
||||
//
|
||||
// toolStripMenuItem22
|
||||
//
|
||||
this.toolStripMenuItem22.Name = "toolStripMenuItem22";
|
||||
this.toolStripMenuItem22.Size = new System.Drawing.Size(152, 6);
|
||||
//
|
||||
// mnuEventViewer
|
||||
//
|
||||
this.mnuEventViewer.Image = global::Mesen.GUI.Properties.Resources.NesEventViewer;
|
||||
|
@ -965,24 +993,6 @@
|
|||
this.ctrlRecentGames.TabIndex = 1;
|
||||
this.ctrlRecentGames.Visible = false;
|
||||
//
|
||||
// mnuPaletteViewer
|
||||
//
|
||||
this.mnuPaletteViewer.Image = global::Mesen.GUI.Properties.Resources.VideoFilter;
|
||||
this.mnuPaletteViewer.Name = "mnuPaletteViewer";
|
||||
this.mnuPaletteViewer.Size = new System.Drawing.Size(155, 22);
|
||||
this.mnuPaletteViewer.Text = "Palette Viewer";
|
||||
this.mnuPaletteViewer.Click += new System.EventHandler(this.mnuPaletteViewer_Click);
|
||||
//
|
||||
// toolStripMenuItem12
|
||||
//
|
||||
this.toolStripMenuItem12.Name = "toolStripMenuItem12";
|
||||
this.toolStripMenuItem12.Size = new System.Drawing.Size(152, 6);
|
||||
//
|
||||
// toolStripMenuItem22
|
||||
//
|
||||
this.toolStripMenuItem22.Name = "toolStripMenuItem22";
|
||||
this.toolStripMenuItem22.Size = new System.Drawing.Size(152, 6);
|
||||
//
|
||||
// frmMain
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
|
@ -1116,5 +1126,6 @@
|
|||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem12;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuPaletteViewer;
|
||||
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem22;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuTileViewer;
|
||||
}
|
||||
}
|
|
@ -184,6 +184,7 @@ namespace Mesen.GUI.Forms
|
|||
mnuMemoryTools.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenMemoryTools));
|
||||
mnuEventViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenEventViewer));
|
||||
mnuTilemapViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTilemapViewer));
|
||||
mnuTileViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTileViewer));
|
||||
mnuPaletteViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenPaletteViewer));
|
||||
mnuTraceLogger.InitShortcut(this, nameof(DebuggerShortcutsConfig.OpenTraceLogger));
|
||||
|
||||
|
@ -292,6 +293,11 @@ namespace Mesen.GUI.Forms
|
|||
DebugWindowManager.OpenDebugWindow(DebugWindow.TilemapViewer);
|
||||
}
|
||||
|
||||
private void mnuTileViewer_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugWindowManager.OpenDebugWindow(DebugWindow.TileViewer);
|
||||
}
|
||||
|
||||
private void mnuPaletteViewer_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugWindowManager.OpenDebugWindow(DebugWindow.PaletteViewer);
|
||||
|
|
|
@ -79,6 +79,14 @@ namespace Mesen.GUI
|
|||
return buffer;
|
||||
}
|
||||
|
||||
[DllImport(DllPath, EntryPoint = "GetTileView")] private static extern void GetTileViewWrapper(GetTileViewOptions options, [In, Out] byte[] buffer);
|
||||
public static byte[] GetTileView(GetTileViewOptions options)
|
||||
{
|
||||
byte[] buffer = new byte[512 * 512 * 4];
|
||||
DebugApi.GetTileViewWrapper(options, buffer);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
[DllImport(DllPath)] public static extern void SetViewerUpdateTiming(Int32 viewerId, Int32 scanline, Int32 cycle);
|
||||
|
||||
[DllImport(DllPath)] private static extern UInt32 GetDebugEventCount([MarshalAs(UnmanagedType.I1)]bool getPreviousFrameData);
|
||||
|
@ -286,6 +294,27 @@ namespace Mesen.GUI
|
|||
[MarshalAs(UnmanagedType.I1)] public bool ShowScrollOverlay;
|
||||
}
|
||||
|
||||
public struct GetTileViewOptions
|
||||
{
|
||||
public TileFormat Format;
|
||||
public Int32 Width;
|
||||
public Int32 Palette;
|
||||
public SnesMemoryType MemoryType;
|
||||
public Int32 AddressOffset;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowTileGrid;
|
||||
}
|
||||
|
||||
public enum TileFormat
|
||||
{
|
||||
Bpp2,
|
||||
Bpp4,
|
||||
Bpp8,
|
||||
DirectColor,
|
||||
Mode7,
|
||||
Mode7DirectColor,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public struct InteropTraceLoggerOptions
|
||||
{
|
||||
|
|
18
UI/UI.csproj
18
UI/UI.csproj
|
@ -414,6 +414,12 @@
|
|||
<DependentUpon>frmMemoryTools.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\GraphicsExtensions.cs" />
|
||||
<Compile Include="Debugger\PpuViewer\ctrlPaletteViewer.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\ctrlPaletteViewer.Designer.cs">
|
||||
<DependentUpon>ctrlPaletteViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\ctrlScanlineCycleSelect.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -426,6 +432,12 @@
|
|||
<Compile Include="Debugger\PpuViewer\frmPaletteViewer.Designer.cs">
|
||||
<DependentUpon>frmPaletteViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\frmTileViewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\frmTileViewer.Designer.cs">
|
||||
<DependentUpon>frmTileViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\PpuViewer\frmTilemapViewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -712,12 +724,18 @@
|
|||
<EmbeddedResource Include="Debugger\frmMemoryTools.resx">
|
||||
<DependentUpon>frmMemoryTools.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\ctrlPaletteViewer.resx">
|
||||
<DependentUpon>ctrlPaletteViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\ctrlScanlineCycleSelect.resx">
|
||||
<DependentUpon>ctrlScanlineCycleSelect.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\frmPaletteViewer.resx">
|
||||
<DependentUpon>frmPaletteViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\frmTileViewer.resx">
|
||||
<DependentUpon>frmTileViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\PpuViewer\frmTilemapViewer.resx">
|
||||
<DependentUpon>frmTilemapViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
Loading…
Add table
Reference in a new issue