Debugger: Added hex editor

This commit is contained in:
Sour 2019-02-15 21:33:13 -05:00
parent 829f4e23c9
commit 6d22b920b8
79 changed files with 11834 additions and 188 deletions

47
Core/BaseCartridge.h Normal file
View file

@ -0,0 +1,47 @@
#pragma once
#include "stdafx.h"
#include "IMemoryHandler.h"
#include "../Utilities/VirtualFile.h"
class BaseCartridge : public IMemoryHandler
{
private:
uint8_t* _prgRom = nullptr;
uint8_t* _saveRam = nullptr;
uint32_t _prgRomSize = 0;
uint32_t _saveRamSize = 0;
public:
static shared_ptr<BaseCartridge> CreateCartridge(VirtualFile romFile, VirtualFile patchFile)
{
if(romFile.IsValid()) {
vector<uint8_t> romData;
romFile.ReadFile(romData);
shared_ptr<BaseCartridge> cart(new BaseCartridge());
cart->_prgRomSize = (uint32_t)romData.size();
cart->_prgRom = new uint8_t[cart->_prgRomSize];
memcpy(cart->_prgRom, romData.data(), cart->_prgRomSize);
return cart;
} else {
return nullptr;
}
}
uint8_t Read(uint32_t addr) override
{
uint8_t bank = (addr >> 16) & 0x7F;
return _prgRom[((bank * 0x8000) | (addr & 0x7FFF)) & (_prgRomSize - 1)];
}
void Write(uint32_t addr, uint8_t value) override
{
}
uint8_t* DebugGetPrgRom() { return _prgRom; }
uint8_t* DebugGetSaveRam() { return _saveRam; }
uint32_t DebugGetPrgRomSize() { return _prgRomSize; }
uint32_t DebugGetSaveRamSize() { return _saveRamSize; }
};

View file

@ -3,6 +3,7 @@
#include "Cpu.h"
#include "MemoryManager.h"
#include "Debugger.h"
#include "NotificationManager.h"
#include "VideoDecoder.h"
#include "VideoRenderer.h"
#include "DebugHud.h"
@ -11,6 +12,7 @@
void Console::Initialize()
{
_notificationManager.reset(new NotificationManager());
_videoDecoder.reset(new VideoDecoder(shared_from_this()));
_videoRenderer.reset(new VideoRenderer(shared_from_this()));
_debugHud.reset(new DebugHud());
@ -57,12 +59,12 @@ void Console::LoadRom(VirtualFile romFile, VirtualFile patchFile)
shared_ptr<BaseCartridge> cart = BaseCartridge::CreateCartridge(romFile, patchFile);
if(cart) {
_ppu.reset(new Ppu(shared_from_this()));
_cart = cart;
_memoryManager.reset(new MemoryManager());
_memoryManager->Initialize(cart, shared_from_this());
_cpu.reset(new Cpu(_memoryManager));
_debugger.reset(new Debugger(_cpu, _ppu, _memoryManager));
_debugger.reset(new Debugger(shared_from_this()));
}
}
@ -76,6 +78,11 @@ shared_ptr<VideoDecoder> Console::GetVideoDecoder()
return _videoDecoder;
}
shared_ptr<NotificationManager> Console::GetNotificationManager()
{
return _notificationManager;
}
shared_ptr<DebugHud> Console::GetDebugHud()
{
return _debugHud;
@ -91,6 +98,11 @@ shared_ptr<Ppu> Console::GetPpu()
return _ppu;
}
shared_ptr<BaseCartridge> Console::GetCartridge()
{
return _cart;
}
shared_ptr<MemoryManager> Console::GetMemoryManager()
{
return _memoryManager;

View file

@ -5,11 +5,13 @@
class Cpu;
class Ppu;
class BaseCartridge;
class MemoryManager;
class Debugger;
class DebugHud;
class VideoRenderer;
class VideoDecoder;
class NotificationManager;
enum class MemoryOperationType;
class Console : public std::enable_shared_from_this<Console>
@ -18,8 +20,10 @@ private:
shared_ptr<Cpu> _cpu;
shared_ptr<Ppu> _ppu;
shared_ptr<MemoryManager> _memoryManager;
shared_ptr<BaseCartridge> _cart;
shared_ptr<Debugger> _debugger;
shared_ptr<NotificationManager> _notificationManager;
shared_ptr<VideoRenderer> _videoRenderer;
shared_ptr<VideoDecoder> _videoDecoder;
shared_ptr<DebugHud> _debugHud;
@ -37,10 +41,13 @@ public:
shared_ptr<VideoRenderer> GetVideoRenderer();
shared_ptr<VideoDecoder> GetVideoDecoder();
shared_ptr<NotificationManager> GetNotificationManager();
shared_ptr<DebugHud> GetDebugHud();
shared_ptr<Cpu> GetCpu();
shared_ptr<Ppu> GetPpu();
shared_ptr<BaseCartridge> GetCartridge();
shared_ptr<MemoryManager> GetMemoryManager();
shared_ptr<Debugger> GetDebugger(bool allowStart = true);

View file

@ -43,6 +43,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="BaseCartridge.h" />
<ClInclude Include="BaseRenderer.h" />
<ClInclude Include="BaseSoundManager.h" />
<ClInclude Include="BaseVideoFilter.h" />
@ -51,6 +52,7 @@
<ClInclude Include="CpuTypes.h" />
<ClInclude Include="Debugger.h" />
<ClInclude Include="DebugHud.h" />
<ClInclude Include="DebugTypes.h" />
<ClInclude Include="DefaultVideoFilter.h" />
<ClInclude Include="DisassemblyInfo.h" />
<ClInclude Include="DmaController.h" />
@ -64,12 +66,15 @@
<ClInclude Include="IInputProvider.h" />
<ClInclude Include="IInputRecorder.h" />
<ClInclude Include="IKeyManager.h" />
<ClInclude Include="IMemoryHandler.h" />
<ClInclude Include="IMessageManager.h" />
<ClInclude Include="INotificationListener.h" />
<ClInclude Include="IRenderingDevice.h" />
<ClInclude Include="KeyManager.h" />
<ClInclude Include="MemoryDumper.h" />
<ClInclude Include="MemoryManager.h" />
<ClInclude Include="MessageManager.h" />
<ClInclude Include="NotificationManager.h" />
<ClInclude Include="Ppu.h" />
<ClInclude Include="PpuTypes.h" />
<ClInclude Include="SettingTypes.h" />
@ -91,7 +96,9 @@
<ClCompile Include="DisassemblyInfo.cpp" />
<ClCompile Include="DmaController.cpp" />
<ClCompile Include="KeyManager.cpp" />
<ClCompile Include="MemoryDumper.cpp" />
<ClCompile Include="MessageManager.cpp" />
<ClCompile Include="NotificationManager.cpp" />
<ClCompile Include="Ppu.cpp" />
<ClCompile Include="stdafx.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>

View file

@ -101,6 +101,21 @@
<ClInclude Include="DmaController.h">
<Filter>SNES</Filter>
</ClInclude>
<ClInclude Include="MemoryDumper.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="DebugTypes.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="BaseCartridge.h">
<Filter>SNES</Filter>
</ClInclude>
<ClInclude Include="IMemoryHandler.h">
<Filter>Interfaces</Filter>
</ClInclude>
<ClInclude Include="NotificationManager.h">
<Filter>Misc</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp" />
@ -155,6 +170,12 @@
<ClCompile Include="DmaController.cpp">
<Filter>SNES</Filter>
</ClCompile>
<ClCompile Include="MemoryDumper.cpp">
<Filter>Debugger</Filter>
</ClCompile>
<ClCompile Include="NotificationManager.cpp">
<Filter>Misc</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="SNES">

13
Core/DebugTypes.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#include "stdafx.h"
enum class SnesMemoryType
{
CpuMemory,
PrgRom,
WorkRam,
SaveRam,
VideoRam,
SpriteRam,
CGRam,
};

View file

@ -1,18 +1,22 @@
#include "stdafx.h"
#include "Debugger.h"
#include "Console.h"
#include "Cpu.h"
#include "Ppu.h"
#include "CpuTypes.h"
#include "DisassemblyInfo.h"
#include "TraceLogger.h"
#include "MemoryDumper.h"
#include "../Utilities/HexUtilities.h"
Debugger::Debugger(shared_ptr<Cpu> cpu, shared_ptr<Ppu> ppu, shared_ptr<MemoryManager> memoryManager)
Debugger::Debugger(shared_ptr<Console> console)
{
_cpu = cpu;
_ppu = ppu;
_memoryManager = memoryManager;
_traceLogger.reset(new TraceLogger(this, memoryManager));
_cpu = console->GetCpu();
_ppu = console->GetPpu();
_memoryManager = console->GetMemoryManager();
_traceLogger.reset(new TraceLogger(this, _memoryManager));
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, console->GetCartridge()));
_cpuStepCount = 0;
}
@ -73,3 +77,8 @@ shared_ptr<TraceLogger> Debugger::GetTraceLogger()
{
return _traceLogger;
}
shared_ptr<MemoryDumper> Debugger::GetMemoryDumper()
{
return _memoryDumper;
}

View file

@ -3,12 +3,15 @@
#include "CpuTypes.h"
#include "PpuTypes.h"
class Console;
class Cpu;
class Ppu;
class BaseCartridge;
class MemoryManager;
enum class MemoryOperationType;
class TraceLogger;
class MemoryDumper;
//class Disassembler;
struct DebugState
@ -24,14 +27,16 @@ private:
shared_ptr<Cpu> _cpu;
shared_ptr<Ppu> _ppu;
shared_ptr<MemoryManager> _memoryManager;
shared_ptr<BaseCartridge> _baseCartridge;
shared_ptr<TraceLogger> _traceLogger;
shared_ptr<MemoryDumper> _memoryDumper;
//unique_ptr<Disassembler> _disassembler;
atomic<int32_t> _cpuStepCount;
public:
Debugger(shared_ptr<Cpu> cpu, shared_ptr<Ppu> ppu, shared_ptr<MemoryManager> memoryManager);
Debugger(shared_ptr<Console> console);
~Debugger();
void ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType type);
@ -44,4 +49,5 @@ public:
void GetState(DebugState *state);
shared_ptr<TraceLogger> GetTraceLogger();
shared_ptr<MemoryDumper> GetMemoryDumper();
};

14
Core/IMemoryHandler.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include "stdafx.h"
class IMemoryHandler
{
public:
virtual uint8_t Read(uint32_t addr) = 0;
virtual void Write(uint32_t addr, uint8_t value) = 0;
//virtual void GetMemoryRanges(MemoryRanges &ranges) = 0;
//virtual uint8_t PeekRAM(uint16_t addr) { return 0; }
virtual ~IMemoryHandler() {}
};

View file

@ -10,12 +10,12 @@ enum class ConsoleNotificationType
GameResumed = 4,
GameStopped = 5,
CodeBreak = 6,
PpuFrameDone = 9,
ResolutionChanged = 11,
ConfigChanged = 13,
ExecuteShortcut = 16,
EmulationStopped = 17,
BeforeEmulationStop = 19,
PpuFrameDone = 7,
ResolutionChanged = 8,
ConfigChanged = 9,
ExecuteShortcut = 10,
EmulationStopped = 11,
BeforeEmulationStop = 12,
};
class INotificationListener

113
Core/MemoryDumper.cpp Normal file
View file

@ -0,0 +1,113 @@
#include "stdafx.h"
#include "Debugger.h"
#include "MemoryManager.h"
#include "Ppu.h"
#include "MemoryDumper.h"
#include "BaseCartridge.h"
#include "VideoDecoder.h"
#include "DebugTypes.h"
MemoryDumper::MemoryDumper(shared_ptr<Ppu> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseCartridge> cartridge)
{
_ppu = ppu;
_memoryManager = memoryManager;
_cartridge = cartridge;
}
void MemoryDumper::SetMemoryState(SnesMemoryType type, uint8_t *buffer, uint32_t length)
{
if(length > GetMemorySize(type)) {
return;
}
switch(type) {
case SnesMemoryType::CpuMemory:
break;
case SnesMemoryType::PrgRom: memcpy(_cartridge->DebugGetPrgRom(), buffer, length); break;
case SnesMemoryType::WorkRam: memcpy(_memoryManager->DebugGetWorkRam(), buffer, length); break;
case SnesMemoryType::SaveRam: memcpy(_cartridge->DebugGetSaveRam(), buffer, length); break;
case SnesMemoryType::VideoRam: memcpy(_ppu->GetVideoRam(), buffer, length); break;
case SnesMemoryType::SpriteRam: memcpy(_ppu->GetSpriteRam(), buffer, length); break;
case SnesMemoryType::CGRam: memcpy(_ppu->GetCgRam(), buffer, length); break;
}
}
uint32_t MemoryDumper::GetMemorySize(SnesMemoryType type)
{
switch(type) {
case SnesMemoryType::CpuMemory: return 0x1000000;
case SnesMemoryType::PrgRom: return _cartridge->DebugGetPrgRomSize();
case SnesMemoryType::WorkRam: return MemoryManager::WorkRamSize;
case SnesMemoryType::SaveRam: return _cartridge->DebugGetSaveRamSize();
case SnesMemoryType::VideoRam: return Ppu::VideoRamSize;
case SnesMemoryType::SpriteRam: return Ppu::SpriteRamSize;
case SnesMemoryType::CGRam: return Ppu::CgRamSize;
}
return 0;
}
void MemoryDumper::GetMemoryState(SnesMemoryType type, uint8_t *buffer)
{
switch(type) {
case SnesMemoryType::CpuMemory:
for(int i = 0; i <= 0xFFFFFF; i++) {
buffer[i] = _memoryManager->Peek(i);
}
break;
case SnesMemoryType::PrgRom: memcpy(buffer, _cartridge->DebugGetPrgRom(), _cartridge->DebugGetPrgRomSize()); break;
case SnesMemoryType::WorkRam: memcpy(buffer, _memoryManager->DebugGetWorkRam(), MemoryManager::WorkRamSize); break;
case SnesMemoryType::SaveRam: memcpy(buffer, _cartridge->DebugGetSaveRam(), _cartridge->DebugGetSaveRamSize()); break;
case SnesMemoryType::VideoRam: memcpy(buffer, _ppu->GetVideoRam(), Ppu::VideoRamSize); break;
case SnesMemoryType::SpriteRam: memcpy(buffer, _ppu->GetSpriteRam(), Ppu::SpriteRamSize); break;
case SnesMemoryType::CGRam: memcpy(buffer, _ppu->GetCgRam(), Ppu::CgRamSize); break;
}
}
void MemoryDumper::SetMemoryValues(SnesMemoryType memoryType, uint32_t address, uint8_t* data, uint32_t length)
{
for(uint32_t i = 0; i < length; i++) {
SetMemoryValue(memoryType, address+i, data[i], true);
}
}
void MemoryDumper::SetMemoryValue(SnesMemoryType memoryType, uint32_t address, uint8_t value, bool disableSideEffects)
{
if(address >= GetMemorySize(memoryType)) {
return;
}
switch(memoryType) {
case SnesMemoryType::CpuMemory: _memoryManager->Write(address, value, MemoryOperationType::Write); break;
case SnesMemoryType::PrgRom: _cartridge->DebugGetPrgRom()[address] = value; break;
case SnesMemoryType::WorkRam: _memoryManager->DebugGetWorkRam()[address] = value; break;
case SnesMemoryType::SaveRam: _cartridge->DebugGetSaveRam()[address] = value; break;
case SnesMemoryType::VideoRam: _ppu->GetVideoRam()[address & (Ppu::VideoRamSize - 1)] = value;
case SnesMemoryType::SpriteRam: _ppu->GetSpriteRam()[address % Ppu::SpriteRamSize] = value; break;
case SnesMemoryType::CGRam: _ppu->GetCgRam()[address & (Ppu::CgRamSize - 1)] = value; break;
}
}
uint8_t MemoryDumper::GetMemoryValue(SnesMemoryType memoryType, uint32_t address, bool disableSideEffects)
{
if(address >= GetMemorySize(memoryType)) {
return 0;
}
switch(memoryType) {
case SnesMemoryType::CpuMemory: return _memoryManager->Peek(address);
case SnesMemoryType::PrgRom: return _cartridge->DebugGetPrgRom()[address];
case SnesMemoryType::WorkRam: return _memoryManager->DebugGetWorkRam()[address];
case SnesMemoryType::SaveRam: return _cartridge->DebugGetSaveRam()[address];
case SnesMemoryType::VideoRam: return _ppu->GetVideoRam()[address & (Ppu::VideoRamSize - 1)];
case SnesMemoryType::SpriteRam: return _ppu->GetSpriteRam()[address % Ppu::SpriteRamSize];
case SnesMemoryType::CGRam: return _ppu->GetCgRam()[address & (Ppu::CgRamSize - 1)];
}
return 0;
}

28
Core/MemoryDumper.h Normal file
View file

@ -0,0 +1,28 @@
#pragma once
#include "stdafx.h"
#include <unordered_map>
#include "DebugTypes.h"
class MemoryManager;
class BaseCartridge;
class Ppu;
enum class SnesMemoryType;
class MemoryDumper
{
private:
shared_ptr<Ppu> _ppu;
shared_ptr<MemoryManager> _memoryManager;
shared_ptr<BaseCartridge> _cartridge;
public:
MemoryDumper(shared_ptr<Ppu> ppu, shared_ptr<MemoryManager> memoryManager, shared_ptr<BaseCartridge> cartridge);
uint32_t GetMemorySize(SnesMemoryType type);
void GetMemoryState(SnesMemoryType type, uint8_t *buffer);
uint8_t GetMemoryValue(SnesMemoryType memoryType, uint32_t address, bool disableSideEffects = true);
void SetMemoryValue(SnesMemoryType memoryType, uint32_t address, uint8_t value, bool disableSideEffects = true);
void SetMemoryValues(SnesMemoryType memoryType, uint32_t address, uint8_t* data, uint32_t length);
void SetMemoryState(SnesMemoryType type, uint8_t *buffer, uint32_t length);
};

View file

@ -3,55 +3,9 @@
#include "Console.h"
#include "Ppu.h"
#include "DmaController.h"
#include "BaseCartridge.h"
#include "IMemoryHandler.h"
#include "../Utilities/HexUtilities.h"
#include "../Utilities/VirtualFile.h"
class IMemoryHandler
{
public:
virtual uint8_t Read(uint32_t addr) = 0;
virtual void Write(uint32_t addr, uint8_t value) = 0;
//virtual void GetMemoryRanges(MemoryRanges &ranges) = 0;
//virtual uint8_t PeekRAM(uint16_t addr) { return 0; }
virtual ~IMemoryHandler() {}
};
class BaseCartridge : public IMemoryHandler
{
private:
size_t _prgRomSize;
uint8_t* _prgRom;
public:
static shared_ptr<BaseCartridge> CreateCartridge(VirtualFile romFile, VirtualFile patchFile)
{
if(romFile.IsValid()) {
vector<uint8_t> romData;
romFile.ReadFile(romData);
shared_ptr<BaseCartridge> cart(new BaseCartridge());
cart->_prgRomSize = romData.size();
cart->_prgRom = new uint8_t[cart->_prgRomSize];
memcpy(cart->_prgRom, romData.data(), cart->_prgRomSize);
return cart;
} else {
return nullptr;
}
}
uint8_t Read(uint32_t addr) override
{
uint8_t bank = (addr >> 16) & 0x7F;
return _prgRom[((bank * 0x8000) | (addr & 0x7FFF)) & (_prgRomSize - 1)];
}
void Write(uint32_t addr, uint8_t value) override
{
}
};
class CpuRegisterHandler : public IMemoryHandler
{
@ -104,6 +58,9 @@ public:
class MemoryManager
{
public:
constexpr static uint32_t WorkRamSize = 0x20000;
private:
shared_ptr<Console> _console;
@ -133,7 +90,7 @@ public:
_cpuRegisterHandler.reset(new CpuRegisterHandler(console));
memset(_handlers, 0, sizeof(_handlers));
_workRam = new uint8_t[128 * 1024];
_workRam = new uint8_t[MemoryManager::WorkRamSize];
//memset(_workRam, 0, 128 * 1024);
for(uint32_t i = 0; i < 128 * 1024; i += 0x1000) {
@ -270,4 +227,6 @@ public:
//std::cout << "Write - missing handler: $" << HexUtilities::ToHex(addr) << " = " << HexUtilities::ToHex(value) << std::endl;
}
}
uint8_t* DebugGetWorkRam() { return _workRam; }
};

View file

@ -0,0 +1,50 @@
#include "stdafx.h"
#include <algorithm>
#include "NotificationManager.h"
void NotificationManager::RegisterNotificationListener(shared_ptr<INotificationListener> notificationListener)
{
auto lock = _lock.AcquireSafe();
for(weak_ptr<INotificationListener> listener : _listeners) {
if(listener.lock() == notificationListener) {
//This listener is already registered, do nothing
return;
}
}
_listeners.push_back(notificationListener);
}
void NotificationManager::CleanupNotificationListeners()
{
auto lock = _lock.AcquireSafe();
//Remove expired listeners
_listeners.erase(
std::remove_if(
_listeners.begin(),
_listeners.end(),
[](weak_ptr<INotificationListener> ptr) { return ptr.expired(); }
),
_listeners.end()
);
}
void NotificationManager::SendNotification(ConsoleNotificationType type, void* parameter)
{
vector<weak_ptr<INotificationListener>> listeners;
{
auto lock = _lock.AcquireSafe();
CleanupNotificationListeners();
listeners = _listeners;
}
//Iterate on a copy without using a lock
for(weak_ptr<INotificationListener> notificationListener : listeners) {
shared_ptr<INotificationListener> listener = notificationListener.lock();
if(listener) {
listener->ProcessNotification(type, parameter);
}
}
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "stdafx.h"
#include "INotificationListener.h"
#include "../Utilities/SimpleLock.h"
class NotificationManager
{
private:
SimpleLock _lock;
vector<weak_ptr<INotificationListener>> _listenersToAdd;
vector<weak_ptr<INotificationListener>> _listeners;
void CleanupNotificationListeners();
public:
void RegisterNotificationListener(shared_ptr<INotificationListener> notificationListener);
void SendNotification(ConsoleNotificationType type, void* parameter = nullptr);
};

View file

@ -4,13 +4,14 @@
#include "MemoryManager.h"
#include "Cpu.h"
#include "VideoDecoder.h"
#include "NotificationManager.h"
Ppu::Ppu(shared_ptr<Console> console)
{
_console = console;
_vram = new uint8_t[0x10000];
memset(_vram, 0, 0x10000);
_vram = new uint8_t[Ppu::VideoRamSize];
memset(_vram, 0, Ppu::VideoRamSize);
_layerConfig[0] = {};
_layerConfig[1] = {};
@ -95,10 +96,26 @@ void Ppu::SendFrame()
}
}
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::PpuFrameDone);
_currentBuffer = _currentBuffer == _outputBuffers[0] ? _outputBuffers[1] : _outputBuffers[0];
_console->GetVideoDecoder()->UpdateFrame(_currentBuffer, _frameCount);
}
uint8_t* Ppu::GetVideoRam()
{
return _vram;
}
uint8_t* Ppu::GetCgRam()
{
return _cgram;
}
uint8_t* Ppu::GetSpriteRam()
{
return _spriteRam;
}
uint8_t Ppu::Read(uint16_t addr)
{
switch(addr) {

View file

@ -6,6 +6,11 @@ class Console;
class Ppu
{
public:
constexpr static uint32_t SpriteRamSize = 544;
constexpr static uint32_t CgRamSize = 512;
constexpr static uint32_t VideoRamSize = 0x10000;
private:
shared_ptr<Console> _console;
@ -22,7 +27,9 @@ private:
bool _vramAddrIncrementOnSecondReg;
uint16_t _cgramAddress;
uint8_t _cgram[512];
uint8_t _cgram[Ppu::CgRamSize];
uint8_t _spriteRam[Ppu::SpriteRamSize];
uint16_t *_outputBuffers[2];
uint16_t *_currentBuffer;
@ -39,6 +46,10 @@ public:
void SendFrame();
uint8_t* GetVideoRam();
uint8_t* GetCgRam();
uint8_t* GetSpriteRam();
uint8_t Read(uint16_t addr);
void Write(uint32_t addr, uint8_t value);
};

View file

@ -17,6 +17,7 @@
#include <list>
#include <atomic>
#include <thread>
#include <deque>
#include "../Utilities/UTF8Util.h"
@ -44,6 +45,7 @@ using std::string;
using std::atomic_flag;
using std::atomic;
using std::thread;
using std::deque;
#ifdef _DEBUG
#pragma comment(lib, "C:\\Code\\Mesen-S\\bin\\x64\\Debug\\Utilities.lib")

View file

@ -2,6 +2,8 @@
#include "../Core/Console.h"
#include "../Core/Debugger.h"
#include "../Core/TraceLogger.h"
#include "../Core/MemoryDumper.h"
#include "../Core/DebugTypes.h"
extern shared_ptr<Console> _console;
shared_ptr<Debugger> _debugger;
@ -45,4 +47,11 @@ extern "C"
DllExport const char* GetExecutionTrace(uint32_t lineCount) { return GetDebugger()->GetTraceLogger()->GetExecutionTrace(lineCount); }
DllExport void __stdcall GetState(DebugState *state) { GetDebugger()->GetState(state); }
DllExport void __stdcall SetMemoryState(SnesMemoryType type, uint8_t *buffer, int32_t length) { GetDebugger()->GetMemoryDumper()->SetMemoryState(type, buffer, length); }
DllExport uint32_t __stdcall GetMemorySize(SnesMemoryType type) { return GetDebugger()->GetMemoryDumper()->GetMemorySize(type); }
DllExport void __stdcall GetMemoryState(SnesMemoryType type, uint8_t *buffer) { GetDebugger()->GetMemoryDumper()->GetMemoryState(type, buffer); }
DllExport uint8_t __stdcall GetMemoryValue(SnesMemoryType type, uint32_t address) { return GetDebugger()->GetMemoryDumper()->GetMemoryValue(type, address); }
DllExport void __stdcall SetMemoryValue(SnesMemoryType type, uint32_t address, uint8_t value) { return GetDebugger()->GetMemoryDumper()->SetMemoryValue(type, address, value); }
DllExport void __stdcall SetMemoryValues(SnesMemoryType type, uint32_t address, uint8_t* data, int32_t length) { return GetDebugger()->GetMemoryDumper()->SetMemoryValues(type, address, data, length); }
};

View file

@ -3,8 +3,8 @@
#include "../Core/MessageManager.h"
#include "../Core/INotificationListener.h"
#include "../Core/KeyManager.h"
#include "../Utilities/SimpleLock.h"
#include "../Utilities/ArchiveReader.h"
#include "InteropNotificationListeners.h"
#ifdef _WIN32
#include "../Windows/Renderer.h"
@ -26,31 +26,9 @@ void* _viewerHandle = nullptr;
string _returnString;
string _logString;
shared_ptr<Console> _console;
SimpleLock _externalNotificationListenerLock;
vector<shared_ptr<INotificationListener>> _externalNotificationListeners;
typedef void (__stdcall *NotificationListenerCallback)(int, void*);
InteropNotificationListeners _listeners;
namespace InteropEmu {
class InteropNotificationListener : public INotificationListener
{
NotificationListenerCallback _callback;
public:
InteropNotificationListener(NotificationListenerCallback callback)
{
_callback = callback;
}
virtual ~InteropNotificationListener()
{
}
void ProcessNotification(ConsoleNotificationType type, void* parameter)
{
_callback((int)type, parameter);
}
};
extern "C" {
DllExport bool __stdcall TestDll()
{
@ -192,24 +170,12 @@ namespace InteropEmu {
DllExport INotificationListener* __stdcall RegisterNotificationCallback(NotificationListenerCallback callback)
{
auto lock = _externalNotificationListenerLock.AcquireSafe();
auto listener = shared_ptr<INotificationListener>(new InteropNotificationListener(callback));
_externalNotificationListeners.push_back(listener);
//_console->GetNotificationManager()->RegisterNotificationListener(listener);
return listener.get();
return _listeners.RegisterNotificationCallback(callback, _console);
}
DllExport void __stdcall UnregisterNotificationCallback(INotificationListener *listener)
{
auto lock = _externalNotificationListenerLock.AcquireSafe();
_externalNotificationListeners.erase(
std::remove_if(
_externalNotificationListeners.begin(),
_externalNotificationListeners.end(),
[=](shared_ptr<INotificationListener> ptr) { return ptr.get() == listener; }
),
_externalNotificationListeners.end()
);
_listeners.UnregisterNotificationCallback(listener);
}
DllExport void __stdcall DisplayMessage(char* title, char* message, char* param1) { MessageManager::DisplayMessage(title, message, param1 ? param1 : ""); }

View file

@ -448,6 +448,8 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="InteropNotificationListeners.h" />
<ClInclude Include="InteropNotificationListener.h" />
<ClInclude Include="stdafx.h" />
</ItemGroup>
<ItemGroup>

View file

@ -14,6 +14,12 @@
<ClInclude Include="stdafx.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InteropNotificationListener.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InteropNotificationListeners.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">

View file

@ -0,0 +1,26 @@
#pragma once
#include "stdafx.h"
#include "../Core/INotificationListener.h"
#include "../Core/NotificationManager.h"
typedef void(__stdcall *NotificationListenerCallback)(int, void*);
class InteropNotificationListener : public INotificationListener
{
NotificationListenerCallback _callback;
public:
InteropNotificationListener(NotificationListenerCallback callback)
{
_callback = callback;
}
virtual ~InteropNotificationListener()
{
}
void ProcessNotification(ConsoleNotificationType type, void* parameter)
{
_callback((int)type, parameter);
}
};

View file

@ -0,0 +1,38 @@
#pragma once
#include "stdafx.h"
#include "../Core/INotificationListener.h"
#include "../Core/NotificationManager.h"
#include "../Core/Console.h"
#include "../Utilities/SimpleLock.h"
#include "InteropNotificationListener.h"
typedef void(__stdcall *NotificationListenerCallback)(int, void*);
class InteropNotificationListeners
{
SimpleLock _externalNotificationListenerLock;
vector<shared_ptr<INotificationListener>> _externalNotificationListeners;
public:
INotificationListener* RegisterNotificationCallback(NotificationListenerCallback callback, shared_ptr<Console> console)
{
auto lock = _externalNotificationListenerLock.AcquireSafe();
auto listener = shared_ptr<INotificationListener>(new InteropNotificationListener(callback));
_externalNotificationListeners.push_back(listener);
console->GetNotificationManager()->RegisterNotificationListener(listener);
return listener.get();
}
void UnregisterNotificationCallback(INotificationListener *listener)
{
auto lock = _externalNotificationListenerLock.AcquireSafe();
_externalNotificationListeners.erase(
std::remove_if(
_externalNotificationListeners.begin(),
_externalNotificationListeners.end(),
[=](shared_ptr<INotificationListener> ptr) { return ptr.get() == listener; }
),
_externalNotificationListeners.end()
);
}
};

View file

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using Mesen.GUI.Debugger;
using Mesen.GUI.Controls;
using Mesen.GUI.Utilities;
namespace Mesen.GUI.Config
{
public class DebugInfo
{
public DebuggerShortcutsConfig Shortcuts = new DebuggerShortcutsConfig();
public TraceLoggerInfo TraceLogger = new TraceLoggerInfo();
public HexEditorInfo HexEditor = new HexEditorInfo();
public bool ShowSelectionLength = false;
public XmlColor EventViewerBreakpointColor = ColorTranslator.FromHtml("#1898E4");
public XmlColor CodeOpcodeColor = Color.FromArgb(22, 37, 37);
public XmlColor CodeLabelDefinitionColor = Color.Blue;
public XmlColor CodeImmediateColor = Color.Chocolate;
public XmlColor CodeAddressColor = Color.DarkRed;
public XmlColor CodeCommentColor = Color.Green;
public XmlColor CodeEffectiveAddressColor = Color.SteelBlue;
public DebugInfo()
{
}
}
public enum RefreshSpeed
{
Low = 0,
Normal = 1,
High = 2
}
}

View file

@ -0,0 +1,388 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Windows.Forms;
using Mesen.GUI.Forms;
using static Mesen.GUI.Forms.BaseForm;
namespace Mesen.GUI.Config
{
public class DebuggerShortcutsConfig
{
//Shared
[ShortcutName("Increase Font Size")]
public XmlKeys IncreaseFontSize = Keys.Control | Keys.Oemplus;
[ShortcutName("Decrease Font Size")]
public XmlKeys DecreaseFontSize = Keys.Control | Keys.OemMinus;
[ShortcutName("Reset Font Size")]
public XmlKeys ResetFontSize = Keys.Control | Keys.D0;
[ShortcutName("Go To...")]
public XmlKeys GoTo = Keys.Control | Keys.G;
[ShortcutName("Find")]
public XmlKeys Find = Keys.Control | Keys.F;
[ShortcutName("Find Next")]
public XmlKeys FindNext = Keys.F3;
[ShortcutName("Find Previous")]
public XmlKeys FindPrev = Keys.Shift | Keys.F3;
[ShortcutName("Undo")]
public XmlKeys Undo = Keys.Control | Keys.Z;
[ShortcutName("Copy")]
public XmlKeys Copy = Keys.Control | Keys.C;
[ShortcutName("Cut")]
public XmlKeys Cut = Keys.Control | Keys.X;
[ShortcutName("Paste")]
public XmlKeys Paste = Keys.Control | Keys.V;
[ShortcutName("Select All")]
public XmlKeys SelectAll = Keys.Control | Keys.A;
[ShortcutName("Refresh")]
public XmlKeys Refresh = Keys.F5;
[ShortcutName("Mark Selection as Code")]
public XmlKeys MarkAsCode = Keys.Control | Keys.D1;
[ShortcutName("Mark Selection as Data")]
public XmlKeys MarkAsData = Keys.Control | Keys.D2;
[ShortcutName("Mark Selection as Unidentified Code/Data")]
public XmlKeys MarkAsUnidentified = Keys.Control | Keys.D3;
[ShortcutName("Go to All")]
public XmlKeys GoToAll = Keys.Control | Keys.Oemcomma;
[ShortcutName("PPU Viewer: Toggle View")]
public XmlKeys PpuViewer_ToggleView = Keys.Control | Keys.Q;
[ShortcutName("PPU Viewer: Toggle Zoom")]
public XmlKeys PpuViewer_ToggleZoom = Keys.Control | Keys.W;
[ShortcutName("Edit in Memory Viewer")]
public XmlKeys CodeWindow_EditInMemoryViewer = Keys.F1;
[ShortcutName("View in disassembly")]
public XmlKeys MemoryViewer_ViewInDisassembly = Keys.None;
[ShortcutName("Open APU Viewer")]
public XmlKeys OpenApuViewer = Keys.Control | Keys.U;
[ShortcutName("Open Assembler")]
public XmlKeys OpenAssembler = Keys.Control | Keys.K;
[ShortcutName("Open Debugger")]
public XmlKeys OpenDebugger = Keys.Control | Keys.D;
[ShortcutName("Open Event Viewer")]
public XmlKeys OpenEventViewer = Keys.Control | Keys.E;
[ShortcutName("Open Memory Tools")]
public XmlKeys OpenMemoryTools = Keys.Control | Keys.M;
[ShortcutName("Open PPU Viewer")]
public XmlKeys OpenPpuViewer = Keys.Control | Keys.P;
[ShortcutName("Open Performance Profiler")]
public XmlKeys OpenProfiler = Keys.Control | Keys.Y;
[ShortcutName("Open Script Window")]
public XmlKeys OpenScriptWindow = Keys.Control | Keys.N;
[ShortcutName("Open Trace Logger")]
public XmlKeys OpenTraceLogger = Keys.Control | Keys.J;
[ShortcutName("Open Text Hooker")]
public XmlKeys OpenTextHooker = Keys.Control | Keys.H;
[ShortcutName("Open Watch Window")]
public XmlKeys OpenWatchWindow = Keys.Control | Keys.W;
[ShortcutName("Open Nametabler Viewer (Compact)")]
public XmlKeys OpenNametableViewer = Keys.Control | Keys.D1;
[ShortcutName("Open CHR Viewer (Compact)")]
public XmlKeys OpenChrViewer = Keys.Control | Keys.D2;
[ShortcutName("Open Sprite Viewer (Compact)")]
public XmlKeys OpenSpriteViewer = Keys.Control | Keys.D3;
[ShortcutName("Open Palette Viewer (Compact)")]
public XmlKeys OpenPaletteViewer = Keys.Control | Keys.D4;
//Debugger window
[ShortcutName("Reset")]
public XmlKeys Reset = Keys.Control | Keys.R;
[ShortcutName("Power Cycle")]
public XmlKeys PowerCycle = Keys.Control | Keys.T;
[ShortcutName("Continue")]
public XmlKeys Continue = Keys.F5;
[ShortcutName("Break")]
public XmlKeys Break = Keys.Control | Keys.Alt | Keys.Cancel;
[ShortcutName("Toggle Break/Continue")]
public XmlKeys ToggleBreakContinue = Keys.Escape;
[ShortcutName("Step Into")]
public XmlKeys StepInto = Keys.F11;
[ShortcutName("Step Over")]
public XmlKeys StepOver = Keys.F10;
[ShortcutName("Step Out")]
public XmlKeys StepOut = Keys.Shift | Keys.F11;
[ShortcutName("Step Back")]
public XmlKeys StepBack = Keys.Shift | Keys.F10;
[ShortcutName("Run one CPU Cycle")]
public XmlKeys RunCpuCycle = Keys.None;
[ShortcutName("Run one PPU Cycle")]
public XmlKeys RunPpuCycle = Keys.F6;
[ShortcutName("Run one scanline")]
public XmlKeys RunPpuScanline = Keys.F7;
[ShortcutName("Run one frame")]
public XmlKeys RunPpuFrame = Keys.F8;
[ShortcutName("Break In...")]
public XmlKeys BreakIn = Keys.Control | Keys.B;
[ShortcutName("Break On...")]
public XmlKeys BreakOn = Keys.Alt | Keys.B;
[ShortcutName("Find Occurrences")]
public XmlKeys FindOccurrences = Keys.Control | Keys.Shift | Keys.F;
[ShortcutName("Go To Program Counter")]
public XmlKeys GoToProgramCounter = Keys.Alt | Keys.Multiply;
[ShortcutName("Toggle Verified Data Display")]
public XmlKeys ToggleVerifiedData = Keys.Alt | Keys.D1;
[ShortcutName("Toggle Unidentified Code/Data Display")]
public XmlKeys ToggleUnidentifiedCodeData = Keys.Alt | Keys.D2;
[ShortcutName("Code Window: Set Next Statement")]
public XmlKeys CodeWindow_SetNextStatement = Keys.Control | Keys.Shift | Keys.F10;
[ShortcutName("Code Window: Edit Subroutine")]
public XmlKeys CodeWindow_EditSubroutine = Keys.F4;
[ShortcutName("Code Window: Edit Selected Code")]
public XmlKeys CodeWindow_EditSelectedCode = Keys.None;
[ShortcutName("Code Window: Edit Source File (Source View)")]
public XmlKeys CodeWindow_EditSourceFile = Keys.F4;
[ShortcutName("Code Window: Edit Label")]
public XmlKeys CodeWindow_EditLabel = Keys.F2;
[ShortcutName("Code Window: Navigate Back")]
public XmlKeys CodeWindow_NavigateBack = Keys.Alt | Keys.Left;
[ShortcutName("Code Window: Navigate Forward")]
public XmlKeys CodeWindow_NavigateForward = Keys.Alt | Keys.Right;
[ShortcutName("Code Window: Toggle Breakpoint")]
public XmlKeys CodeWindow_ToggleBreakpoint = Keys.F9;
[ShortcutName("Code Window: Disable/Enable Breakpoint")]
public XmlKeys CodeWindow_DisableEnableBreakpoint = Keys.Control | Keys.F9;
[ShortcutName("Code Window: Switch View (Disassembly / Source View)")]
public XmlKeys CodeWindow_SwitchView = Keys.Control | Keys.Q;
[ShortcutName("Function List: Edit Label")]
public XmlKeys FunctionList_EditLabel = Keys.F2;
[ShortcutName("Function List: Add Breakpoint")]
public XmlKeys FunctionList_AddBreakpoint = Keys.None;
[ShortcutName("Function List: Find Occurrences")]
public XmlKeys FunctionList_FindOccurrences = Keys.None;
[ShortcutName("Label List: Add Label")]
public XmlKeys LabelList_Add = Keys.Insert;
[ShortcutName("Label List: Edit Label")]
public XmlKeys LabelList_Edit = Keys.F2;
[ShortcutName("Label List: Delete Label")]
public XmlKeys LabelList_Delete = Keys.Delete;
[ShortcutName("Label List: Add Breakpoint")]
public XmlKeys LabelList_AddBreakpoint = Keys.None;
[ShortcutName("Label List: Add to Watch")]
public XmlKeys LabelList_AddToWatch = Keys.None;
[ShortcutName("Label List: Find Occurrences")]
public XmlKeys LabelList_FindOccurrences = Keys.None;
[ShortcutName("Label List: View in CPU Memory")]
public XmlKeys LabelList_ViewInCpuMemory = Keys.None;
[ShortcutName("Label List: View in [memory type]")]
public XmlKeys LabelList_ViewInMemoryType = Keys.None;
[ShortcutName("Breakpoint List: Add Breakpoint")]
public XmlKeys BreakpointList_Add = Keys.Insert;
[ShortcutName("Breakpoint List: Edit Breakpoint")]
public XmlKeys BreakpointList_Edit = Keys.F2;
[ShortcutName("Breakpoint List: Go To Location")]
public XmlKeys BreakpointList_GoToLocation = Keys.None;
[ShortcutName("Breakpoint List: Delete Breakpoint")]
public XmlKeys BreakpointList_Delete = Keys.Delete;
[ShortcutName("Watch List: Delete")]
public XmlKeys WatchList_Delete = Keys.Delete;
[ShortcutName("Watch List: Move Up")]
public XmlKeys WatchList_MoveUp = Keys.Control | Keys.Up;
[ShortcutName("Watch List: Move Down")]
public XmlKeys WatchList_MoveDown = Keys.Control | Keys.Down;
[ShortcutName("Save Rom")]
public XmlKeys SaveRom = Keys.Control | Keys.S;
[ShortcutName("Save Rom As...")]
public XmlKeys SaveRomAs = Keys.None;
[ShortcutName("Save edits as IPS patch...")]
public XmlKeys SaveEditAsIps = Keys.None;
[ShortcutName("Revert PRG/CHR changes")]
public XmlKeys RevertPrgChrChanges = Keys.None;
//Memory Tools
[ShortcutName("Freeze")]
public XmlKeys MemoryViewer_Freeze = Keys.Control | Keys.Q;
[ShortcutName("Unfreeze")]
public XmlKeys MemoryViewer_Unfreeze = Keys.Control | Keys.W;
[ShortcutName("Add to Watch")]
public XmlKeys MemoryViewer_AddToWatch = Keys.None;
[ShortcutName("Edit Breakpoint")]
public XmlKeys MemoryViewer_EditBreakpoint = Keys.None;
[ShortcutName("Edit Label")]
public XmlKeys MemoryViewer_EditLabel = Keys.None;
[ShortcutName("Import")]
public XmlKeys MemoryViewer_Import = Keys.Control | Keys.O;
[ShortcutName("Export")]
public XmlKeys MemoryViewer_Export = Keys.Control | Keys.S;
[ShortcutName("View in CPU/PPU Memory")]
public XmlKeys MemoryViewer_ViewInCpuMemory = Keys.None;
[ShortcutName("View in [memory type]")]
public XmlKeys MemoryViewer_ViewInMemoryType = Keys.None;
//Script Window
[ShortcutName("Open Script")]
public XmlKeys ScriptWindow_OpenScript = Keys.Control | Keys.N;
[ShortcutName("Save Script")]
public XmlKeys ScriptWindow_SaveScript = Keys.Control | Keys.S;
[ShortcutName("Run Script")]
public XmlKeys ScriptWindow_RunScript = Keys.F5;
[ShortcutName("Stop Script")]
public XmlKeys ScriptWindow_StopScript = Keys.Escape;
public static string GetShortcutDisplay(Keys keys)
{
if(keys == Keys.None) {
return "";
} else {
string keyString = new KeysConverter().ConvertToString(keys);
return keyString.Replace("+None", "").Replace("Oemcomma", ",").Replace("Oemplus", "+").Replace("Oemtilde", "Tilde").Replace("OemMinus", "-").Replace("Cancel", "Break").Replace("Escape", "Esc");
}
}
private static Dictionary<WeakReference<ToolStripMenuItem>, string> _bindings = new Dictionary<WeakReference<ToolStripMenuItem>, string>();
private static Dictionary<WeakReference<ToolStripMenuItem>, WeakReference<Control>> _parents = new Dictionary<WeakReference<ToolStripMenuItem>, WeakReference<Control>>();
public static void RegisterMenuItem(ToolStripMenuItem item, Control parent, string fieldName)
{
var weakRef = new WeakReference<ToolStripMenuItem>(item);
_bindings[weakRef] = fieldName;
_parents[weakRef] = new WeakReference<Control>(parent);
//Remove old references
var dictCopy = new Dictionary<WeakReference<ToolStripMenuItem>, string>(_bindings);
//Iterate on a copy to avoid "collection was modified" error
foreach(var kvp in dictCopy) {
ToolStripMenuItem menuItem;
if(!kvp.Key.TryGetTarget(out menuItem)) {
_bindings.Remove(kvp.Key);
_parents.Remove(kvp.Key);
}
}
}
public static void UpdateMenus()
{
foreach(WeakReference<ToolStripMenuItem> itemRef in _bindings.Keys) {
ToolStripMenuItem item;
if(itemRef.TryGetTarget(out item)) {
string fieldName = _bindings[itemRef];
Control parent;
_parents[itemRef].TryGetTarget(out parent);
if(parent != null) {
UpdateShortcutItem(item, parent, fieldName);
}
}
}
}
public static void ClearProcessCmdKeyHandler(ToolStripMenuItem item, Control parent)
{
Form parentForm = parent.FindForm();
if(parentForm is BaseForm) {
(parentForm as BaseForm).OnProcessCmdKey -= ((ShortcutInfo)item.Tag).KeyHandler;
}
((ShortcutInfo)item.Tag).KeyHandler = null;
}
public static void UpdateShortcutItem(ToolStripMenuItem item, Control parent, string fieldName)
{
if(item.Tag == null) {
item.Tag = new ShortcutInfo() { KeyHandler = null, ShortcutKey = fieldName };
} else if(((ShortcutInfo)item.Tag).KeyHandler != null) {
ClearProcessCmdKeyHandler(item, parent);
}
Keys keys = (XmlKeys)typeof(DebuggerShortcutsConfig).GetField(fieldName).GetValue(ConfigManager.Config.Debug.Shortcuts);
if((keys != Keys.None && !ToolStripManager.IsValidShortcut(keys)) || Program.IsMono) {
//Support normally invalid shortcut keys as a shortcut
item.ShortcutKeys = Keys.None;
item.ShortcutKeyDisplayString = GetShortcutDisplay(keys);
Form parentForm = parent.FindForm();
if(parentForm is BaseForm) {
ProcessCmdKeyHandler onProcessCmdKeyHandler = (Keys keyData, ref bool processed) => {
if(!processed && item.Enabled && parent.ContainsFocus && keyData == keys) {
item.PerformClick();
processed = true;
}
};
((ShortcutInfo)item.Tag).KeyHandler = onProcessCmdKeyHandler;
(parentForm as BaseForm).OnProcessCmdKey += onProcessCmdKeyHandler;
}
} else {
item.ShortcutKeys = keys;
item.ShortcutKeyDisplayString = GetShortcutDisplay(keys);
}
}
}
public static class ToolStripMenuItemExtensions
{
public static void InitShortcut(this ToolStripMenuItem item, Control parent, string fieldName)
{
DebuggerShortcutsConfig.UpdateShortcutItem(item, parent, fieldName);
DebuggerShortcutsConfig.RegisterMenuItem(item, parent, fieldName);
}
}
public class ShortcutInfo
{
public string ShortcutKey;
public ProcessCmdKeyHandler KeyHandler;
}
public class XmlKeys
{
private Keys _keys = Keys.None;
public XmlKeys() { }
public XmlKeys(Keys k) { _keys = k; }
public static implicit operator Keys(XmlKeys k)
{
return k._keys;
}
public static implicit operator XmlKeys(Keys k)
{
return new XmlKeys(k);
}
[XmlAttribute]
public string Value
{
get { return _keys.ToString(); }
set
{
try {
Enum.TryParse<Keys>(value, out _keys);
} catch(Exception) {
_keys = Keys.None;
}
}
}
}
public class ShortcutNameAttribute : Attribute
{
public string Name { get; private set; }
public ShortcutNameAttribute(string name)
{
this.Name = name;
}
}
}

View file

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;
using Mesen.GUI.Debugger;
using Mesen.GUI.Controls;
using Mesen.GUI.Utilities;
namespace Mesen.GUI.Config
{
public class HexEditorInfo
{
public bool HighDensityTextMode = false;
public bool EnablePerByteNavigation = false;
public bool ByteEditingMode = false;
public bool AutoRefresh = true;
public RefreshSpeed AutoRefreshSpeed = RefreshSpeed.Normal;
public bool IgnoreRedundantWrites = false;
public bool HighlightCurrentRowColumn = true;
public int ColumnCount = 2;
public string FontFamily = BaseControl.MonospaceFontFamily;
public FontStyle FontStyle = FontStyle.Regular;
public float FontSize = BaseControl.DefaultFontSize;
public int TextZoom = 100;
public bool ShowCharacters = true;
public bool ShowLabelInfo = true;
public bool HighlightExecution = true;
public bool HighlightWrites = true;
public bool HighlightReads = true;
public int FadeSpeed = 300;
public bool HideUnusedBytes = false;
public bool HideReadBytes = false;
public bool HideWrittenBytes = false;
public bool HideExecutedBytes = false;
public bool HighlightBreakpoints = false;
public bool HighlightLabelledBytes = false;
public bool HighlightChrDrawnBytes = false;
public bool HighlightChrReadBytes = false;
public bool HighlightCodeBytes = false;
public bool HighlightDataBytes = false;
public bool HighlightDmcDataBytes = false;
public XmlColor ReadColor = Color.Blue;
public XmlColor WriteColor = Color.Red;
public XmlColor ExecColor = Color.Green;
public XmlColor LabelledByteColor = Color.LightPink;
public XmlColor CodeByteColor = Color.DarkSeaGreen;
public XmlColor DataByteColor = Color.LightSteelBlue;
public SnesMemoryType MemoryType = SnesMemoryType.CpuMemory;
public Size WindowSize = new Size(0, 0);
public Point WindowLocation;
public HexEditorInfo()
{
}
}
}

View file

@ -14,6 +14,36 @@ using Mesen.GUI.Utilities;
namespace Mesen.GUI.Config
{
public class TraceLoggerInfo
{
public TraceLoggerOptions LogOptions;
public bool AutoRefresh = true;
public int LineCount = 1000;
public Size WindowSize = new Size(0, 0);
public Point WindowLocation;
public string FontFamily = BaseControl.MonospaceFontFamily;
public FontStyle FontStyle = FontStyle.Regular;
public float FontSize = BaseControl.DefaultFontSize;
public int TextZoom = 100;
public TraceLoggerInfo()
{
LogOptions = new TraceLoggerOptions() {
ShowByteCode = true,
ShowCpuCycles = true,
ShowEffectiveAddresses = true,
ShowExtraInfo = true,
ShowPpuFrames = false,
ShowPpuCycles = true,
ShowPpuScanline = true,
ShowRegisters = true,
UseLabels = false,
StatusFormat = StatusFlagFormat.Hexadecimal
};
}
}
public class TraceLoggerOptions
{
public bool ShowByteCode;
@ -36,46 +66,6 @@ namespace Mesen.GUI.Config
public string Format;
}
public class DebugInfo
{
public bool ShowSelectionLength = false;
public XmlColor EventViewerBreakpointColor = ColorTranslator.FromHtml("#1898E4");
public XmlColor AssemblerOpcodeColor = Color.FromArgb(22, 37, 37);
public XmlColor AssemblerLabelDefinitionColor = Color.Blue;
public XmlColor AssemblerImmediateColor = Color.Chocolate;
public XmlColor AssemblerAddressColor = Color.DarkRed;
public XmlColor AssemblerCommentColor = Color.Green;
public XmlColor CodeEffectiveAddressColor = Color.SteelBlue;
public TraceLoggerOptions TraceLoggerOptions;
public bool TraceAutoRefresh = true;
public int TraceLineCount = 1000;
public Size TraceLoggerSize = new Size(0, 0);
public Point TraceLoggerLocation;
public string TraceFontFamily = BaseControl.MonospaceFontFamily;
public FontStyle TraceFontStyle = FontStyle.Regular;
public float TraceFontSize = BaseControl.DefaultFontSize;
public int TraceTextZoom = 100;
public DebugInfo()
{
TraceLoggerOptions = new TraceLoggerOptions() {
ShowByteCode = true,
ShowCpuCycles = true,
ShowEffectiveAddresses = true,
ShowExtraInfo = true,
ShowPpuFrames = false,
ShowPpuCycles = true,
ShowPpuScanline = true,
ShowRegisters = true,
UseLabels = false,
StatusFormat = StatusFlagFormat.Hexadecimal
};
}
}
public enum StatusFlagFormat
{
Hexadecimal = 0,

View file

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Debugger.Controls
{
public class ComboBoxWithSeparator : ComboBox
{
private int _previousSelectedIndex = 0;
public ComboBoxWithSeparator() : base()
{
this.DrawMode = DrawMode.OwnerDrawFixed;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
base.OnDrawItem(e);
if(e.Index >= 0) {
var item = this.Items[e.Index];
if(item.ToString() == "-") {
e.Graphics.FillRectangle(SystemBrushes.ControlLightLight, e.Bounds);
e.Graphics.DrawLine(Pens.DarkGray, e.Bounds.X + 2, e.Bounds.Y + e.Bounds.Height / 2, e.Bounds.Right - 2, e.Bounds.Y + e.Bounds.Height / 2);
} else {
e.DrawBackground();
if(e.State == DrawItemState.Focus) {
e.DrawFocusRectangle();
}
using(Brush brush = new SolidBrush(e.ForeColor)) {
e.Graphics.DrawString(item.ToString(), e.Font, brush, e.Bounds);
}
}
} else {
e.DrawBackground();
}
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
if(this.SelectedItem.ToString() == "-") {
if(_previousSelectedIndex > this.SelectedIndex) {
this.SelectedIndex--;
} else {
this.SelectedIndex++;
}
return;
}
this._previousSelectedIndex = this.SelectedIndex;
base.OnSelectedIndexChanged(e);
}
}
}

View file

@ -0,0 +1,68 @@
using System;
using System.ComponentModel;
using System.Windows.Forms;
using Mesen.GUI.Config;
using System.Reflection;
using Mesen.GUI.Controls;
using System.Collections.Generic;
namespace Mesen.GUI.Debugger
{
public partial class ctrlDbgShortcuts : BaseControl
{
private FieldInfo[] _shortcuts;
public ctrlDbgShortcuts()
{
InitializeComponent();
}
public FieldInfo[] Shortcuts
{
set
{
_shortcuts = value;
InitializeGrid();
}
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.colShortcut.Width = (int)(this.Width / 2.1);
this.colKeys.Width = (int)(this.Width / 2.1);
}
public void InitializeGrid()
{
gridShortcuts.Rows.Clear();
foreach(FieldInfo shortcut in _shortcuts) {
int i = gridShortcuts.Rows.Add();
gridShortcuts.Rows[i].Cells[0].Tag = shortcut;
gridShortcuts.Rows[i].Cells[0].Value = shortcut.GetCustomAttribute<ShortcutNameAttribute>()?.Name ?? shortcut.Name;
gridShortcuts.Rows[i].Cells[1].Value = DebuggerShortcutsConfig.GetShortcutDisplay(((XmlKeys)shortcut.GetValue(ConfigManager.Config.Debug.Shortcuts)));
}
}
private void gridShortcuts_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
//Right-click on buttons to clear mappings
if(gridShortcuts.Columns[e.ColumnIndex] is DataGridViewButtonColumn && e.RowIndex >= 0) {
DataGridViewButtonCell button = gridShortcuts.Rows[e.RowIndex].Cells[e.ColumnIndex] as DataGridViewButtonCell;
if(button != null) {
if(e.Button == MouseButtons.Right) {
button.Value = "";
_shortcuts[e.RowIndex].SetValue(ConfigManager.Config.Debug.Shortcuts, (XmlKeys)Keys.None);
} else if(e.Button == MouseButtons.Left) {
using(frmDbgShortcutGetKey frm = new frmDbgShortcutGetKey()) {
frm.ShowDialog();
button.Value = DebuggerShortcutsConfig.GetShortcutDisplay(frm.ShortcutKeys);
_shortcuts[e.RowIndex].SetValue(ConfigManager.Config.Debug.Shortcuts, (XmlKeys)frm.ShortcutKeys);
}
}
}
}
}
}
}

View file

@ -0,0 +1,175 @@
namespace Mesen.GUI.Debugger
{
partial class ctrlDbgShortcuts
{
/// <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.gridShortcuts = new System.Windows.Forms.DataGridView();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.pnlConflictWarning = new System.Windows.Forms.Panel();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.picWarning = new System.Windows.Forms.PictureBox();
this.lblShortcutWarning = new System.Windows.Forms.Label();
this.colShortcut = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.colKeys = new System.Windows.Forms.DataGridViewButtonColumn();
((System.ComponentModel.ISupportInitialize)(this.gridShortcuts)).BeginInit();
this.tableLayoutPanel1.SuspendLayout();
this.pnlConflictWarning.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picWarning)).BeginInit();
this.SuspendLayout();
//
// gridShortcuts
//
this.gridShortcuts.AllowUserToAddRows = false;
this.gridShortcuts.AllowUserToDeleteRows = false;
this.gridShortcuts.AllowUserToResizeColumns = false;
this.gridShortcuts.AllowUserToResizeRows = false;
this.gridShortcuts.BackgroundColor = System.Drawing.SystemColors.ControlLightLight;
this.gridShortcuts.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.gridShortcuts.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.colShortcut,
this.colKeys});
this.gridShortcuts.Dock = System.Windows.Forms.DockStyle.Fill;
this.gridShortcuts.Location = new System.Drawing.Point(0, 32);
this.gridShortcuts.Margin = new System.Windows.Forms.Padding(0);
this.gridShortcuts.MultiSelect = false;
this.gridShortcuts.Name = "gridShortcuts";
this.gridShortcuts.RowHeadersVisible = false;
this.gridShortcuts.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.gridShortcuts.Size = new System.Drawing.Size(448, 216);
this.gridShortcuts.TabIndex = 2;
this.gridShortcuts.CellMouseDown += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.gridShortcuts_CellMouseDown);
//
// 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.pnlConflictWarning, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.gridShortcuts, 0, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
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(448, 248);
this.tableLayoutPanel1.TabIndex = 3;
//
// pnlConflictWarning
//
this.pnlConflictWarning.BackColor = System.Drawing.Color.WhiteSmoke;
this.pnlConflictWarning.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.pnlConflictWarning.Controls.Add(this.tableLayoutPanel2);
this.pnlConflictWarning.Dock = System.Windows.Forms.DockStyle.Fill;
this.pnlConflictWarning.Location = new System.Drawing.Point(0, 0);
this.pnlConflictWarning.Margin = new System.Windows.Forms.Padding(0, 0, 0, 2);
this.pnlConflictWarning.Name = "pnlConflictWarning";
this.pnlConflictWarning.Size = new System.Drawing.Size(448, 30);
this.pnlConflictWarning.TabIndex = 20;
this.pnlConflictWarning.Visible = false;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 2;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Controls.Add(this.picWarning, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.lblShortcutWarning, 1, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 1;
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Size = new System.Drawing.Size(446, 28);
this.tableLayoutPanel2.TabIndex = 0;
//
// picWarning
//
this.picWarning.Anchor = System.Windows.Forms.AnchorStyles.None;
this.picWarning.Image = global::Mesen.GUI.Properties.Resources.Warning;
this.picWarning.Location = new System.Drawing.Point(3, 6);
this.picWarning.Name = "picWarning";
this.picWarning.Size = new System.Drawing.Size(16, 16);
this.picWarning.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.picWarning.TabIndex = 0;
this.picWarning.TabStop = false;
//
// lblShortcutWarning
//
this.lblShortcutWarning.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblShortcutWarning.Location = new System.Drawing.Point(25, 0);
this.lblShortcutWarning.Name = "lblShortcutWarning";
this.lblShortcutWarning.Size = new System.Drawing.Size(418, 28);
this.lblShortcutWarning.TabIndex = 1;
this.lblShortcutWarning.Text = "Warning: Your current configuration contains conflicting key bindings. If this is" +
" not intentional, please review and correct your key bindings.";
//
// colShortcut
//
this.colShortcut.HeaderText = "Shortcut";
this.colShortcut.Name = "colShortcut";
this.colShortcut.ReadOnly = true;
this.colShortcut.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.colShortcut.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.NotSortable;
this.colShortcut.Width = 233;
//
// colKeys
//
this.colKeys.HeaderText = "Keys";
this.colKeys.Name = "colKeys";
this.colKeys.Resizable = System.Windows.Forms.DataGridViewTriState.False;
this.colKeys.Width = 110;
//
// ctrlDbgShortcuts
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "ctrlDbgShortcuts";
this.Size = new System.Drawing.Size(448, 248);
((System.ComponentModel.ISupportInitialize)(this.gridShortcuts)).EndInit();
this.tableLayoutPanel1.ResumeLayout(false);
this.pnlConflictWarning.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picWarning)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView gridShortcuts;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Panel pnlConflictWarning;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.PictureBox picWarning;
private System.Windows.Forms.Label lblShortcutWarning;
private System.Windows.Forms.DataGridViewTextBoxColumn colShortcut;
private System.Windows.Forms.DataGridViewButtonColumn colKeys;
}
}

View file

@ -0,0 +1,126 @@
<?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="colShortcut.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="colKeys.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

View file

@ -0,0 +1,457 @@
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 Mesen.GUI.Config;
using Be.Windows.Forms;
using Mesen.GUI.Controls;
using static Be.Windows.Forms.DynamicByteProvider;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger.Controls
{
public partial class ctrlHexViewer : BaseControl
{
private FindOptions _findOptions;
private StaticByteProvider _byteProvider;
private SnesMemoryType _memoryType;
public ctrlHexViewer()
{
InitializeComponent();
this.BaseFont = new Font(BaseControl.MonospaceFontFamily, 10, FontStyle.Regular);
this.ctrlHexBox.ContextMenuStrip = this.ctxMenuStrip;
this.ctrlHexBox.SelectionForeColor = Color.White;
this.ctrlHexBox.SelectionBackColor = Color.FromArgb(31, 123, 205);
this.ctrlHexBox.ShadowSelectionColor = Color.FromArgb(100, 60, 128, 200);
this.ctrlHexBox.InfoBackColor = Color.FromArgb(235, 235, 235);
this.ctrlHexBox.InfoForeColor = Color.Gray;
this.ctrlHexBox.HighlightCurrentRowColumn = true;
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if(!IsDesignMode) {
this.cboNumberColumns.SelectedIndex = ConfigManager.Config.Debug.HexEditor.ColumnCount;
}
}
public byte[] GetData()
{
return this._byteProvider != null ? this._byteProvider.Bytes.ToArray() : new byte[0];
}
public void RefreshData(SnesMemoryType memoryType)
{
if(_memoryType != memoryType) {
_memoryType = memoryType;
_byteProvider = null;
}
byte[] data = DebugApi.GetMemoryState(this._memoryType);
if(data != null) {
bool changed = true;
if(this._byteProvider != null && data.Length == this._byteProvider.Bytes.Count) {
changed = false;
for(int i = 0; i < this._byteProvider.Bytes.Count; i++) {
if(this._byteProvider.Bytes[i] != data[i]) {
changed = true;
break;
}
}
}
if(changed) {
if(_byteProvider == null || _byteProvider.Length != data.Length) {
_byteProvider = new StaticByteProvider(data);
_byteProvider.ByteChanged += (int byteIndex, byte newValue, byte oldValue) => {
DebugApi.SetMemoryValue(_memoryType, (UInt32)byteIndex, newValue);
};
_byteProvider.BytesChanged += (int byteIndex, byte[] values) => {
DebugApi.SetMemoryValues(_memoryType, (UInt32)byteIndex, values, values.Length);
};
this.ctrlHexBox.ByteProvider = _byteProvider;
} else {
_byteProvider.SetData(data);
}
this.ctrlHexBox.Refresh();
}
}
}
private int ColumnCount
{
get { return Int32.Parse(this.cboNumberColumns.Text); }
}
public int RequiredWidth
{
get { return this.ctrlHexBox.RequiredWidth; }
}
private void cboNumberColumns_SelectedIndexChanged(object sender, EventArgs e)
{
this.ctrlHexBox.Focus();
this.ctrlHexBox.BytesPerLine = this.ColumnCount;
this.ctrlHexBox.UseFixedBytesPerLine = true;
ConfigManager.Config.Debug.HexEditor.ColumnCount = this.cboNumberColumns.SelectedIndex;
ConfigManager.ApplyChanges();
}
public Font HexFont
{
get { return this.ctrlHexBox.Font; }
}
private int _textZoom = 100;
public int TextZoom
{
get { return _textZoom; }
set
{
if(value >= 30 && value <= 500) {
_textZoom = value;
this.UpdateFont();
}
}
}
private Font _baseFont = new Font(BaseControl.MonospaceFontFamily, BaseControl.DefaultFontSize, FontStyle.Regular);
public Font BaseFont {
get { return _baseFont; }
set
{
if(!value.Equals(_baseFont)) {
_baseFont = value;
this.UpdateFont();
}
}
}
public void UpdateFont()
{
this.ctrlHexBox.Font = new Font(BaseFont.FontFamily, BaseFont.Size * _textZoom / 100f, BaseFont.Style);
}
public void GoToAddress(int address)
{
this.ctrlHexBox.ScrollByteIntoView(GetData().Length - 1);
this.ctrlHexBox.ScrollByteIntoView(address);
this.ctrlHexBox.Select(address, 0);
this.ctrlHexBox.Focus();
}
public void GoToAddress()
{
GoToAddress address = new GoToAddress();
int currentAddr = (int)(this.ctrlHexBox.CurrentLine - 1) * this.ctrlHexBox.BytesPerLine;
address.Address = (UInt32)currentAddr;
using(frmGoToLine frm = new frmGoToLine(address, (_byteProvider.Length - 1).ToString("X").Length)) {
frm.StartPosition = FormStartPosition.Manual;
Point topLeft = this.PointToScreen(new Point(0, 0));
frm.Location = new Point(topLeft.X + (this.Width - frm.Width) / 2, topLeft.Y + (this.Height - frm.Height) / 2);
if(frm.ShowDialog() == DialogResult.OK) {
GoToAddress((int)address.Address);
}
}
}
public void OpenSearchBox(bool forceFocus = false)
{
this._findOptions = new Be.Windows.Forms.FindOptions();
this._findOptions.Type = chkTextSearch.Checked ? FindType.Text : FindType.Hex;
this._findOptions.MatchCase = false;
this._findOptions.Text = this.cboSearch.Text;
this._findOptions.WrapSearch = true;
bool focus = !this.panelSearch.Visible;
this.panelSearch.Visible = true;
if(Program.IsMono) {
//Mono doesn't resize the TLP properly for some reason when set to autosize
this.tlpMain.RowStyles[2].SizeType = System.Windows.Forms.SizeType.Absolute;
this.tlpMain.RowStyles[2].Height = 30;
}
if(focus || forceFocus) {
this.cboSearch.Focus();
this.cboSearch.SelectAll();
}
}
private void CloseSearchBox()
{
this.panelSearch.Visible = false;
if(Program.IsMono) {
//Mono doesn't resize the TLP properly for some reason when set to autosize
this.tlpMain.RowStyles[2].SizeType = System.Windows.Forms.SizeType.Absolute;
this.tlpMain.RowStyles[2].Height = 0;
}
this.Focus();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == ConfigManager.Config.Debug.Shortcuts.Find) {
this.OpenSearchBox(true);
return true;
} else if(keyData == ConfigManager.Config.Debug.Shortcuts.IncreaseFontSize) {
this.TextZoom += 10;
return true;
} else if(keyData == ConfigManager.Config.Debug.Shortcuts.DecreaseFontSize) {
this.TextZoom -= 10;
return true;
} else if(keyData == ConfigManager.Config.Debug.Shortcuts.ResetFontSize) {
this.TextZoom = 100;
return true;
}
if(this.cboSearch.Focused) {
if(keyData == Keys.Escape) {
this.CloseSearchBox();
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
public void FindNext()
{
this.OpenSearchBox();
if(this.UpdateSearchOptions()) {
if(this.ctrlHexBox.Find(this._findOptions, HexBox.eSearchDirection.Next) == -1) {
this.lblSearchWarning.Text = "No matches found!";
}
}
}
public void FindPrevious()
{
this.OpenSearchBox();
if(this.UpdateSearchOptions()) {
if(this.ctrlHexBox.Find(this._findOptions, HexBox.eSearchDirection.Previous) == -1) {
this.lblSearchWarning.Text = "No matches found!";
}
}
}
private void picCloseSearch_Click(object sender, EventArgs e)
{
this.CloseSearchBox();
}
private void picSearchPrevious_MouseUp(object sender, MouseEventArgs e)
{
this.FindPrevious();
}
private void picSearchNext_MouseUp(object sender, MouseEventArgs e)
{
this.FindNext();
}
private byte[] GetByteArray(string hexText, ref bool hasWildcard)
{
hexText = hexText.Replace(" ", "");
try {
List<byte> bytes = new List<byte>(hexText.Length/2);
for(int i = 0; i < hexText.Length; i+=2) {
if(i == hexText.Length - 1) {
bytes.Add((byte)(Convert.ToByte(hexText.Substring(i, 1), 16) << 4));
hasWildcard = true;
} else {
bytes.Add(Convert.ToByte(hexText.Substring(i, 2), 16));
}
}
return bytes.ToArray();
} catch {
return new byte[0];
}
}
private bool UpdateSearchOptions()
{
bool invalidSearchString = false;
this._findOptions.MatchCase = this.chkMatchCase.Checked;
if(this.chkTextSearch.Checked) {
this._findOptions.Type = FindType.Text;
this._findOptions.Text = this.cboSearch.Text;
this._findOptions.HasWildcard = false;
} else {
this._findOptions.Type = FindType.Hex;
bool hasWildcard = false;
this._findOptions.Hex = this.GetByteArray(this.cboSearch.Text, ref hasWildcard);
this._findOptions.HasWildcard = hasWildcard;
invalidSearchString = this._findOptions.Hex.Length == 0 && this.cboSearch.Text.Trim().Length > 0;
}
this.lblSearchWarning.Text = "";
bool emptySearch = this._findOptions.Text.Length == 0 || (!this.chkTextSearch.Checked && (this._findOptions.Hex == null || this._findOptions.Hex.Length == 0));
if(invalidSearchString) {
this.lblSearchWarning.Text = "Invalid search string";
} else if(!emptySearch) {
return true;
}
return false;
}
private void cboSearch_TextUpdate(object sender, EventArgs e)
{
if(this.UpdateSearchOptions()) {
if(this.ctrlHexBox.Find(this._findOptions, HexBox.eSearchDirection.Incremental) == -1) {
this.lblSearchWarning.Text = "No matches found!";
}
}
}
private void cboSearch_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter) {
this.FindNext();
if(this.cboSearch.Items.Contains(this.cboSearch.Text)) {
this.cboSearch.Items.Remove(this.cboSearch.Text);
}
this.cboSearch.Items.Insert(0, this.cboSearch.Text);
e.Handled = true;
e.SuppressKeyPress = true;
}
}
private void chkTextSearch_CheckedChanged(object sender, EventArgs e)
{
this.UpdateSearchOptions();
}
public event EventHandler RequiredWidthChanged
{
add { this.ctrlHexBox.RequiredWidthChanged += value; }
remove { this.ctrlHexBox.RequiredWidthChanged -= value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IByteCharConverter ByteCharConverter
{
get { return this.ctrlHexBox.ByteCharConverter; }
set { this.ctrlHexBox.ByteCharConverter = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public IByteColorProvider ByteColorProvider
{
get { return this.ctrlHexBox.ByteColorProvider; }
set { this.ctrlHexBox.ByteColorProvider = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool StringViewVisible
{
get { return this.ctrlHexBox.StringViewVisible; }
set { this.ctrlHexBox.StringViewVisible = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool ReadOnly
{
get { return this.ctrlHexBox.ReadOnly; }
set { this.ctrlHexBox.ReadOnly = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool HighDensityMode
{
get { return this.ctrlHexBox.HighDensityMode; }
set { this.ctrlHexBox.HighDensityMode = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool EnablePerByteNavigation
{
get { return this.ctrlHexBox.EnablePerByteNavigation; }
set { this.ctrlHexBox.EnablePerByteNavigation = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool ByteEditingMode
{
get { return this.ctrlHexBox.ByteEditingMode; }
set { this.ctrlHexBox.ByteEditingMode = value; }
}
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public bool HighlightCurrentRowColumn
{
get { return this.ctrlHexBox.HighlightCurrentRowColumn; }
set { this.ctrlHexBox.HighlightCurrentRowColumn = value; }
}
public delegate void ByteMouseHoverHandler(int address, Point position);
public event ByteMouseHoverHandler ByteMouseHover;
private void ctrlHexBox_MouseMove(object sender, MouseEventArgs e)
{
BytePositionInfo? bpi = ctrlHexBox.GetRestrictedHexBytePositionInfo(e.Location);
if(bpi.HasValue) {
Point position = ctrlHexBox.GetBytePosition(bpi.Value.Index);
ByteMouseHover?.Invoke((int)bpi.Value.Index, new Point(position.X + (int)(ctrlHexBox.CharSize.Width * 2.5), position.Y + (int)(ctrlHexBox.CharSize.Height * 1.1)));
} else {
ByteMouseHover?.Invoke(-1, Point.Empty);
}
}
private void ctrlHexBox_MouseLeave(object sender, EventArgs e)
{
ByteMouseHover?.Invoke(-1, Point.Empty);
}
private void UpdateLocationLabel()
{
if(ctrlHexBox.SelectionLength > 0) {
this.lblLocation.Text = $"Selection: ${ctrlHexBox.SelectionStart.ToString("X4")} - ${(ctrlHexBox.SelectionStart + ctrlHexBox.SelectionLength - 1).ToString("X4")} ({ctrlHexBox.SelectionLength} bytes)";
} else {
this.lblLocation.Text = $"Location: ${ctrlHexBox.SelectionStart.ToString("X4")}";
}
}
private void ctrlHexBox_SelectionStartChanged(object sender, EventArgs e)
{
UpdateLocationLabel();
}
private void ctrlHexBox_SelectionLengthChanged(object sender, EventArgs e)
{
UpdateLocationLabel();
}
private void mnuCopy_Click(object sender, EventArgs e)
{
ctrlHexBox.CopyHex();
}
private void mnuPaste_Click(object sender, EventArgs e)
{
ctrlHexBox.Paste();
}
private void mnuSelectAll_Click(object sender, EventArgs e)
{
ctrlHexBox.SelectAll();
}
}
}

View file

@ -0,0 +1,389 @@
namespace Mesen.GUI.Debugger.Controls
{
partial class ctrlHexViewer
{
/// <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.components = new System.ComponentModel.Container();
this.tlpMain = new System.Windows.Forms.TableLayoutPanel();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.lblNumberOfColumns = new System.Windows.Forms.Label();
this.cboNumberColumns = new System.Windows.Forms.ComboBox();
this.panelSearch = new System.Windows.Forms.Panel();
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
this.picCloseSearch = new System.Windows.Forms.PictureBox();
this.picSearchNext = new System.Windows.Forms.PictureBox();
this.picSearchPrevious = new System.Windows.Forms.PictureBox();
this.cboSearch = new System.Windows.Forms.ComboBox();
this.lblSearchWarning = new System.Windows.Forms.Label();
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
this.chkTextSearch = new System.Windows.Forms.CheckBox();
this.chkMatchCase = new System.Windows.Forms.CheckBox();
this.ctrlHexBox = new Be.Windows.Forms.HexBox();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.lblLocation = new System.Windows.Forms.ToolStripStatusLabel();
this.ctxMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components);
this.mnuCopy = new System.Windows.Forms.ToolStripMenuItem();
this.mnuPaste = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuSelectAll = new System.Windows.Forms.ToolStripMenuItem();
this.tlpMain.SuspendLayout();
this.flowLayoutPanel1.SuspendLayout();
this.panelSearch.SuspendLayout();
this.tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picCloseSearch)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picSearchNext)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.picSearchPrevious)).BeginInit();
this.flowLayoutPanel2.SuspendLayout();
this.statusStrip.SuspendLayout();
this.ctxMenuStrip.SuspendLayout();
this.SuspendLayout();
//
// tlpMain
//
this.tlpMain.ColumnCount = 1;
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpMain.Controls.Add(this.flowLayoutPanel1, 0, 0);
this.tlpMain.Controls.Add(this.panelSearch, 0, 2);
this.tlpMain.Controls.Add(this.ctrlHexBox, 0, 1);
this.tlpMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tlpMain.Location = new System.Drawing.Point(0, 0);
this.tlpMain.Margin = new System.Windows.Forms.Padding(0);
this.tlpMain.Name = "tlpMain";
this.tlpMain.RowCount = 3;
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tlpMain.Size = new System.Drawing.Size(543, 287);
this.tlpMain.TabIndex = 0;
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.flowLayoutPanel1.AutoSize = true;
this.flowLayoutPanel1.Controls.Add(this.lblNumberOfColumns);
this.flowLayoutPanel1.Controls.Add(this.cboNumberColumns);
this.flowLayoutPanel1.Location = new System.Drawing.Point(379, 0);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(164, 27);
this.flowLayoutPanel1.TabIndex = 1;
//
// lblNumberOfColumns
//
this.lblNumberOfColumns.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblNumberOfColumns.AutoSize = true;
this.lblNumberOfColumns.Location = new System.Drawing.Point(3, 7);
this.lblNumberOfColumns.Name = "lblNumberOfColumns";
this.lblNumberOfColumns.Size = new System.Drawing.Size(102, 13);
this.lblNumberOfColumns.TabIndex = 0;
this.lblNumberOfColumns.Text = "Number of Columns:";
//
// cboNumberColumns
//
this.cboNumberColumns.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboNumberColumns.FormattingEnabled = true;
this.cboNumberColumns.Items.AddRange(new object[] {
"4",
"8",
"16",
"32",
"64"});
this.cboNumberColumns.Location = new System.Drawing.Point(111, 3);
this.cboNumberColumns.Name = "cboNumberColumns";
this.cboNumberColumns.Size = new System.Drawing.Size(50, 21);
this.cboNumberColumns.TabIndex = 1;
this.cboNumberColumns.SelectedIndexChanged += new System.EventHandler(this.cboNumberColumns_SelectedIndexChanged);
//
// panelSearch
//
this.panelSearch.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.panelSearch.Controls.Add(this.tableLayoutPanel2);
this.panelSearch.Dock = System.Windows.Forms.DockStyle.Fill;
this.panelSearch.Location = new System.Drawing.Point(3, 259);
this.panelSearch.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
this.panelSearch.Name = "panelSearch";
this.panelSearch.Size = new System.Drawing.Size(537, 28);
this.panelSearch.TabIndex = 3;
this.panelSearch.Visible = false;
//
// tableLayoutPanel2
//
this.tableLayoutPanel2.ColumnCount = 6;
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 250F));
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel2.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel2.Controls.Add(this.picCloseSearch, 3, 0);
this.tableLayoutPanel2.Controls.Add(this.picSearchNext, 2, 0);
this.tableLayoutPanel2.Controls.Add(this.picSearchPrevious, 1, 0);
this.tableLayoutPanel2.Controls.Add(this.cboSearch, 0, 0);
this.tableLayoutPanel2.Controls.Add(this.lblSearchWarning, 4, 0);
this.tableLayoutPanel2.Controls.Add(this.flowLayoutPanel2, 5, 0);
this.tableLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel2.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel2.Margin = new System.Windows.Forms.Padding(0);
this.tableLayoutPanel2.Name = "tableLayoutPanel2";
this.tableLayoutPanel2.RowCount = 2;
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(535, 26);
this.tableLayoutPanel2.TabIndex = 0;
//
// picCloseSearch
//
this.picCloseSearch.Anchor = System.Windows.Forms.AnchorStyles.None;
this.picCloseSearch.Cursor = System.Windows.Forms.Cursors.Hand;
this.picCloseSearch.Image = global::Mesen.GUI.Properties.Resources.Close;
this.picCloseSearch.Location = new System.Drawing.Point(297, 5);
this.picCloseSearch.Name = "picCloseSearch";
this.picCloseSearch.Size = new System.Drawing.Size(16, 16);
this.picCloseSearch.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.picCloseSearch.TabIndex = 3;
this.picCloseSearch.TabStop = false;
this.picCloseSearch.Click += new System.EventHandler(this.picCloseSearch_Click);
//
// picSearchNext
//
this.picSearchNext.Anchor = System.Windows.Forms.AnchorStyles.None;
this.picSearchNext.Cursor = System.Windows.Forms.Cursors.Hand;
this.picSearchNext.Image = global::Mesen.GUI.Properties.Resources.NextArrow;
this.picSearchNext.Location = new System.Drawing.Point(275, 5);
this.picSearchNext.Name = "picSearchNext";
this.picSearchNext.Size = new System.Drawing.Size(16, 16);
this.picSearchNext.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.picSearchNext.TabIndex = 2;
this.picSearchNext.TabStop = false;
this.picSearchNext.MouseUp += new System.Windows.Forms.MouseEventHandler(this.picSearchNext_MouseUp);
//
// picSearchPrevious
//
this.picSearchPrevious.Anchor = System.Windows.Forms.AnchorStyles.None;
this.picSearchPrevious.Cursor = System.Windows.Forms.Cursors.Hand;
this.picSearchPrevious.Image = global::Mesen.GUI.Properties.Resources.PreviousArrow;
this.picSearchPrevious.Location = new System.Drawing.Point(253, 5);
this.picSearchPrevious.Name = "picSearchPrevious";
this.picSearchPrevious.Size = new System.Drawing.Size(16, 16);
this.picSearchPrevious.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.picSearchPrevious.TabIndex = 1;
this.picSearchPrevious.TabStop = false;
this.picSearchPrevious.MouseUp += new System.Windows.Forms.MouseEventHandler(this.picSearchPrevious_MouseUp);
//
// cboSearch
//
this.cboSearch.Dock = System.Windows.Forms.DockStyle.Fill;
this.cboSearch.FormattingEnabled = true;
this.cboSearch.Location = new System.Drawing.Point(3, 3);
this.cboSearch.Name = "cboSearch";
this.cboSearch.Size = new System.Drawing.Size(244, 21);
this.cboSearch.TabIndex = 4;
this.cboSearch.TextUpdate += new System.EventHandler(this.cboSearch_TextUpdate);
this.cboSearch.KeyDown += new System.Windows.Forms.KeyEventHandler(this.cboSearch_KeyDown);
//
// lblSearchWarning
//
this.lblSearchWarning.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblSearchWarning.AutoSize = true;
this.lblSearchWarning.ForeColor = System.Drawing.Color.Red;
this.lblSearchWarning.Location = new System.Drawing.Point(319, 7);
this.lblSearchWarning.Name = "lblSearchWarning";
this.lblSearchWarning.Size = new System.Drawing.Size(0, 13);
this.lblSearchWarning.TabIndex = 6;
//
// flowLayoutPanel2
//
this.flowLayoutPanel2.Controls.Add(this.chkTextSearch);
this.flowLayoutPanel2.Controls.Add(this.chkMatchCase);
this.flowLayoutPanel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel2.FlowDirection = System.Windows.Forms.FlowDirection.RightToLeft;
this.flowLayoutPanel2.Location = new System.Drawing.Point(322, 2);
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(0, 2, 0, 0);
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
this.flowLayoutPanel2.Size = new System.Drawing.Size(213, 25);
this.flowLayoutPanel2.TabIndex = 7;
//
// chkTextSearch
//
this.chkTextSearch.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.chkTextSearch.AutoSize = true;
this.chkTextSearch.Location = new System.Drawing.Point(128, 3);
this.chkTextSearch.Name = "chkTextSearch";
this.chkTextSearch.Size = new System.Drawing.Size(82, 17);
this.chkTextSearch.TabIndex = 5;
this.chkTextSearch.Text = "Text search";
this.chkTextSearch.UseVisualStyleBackColor = true;
this.chkTextSearch.CheckedChanged += new System.EventHandler(this.chkTextSearch_CheckedChanged);
//
// chkMatchCase
//
this.chkMatchCase.Anchor = System.Windows.Forms.AnchorStyles.Right;
this.chkMatchCase.AutoSize = true;
this.chkMatchCase.Location = new System.Drawing.Point(39, 3);
this.chkMatchCase.Name = "chkMatchCase";
this.chkMatchCase.Size = new System.Drawing.Size(83, 17);
this.chkMatchCase.TabIndex = 6;
this.chkMatchCase.Text = "Match Case";
this.chkMatchCase.UseVisualStyleBackColor = true;
//
// ctrlHexBox
//
this.ctrlHexBox.ByteColorProvider = null;
this.ctrlHexBox.ByteEditingMode = false;
this.ctrlHexBox.ColumnInfoVisible = true;
this.ctrlHexBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlHexBox.EnablePerByteNavigation = false;
this.ctrlHexBox.Font = new System.Drawing.Font("Consolas", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.ctrlHexBox.HighDensityMode = false;
this.ctrlHexBox.InfoBackColor = System.Drawing.Color.DarkGray;
this.ctrlHexBox.LineInfoVisible = true;
this.ctrlHexBox.Location = new System.Drawing.Point(0, 27);
this.ctrlHexBox.Margin = new System.Windows.Forms.Padding(0);
this.ctrlHexBox.Name = "ctrlHexBox";
this.ctrlHexBox.SelectionBackColor = System.Drawing.Color.RoyalBlue;
this.ctrlHexBox.ShadowSelectionColor = System.Drawing.Color.Orange;
this.ctrlHexBox.Size = new System.Drawing.Size(543, 232);
this.ctrlHexBox.StringViewVisible = true;
this.ctrlHexBox.TabIndex = 2;
this.ctrlHexBox.UseFixedBytesPerLine = true;
this.ctrlHexBox.VScrollBarVisible = true;
this.ctrlHexBox.SelectionStartChanged += new System.EventHandler(this.ctrlHexBox_SelectionStartChanged);
this.ctrlHexBox.SelectionLengthChanged += new System.EventHandler(this.ctrlHexBox_SelectionLengthChanged);
this.ctrlHexBox.MouseLeave += new System.EventHandler(this.ctrlHexBox_MouseLeave);
this.ctrlHexBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ctrlHexBox_MouseMove);
//
// statusStrip
//
this.statusStrip.BackColor = System.Drawing.SystemColors.ControlLightLight;
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.lblLocation});
this.statusStrip.Location = new System.Drawing.Point(0, 287);
this.statusStrip.Name = "statusStrip";
this.statusStrip.RenderMode = System.Windows.Forms.ToolStripRenderMode.Professional;
this.statusStrip.Size = new System.Drawing.Size(543, 22);
this.statusStrip.SizingGrip = false;
this.statusStrip.TabIndex = 1;
//
// lblLocation
//
this.lblLocation.Name = "lblLocation";
this.lblLocation.Size = new System.Drawing.Size(0, 17);
//
// ctxMenuStrip
//
this.ctxMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuCopy,
this.mnuPaste,
this.toolStripMenuItem5,
this.mnuSelectAll});
this.ctxMenuStrip.Name = "ctxMenuStrip";
this.ctxMenuStrip.Size = new System.Drawing.Size(153, 98);
//
// mnuCopy
//
this.mnuCopy.Image = global::Mesen.GUI.Properties.Resources.Copy;
this.mnuCopy.Name = "mnuCopy";
this.mnuCopy.Size = new System.Drawing.Size(152, 22);
this.mnuCopy.Text = "Copy";
this.mnuCopy.Click += new System.EventHandler(this.mnuCopy_Click);
//
// mnuPaste
//
this.mnuPaste.Image = global::Mesen.GUI.Properties.Resources.Paste;
this.mnuPaste.Name = "mnuPaste";
this.mnuPaste.Size = new System.Drawing.Size(152, 22);
this.mnuPaste.Text = "Paste";
this.mnuPaste.Click += new System.EventHandler(this.mnuPaste_Click);
//
// toolStripMenuItem5
//
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
this.toolStripMenuItem5.Size = new System.Drawing.Size(149, 6);
//
// mnuSelectAll
//
this.mnuSelectAll.Image = global::Mesen.GUI.Properties.Resources.SelectAll;
this.mnuSelectAll.Name = "mnuSelectAll";
this.mnuSelectAll.Size = new System.Drawing.Size(152, 22);
this.mnuSelectAll.Text = "Select All";
this.mnuSelectAll.Click += new System.EventHandler(this.mnuSelectAll_Click);
//
// ctrlHexViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tlpMain);
this.Controls.Add(this.statusStrip);
this.Margin = new System.Windows.Forms.Padding(0);
this.Name = "ctrlHexViewer";
this.Size = new System.Drawing.Size(543, 309);
this.tlpMain.ResumeLayout(false);
this.tlpMain.PerformLayout();
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
this.panelSearch.ResumeLayout(false);
this.tableLayoutPanel2.ResumeLayout(false);
this.tableLayoutPanel2.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.picCloseSearch)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picSearchNext)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.picSearchPrevious)).EndInit();
this.flowLayoutPanel2.ResumeLayout(false);
this.flowLayoutPanel2.PerformLayout();
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ctxMenuStrip.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.TableLayoutPanel tlpMain;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Label lblNumberOfColumns;
private System.Windows.Forms.ComboBox cboNumberColumns;
private Be.Windows.Forms.HexBox ctrlHexBox;
private System.Windows.Forms.Panel panelSearch;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
private System.Windows.Forms.PictureBox picCloseSearch;
private System.Windows.Forms.PictureBox picSearchNext;
private System.Windows.Forms.PictureBox picSearchPrevious;
private System.Windows.Forms.ComboBox cboSearch;
private System.Windows.Forms.CheckBox chkTextSearch;
private System.Windows.Forms.Label lblSearchWarning;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
private System.Windows.Forms.CheckBox chkMatchCase;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel lblLocation;
private System.Windows.Forms.ContextMenuStrip ctxMenuStrip;
private System.Windows.Forms.ToolStripMenuItem mnuCopy;
private System.Windows.Forms.ToolStripMenuItem mnuPaste;
private System.Windows.Forms.ToolStripMenuItem mnuSelectAll;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
}
}

View file

@ -0,0 +1,126 @@
<?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="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>
<metadata name="ctxMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>216, 17</value>
</metadata>
</root>

View file

@ -1050,8 +1050,8 @@ namespace Mesen.GUI.Debugger.Controls
string indirect = match.Groups[14].Value;
string paren3 = match.Groups[15].Value;
string rest = match.Groups[16].Value;
Color operandColor = operand.Length > 0 ? (operand[0] == '#' ? (Color)info.AssemblerImmediateColor : (operand[0] == '$' ? (Color)info.AssemblerAddressColor : (Color)info.AssemblerLabelDefinitionColor)) : Color.Black;
List<Color> colors = new List<Color>() { defaultColor, info.AssemblerOpcodeColor, defaultColor, defaultColor, defaultColor, operandColor, defaultColor, defaultColor, defaultColor };
Color operandColor = operand.Length > 0 ? (operand[0] == '#' ? (Color)info.CodeImmediateColor : (operand[0] == '$' ? (Color)info.CodeAddressColor : (Color)info.CodeLabelDefinitionColor)) : Color.Black;
List<Color> colors = new List<Color>() { defaultColor, info.CodeOpcodeColor, defaultColor, defaultColor, defaultColor, operandColor, defaultColor, defaultColor, defaultColor };
int codePartCount = colors.Count;
List<string> parts = new List<string>() { padding, opcode, invalidStar, " ", paren1, operand, paren2, indirect, paren3 };
@ -1110,7 +1110,7 @@ namespace Mesen.GUI.Debugger.Controls
}
codeStringLength = xOffset;
} else {
using(Brush fgBrush = new SolidBrush(codeString.EndsWith(":") ? (Color)info.AssemblerLabelDefinitionColor : (textColor ?? defaultColor))) {
using(Brush fgBrush = new SolidBrush(codeString.EndsWith(":") ? (Color)info.CodeLabelDefinitionColor : (textColor ?? defaultColor))) {
g.DrawString(codeString, this.Font, fgBrush, marginLeft, positionY, StringFormat.GenericTypographic);
}
characterCount = codeString.Trim().Length;
@ -1118,7 +1118,7 @@ namespace Mesen.GUI.Debugger.Controls
}
if(!string.IsNullOrWhiteSpace(commentString)) {
using(Brush commentBrush = new SolidBrush(info.AssemblerCommentColor)) {
using(Brush commentBrush = new SolidBrush(info.CodeCommentColor)) {
int padding = Math.Max(CommentSpacingCharCount, characterCount + 1);
if(characterCount == 0) {
//Draw comment left-aligned, next to the margin when there is no code on the line

View file

@ -0,0 +1,220 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.ComponentModel;
using System.Windows.Forms;
namespace Be.Windows.Forms
{
/// <summary>
/// Defines a build-in ContextMenuStrip manager for HexBox control to show Copy, Cut, Paste menu in contextmenu of the control.
/// </summary>
[TypeConverterAttribute(typeof(ExpandableObjectConverter))]
public sealed class BuiltInContextMenu : Component
{
/// <summary>
/// Contains the HexBox control.
/// </summary>
HexBox _hexBox;
/// <summary>
/// Contains the ContextMenuStrip control.
/// </summary>
ContextMenuStrip _contextMenuStrip;
/// <summary>
/// Contains the "Cut"-ToolStripMenuItem object.
/// </summary>
ToolStripMenuItem _cutToolStripMenuItem;
/// <summary>
/// Contains the "Copy"-ToolStripMenuItem object.
/// </summary>
ToolStripMenuItem _copyToolStripMenuItem;
/// <summary>
/// Contains the "Paste"-ToolStripMenuItem object.
/// </summary>
ToolStripMenuItem _pasteToolStripMenuItem;
/// <summary>
/// Contains the "Select All"-ToolStripMenuItem object.
/// </summary>
ToolStripMenuItem _selectAllToolStripMenuItem;
/// <summary>
/// Initializes a new instance of BuildInContextMenu class.
/// </summary>
/// <param name="hexBox">the HexBox control</param>
internal BuiltInContextMenu(HexBox hexBox)
{
_hexBox = hexBox;
_hexBox.ByteProviderChanged += new EventHandler(HexBox_ByteProviderChanged);
}
/// <summary>
/// If ByteProvider
/// </summary>
/// <param name="sender">the sender object</param>
/// <param name="e">the event data</param>
void HexBox_ByteProviderChanged(object sender, EventArgs e)
{
CheckBuiltInContextMenu();
}
/// <summary>
/// Assigns the ContextMenuStrip control to the HexBox control.
/// </summary>
void CheckBuiltInContextMenu()
{
if (Util.DesignMode)
return;
if (this._contextMenuStrip == null)
{
ContextMenuStrip cms = new ContextMenuStrip();
_cutToolStripMenuItem = new ToolStripMenuItem(CutMenuItemTextInternal, CutMenuItemImage, new EventHandler(CutMenuItem_Click));
cms.Items.Add(_cutToolStripMenuItem);
_copyToolStripMenuItem = new ToolStripMenuItem(CopyMenuItemTextInternal, CopyMenuItemImage, new EventHandler(CopyMenuItem_Click));
cms.Items.Add(_copyToolStripMenuItem);
_pasteToolStripMenuItem = new ToolStripMenuItem(PasteMenuItemTextInternal, PasteMenuItemImage, new EventHandler(PasteMenuItem_Click));
cms.Items.Add(_pasteToolStripMenuItem);
cms.Items.Add(new ToolStripSeparator());
_selectAllToolStripMenuItem = new ToolStripMenuItem(SelectAllMenuItemTextInternal, SelectAllMenuItemImage, new EventHandler(SelectAllMenuItem_Click));
cms.Items.Add(_selectAllToolStripMenuItem);
cms.Opening += new CancelEventHandler(BuildInContextMenuStrip_Opening);
_contextMenuStrip = cms;
}
if (this._hexBox.ByteProvider == null && this._hexBox.ContextMenuStrip == this._contextMenuStrip)
this._hexBox.ContextMenuStrip = null;
else if (this._hexBox.ByteProvider != null && this._hexBox.ContextMenuStrip == null)
this._hexBox.ContextMenuStrip = _contextMenuStrip;
}
/// <summary>
/// Before opening the ContextMenuStrip, we manage the availability of the items.
/// </summary>
/// <param name="sender">the sender object</param>
/// <param name="e">the event data</param>
void BuildInContextMenuStrip_Opening(object sender, CancelEventArgs e)
{
_cutToolStripMenuItem.Enabled = this._hexBox.CanCut();
_copyToolStripMenuItem.Enabled = this._hexBox.CanCopy();
_pasteToolStripMenuItem.Enabled = this._hexBox.CanPaste();
_selectAllToolStripMenuItem.Enabled = this._hexBox.CanSelectAll();
}
/// <summary>
/// The handler for the "Cut"-Click event
/// </summary>
/// <param name="sender">the sender object</param>
/// <param name="e">the event data</param>
void CutMenuItem_Click(object sender, EventArgs e) { this._hexBox.Cut(); }
/// <summary>
/// The handler for the "Copy"-Click event
/// </summary>
/// <param name="sender">the sender object</param>
/// <param name="e">the event data</param>
void CopyMenuItem_Click(object sender, EventArgs e) { this._hexBox.Copy(); }
/// <summary>
/// The handler for the "Paste"-Click event
/// </summary>
/// <param name="sender">the sender object</param>
/// <param name="e">the event data</param>
void PasteMenuItem_Click(object sender, EventArgs e) { this._hexBox.Paste(); }
/// <summary>
/// The handler for the "Select All"-Click event
/// </summary>
/// <param name="sender">the sender object</param>
/// <param name="e">the event data</param>
void SelectAllMenuItem_Click(object sender, EventArgs e) { this._hexBox.SelectAll(); }
/// <summary>
/// Gets or sets the custom text of the "Copy" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
public string CopyMenuItemText
{
get { return _copyMenuItemText; }
set { _copyMenuItemText = value; }
} string _copyMenuItemText;
/// <summary>
/// Gets or sets the custom text of the "Cut" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
public string CutMenuItemText
{
get { return _cutMenuItemText; }
set { _cutMenuItemText = value; }
} string _cutMenuItemText;
/// <summary>
/// Gets or sets the custom text of the "Paste" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
public string PasteMenuItemText
{
get { return _pasteMenuItemText; }
set { _pasteMenuItemText = value; }
} string _pasteMenuItemText;
/// <summary>
/// Gets or sets the custom text of the "Select All" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null), Localizable(true)]
public string SelectAllMenuItemText
{
get { return _selectAllMenuItemText; }
set { _selectAllMenuItemText = value; }
} string _selectAllMenuItemText = null;
/// <summary>
/// Gets the text of the "Cut" ContextMenuStrip item.
/// </summary>
internal string CutMenuItemTextInternal { get { return !string.IsNullOrEmpty(CutMenuItemText) ? CutMenuItemText : "Cut"; } }
/// <summary>
/// Gets the text of the "Copy" ContextMenuStrip item.
/// </summary>
internal string CopyMenuItemTextInternal { get { return !string.IsNullOrEmpty(CopyMenuItemText) ? CopyMenuItemText : "Copy"; } }
/// <summary>
/// Gets the text of the "Paste" ContextMenuStrip item.
/// </summary>
internal string PasteMenuItemTextInternal { get { return !string.IsNullOrEmpty(PasteMenuItemText) ? PasteMenuItemText : "Paste"; } }
/// <summary>
/// Gets the text of the "Select All" ContextMenuStrip item.
/// </summary>
internal string SelectAllMenuItemTextInternal { get { return !string.IsNullOrEmpty(SelectAllMenuItemText) ? SelectAllMenuItemText : "Select All"; } }
/// <summary>
/// Gets or sets the image of the "Cut" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
public Image CutMenuItemImage
{
get { return _cutMenuItemImage; }
set { _cutMenuItemImage = value; }
} Image _cutMenuItemImage = null;
/// <summary>
/// Gets or sets the image of the "Copy" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
public Image CopyMenuItemImage
{
get { return _copyMenuItemImage; }
set { _copyMenuItemImage = value; }
} Image _copyMenuItemImage = null;
/// <summary>
/// Gets or sets the image of the "Paste" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
public Image PasteMenuItemImage
{
get { return _pasteMenuItemImage; }
set { _pasteMenuItemImage = value; }
} Image _pasteMenuItemImage = null;
/// <summary>
/// Gets or sets the image of the "Select All" ContextMenuStrip item.
/// </summary>
[Category("BuiltIn-ContextMenu"), DefaultValue(null)]
public Image SelectAllMenuItemImage
{
get { return _selectAllMenuItemImage; }
set { _selectAllMenuItemImage = value; }
} Image _selectAllMenuItemImage = null;
}
}

View file

@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Be.Windows.Forms
{
/// <summary>
/// The interface for objects that can translate between characters and bytes.
/// </summary>
public interface IByteCharConverter
{
/// <summary>
/// Returns the character to display for the byte passed across.
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
string ToChar(UInt64 value, out int keyLength);
/// <summary>
/// Returns the byte to use when the character passed across is entered during editing.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
byte ToByte(char c);
byte[] GetBytes(string str);
}
/// <summary>
/// The default <see cref="IByteCharConverter"/> implementation.
/// </summary>
public class DefaultByteCharConverter : IByteCharConverter
{
/// <summary>
/// Returns the character to display for the byte passed across.
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public virtual string ToChar(UInt64 value, out int keyLength)
{
keyLength = 1;
byte b = (byte)value;
return new string(b > 0x1F && !(b > 0x7E && b < 0xA0) ? (char)b : '.', 1);
}
/// <summary>
/// Returns the byte to use for the character passed across.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public virtual byte ToByte(char c)
{
return (byte)c;
}
public virtual byte[] GetBytes(string str)
{
List<byte> bytes = new List<byte>(str.Length);
foreach(char c in str) {
bytes.Add((byte)c);
}
return bytes.ToArray();
}
/// <summary>
/// Returns a description of the byte char provider.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "ANSI (Default)";
}
}
/// <summary>
/// A byte char provider that can translate bytes encoded in codepage 500 EBCDIC
/// </summary>
public class EbcdicByteCharProvider : IByteCharConverter
{
/// <summary>
/// The IBM EBCDIC code page 500 encoding. Note that this is not always supported by .NET,
/// the underlying platform has to provide support for it.
/// </summary>
private Encoding _ebcdicEncoding = Encoding.GetEncoding(500);
/// <summary>
/// Returns the EBCDIC character corresponding to the byte passed across.
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public virtual string ToChar(UInt64 value, out int keyLength)
{
keyLength = 1;
byte b = (byte)value;
string encoded = _ebcdicEncoding.GetString(new byte[] { b });
return new string(encoded.Length > 0 ? encoded[0] : '.', 1);
}
/// <summary>
/// Returns the byte corresponding to the EBCDIC character passed across.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public virtual byte ToByte(char c)
{
byte[] decoded = _ebcdicEncoding.GetBytes(new char[] { c });
return decoded.Length > 0 ? decoded[0] : (byte)0;
}
public virtual byte[] GetBytes(string str)
{
List<byte> bytes = new List<byte>(str.Length);
foreach(char c in str) {
bytes.Add((byte)c);
}
return bytes.ToArray();
}
/// <summary>
/// Returns a description of the byte char provider.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "EBCDIC (Code Page 500)";
}
}
}

View file

@ -0,0 +1,127 @@
using System;
using System.Collections;
namespace Be.Windows.Forms
{
/// <summary>
/// Represents a collection of bytes.
/// </summary>
public class ByteCollection : CollectionBase
{
/// <summary>
/// Initializes a new instance of ByteCollection class.
/// </summary>
public ByteCollection() { }
/// <summary>
/// Initializes a new instance of ByteCollection class.
/// </summary>
/// <param name="bs">an array of bytes to add to collection</param>
public ByteCollection(byte[] bs)
{ AddRange(bs); }
/// <summary>
/// Gets or sets the value of a byte
/// </summary>
public byte this[int index]
{
get { return (byte)List[index]; }
set { List[index] = value; }
}
/// <summary>
/// Adds a byte into the collection.
/// </summary>
/// <param name="b">the byte to add</param>
public void Add(byte b)
{ List.Add(b); }
/// <summary>
/// Adds a range of bytes to the collection.
/// </summary>
/// <param name="bs">the bytes to add</param>
public void AddRange(byte[] bs)
{ InnerList.AddRange(bs); }
/// <summary>
/// Removes a byte from the collection.
/// </summary>
/// <param name="b">the byte to remove</param>
public void Remove(byte b)
{ List.Remove(b); }
/// <summary>
/// Removes a range of bytes from the collection.
/// </summary>
/// <param name="index">the index of the start byte</param>
/// <param name="count">the count of the bytes to remove</param>
public void RemoveRange(int index, int count)
{ InnerList.RemoveRange(index, count); }
/// <summary>
/// Inserts a range of bytes to the collection.
/// </summary>
/// <param name="index">the index of start byte</param>
/// <param name="bs">an array of bytes to insert</param>
public void InsertRange(int index, byte[] bs)
{ InnerList.InsertRange(index, bs); }
/// <summary>
/// Gets all bytes in the array
/// </summary>
/// <returns>an array of bytes.</returns>
public byte[] GetBytes()
{
byte[] bytes = new byte[Count];
InnerList.CopyTo(0, bytes, 0, bytes.Length);
return bytes;
}
/// <summary>
/// Inserts a byte to the collection.
/// </summary>
/// <param name="index">the index</param>
/// <param name="b">a byte to insert</param>
public void Insert(int index, byte b)
{
InnerList.Insert(index, b);
}
/// <summary>
/// Returns the index of the given byte.
/// </summary>
public int IndexOf(byte b)
{
return InnerList.IndexOf(b);
}
/// <summary>
/// Returns true, if the byte exists in the collection.
/// </summary>
public bool Contains(byte b)
{
return InnerList.Contains(b);
}
/// <summary>
/// Copies the content of the collection into the given array.
/// </summary>
public void CopyTo(byte[] bs, int index)
{
InnerList.CopyTo(bs, index);
}
/// <summary>
/// Copies the content of the collection into an array.
/// </summary>
/// <returns>the array containing all bytes.</returns>
public byte[] ToArray()
{
byte[] data = new byte[this.Count];
this.CopyTo(data, 0);
return data;
}
}
}

View file

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Be.Windows.Forms
{
/// <summary>
/// Represents a position in the HexBox control
/// </summary>
internal struct BytePositionInfo
{
public BytePositionInfo(long index, int characterPosition)
{
_index = index;
_characterPosition = characterPosition;
}
public int CharacterPosition
{
get { return _characterPosition; }
} int _characterPosition;
public long Index
{
get { return _index; }
} long _index;
}
}

View file

@ -0,0 +1,42 @@
using System;
namespace Be.Windows.Forms
{
internal abstract class DataBlock
{
internal DataMap _map;
internal DataBlock _nextBlock;
internal DataBlock _previousBlock;
public abstract long Length
{
get;
}
public DataMap Map
{
get
{
return _map;
}
}
public DataBlock NextBlock
{
get
{
return _nextBlock;
}
}
public DataBlock PreviousBlock
{
get
{
return _previousBlock;
}
}
public abstract void RemoveBytes(long position, long count);
}
}

View file

@ -0,0 +1,318 @@
using System;
using System.Collections;
using System.Text;
namespace Be.Windows.Forms
{
internal class DataMap : ICollection, IEnumerable
{
readonly object _syncRoot = new object();
internal int _count;
internal DataBlock _firstBlock;
internal int _version;
public DataMap()
{
}
public DataMap(IEnumerable collection)
{
if (collection == null)
{
throw new ArgumentNullException("collection");
}
foreach (DataBlock item in collection)
{
AddLast(item);
}
}
public DataBlock FirstBlock
{
get
{
return _firstBlock;
}
}
public void AddAfter(DataBlock block, DataBlock newBlock)
{
AddAfterInternal(block, newBlock);
}
public void AddBefore(DataBlock block, DataBlock newBlock)
{
AddBeforeInternal(block, newBlock);
}
public void AddFirst(DataBlock block)
{
if (_firstBlock == null)
{
AddBlockToEmptyMap(block);
}
else
{
AddBeforeInternal(_firstBlock, block);
}
}
public void AddLast(DataBlock block)
{
if (_firstBlock == null)
{
AddBlockToEmptyMap(block);
}
else
{
AddAfterInternal(GetLastBlock(), block);
}
}
public void Remove(DataBlock block)
{
RemoveInternal(block);
}
public void RemoveFirst()
{
if (_firstBlock == null)
{
throw new InvalidOperationException("The collection is empty.");
}
RemoveInternal(_firstBlock);
}
public void RemoveLast()
{
if (_firstBlock == null)
{
throw new InvalidOperationException("The collection is empty.");
}
RemoveInternal(GetLastBlock());
}
public DataBlock Replace(DataBlock block, DataBlock newBlock)
{
AddAfterInternal(block, newBlock);
RemoveInternal(block);
return newBlock;
}
public void Clear()
{
DataBlock block = FirstBlock;
while (block != null)
{
DataBlock nextBlock = block.NextBlock;
InvalidateBlock(block);
block = nextBlock;
}
_firstBlock = null;
_count = 0;
_version++;
}
void AddAfterInternal(DataBlock block, DataBlock newBlock)
{
newBlock._previousBlock = block;
newBlock._nextBlock = block._nextBlock;
newBlock._map = this;
if (block._nextBlock != null)
{
block._nextBlock._previousBlock = newBlock;
}
block._nextBlock = newBlock;
this._version++;
this._count++;
}
void AddBeforeInternal(DataBlock block, DataBlock newBlock)
{
newBlock._nextBlock = block;
newBlock._previousBlock = block._previousBlock;
newBlock._map = this;
if (block._previousBlock != null)
{
block._previousBlock._nextBlock = newBlock;
}
block._previousBlock = newBlock;
if (_firstBlock == block)
{
_firstBlock = newBlock;
}
this._version++;
this._count++;
}
void RemoveInternal(DataBlock block)
{
DataBlock previousBlock = block._previousBlock;
DataBlock nextBlock = block._nextBlock;
if (previousBlock != null)
{
previousBlock._nextBlock = nextBlock;
}
if (nextBlock != null)
{
nextBlock._previousBlock = previousBlock;
}
if (_firstBlock == block)
{
_firstBlock = nextBlock;
}
InvalidateBlock(block);
_count--;
_version++;
}
DataBlock GetLastBlock()
{
DataBlock lastBlock = null;
for (DataBlock block = FirstBlock; block != null; block = block.NextBlock)
{
lastBlock = block;
}
return lastBlock;
}
void InvalidateBlock(DataBlock block)
{
block._map = null;
block._nextBlock = null;
block._previousBlock = null;
}
void AddBlockToEmptyMap(DataBlock block)
{
block._map = this;
block._nextBlock = null;
block._previousBlock = null;
_firstBlock = block;
_version++;
_count++;
}
#region ICollection Members
public void CopyTo(Array array, int index)
{
DataBlock[] blockArray = array as DataBlock[];
for (DataBlock block = FirstBlock; block != null; block = block.NextBlock)
{
blockArray[index++] = block;
}
}
public int Count
{
get
{
return _count;
}
}
public bool IsSynchronized
{
get
{
return false;
}
}
public object SyncRoot
{
get
{
return _syncRoot;
}
}
#endregion
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
return new Enumerator(this);
}
#endregion
#region Enumerator Nested Type
internal class Enumerator : IEnumerator, IDisposable
{
DataMap _map;
DataBlock _current;
int _index;
int _version;
internal Enumerator(DataMap map)
{
_map = map;
_version = map._version;
_current = null;
_index = -1;
}
object IEnumerator.Current
{
get
{
if (_index < 0 || _index > _map.Count)
{
throw new InvalidOperationException("Enumerator is positioned before the first element or after the last element of the collection.");
}
return _current;
}
}
public bool MoveNext()
{
if (this._version != _map._version)
{
throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
}
if (_index >= _map.Count)
{
return false;
}
if (++_index == 0)
{
_current = _map.FirstBlock;
}
else
{
_current = _current.NextBlock;
}
return (_index < _map.Count);
}
void IEnumerator.Reset()
{
if (this._version != this._map._version)
{
throw new InvalidOperationException("Collection was modified after the enumerator was instantiated.");
}
this._index = -1;
this._current = null;
}
public void Dispose()
{
}
}
#endregion
}
}

View file

@ -0,0 +1,226 @@
using System;
using System.Collections.Generic;
namespace Be.Windows.Forms
{
/// <summary>
/// Byte provider for a small amount of data.
/// </summary>
public class DynamicByteProvider : IByteProvider
{
/// <summary>
/// Contains information about changes.
/// </summary>
bool _hasChanges;
/// <summary>
/// Contains a byte collection.
/// </summary>
List<byte> _bytes;
/// <summary>
/// Initializes a new instance of the DynamicByteProvider class.
/// </summary>
/// <param name="data"></param>
public DynamicByteProvider(byte[] data) : this(new List<Byte>(data))
{
}
/// <summary>
/// Initializes a new instance of the DynamicByteProvider class.
/// </summary>
/// <param name="bytes"></param>
public DynamicByteProvider(List<Byte> bytes)
{
_bytes = bytes;
}
public void SetData(byte[] data)
{
_bytes = new List<byte>(data);
}
/// <summary>
/// Raises the Changed event.
/// </summary>
void OnChanged(EventArgs e)
{
_hasChanges = true;
if(Changed != null)
Changed(this, e);
}
/// <summary>
/// Raises the LengthChanged event.
/// </summary>
void OnLengthChanged(EventArgs e)
{
if(LengthChanged != null)
LengthChanged(this, e);
}
/// <summary>
/// Gets the byte collection.
/// </summary>
public List<Byte> Bytes
{
get { return _bytes; }
}
#region IByteProvider Members
/// <summary>
/// True, when changes are done.
/// </summary>
public bool HasChanges()
{
return _hasChanges;
}
/// <summary>
/// Applies changes.
/// </summary>
public void ApplyChanges()
{
_hasChanges = false;
}
/// <summary>
/// Occurs, when the write buffer contains new changes.
/// </summary>
public event EventHandler Changed;
/// <summary>
/// Occurs, when InsertBytes or DeleteBytes method is called.
/// </summary>
public event EventHandler LengthChanged;
public delegate void ByteChangedHandler(int byteIndex, byte newValue, byte oldValue);
public event ByteChangedHandler ByteChanged;
public delegate void BytesChangedHandler(int byteIndex, byte[] values);
public event BytesChangedHandler BytesChanged;
/// <summary>
/// Reads a byte from the byte collection.
/// </summary>
/// <param name="index">the index of the byte to read</param>
/// <returns>the byte</returns>
public byte ReadByte(long index)
{
if(_partialPos == index) {
return _partialValue;
} else {
return _bytes[(int)index];
}
}
/// <summary>
/// Write a byte into the byte collection.
/// </summary>
/// <param name="index">the index of the byte to write.</param>
/// <param name="value">the byte</param>
public void WriteByte(long index, byte value)
{
if(index == _partialPos) {
_partialPos = -1;
}
if(_bytes[(int)index] != value) {
ByteChanged?.Invoke((int)index, value, _bytes[(int)index]);
_bytes[(int)index] = value;
OnChanged(EventArgs.Empty);
}
}
public void WriteBytes(long index, byte[] values)
{
_partialPos = -1;
BytesChanged?.Invoke((int)index, values);
for(int i = 0; i < values.Length && index + i < _bytes.Count; i++) {
_bytes[(int)index+i] = values[i];
}
}
long _partialPos = -1;
byte _partialValue = 0;
public void PartialWriteByte(long index, byte value)
{
//Wait for a full byte to be written
_partialPos = index;
_partialValue = value;
}
public void CommitWriteByte()
{
if(_partialPos >= 0) {
WriteByte(_partialPos, _partialValue);
_partialPos = -1;
}
}
/// <summary>
/// Deletes bytes from the byte collection.
/// </summary>
/// <param name="index">the start index of the bytes to delete.</param>
/// <param name="length">the length of bytes to delete.</param>
public void DeleteBytes(long index, long length)
{
int internal_index = (int)Math.Max(0, index);
int internal_length = (int)Math.Min((int)Length, length);
_bytes.RemoveRange(internal_index, internal_length);
OnLengthChanged(EventArgs.Empty);
OnChanged(EventArgs.Empty);
}
/// <summary>
/// Inserts byte into the byte collection.
/// </summary>
/// <param name="index">the start index of the bytes in the byte collection</param>
/// <param name="bs">the byte array to insert</param>
public void InsertBytes(long index, byte[] bs)
{
_bytes.InsertRange((int)index, bs);
OnLengthChanged(EventArgs.Empty);
OnChanged(EventArgs.Empty);
}
/// <summary>
/// Gets the length of the bytes in the byte collection.
/// </summary>
public long Length
{
get
{
return _bytes.Count;
}
}
/// <summary>
/// Returns true
/// </summary>
public virtual bool SupportsWriteByte()
{
return true;
}
/// <summary>
/// Returns true
/// </summary>
public virtual bool SupportsInsertBytes()
{
return true;
}
/// <summary>
/// Returns true
/// </summary>
public virtual bool SupportsDeleteBytes()
{
return true;
}
#endregion
}
}

View file

@ -0,0 +1,96 @@
using System;
namespace Be.Windows.Forms
{
internal sealed class FileDataBlock : DataBlock
{
long _length;
long _fileOffset;
public FileDataBlock(long fileOffset, long length)
{
_fileOffset = fileOffset;
_length = length;
}
public long FileOffset
{
get
{
return _fileOffset;
}
}
public override long Length
{
get
{
return _length;
}
}
public void SetFileOffset(long value)
{
_fileOffset = value;
}
public void RemoveBytesFromEnd(long count)
{
if (count > _length)
{
throw new ArgumentOutOfRangeException("count");
}
_length -= count;
}
public void RemoveBytesFromStart(long count)
{
if (count > _length)
{
throw new ArgumentOutOfRangeException("count");
}
_fileOffset += count;
_length -= count;
}
public override void RemoveBytes(long position, long count)
{
if (position > _length)
{
throw new ArgumentOutOfRangeException("position");
}
if (position + count > _length)
{
throw new ArgumentOutOfRangeException("count");
}
long prefixLength = position;
long prefixFileOffset = _fileOffset;
long suffixLength = _length - count - prefixLength;
long suffixFileOffset = _fileOffset + position + count;
if (prefixLength > 0 && suffixLength > 0)
{
_fileOffset = prefixFileOffset;
_length = prefixLength;
_map.AddAfter(this, new FileDataBlock(suffixFileOffset, suffixLength));
return;
}
if (prefixLength > 0)
{
_fileOffset = prefixFileOffset;
_length = prefixLength;
}
else
{
_fileOffset = suffixFileOffset;
_length = suffixLength;
}
}
}
}

View file

@ -0,0 +1,95 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Be.Windows.Forms
{
/// <summary>
/// Defines the type of the Find operation.
/// </summary>
public enum FindType
{
/// <summary>
/// Used for Text Find operations
/// </summary>
Text,
/// <summary>
/// Used for Hex Find operations
/// </summary>
Hex
}
/// <summary>
/// Defines all state information nee
/// </summary>
public class FindOptions
{
public bool WrapSearch { get; set; }
public bool HasWildcard { get; set; }
/// <summary>
/// Gets or sets whether the Find options are valid
/// </summary>
public bool IsValid { get; set; }
/// <summary>
/// Gets the Find buffer used for case insensitive Find operations. This is the binary representation of Text.
/// </summary>
internal byte[] FindBuffer { get; private set; }
/// <summary>
/// Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in lower case format.
/// </summary>
internal byte[] FindBufferLowerCase { get; private set; }
/// <summary>
/// Gets the Find buffer used for case sensitive Find operations. This is the binary representation of Text in upper case format.
/// </summary>
internal byte[] FindBufferUpperCase { get; private set; }
/// <summary>
/// Contains the MatchCase value
/// </summary>
bool _matchCase;
/// <summary>
/// Gets or sets the value, whether the Find operation is case sensitive or not.
/// </summary>
public bool MatchCase
{
get { return _matchCase; }
set
{
_matchCase = value;
}
}
/// <summary>
/// Contains the text that should be found.
/// </summary>
string _text;
/// <summary>
/// Gets or sets the text that should be found. Only used, when Type is FindType.Hex.
/// </summary>
public string Text
{
get { return _text; }
set
{
_text = value;
}
}
/// <summary>
/// Gets or sets the hex buffer that should be found. Only used, when Type is FindType.Hex.
/// </summary>
public byte[] Hex { get; set; }
/// <summary>
/// Gets or sets the type what should be searched.
/// </summary>
public FindType Type { get; set; }
/// <summary>
/// Updates the find buffer.
/// </summary>
internal void UpdateFindBuffer(IByteCharConverter byteCharConverter)
{
string text = this.Text != null ? this.Text : string.Empty;
FindBuffer = byteCharConverter.GetBytes(text);
FindBufferLowerCase = byteCharConverter.GetBytes(text.ToLower());
FindBufferUpperCase = byteCharConverter.GetBytes(text.ToUpper());
}
}
}

4244
UI/Debugger/HexBox/HexBox.cs Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
<?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=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="contextMenuStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>

View file

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Be.Windows.Forms
{
/// <summary>
/// Specifies the case of hex characters in the HexBox control
/// </summary>
public enum HexCasing
{
/// <summary>
/// Converts all characters to uppercase.
/// </summary>
Upper = 0,
/// <summary>
/// Converts all characters to lowercase.
/// </summary>
Lower = 1
}
}

View file

@ -0,0 +1,18 @@
using System;
using System.Drawing;
namespace Be.Windows.Forms
{
public interface IByteColorProvider
{
void Prepare(long firstByteIndex, long lastByteIndex);
ByteColors GetByteColor(long firstByteIndex, long byteIndex);
}
public class ByteColors
{
public Color ForeColor { get; set; }
public Color BackColor { get; set; }
public Color BorderColor { get; set; }
}
}

View file

@ -0,0 +1,81 @@
using System;
namespace Be.Windows.Forms
{
/// <summary>
/// Defines a byte provider for HexBox control
/// </summary>
public interface IByteProvider
{
/// <summary>
/// Reads a byte from the provider
/// </summary>
/// <param name="index">the index of the byte to read</param>
/// <returns>the byte to read</returns>
byte ReadByte(long index);
/// <summary>
/// Writes a byte into the provider
/// </summary>
/// <param name="index">the index of the byte to write</param>
/// <param name="value">the byte to write</param>
void WriteByte(long index, byte value);
void WriteBytes(long index, byte[] values);
void PartialWriteByte(long index, byte value);
void CommitWriteByte();
/// <summary>
/// Inserts bytes into the provider
/// </summary>
/// <param name="index"></param>
/// <param name="bs"></param>
/// <remarks>This method must raise the LengthChanged event.</remarks>
void InsertBytes(long index, byte[] bs);
/// <summary>
/// Deletes bytes from the provider
/// </summary>
/// <param name="index">the start index of the bytes to delete</param>
/// <param name="length">the length of the bytes to delete</param>
/// <remarks>This method must raise the LengthChanged event.</remarks>
void DeleteBytes(long index, long length);
/// <summary>
/// Returns the total length of bytes the byte provider is providing.
/// </summary>
long Length { get; }
/// <summary>
/// Occurs, when the Length property changed.
/// </summary>
event EventHandler LengthChanged;
/// <summary>
/// True, when changes are done.
/// </summary>
bool HasChanges();
/// <summary>
/// Applies changes.
/// </summary>
void ApplyChanges();
/// <summary>
/// Occurs, when bytes are changed.
/// </summary>
event EventHandler Changed;
/// <summary>
/// Returns a value if the WriteByte methods is supported by the provider.
/// </summary>
/// <returns>True, when it´s supported.</returns>
bool SupportsWriteByte();
/// <summary>
/// Returns a value if the InsertBytes methods is supported by the provider.
/// </summary>
/// <returns>True, when it´s supported.</returns>
bool SupportsInsertBytes();
/// <summary>
/// Returns a value if the DeleteBytes methods is supported by the provider.
/// </summary>
/// <returns>True, when it´s supported.</returns>
bool SupportsDeleteBytes();
}
}

View file

@ -0,0 +1,87 @@
using System;
namespace Be.Windows.Forms
{
internal sealed class MemoryDataBlock : DataBlock
{
byte[] _data;
public MemoryDataBlock(byte data)
{
_data = new byte[] { data };
}
public MemoryDataBlock(byte[] data)
{
if (data == null)
{
throw new ArgumentNullException("data");
}
_data = (byte[])data.Clone();
}
public override long Length
{
get
{
return _data.LongLength;
}
}
public byte[] Data
{
get
{
return _data;
}
}
public void AddByteToEnd(byte value)
{
byte[] newData = new byte[_data.LongLength + 1];
_data.CopyTo(newData, 0);
newData[newData.LongLength - 1] = value;
_data = newData;
}
public void AddByteToStart(byte value)
{
byte[] newData = new byte[_data.LongLength + 1];
newData[0] = value;
_data.CopyTo(newData, 1);
_data = newData;
}
public void InsertBytes(long position, byte[] data)
{
byte[] newData = new byte[_data.LongLength + data.LongLength];
if (position > 0)
{
Array.Copy(_data, 0, newData, 0, position);
}
Array.Copy(data, 0, newData, position, data.LongLength);
if (position < _data.LongLength)
{
Array.Copy(_data, position, newData, position + data.LongLength, _data.LongLength - position);
}
_data = newData;
}
public override void RemoveBytes(long position, long count)
{
byte[] newData = new byte[_data.LongLength - count];
if (position > 0)
{
Array.Copy(_data, 0, newData, 0, position);
}
if (position + count < _data.LongLength)
{
Array.Copy(_data, position + count, newData, position, newData.LongLength - position);
}
_data = newData;
}
}
}

View file

@ -0,0 +1,14 @@
using System;
using System.Drawing;
using System.Runtime.InteropServices;
namespace Be.Windows.Forms
{
internal static class NativeMethods
{
// Key definitions
public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
public const int WM_CHAR = 0x102;
}
}

View file

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Be.Windows.Forms
{
public class StaticByteProvider : DynamicByteProvider
{
public StaticByteProvider(byte[] data) : base(data)
{
}
public override bool SupportsInsertBytes()
{
return false;
}
public override bool SupportsDeleteBytes()
{
return false;
}
}
}

View file

@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static Mesen.GUI.Debugger.TblLoader;
namespace Be.Windows.Forms
{
/// <summary>
/// The default <see cref="IByteCharConverter"/> implementation.
/// </summary>
class TblByteCharConverter : IByteCharConverter
{
Dictionary<TblKey, string> _tblRules;
Dictionary<string, TblKey> _reverseTblRules;
List<string> _stringList;
bool[] _hasPotentialRule = new bool[256];
public TblByteCharConverter(Dictionary<TblKey, string> tblRules)
{
this._tblRules = tblRules;
foreach(KeyValuePair<TblKey, string> kvp in tblRules) {
_hasPotentialRule[kvp.Key.Key & 0xFF] = true;
}
this._stringList = new List<string>();
this._reverseTblRules = new Dictionary<string, TblKey>();
foreach(KeyValuePair<TblKey, string> kvp in tblRules) {
this._stringList.Add(kvp.Value);
this._reverseTblRules[kvp.Value] = kvp.Key;
}
this._stringList.Sort(new Comparison<string>((a, b) => {
if(a.Length > b.Length) {
return 1;
} else if(a.Length < b.Length) {
return -1;
} else {
return string.Compare(a, b);
}
}));
}
/// <summary>
/// Returns the character to display for the byte passed across.
/// </summary>
/// <param name="b"></param>
/// <returns></returns>
public virtual string ToChar(UInt64 value, out int keyLength)
{
if(!_hasPotentialRule[value & 0xFF]) {
keyLength = 1;
return ".";
}
int byteCount = 8;
string result;
while(!_tblRules.TryGetValue(new TblKey() { Key = value, Length = byteCount }, out result) && byteCount > 0) {
value &= ~(((UInt64)0xFF) << (8 * (byteCount - 1)));
byteCount--;
}
if(result != null) {
keyLength = byteCount;
return result;
} else {
keyLength = 1;
return ".";
}
}
public virtual byte[] GetBytes(string text)
{
List<byte> bytes = new List<byte>();
bool match = false;
while(text.Length > 0) {
do {
match = false;
foreach(string key in _stringList) {
//Without an ordinal comparison, it's possible for an empty string to "StartsWith" a non-empty string (e.g replacement char U+FFFD)
//This causes a crash here (because key.Length > text.Length)
if(text.StartsWith(key, StringComparison.Ordinal)) {
bytes.AddRange(_reverseTblRules[key].GetBytes());
text = text.Substring(key.Length);
match = true;
break;
}
}
} while(match);
if(!match && text.Length > 0) {
bytes.Add(0);
text = text.Substring(1);
}
}
return bytes.ToArray();
}
/// <summary>
/// Returns the byte to use for the character passed across.
/// </summary>
/// <param name="c"></param>
/// <returns></returns>
public virtual byte ToByte(char c)
{
return (byte)c;
}
/// <summary>
/// Returns a description of the byte char provider.
/// </summary>
/// <returns></returns>
public override string ToString()
{
return "TBL";
}
}
}

View file

@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Be.Windows.Forms
{
static class Util
{
/// <summary>
/// Contains true, if we are in design mode of Visual Studio
/// </summary>
private static bool _designMode;
/// <summary>
/// Initializes an instance of Util class
/// </summary>
static Util()
{
// design mode is true if host process is: Visual Studio, Visual Studio Express Versions (C#, VB, C++) or SharpDevelop
var designerHosts = new List<string>() { "devenv", "vcsexpress", "vbexpress", "vcexpress", "sharpdevelop" };
using (var process = System.Diagnostics.Process.GetCurrentProcess())
{
var processName = process.ProcessName.ToLower();
_designMode = designerHosts.Contains(processName);
}
}
/// <summary>
/// Gets true, if we are in design mode of Visual Studio
/// </summary>
/// <remarks>
/// In Visual Studio 2008 SP1 the designer is crashing sometimes on windows forms.
/// The DesignMode property of Control class is buggy and cannot be used, so use our own implementation instead.
/// </remarks>
public static bool DesignMode
{
get
{
return _designMode;
}
}
}
}

61
UI/Debugger/TblLoader.cs Normal file
View file

@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Mesen.GUI.Debugger
{
public class TblLoader
{
public struct TblKey
{
public UInt64 Key;
public int Length;
public byte[] GetBytes()
{
byte[] bytes = new byte[this.Length];
UInt64 value = this.Key;
for(int i = 0; i < this.Length; i++) {
bytes[i] = (byte)value;
value >>= 8;
}
return bytes;
}
}
public static Dictionary<TblKey, string> ToDictionary(string[] fileContents)
{
try {
Dictionary<TblKey, string> dict = new Dictionary<TblKey, string>();
for(int i = 0; i < fileContents.Length; i++) {
if(!string.IsNullOrWhiteSpace(fileContents[i])) {
string[] data = fileContents[i].Split('=');
if(data.Length == 2) {
data[0] = data[0].Replace(" ", "");
if(data[0].Length % 2 == 0 && Regex.IsMatch(data[0], "[0-9A-Fa-f]+")) {
TblKey key = new TblKey();
for(int j = 0; j < data[0].Length; j+=2) {
byte result = byte.Parse(data[0].Substring(j, 2), System.Globalization.NumberStyles.HexNumber);
key.Key |= (UInt64)result << (8 * j / 2);
key.Length++;
}
dict[key] = string.IsNullOrEmpty(data[1]) ? " " : data[1];
}
}
}
}
return dict;
} catch {
return null;
}
}
}
}

View file

@ -0,0 +1,161 @@
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmDbgPreferences : BaseConfigForm
{
public frmDbgPreferences()
{
InitializeComponent();
ctrlDbgShortcutsShared.Shortcuts = new FieldInfo[] {
GetMember(nameof(DebuggerShortcutsConfig.IncreaseFontSize)),
GetMember(nameof(DebuggerShortcutsConfig.DecreaseFontSize)),
GetMember(nameof(DebuggerShortcutsConfig.ResetFontSize)),
GetMember(nameof(DebuggerShortcutsConfig.GoTo)),
GetMember(nameof(DebuggerShortcutsConfig.Find)),
GetMember(nameof(DebuggerShortcutsConfig.FindNext)),
GetMember(nameof(DebuggerShortcutsConfig.FindPrev)),
GetMember(nameof(DebuggerShortcutsConfig.Undo)),
GetMember(nameof(DebuggerShortcutsConfig.Cut)),
GetMember(nameof(DebuggerShortcutsConfig.Copy)),
GetMember(nameof(DebuggerShortcutsConfig.Paste)),
GetMember(nameof(DebuggerShortcutsConfig.SelectAll)),
GetMember(nameof(DebuggerShortcutsConfig.Refresh)),
GetMember(nameof(DebuggerShortcutsConfig.MarkAsCode)),
GetMember(nameof(DebuggerShortcutsConfig.MarkAsData)),
GetMember(nameof(DebuggerShortcutsConfig.MarkAsUnidentified)),
GetMember(nameof(DebuggerShortcutsConfig.GoToAll)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInDisassembly)),
GetMember(nameof(DebuggerShortcutsConfig.PpuViewer_ToggleView)),
GetMember(nameof(DebuggerShortcutsConfig.PpuViewer_ToggleZoom)),
GetMember(nameof(DebuggerShortcutsConfig.OpenApuViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenAssembler)),
GetMember(nameof(DebuggerShortcutsConfig.OpenDebugger)),
GetMember(nameof(DebuggerShortcutsConfig.OpenEventViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenMemoryTools)),
GetMember(nameof(DebuggerShortcutsConfig.OpenProfiler)),
GetMember(nameof(DebuggerShortcutsConfig.OpenPpuViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenScriptWindow)),
GetMember(nameof(DebuggerShortcutsConfig.OpenTextHooker)),
GetMember(nameof(DebuggerShortcutsConfig.OpenTraceLogger)),
GetMember(nameof(DebuggerShortcutsConfig.OpenWatchWindow)),
GetMember(nameof(DebuggerShortcutsConfig.OpenNametableViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenChrViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenSpriteViewer)),
GetMember(nameof(DebuggerShortcutsConfig.OpenPaletteViewer)),
};
ctrlDbgShortcutsMemoryViewer.Shortcuts = new FieldInfo[] {
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Freeze)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Unfreeze)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_AddToWatch)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_EditBreakpoint)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_EditLabel)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Import)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_Export)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInCpuMemory)),
GetMember(nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInMemoryType))
};
ctrlDbgShortcutsScriptWindow.Shortcuts = new FieldInfo[] {
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_OpenScript)),
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_SaveScript)),
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_RunScript)),
GetMember(nameof(DebuggerShortcutsConfig.ScriptWindow_StopScript))
};
ctrlDbgShortcutsDebugger.Shortcuts = new FieldInfo[] {
GetMember(nameof(DebuggerShortcutsConfig.Reset)),
GetMember(nameof(DebuggerShortcutsConfig.PowerCycle)),
GetMember(nameof(DebuggerShortcutsConfig.Continue)),
GetMember(nameof(DebuggerShortcutsConfig.Break)),
GetMember(nameof(DebuggerShortcutsConfig.ToggleBreakContinue)),
GetMember(nameof(DebuggerShortcutsConfig.StepInto)),
GetMember(nameof(DebuggerShortcutsConfig.StepOver)),
GetMember(nameof(DebuggerShortcutsConfig.StepOut)),
GetMember(nameof(DebuggerShortcutsConfig.StepBack)),
GetMember(nameof(DebuggerShortcutsConfig.RunPpuCycle)),
GetMember(nameof(DebuggerShortcutsConfig.RunPpuScanline)),
GetMember(nameof(DebuggerShortcutsConfig.RunPpuFrame)),
GetMember(nameof(DebuggerShortcutsConfig.BreakIn)),
GetMember(nameof(DebuggerShortcutsConfig.BreakOn)),
GetMember(nameof(DebuggerShortcutsConfig.FindOccurrences)),
GetMember(nameof(DebuggerShortcutsConfig.GoToProgramCounter)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_SetNextStatement)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditSubroutine)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditSelectedCode)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditSourceFile)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_EditLabel)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_NavigateBack)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_NavigateForward)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_ToggleBreakpoint)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_DisableEnableBreakpoint)),
GetMember(nameof(DebuggerShortcutsConfig.CodeWindow_SwitchView)),
GetMember(nameof(DebuggerShortcutsConfig.FunctionList_EditLabel)),
GetMember(nameof(DebuggerShortcutsConfig.FunctionList_AddBreakpoint)),
GetMember(nameof(DebuggerShortcutsConfig.FunctionList_FindOccurrences)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_Add)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_Edit)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_Delete)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_AddBreakpoint)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_AddToWatch)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_FindOccurrences)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_ViewInCpuMemory)),
GetMember(nameof(DebuggerShortcutsConfig.LabelList_ViewInMemoryType)),
GetMember(nameof(DebuggerShortcutsConfig.BreakpointList_Add)),
GetMember(nameof(DebuggerShortcutsConfig.BreakpointList_Edit)),
GetMember(nameof(DebuggerShortcutsConfig.BreakpointList_GoToLocation)),
GetMember(nameof(DebuggerShortcutsConfig.BreakpointList_Delete)),
GetMember(nameof(DebuggerShortcutsConfig.WatchList_Delete)),
GetMember(nameof(DebuggerShortcutsConfig.WatchList_MoveUp)),
GetMember(nameof(DebuggerShortcutsConfig.WatchList_MoveDown)),
GetMember(nameof(DebuggerShortcutsConfig.SaveRom)),
GetMember(nameof(DebuggerShortcutsConfig.SaveRomAs)),
GetMember(nameof(DebuggerShortcutsConfig.SaveEditAsIps)),
GetMember(nameof(DebuggerShortcutsConfig.RevertPrgChrChanges)),
GetMember(nameof(DebuggerShortcutsConfig.ToggleVerifiedData)),
GetMember(nameof(DebuggerShortcutsConfig.ToggleUnidentifiedCodeData))
};
}
private FieldInfo GetMember(string name)
{
return typeof(DebuggerShortcutsConfig).GetField(name);
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
if(DialogResult == DialogResult.OK) {
DebuggerShortcutsConfig.UpdateMenus();
}
}
private void btnReset_Click(object sender, EventArgs e)
{
DebuggerShortcutsConfig defaults = new DebuggerShortcutsConfig();
foreach(FieldInfo field in typeof(DebuggerShortcutsConfig).GetFields()) {
field.SetValue(ConfigManager.Config.Debug.Shortcuts, field.GetValue(defaults));
}
ctrlDbgShortcutsDebugger.InitializeGrid();
ctrlDbgShortcutsMemoryViewer.InitializeGrid();
ctrlDbgShortcutsScriptWindow.InitializeGrid();
ctrlDbgShortcutsShared.InitializeGrid();
}
}
}

188
UI/Debugger/frmDbgPreferences.designer.cs generated Normal file
View file

@ -0,0 +1,188 @@
namespace Mesen.GUI.Debugger
{
partial class frmDbgPreferences
{
/// <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.ctrlDbgShortcutsShared = new Mesen.GUI.Debugger.ctrlDbgShortcuts();
this.tabMain = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.ctrlDbgShortcutsDebugger = new Mesen.GUI.Debugger.ctrlDbgShortcuts();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.ctrlDbgShortcutsMemoryViewer = new Mesen.GUI.Debugger.ctrlDbgShortcuts();
this.tabPage4 = new System.Windows.Forms.TabPage();
this.ctrlDbgShortcutsScriptWindow = new Mesen.GUI.Debugger.ctrlDbgShortcuts();
this.btnReset = new System.Windows.Forms.Button();
this.baseConfigPanel.SuspendLayout();
this.tabMain.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage3.SuspendLayout();
this.tabPage4.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Controls.Add(this.btnReset);
this.baseConfigPanel.Location = new System.Drawing.Point(0, 460);
this.baseConfigPanel.Size = new System.Drawing.Size(605, 29);
this.baseConfigPanel.Controls.SetChildIndex(this.btnReset, 0);
//
// ctrlDbgShortcutsShared
//
this.ctrlDbgShortcutsShared.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDbgShortcutsShared.Location = new System.Drawing.Point(3, 3);
this.ctrlDbgShortcutsShared.Name = "ctrlDbgShortcutsShared";
this.ctrlDbgShortcutsShared.Size = new System.Drawing.Size(591, 428);
this.ctrlDbgShortcutsShared.TabIndex = 2;
//
// tabMain
//
this.tabMain.Controls.Add(this.tabPage1);
this.tabMain.Controls.Add(this.tabPage2);
this.tabMain.Controls.Add(this.tabPage3);
this.tabMain.Controls.Add(this.tabPage4);
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabMain.Location = new System.Drawing.Point(0, 0);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(605, 460);
this.tabMain.TabIndex = 3;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.ctrlDbgShortcutsShared);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
this.tabPage1.Size = new System.Drawing.Size(597, 434);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Shared";
this.tabPage1.UseVisualStyleBackColor = true;
//
// tabPage2
//
this.tabPage2.Controls.Add(this.ctrlDbgShortcutsDebugger);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(597, 434);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Debugger";
this.tabPage2.UseVisualStyleBackColor = true;
//
// ctrlDbgShortcutsDebugger
//
this.ctrlDbgShortcutsDebugger.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDbgShortcutsDebugger.Location = new System.Drawing.Point(3, 3);
this.ctrlDbgShortcutsDebugger.Name = "ctrlDbgShortcutsDebugger";
this.ctrlDbgShortcutsDebugger.Size = new System.Drawing.Size(591, 428);
this.ctrlDbgShortcutsDebugger.TabIndex = 3;
//
// tabPage3
//
this.tabPage3.Controls.Add(this.ctrlDbgShortcutsMemoryViewer);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
this.tabPage3.Size = new System.Drawing.Size(597, 434);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Memory Viewer";
this.tabPage3.UseVisualStyleBackColor = true;
//
// ctrlDbgShortcutsMemoryViewer
//
this.ctrlDbgShortcutsMemoryViewer.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDbgShortcutsMemoryViewer.Location = new System.Drawing.Point(3, 3);
this.ctrlDbgShortcutsMemoryViewer.Name = "ctrlDbgShortcutsMemoryViewer";
this.ctrlDbgShortcutsMemoryViewer.Size = new System.Drawing.Size(591, 428);
this.ctrlDbgShortcutsMemoryViewer.TabIndex = 3;
//
// tabPage4
//
this.tabPage4.Controls.Add(this.ctrlDbgShortcutsScriptWindow);
this.tabPage4.Location = new System.Drawing.Point(4, 22);
this.tabPage4.Name = "tabPage4";
this.tabPage4.Padding = new System.Windows.Forms.Padding(3);
this.tabPage4.Size = new System.Drawing.Size(597, 434);
this.tabPage4.TabIndex = 3;
this.tabPage4.Text = "Script Window";
this.tabPage4.UseVisualStyleBackColor = true;
//
// ctrlDbgShortcutsScriptWindow
//
this.ctrlDbgShortcutsScriptWindow.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlDbgShortcutsScriptWindow.Location = new System.Drawing.Point(3, 3);
this.ctrlDbgShortcutsScriptWindow.Name = "ctrlDbgShortcutsScriptWindow";
this.ctrlDbgShortcutsScriptWindow.Size = new System.Drawing.Size(591, 428);
this.ctrlDbgShortcutsScriptWindow.TabIndex = 3;
//
// btnReset
//
this.btnReset.Location = new System.Drawing.Point(4, 3);
this.btnReset.Name = "btnReset";
this.btnReset.Size = new System.Drawing.Size(111, 23);
this.btnReset.TabIndex = 3;
this.btnReset.Text = "Reset to Defaults";
this.btnReset.UseVisualStyleBackColor = true;
this.btnReset.Click += new System.EventHandler(this.btnReset_Click);
//
// frmDbgPreferences
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(605, 489);
this.Controls.Add(this.tabMain);
this.Name = "frmDbgPreferences";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Configure Shortcut Keys";
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.Controls.SetChildIndex(this.tabMain, 0);
this.baseConfigPanel.ResumeLayout(false);
this.tabMain.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.tabPage3.ResumeLayout(false);
this.tabPage4.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private ctrlDbgShortcuts ctrlDbgShortcutsShared;
private System.Windows.Forms.TabControl tabMain;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private ctrlDbgShortcuts ctrlDbgShortcutsDebugger;
private System.Windows.Forms.TabPage tabPage3;
private ctrlDbgShortcuts ctrlDbgShortcutsMemoryViewer;
private System.Windows.Forms.TabPage tabPage4;
private ctrlDbgShortcuts ctrlDbgShortcutsScriptWindow;
private System.Windows.Forms.Button btnReset;
}
}

View 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>

View file

@ -0,0 +1,62 @@
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmDbgShortcutGetKey : BaseForm
{
private Keys[] _ignoredKeys = new Keys[9] {
Keys.LMenu, Keys.RMenu, Keys.Menu, Keys.LShiftKey, Keys.RShiftKey, Keys.ShiftKey, Keys.LControlKey, Keys.RControlKey, Keys.ControlKey
};
private Keys _shortcutKeys = Keys.None;
public Keys ShortcutKeys
{
get { return this._shortcutKeys; }
set { this._shortcutKeys = value; }
}
public frmDbgShortcutGetKey()
{
InitializeComponent();
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
foreach(Keys ignoredKey in _ignoredKeys) {
if((keyData & (Keys)0xFF) == ignoredKey) {
keyData ^= ignoredKey;
}
}
_shortcutKeys = keyData;
lblCurrentKeys.Text = DebuggerShortcutsConfig.GetShortcutDisplay(keyData);
return true;
}
protected override void OnKeyDown(KeyEventArgs e)
{
}
protected override void OnKeyUp(KeyEventArgs e)
{
base.OnKeyUp(e);
this.Close();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
}
}
}

View file

@ -0,0 +1,114 @@
namespace Mesen.GUI.Debugger
{
partial class frmDbgShortcutGetKey
{
/// <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.groupBox1 = new System.Windows.Forms.GroupBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lblSetKeyMessage = new System.Windows.Forms.Label();
this.lblCurrentKeys = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.AutoSize = true;
this.groupBox1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.groupBox1.Controls.Add(this.tableLayoutPanel1);
this.groupBox1.Dock = System.Windows.Forms.DockStyle.Fill;
this.groupBox1.Location = new System.Drawing.Point(3, 0);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(391, 105);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.AutoSize = true;
this.tableLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.tableLayoutPanel1.ColumnCount = 1;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.lblSetKeyMessage, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.lblCurrentKeys, 0, 1);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 16);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(385, 86);
this.tableLayoutPanel1.TabIndex = 2;
//
// lblSetKeyMessage
//
this.lblSetKeyMessage.AutoSize = true;
this.lblSetKeyMessage.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblSetKeyMessage.Location = new System.Drawing.Point(3, 0);
this.lblSetKeyMessage.Name = "lblSetKeyMessage";
this.lblSetKeyMessage.Size = new System.Drawing.Size(379, 43);
this.lblSetKeyMessage.TabIndex = 0;
this.lblSetKeyMessage.Text = "Press any key on your keyboard to set a new binding.";
this.lblSetKeyMessage.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// lblCurrentKeys
//
this.lblCurrentKeys.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblCurrentKeys.Location = new System.Drawing.Point(3, 43);
this.lblCurrentKeys.Name = "lblCurrentKeys";
this.lblCurrentKeys.Size = new System.Drawing.Size(379, 43);
this.lblCurrentKeys.TabIndex = 1;
this.lblCurrentKeys.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// frmDbgShortcutGetKey
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(397, 108);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmDbgShortcutGetKey";
this.Padding = new System.Windows.Forms.Padding(3, 0, 3, 3);
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Set key binding...";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label lblSetKeyMessage;
private System.Windows.Forms.Label lblCurrentKeys;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
}
}

View 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>

View file

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmFadeSpeed : BaseConfigForm
{
public frmFadeSpeed(int initialValue)
{
InitializeComponent();
nudFrameCount.Value = initialValue;
}
public int FadeSpeed
{
get { return (int)nudFrameCount.Value; }
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
nudFrameCount.Focus();
}
}
}

125
UI/Debugger/frmFadeSpeed.designer.cs generated Normal file
View file

@ -0,0 +1,125 @@
using Mesen.GUI.Controls;
namespace Mesen.GUI.Debugger
{
partial class frmFadeSpeed
{
/// <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.lblAddress = new System.Windows.Forms.Label();
this.lblFrames = new System.Windows.Forms.Label();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.nudFrameCount = new MesenNumericUpDown();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 28);
this.baseConfigPanel.Size = new System.Drawing.Size(226, 29);
//
// lblAddress
//
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
this.lblAddress.Location = new System.Drawing.Point(3, 6);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(55, 13);
this.lblAddress.TabIndex = 0;
this.lblAddress.Text = "Fade after";
//
// lblFrames
//
this.lblFrames.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblFrames.AutoSize = true;
this.lblFrames.Location = new System.Drawing.Point(149, 6);
this.lblFrames.Name = "lblFrames";
this.lblFrames.Size = new System.Drawing.Size(38, 13);
this.lblFrames.TabIndex = 2;
this.lblFrames.Text = "frames";
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 3;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 80F));
this.tableLayoutPanel1.Controls.Add(this.lblFrames, 2, 0);
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.nudFrameCount, 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 = 2;
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(226, 57);
this.tableLayoutPanel1.TabIndex = 0;
//
// nudFrameCount
//
this.nudFrameCount.Dock = System.Windows.Forms.DockStyle.Fill;
this.nudFrameCount.Location = new System.Drawing.Point(64, 3);
this.nudFrameCount.Maximum = new decimal(new int[] {
99999,
0,
0,
0});
this.nudFrameCount.Name = "nudFrameCount";
this.nudFrameCount.Size = new System.Drawing.Size(79, 20);
this.nudFrameCount.TabIndex = 3;
this.nudFrameCount.Value = new decimal(new int[] {
1,
0,
0,
0});
//
// frmFadeSpeed
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(226, 57);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmFadeSpeed";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Fade speed...";
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Label lblAddress;
private System.Windows.Forms.Label lblFrames;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private MesenNumericUpDown nudFrameCount;
}
}

View 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>

View file

@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Forms;
namespace Mesen.GUI.Debugger
{
public partial class frmGoToLine : BaseConfigForm
{
public frmGoToLine(GoToAddress address, int charLimit)
{
InitializeComponent();
Entity = address;
AddBinding("Address", txtAddress);
txtAddress.MaxLength = charLimit;
}
protected override void OnShown(EventArgs e)
{
base.OnShown(e);
txtAddress.Focus();
}
}
public class GoToAddress
{
public UInt32 Address;
}
}

101
UI/Debugger/frmGoToLine.designer.cs generated Normal file
View file

@ -0,0 +1,101 @@
namespace Mesen.GUI.Debugger
{
partial class frmGoToLine
{
/// <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.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lblAddress = new System.Windows.Forms.Label();
this.txtAddress = new System.Windows.Forms.TextBox();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// baseConfigPanel
//
this.baseConfigPanel.Location = new System.Drawing.Point(0, 28);
this.baseConfigPanel.Size = new System.Drawing.Size(219, 29);
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.lblAddress, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.txtAddress, 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 = 2;
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(219, 57);
this.tableLayoutPanel1.TabIndex = 0;
//
// lblAddress
//
this.lblAddress.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblAddress.AutoSize = true;
this.lblAddress.Location = new System.Drawing.Point(3, 6);
this.lblAddress.Name = "lblAddress";
this.lblAddress.Size = new System.Drawing.Size(48, 13);
this.lblAddress.TabIndex = 0;
this.lblAddress.Text = "Address:";
//
// txtAddress
//
this.txtAddress.Dock = System.Windows.Forms.DockStyle.Fill;
this.txtAddress.Location = new System.Drawing.Point(57, 3);
this.txtAddress.MaxLength = 4;
this.txtAddress.Name = "txtAddress";
this.txtAddress.Size = new System.Drawing.Size(159, 20);
this.txtAddress.TabIndex = 1;
//
// frmGoToLine
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(219, 57);
this.Controls.Add(this.tableLayoutPanel1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmGoToLine";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Go To...";
this.Controls.SetChildIndex(this.tableLayoutPanel1, 0);
this.Controls.SetChildIndex(this.baseConfigPanel, 0);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label lblAddress;
private System.Windows.Forms.TextBox txtAddress;
}
}

View 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>

View file

@ -0,0 +1,693 @@
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Mesen.GUI.Config;
using Mesen.GUI.Forms;
using Mesen.GUI.Debugger.Controls;
namespace Mesen.GUI.Debugger
{
public partial class frmMemoryTools : BaseForm
{
private EntityBinder _entityBinder = new EntityBinder();
private NotificationListener _notifListener;
private SnesMemoryType _memoryType = SnesMemoryType.CpuMemory;
private bool _updating = false;
private DateTime _lastUpdate = DateTime.MinValue;
private TabPage _selectedTab;
private bool _formClosed;
public frmMemoryTools()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
this._selectedTab = this.tabMain.SelectedTab;
HexEditorInfo config = ConfigManager.Config.Debug.HexEditor;
_entityBinder.Entity = config;
_entityBinder.AddBinding(nameof(config.AutoRefresh), mnuAutoRefresh);
_entityBinder.AddBinding(nameof(config.HighDensityTextMode), mnuHighDensityMode);
_entityBinder.AddBinding(nameof(config.ByteEditingMode), mnuByteEditingMode);
_entityBinder.AddBinding(nameof(config.EnablePerByteNavigation), mnuEnablePerByteNavigation);
_entityBinder.AddBinding(nameof(config.IgnoreRedundantWrites), mnuIgnoreRedundantWrites);
_entityBinder.AddBinding(nameof(config.HighlightCurrentRowColumn), mnuHighlightCurrentRowColumn);
_entityBinder.AddBinding(nameof(config.ShowCharacters), mnuShowCharacters);
_entityBinder.AddBinding(nameof(config.ShowLabelInfo), mnuShowLabelInfoOnMouseOver);
_entityBinder.AddBinding(nameof(config.HighlightExecution), mnuHighlightExecution);
_entityBinder.AddBinding(nameof(config.HighlightReads), mnuHightlightReads);
_entityBinder.AddBinding(nameof(config.HighlightWrites), mnuHighlightWrites);
_entityBinder.AddBinding(nameof(config.HideUnusedBytes), mnuHideUnusedBytes);
_entityBinder.AddBinding(nameof(config.HideReadBytes), mnuHideReadBytes);
_entityBinder.AddBinding(nameof(config.HideWrittenBytes), mnuHideWrittenBytes);
_entityBinder.AddBinding(nameof(config.HideExecutedBytes), mnuHideExecutedBytes);
_entityBinder.AddBinding(nameof(config.HighlightLabelledBytes), mnuHighlightLabelledBytes);
_entityBinder.AddBinding(nameof(config.HighlightBreakpoints), mnuHighlightBreakpoints);
_entityBinder.AddBinding(nameof(config.HighlightCodeBytes), mnuHighlightCodeBytes);
_entityBinder.AddBinding(nameof(config.HighlightDataBytes), mnuHighlightDataBytes);
_entityBinder.UpdateUI();
UpdateRefreshSpeedMenu();
UpdateFlags();
this.ctrlHexViewer.HighlightCurrentRowColumn = config.HighlightCurrentRowColumn;
this.ctrlHexViewer.TextZoom = config.TextZoom;
this.ctrlHexViewer.BaseFont = new Font(config.FontFamily, config.FontSize, config.FontStyle);
//TODO this.ctrlMemoryAccessCounters.BaseFont = new Font(config.FontFamily, config.FontSize, config.FontStyle);
//TODO this.ctrlMemoryAccessCounters.TextZoom = config.TextZoom;
this.UpdateFadeOptions();
//TODO
//this.InitTblMappings();
this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked;
//TODO
//this.ctrlHexViewer.MemoryViewer = this;
UpdateImportButton();
InitMemoryTypeDropdown(true);
_notifListener = new NotificationListener();
_notifListener.OnNotification += _notifListener_OnNotification;
this.mnuShowCharacters.CheckedChanged += this.mnuShowCharacters_CheckedChanged;
this.mnuIgnoreRedundantWrites.CheckedChanged += mnuIgnoreRedundantWrites_CheckedChanged;
if(!config.WindowSize.IsEmpty) {
this.StartPosition = FormStartPosition.Manual;
this.Size = config.WindowSize;
this.Location = config.WindowLocation;
}
this.InitShortcuts();
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
HexEditorInfo config = ConfigManager.Config.Debug.HexEditor;
config.TextZoom = this.ctrlHexViewer.TextZoom;
config.FontFamily = ctrlHexViewer.BaseFont.FontFamily.Name;
config.FontStyle = ctrlHexViewer.BaseFont.Style;
config.FontSize = ctrlHexViewer.BaseFont.Size;
config.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
config.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
config.MemoryType = cboMemoryType.GetEnumValue<SnesMemoryType>();
_entityBinder.UpdateObject();
ConfigManager.ApplyChanges();
//TODO?
//DebugWorkspaceManager.SaveWorkspace();
if(this._notifListener != null) {
this._notifListener.Dispose();
this._notifListener = null;
}
_formClosed = true;
}
private void InitShortcuts()
{
mnuIncreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.IncreaseFontSize));
mnuDecreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.DecreaseFontSize));
mnuResetFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.ResetFontSize));
mnuImport.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_Import));
mnuExport.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_Export));
mnuRefresh.InitShortcut(this, nameof(DebuggerShortcutsConfig.Refresh));
mnuGoToAll.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoToAll));
mnuGoTo.InitShortcut(this, nameof(DebuggerShortcutsConfig.GoTo));
mnuFind.InitShortcut(this, nameof(DebuggerShortcutsConfig.Find));
mnuFindNext.InitShortcut(this, nameof(DebuggerShortcutsConfig.FindNext));
mnuFindPrev.InitShortcut(this, nameof(DebuggerShortcutsConfig.FindPrev));
}
private void InitMemoryTypeDropdown(bool forStartup)
{
cboMemoryType.SelectedIndexChanged -= this.cboMemoryType_SelectedIndexChanged;
SnesMemoryType originalValue = forStartup ? ConfigManager.Config.Debug.HexEditor.MemoryType : cboMemoryType.GetEnumValue<SnesMemoryType>();
cboMemoryType.BeginUpdate();
cboMemoryType.Items.Clear();
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CpuMemory));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.PrgRom));
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.WorkRam));
if(DebugApi.GetMemorySize(SnesMemoryType.SaveRam) > 0) {
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SaveRam));
}
cboMemoryType.Items.Add("-");
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.VideoRam));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.CGRam));
cboMemoryType.Items.Add(ResourceHelper.GetEnumText(SnesMemoryType.SpriteRam));
cboMemoryType.SelectedIndex = 0;
cboMemoryType.SetEnumValue(originalValue);
cboMemoryType.SelectedIndexChanged += this.cboMemoryType_SelectedIndexChanged;
cboMemoryType.EndUpdate();
UpdateMemoryType();
}
private void UpdateFlags()
{
//TODO
/*
if(mnuIgnoreRedundantWrites.Checked) {
DebugWorkspaceManager.SetFlags(DebuggerFlags.IgnoreRedundantWrites);
} else {
DebugWorkspaceManager.ClearFlags(DebuggerFlags.IgnoreRedundantWrites);
}
*/
}
public void ShowAddress(int address, SnesMemoryType memoryType)
{
tabMain.SelectedTab = tpgMemoryViewer;
cboMemoryType.SetEnumValue(memoryType);
ctrlHexViewer.GoToAddress(address);
}
//TODO
/*
public void GoToDestination(GoToDestination dest)
{
if(_memoryType == DebugMemoryType.CpuMemory && dest.CpuAddress >= 0) {
this.ShowAddress(dest.CpuAddress, DebugMemoryType.CpuMemory);
} else if(dest.AddressInfo != null) {
this.ShowAddress(dest.AddressInfo.Address, dest.AddressInfo.Type.ToMemoryType());
} else if(dest.Label != null) {
int relAddress = dest.Label.GetRelativeAddress();
if(_memoryType == DebugMemoryType.CpuMemory && relAddress >= 0) {
this.ShowAddress(relAddress, DebugMemoryType.CpuMemory);
} else {
this.ShowAddress((int)dest.Label.Address, dest.Label.AddressType.ToMemoryType());
}
} else if(dest.CpuAddress >= 0) {
this.ShowAddress(dest.CpuAddress, DebugMemoryType.CpuMemory);
}
this.BringToFront();
}
public void GoToAll()
{
using(frmGoToAll frm = new frmGoToAll(true, false)) {
if(frm.ShowDialog() == DialogResult.OK) {
GoToDestination(frm.Destination);
}
}
}
private void InitTblMappings()
{
DebugWorkspace workspace = DebugWorkspaceManager.GetWorkspace();
if(workspace.TblMappings != null && workspace.TblMappings.Count > 0) {
var tblDict = TblLoader.ToDictionary(workspace.TblMappings.ToArray());
if(tblDict != null) {
this.ctrlHexViewer.ByteCharConverter = new TblByteCharConverter(tblDict);
}
} else {
this.ctrlHexViewer.ByteCharConverter = null;
}
}*/
private void _notifListener_OnNotification(NotificationEventArgs e)
{
switch(e.NotificationType) {
case ConsoleNotificationType.CodeBreak:
this.BeginInvoke((MethodInvoker)(() => this.RefreshData()));
break;
case ConsoleNotificationType.GameReset:
case ConsoleNotificationType.GameLoaded:
this.BeginInvoke((Action)(() => {
if(_formClosed) {
return;
}
this.InitMemoryTypeDropdown(false);
//TODO ctrlMemoryAccessCounters.InitMemoryTypeDropdown();
}));
this.UpdateFlags();
break;
case ConsoleNotificationType.PpuFrameDone:
int refreshDelay = 90;
switch(ConfigManager.Config.Debug.HexEditor.AutoRefreshSpeed) {
case RefreshSpeed.Low: refreshDelay = 90; break;
case RefreshSpeed.Normal: refreshDelay = 32; break;
case RefreshSpeed.High: refreshDelay = 16; break;
}
DateTime now = DateTime.Now;
if(!_updating && ConfigManager.Config.Debug.HexEditor.AutoRefresh && (now - _lastUpdate).Milliseconds >= refreshDelay) {
_lastUpdate = now;
_updating = true;
this.BeginInvoke((Action)(() => {
this.RefreshData();
_updating = false;
}));
}
break;
}
}
private void cboMemoryType_SelectedIndexChanged(object sender, EventArgs e)
{
UpdateMemoryType();
}
private void UpdateMemoryType()
{
this._memoryType = this.cboMemoryType.GetEnumValue<SnesMemoryType>();
this.UpdateImportButton();
this.RefreshData();
}
private void UpdateByteColorProvider()
{
//TODO
/*switch(this._memoryType) {
case SnesMemoryType.CpuMemory:
case SnesMemoryType.PrgRom:
case SnesMemoryType.WorkRam:
case SnesMemoryType.SaveRam:
this.ctrlHexViewer.ByteColorProvider = new ByteColorProvider(
this._memoryType,
mnuHighlightExecution.Checked,
mnuHighlightWrites.Checked,
mnuHightlightReads.Checked,
ConfigManager.Config.Debug.RamFadeSpeed,
mnuHideUnusedBytes.Checked,
mnuHideReadBytes.Checked,
mnuHideWrittenBytes.Checked,
mnuHideExecutedBytes.Checked,
mnuHighlightDataBytes.Checked,
mnuHighlightCodeBytes.Checked,
mnuHighlightLabelledBytes.Checked,
mnuHighlightBreakpoints.Checked
);
break;
case SnesMemoryType.VideoRam:
case DebugMemoryType.ChrRom:
case DebugMemoryType.ChrRam:
case DebugMemoryType.PaletteMemory:
case DebugMemoryType.NametableRam:
this.ctrlHexViewer.ByteColorProvider = new ChrByteColorProvider(
this._memoryType,
mnuHighlightWrites.Checked,
mnuHightlightReads.Checked,
ConfigManager.Config.Debug.RamFadeSpeed,
mnuHideUnusedBytes.Checked,
mnuHideReadBytes.Checked,
mnuHideWrittenBytes.Checked,
mnuHighlightChrDrawnBytes.Checked,
mnuHighlightChrReadBytes.Checked,
mnuHighlightBreakpoints.Checked
);
break;
default:
this.ctrlHexViewer.ByteColorProvider = null;
break;
}*/
}
private void mnuRefresh_Click(object sender, EventArgs e)
{
this.RefreshData();
}
private void RefreshData()
{
if(_formClosed) {
return;
}
//TODO
/*
if(DebugWorkspaceManager.GetWorkspace() != this._previousWorkspace) {
this.InitTblMappings();
_previousWorkspace = DebugWorkspaceManager.GetWorkspace();
}
*/
if(this.tabMain.SelectedTab == this.tpgAccessCounters) {
//TODO this.ctrlMemoryAccessCounters.RefreshData();
} else if(this.tabMain.SelectedTab == this.tpgMemoryViewer) {
this.UpdateByteColorProvider();
this.ctrlHexViewer.RefreshData(_memoryType);
}
}
private void mnuFind_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.OpenSearchBox();
}
private void mnuFindNext_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.FindNext();
}
private void mnuFindPrev_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.FindPrevious();
}
private void mnuGoTo_Click(object sender, EventArgs e)
{
if(_selectedTab == tpgMemoryViewer) {
this.ctrlHexViewer.GoToAddress();
} else if(_selectedTab == tpgAccessCounters) {
//TODO this.ctrlMemoryAccessCounters.GoToAddress();
}
}
private void mnuGoToAll_Click(object sender, EventArgs e)
{
//TODO
//this.GoToAll();
}
private void mnuIncreaseFontSize_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.TextZoom += 10;
//TODO this.ctrlMemoryAccessCounters.TextZoom += 10;
}
private void mnuDecreaseFontSize_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.TextZoom -= 10;
//TODO this.ctrlMemoryAccessCounters.TextZoom -= 10;
}
private void mnuResetFontSize_Click(object sender, EventArgs e)
{
this.ctrlHexViewer.TextZoom = 100;
//TODO this.ctrlMemoryAccessCounters.TextZoom = 100;
}
private void mnuClose_Click(object sender, EventArgs e)
{
this.Close();
}
private void UpdateImportButton()
{
switch(_memoryType) {
case SnesMemoryType.VideoRam:
case SnesMemoryType.CGRam:
case SnesMemoryType.SpriteRam:
case SnesMemoryType.WorkRam:
case SnesMemoryType.SaveRam:
mnuImport.Enabled = true;
break;
default:
mnuImport.Enabled = false;
break;
}
}
private void mnuImport_Click(object sender, EventArgs e)
{
using(OpenFileDialog ofd = new OpenFileDialog()) {
ofd.SetFilter("Memory dump files (*.dmp)|*.dmp|All files (*.*)|*.*");
ofd.InitialDirectory = ConfigManager.DebuggerFolder;
if(ofd.ShowDialog() == DialogResult.OK) {
byte[] fileContent = File.ReadAllBytes(ofd.FileName);
DebugApi.SetMemoryState(_memoryType, fileContent, fileContent.Length);
RefreshData();
}
}
}
private void mnuExport_Click(object sender, EventArgs e)
{
using(SaveFileDialog sfd = new SaveFileDialog()) {
sfd.SetFilter("Memory dump files (*.dmp)|*.dmp|All files (*.*)|*.*");
sfd.InitialDirectory = ConfigManager.DebuggerFolder;
//TODO sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + " - " + cboMemoryType.SelectedItem.ToString() + ".dmp";
sfd.FileName = cboMemoryType.SelectedItem.ToString() + ".dmp";
if(sfd.ShowDialog() == DialogResult.OK) {
File.WriteAllBytes(sfd.FileName, this.ctrlHexViewer.GetData());
}
}
}
private void tabMain_SelectedIndexChanged(object sender, EventArgs e)
{
_selectedTab = this.tabMain.SelectedTab;
this.RefreshData();
}
private void ctrlHexViewer_RequiredWidthChanged(object sender, EventArgs e)
{
this.Size = new Size(this.ctrlHexViewer.RequiredWidth + 20, this.Height);
}
private void mnuLoadTblFile_Click(object sender, EventArgs e)
{
//TODO
/*OpenFileDialog ofd = new OpenFileDialog();
ofd.SetFilter("TBL files (*.tbl)|*.tbl");
if(ofd.ShowDialog() == DialogResult.OK) {
string[] fileContents = File.ReadAllLines(ofd.FileName);
var tblDict = TblLoader.ToDictionary(fileContents);
if(tblDict == null) {
MessageBox.Show("Could not load TBL file. The file selected file appears to be invalid.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
} else {
DebugWorkspaceManager.GetWorkspace().TblMappings = new List<string>(fileContents);
this.ctrlHexViewer.ByteCharConverter = new TblByteCharConverter(tblDict);
this.mnuShowCharacters.Checked = true;
}
}*/
}
private void mnuResetTblMappings_Click(object sender, EventArgs e)
{
//TODO
//DebugWorkspaceManager.GetWorkspace().TblMappings = null;
//this.ctrlHexViewer.ByteCharConverter = null;
}
private void mnuShowCharacters_CheckedChanged(object sender, EventArgs e)
{
this.ctrlHexViewer.StringViewVisible = mnuShowCharacters.Checked;
}
private void mnuIgnoreRedundantWrites_CheckedChanged(object sender, EventArgs e)
{
this.UpdateFlags();
}
private void UpdateFadeOptions()
{
int fadeSpeed = ConfigManager.Config.Debug.HexEditor.FadeSpeed;
mnuFadeSlow.Checked = fadeSpeed == 600;
mnuFadeNormal.Checked = fadeSpeed == 300;
mnuFadeFast.Checked = fadeSpeed == 120;
mnuFadeNever.Checked = fadeSpeed == 0;
mnuCustomFadeSpeed.Checked = !mnuFadeSlow.Checked && !mnuFadeNormal.Checked && !mnuFadeFast.Checked && !mnuFadeSlow.Checked;
}
private void mnuFadeSpeed_Click(object sender, EventArgs e)
{
HexEditorInfo config = ConfigManager.Config.Debug.HexEditor;
if(sender == mnuFadeSlow) {
config.FadeSpeed = 600;
} else if(sender == mnuFadeNormal) {
config.FadeSpeed = 300;
} else if(sender == mnuFadeFast) {
config.FadeSpeed = 120;
} else if(sender == mnuFadeNever) {
config.FadeSpeed = 0;
}
ConfigManager.ApplyChanges();
UpdateFadeOptions();
}
private void mnuCustomFadeSpeed_Click(object sender, EventArgs e)
{
using(frmFadeSpeed frm = new frmFadeSpeed(ConfigManager.Config.Debug.HexEditor.FadeSpeed)) {
if(frm.ShowDialog() == DialogResult.OK) {
ConfigManager.Config.Debug.HexEditor.FadeSpeed = frm.FadeSpeed;
ConfigManager.ApplyChanges();
UpdateFadeOptions();
}
}
}
private void mnuColorProviderOptions_Click(object sender, EventArgs e)
{
this.UpdateByteColorProvider();
}
private void mnuConfigureColors_Click(object sender, EventArgs e)
{
//TODO
//using(frmMemoryViewerColors frm = new frmMemoryViewerColors()) {
// if(frm.ShowDialog(this, this) == DialogResult.OK) {
// this.RefreshData();
// }
//}
}
/*private frmCodeTooltip _tooltip = null;
private CodeLabel _lastLabelTooltip = null;
private int _lastLabelArrayOffset = -1;
private int _lastTooltipAddress = -1;*/
private void ctrlHexViewer_ByteMouseHover(int address, Point position)
{
//TODO
/*if(address < 0 || !mnuShowLabelInfoOnMouseOver.Checked) {
if(_tooltip != null) {
_tooltip.Close();
_lastLabelTooltip = null;
_lastLabelArrayOffset = -1;
_lastTooltipAddress = -1;
}
return;
}
if(_lastTooltipAddress == address) {
return;
}
_lastTooltipAddress = address;
CodeLabel label = null;
int arrayOffset = 0;
switch(_memoryType) {
case DebugMemoryType.CpuMemory:
AddressTypeInfo info = new AddressTypeInfo();
InteropEmu.DebugGetAbsoluteAddressAndType((UInt32)address, info);
if(info.Address >= 0) {
label = LabelManager.GetLabel((UInt32)info.Address, info.Type);
if(label != null) {
arrayOffset = info.Address - (int)label.Address;
}
}
if(label == null) {
label = LabelManager.GetLabel((UInt32)address, AddressType.Register);
}
break;
case DebugMemoryType.InternalRam:
case DebugMemoryType.WorkRam:
case DebugMemoryType.SaveRam:
case DebugMemoryType.PrgRom:
label = LabelManager.GetLabel((UInt32)address, _memoryType.ToAddressType());
if(label != null) {
arrayOffset = address - (int)label.Address;
}
break;
}
if(label != null) {
if(_lastLabelTooltip != label || _lastLabelArrayOffset != arrayOffset) {
if(_tooltip != null) {
_tooltip.Close();
}
Dictionary<string, string> values = new Dictionary<string, string>();
if(!string.IsNullOrWhiteSpace(label.Label)) {
values["Label"] = label.Label;
if(label.Length > 1) {
values["Label"] += "+" + arrayOffset.ToString();
}
}
values["Address"] = "$" + (label.Address + arrayOffset).ToString("X4");
values["Address Type"] = label.AddressType.ToString();
if(!string.IsNullOrWhiteSpace(label.Comment)) {
values["Comment"] = label.Comment;
}
_tooltip = new frmCodeTooltip(this, values);
_tooltip.FormClosed += (s, evt) => { _tooltip = null; };
_tooltip.SetFormLocation(new Point(position.X, position.Y), ctrlHexViewer);
_lastLabelTooltip = label;
_lastLabelArrayOffset = arrayOffset;
}
} else {
if(_tooltip != null) {
_tooltip.Close();
_lastLabelTooltip = null;
_lastLabelArrayOffset = -1;
_lastTooltipAddress = -1;
}
}*/
}
private void mnuAutoRefreshSpeed_Click(object sender, EventArgs e)
{
HexEditorInfo config = ConfigManager.Config.Debug.HexEditor;
if(sender == mnuAutoRefreshLow) {
config.AutoRefreshSpeed = RefreshSpeed.Low;
} else if(sender == mnuAutoRefreshNormal) {
config.AutoRefreshSpeed = RefreshSpeed.Normal;
} else if(sender == mnuAutoRefreshHigh) {
config.AutoRefreshSpeed = RefreshSpeed.High;
}
ConfigManager.ApplyChanges();
UpdateRefreshSpeedMenu();
}
private void UpdateRefreshSpeedMenu()
{
HexEditorInfo config = ConfigManager.Config.Debug.HexEditor;
mnuAutoRefreshLow.Checked = config.AutoRefreshSpeed == RefreshSpeed.Low;
mnuAutoRefreshNormal.Checked = config.AutoRefreshSpeed == RefreshSpeed.Normal;
mnuAutoRefreshHigh.Checked = config.AutoRefreshSpeed == RefreshSpeed.High;
}
private void mnuHighDensityMode_CheckedChanged(object sender, EventArgs e)
{
ctrlHexViewer.HighDensityMode = mnuHighDensityMode.Checked;
}
private void mnuEnablePerByteNavigation_CheckedChanged(object sender, EventArgs e)
{
ctrlHexViewer.EnablePerByteNavigation = mnuEnablePerByteNavigation.Checked;
}
private void mnuSelectFont_Click(object sender, EventArgs e)
{
ctrlHexViewer.BaseFont = FontDialogHelper.SelectFont(ctrlHexViewer.BaseFont);
//TODO ctrlMemoryAccessCounters.BaseFont = ctrlHexViewer.BaseFont;
}
private void mnuByteEditingMode_CheckedChanged(object sender, EventArgs e)
{
ctrlHexViewer.ByteEditingMode = mnuByteEditingMode.Checked;
}
private void mnuHighlightCurrentRowColumn_CheckedChanged(object sender, EventArgs e)
{
ctrlHexViewer.HighlightCurrentRowColumn = mnuHighlightCurrentRowColumn.Checked;
}
}
}

876
UI/Debugger/frmMemoryTools.designer.cs generated Normal file
View file

@ -0,0 +1,876 @@
namespace Mesen.GUI.Debugger
{
partial class frmMemoryTools
{
/// <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();
}
if(this._notifListener != null) {
this._notifListener.Dispose();
this._notifListener = null;
}
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.ctrlHexViewer = new Mesen.GUI.Debugger.Controls.ctrlHexViewer();
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.lblViewMemoryType = new System.Windows.Forms.Label();
this.cboMemoryType = new Mesen.GUI.Debugger.Controls.ComboBoxWithSeparator();
this.menuStrip1 = new Mesen.GUI.Controls.ctrlMesenMenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuImport = new System.Windows.Forms.ToolStripMenuItem();
this.mnuExport = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();
this.mnuLoadTblFile = new System.Windows.Forms.ToolStripMenuItem();
this.mnuResetTblMappings = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem4 = new System.Windows.Forms.ToolStripSeparator();
this.mnuClose = new System.Windows.Forms.ToolStripMenuItem();
this.mnuView = new System.Windows.Forms.ToolStripMenuItem();
this.highlightToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightExecution = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightWrites = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHightlightReads = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();
this.fadeSpeedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFadeSlow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFadeNormal = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFadeFast = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFadeNever = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem7 = new System.Windows.Forms.ToolStripSeparator();
this.mnuCustomFadeSpeed = new System.Windows.Forms.ToolStripMenuItem();
this.dataTypeHighlightingToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightLabelledBytes = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightBreakpoints = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem8 = new System.Windows.Forms.ToolStripSeparator();
this.mnuHighlightCodeBytes = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightDataBytes = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightDmcDataBytes = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem11 = new System.Windows.Forms.ToolStripSeparator();
this.mnuHighlightChrDrawnBytes = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightChrReadBytes = new System.Windows.Forms.ToolStripMenuItem();
this.fadeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHideUnusedBytes = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHideReadBytes = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHideWrittenBytes = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHideExecutedBytes = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();
this.mnuConfigureColors = new System.Windows.Forms.ToolStripMenuItem();
this.fontSizeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuIncreaseFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.mnuDecreaseFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.mnuResetFontSize = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem12 = new System.Windows.Forms.ToolStripSeparator();
this.mnuSelectFont = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem13 = new System.Windows.Forms.ToolStripSeparator();
this.mnuHighDensityMode = new System.Windows.Forms.ToolStripMenuItem();
this.autorefreshSpeedToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshLow = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshNormal = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAutoRefreshHigh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();
this.mnuRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem9 = new System.Windows.Forms.ToolStripSeparator();
this.mnuAutoRefresh = new System.Windows.Forms.ToolStripMenuItem();
this.mnuShowCharacters = new System.Windows.Forms.ToolStripMenuItem();
this.mnuShowLabelInfoOnMouseOver = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem10 = new System.Windows.Forms.ToolStripSeparator();
this.mnuIgnoreRedundantWrites = new System.Windows.Forms.ToolStripMenuItem();
this.mnuEnablePerByteNavigation = new System.Windows.Forms.ToolStripMenuItem();
this.mnuByteEditingMode = new System.Windows.Forms.ToolStripMenuItem();
this.mnuHighlightCurrentRowColumn = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
this.mnuGoToAll = new System.Windows.Forms.ToolStripMenuItem();
this.mnuGoTo = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem14 = new System.Windows.Forms.ToolStripSeparator();
this.mnuFind = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFindNext = new System.Windows.Forms.ToolStripMenuItem();
this.mnuFindPrev = new System.Windows.Forms.ToolStripMenuItem();
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgMemoryViewer = new System.Windows.Forms.TabPage();
this.panel1 = new System.Windows.Forms.Panel();
this.tpgAccessCounters = new System.Windows.Forms.TabPage();
this.flowLayoutPanel1.SuspendLayout();
this.menuStrip1.SuspendLayout();
this.tabMain.SuspendLayout();
this.tpgMemoryViewer.SuspendLayout();
this.panel1.SuspendLayout();
this.SuspendLayout();
//
// ctrlHexViewer
//
this.ctrlHexViewer.BaseFont = new System.Drawing.Font("Consolas", 10F);
this.ctrlHexViewer.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlHexViewer.Location = new System.Drawing.Point(0, 0);
this.ctrlHexViewer.Margin = new System.Windows.Forms.Padding(0);
this.ctrlHexViewer.Name = "ctrlHexViewer";
this.ctrlHexViewer.Size = new System.Drawing.Size(606, 343);
this.ctrlHexViewer.TabIndex = 0;
this.ctrlHexViewer.TextZoom = 100;
this.ctrlHexViewer.RequiredWidthChanged += new System.EventHandler(this.ctrlHexViewer_RequiredWidthChanged);
this.ctrlHexViewer.ByteMouseHover += new Mesen.GUI.Debugger.Controls.ctrlHexViewer.ByteMouseHoverHandler(this.ctrlHexViewer_ByteMouseHover);
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.AutoSize = true;
this.flowLayoutPanel1.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.flowLayoutPanel1.Controls.Add(this.lblViewMemoryType);
this.flowLayoutPanel1.Controls.Add(this.cboMemoryType);
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(207, 27);
this.flowLayoutPanel1.TabIndex = 1;
this.flowLayoutPanel1.WrapContents = false;
//
// lblViewMemoryType
//
this.lblViewMemoryType.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblViewMemoryType.AutoSize = true;
this.lblViewMemoryType.Location = new System.Drawing.Point(3, 7);
this.lblViewMemoryType.Name = "lblViewMemoryType";
this.lblViewMemoryType.Size = new System.Drawing.Size(33, 13);
this.lblViewMemoryType.TabIndex = 0;
this.lblViewMemoryType.Text = "View:";
//
// 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(42, 3);
this.cboMemoryType.Name = "cboMemoryType";
this.cboMemoryType.Size = new System.Drawing.Size(162, 21);
this.cboMemoryType.TabIndex = 1;
//
// menuStrip1
//
this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.fileToolStripMenuItem,
this.mnuView,
this.toolStripMenuItem1});
this.menuStrip1.Location = new System.Drawing.Point(0, 0);
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(614, 24);
this.menuStrip1.TabIndex = 2;
this.menuStrip1.Text = "menuStrip1";
//
// fileToolStripMenuItem
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuImport,
this.mnuExport,
this.toolStripMenuItem3,
this.mnuLoadTblFile,
this.mnuResetTblMappings,
this.toolStripMenuItem4,
this.mnuClose});
this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
this.fileToolStripMenuItem.Text = "File";
//
// mnuImport
//
this.mnuImport.Image = global::Mesen.GUI.Properties.Resources.Import;
this.mnuImport.Name = "mnuImport";
this.mnuImport.Size = new System.Drawing.Size(181, 22);
this.mnuImport.Text = "Import";
this.mnuImport.Click += new System.EventHandler(this.mnuImport_Click);
//
// mnuExport
//
this.mnuExport.Image = global::Mesen.GUI.Properties.Resources.Export;
this.mnuExport.Name = "mnuExport";
this.mnuExport.Size = new System.Drawing.Size(181, 22);
this.mnuExport.Text = "Export";
this.mnuExport.Click += new System.EventHandler(this.mnuExport_Click);
//
// toolStripMenuItem3
//
this.toolStripMenuItem3.Name = "toolStripMenuItem3";
this.toolStripMenuItem3.Size = new System.Drawing.Size(178, 6);
//
// mnuLoadTblFile
//
this.mnuLoadTblFile.Name = "mnuLoadTblFile";
this.mnuLoadTblFile.Size = new System.Drawing.Size(181, 22);
this.mnuLoadTblFile.Text = "Load TBL file";
this.mnuLoadTblFile.Click += new System.EventHandler(this.mnuLoadTblFile_Click);
//
// mnuResetTblMappings
//
this.mnuResetTblMappings.Name = "mnuResetTblMappings";
this.mnuResetTblMappings.Size = new System.Drawing.Size(181, 22);
this.mnuResetTblMappings.Text = "Reset TBL mappings";
this.mnuResetTblMappings.Click += new System.EventHandler(this.mnuResetTblMappings_Click);
//
// toolStripMenuItem4
//
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
this.toolStripMenuItem4.Size = new System.Drawing.Size(178, 6);
//
// mnuClose
//
this.mnuClose.Image = global::Mesen.GUI.Properties.Resources.Exit;
this.mnuClose.Name = "mnuClose";
this.mnuClose.Size = new System.Drawing.Size(181, 22);
this.mnuClose.Text = "Close";
this.mnuClose.Click += new System.EventHandler(this.mnuClose_Click);
//
// mnuView
//
this.mnuView.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.highlightToolStripMenuItem,
this.dataTypeHighlightingToolStripMenuItem,
this.fadeToolStripMenuItem,
this.toolStripMenuItem5,
this.mnuConfigureColors,
this.fontSizeToolStripMenuItem,
this.autorefreshSpeedToolStripMenuItem,
this.toolStripMenuItem2,
this.mnuRefresh,
this.toolStripMenuItem9,
this.mnuAutoRefresh,
this.mnuShowCharacters,
this.mnuShowLabelInfoOnMouseOver,
this.toolStripMenuItem10,
this.mnuIgnoreRedundantWrites,
this.mnuEnablePerByteNavigation,
this.mnuByteEditingMode,
this.mnuHighlightCurrentRowColumn});
this.mnuView.Name = "mnuView";
this.mnuView.Size = new System.Drawing.Size(44, 20);
this.mnuView.Text = "View";
//
// highlightToolStripMenuItem
//
this.highlightToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuHighlightExecution,
this.mnuHighlightWrites,
this.mnuHightlightReads,
this.toolStripMenuItem6,
this.fadeSpeedToolStripMenuItem});
this.highlightToolStripMenuItem.Name = "highlightToolStripMenuItem";
this.highlightToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
this.highlightToolStripMenuItem.Text = "Memory Access Highlighting";
//
// mnuHighlightExecution
//
this.mnuHighlightExecution.CheckOnClick = true;
this.mnuHighlightExecution.Name = "mnuHighlightExecution";
this.mnuHighlightExecution.Size = new System.Drawing.Size(133, 22);
this.mnuHighlightExecution.Text = "Execution";
this.mnuHighlightExecution.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHighlightWrites
//
this.mnuHighlightWrites.CheckOnClick = true;
this.mnuHighlightWrites.Name = "mnuHighlightWrites";
this.mnuHighlightWrites.Size = new System.Drawing.Size(133, 22);
this.mnuHighlightWrites.Text = "Writes";
this.mnuHighlightWrites.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHightlightReads
//
this.mnuHightlightReads.CheckOnClick = true;
this.mnuHightlightReads.Name = "mnuHightlightReads";
this.mnuHightlightReads.Size = new System.Drawing.Size(133, 22);
this.mnuHightlightReads.Text = "Reads";
this.mnuHightlightReads.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// toolStripMenuItem6
//
this.toolStripMenuItem6.Name = "toolStripMenuItem6";
this.toolStripMenuItem6.Size = new System.Drawing.Size(130, 6);
//
// fadeSpeedToolStripMenuItem
//
this.fadeSpeedToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuFadeSlow,
this.mnuFadeNormal,
this.mnuFadeFast,
this.mnuFadeNever,
this.toolStripMenuItem7,
this.mnuCustomFadeSpeed});
this.fadeSpeedToolStripMenuItem.Name = "fadeSpeedToolStripMenuItem";
this.fadeSpeedToolStripMenuItem.Size = new System.Drawing.Size(133, 22);
this.fadeSpeedToolStripMenuItem.Text = "Fade speed";
//
// mnuFadeSlow
//
this.mnuFadeSlow.Name = "mnuFadeSlow";
this.mnuFadeSlow.Size = new System.Drawing.Size(136, 22);
this.mnuFadeSlow.Text = "Slow";
this.mnuFadeSlow.Click += new System.EventHandler(this.mnuFadeSpeed_Click);
//
// mnuFadeNormal
//
this.mnuFadeNormal.Checked = true;
this.mnuFadeNormal.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuFadeNormal.Name = "mnuFadeNormal";
this.mnuFadeNormal.Size = new System.Drawing.Size(136, 22);
this.mnuFadeNormal.Text = "Normal";
this.mnuFadeNormal.Click += new System.EventHandler(this.mnuFadeSpeed_Click);
//
// mnuFadeFast
//
this.mnuFadeFast.Name = "mnuFadeFast";
this.mnuFadeFast.Size = new System.Drawing.Size(136, 22);
this.mnuFadeFast.Text = "Fast";
this.mnuFadeFast.Click += new System.EventHandler(this.mnuFadeSpeed_Click);
//
// mnuFadeNever
//
this.mnuFadeNever.Name = "mnuFadeNever";
this.mnuFadeNever.Size = new System.Drawing.Size(136, 22);
this.mnuFadeNever.Text = "Do not fade";
this.mnuFadeNever.Click += new System.EventHandler(this.mnuFadeSpeed_Click);
//
// toolStripMenuItem7
//
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
this.toolStripMenuItem7.Size = new System.Drawing.Size(133, 6);
//
// mnuCustomFadeSpeed
//
this.mnuCustomFadeSpeed.Name = "mnuCustomFadeSpeed";
this.mnuCustomFadeSpeed.Size = new System.Drawing.Size(136, 22);
this.mnuCustomFadeSpeed.Text = "Custom...";
this.mnuCustomFadeSpeed.Click += new System.EventHandler(this.mnuCustomFadeSpeed_Click);
//
// dataTypeHighlightingToolStripMenuItem
//
this.dataTypeHighlightingToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuHighlightLabelledBytes,
this.mnuHighlightBreakpoints,
this.toolStripMenuItem8,
this.mnuHighlightCodeBytes,
this.mnuHighlightDataBytes,
this.mnuHighlightDmcDataBytes,
this.toolStripMenuItem11,
this.mnuHighlightChrDrawnBytes,
this.mnuHighlightChrReadBytes});
this.dataTypeHighlightingToolStripMenuItem.Name = "dataTypeHighlightingToolStripMenuItem";
this.dataTypeHighlightingToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
this.dataTypeHighlightingToolStripMenuItem.Text = "Data Type Highlighting";
//
// mnuHighlightLabelledBytes
//
this.mnuHighlightLabelledBytes.CheckOnClick = true;
this.mnuHighlightLabelledBytes.Name = "mnuHighlightLabelledBytes";
this.mnuHighlightLabelledBytes.Size = new System.Drawing.Size(236, 22);
this.mnuHighlightLabelledBytes.Text = "Labeled bytes";
this.mnuHighlightLabelledBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHighlightBreakpoints
//
this.mnuHighlightBreakpoints.CheckOnClick = true;
this.mnuHighlightBreakpoints.Name = "mnuHighlightBreakpoints";
this.mnuHighlightBreakpoints.Size = new System.Drawing.Size(236, 22);
this.mnuHighlightBreakpoints.Text = "Breakpoints";
this.mnuHighlightBreakpoints.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// toolStripMenuItem8
//
this.toolStripMenuItem8.Name = "toolStripMenuItem8";
this.toolStripMenuItem8.Size = new System.Drawing.Size(233, 6);
//
// mnuHighlightCodeBytes
//
this.mnuHighlightCodeBytes.CheckOnClick = true;
this.mnuHighlightCodeBytes.Name = "mnuHighlightCodeBytes";
this.mnuHighlightCodeBytes.Size = new System.Drawing.Size(236, 22);
this.mnuHighlightCodeBytes.Text = "Code bytes (PRG ROM)";
this.mnuHighlightCodeBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHighlightDataBytes
//
this.mnuHighlightDataBytes.CheckOnClick = true;
this.mnuHighlightDataBytes.Name = "mnuHighlightDataBytes";
this.mnuHighlightDataBytes.Size = new System.Drawing.Size(236, 22);
this.mnuHighlightDataBytes.Text = "Data bytes (PRG ROM)";
this.mnuHighlightDataBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHighlightDmcDataBytes
//
this.mnuHighlightDmcDataBytes.CheckOnClick = true;
this.mnuHighlightDmcDataBytes.Name = "mnuHighlightDmcDataBytes";
this.mnuHighlightDmcDataBytes.Size = new System.Drawing.Size(236, 22);
this.mnuHighlightDmcDataBytes.Text = "DMC sample bytes (PRG ROM)";
this.mnuHighlightDmcDataBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// toolStripMenuItem11
//
this.toolStripMenuItem11.Name = "toolStripMenuItem11";
this.toolStripMenuItem11.Size = new System.Drawing.Size(233, 6);
//
// mnuHighlightChrDrawnBytes
//
this.mnuHighlightChrDrawnBytes.CheckOnClick = true;
this.mnuHighlightChrDrawnBytes.Name = "mnuHighlightChrDrawnBytes";
this.mnuHighlightChrDrawnBytes.Size = new System.Drawing.Size(236, 22);
this.mnuHighlightChrDrawnBytes.Text = "Drawn bytes (CHR ROM)";
this.mnuHighlightChrDrawnBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHighlightChrReadBytes
//
this.mnuHighlightChrReadBytes.CheckOnClick = true;
this.mnuHighlightChrReadBytes.Name = "mnuHighlightChrReadBytes";
this.mnuHighlightChrReadBytes.Size = new System.Drawing.Size(236, 22);
this.mnuHighlightChrReadBytes.Text = "Read bytes (CHR ROM)";
this.mnuHighlightChrReadBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// fadeToolStripMenuItem
//
this.fadeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuHideUnusedBytes,
this.mnuHideReadBytes,
this.mnuHideWrittenBytes,
this.mnuHideExecutedBytes});
this.fadeToolStripMenuItem.Name = "fadeToolStripMenuItem";
this.fadeToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
this.fadeToolStripMenuItem.Text = "De-emphasize";
//
// mnuHideUnusedBytes
//
this.mnuHideUnusedBytes.CheckOnClick = true;
this.mnuHideUnusedBytes.Name = "mnuHideUnusedBytes";
this.mnuHideUnusedBytes.Size = new System.Drawing.Size(152, 22);
this.mnuHideUnusedBytes.Text = "Unused bytes";
this.mnuHideUnusedBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHideReadBytes
//
this.mnuHideReadBytes.CheckOnClick = true;
this.mnuHideReadBytes.Name = "mnuHideReadBytes";
this.mnuHideReadBytes.Size = new System.Drawing.Size(152, 22);
this.mnuHideReadBytes.Text = "Read bytes";
this.mnuHideReadBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHideWrittenBytes
//
this.mnuHideWrittenBytes.CheckOnClick = true;
this.mnuHideWrittenBytes.Name = "mnuHideWrittenBytes";
this.mnuHideWrittenBytes.Size = new System.Drawing.Size(152, 22);
this.mnuHideWrittenBytes.Text = "Written bytes";
this.mnuHideWrittenBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// mnuHideExecutedBytes
//
this.mnuHideExecutedBytes.CheckOnClick = true;
this.mnuHideExecutedBytes.Name = "mnuHideExecutedBytes";
this.mnuHideExecutedBytes.Size = new System.Drawing.Size(152, 22);
this.mnuHideExecutedBytes.Text = "Executed bytes";
this.mnuHideExecutedBytes.Click += new System.EventHandler(this.mnuColorProviderOptions_Click);
//
// toolStripMenuItem5
//
this.toolStripMenuItem5.Name = "toolStripMenuItem5";
this.toolStripMenuItem5.Size = new System.Drawing.Size(253, 6);
//
// mnuConfigureColors
//
this.mnuConfigureColors.Image = global::Mesen.GUI.Properties.Resources.PipetteSmall;
this.mnuConfigureColors.Name = "mnuConfigureColors";
this.mnuConfigureColors.Size = new System.Drawing.Size(256, 22);
this.mnuConfigureColors.Text = "Configure Colors";
this.mnuConfigureColors.Click += new System.EventHandler(this.mnuConfigureColors_Click);
//
// fontSizeToolStripMenuItem
//
this.fontSizeToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuIncreaseFontSize,
this.mnuDecreaseFontSize,
this.mnuResetFontSize,
this.toolStripMenuItem12,
this.mnuSelectFont,
this.toolStripMenuItem13,
this.mnuHighDensityMode});
this.fontSizeToolStripMenuItem.Image = global::Mesen.GUI.Properties.Resources.Font;
this.fontSizeToolStripMenuItem.Name = "fontSizeToolStripMenuItem";
this.fontSizeToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
this.fontSizeToolStripMenuItem.Text = "Font Options";
//
// mnuIncreaseFontSize
//
this.mnuIncreaseFontSize.Name = "mnuIncreaseFontSize";
this.mnuIncreaseFontSize.ShortcutKeyDisplayString = "";
this.mnuIncreaseFontSize.Size = new System.Drawing.Size(217, 22);
this.mnuIncreaseFontSize.Text = "Increase";
this.mnuIncreaseFontSize.Click += new System.EventHandler(this.mnuIncreaseFontSize_Click);
//
// mnuDecreaseFontSize
//
this.mnuDecreaseFontSize.Name = "mnuDecreaseFontSize";
this.mnuDecreaseFontSize.ShortcutKeyDisplayString = "";
this.mnuDecreaseFontSize.Size = new System.Drawing.Size(217, 22);
this.mnuDecreaseFontSize.Text = "Decrease";
this.mnuDecreaseFontSize.Click += new System.EventHandler(this.mnuDecreaseFontSize_Click);
//
// mnuResetFontSize
//
this.mnuResetFontSize.Name = "mnuResetFontSize";
this.mnuResetFontSize.ShortcutKeyDisplayString = "";
this.mnuResetFontSize.Size = new System.Drawing.Size(217, 22);
this.mnuResetFontSize.Text = "Reset to Default";
this.mnuResetFontSize.Click += new System.EventHandler(this.mnuResetFontSize_Click);
//
// toolStripMenuItem12
//
this.toolStripMenuItem12.Name = "toolStripMenuItem12";
this.toolStripMenuItem12.Size = new System.Drawing.Size(214, 6);
//
// mnuSelectFont
//
this.mnuSelectFont.Name = "mnuSelectFont";
this.mnuSelectFont.Size = new System.Drawing.Size(217, 22);
this.mnuSelectFont.Text = "Select Font...";
this.mnuSelectFont.Click += new System.EventHandler(this.mnuSelectFont_Click);
//
// toolStripMenuItem13
//
this.toolStripMenuItem13.Name = "toolStripMenuItem13";
this.toolStripMenuItem13.Size = new System.Drawing.Size(214, 6);
//
// mnuHighDensityMode
//
this.mnuHighDensityMode.CheckOnClick = true;
this.mnuHighDensityMode.Name = "mnuHighDensityMode";
this.mnuHighDensityMode.Size = new System.Drawing.Size(217, 22);
this.mnuHighDensityMode.Text = "Use high text density mode";
this.mnuHighDensityMode.CheckedChanged += new System.EventHandler(this.mnuHighDensityMode_CheckedChanged);
//
// autorefreshSpeedToolStripMenuItem
//
this.autorefreshSpeedToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuAutoRefreshLow,
this.mnuAutoRefreshNormal,
this.mnuAutoRefreshHigh});
this.autorefreshSpeedToolStripMenuItem.Image = global::Mesen.GUI.Properties.Resources.Speed;
this.autorefreshSpeedToolStripMenuItem.Name = "autorefreshSpeedToolStripMenuItem";
this.autorefreshSpeedToolStripMenuItem.Size = new System.Drawing.Size(256, 22);
this.autorefreshSpeedToolStripMenuItem.Text = "Auto-refresh Speed";
//
// mnuAutoRefreshLow
//
this.mnuAutoRefreshLow.Name = "mnuAutoRefreshLow";
this.mnuAutoRefreshLow.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshLow.Text = "Low (10 FPS)";
this.mnuAutoRefreshLow.Click += new System.EventHandler(this.mnuAutoRefreshSpeed_Click);
//
// mnuAutoRefreshNormal
//
this.mnuAutoRefreshNormal.Name = "mnuAutoRefreshNormal";
this.mnuAutoRefreshNormal.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshNormal.Text = "Normal (30 FPS)";
this.mnuAutoRefreshNormal.Click += new System.EventHandler(this.mnuAutoRefreshSpeed_Click);
//
// mnuAutoRefreshHigh
//
this.mnuAutoRefreshHigh.Name = "mnuAutoRefreshHigh";
this.mnuAutoRefreshHigh.Size = new System.Drawing.Size(159, 22);
this.mnuAutoRefreshHigh.Text = "High (60 FPS)";
this.mnuAutoRefreshHigh.Click += new System.EventHandler(this.mnuAutoRefreshSpeed_Click);
//
// toolStripMenuItem2
//
this.toolStripMenuItem2.Name = "toolStripMenuItem2";
this.toolStripMenuItem2.Size = new System.Drawing.Size(253, 6);
//
// mnuRefresh
//
this.mnuRefresh.Image = global::Mesen.GUI.Properties.Resources.Refresh;
this.mnuRefresh.Name = "mnuRefresh";
this.mnuRefresh.Size = new System.Drawing.Size(256, 22);
this.mnuRefresh.Text = "Refresh";
this.mnuRefresh.Click += new System.EventHandler(this.mnuRefresh_Click);
//
// toolStripMenuItem9
//
this.toolStripMenuItem9.Name = "toolStripMenuItem9";
this.toolStripMenuItem9.Size = new System.Drawing.Size(253, 6);
//
// mnuAutoRefresh
//
this.mnuAutoRefresh.Checked = true;
this.mnuAutoRefresh.CheckOnClick = true;
this.mnuAutoRefresh.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuAutoRefresh.Name = "mnuAutoRefresh";
this.mnuAutoRefresh.Size = new System.Drawing.Size(256, 22);
this.mnuAutoRefresh.Text = "Auto-refresh";
//
// mnuShowCharacters
//
this.mnuShowCharacters.Checked = true;
this.mnuShowCharacters.CheckOnClick = true;
this.mnuShowCharacters.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuShowCharacters.Name = "mnuShowCharacters";
this.mnuShowCharacters.Size = new System.Drawing.Size(256, 22);
this.mnuShowCharacters.Text = "Show characters";
//
// mnuShowLabelInfoOnMouseOver
//
this.mnuShowLabelInfoOnMouseOver.CheckOnClick = true;
this.mnuShowLabelInfoOnMouseOver.Name = "mnuShowLabelInfoOnMouseOver";
this.mnuShowLabelInfoOnMouseOver.Size = new System.Drawing.Size(256, 22);
this.mnuShowLabelInfoOnMouseOver.Text = "Show label tooltip on mouseover";
//
// toolStripMenuItem10
//
this.toolStripMenuItem10.Name = "toolStripMenuItem10";
this.toolStripMenuItem10.Size = new System.Drawing.Size(253, 6);
//
// mnuIgnoreRedundantWrites
//
this.mnuIgnoreRedundantWrites.CheckOnClick = true;
this.mnuIgnoreRedundantWrites.Name = "mnuIgnoreRedundantWrites";
this.mnuIgnoreRedundantWrites.Size = new System.Drawing.Size(256, 22);
this.mnuIgnoreRedundantWrites.Text = "Ignore writes that do not alter data";
//
// mnuEnablePerByteNavigation
//
this.mnuEnablePerByteNavigation.CheckOnClick = true;
this.mnuEnablePerByteNavigation.Name = "mnuEnablePerByteNavigation";
this.mnuEnablePerByteNavigation.Size = new System.Drawing.Size(256, 22);
this.mnuEnablePerByteNavigation.Text = "Use per-byte left/right navigation";
this.mnuEnablePerByteNavigation.CheckedChanged += new System.EventHandler(this.mnuEnablePerByteNavigation_CheckedChanged);
//
// mnuByteEditingMode
//
this.mnuByteEditingMode.CheckOnClick = true;
this.mnuByteEditingMode.Name = "mnuByteEditingMode";
this.mnuByteEditingMode.Size = new System.Drawing.Size(256, 22);
this.mnuByteEditingMode.Text = "Use per-byte editing mode";
this.mnuByteEditingMode.CheckedChanged += new System.EventHandler(this.mnuByteEditingMode_CheckedChanged);
//
// mnuHighlightCurrentRowColumn
//
this.mnuHighlightCurrentRowColumn.CheckOnClick = true;
this.mnuHighlightCurrentRowColumn.Name = "mnuHighlightCurrentRowColumn";
this.mnuHighlightCurrentRowColumn.Size = new System.Drawing.Size(256, 22);
this.mnuHighlightCurrentRowColumn.Text = "Highlight current row/column";
this.mnuHighlightCurrentRowColumn.CheckedChanged += new System.EventHandler(this.mnuHighlightCurrentRowColumn_CheckedChanged);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.mnuGoToAll,
this.mnuGoTo,
this.toolStripMenuItem14,
this.mnuFind,
this.mnuFindNext,
this.mnuFindPrev});
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(54, 20);
this.toolStripMenuItem1.Text = "Search";
//
// mnuGoToAll
//
this.mnuGoToAll.Name = "mnuGoToAll";
this.mnuGoToAll.Size = new System.Drawing.Size(145, 22);
this.mnuGoToAll.Text = "Go to All";
this.mnuGoToAll.Click += new System.EventHandler(this.mnuGoToAll_Click);
//
// mnuGoTo
//
this.mnuGoTo.Name = "mnuGoTo";
this.mnuGoTo.Size = new System.Drawing.Size(145, 22);
this.mnuGoTo.Text = "Go To...";
this.mnuGoTo.Click += new System.EventHandler(this.mnuGoTo_Click);
//
// toolStripMenuItem14
//
this.toolStripMenuItem14.Name = "toolStripMenuItem14";
this.toolStripMenuItem14.Size = new System.Drawing.Size(142, 6);
//
// mnuFind
//
this.mnuFind.Image = global::Mesen.GUI.Properties.Resources.Find;
this.mnuFind.Name = "mnuFind";
this.mnuFind.Size = new System.Drawing.Size(145, 22);
this.mnuFind.Text = "Find...";
this.mnuFind.Click += new System.EventHandler(this.mnuFind_Click);
//
// mnuFindNext
//
this.mnuFindNext.Image = global::Mesen.GUI.Properties.Resources.NextArrow;
this.mnuFindNext.Name = "mnuFindNext";
this.mnuFindNext.Size = new System.Drawing.Size(145, 22);
this.mnuFindNext.Text = "Find Next";
this.mnuFindNext.Click += new System.EventHandler(this.mnuFindNext_Click);
//
// mnuFindPrev
//
this.mnuFindPrev.Image = global::Mesen.GUI.Properties.Resources.PreviousArrow;
this.mnuFindPrev.Name = "mnuFindPrev";
this.mnuFindPrev.Size = new System.Drawing.Size(145, 22);
this.mnuFindPrev.Text = "Find Previous";
this.mnuFindPrev.Click += new System.EventHandler(this.mnuFindPrev_Click);
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgMemoryViewer);
this.tabMain.Controls.Add(this.tpgAccessCounters);
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabMain.Location = new System.Drawing.Point(0, 24);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(614, 369);
this.tabMain.TabIndex = 4;
this.tabMain.SelectedIndexChanged += new System.EventHandler(this.tabMain_SelectedIndexChanged);
//
// tpgMemoryViewer
//
this.tpgMemoryViewer.Controls.Add(this.panel1);
this.tpgMemoryViewer.Location = new System.Drawing.Point(4, 22);
this.tpgMemoryViewer.Margin = new System.Windows.Forms.Padding(0);
this.tpgMemoryViewer.Name = "tpgMemoryViewer";
this.tpgMemoryViewer.Size = new System.Drawing.Size(606, 343);
this.tpgMemoryViewer.TabIndex = 0;
this.tpgMemoryViewer.Text = "Memory Viewer";
this.tpgMemoryViewer.UseVisualStyleBackColor = true;
//
// panel1
//
this.panel1.Controls.Add(this.flowLayoutPanel1);
this.panel1.Controls.Add(this.ctrlHexViewer);
this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel1.Location = new System.Drawing.Point(0, 0);
this.panel1.Margin = new System.Windows.Forms.Padding(0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(606, 343);
this.panel1.TabIndex = 4;
//
// tpgAccessCounters
//
this.tpgAccessCounters.Location = new System.Drawing.Point(4, 22);
this.tpgAccessCounters.Margin = new System.Windows.Forms.Padding(0);
this.tpgAccessCounters.Name = "tpgAccessCounters";
this.tpgAccessCounters.Size = new System.Drawing.Size(606, 343);
this.tpgAccessCounters.TabIndex = 1;
this.tpgAccessCounters.Text = "Access Counters";
this.tpgAccessCounters.UseVisualStyleBackColor = true;
//
// frmMemoryViewer
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(614, 393);
this.Controls.Add(this.tabMain);
this.Controls.Add(this.menuStrip1);
this.MainMenuStrip = this.menuStrip1;
this.MinimumSize = new System.Drawing.Size(429, 337);
this.Name = "frmMemoryViewer";
this.Text = "Memory Tools";
this.flowLayoutPanel1.ResumeLayout(false);
this.flowLayoutPanel1.PerformLayout();
this.menuStrip1.ResumeLayout(false);
this.menuStrip1.PerformLayout();
this.tabMain.ResumeLayout(false);
this.tpgMemoryViewer.ResumeLayout(false);
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private Controls.ctrlHexViewer ctrlHexViewer;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
private System.Windows.Forms.Label lblViewMemoryType;
private Mesen.GUI.Debugger.Controls.ComboBoxWithSeparator cboMemoryType;
private Mesen.GUI.Controls.ctrlMesenMenuStrip menuStrip1;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuFind;
private System.Windows.Forms.ToolStripMenuItem mnuFindNext;
private System.Windows.Forms.ToolStripMenuItem mnuFindPrev;
private System.Windows.Forms.ToolStripMenuItem mnuGoTo;
private System.Windows.Forms.ToolStripMenuItem mnuView;
private System.Windows.Forms.ToolStripMenuItem mnuRefresh;
private System.Windows.Forms.ToolStripMenuItem fontSizeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuIncreaseFontSize;
private System.Windows.Forms.ToolStripMenuItem mnuDecreaseFontSize;
private System.Windows.Forms.ToolStripMenuItem mnuResetFontSize;
private System.Windows.Forms.ToolStripMenuItem fileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuClose;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefresh;
private System.Windows.Forms.ToolStripMenuItem mnuImport;
private System.Windows.Forms.ToolStripMenuItem mnuExport;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem3;
private System.Windows.Forms.TabControl tabMain;
private System.Windows.Forms.TabPage tpgMemoryViewer;
private System.Windows.Forms.TabPage tpgAccessCounters;
private System.Windows.Forms.ToolStripMenuItem mnuLoadTblFile;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem4;
private System.Windows.Forms.ToolStripMenuItem mnuShowCharacters;
private System.Windows.Forms.ToolStripMenuItem mnuResetTblMappings;
private System.Windows.Forms.ToolStripMenuItem highlightToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuHightlightReads;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightWrites;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightExecution;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem6;
private System.Windows.Forms.ToolStripMenuItem fadeSpeedToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem5;
private System.Windows.Forms.ToolStripMenuItem mnuFadeSlow;
private System.Windows.Forms.ToolStripMenuItem mnuFadeNormal;
private System.Windows.Forms.ToolStripMenuItem mnuFadeFast;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem7;
private System.Windows.Forms.ToolStripMenuItem mnuCustomFadeSpeed;
private System.Windows.Forms.ToolStripMenuItem fadeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuHideUnusedBytes;
private System.Windows.Forms.ToolStripMenuItem mnuHideReadBytes;
private System.Windows.Forms.ToolStripMenuItem mnuHideWrittenBytes;
private System.Windows.Forms.ToolStripMenuItem mnuHideExecutedBytes;
private System.Windows.Forms.ToolStripMenuItem mnuFadeNever;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.ToolStripMenuItem dataTypeHighlightingToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightCodeBytes;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightDataBytes;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem11;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightChrDrawnBytes;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightChrReadBytes;
private System.Windows.Forms.ToolStripMenuItem mnuConfigureColors;
private System.Windows.Forms.ToolStripMenuItem mnuShowLabelInfoOnMouseOver;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightLabelledBytes;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem8;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightDmcDataBytes;
private System.Windows.Forms.ToolStripMenuItem autorefreshSpeedToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshLow;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshNormal;
private System.Windows.Forms.ToolStripMenuItem mnuAutoRefreshHigh;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem9;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem10;
private System.Windows.Forms.ToolStripMenuItem mnuIgnoreRedundantWrites;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem12;
private System.Windows.Forms.ToolStripMenuItem mnuHighDensityMode;
private System.Windows.Forms.ToolStripMenuItem mnuEnablePerByteNavigation;
private System.Windows.Forms.ToolStripMenuItem mnuSelectFont;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem13;
private System.Windows.Forms.ToolStripMenuItem mnuByteEditingMode;
private System.Windows.Forms.ToolStripMenuItem mnuGoToAll;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem14;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightBreakpoints;
private System.Windows.Forms.ToolStripMenuItem mnuHighlightCurrentRowColumn;
}
}

View file

@ -0,0 +1,126 @@
<?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>
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>107, 17</value>
</metadata>
</root>

View file

@ -29,20 +29,20 @@ namespace Mesen.GUI.Debugger
{
InitializeComponent();
DebugInfo debugInfo = ConfigManager.Config.Debug;
if(!debugInfo.TraceLoggerSize.IsEmpty) {
TraceLoggerInfo config = ConfigManager.Config.Debug.TraceLogger;
if(!config.WindowSize.IsEmpty) {
this.StartPosition = FormStartPosition.Manual;
this.Size = debugInfo.TraceLoggerSize;
this.Location = debugInfo.TraceLoggerLocation;
this.Size = config.WindowSize;
this.Location = config.WindowLocation;
}
txtTraceLog.BaseFont = new Font(debugInfo.TraceFontFamily, debugInfo.TraceFontSize, debugInfo.TraceFontStyle);
txtTraceLog.TextZoom = debugInfo.TraceTextZoom;
txtTraceLog.BaseFont = new Font(config.FontFamily, config.FontSize, config.FontStyle);
txtTraceLog.TextZoom = config.TextZoom;
mnuAutoRefresh.Checked = debugInfo.TraceAutoRefresh;
_lineCount = debugInfo.TraceLineCount;
mnuAutoRefresh.Checked = config.AutoRefresh;
_lineCount = config.LineCount;
_entityBinder.Entity = debugInfo.TraceLoggerOptions;
_entityBinder.Entity = config.LogOptions;
_entityBinder.AddBinding("ShowByteCode", chkShowByteCode);
_entityBinder.AddBinding("ShowCpuCycles", chkShowCpuCycles);
_entityBinder.AddBinding("ShowEffectiveAddresses", chkShowEffectiveAddresses);
@ -90,16 +90,16 @@ namespace Mesen.GUI.Debugger
private void InitShortcuts()
{
//TODO
/*mnuIncreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.IncreaseFontSize));
mnuIncreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.IncreaseFontSize));
mnuDecreaseFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.DecreaseFontSize));
mnuResetFontSize.InitShortcut(this, nameof(DebuggerShortcutsConfig.ResetFontSize));
mnuRefresh.InitShortcut(this, nameof(DebuggerShortcutsConfig.Refresh));
mnuCopy.InitShortcut(this, nameof(DebuggerShortcutsConfig.Copy));
mnuSelectAll.InitShortcut(this, nameof(DebuggerShortcutsConfig.SelectAll));
mnuEditInMemoryViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer));
mnuViewInDisassembly.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInDisassembly));*/
//TODO
//mnuEditInMemoryViewer.InitShortcut(this, nameof(DebuggerShortcutsConfig.CodeWindow_EditInMemoryViewer));
//mnuViewInDisassembly.InitShortcut(this, nameof(DebuggerShortcutsConfig.MemoryViewer_ViewInDisassembly));
}
protected override void OnLoad(EventArgs e)
@ -122,16 +122,16 @@ namespace Mesen.GUI.Debugger
base.OnFormClosing(e);
DebugInfo debugInfo = ConfigManager.Config.Debug;
debugInfo.TraceAutoRefresh = mnuAutoRefresh.Checked;
debugInfo.TraceLineCount = _lineCount;
debugInfo.TraceLoggerSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
debugInfo.TraceLoggerLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
TraceLoggerInfo config = ConfigManager.Config.Debug.TraceLogger;
config.AutoRefresh = mnuAutoRefresh.Checked;
config.LineCount = _lineCount;
config.WindowSize = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Size : this.Size;
config.WindowLocation = this.WindowState != FormWindowState.Normal ? this.RestoreBounds.Location : this.Location;
debugInfo.TraceFontFamily = txtTraceLog.BaseFont.FontFamily.Name;
debugInfo.TraceFontSize = txtTraceLog.BaseFont.Size;
debugInfo.TraceFontStyle = txtTraceLog.BaseFont.Style;
debugInfo.TraceTextZoom = txtTraceLog.TextZoom;
config.FontFamily = txtTraceLog.BaseFont.FontFamily.Name;
config.FontSize = txtTraceLog.BaseFont.Size;
config.FontStyle = txtTraceLog.BaseFont.Style;
config.TextZoom = txtTraceLog.TextZoom;
_entityBinder.UpdateObject();
@ -270,7 +270,6 @@ namespace Mesen.GUI.Debugger
SetOptions();
Task.Run(() => {
//Update trace log in another thread for performance
//DebugState state = new DebugState();
DebugState state = DebugApi.GetState();
if(_previousCycleCount != state.Cpu.CycleCount || forceUpdate) {
string newTrace = DebugApi.GetExecutionTrace((UInt32)_lineCount);

View file

@ -14,7 +14,7 @@ namespace Mesen.GUI.Forms
{
public class EntityBinder
{
private Dictionary<string, Control> _bindings = new Dictionary<string, Control>();
private Dictionary<string, object> _bindings = new Dictionary<string, object>();
private Dictionary<string, eNumberFormat> _fieldFormat = new Dictionary<string, eNumberFormat>();
private Dictionary<string, FieldInfoWrapper> _fieldInfo = null;
@ -27,7 +27,7 @@ namespace Mesen.GUI.Forms
public bool Updating { get; private set; }
public void AddBinding(string fieldName, Control bindedField, eNumberFormat format = eNumberFormat.Default)
public void AddBinding(string fieldName, object bindedField, eNumberFormat format = eNumberFormat.Default)
{
if(BindedType == null) {
throw new Exception("Need to override BindedType to use bindings");
@ -62,7 +62,7 @@ namespace Mesen.GUI.Forms
{
this.Updating = true;
foreach(KeyValuePair<string, Control> kvp in _bindings) {
foreach(KeyValuePair<string, object> kvp in _bindings) {
if(!_fieldInfo.ContainsKey(kvp.Key)) {
throw new Exception("Invalid binding key");
} else {
@ -71,20 +71,22 @@ namespace Mesen.GUI.Forms
object value = field.GetValue(this.Entity);
if(kvp.Value is TextBox) {
if(value is IFormattable) {
kvp.Value.Text = ((IFormattable)value).ToString(format == eNumberFormat.Decimal ? "" : "X", System.Globalization.CultureInfo.InvariantCulture);
((TextBox)kvp.Value).Text = ((IFormattable)value).ToString(format == eNumberFormat.Decimal ? "" : "X", System.Globalization.CultureInfo.InvariantCulture);
} else {
kvp.Value.Text = value == null ? "" : ((string)value).Replace(Environment.NewLine, "\n").Replace("\n", Environment.NewLine);
((TextBox)kvp.Value).Text = value == null ? "" : ((string)value).Replace(Environment.NewLine, "\n").Replace("\n", Environment.NewLine);
}
} else if(kvp.Value is ctrlPathSelection) {
kvp.Value.Text = (string)value;
((ctrlPathSelection)kvp.Value).Text = (string)value;
} else if(kvp.Value is CheckBox) {
((CheckBox)kvp.Value).Checked = Convert.ToBoolean(value);
} else if(kvp.Value is ToolStripMenuItem) {
((ToolStripMenuItem)kvp.Value).Checked = Convert.ToBoolean(value);
} else if(kvp.Value is ctrlRiskyOption) {
((ctrlRiskyOption)kvp.Value).Checked = Convert.ToBoolean(value);
} else if(kvp.Value is RadioButton) {
((RadioButton)kvp.Value).Checked = (bool)value;
} else if(kvp.Value is Panel) {
RadioButton radio = kvp.Value.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Tag.Equals(value));
RadioButton radio = ((Panel)kvp.Value).Controls.OfType<RadioButton>().FirstOrDefault(r => r.Tag.Equals(value));
if(radio != null) {
radio.Checked = true;
} else {
@ -146,7 +148,7 @@ namespace Mesen.GUI.Forms
public void UpdateObject()
{
foreach(KeyValuePair<string, Control> kvp in _bindings) {
foreach(KeyValuePair<string, object> kvp in _bindings) {
if(!_fieldInfo.ContainsKey(kvp.Key)) {
throw new Exception("Invalid binding key");
} else {
@ -154,7 +156,7 @@ namespace Mesen.GUI.Forms
FieldInfoWrapper field = _fieldInfo[kvp.Key];
eNumberFormat format = _fieldFormat[kvp.Key];
if(kvp.Value is TextBox) {
object value = kvp.Value.Text;
object value = ((TextBox)kvp.Value).Text;
NumberStyles numberStyle = format == eNumberFormat.Decimal ? NumberStyles.Integer : NumberStyles.HexNumber;
if(field.FieldType != typeof(string)) {
value = ((string)value).Trim().Replace("$", "").Replace("0x", "");
@ -208,6 +210,10 @@ namespace Mesen.GUI.Forms
} else if(field.FieldType == typeof(byte)) {
field.SetValue(Entity, ((CheckBox)kvp.Value).Checked ? (byte)1 : (byte)0);
}
} else if(kvp.Value is ToolStripMenuItem) {
if(field.FieldType == typeof(bool)) {
field.SetValue(Entity, ((ToolStripMenuItem)kvp.Value).Checked);
}
} else if(kvp.Value is ctrlRiskyOption) {
if(field.FieldType == typeof(bool)) {
field.SetValue(Entity, ((ctrlRiskyOption)kvp.Value).Checked);
@ -217,7 +223,7 @@ namespace Mesen.GUI.Forms
} else if(kvp.Value is RadioButton) {
field.SetValue(Entity, ((RadioButton)kvp.Value).Checked);
} else if(kvp.Value is Panel) {
field.SetValue(Entity, kvp.Value.Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked).Tag);
field.SetValue(Entity, ((Panel)kvp.Value).Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked).Tag);
} else if(kvp.Value is ctrlTrackbar) {
if(field.FieldType == typeof(Int32)) {
field.SetValue(Entity, (Int32)((ctrlTrackbar)kvp.Value).Value);

View file

@ -38,6 +38,7 @@
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuDebugger = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMemoryTools = new System.Windows.Forms.ToolStripMenuItem();
this.mnuMain.SuspendLayout();
this.SuspendLayout();
//
@ -84,6 +85,7 @@
this.mnuRun100Instructions,
this.toolStripMenuItem1,
this.mnuDebugger,
this.mnuMemoryTools,
this.mnuTraceLogger});
this.debugToolStripMenuItem.Name = "debugToolStripMenuItem";
this.debugToolStripMenuItem.Size = new System.Drawing.Size(54, 20);
@ -120,19 +122,31 @@
//
// mnuDebugger
//
this.mnuDebugger.Enabled = false;
this.mnuDebugger.Image = global::Mesen.GUI.Properties.Resources.Debugger;
this.mnuDebugger.Name = "mnuDebugger";
this.mnuDebugger.Size = new System.Drawing.Size(163, 22);
this.mnuDebugger.Text = "Debugger";
//
// mnuTraceLogger
//
this.mnuTraceLogger.Image = global::Mesen.GUI.Properties.Resources.LogWindow;
this.mnuTraceLogger.Name = "mnuTraceLogger";
this.mnuTraceLogger.Size = new System.Drawing.Size(163, 22);
this.mnuTraceLogger.Text = "Trace Logger";
this.mnuTraceLogger.Click += new System.EventHandler(this.mnuTraceLogger_Click);
//
// mnuMemoryTools
//
this.mnuMemoryTools.Image = global::Mesen.GUI.Properties.Resources.CheatCode;
this.mnuMemoryTools.Name = "mnuMemoryTools";
this.mnuMemoryTools.Size = new System.Drawing.Size(163, 22);
this.mnuMemoryTools.Text = "Memory Tools";
this.mnuMemoryTools.Click += new System.EventHandler(this.mnuMemoryTools_Click);
//
// frmMain
//
this.AllowDrop = true;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(512, 475);
@ -161,5 +175,6 @@
private System.Windows.Forms.ToolStripMenuItem mnuRun;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuRun100Instructions;
private System.Windows.Forms.ToolStripMenuItem mnuMemoryTools;
}
}

View file

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -34,6 +35,12 @@ namespace Mesen.GUI.Forms
frm.Show();
}
private void mnuMemoryTools_Click(object sender, EventArgs e)
{
frmMemoryTools frm = new frmMemoryTools();
frm.Show();
}
private void mnuStep_Click(object sender, EventArgs e)
{
DebugApi.Step(1);
@ -44,10 +51,7 @@ namespace Mesen.GUI.Forms
using(OpenFileDialog ofd = new OpenFileDialog()) {
ofd.Filter = ResourceHelper.GetMessage("FilterRom");
if(ofd.ShowDialog() == DialogResult.OK) {
EmuApi.LoadRom(ofd.FileName);
Task.Run(() => {
EmuApi.Run();
});
LoadFile(ofd.FileName);
}
}
}
@ -61,5 +65,45 @@ namespace Mesen.GUI.Forms
{
DebugApi.Step(1000);
}
private void LoadFile(string filepath)
{
EmuApi.LoadRom(filepath);
Task.Run(() => {
EmuApi.Run();
});
}
protected override void OnDragDrop(DragEventArgs e)
{
base.OnDragDrop(e);
try {
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
if(File.Exists(files[0])) {
LoadFile(files[0]);
this.Activate();
} else {
//InteropEmu.DisplayMessage("Error", "File not found: " + files[0]);
}
} catch(Exception ex) {
MesenMsgBox.Show("UnexpectedError", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.ToString());
}
}
protected override void OnDragEnter(DragEventArgs e)
{
base.OnDragEnter(e);
try {
if(e.Data != null && e.Data.GetDataPresent(DataFormats.FileDrop)) {
e.Effect = DragDropEffects.Copy;
} else {
//InteropEmu.DisplayMessage("Error", "Unsupported operation.");
}
} catch(Exception ex) {
MesenMsgBox.Show("UnexpectedError", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.ToString());
}
}
}
}

View file

@ -35,6 +35,31 @@ namespace Mesen.GUI
DebugApi.GetStateWrapper(ref state);
return state;
}
[DllImport(DllPath)] public static extern Int32 GetMemorySize(SnesMemoryType type);
[DllImport(DllPath)] public static extern Byte GetMemoryValue(SnesMemoryType type, UInt32 address);
[DllImport(DllPath)] public static extern void SetMemoryValue(SnesMemoryType type, UInt32 address, byte value);
[DllImport(DllPath)] public static extern void SetMemoryValues(SnesMemoryType type, UInt32 address, [In] byte[] data, Int32 length);
[DllImport(DllPath)] public static extern void SetMemoryState(SnesMemoryType type, [In] byte[] buffer, Int32 length);
[DllImport(DllPath, EntryPoint = "GetMemoryState")] private static extern void GetMemoryStateWrapper(SnesMemoryType type, [In, Out] byte[] buffer);
public static byte[] GetMemoryState(SnesMemoryType type)
{
byte[] buffer = new byte[DebugApi.GetMemorySize(type)];
DebugApi.GetMemoryStateWrapper(type, buffer);
return buffer;
}
}
public enum SnesMemoryType
{
CpuMemory,
PrgRom,
WorkRam,
SaveRam,
VideoRam,
SpriteRam,
CGRam,
}
public struct CpuState

View file

@ -20,6 +20,9 @@ namespace Mesen.GUI
[DllImport(DllPath, EntryPoint = "GetMesenVersion")] private static extern UInt32 GetMesenVersionWrapper();
[DllImport(DllPath)] public static extern IntPtr RegisterNotificationCallback(NotificationListener.NotificationCallback callback);
[DllImport(DllPath)] public static extern void UnregisterNotificationCallback(IntPtr notificationListener);
[DllImport(DllPath)] public static extern void InitializeEmu([MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(Utf8Marshaler))]string homeFolder, IntPtr windowHandle, IntPtr dxViewerHandle, [MarshalAs(UnmanagedType.I1)]bool noAudio, [MarshalAs(UnmanagedType.I1)]bool noVideo, [MarshalAs(UnmanagedType.I1)]bool noInput);
[DllImport(DllPath)] public static extern void Release();

View file

@ -0,0 +1,61 @@
using System;
namespace Mesen.GUI
{
public class NotificationListener : IDisposable
{
public delegate void NotificationCallback(int type, IntPtr parameter);
public delegate void NotificationEventHandler(NotificationEventArgs e);
public event NotificationEventHandler OnNotification;
//Need to keep a reference to this callback, or it will get garbage collected (since the only reference to it is on the native side)
NotificationCallback _callback;
IntPtr _notificationListener;
public NotificationListener()
{
_callback = (int type, IntPtr parameter) => {
this.ProcessNotification(type, parameter);
};
_notificationListener = EmuApi.RegisterNotificationCallback(_callback);
}
public void Dispose()
{
EmuApi.UnregisterNotificationCallback(_notificationListener);
}
public void ProcessNotification(int type, IntPtr parameter)
{
if(this.OnNotification != null) {
this.OnNotification(new NotificationEventArgs() {
NotificationType = (ConsoleNotificationType)type,
Parameter = parameter
});
}
}
}
public class NotificationEventArgs
{
public ConsoleNotificationType NotificationType;
public IntPtr Parameter;
}
public enum ConsoleNotificationType
{
GameLoaded = 0,
StateLoaded = 1,
GameReset = 2,
GamePaused = 3,
GameResumed = 4,
GameStopped = 5,
CodeBreak = 6,
PpuFrameDone = 7,
ResolutionChanged = 8,
ConfigChanged = 9,
ExecuteShortcut = 10,
EmulationStopped = 11,
BeforeEmulationStop = 12,
}
}

View file

@ -213,7 +213,10 @@
<Compile Include="Config\ConfigAttributes.cs" />
<Compile Include="Config\Configuration.cs" />
<Compile Include="Config\ConfigManager.cs" />
<Compile Include="Config\DebugInfo.cs" />
<Compile Include="Debugger\Config\DebuggerShortcutsConfig.cs" />
<Compile Include="Debugger\Config\HexEditorInfo.cs" />
<Compile Include="Debugger\Config\TraceLoggerInfo.cs" />
<Compile Include="Debugger\Config\DebugInfo.cs" />
<Compile Include="Controls\BaseControl.cs">
<SubType>UserControl</SubType>
</Compile>
@ -277,6 +280,33 @@
<Compile Include="Controls\MyListView.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Debugger\Controls\ComboBoxWithSeparator.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlDbgShortcuts.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlDbgShortcuts.designer.cs">
<DependentUpon>ctrlDbgShortcuts.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlHexViewer.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Debugger\Controls\ctrlHexViewer.designer.cs">
<DependentUpon>ctrlHexViewer.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmDbgPreferences.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmDbgPreferences.designer.cs">
<DependentUpon>frmDbgPreferences.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmDbgShortcutGetKey.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmDbgShortcutGetKey.designer.cs">
<DependentUpon>frmDbgShortcutGetKey.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\ctrlCodeScrollbar.cs">
<SubType>Component</SubType>
</Compile>
@ -293,6 +323,24 @@
<DependentUpon>ctrlScrollableTextbox.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\FontDialogHelper.cs" />
<Compile Include="Debugger\frmFadeSpeed.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmFadeSpeed.designer.cs">
<DependentUpon>frmFadeSpeed.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmGoToLine.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmGoToLine.designer.cs">
<DependentUpon>frmGoToLine.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmMemoryTools.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Debugger\frmMemoryTools.designer.cs">
<DependentUpon>frmMemoryTools.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\frmTraceLogger.cs">
<SubType>Form</SubType>
</Compile>
@ -300,6 +348,29 @@
<DependentUpon>frmTraceLogger.cs</DependentUpon>
</Compile>
<Compile Include="Debugger\Controls\TextboxHistory.cs" />
<Compile Include="Debugger\HexBox\BuiltInContextMenu.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Debugger\HexBox\ByteCharConverters.cs" />
<Compile Include="Debugger\HexBox\ByteCollection.cs" />
<Compile Include="Debugger\HexBox\BytePositionInfo.cs" />
<Compile Include="Debugger\HexBox\DataBlock.cs" />
<Compile Include="Debugger\HexBox\DataMap.cs" />
<Compile Include="Debugger\HexBox\DynamicByteProvider.cs" />
<Compile Include="Debugger\HexBox\FileDataBlock.cs" />
<Compile Include="Debugger\HexBox\FindOptions.cs" />
<Compile Include="Debugger\HexBox\HexBox.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Debugger\HexBox\HexCasing.cs" />
<Compile Include="Debugger\HexBox\IByteColorProvider.cs" />
<Compile Include="Debugger\HexBox\IByteProvider.cs" />
<Compile Include="Debugger\HexBox\MemoryDataBlock.cs" />
<Compile Include="Debugger\HexBox\NativeMethods.cs" />
<Compile Include="Debugger\HexBox\StaticByteProvider.cs" />
<Compile Include="Debugger\HexBox\TblByteCharConverter.cs" />
<Compile Include="Debugger\HexBox\Util.cs" />
<Compile Include="Debugger\TblLoader.cs" />
<Compile Include="Forms\BaseConfigForm.Designer.cs">
<DependentUpon>BaseConfigForm.cs</DependentUpon>
</Compile>
@ -325,6 +396,7 @@
<Compile Include="Forms\ResourcePath.cs" />
<Compile Include="Interop\DebugApi.cs" />
<Compile Include="Interop\EmuApi.cs" />
<Compile Include="Interop\NotificationListener.cs" />
<Compile Include="Interop\Utf8Marshaler.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
@ -355,12 +427,36 @@
<EmbeddedResource Include="Controls\ctrlRenderer.resx">
<DependentUpon>ctrlRenderer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlDbgShortcuts.resx">
<DependentUpon>ctrlDbgShortcuts.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlHexViewer.resx">
<DependentUpon>ctrlHexViewer.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmDbgPreferences.resx">
<DependentUpon>frmDbgPreferences.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmDbgShortcutGetKey.resx">
<DependentUpon>frmDbgShortcutGetKey.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\Controls\ctrlScrollableTextbox.resx">
<DependentUpon>ctrlScrollableTextbox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmFadeSpeed.resx">
<DependentUpon>frmFadeSpeed.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmGoToLine.resx">
<DependentUpon>frmGoToLine.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmMemoryTools.resx">
<DependentUpon>frmMemoryTools.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\frmTraceLogger.resx">
<DependentUpon>frmTraceLogger.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Debugger\HexBox\HexBox.resx">
<DependentUpon>HexBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\BaseConfigForm.resx">
<DependentUpon>BaseConfigForm.cs</DependentUpon>
</EmbeddedResource>