Debugger: Added Event Viewer
This commit is contained in:
parent
b6f1f54888
commit
0ada7f9d2f
43 changed files with 2309 additions and 38 deletions
|
@ -19,6 +19,7 @@
|
|||
#include "FrameLimiter.h"
|
||||
#include "MessageManager.h"
|
||||
#include "KeyManager.h"
|
||||
#include "EventType.h"
|
||||
#include "../Utilities/Timer.h"
|
||||
#include "../Utilities/VirtualFile.h"
|
||||
#include "../Utilities/PlatformUtilities.h"
|
||||
|
@ -68,6 +69,8 @@ void Console::Run()
|
|||
|
||||
uint32_t keyCode = KeyManager::GetKeyCode("Tab");
|
||||
|
||||
_emulationThreadId = std::this_thread::get_id();
|
||||
|
||||
auto lock = _runLock.AcquireSafe();
|
||||
while(!_stopFlag) {
|
||||
_cpu->Exec();
|
||||
|
@ -81,6 +84,8 @@ void Console::Run()
|
|||
}
|
||||
}
|
||||
|
||||
_emulationThreadId = thread::id();
|
||||
|
||||
PlatformUtilities::RestoreTimerResolution();
|
||||
}
|
||||
|
||||
|
@ -136,7 +141,7 @@ void Console::LoadRom(VirtualFile romFile, VirtualFile patchFile)
|
|||
|
||||
_memoryManager->Initialize(shared_from_this());
|
||||
|
||||
_cpu.reset(new Cpu(_memoryManager.get()));
|
||||
_cpu.reset(new Cpu(this));
|
||||
_memoryManager->IncrementMasterClockValue<162>();
|
||||
|
||||
//if(_debugger) {
|
||||
|
@ -228,6 +233,11 @@ shared_ptr<Debugger> Console::GetDebugger(bool autoStart)
|
|||
return debugger;
|
||||
}
|
||||
|
||||
thread::id Console::GetEmulationThreadId()
|
||||
{
|
||||
return _emulationThreadId;
|
||||
}
|
||||
|
||||
bool Console::IsRunning()
|
||||
{
|
||||
return _cpu != nullptr;
|
||||
|
@ -280,4 +290,11 @@ void Console::ProcessPpuCycle()
|
|||
if(_debugger) {
|
||||
_debugger->ProcessPpuCycle();
|
||||
}
|
||||
}
|
||||
|
||||
void Console::ProcessEvent(EventType type)
|
||||
{
|
||||
if(_debugger) {
|
||||
_debugger->ProcessEvent(type);
|
||||
}
|
||||
}
|
|
@ -19,6 +19,7 @@ class VideoDecoder;
|
|||
class NotificationManager;
|
||||
enum class MemoryOperationType;
|
||||
enum class SnesMemoryType;
|
||||
enum class EventType;
|
||||
|
||||
class Console : public std::enable_shared_from_this<Console>
|
||||
{
|
||||
|
@ -40,6 +41,8 @@ private:
|
|||
shared_ptr<VideoDecoder> _videoDecoder;
|
||||
shared_ptr<DebugHud> _debugHud;
|
||||
|
||||
thread::id _emulationThreadId;
|
||||
|
||||
SimpleLock _runLock;
|
||||
SimpleLock _debuggerLock;
|
||||
atomic<bool> _stopFlag;
|
||||
|
@ -71,6 +74,8 @@ public:
|
|||
shared_ptr<ControlManager> GetControlManager();
|
||||
shared_ptr<DmaController> GetDmaController();
|
||||
shared_ptr<Debugger> GetDebugger(bool autoStart = true);
|
||||
|
||||
thread::id GetEmulationThreadId();
|
||||
|
||||
bool IsRunning();
|
||||
|
||||
|
@ -81,4 +86,5 @@ public:
|
|||
void ProcessWorkRamRead(uint32_t addr, uint8_t value);
|
||||
void ProcessWorkRamWrite(uint32_t addr, uint8_t value);
|
||||
void ProcessPpuCycle();
|
||||
void ProcessEvent(EventType type);
|
||||
};
|
|
@ -59,7 +59,10 @@
|
|||
<ClInclude Include="ControlDeviceState.h" />
|
||||
<ClInclude Include="ControlManager.h" />
|
||||
<ClInclude Include="Cpu.h" />
|
||||
<ClInclude Include="DebugBreakHelper.h" />
|
||||
<ClInclude Include="DummyCpu.h" />
|
||||
<ClInclude Include="EventManager.h" />
|
||||
<ClInclude Include="EventType.h" />
|
||||
<ClInclude Include="ExpressionEvaluator.h" />
|
||||
<ClInclude Include="PpuTools.h" />
|
||||
<ClInclude Include="RegisterHandlerB.h" />
|
||||
|
@ -130,6 +133,7 @@
|
|||
<ClCompile Include="Disassembler.cpp" />
|
||||
<ClCompile Include="DisassemblyInfo.cpp" />
|
||||
<ClCompile Include="DmaController.cpp" />
|
||||
<ClCompile Include="EventManager.cpp" />
|
||||
<ClCompile Include="ExpressionEvaluator.cpp" />
|
||||
<ClCompile Include="InternalRegisters.cpp" />
|
||||
<ClCompile Include="KeyManager.cpp" />
|
||||
|
|
|
@ -200,6 +200,15 @@
|
|||
<ClInclude Include="PpuTools.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EventManager.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="EventType.h">
|
||||
<Filter>Misc</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DebugBreakHelper.h">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp" />
|
||||
|
@ -308,8 +317,15 @@
|
|||
<ClCompile Include="Breakpoint.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="BreakpointManager.cpp" />
|
||||
<ClCompile Include="PpuTools.cpp" />
|
||||
<ClCompile Include="BreakpointManager.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="EventManager.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PpuTools.cpp">
|
||||
<Filter>Debugger</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="SNES">
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#include "stdafx.h"
|
||||
#include "CpuTypes.h"
|
||||
#include "Cpu.h"
|
||||
#include "Console.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "EventType.h"
|
||||
|
||||
Cpu::Cpu(MemoryManager* memoryManager)
|
||||
Cpu::Cpu(Console *console)
|
||||
{
|
||||
_memoryManager = memoryManager;
|
||||
_console = console;
|
||||
_memoryManager = console->GetMemoryManager().get();
|
||||
_state = {};
|
||||
_state.PC = ReadDataWord(Cpu::ResetVector);
|
||||
_state.SP = 0x1FF;
|
||||
|
@ -292,9 +295,11 @@ void Cpu::Exec()
|
|||
//Use the state of the IRQ/NMI flags on the previous cycle to determine if an IRQ is processed or not
|
||||
if(_prevNmiFlag) {
|
||||
ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyNmiVector : Cpu::NmiVector);
|
||||
_console->ProcessEvent(EventType::Nmi);
|
||||
_nmiFlag = false;
|
||||
} else if(_prevIrqSource && !CheckFlag(ProcFlags::IrqDisable)) {
|
||||
ProcessInterrupt(_state.EmulationMode ? Cpu::LegacyIrqVector : Cpu::IrqVector);
|
||||
_console->ProcessEvent(EventType::Irq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "CpuTypes.h"
|
||||
|
||||
class MemoryManager;
|
||||
class Console;
|
||||
|
||||
class Cpu
|
||||
{
|
||||
|
@ -31,7 +32,8 @@ private:
|
|||
|
||||
typedef void(Cpu::*Func)();
|
||||
|
||||
MemoryManager* _memoryManager;
|
||||
MemoryManager *_memoryManager;
|
||||
Console *_console;
|
||||
|
||||
bool _immediateMode = false;
|
||||
|
||||
|
@ -292,7 +294,7 @@ private:
|
|||
void AddrMode_StkRelIndIdxY();
|
||||
|
||||
public:
|
||||
Cpu(MemoryManager* memoryManager);
|
||||
Cpu(Console *console);
|
||||
~Cpu();
|
||||
|
||||
void Reset();
|
||||
|
|
36
Core/DebugBreakHelper.h
Normal file
36
Core/DebugBreakHelper.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "Debugger.h"
|
||||
#include "Console.h"
|
||||
|
||||
class DebugBreakHelper
|
||||
{
|
||||
private:
|
||||
Debugger * _debugger;
|
||||
bool _needResume = false;
|
||||
bool _isEmulationThread = false;
|
||||
|
||||
public:
|
||||
DebugBreakHelper(Debugger* debugger)
|
||||
{
|
||||
_debugger = debugger;
|
||||
|
||||
_isEmulationThread = debugger->GetConsole()->GetEmulationThreadId() == std::this_thread::get_id();
|
||||
|
||||
if(!_isEmulationThread) {
|
||||
//Only attempt to break if this is done in a thread other than the main emulation thread
|
||||
debugger->BreakRequest(true);
|
||||
if(!debugger->IsExecutionStopped()) {
|
||||
while(!debugger->IsExecutionStopped()) {}
|
||||
_needResume = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~DebugBreakHelper()
|
||||
{
|
||||
if(!_isEmulationThread) {
|
||||
_debugger->BreakRequest(false);
|
||||
}
|
||||
}
|
||||
};
|
|
@ -6,6 +6,7 @@
|
|||
#include "Ppu.h"
|
||||
#include "BaseCartridge.h"
|
||||
#include "MemoryManager.h"
|
||||
#include "SoundMixer.h"
|
||||
#include "NotificationManager.h"
|
||||
#include "CpuTypes.h"
|
||||
#include "DisassemblyInfo.h"
|
||||
|
@ -15,6 +16,8 @@
|
|||
#include "Disassembler.h"
|
||||
#include "BreakpointManager.h"
|
||||
#include "PpuTools.h"
|
||||
#include "EventManager.h"
|
||||
#include "EventType.h"
|
||||
#include "ExpressionEvaluator.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
#include "../Utilities/FolderUtilities.h"
|
||||
|
@ -29,11 +32,15 @@ Debugger::Debugger(shared_ptr<Console> console)
|
|||
_watchExpEval.reset(new ExpressionEvaluator(this));
|
||||
_codeDataLogger.reset(new CodeDataLogger(console->GetCartridge()->DebugGetPrgRomSize()));
|
||||
_disassembler.reset(new Disassembler(console, _codeDataLogger));
|
||||
_traceLogger.reset(new TraceLogger(this, _memoryManager));
|
||||
_traceLogger.reset(new TraceLogger(this, _console));
|
||||
_memoryDumper.reset(new MemoryDumper(_ppu, _memoryManager, console->GetCartridge()));
|
||||
_breakpointManager.reset(new BreakpointManager(this));
|
||||
_ppuTools.reset(new PpuTools(_console.get(), _ppu.get()));
|
||||
_eventManager.reset(new EventManager(this, _cpu.get(), _ppu.get()));
|
||||
|
||||
_cpuStepCount = 0;
|
||||
_executionStopped = false;
|
||||
_breakRequestCount = 0;
|
||||
|
||||
string cdlFile = FolderUtilities::CombinePath(FolderUtilities::GetDebuggerFolder(), FolderUtilities::GetFilename(_console->GetCartridge()->GetRomInfo().RomPath, false) + ".cdl");
|
||||
_codeDataLogger->LoadCdlFile(cdlFile);
|
||||
|
@ -100,6 +107,10 @@ void Debugger::ProcessCpuRead(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
}
|
||||
}
|
||||
|
||||
if(_memoryManager->IsRegister(addr)) {
|
||||
_eventManager->AddEvent(DebugEventType::Register, operation);
|
||||
}
|
||||
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
|
@ -111,6 +122,10 @@ void Debugger::ProcessCpuWrite(uint32_t addr, uint8_t value, MemoryOperationType
|
|||
_disassembler->InvalidateCache(addressInfo);
|
||||
}
|
||||
|
||||
if(_memoryManager->IsRegister(addr)) {
|
||||
_eventManager->AddEvent(DebugEventType::Register, operation);
|
||||
}
|
||||
|
||||
ProcessBreakConditions(operation, addressInfo);
|
||||
}
|
||||
|
||||
|
@ -157,12 +172,25 @@ void Debugger::ProcessBreakConditions(MemoryOperationInfo &operation, AddressInf
|
|||
_cpuStepCount = 0;
|
||||
}
|
||||
|
||||
if(_cpuStepCount == 0) {
|
||||
if(_cpuStepCount == 0 || _breakRequestCount) {
|
||||
_console->GetSoundMixer()->StopAudio();
|
||||
_disassembler->Disassemble();
|
||||
|
||||
_console->GetNotificationManager()->SendNotification(ConsoleNotificationType::CodeBreak);
|
||||
while(_cpuStepCount == 0) {
|
||||
_executionStopped = true;
|
||||
while(_cpuStepCount == 0 || _breakRequestCount) {
|
||||
std::this_thread::sleep_for(std::chrono::duration<int, std::milli>(10));
|
||||
}
|
||||
_executionStopped = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::ProcessEvent(EventType type)
|
||||
{
|
||||
switch(type) {
|
||||
case EventType::Nmi: _eventManager->AddEvent(DebugEventType::Nmi); break;
|
||||
case EventType::Irq: _eventManager->AddEvent(DebugEventType::Irq); break;
|
||||
case EventType::StartFrame: _eventManager->ClearFrameEvents(); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -191,8 +219,16 @@ void Debugger::Step(int32_t stepCount)
|
|||
|
||||
bool Debugger::IsExecutionStopped()
|
||||
{
|
||||
//TODO
|
||||
return false;
|
||||
return _executionStopped;
|
||||
}
|
||||
|
||||
void Debugger::BreakRequest(bool release)
|
||||
{
|
||||
if(release) {
|
||||
_breakRequestCount--;
|
||||
} else {
|
||||
_breakRequestCount++;
|
||||
}
|
||||
}
|
||||
|
||||
void Debugger::GetState(DebugState &state)
|
||||
|
@ -225,3 +261,13 @@ shared_ptr<PpuTools> Debugger::GetPpuTools()
|
|||
{
|
||||
return _ppuTools;
|
||||
}
|
||||
|
||||
shared_ptr<EventManager> Debugger::GetEventManager()
|
||||
{
|
||||
return _eventManager;
|
||||
}
|
||||
|
||||
shared_ptr<Console> Debugger::GetConsole()
|
||||
{
|
||||
return _console;
|
||||
}
|
|
@ -8,18 +8,22 @@ class Cpu;
|
|||
class Ppu;
|
||||
class BaseCartridge;
|
||||
class MemoryManager;
|
||||
class CodeDataLogger;
|
||||
|
||||
enum class SnesMemoryType;
|
||||
enum class MemoryOperationType;
|
||||
enum class BreakpointCategory;
|
||||
enum class EvalResultType : int32_t;
|
||||
class TraceLogger;
|
||||
class ExpressionEvaluator;
|
||||
class MemoryDumper;
|
||||
class Disassembler;
|
||||
class BreakpointManager;
|
||||
class PpuTools;
|
||||
class CodeDataLogger;
|
||||
class EventManager;
|
||||
|
||||
enum class EventType;
|
||||
enum class SnesMemoryType;
|
||||
enum class MemoryOperationType;
|
||||
enum class BreakpointCategory;
|
||||
enum class EvalResultType : int32_t;
|
||||
|
||||
struct DebugState;
|
||||
struct MemoryOperationInfo;
|
||||
struct AddressInfo;
|
||||
|
@ -39,9 +43,13 @@ private:
|
|||
shared_ptr<Disassembler> _disassembler;
|
||||
shared_ptr<BreakpointManager> _breakpointManager;
|
||||
shared_ptr<PpuTools> _ppuTools;
|
||||
shared_ptr<EventManager> _eventManager;
|
||||
|
||||
unique_ptr<ExpressionEvaluator> _watchExpEval;
|
||||
|
||||
atomic<bool> _executionStopped;
|
||||
atomic<uint32_t> _breakRequestCount;
|
||||
|
||||
atomic<int32_t> _cpuStepCount;
|
||||
uint8_t _prevOpCode = 0;
|
||||
|
||||
|
@ -60,6 +68,7 @@ public:
|
|||
void ProcessPpuCycle();
|
||||
|
||||
void ProcessBreakConditions(MemoryOperationInfo &operation, AddressInfo &addressInfo);
|
||||
void ProcessEvent(EventType type);
|
||||
|
||||
int32_t EvaluateExpression(string expression, EvalResultType &resultType, bool useCache);
|
||||
|
||||
|
@ -67,6 +76,8 @@ public:
|
|||
void Step(int32_t stepCount);
|
||||
bool IsExecutionStopped();
|
||||
|
||||
void BreakRequest(bool release);
|
||||
|
||||
void GetState(DebugState &state);
|
||||
|
||||
shared_ptr<TraceLogger> GetTraceLogger();
|
||||
|
@ -74,4 +85,6 @@ public:
|
|||
shared_ptr<Disassembler> GetDisassembler();
|
||||
shared_ptr<BreakpointManager> GetBreakpointManager();
|
||||
shared_ptr<PpuTools> GetPpuTools();
|
||||
shared_ptr<EventManager> GetEventManager();
|
||||
shared_ptr<Console> GetConsole();
|
||||
};
|
|
@ -252,10 +252,9 @@ bool Disassembler::GetLineData(uint32_t lineIndex, CodeLineData &data)
|
|||
|
||||
data.OpSize = disInfo->GetOperandSize() + 1;
|
||||
|
||||
MemoryManager *memoryManager = _console->GetMemoryManager().get();
|
||||
data.EffectiveAddress = disInfo->GetEffectiveAddress(state, memoryManager);
|
||||
data.EffectiveAddress = disInfo->GetEffectiveAddress(state, _console);
|
||||
if(data.EffectiveAddress >= 0) {
|
||||
data.Value = disInfo->GetMemoryValue(data.EffectiveAddress, memoryManager, data.ValueSize);
|
||||
data.Value = disInfo->GetMemoryValue(data.EffectiveAddress, _console->GetMemoryManager().get(), data.ValueSize);
|
||||
} else {
|
||||
data.ValueSize = 0;
|
||||
}
|
||||
|
|
|
@ -185,18 +185,18 @@ void DisassemblyInfo::GetByteCode(string &out)
|
|||
out += str.ToString();
|
||||
}
|
||||
|
||||
void DisassemblyInfo::GetEffectiveAddressString(string &out, CpuState &state, MemoryManager* memoryManager)
|
||||
void DisassemblyInfo::GetEffectiveAddressString(string &out, CpuState &state, Console* console)
|
||||
{
|
||||
int32_t effectiveAddress = GetEffectiveAddress(state, memoryManager);
|
||||
int32_t effectiveAddress = GetEffectiveAddress(state, console);
|
||||
if(effectiveAddress >= 0) {
|
||||
out += " [" + HexUtilities::ToHex24(effectiveAddress) + "]";
|
||||
}
|
||||
}
|
||||
|
||||
int32_t DisassemblyInfo::GetEffectiveAddress(CpuState &state, MemoryManager *memoryManager)
|
||||
int32_t DisassemblyInfo::GetEffectiveAddress(CpuState &state, Console *console)
|
||||
{
|
||||
if(_addrMode > AddrMode::ImmM && _addrMode != AddrMode::Acc && _addrMode != AddrMode::Imp && _addrMode != AddrMode::Stk && _addrMode != AddrMode::Rel && _addrMode != AddrMode::RelLng && _addrMode != AddrMode::BlkMov) {
|
||||
DummyCpu cpu(memoryManager);
|
||||
DummyCpu cpu(console);
|
||||
state.PS &= ~(ProcFlags::IndexMode8 | ProcFlags::MemoryMode8);
|
||||
state.PS |= _flags;
|
||||
cpu.SetDummyState(state);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "stdafx.h"
|
||||
#include <unordered_map>
|
||||
|
||||
class Console;
|
||||
class MemoryManager;
|
||||
|
||||
struct CpuState;
|
||||
|
@ -36,8 +37,8 @@ public:
|
|||
void GetByteCode(uint8_t copyBuffer[4]);
|
||||
void GetByteCode(string &out);
|
||||
|
||||
void GetEffectiveAddressString(string &out, CpuState &state, MemoryManager* memoryManager);
|
||||
int32_t GetEffectiveAddress(CpuState &state, MemoryManager *memoryManager);
|
||||
void GetEffectiveAddressString(string &out, CpuState &state, Console* console);
|
||||
int32_t GetEffectiveAddress(CpuState &state, Console *console);
|
||||
uint16_t GetMemoryValue(uint32_t effectiveAddress, MemoryManager *memoryManager, uint8_t &valueSize);
|
||||
};
|
||||
|
||||
|
|
192
Core/EventManager.cpp
Normal file
192
Core/EventManager.cpp
Normal file
|
@ -0,0 +1,192 @@
|
|||
#include "stdafx.h"
|
||||
#include "EventManager.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "Cpu.h"
|
||||
#include "Ppu.h"
|
||||
#include "Debugger.h"
|
||||
#include "DebugBreakHelper.h"
|
||||
|
||||
EventManager::EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu)
|
||||
{
|
||||
_debugger = debugger;
|
||||
_cpu = cpu;
|
||||
_ppu = ppu;
|
||||
}
|
||||
|
||||
void EventManager::AddEvent(DebugEventType type, MemoryOperationInfo &operation, int32_t breakpointId)
|
||||
{
|
||||
DebugEventInfo evt;
|
||||
evt.Type = type;
|
||||
evt.Operation = operation;
|
||||
evt.Scanline = _ppu->GetScanline();
|
||||
evt.Cycle = _ppu->GetCycle();
|
||||
evt.BreakpointId = breakpointId;
|
||||
evt.ProgramCounter = _cpu->GetState().PC;
|
||||
|
||||
_debugEvents.push_back(evt);
|
||||
}
|
||||
|
||||
void EventManager::AddEvent(DebugEventType type)
|
||||
{
|
||||
DebugEventInfo evt = {};
|
||||
evt.Type = type;
|
||||
evt.Scanline = _ppu->GetScanline();
|
||||
evt.Cycle = _ppu->GetCycle();
|
||||
evt.ProgramCounter = _cpu->GetState().PC;
|
||||
_debugEvents.push_back(evt);
|
||||
}
|
||||
|
||||
void EventManager::GetEvents(DebugEventInfo *eventArray, uint32_t &maxEventCount, bool getPreviousFrameData)
|
||||
{
|
||||
DebugBreakHelper breakHelper(_debugger);
|
||||
|
||||
vector<DebugEventInfo> &events = getPreviousFrameData ? _prevDebugEvents : _debugEvents;
|
||||
uint32_t eventCount = std::min(maxEventCount, (uint32_t)events.size());
|
||||
memcpy(eventArray, events.data(), eventCount * sizeof(DebugEventInfo));
|
||||
maxEventCount = eventCount;
|
||||
}
|
||||
|
||||
DebugEventInfo EventManager::GetEvent(uint16_t scanline, uint16_t cycle, EventViewerDisplayOptions &options)
|
||||
{
|
||||
auto lock = _lock.AcquireSafe();
|
||||
|
||||
for(DebugEventInfo &evt : _sentEvents) {
|
||||
if(evt.Cycle == cycle && evt.Scanline == scanline) {
|
||||
return evt;
|
||||
}
|
||||
}
|
||||
|
||||
DebugEventInfo empty = {};
|
||||
empty.ProgramCounter = 0xFFFFFFFF;
|
||||
return empty;
|
||||
}
|
||||
|
||||
uint32_t EventManager::GetEventCount(bool getPreviousFrameData)
|
||||
{
|
||||
DebugBreakHelper breakHelper(_debugger);
|
||||
return (uint32_t)(getPreviousFrameData ? _prevDebugEvents.size() : _debugEvents.size());
|
||||
}
|
||||
|
||||
void EventManager::ClearFrameEvents()
|
||||
{
|
||||
_prevDebugEvents = _debugEvents;
|
||||
_debugEvents.clear();
|
||||
}
|
||||
|
||||
void EventManager::DrawEvent(DebugEventInfo &evt, bool drawBackground, uint32_t *buffer, EventViewerDisplayOptions &options)
|
||||
{
|
||||
bool isWrite = evt.Operation.Type == MemoryOperationType::Write || evt.Operation.Type == MemoryOperationType::DmaWrite;
|
||||
bool showEvent = false;
|
||||
uint32_t color = 0;
|
||||
switch(evt.Type) {
|
||||
case DebugEventType::Breakpoint: showEvent = options.ShowMarkedBreakpoints; color = options.BreakpointColor; break;
|
||||
case DebugEventType::Irq: showEvent = options.ShowIrq; color = options.IrqColor; break;
|
||||
case DebugEventType::Nmi: showEvent = options.ShowNmi; color = options.NmiColor; break;
|
||||
case DebugEventType::Register:
|
||||
uint16_t reg = evt.Operation.Address & 0xFFFF;
|
||||
if(reg <= 0x213F) {
|
||||
showEvent = isWrite ? options.ShowPpuRegisterWrites : options.ShowPpuRegisterReads;
|
||||
color = isWrite ? options.PpuRegisterWriteColor : options.PpuRegisterReadColor;
|
||||
} else if(reg <= 0x217F) {
|
||||
showEvent = isWrite ? options.ShowApuRegisterWrites : options.ShowApuRegisterReads;
|
||||
color = isWrite ? options.ApuRegisterWriteColor : options.ApuRegisterReadColor;
|
||||
} else if(reg <= 0x2183) {
|
||||
showEvent = isWrite ? options.ShowWorkRamRegisterWrites : options.ShowWorkRamRegisterReads;
|
||||
color = isWrite ? options.WorkRamRegisterWriteColor : options.WorkRamRegisterReadColor;
|
||||
} else if(reg >= 0x4000) {
|
||||
showEvent = isWrite ? options.ShowCpuRegisterWrites : options.ShowCpuRegisterReads;
|
||||
color = isWrite ? options.CpuRegisterWriteColor : options.CpuRegisterReadColor;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(!showEvent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(drawBackground){
|
||||
color = 0xFF000000 | ((color >> 1) & 0x7F7F7F);
|
||||
} else {
|
||||
_sentEvents.push_back(evt);
|
||||
color |= 0xFF000000;
|
||||
}
|
||||
|
||||
int iMin = drawBackground ? -2 : 0;
|
||||
int iMax = drawBackground ? 3 : 1;
|
||||
int jMin = drawBackground ? -2 : 0;
|
||||
int jMax = drawBackground ? 3 : 1;
|
||||
uint32_t y = evt.Scanline * 2;
|
||||
uint32_t x = evt.Cycle * 2;
|
||||
|
||||
for(int i = iMin; i <= iMax; i++) {
|
||||
for(int j = jMin; j <= jMax; j++) {
|
||||
int32_t pos = (y + i) * 340 * 2 + x + j;
|
||||
if(pos < 0 || pos > 340 * 2 * 262 * 2) {
|
||||
continue;
|
||||
}
|
||||
buffer[pos] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventManager::TakeEventSnapshot(EventViewerDisplayOptions options)
|
||||
{
|
||||
DebugBreakHelper breakHelper(_debugger);
|
||||
auto lock = _lock.AcquireSafe();
|
||||
_snapshot.clear();
|
||||
|
||||
uint16_t cycle = _ppu->GetState().Cycle;
|
||||
uint16_t scanline = _ppu->GetState().Scanline;
|
||||
uint32_t key = (scanline << 9) + cycle;
|
||||
|
||||
_snapshot = _debugEvents;
|
||||
_snapshotScanline = scanline;
|
||||
if(options.ShowPreviousFrameEvents) {
|
||||
for(DebugEventInfo &evt : _prevDebugEvents) {
|
||||
uint32_t evtKey = (evt.Scanline << 9) + evt.Cycle;
|
||||
if(evtKey > key) {
|
||||
_snapshot.push_back(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventManager::GetDisplayBuffer(uint32_t *buffer, EventViewerDisplayOptions options)
|
||||
{
|
||||
auto lock = _lock.AcquireSafe();
|
||||
_sentEvents.clear();
|
||||
|
||||
for(int i = 0; i < 340 * 2 * 262 * 2; i++) {
|
||||
buffer[i] = 0xFF555555;
|
||||
}
|
||||
bool overscanMode = _ppu->GetState().OverscanMode;
|
||||
uint16_t *ppuBuffer = _ppu->GetScreenBuffer();
|
||||
uint32_t pixelCount = 256*2*239*2;
|
||||
for(uint32_t y = 0, len = overscanMode ? 239*2 : 224*2; y < len; y++) {
|
||||
for(uint32_t x = 0; x < 512; x++) {
|
||||
uint16_t rgb555 = ppuBuffer[(y << 9) | x];
|
||||
uint8_t b = (rgb555 >> 10) * 256 / 32;
|
||||
uint8_t g = ((rgb555 >> 5) & 0x1F) * 256 / 32;
|
||||
uint8_t r = (rgb555 & 0x1F) * 256 / 32;
|
||||
|
||||
buffer[(y + 2)*340*2 + x + 22*2] = 0xFF000000 | (r << 16) | (g << 8) | b;
|
||||
}
|
||||
}
|
||||
|
||||
constexpr uint32_t nmiColor = 0xFF55FFFF;
|
||||
int nmiScanline = (overscanMode ? 240 : 225) * 2 * 340 * 2;
|
||||
uint32_t scanlineOffset = _snapshotScanline * 2 * 340 * 2;
|
||||
for(int i = 0; i < 340 * 2; i++) {
|
||||
buffer[nmiScanline + i] = nmiColor;
|
||||
buffer[nmiScanline + 340 * 2 + i] = nmiColor;
|
||||
buffer[scanlineOffset + i] = nmiColor;
|
||||
buffer[scanlineOffset + 340 * 2 + i] = nmiColor;
|
||||
}
|
||||
|
||||
for(DebugEventInfo &evt : _snapshot) {
|
||||
DrawEvent(evt, true, buffer, options);
|
||||
}
|
||||
for(DebugEventInfo &evt : _snapshot) {
|
||||
DrawEvent(evt, false, buffer, options);
|
||||
}
|
||||
}
|
94
Core/EventManager.h
Normal file
94
Core/EventManager.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "DmaController.h"
|
||||
#include "DebugTypes.h"
|
||||
#include "../Utilities/SimpleLock.h"
|
||||
|
||||
enum class DebugEventType;
|
||||
struct DebugEventInfo;
|
||||
struct EventViewerDisplayOptions;
|
||||
class Cpu;
|
||||
class Ppu;
|
||||
class Debugger;
|
||||
|
||||
class EventManager
|
||||
{
|
||||
private:
|
||||
Cpu * _cpu;
|
||||
Ppu *_ppu;
|
||||
Debugger *_debugger;
|
||||
vector<DebugEventInfo> _debugEvents;
|
||||
vector<DebugEventInfo> _prevDebugEvents;
|
||||
vector<DebugEventInfo> _sentEvents;
|
||||
|
||||
vector<DebugEventInfo> _snapshot;
|
||||
uint16_t _snapshotScanline;
|
||||
SimpleLock _lock;
|
||||
|
||||
void DrawEvent(DebugEventInfo &evt, bool drawBackground, uint32_t *buffer, EventViewerDisplayOptions &options);
|
||||
|
||||
public:
|
||||
EventManager(Debugger *debugger, Cpu *cpu, Ppu *ppu);
|
||||
|
||||
void AddEvent(DebugEventType type, MemoryOperationInfo &operation, int32_t breakpointId = -1);
|
||||
void AddEvent(DebugEventType type);
|
||||
|
||||
void GetEvents(DebugEventInfo *eventArray, uint32_t &maxEventCount, bool getPreviousFrameData);
|
||||
uint32_t GetEventCount(bool getPreviousFrameData);
|
||||
void ClearFrameEvents();
|
||||
|
||||
void TakeEventSnapshot(EventViewerDisplayOptions options);
|
||||
void GetDisplayBuffer(uint32_t *buffer, EventViewerDisplayOptions options);
|
||||
DebugEventInfo GetEvent(uint16_t scanline, uint16_t cycle, EventViewerDisplayOptions &options);
|
||||
};
|
||||
|
||||
enum class DebugEventType
|
||||
{
|
||||
Register,
|
||||
Nmi,
|
||||
Irq,
|
||||
Breakpoint
|
||||
};
|
||||
|
||||
struct DebugEventInfo
|
||||
{
|
||||
MemoryOperationInfo Operation;
|
||||
DebugEventType Type;
|
||||
uint32_t ProgramCounter;
|
||||
uint16_t Scanline;
|
||||
uint16_t Cycle;
|
||||
int16_t BreakpointId;
|
||||
//DmaChannelConfig DmaChannelInfo;
|
||||
//uint8_t DmaChannel;
|
||||
};
|
||||
|
||||
struct EventViewerDisplayOptions
|
||||
{
|
||||
bool ShowPpuRegisterWrites;
|
||||
bool ShowPpuRegisterReads;
|
||||
bool ShowCpuRegisterWrites;
|
||||
bool ShowCpuRegisterReads;
|
||||
|
||||
bool ShowApuRegisterWrites;
|
||||
bool ShowApuRegisterReads;
|
||||
bool ShowWorkRamRegisterWrites;
|
||||
bool ShowWorkRamRegisterReads;
|
||||
|
||||
bool ShowNmi;
|
||||
bool ShowIrq;
|
||||
|
||||
bool ShowMarkedBreakpoints;
|
||||
bool ShowPreviousFrameEvents;
|
||||
|
||||
uint32_t IrqColor;
|
||||
uint32_t NmiColor;
|
||||
uint32_t BreakpointColor;
|
||||
uint32_t PpuRegisterReadColor;
|
||||
uint32_t PpuRegisterWriteColor;
|
||||
uint32_t ApuRegisterReadColor;
|
||||
uint32_t ApuRegisterWriteColor;
|
||||
uint32_t CpuRegisterReadColor;
|
||||
uint32_t CpuRegisterWriteColor;
|
||||
uint32_t WorkRamRegisterReadColor;
|
||||
uint32_t WorkRamRegisterWriteColor;
|
||||
};
|
9
Core/EventType.h
Normal file
9
Core/EventType.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
enum class EventType
|
||||
{
|
||||
Nmi = 0,
|
||||
Irq = 1,
|
||||
StartFrame = 2,
|
||||
EndFrame = 3
|
||||
};
|
|
@ -233,6 +233,11 @@ uint8_t * MemoryManager::DebugGetWorkRam()
|
|||
return _workRam;
|
||||
}
|
||||
|
||||
bool MemoryManager::IsRegister(uint32_t cpuAddress)
|
||||
{
|
||||
return _handlers[cpuAddress >> 12] == _registerHandlerA.get() || _handlers[cpuAddress >> 12] == _registerHandlerB.get();
|
||||
}
|
||||
|
||||
AddressInfo MemoryManager::GetAbsoluteAddress(uint32_t addr)
|
||||
{
|
||||
if(_handlers[addr >> 12]) {
|
||||
|
|
|
@ -58,6 +58,7 @@ public:
|
|||
uint64_t GetMasterClock();
|
||||
uint8_t* DebugGetWorkRam();
|
||||
|
||||
bool IsRegister(uint32_t cpuAddress);
|
||||
AddressInfo GetAbsoluteAddress(uint32_t addr);
|
||||
int GetRelativeAddress(AddressInfo &address, int32_t cpuAddress = -1);
|
||||
};
|
||||
|
|
17
Core/Ppu.cpp
17
Core/Ppu.cpp
|
@ -10,6 +10,7 @@
|
|||
#include "NotificationManager.h"
|
||||
#include "DmaController.h"
|
||||
#include "MessageManager.h"
|
||||
#include "EventType.h"
|
||||
#include "../Utilities/HexUtilities.h"
|
||||
|
||||
Ppu::Ppu(shared_ptr<Console> console)
|
||||
|
@ -54,6 +55,16 @@ uint32_t Ppu::GetFrameCount()
|
|||
return _frameCount;
|
||||
}
|
||||
|
||||
uint16_t Ppu::GetScanline()
|
||||
{
|
||||
return _scanline;
|
||||
}
|
||||
|
||||
uint16_t Ppu::GetCycle()
|
||||
{
|
||||
return _cycle;
|
||||
}
|
||||
|
||||
PpuState Ppu::GetState()
|
||||
{
|
||||
PpuState state;
|
||||
|
@ -110,6 +121,7 @@ void Ppu::Exec()
|
|||
_scanline = 0;
|
||||
_rangeOver = false;
|
||||
_timeOver = false;
|
||||
_console->ProcessEvent(EventType::StartFrame);
|
||||
|
||||
if(_mosaicEnabled) {
|
||||
_mosaicStartScanline = 0;
|
||||
|
@ -1066,6 +1078,11 @@ void Ppu::SendFrame()
|
|||
}
|
||||
}
|
||||
|
||||
uint16_t* Ppu::GetScreenBuffer()
|
||||
{
|
||||
return _currentBuffer;
|
||||
}
|
||||
|
||||
uint8_t* Ppu::GetVideoRam()
|
||||
{
|
||||
return _vram;
|
||||
|
|
|
@ -224,10 +224,13 @@ public:
|
|||
~Ppu();
|
||||
|
||||
uint32_t GetFrameCount();
|
||||
uint16_t GetScanline();
|
||||
uint16_t GetCycle();
|
||||
PpuState GetState();
|
||||
|
||||
void Exec();
|
||||
|
||||
uint16_t* GetScreenBuffer();
|
||||
uint8_t* GetVideoRam();
|
||||
uint8_t* GetCgRam();
|
||||
uint8_t* GetSpriteRam();
|
||||
|
|
|
@ -10,9 +10,9 @@
|
|||
|
||||
string TraceLogger::_executionTrace = "";
|
||||
|
||||
TraceLogger::TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager)
|
||||
TraceLogger::TraceLogger(Debugger* debugger, shared_ptr<Console> console)
|
||||
{
|
||||
_memoryManager = memoryManager;
|
||||
_console = console;
|
||||
_currentPos = 0;
|
||||
_logCount = 0;
|
||||
_logToFile = false;
|
||||
|
@ -218,17 +218,17 @@ void TraceLogger::GetTraceRow(string &output, CpuState &cpuState, PpuState &ppuS
|
|||
case RowDataType::EffectiveAddress:
|
||||
{
|
||||
string effectiveAddress;
|
||||
disassemblyInfo.GetEffectiveAddressString(effectiveAddress, cpuState, _memoryManager.get());
|
||||
disassemblyInfo.GetEffectiveAddressString(effectiveAddress, cpuState, _console.get());
|
||||
WriteValue(output, effectiveAddress, rowPart);
|
||||
break;
|
||||
}
|
||||
|
||||
case RowDataType::MemoryValue:
|
||||
{
|
||||
int32_t address = disassemblyInfo.GetEffectiveAddress(cpuState, _memoryManager.get());
|
||||
int32_t address = disassemblyInfo.GetEffectiveAddress(cpuState, _console.get());
|
||||
if(address >= 0) {
|
||||
uint8_t valueSize;
|
||||
uint16_t value = disassemblyInfo.GetMemoryValue(address, _memoryManager.get(), valueSize);
|
||||
uint16_t value = disassemblyInfo.GetMemoryValue(address, _console->GetMemoryManager().get(), valueSize);
|
||||
if(rowPart.DisplayInHex) {
|
||||
output += "= $";
|
||||
if(valueSize == 2) {
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include "DisassemblyInfo.h"
|
||||
#include "../Utilities/SimpleLock.h"
|
||||
|
||||
class MemoryManager;
|
||||
class Console;
|
||||
class Debugger;
|
||||
struct DebugState;
|
||||
|
||||
|
@ -63,7 +63,7 @@ private:
|
|||
string _outputFilepath;
|
||||
string _outputBuffer;
|
||||
ofstream _outputFile;
|
||||
shared_ptr<MemoryManager> _memoryManager;
|
||||
shared_ptr<Console> _console;
|
||||
//shared_ptr<LabelManager> _labelManager;
|
||||
|
||||
vector<RowPart> _rowParts;
|
||||
|
@ -94,7 +94,7 @@ private:
|
|||
template<typename T> void WriteValue(string &output, T value, RowPart& rowPart);
|
||||
|
||||
public:
|
||||
TraceLogger(Debugger* debugger, shared_ptr<MemoryManager> memoryManager);
|
||||
TraceLogger(Debugger* debugger, shared_ptr<Console> console);
|
||||
~TraceLogger();
|
||||
|
||||
void Log(DebugState &state, DisassemblyInfo &disassemblyInfo);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "../Core/Breakpoint.h"
|
||||
#include "../Core/BreakpointManager.h"
|
||||
#include "../Core/PpuTools.h"
|
||||
#include "../Core/EventManager.h"
|
||||
|
||||
extern shared_ptr<Console> _console;
|
||||
|
||||
|
@ -63,4 +64,10 @@ extern "C"
|
|||
|
||||
DllExport void __stdcall GetTilemap(GetTilemapOptions options, uint32_t *buffer) { GetDebugger()->GetPpuTools()->GetTilemap(options, buffer); }
|
||||
DllExport void __stdcall SetViewerUpdateTiming(uint32_t viewerId, uint16_t scanline, uint16_t cycle) { GetDebugger()->GetPpuTools()->SetViewerUpdateTiming(viewerId, scanline, cycle); }
|
||||
|
||||
DllExport void __stdcall GetDebugEvents(DebugEventInfo *infoArray, uint32_t &maxEventCount, bool getPreviousFrameData) { GetDebugger()->GetEventManager()->GetEvents(infoArray, maxEventCount, getPreviousFrameData); }
|
||||
DllExport uint32_t __stdcall GetDebugEventCount(bool getPreviousFrameData) { return GetDebugger()->GetEventManager()->GetEventCount(getPreviousFrameData); }
|
||||
DllExport void __stdcall GetEventViewerOutput(uint32_t *buffer, EventViewerDisplayOptions options) { GetDebugger()->GetEventManager()->GetDisplayBuffer(buffer, options); }
|
||||
DllExport DebugEventInfo __stdcall GetEventViewerEvent(uint16_t scanline, uint16_t cycle, EventViewerDisplayOptions options) { return GetDebugger()->GetEventManager()->GetEvent(scanline, cycle, options); }
|
||||
DllExport void __stdcall TakeEventSnapshot(EventViewerDisplayOptions options) { GetDebugger()->GetEventManager()->TakeEventSnapshot(options); }
|
||||
};
|
|
@ -19,10 +19,10 @@ namespace Mesen.GUI.Config
|
|||
public DebuggerShortcutsConfig Shortcuts = new DebuggerShortcutsConfig();
|
||||
public TraceLoggerInfo TraceLogger = new TraceLoggerInfo();
|
||||
public HexEditorInfo HexEditor = new HexEditorInfo();
|
||||
public EventViewerInfo EventViewer = new EventViewerInfo();
|
||||
|
||||
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;
|
||||
|
|
70
UI/Debugger/Config/EventViewerInfo.cs
Normal file
70
UI/Debugger/Config/EventViewerInfo.cs
Normal file
|
@ -0,0 +1,70 @@
|
|||
using Mesen.GUI.Utilities;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Mesen.GUI.Config
|
||||
{
|
||||
public class EventViewerInfo
|
||||
{
|
||||
public bool ShowPpuRegisterWrites = true;
|
||||
public bool ShowPpuRegisterReads = true;
|
||||
public bool ShowCpuRegisterWrites = true;
|
||||
public bool ShowCpuRegisterReads = true;
|
||||
|
||||
public bool ShowApuRegisterWrites = false;
|
||||
public bool ShowApuRegisterReads = false;
|
||||
public bool ShowWorkRamRegisterWrites = false;
|
||||
public bool ShowWorkRamRegisterReads = false;
|
||||
|
||||
public bool ShowNmi = true;
|
||||
public bool ShowIrq = true;
|
||||
|
||||
public bool ShowMarkedBreakpoints = true;
|
||||
public bool ShowPreviousFrameEvents = true;
|
||||
|
||||
public XmlColor IrqColor = ColorTranslator.FromHtml("#FFADAC");
|
||||
public XmlColor NmiColor = ColorTranslator.FromHtml("#FFADAC");
|
||||
public XmlColor BreakpointColor = ColorTranslator.FromHtml("#FFADAC");
|
||||
public XmlColor PpuRegisterReadColor = ColorTranslator.FromHtml("#007597");
|
||||
public XmlColor PpuRegisterWriteColor = ColorTranslator.FromHtml("#C92929");
|
||||
public XmlColor ApuRegisterReadColor = ColorTranslator.FromHtml("#F9FEAC");
|
||||
public XmlColor ApuRegisterWriteColor = ColorTranslator.FromHtml("#9F93C6");
|
||||
public XmlColor CpuRegisterReadColor = ColorTranslator.FromHtml("#1898E4");
|
||||
public XmlColor CpuRegisterWriteColor = ColorTranslator.FromHtml("#FF5E5E");
|
||||
public XmlColor WorkRamRegisterReadColor = ColorTranslator.FromHtml("#8E33FF");
|
||||
public XmlColor WorkRamRegisterWriteColor = ColorTranslator.FromHtml("#2EFF28");
|
||||
|
||||
public EventViewerDisplayOptions GetInteropOptions()
|
||||
{
|
||||
return new EventViewerDisplayOptions() {
|
||||
ShowPpuRegisterWrites = this.ShowPpuRegisterWrites,
|
||||
ShowPpuRegisterReads = this.ShowPpuRegisterReads,
|
||||
ShowCpuRegisterWrites = this.ShowCpuRegisterWrites,
|
||||
ShowCpuRegisterReads = this.ShowCpuRegisterReads,
|
||||
ShowApuRegisterWrites = this.ShowApuRegisterWrites,
|
||||
ShowApuRegisterReads = this.ShowApuRegisterReads,
|
||||
ShowWorkRamRegisterWrites = this.ShowWorkRamRegisterWrites,
|
||||
ShowWorkRamRegisterReads = this.ShowWorkRamRegisterReads,
|
||||
ShowNmi = this.ShowNmi,
|
||||
ShowIrq = this.ShowIrq,
|
||||
ShowMarkedBreakpoints = this.ShowMarkedBreakpoints,
|
||||
ShowPreviousFrameEvents = this.ShowPreviousFrameEvents,
|
||||
IrqColor = (uint)this.IrqColor.Color.ToArgb(),
|
||||
NmiColor = (uint)this.NmiColor.Color.ToArgb(),
|
||||
BreakpointColor = (uint)this.BreakpointColor.Color.ToArgb(),
|
||||
PpuRegisterReadColor = (uint)this.PpuRegisterReadColor.Color.ToArgb(),
|
||||
PpuRegisterWriteColor = (uint)this.PpuRegisterWriteColor.Color.ToArgb(),
|
||||
ApuRegisterReadColor = (uint)this.ApuRegisterReadColor.Color.ToArgb(),
|
||||
ApuRegisterWriteColor = (uint)this.ApuRegisterWriteColor.Color.ToArgb(),
|
||||
CpuRegisterReadColor = (uint)this.CpuRegisterReadColor.Color.ToArgb(),
|
||||
CpuRegisterWriteColor = (uint)this.CpuRegisterWriteColor.Color.ToArgb(),
|
||||
WorkRamRegisterReadColor = (uint)this.WorkRamRegisterReadColor.Color.ToArgb(),
|
||||
WorkRamRegisterWriteColor = (uint)this.WorkRamRegisterWriteColor.Color.ToArgb()
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
32
UI/Debugger/Controls/ctrlColorPicker.cs
Normal file
32
UI/Debugger/Controls/ctrlColorPicker.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public class ctrlColorPicker : PictureBox
|
||||
{
|
||||
public ctrlColorPicker() : base()
|
||||
{
|
||||
this.BorderStyle = BorderStyle.FixedSingle;
|
||||
}
|
||||
|
||||
protected override void OnClick(EventArgs e)
|
||||
{
|
||||
base.OnClick(e);
|
||||
|
||||
using(ColorDialog cd = new ColorDialog()) {
|
||||
cd.SolidColorOnly = true;
|
||||
cd.AllowFullOpen = true;
|
||||
cd.FullOpen = true;
|
||||
cd.Color = this.BackColor;
|
||||
if(cd.ShowDialog() == DialogResult.OK) {
|
||||
this.BackColor = cd.Color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1052,7 +1052,7 @@ namespace Mesen.GUI.Debugger.Controls
|
|||
}
|
||||
|
||||
if(lineProperties.Symbol.HasFlag(LineSymbol.Mark)) {
|
||||
using(Brush b = new SolidBrush(ConfigManager.Config.Debug.EventViewerBreakpointColor)) {
|
||||
using(Brush b = new SolidBrush(ConfigManager.Config.Debug.EventViewer.BreakpointColor)) {
|
||||
g.FillEllipse(b, circleOffsetX + circleSize * 3 / 4, positionY + 1, lineHeight / 2.0f, lineHeight / 2.0f);
|
||||
}
|
||||
g.DrawEllipse(Pens.Black, circleOffsetX + circleSize * 3 / 4, positionY + 1, lineHeight / 2.0f, lineHeight / 2.0f);
|
||||
|
|
|
@ -35,6 +35,7 @@ namespace Mesen.GUI.Debugger
|
|||
case DebugWindow.TraceLogger: frm = new frmTraceLogger(); frm.Icon = Properties.Resources.LogWindow; break;
|
||||
case DebugWindow.MemoryTools: frm = new frmMemoryTools(); frm.Icon = Properties.Resources.CheatCode; break;
|
||||
case DebugWindow.TilemapViewer: frm = new frmTilemapViewer(); frm.Icon = Properties.Resources.VideoOptions; break;
|
||||
case DebugWindow.EventViewer: frm = new frmEventViewer(); frm.Icon = Properties.Resources.NesEventViewer; break;
|
||||
}
|
||||
_openedWindows.Add(frm);
|
||||
frm.FormClosed += Debugger_FormClosed;
|
||||
|
@ -117,6 +118,7 @@ namespace Mesen.GUI.Debugger
|
|||
Debugger,
|
||||
MemoryTools,
|
||||
TraceLogger,
|
||||
TilemapViewer
|
||||
TilemapViewer,
|
||||
EventViewer
|
||||
}
|
||||
}
|
||||
|
|
280
UI/Debugger/EventViewer/ctrlEventViewerPpuView.cs
Normal file
280
UI/Debugger/EventViewer/ctrlEventViewerPpuView.cs
Normal file
|
@ -0,0 +1,280 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Data;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
using System.Runtime.InteropServices;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Forms;
|
||||
using Mesen.GUI.Config;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class ctrlEventViewerPpuView : BaseControl
|
||||
{
|
||||
private int _baseWidth = 340 * 2;
|
||||
private int _baseHeight = 262 * 2;
|
||||
|
||||
private EntityBinder _entityBinder = new EntityBinder();
|
||||
private frmInfoTooltip _tooltip = null;
|
||||
private Point _lastPos = new Point(-1, -1);
|
||||
private bool _needUpdate = false;
|
||||
private Bitmap _screenBitmap = null;
|
||||
private Bitmap _overlayBitmap = null;
|
||||
private Bitmap _displayBitmap = null;
|
||||
private byte[] _pictureData = null;
|
||||
private Font _overlayFont;
|
||||
private bool _zoomed = false;
|
||||
|
||||
public ctrlEventViewerPpuView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
if(!IsDesignMode) {
|
||||
tmrOverlay.Start();
|
||||
_overlayFont = new Font(BaseControl.MonospaceFontFamily, 10);
|
||||
|
||||
_entityBinder.Entity = ConfigManager.Config.Debug.EventViewer;
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ApuRegisterReadColor), picApuReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ApuRegisterWriteColor), picApuWrites);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.CpuRegisterReadColor), picCpuReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.CpuRegisterWriteColor), picCpuWrites);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.IrqColor), picIrq);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.BreakpointColor), picMarkedBreakpoints);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.NmiColor), picNmi);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.PpuRegisterReadColor), picPpuReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.PpuRegisterWriteColor), picPpuWrites);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.WorkRamRegisterReadColor), picWramReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.WorkRamRegisterWriteColor), picWramWrites);
|
||||
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowApuRegisterReads), chkShowApuRegisterReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowApuRegisterWrites), chkShowApuRegisterWrites);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowCpuRegisterReads), chkShowCpuRegisterReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowCpuRegisterWrites), chkShowCpuRegisterWrites);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowIrq), chkShowIrq);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowMarkedBreakpoints), chkShowMarkedBreakpoints);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowNmi), chkShowNmi);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowPpuRegisterReads), chkShowPpuRegisterReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowPpuRegisterWrites), chkShowPpuRegisterWrites);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowWorkRamRegisterReads), chkShowWorkRamRegisterReads);
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowWorkRamRegisterWrites), chkShowWorkRamRegisterWrites);
|
||||
|
||||
_entityBinder.AddBinding(nameof(EventViewerInfo.ShowPreviousFrameEvents), chkShowPreviousFrameEvents);
|
||||
|
||||
_entityBinder.UpdateUI();
|
||||
|
||||
RefreshData();
|
||||
RefreshViewer();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnHandleDestroyed(EventArgs e)
|
||||
{
|
||||
if(!IsDesignMode) {
|
||||
_entityBinder.UpdateObject();
|
||||
ConfigManager.ApplyChanges();
|
||||
}
|
||||
|
||||
base.OnHandleDestroyed(e);
|
||||
}
|
||||
|
||||
public void RefreshData()
|
||||
{
|
||||
this.BeginInvoke((Action)(() => {
|
||||
_entityBinder.UpdateObject();
|
||||
}));
|
||||
|
||||
EventViewerDisplayOptions options = ConfigManager.Config.Debug.EventViewer.GetInteropOptions();
|
||||
DebugApi.TakeEventSnapshot(options);
|
||||
}
|
||||
|
||||
public void RefreshViewer()
|
||||
{
|
||||
_entityBinder.UpdateObject();
|
||||
EventViewerDisplayOptions options = ConfigManager.Config.Debug.EventViewer.GetInteropOptions();
|
||||
_pictureData = DebugApi.GetEventViewerOutput(options);
|
||||
|
||||
int picHeight = _baseHeight;
|
||||
if(_screenBitmap == null || _screenBitmap.Height != picHeight) {
|
||||
_screenBitmap = new Bitmap(_baseWidth, picHeight);
|
||||
_overlayBitmap = new Bitmap(_baseWidth, picHeight);
|
||||
_displayBitmap = new Bitmap(_baseWidth, picHeight);
|
||||
}
|
||||
|
||||
GCHandle handle = GCHandle.Alloc(this._pictureData, GCHandleType.Pinned);
|
||||
try {
|
||||
Bitmap source = new Bitmap(_baseWidth, _baseHeight, _baseWidth*4, System.Drawing.Imaging.PixelFormat.Format32bppArgb, handle.AddrOfPinnedObject());
|
||||
using(Graphics g = Graphics.FromImage(_screenBitmap)) {
|
||||
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;
|
||||
g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.None;
|
||||
g.DrawImageUnscaled(source, 0, 0);
|
||||
}
|
||||
} finally {
|
||||
handle.Free();
|
||||
}
|
||||
|
||||
UpdateDisplay(true);
|
||||
}
|
||||
|
||||
private void UpdateDisplay(bool forceUpdate)
|
||||
{
|
||||
if(!_needUpdate && !forceUpdate) {
|
||||
return;
|
||||
}
|
||||
|
||||
using(Graphics g = Graphics.FromImage(_displayBitmap)) {
|
||||
g.DrawImage(_screenBitmap, 0, 0);
|
||||
g.DrawImage(_overlayBitmap, 0, 0);
|
||||
|
||||
if(_lastPos.X >= 0) {
|
||||
string location = _lastPos.X / 2 + ", " + (_lastPos.Y / 2);
|
||||
SizeF size = g.MeasureString(location, _overlayFont);
|
||||
int x = _lastPos.X + 15;
|
||||
int y = _lastPos.Y - (int)size.Height - 5;
|
||||
if(x + size.Width > _displayBitmap.Width - 5) {
|
||||
x -= (int)size.Width + 20;
|
||||
}
|
||||
if(y < size.Height + 5) {
|
||||
y = _lastPos.Y + 5;
|
||||
}
|
||||
|
||||
g.DrawOutlinedString(location, _overlayFont, Brushes.Black, Brushes.White, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
picViewer.Image = _displayBitmap;
|
||||
_needUpdate = false;
|
||||
}
|
||||
|
||||
private void UpdateOverlay(Point p)
|
||||
{
|
||||
int x = ((p.X & ~0x01) / (_zoomed ? 2 : 1)) & ~0x01;
|
||||
int y = ((p.Y & ~0x01) / (_zoomed ? 2 : 1)) & ~0x01;
|
||||
|
||||
if(_lastPos.X == x && _lastPos.Y == y) {
|
||||
//Same x,y location, no need to update
|
||||
return;
|
||||
}
|
||||
|
||||
using(Graphics g = Graphics.FromImage(_overlayBitmap)) {
|
||||
g.Clear(Color.Transparent);
|
||||
using(Pen bg = new Pen(Color.FromArgb(128, Color.LightGray))) {
|
||||
g.DrawRectangle(bg, x - 1, 0, 3, _overlayBitmap.Height);
|
||||
g.DrawRectangle(bg, 0, y - 1, _overlayBitmap.Width, 3);
|
||||
}
|
||||
}
|
||||
|
||||
_needUpdate = true;
|
||||
_lastPos = new Point(x, y);
|
||||
}
|
||||
|
||||
private void ClearOverlay()
|
||||
{
|
||||
using(Graphics g = Graphics.FromImage(_overlayBitmap)) {
|
||||
g.Clear(Color.Transparent);
|
||||
}
|
||||
UpdateDisplay(false);
|
||||
_lastPos = new Point(-1, -1);
|
||||
}
|
||||
|
||||
private void picPicture_MouseMove(object sender, MouseEventArgs e)
|
||||
{
|
||||
int cycle = ((e.X & ~0x01) / (_zoomed ? 2 : 1)) / 2;
|
||||
int scanline = ((e.Y & ~0x01) / (_zoomed ? 2 : 1)) / 2;
|
||||
|
||||
EventViewerDisplayOptions options = ConfigManager.Config.Debug.EventViewer.GetInteropOptions();
|
||||
DebugEventInfo evt = DebugApi.GetEventViewerEvent((UInt16)scanline, (UInt16)cycle, options);
|
||||
if(evt.ProgramCounter == 0xFFFFFFFF) {
|
||||
ResetTooltip();
|
||||
UpdateOverlay(e.Location);
|
||||
return;
|
||||
}
|
||||
|
||||
Dictionary<string, string> values = new Dictionary<string, string>() {
|
||||
{ "Type", ResourceHelper.GetEnumText(evt.Type) },
|
||||
{ "Scanline", evt.Scanline.ToString() },
|
||||
{ "Cycle", evt.Cycle.ToString() },
|
||||
{ "PC", "$" + evt.ProgramCounter.ToString("X6") },
|
||||
};
|
||||
|
||||
switch(evt.Type) {
|
||||
case DebugEventType.Register:
|
||||
bool isWrite = evt.Operation.Type == MemoryOperationType.Write || evt.Operation.Type == MemoryOperationType.DmaWrite;
|
||||
bool isDma = evt.Operation.Type == MemoryOperationType.DmaWrite|| evt.Operation.Type == MemoryOperationType.DmaRead;
|
||||
values["Register"] = "$" + evt.Operation.Address.ToString("X4") + (isWrite ? " (Write)" : " (Read)") + (isDma ? " (DMA)" : "");
|
||||
values["Value"] = "$" + evt.Operation.Value.ToString("X2");
|
||||
break;
|
||||
|
||||
case DebugEventType.Breakpoint:
|
||||
//TODO
|
||||
/*ReadOnlyCollection<Breakpoint> breakpoints = BreakpointManager.Breakpoints;
|
||||
if(debugEvent.BreakpointId >= 0 && debugEvent.BreakpointId < breakpoints.Count) {
|
||||
Breakpoint bp = breakpoints[debugEvent.BreakpointId];
|
||||
values["BP Type"] = bp.ToReadableType();
|
||||
values["BP Addresses"] = bp.GetAddressString(true);
|
||||
if(bp.Condition.Length > 0) {
|
||||
values["BP Condition"] = bp.Condition;
|
||||
}
|
||||
}*/
|
||||
break;
|
||||
}
|
||||
|
||||
double scale = _zoomed ? 2 : 1;
|
||||
UpdateOverlay(new Point((int)(evt.Cycle * 2 * scale), (int)(evt.Scanline * 2 * scale)));
|
||||
|
||||
ResetTooltip();
|
||||
Form parentForm = this.FindForm();
|
||||
_tooltip = new frmInfoTooltip(parentForm, values, 10);
|
||||
_tooltip.FormClosed += (s, ev) => { _tooltip = null; };
|
||||
Point location = picViewer.PointToScreen(e.Location);
|
||||
location.Offset(10, 10);
|
||||
_tooltip.SetFormLocation(location, this);
|
||||
}
|
||||
|
||||
private void ResetTooltip()
|
||||
{
|
||||
if(_tooltip != null) {
|
||||
_tooltip.Close();
|
||||
_tooltip = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void picPicture_MouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
ResetTooltip();
|
||||
ClearOverlay();
|
||||
}
|
||||
|
||||
private void tmrOverlay_Tick(object sender, EventArgs e)
|
||||
{
|
||||
UpdateDisplay(false);
|
||||
}
|
||||
|
||||
private void picPicture_DoubleClick(object sender, EventArgs e)
|
||||
{
|
||||
_zoomed = !_zoomed;
|
||||
UpdateViewerSize();
|
||||
}
|
||||
|
||||
private void UpdateViewerSize()
|
||||
{
|
||||
picViewer.Width = (_zoomed ? _baseWidth * 2 : _baseWidth) + 2;
|
||||
picViewer.Height = (_zoomed ? _baseHeight * 2 : _baseHeight) + 2;
|
||||
}
|
||||
|
||||
private void chkOption_Click(object sender, EventArgs e)
|
||||
{
|
||||
RefreshViewer();
|
||||
}
|
||||
}
|
||||
}
|
524
UI/Debugger/EventViewer/ctrlEventViewerPpuView.designer.cs
generated
Normal file
524
UI/Debugger/EventViewer/ctrlEventViewerPpuView.designer.cs
generated
Normal file
|
@ -0,0 +1,524 @@
|
|||
using Mesen.GUI.Controls;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class ctrlEventViewerPpuView
|
||||
{
|
||||
/// <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.picViewer = new Mesen.GUI.Controls.ctrlMesenPictureBox();
|
||||
this.tmrOverlay = new System.Windows.Forms.Timer(this.components);
|
||||
this.pnlPicture = new System.Windows.Forms.Panel();
|
||||
this.grpOptions = new System.Windows.Forms.GroupBox();
|
||||
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.picNmi = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowNmi = new System.Windows.Forms.CheckBox();
|
||||
this.picIrq = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowIrq = new System.Windows.Forms.CheckBox();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
this.picWramWrites = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowWorkRamRegisterWrites = new System.Windows.Forms.CheckBox();
|
||||
this.picWramReads = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowWorkRamRegisterReads = new System.Windows.Forms.CheckBox();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.picCpuWrites = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowCpuRegisterWrites = new System.Windows.Forms.CheckBox();
|
||||
this.picCpuReads = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowCpuRegisterReads = new System.Windows.Forms.CheckBox();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.picApuWrites = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowApuRegisterWrites = new System.Windows.Forms.CheckBox();
|
||||
this.picApuReads = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowApuRegisterReads = new System.Windows.Forms.CheckBox();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.picPpuWrites = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowPpuRegisterWrites = new System.Windows.Forms.CheckBox();
|
||||
this.chkShowPpuRegisterReads = new System.Windows.Forms.CheckBox();
|
||||
this.lblPpuRegisters = new System.Windows.Forms.Label();
|
||||
this.picPpuReads = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowMarkedBreakpoints = new System.Windows.Forms.CheckBox();
|
||||
this.picMarkedBreakpoints = new Mesen.GUI.Debugger.ctrlColorPicker();
|
||||
this.chkShowPreviousFrameEvents = new System.Windows.Forms.CheckBox();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picViewer)).BeginInit();
|
||||
this.pnlPicture.SuspendLayout();
|
||||
this.grpOptions.SuspendLayout();
|
||||
this.tableLayoutPanel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picNmi)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picIrq)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWramWrites)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWramReads)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCpuWrites)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCpuReads)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picApuWrites)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picApuReads)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPpuWrites)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPpuReads)).BeginInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picMarkedBreakpoints)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// picViewer
|
||||
//
|
||||
this.picViewer.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picViewer.Cursor = System.Windows.Forms.Cursors.Default;
|
||||
this.picViewer.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
|
||||
this.picViewer.Location = new System.Drawing.Point(0, 0);
|
||||
this.picViewer.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.picViewer.Name = "picViewer";
|
||||
this.picViewer.Size = new System.Drawing.Size(682, 526);
|
||||
this.picViewer.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
|
||||
this.picViewer.TabIndex = 0;
|
||||
this.picViewer.TabStop = false;
|
||||
this.picViewer.DoubleClick += new System.EventHandler(this.picPicture_DoubleClick);
|
||||
this.picViewer.MouseLeave += new System.EventHandler(this.picPicture_MouseLeave);
|
||||
this.picViewer.MouseMove += new System.Windows.Forms.MouseEventHandler(this.picPicture_MouseMove);
|
||||
//
|
||||
// tmrOverlay
|
||||
//
|
||||
this.tmrOverlay.Interval = 50;
|
||||
this.tmrOverlay.Tick += new System.EventHandler(this.tmrOverlay_Tick);
|
||||
//
|
||||
// pnlPicture
|
||||
//
|
||||
this.pnlPicture.AutoScroll = true;
|
||||
this.pnlPicture.Controls.Add(this.picViewer);
|
||||
this.pnlPicture.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.pnlPicture.Location = new System.Drawing.Point(0, 0);
|
||||
this.pnlPicture.Name = "pnlPicture";
|
||||
this.pnlPicture.Size = new System.Drawing.Size(686, 529);
|
||||
this.pnlPicture.TabIndex = 1;
|
||||
//
|
||||
// grpOptions
|
||||
//
|
||||
this.grpOptions.Controls.Add(this.tableLayoutPanel1);
|
||||
this.grpOptions.Dock = System.Windows.Forms.DockStyle.Right;
|
||||
this.grpOptions.Location = new System.Drawing.Point(686, 0);
|
||||
this.grpOptions.Name = "grpOptions";
|
||||
this.grpOptions.Size = new System.Drawing.Size(261, 529);
|
||||
this.grpOptions.TabIndex = 2;
|
||||
this.grpOptions.TabStop = false;
|
||||
this.grpOptions.Text = "Show...";
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
this.tableLayoutPanel1.ColumnCount = 6;
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 15F));
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowPreviousFrameEvents, 0, 6);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picNmi, 5, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowNmi, 4, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picIrq, 2, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowIrq, 1, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label4, 0, 4);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picWramWrites, 5, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowWorkRamRegisterWrites, 4, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picWramReads, 2, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowWorkRamRegisterReads, 1, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label3, 0, 3);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picCpuWrites, 5, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowCpuRegisterWrites, 4, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picCpuReads, 2, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowCpuRegisterReads, 1, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label2, 0, 2);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picApuWrites, 5, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowApuRegisterWrites, 4, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picApuReads, 2, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowApuRegisterReads, 1, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.label1, 0, 1);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picPpuWrites, 5, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowPpuRegisterWrites, 4, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowPpuRegisterReads, 1, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.lblPpuRegisters, 0, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picPpuReads, 2, 0);
|
||||
this.tableLayoutPanel1.Controls.Add(this.chkShowMarkedBreakpoints, 0, 5);
|
||||
this.tableLayoutPanel1.Controls.Add(this.picMarkedBreakpoints, 2, 5);
|
||||
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.tableLayoutPanel1.Location = new System.Drawing.Point(3, 16);
|
||||
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
this.tableLayoutPanel1.RowCount = 7;
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
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(255, 510);
|
||||
this.tableLayoutPanel1.TabIndex = 0;
|
||||
//
|
||||
// picNmi
|
||||
//
|
||||
this.picNmi.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picNmi.Location = new System.Drawing.Point(238, 95);
|
||||
this.picNmi.Name = "picNmi";
|
||||
this.picNmi.Size = new System.Drawing.Size(14, 14);
|
||||
this.picNmi.TabIndex = 25;
|
||||
this.picNmi.TabStop = false;
|
||||
//
|
||||
// chkShowNmi
|
||||
//
|
||||
this.chkShowNmi.AutoSize = true;
|
||||
this.chkShowNmi.Location = new System.Drawing.Point(181, 95);
|
||||
this.chkShowNmi.Name = "chkShowNmi";
|
||||
this.chkShowNmi.Size = new System.Drawing.Size(46, 17);
|
||||
this.chkShowNmi.TabIndex = 24;
|
||||
this.chkShowNmi.Text = "NMI";
|
||||
this.chkShowNmi.UseVisualStyleBackColor = true;
|
||||
this.chkShowNmi.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// picIrq
|
||||
//
|
||||
this.picIrq.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picIrq.Location = new System.Drawing.Point(146, 95);
|
||||
this.picIrq.Name = "picIrq";
|
||||
this.picIrq.Size = new System.Drawing.Size(14, 14);
|
||||
this.picIrq.TabIndex = 23;
|
||||
this.picIrq.TabStop = false;
|
||||
//
|
||||
// chkShowIrq
|
||||
//
|
||||
this.chkShowIrq.AutoSize = true;
|
||||
this.chkShowIrq.Location = new System.Drawing.Point(88, 95);
|
||||
this.chkShowIrq.Name = "chkShowIrq";
|
||||
this.chkShowIrq.Size = new System.Drawing.Size(45, 17);
|
||||
this.chkShowIrq.TabIndex = 22;
|
||||
this.chkShowIrq.Text = "IRQ";
|
||||
this.chkShowIrq.UseVisualStyleBackColor = true;
|
||||
this.chkShowIrq.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(3, 97);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(51, 13);
|
||||
this.label4.TabIndex = 21;
|
||||
this.label4.Text = "Interrupts";
|
||||
//
|
||||
// picWramWrites
|
||||
//
|
||||
this.picWramWrites.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picWramWrites.Location = new System.Drawing.Point(238, 72);
|
||||
this.picWramWrites.Name = "picWramWrites";
|
||||
this.picWramWrites.Size = new System.Drawing.Size(14, 14);
|
||||
this.picWramWrites.TabIndex = 20;
|
||||
this.picWramWrites.TabStop = false;
|
||||
//
|
||||
// chkShowWorkRamRegisterWrites
|
||||
//
|
||||
this.chkShowWorkRamRegisterWrites.AutoSize = true;
|
||||
this.chkShowWorkRamRegisterWrites.Location = new System.Drawing.Point(181, 72);
|
||||
this.chkShowWorkRamRegisterWrites.Name = "chkShowWorkRamRegisterWrites";
|
||||
this.chkShowWorkRamRegisterWrites.Size = new System.Drawing.Size(51, 17);
|
||||
this.chkShowWorkRamRegisterWrites.TabIndex = 19;
|
||||
this.chkShowWorkRamRegisterWrites.Text = "Write";
|
||||
this.chkShowWorkRamRegisterWrites.UseVisualStyleBackColor = true;
|
||||
this.chkShowWorkRamRegisterWrites.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// picWramReads
|
||||
//
|
||||
this.picWramReads.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picWramReads.Location = new System.Drawing.Point(146, 72);
|
||||
this.picWramReads.Name = "picWramReads";
|
||||
this.picWramReads.Size = new System.Drawing.Size(14, 14);
|
||||
this.picWramReads.TabIndex = 18;
|
||||
this.picWramReads.TabStop = false;
|
||||
//
|
||||
// chkShowWorkRamRegisterReads
|
||||
//
|
||||
this.chkShowWorkRamRegisterReads.AutoSize = true;
|
||||
this.chkShowWorkRamRegisterReads.Location = new System.Drawing.Point(88, 72);
|
||||
this.chkShowWorkRamRegisterReads.Name = "chkShowWorkRamRegisterReads";
|
||||
this.chkShowWorkRamRegisterReads.Size = new System.Drawing.Size(52, 17);
|
||||
this.chkShowWorkRamRegisterReads.TabIndex = 17;
|
||||
this.chkShowWorkRamRegisterReads.Text = "Read";
|
||||
this.chkShowWorkRamRegisterReads.UseVisualStyleBackColor = true;
|
||||
this.chkShowWorkRamRegisterReads.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(3, 74);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(73, 13);
|
||||
this.label3.TabIndex = 16;
|
||||
this.label3.Text = "WRAM Regs:";
|
||||
//
|
||||
// picCpuWrites
|
||||
//
|
||||
this.picCpuWrites.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picCpuWrites.Location = new System.Drawing.Point(238, 49);
|
||||
this.picCpuWrites.Name = "picCpuWrites";
|
||||
this.picCpuWrites.Size = new System.Drawing.Size(14, 14);
|
||||
this.picCpuWrites.TabIndex = 15;
|
||||
this.picCpuWrites.TabStop = false;
|
||||
//
|
||||
// chkShowCpuRegisterWrites
|
||||
//
|
||||
this.chkShowCpuRegisterWrites.AutoSize = true;
|
||||
this.chkShowCpuRegisterWrites.Location = new System.Drawing.Point(181, 49);
|
||||
this.chkShowCpuRegisterWrites.Name = "chkShowCpuRegisterWrites";
|
||||
this.chkShowCpuRegisterWrites.Size = new System.Drawing.Size(51, 17);
|
||||
this.chkShowCpuRegisterWrites.TabIndex = 14;
|
||||
this.chkShowCpuRegisterWrites.Text = "Write";
|
||||
this.chkShowCpuRegisterWrites.UseVisualStyleBackColor = true;
|
||||
this.chkShowCpuRegisterWrites.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// picCpuReads
|
||||
//
|
||||
this.picCpuReads.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picCpuReads.Location = new System.Drawing.Point(146, 49);
|
||||
this.picCpuReads.Name = "picCpuReads";
|
||||
this.picCpuReads.Size = new System.Drawing.Size(14, 14);
|
||||
this.picCpuReads.TabIndex = 13;
|
||||
this.picCpuReads.TabStop = false;
|
||||
//
|
||||
// chkShowCpuRegisterReads
|
||||
//
|
||||
this.chkShowCpuRegisterReads.AutoSize = true;
|
||||
this.chkShowCpuRegisterReads.Location = new System.Drawing.Point(88, 49);
|
||||
this.chkShowCpuRegisterReads.Name = "chkShowCpuRegisterReads";
|
||||
this.chkShowCpuRegisterReads.Size = new System.Drawing.Size(52, 17);
|
||||
this.chkShowCpuRegisterReads.TabIndex = 12;
|
||||
this.chkShowCpuRegisterReads.Text = "Read";
|
||||
this.chkShowCpuRegisterReads.UseVisualStyleBackColor = true;
|
||||
this.chkShowCpuRegisterReads.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(3, 51);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(79, 13);
|
||||
this.label2.TabIndex = 11;
|
||||
this.label2.Text = "CPU Registers:";
|
||||
//
|
||||
// picApuWrites
|
||||
//
|
||||
this.picApuWrites.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picApuWrites.Location = new System.Drawing.Point(238, 26);
|
||||
this.picApuWrites.Name = "picApuWrites";
|
||||
this.picApuWrites.Size = new System.Drawing.Size(14, 14);
|
||||
this.picApuWrites.TabIndex = 10;
|
||||
this.picApuWrites.TabStop = false;
|
||||
//
|
||||
// chkShowApuRegisterWrites
|
||||
//
|
||||
this.chkShowApuRegisterWrites.AutoSize = true;
|
||||
this.chkShowApuRegisterWrites.Location = new System.Drawing.Point(181, 26);
|
||||
this.chkShowApuRegisterWrites.Name = "chkShowApuRegisterWrites";
|
||||
this.chkShowApuRegisterWrites.Size = new System.Drawing.Size(51, 17);
|
||||
this.chkShowApuRegisterWrites.TabIndex = 9;
|
||||
this.chkShowApuRegisterWrites.Text = "Write";
|
||||
this.chkShowApuRegisterWrites.UseVisualStyleBackColor = true;
|
||||
this.chkShowApuRegisterWrites.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// picApuReads
|
||||
//
|
||||
this.picApuReads.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picApuReads.Location = new System.Drawing.Point(146, 26);
|
||||
this.picApuReads.Name = "picApuReads";
|
||||
this.picApuReads.Size = new System.Drawing.Size(14, 14);
|
||||
this.picApuReads.TabIndex = 8;
|
||||
this.picApuReads.TabStop = false;
|
||||
//
|
||||
// chkShowApuRegisterReads
|
||||
//
|
||||
this.chkShowApuRegisterReads.AutoSize = true;
|
||||
this.chkShowApuRegisterReads.Location = new System.Drawing.Point(88, 26);
|
||||
this.chkShowApuRegisterReads.Name = "chkShowApuRegisterReads";
|
||||
this.chkShowApuRegisterReads.Size = new System.Drawing.Size(52, 17);
|
||||
this.chkShowApuRegisterReads.TabIndex = 7;
|
||||
this.chkShowApuRegisterReads.Text = "Read";
|
||||
this.chkShowApuRegisterReads.UseVisualStyleBackColor = true;
|
||||
this.chkShowApuRegisterReads.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(3, 28);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(79, 13);
|
||||
this.label1.TabIndex = 6;
|
||||
this.label1.Text = "APU Registers:";
|
||||
//
|
||||
// picPpuWrites
|
||||
//
|
||||
this.picPpuWrites.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picPpuWrites.Location = new System.Drawing.Point(238, 3);
|
||||
this.picPpuWrites.Name = "picPpuWrites";
|
||||
this.picPpuWrites.Size = new System.Drawing.Size(14, 14);
|
||||
this.picPpuWrites.TabIndex = 5;
|
||||
this.picPpuWrites.TabStop = false;
|
||||
//
|
||||
// chkShowPpuRegisterWrites
|
||||
//
|
||||
this.chkShowPpuRegisterWrites.AutoSize = true;
|
||||
this.chkShowPpuRegisterWrites.Location = new System.Drawing.Point(181, 3);
|
||||
this.chkShowPpuRegisterWrites.Name = "chkShowPpuRegisterWrites";
|
||||
this.chkShowPpuRegisterWrites.Size = new System.Drawing.Size(51, 17);
|
||||
this.chkShowPpuRegisterWrites.TabIndex = 2;
|
||||
this.chkShowPpuRegisterWrites.Text = "Write";
|
||||
this.chkShowPpuRegisterWrites.UseVisualStyleBackColor = true;
|
||||
this.chkShowPpuRegisterWrites.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// chkShowPpuRegisterReads
|
||||
//
|
||||
this.chkShowPpuRegisterReads.AutoSize = true;
|
||||
this.chkShowPpuRegisterReads.Location = new System.Drawing.Point(88, 3);
|
||||
this.chkShowPpuRegisterReads.Name = "chkShowPpuRegisterReads";
|
||||
this.chkShowPpuRegisterReads.Size = new System.Drawing.Size(52, 17);
|
||||
this.chkShowPpuRegisterReads.TabIndex = 0;
|
||||
this.chkShowPpuRegisterReads.Text = "Read";
|
||||
this.chkShowPpuRegisterReads.UseVisualStyleBackColor = true;
|
||||
this.chkShowPpuRegisterReads.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// lblPpuRegisters
|
||||
//
|
||||
this.lblPpuRegisters.Anchor = System.Windows.Forms.AnchorStyles.Left;
|
||||
this.lblPpuRegisters.AutoSize = true;
|
||||
this.lblPpuRegisters.Location = new System.Drawing.Point(3, 5);
|
||||
this.lblPpuRegisters.Name = "lblPpuRegisters";
|
||||
this.lblPpuRegisters.Size = new System.Drawing.Size(79, 13);
|
||||
this.lblPpuRegisters.TabIndex = 3;
|
||||
this.lblPpuRegisters.Text = "PPU Registers:";
|
||||
//
|
||||
// picPpuReads
|
||||
//
|
||||
this.picPpuReads.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picPpuReads.Location = new System.Drawing.Point(146, 3);
|
||||
this.picPpuReads.Name = "picPpuReads";
|
||||
this.picPpuReads.Size = new System.Drawing.Size(14, 14);
|
||||
this.picPpuReads.TabIndex = 4;
|
||||
this.picPpuReads.TabStop = false;
|
||||
//
|
||||
// chkShowMarkedBreakpoints
|
||||
//
|
||||
this.chkShowMarkedBreakpoints.AutoSize = true;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.chkShowMarkedBreakpoints, 2);
|
||||
this.chkShowMarkedBreakpoints.Location = new System.Drawing.Point(3, 118);
|
||||
this.chkShowMarkedBreakpoints.Name = "chkShowMarkedBreakpoints";
|
||||
this.chkShowMarkedBreakpoints.Size = new System.Drawing.Size(121, 17);
|
||||
this.chkShowMarkedBreakpoints.TabIndex = 26;
|
||||
this.chkShowMarkedBreakpoints.Text = "Marked Breakpoints";
|
||||
this.chkShowMarkedBreakpoints.UseVisualStyleBackColor = true;
|
||||
this.chkShowMarkedBreakpoints.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// picMarkedBreakpoints
|
||||
//
|
||||
this.picMarkedBreakpoints.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.picMarkedBreakpoints.Location = new System.Drawing.Point(146, 118);
|
||||
this.picMarkedBreakpoints.Name = "picMarkedBreakpoints";
|
||||
this.picMarkedBreakpoints.Size = new System.Drawing.Size(14, 14);
|
||||
this.picMarkedBreakpoints.TabIndex = 27;
|
||||
this.picMarkedBreakpoints.TabStop = false;
|
||||
//
|
||||
// chkShowPreviousFrameEvents
|
||||
//
|
||||
this.chkShowPreviousFrameEvents.AutoSize = true;
|
||||
this.tableLayoutPanel1.SetColumnSpan(this.chkShowPreviousFrameEvents, 6);
|
||||
this.chkShowPreviousFrameEvents.Location = new System.Drawing.Point(3, 148);
|
||||
this.chkShowPreviousFrameEvents.Margin = new System.Windows.Forms.Padding(3, 10, 3, 3);
|
||||
this.chkShowPreviousFrameEvents.Name = "chkShowPreviousFrameEvents";
|
||||
this.chkShowPreviousFrameEvents.Size = new System.Drawing.Size(167, 17);
|
||||
this.chkShowPreviousFrameEvents.TabIndex = 28;
|
||||
this.chkShowPreviousFrameEvents.Text = "Show previous frame\'s events";
|
||||
this.chkShowPreviousFrameEvents.UseVisualStyleBackColor = true;
|
||||
this.chkShowPreviousFrameEvents.Click += new System.EventHandler(this.chkOption_Click);
|
||||
//
|
||||
// ctrlEventViewerPpuView
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.pnlPicture);
|
||||
this.Controls.Add(this.grpOptions);
|
||||
this.Name = "ctrlEventViewerPpuView";
|
||||
this.Size = new System.Drawing.Size(947, 529);
|
||||
((System.ComponentModel.ISupportInitialize)(this.picViewer)).EndInit();
|
||||
this.pnlPicture.ResumeLayout(false);
|
||||
this.grpOptions.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.ResumeLayout(false);
|
||||
this.tableLayoutPanel1.PerformLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picNmi)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picIrq)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWramWrites)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picWramReads)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCpuWrites)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picCpuReads)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picApuWrites)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picApuReads)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPpuWrites)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picPpuReads)).EndInit();
|
||||
((System.ComponentModel.ISupportInitialize)(this.picMarkedBreakpoints)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private ctrlMesenPictureBox picViewer;
|
||||
private System.Windows.Forms.Timer tmrOverlay;
|
||||
private System.Windows.Forms.Panel pnlPicture;
|
||||
private System.Windows.Forms.GroupBox grpOptions;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
private ctrlColorPicker picNmi;
|
||||
private System.Windows.Forms.CheckBox chkShowNmi;
|
||||
private ctrlColorPicker picIrq;
|
||||
private System.Windows.Forms.CheckBox chkShowIrq;
|
||||
private System.Windows.Forms.Label label4;
|
||||
private ctrlColorPicker picWramWrites;
|
||||
private System.Windows.Forms.CheckBox chkShowWorkRamRegisterWrites;
|
||||
private ctrlColorPicker picWramReads;
|
||||
private System.Windows.Forms.CheckBox chkShowWorkRamRegisterReads;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private ctrlColorPicker picCpuWrites;
|
||||
private System.Windows.Forms.CheckBox chkShowCpuRegisterWrites;
|
||||
private ctrlColorPicker picCpuReads;
|
||||
private System.Windows.Forms.CheckBox chkShowCpuRegisterReads;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.CheckBox chkShowApuRegisterWrites;
|
||||
private ctrlColorPicker picApuReads;
|
||||
private System.Windows.Forms.CheckBox chkShowApuRegisterReads;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private ctrlColorPicker picPpuWrites;
|
||||
private System.Windows.Forms.CheckBox chkShowPpuRegisterWrites;
|
||||
private System.Windows.Forms.CheckBox chkShowPpuRegisterReads;
|
||||
private System.Windows.Forms.Label lblPpuRegisters;
|
||||
private ctrlColorPicker picPpuReads;
|
||||
private ctrlColorPicker picApuWrites;
|
||||
private System.Windows.Forms.CheckBox chkShowMarkedBreakpoints;
|
||||
private ctrlColorPicker picMarkedBreakpoints;
|
||||
private System.Windows.Forms.CheckBox chkShowPreviousFrameEvents;
|
||||
}
|
||||
}
|
123
UI/Debugger/EventViewer/ctrlEventViewerPpuView.resx
Normal file
123
UI/Debugger/EventViewer/ctrlEventViewerPpuView.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="tmrOverlay.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
57
UI/Debugger/EventViewer/frmEventViewer.Designer.cs
generated
Normal file
57
UI/Debugger/EventViewer/frmEventViewer.Designer.cs
generated
Normal file
|
@ -0,0 +1,57 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class frmEventViewer
|
||||
{
|
||||
/// <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.ctrlPpuView = new Mesen.GUI.Debugger.ctrlEventViewerPpuView();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// ctrlPpuView
|
||||
//
|
||||
this.ctrlPpuView.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ctrlPpuView.Location = new System.Drawing.Point(0, 0);
|
||||
this.ctrlPpuView.Name = "ctrlPpuView";
|
||||
this.ctrlPpuView.Size = new System.Drawing.Size(945, 531);
|
||||
this.ctrlPpuView.TabIndex = 0;
|
||||
//
|
||||
// frmEventViewer
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(945, 531);
|
||||
this.Controls.Add(this.ctrlPpuView);
|
||||
this.Name = "frmEventViewer";
|
||||
this.Text = "Event Viewer";
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private ctrlEventViewerPpuView ctrlPpuView;
|
||||
}
|
||||
}
|
52
UI/Debugger/EventViewer/frmEventViewer.cs
Normal file
52
UI/Debugger/EventViewer/frmEventViewer.cs
Normal file
|
@ -0,0 +1,52 @@
|
|||
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 frmEventViewer : BaseForm
|
||||
{
|
||||
private NotificationListener _notifListener;
|
||||
|
||||
public frmEventViewer()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
|
||||
if(!this.DesignMode) {
|
||||
_notifListener = new NotificationListener();
|
||||
_notifListener.OnNotification += OnNotificationReceived;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnFormClosed(FormClosedEventArgs e)
|
||||
{
|
||||
base.OnFormClosed(e);
|
||||
_notifListener?.Dispose();
|
||||
}
|
||||
|
||||
private void OnNotificationReceived(NotificationEventArgs e)
|
||||
{
|
||||
switch(e.NotificationType) {
|
||||
case ConsoleNotificationType.CodeBreak:
|
||||
case ConsoleNotificationType.PpuFrameDone:
|
||||
ctrlPpuView.RefreshData();
|
||||
this.BeginInvoke((Action)(() => {
|
||||
ctrlPpuView.RefreshViewer();
|
||||
}));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
123
UI/Debugger/EventViewer/frmEventViewer.resx
Normal file
123
UI/Debugger/EventViewer/frmEventViewer.resx
Normal file
|
@ -0,0 +1,123 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="toolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
</root>
|
20
UI/Debugger/GraphicsExtensions.cs
Normal file
20
UI/Debugger/GraphicsExtensions.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public static class GraphicsExtensions
|
||||
{
|
||||
public static void DrawOutlinedString(this Graphics g, string text, Font font, Brush foreColor, Brush backColor, int x, int y)
|
||||
{
|
||||
for(int i = -1; i <= 1; i++) {
|
||||
for(int j = -1; j <= 1; j++) {
|
||||
g.DrawString(text, font, backColor, x+j, y+i);
|
||||
}
|
||||
}
|
||||
g.DrawString(text, font, foreColor, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
60
UI/Debugger/Tooltips/TooltipForm.cs
Normal file
60
UI/Debugger/Tooltips/TooltipForm.cs
Normal file
|
@ -0,0 +1,60 @@
|
|||
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 class TooltipForm : BaseForm
|
||||
{
|
||||
protected Form _parentForm;
|
||||
private Point _requestedLocation;
|
||||
private bool _parentContainedFocus = false;
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
base.OnLoad(e);
|
||||
if(!DesignMode) {
|
||||
UpdateLocation();
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateLocation()
|
||||
{
|
||||
Point p = _requestedLocation;
|
||||
if(p.Y + this.Height > _parentForm.ClientSize.Height) {
|
||||
this.Location = new Point(p.X, _parentForm.ClientSize.Height - this.Height);
|
||||
} else {
|
||||
this.Location = p;
|
||||
}
|
||||
}
|
||||
|
||||
public bool NeedRestoreFocus
|
||||
{
|
||||
get { return _parentContainedFocus; }
|
||||
}
|
||||
|
||||
public void SetFormLocation(Point screenLocation, Control focusTarget)
|
||||
{
|
||||
_requestedLocation = _parentForm.PointToClient(screenLocation);
|
||||
|
||||
if(!this.Visible) {
|
||||
this._parentContainedFocus = focusTarget.ContainsFocus;
|
||||
UpdateLocation();
|
||||
this.Show();
|
||||
} else {
|
||||
UpdateLocation();
|
||||
}
|
||||
|
||||
if(Program.IsMono) {
|
||||
focusTarget.Focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
91
UI/Debugger/Tooltips/frmInfoTooltip.cs
Normal file
91
UI/Debugger/Tooltips/frmInfoTooltip.cs
Normal file
|
@ -0,0 +1,91 @@
|
|||
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.Controls;
|
||||
using Mesen.GUI.Config;
|
||||
using Mesen.GUI.Debugger.Controls;
|
||||
|
||||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
public partial class frmInfoTooltip : TooltipForm
|
||||
{
|
||||
private Dictionary<string, string> _values;
|
||||
private int _showOnLeftOffset;
|
||||
|
||||
protected override bool ShowWithoutActivation
|
||||
{
|
||||
get { return true; }
|
||||
}
|
||||
|
||||
public frmInfoTooltip(Form parent, Dictionary<string, string> values, int showOnLeftOffset = 0)
|
||||
{
|
||||
_showOnLeftOffset = showOnLeftOffset;
|
||||
_parentForm = parent;
|
||||
_values = values;
|
||||
InitializeComponent();
|
||||
this.TopLevel = false;
|
||||
this.Parent = _parentForm;
|
||||
_parentForm.Controls.Add(this);
|
||||
}
|
||||
|
||||
protected override void OnLoad(EventArgs e)
|
||||
{
|
||||
tlpMain.SuspendLayout();
|
||||
|
||||
TableLayoutPanel tlpLabels = new TableLayoutPanel();
|
||||
tlpLabels.SuspendLayout();
|
||||
tlpLabels.AutoSize = true;
|
||||
tlpMain.Controls.Add(tlpLabels, 0, 0);
|
||||
int i = 0;
|
||||
int maxLabelWidth = (_parentForm.ClientSize.Width - this.Location.X - 150);
|
||||
foreach(KeyValuePair<string, string> kvp in _values) {
|
||||
tlpLabels.RowStyles.Add(new RowStyle());
|
||||
Label lbl = new Label();
|
||||
lbl.Margin = new Padding(2, 3, 2, 2);
|
||||
lbl.Text = kvp.Key + ":";
|
||||
lbl.Font = new Font(lbl.Font, FontStyle.Bold);
|
||||
lbl.AutoSize = true;
|
||||
tlpLabels.Controls.Add(lbl, 0, i);
|
||||
|
||||
lbl = new ctrlAutoGrowLabel();
|
||||
lbl.Font = new Font(BaseControl.MonospaceFontFamily, 10);
|
||||
lbl.Margin = new Padding(2);
|
||||
lbl.Text = kvp.Value;
|
||||
if(_showOnLeftOffset == 0) {
|
||||
lbl.Size = new Size(maxLabelWidth, 10);
|
||||
} else {
|
||||
lbl.Size = new Size(500, 10);
|
||||
}
|
||||
tlpLabels.Controls.Add(lbl, 1, i);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
tlpLabels.ResumeLayout();
|
||||
tlpMain.ResumeLayout();
|
||||
|
||||
base.OnLoad(e);
|
||||
|
||||
this.Width = this.tlpMain.Width;
|
||||
if(this.Location.X + this.Width > _parentForm.ClientSize.Width) {
|
||||
if(_showOnLeftOffset > 0) {
|
||||
this.Left -= this.Width + _showOnLeftOffset * 2;
|
||||
} else {
|
||||
int maxWidth = Math.Max(10, _parentForm.ClientSize.Width - this.Location.X - 10);
|
||||
this.tlpMain.MaximumSize = new Size(maxWidth, _parentForm.ClientSize.Height - 10);
|
||||
this.MaximumSize = new Size(maxWidth, _parentForm.ClientSize.Height - 10);
|
||||
}
|
||||
}
|
||||
this.Height = this.tlpMain.Height;
|
||||
this.BringToFront();
|
||||
|
||||
panel.BackColor = SystemColors.Info;
|
||||
}
|
||||
}
|
||||
}
|
93
UI/Debugger/Tooltips/frmInfoTooltip.designer.cs
generated
Normal file
93
UI/Debugger/Tooltips/frmInfoTooltip.designer.cs
generated
Normal file
|
@ -0,0 +1,93 @@
|
|||
namespace Mesen.GUI.Debugger
|
||||
{
|
||||
partial class frmInfoTooltip
|
||||
{
|
||||
/// <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.panel = new System.Windows.Forms.Panel();
|
||||
this.tlpMain = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.panel.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// panel
|
||||
//
|
||||
this.panel.AutoSize = true;
|
||||
this.panel.BackColor = System.Drawing.SystemColors.Info;
|
||||
this.panel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
|
||||
this.panel.Controls.Add(this.tlpMain);
|
||||
this.panel.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.panel.Location = new System.Drawing.Point(0, 0);
|
||||
this.panel.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
|
||||
this.panel.Name = "panel";
|
||||
this.panel.Size = new System.Drawing.Size(10, 10);
|
||||
this.panel.TabIndex = 0;
|
||||
//
|
||||
// tlpMain
|
||||
//
|
||||
this.tlpMain.AutoSize = true;
|
||||
this.tlpMain.ColumnCount = 1;
|
||||
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
this.tlpMain.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
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, 0, 0, 0);
|
||||
this.tlpMain.Name = "tlpMain";
|
||||
this.tlpMain.RowCount = 1;
|
||||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tlpMain.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
this.tlpMain.Size = new System.Drawing.Size(8, 8);
|
||||
this.tlpMain.TabIndex = 0;
|
||||
//
|
||||
// frmCodeTooltip
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoSize = true;
|
||||
this.ClientSize = new System.Drawing.Size(10, 10);
|
||||
this.ControlBox = false;
|
||||
this.Controls.Add(this.panel);
|
||||
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "frmCodeTooltip";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;
|
||||
this.Text = "frmCodeTooltip";
|
||||
this.panel.ResumeLayout(false);
|
||||
this.panel.PerformLayout();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.Panel panel;
|
||||
private System.Windows.Forms.TableLayoutPanel tlpMain;
|
||||
}
|
||||
}
|
120
UI/Debugger/Tooltips/frmInfoTooltip.resx
Normal file
120
UI/Debugger/Tooltips/frmInfoTooltip.resx
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
|
@ -9,6 +9,7 @@ using System.Threading.Tasks;
|
|||
using System.Windows.Forms;
|
||||
using Mesen.GUI.Controls;
|
||||
using Mesen.GUI.Forms.Config;
|
||||
using Mesen.GUI.Utilities;
|
||||
|
||||
namespace Mesen.GUI.Forms
|
||||
{
|
||||
|
@ -85,6 +86,8 @@ namespace Mesen.GUI.Forms
|
|||
((ctrlRiskyOption)kvp.Value).Checked = Convert.ToBoolean(value);
|
||||
} else if(kvp.Value is RadioButton) {
|
||||
((RadioButton)kvp.Value).Checked = (bool)value;
|
||||
} else if(kvp.Value is PictureBox) {
|
||||
((PictureBox)kvp.Value).BackColor = (XmlColor)value;
|
||||
} else if(kvp.Value is Panel) {
|
||||
RadioButton radio = ((Panel)kvp.Value).Controls.OfType<RadioButton>().FirstOrDefault(r => r.Tag.Equals(value));
|
||||
if(radio != null) {
|
||||
|
@ -222,6 +225,8 @@ namespace Mesen.GUI.Forms
|
|||
}
|
||||
} else if(kvp.Value is RadioButton) {
|
||||
field.SetValue(Entity, ((RadioButton)kvp.Value).Checked);
|
||||
} else if(kvp.Value is PictureBox) {
|
||||
field.SetValue(Entity, (XmlColor)((PictureBox)kvp.Value).BackColor);
|
||||
} else if(kvp.Value is Panel) {
|
||||
field.SetValue(Entity, ((Panel)kvp.Value).Controls.OfType<RadioButton>().FirstOrDefault(r => r.Checked).Tag);
|
||||
} else if(kvp.Value is ctrlTrackbar) {
|
||||
|
|
13
UI/Forms/frmMain.Designer.cs
generated
13
UI/Forms/frmMain.Designer.cs
generated
|
@ -40,6 +40,7 @@
|
|||
this.mnuMemoryTools = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuTraceLogger = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuTilemapViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuEventViewer = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.mnuMain.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
|
@ -88,7 +89,8 @@
|
|||
this.mnuDebugger,
|
||||
this.mnuMemoryTools,
|
||||
this.mnuTraceLogger,
|
||||
this.mnuTilemapViewer});
|
||||
this.mnuTilemapViewer,
|
||||
this.mnuEventViewer});
|
||||
this.debugToolStripMenuItem.Name = "debugToolStripMenuItem";
|
||||
this.debugToolStripMenuItem.Size = new System.Drawing.Size(54, 20);
|
||||
this.debugToolStripMenuItem.Text = "Debug";
|
||||
|
@ -154,6 +156,14 @@
|
|||
this.mnuTilemapViewer.Text = "Tilemap Viewer";
|
||||
this.mnuTilemapViewer.Click += new System.EventHandler(this.mnuTilemapViewer_Click);
|
||||
//
|
||||
// mnuEventViewer
|
||||
//
|
||||
this.mnuEventViewer.Image = global::Mesen.GUI.Properties.Resources.NesEventViewer;
|
||||
this.mnuEventViewer.Name = "mnuEventViewer";
|
||||
this.mnuEventViewer.Size = new System.Drawing.Size(163, 22);
|
||||
this.mnuEventViewer.Text = "Event Viewer";
|
||||
this.mnuEventViewer.Click += new System.EventHandler(this.mnuEventViewer_Click);
|
||||
//
|
||||
// frmMain
|
||||
//
|
||||
this.AllowDrop = true;
|
||||
|
@ -187,5 +197,6 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem mnuRun100Instructions;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuMemoryTools;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuTilemapViewer;
|
||||
private System.Windows.Forms.ToolStripMenuItem mnuEventViewer;
|
||||
}
|
||||
}
|
|
@ -78,6 +78,11 @@ namespace Mesen.GUI.Forms
|
|||
DebugWindowManager.OpenDebugWindow(DebugWindow.TilemapViewer);
|
||||
}
|
||||
|
||||
private void mnuEventViewer_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugWindowManager.OpenDebugWindow(DebugWindow.EventViewer);
|
||||
}
|
||||
|
||||
private void mnuStep_Click(object sender, EventArgs e)
|
||||
{
|
||||
DebugApi.Step(1);
|
||||
|
|
|
@ -80,6 +80,33 @@ namespace Mesen.GUI
|
|||
}
|
||||
|
||||
[DllImport(DllPath)] public static extern void SetViewerUpdateTiming(Int32 viewerId, Int32 scanline, Int32 cycle);
|
||||
|
||||
[DllImport(DllPath)] private static extern UInt32 GetDebugEventCount([MarshalAs(UnmanagedType.I1)]bool getPreviousFrameData);
|
||||
[DllImport(DllPath, EntryPoint = "GetDebugEvents")] private static extern void GetDebugEventsWrapper([In, Out]DebugEventInfo[] eventArray, ref UInt32 maxEventCount, [MarshalAs(UnmanagedType.I1)]bool getPreviousFrameData);
|
||||
public static DebugEventInfo[] GetDebugEvents(bool getPreviousFrameData)
|
||||
{
|
||||
UInt32 maxEventCount = GetDebugEventCount(getPreviousFrameData);
|
||||
DebugEventInfo[] debugEvents = new DebugEventInfo[maxEventCount];
|
||||
|
||||
DebugApi.GetDebugEventsWrapper(debugEvents, ref maxEventCount, getPreviousFrameData);
|
||||
if(maxEventCount < debugEvents.Length) {
|
||||
//Remove the excess from the array if needed
|
||||
Array.Resize(ref debugEvents, (int)maxEventCount);
|
||||
}
|
||||
|
||||
return debugEvents;
|
||||
}
|
||||
|
||||
[DllImport(DllPath)] public static extern DebugEventInfo GetEventViewerEvent(UInt16 scanline, UInt16 cycle, EventViewerDisplayOptions options);
|
||||
[DllImport(DllPath)] public static extern void TakeEventSnapshot(EventViewerDisplayOptions options);
|
||||
|
||||
[DllImport(DllPath, EntryPoint = "GetEventViewerOutput")] private static extern void GetEventViewerOutputWrapper([In, Out]byte[] buffer, EventViewerDisplayOptions options);
|
||||
public static byte[] GetEventViewerOutput(EventViewerDisplayOptions options)
|
||||
{
|
||||
byte[] buffer = new byte[340*2 * 262*2 * 4];
|
||||
DebugApi.GetEventViewerOutputWrapper(buffer, options);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
public enum SnesMemoryType
|
||||
|
@ -150,6 +177,74 @@ namespace Mesen.GUI
|
|||
public PpuState Ppu;
|
||||
}
|
||||
|
||||
public enum MemoryOperationType
|
||||
{
|
||||
Read = 0,
|
||||
Write = 1,
|
||||
ExecOpCode = 2,
|
||||
ExecOperand = 3,
|
||||
DmaRead = 4,
|
||||
DmaWrite = 5
|
||||
}
|
||||
|
||||
public struct MemoryOperationInfo
|
||||
{
|
||||
public UInt32 Address;
|
||||
public Int32 Value;
|
||||
public MemoryOperationType Type;
|
||||
}
|
||||
|
||||
public enum DebugEventType
|
||||
{
|
||||
Register,
|
||||
Nmi,
|
||||
Irq,
|
||||
Breakpoint
|
||||
}
|
||||
|
||||
public struct DebugEventInfo
|
||||
{
|
||||
//public DmaChannelConfig DmaChannelInfo;
|
||||
public MemoryOperationInfo Operation;
|
||||
public DebugEventType Type;
|
||||
public UInt32 ProgramCounter;
|
||||
public UInt16 Scanline;
|
||||
public UInt16 Cycle;
|
||||
public UInt16 BreakpointId;
|
||||
//public byte DmaChannel;
|
||||
};
|
||||
|
||||
public struct EventViewerDisplayOptions
|
||||
{
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowPpuRegisterWrites;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowPpuRegisterReads;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowCpuRegisterWrites;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowCpuRegisterReads;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowApuRegisterWrites;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowApuRegisterReads;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowWorkRamRegisterWrites;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowWorkRamRegisterReads;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowNmi;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowIrq;
|
||||
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowMarkedBreakpoints;
|
||||
[MarshalAs(UnmanagedType.I1)] public bool ShowPreviousFrameEvents;
|
||||
|
||||
public UInt32 IrqColor;
|
||||
public UInt32 NmiColor;
|
||||
public UInt32 BreakpointColor;
|
||||
public UInt32 PpuRegisterReadColor;
|
||||
public UInt32 PpuRegisterWriteColor;
|
||||
public UInt32 ApuRegisterReadColor;
|
||||
public UInt32 ApuRegisterWriteColor;
|
||||
public UInt32 CpuRegisterReadColor;
|
||||
public UInt32 CpuRegisterWriteColor;
|
||||
public UInt32 WorkRamRegisterReadColor;
|
||||
public UInt32 WorkRamRegisterWriteColor;
|
||||
}
|
||||
|
||||
public struct GetTilemapOptions
|
||||
{
|
||||
public byte BgMode;
|
||||
|
|
35
UI/UI.csproj
35
UI/UI.csproj
|
@ -228,6 +228,7 @@
|
|||
</Compile>
|
||||
<Compile Include="Debugger\Breakpoints\InteropBreakpoint.cs" />
|
||||
<Compile Include="Debugger\Config\DebuggerShortcutsConfig.cs" />
|
||||
<Compile Include="Debugger\Config\EventViewerInfo.cs" />
|
||||
<Compile Include="Debugger\Config\HexEditorInfo.cs" />
|
||||
<Compile Include="Debugger\Config\TraceLoggerInfo.cs" />
|
||||
<Compile Include="Debugger\Config\DebugInfo.cs" />
|
||||
|
@ -298,6 +299,9 @@
|
|||
<Compile Include="Debugger\Controls\ComboBoxWithSeparator.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlColorPicker.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Controls\ctrlDbgShortcuts.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -322,6 +326,18 @@
|
|||
<Compile Include="Debugger\Controls\ctrlWatch.designer.cs">
|
||||
<DependentUpon>ctrlWatch.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\EventViewer\ctrlEventViewerPpuView.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\EventViewer\ctrlEventViewerPpuView.designer.cs">
|
||||
<DependentUpon>ctrlEventViewerPpuView.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\EventViewer\frmEventViewer.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\EventViewer\frmEventViewer.Designer.cs">
|
||||
<DependentUpon>frmEventViewer.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\frmDbgPreferences.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
|
@ -374,6 +390,7 @@
|
|||
<Compile Include="Debugger\frmMemoryTools.designer.cs">
|
||||
<DependentUpon>frmMemoryTools.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\GraphicsExtensions.cs" />
|
||||
<Compile Include="Debugger\PpuViewer\ctrlScanlineCycleSelect.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
|
@ -417,6 +434,15 @@
|
|||
<Compile Include="Debugger\HexBox\Util.cs" />
|
||||
<Compile Include="Debugger\TblLoader.cs" />
|
||||
<Compile Include="Debugger\DebugWindowManager.cs" />
|
||||
<Compile Include="Debugger\Tooltips\frmInfoTooltip.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Tooltips\frmInfoTooltip.designer.cs">
|
||||
<DependentUpon>frmInfoTooltip.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\Tooltips\TooltipForm.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Debugger\WatchManager.cs" />
|
||||
<Compile Include="Forms\BaseConfigForm.Designer.cs">
|
||||
<DependentUpon>BaseConfigForm.cs</DependentUpon>
|
||||
|
@ -499,6 +525,12 @@
|
|||
<EmbeddedResource Include="Debugger\Controls\ctrlWatch.resx">
|
||||
<DependentUpon>ctrlWatch.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\EventViewer\ctrlEventViewerPpuView.resx">
|
||||
<DependentUpon>ctrlEventViewerPpuView.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\EventViewer\frmEventViewer.resx">
|
||||
<DependentUpon>frmEventViewer.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\frmDbgPreferences.resx">
|
||||
<DependentUpon>frmDbgPreferences.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
@ -532,6 +564,9 @@
|
|||
<EmbeddedResource Include="Debugger\HexBox\HexBox.resx">
|
||||
<DependentUpon>HexBox.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Debugger\Tooltips\frmInfoTooltip.resx">
|
||||
<DependentUpon>frmInfoTooltip.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Forms\BaseConfigForm.resx">
|
||||
<DependentUpon>BaseConfigForm.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
Loading…
Add table
Reference in a new issue