GUI Updates

Add DisplaySettings, replace ImGui style editor
Update Debugger interface with memory viewer
Decompose SNES initialization routines
Update DungeonObjectRenderer plan
Add DrawObjectRenderer UI mockup fofr DungeonEditor
This commit is contained in:
scawful
2023-11-21 11:07:04 -05:00
parent f7224c3716
commit 59e7dcc7f0
14 changed files with 712 additions and 94 deletions

View File

@@ -1,12 +1,14 @@
#include "app/emu/emulator.h"
#include <imgui/imgui.h>
#include <imgui_memory_editor.h>
#include <cstdint>
#include <vector>
#include "app/core/constants.h"
#include "app/emu/snes.h"
#include "app/gui/icons.h"
#include "app/rom.h"
namespace yaze {
@@ -20,6 +22,65 @@ bool ShouldDisplay(const InstructionEntry& entry, const char* filter,
// filter and showAll flag
return true;
}
void DrawMemoryWindow(Memory* memory) {
const float TEXT_BASE_HEIGHT = ImGui::GetTextLineHeightWithSpacing();
static ImGuiTableFlags flags =
ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable |
ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg |
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX;
if (auto outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 5.5f);
ImGui::BeginTable("table1", 4, flags, outer_size)) {
// Table headers
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("Memory Area");
ImGui::TableNextColumn();
ImGui::Text("Start Address");
ImGui::TableNextColumn();
ImGui::Text("Size");
ImGui::TableNextColumn();
ImGui::Text("Mapping");
// Retrieve memory information from MemoryImpl
MemoryImpl* memoryImpl = dynamic_cast<MemoryImpl*>(memory);
if (memoryImpl) {
// Display memory areas
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("ROM");
ImGui::TableNextColumn();
ImGui::Text("0x000000");
ImGui::TableNextColumn();
ImGui::Text("%d MB", memoryImpl->rom_.size());
ImGui::TableNextColumn();
ImGui::Text("LoROM");
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("RAM");
ImGui::TableNextColumn();
ImGui::Text("0x7E0000");
ImGui::TableNextColumn();
ImGui::Text("%d KB", memoryImpl->ram_.size());
ImGui::TableNextColumn();
ImGui::Text("LoROM");
}
ImGui::EndTable();
if (ImGui::Button("Open Memory Viewer", ImVec2(200, 50))) {
ImGui::OpenPopup("Memory Viewer");
}
if (ImGui::BeginPopupModal("Memory Viewer", nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
static MemoryEditor mem_edit;
mem_edit.DrawContents((void*)memoryImpl->data(), memoryImpl->size());
ImGui::EndPopup();
}
}
}
} // namespace
using ImGui::NextColumn;
@@ -30,7 +91,12 @@ using ImGui::Text;
void Emulator::Run() {
if (!snes_.running() && loading_) {
if (rom()->isLoaded()) {
if (loading_ && !memory_setup_) {
snes_.SetupMemory(*rom());
memory_setup_ = true;
}
if (rom()->isLoaded() && power_) {
snes_.Init(*rom());
running_ = true;
}
@@ -38,6 +104,13 @@ void Emulator::Run() {
RenderNavBar();
ImGui::Button(ICON_MD_ARROW_FORWARD_IOS);
ImGui::SameLine();
ImGui::Button(ICON_MD_DOUBLE_ARROW);
ImGui::SameLine();
ImGui::Button(ICON_MD_SUBDIRECTORY_ARROW_RIGHT);
ImGui::SameLine();
if (running_) {
HandleEvents();
UpdateEmulator();
@@ -67,7 +140,9 @@ void Emulator::RenderNavBar() {
if (ImGui::BeginMenu("Game")) {
MENU_ITEM("Load ROM") { loading_ = true; }
MENU_ITEM("Power On") { power_ = true; }
MENU_ITEM("Power Off") {
power_ = false;
running_ = false;
loading_ = false;
debugger_ = false;
@@ -133,6 +208,7 @@ void Emulator::RenderDebugger() {
TableNextColumn();
RenderBreakpointList();
DrawMemoryWindow(snes_.Memory());
ImGui::EndTable();
}
};

View File

@@ -39,9 +39,11 @@ class Emulator : public SharedROM {
SNES snes_;
bool power_ = false;
bool loading_ = false;
bool running_ = false;
bool debugger_ = true;
bool loading_ = false;
bool memory_setup_ = false;
bool integrated_debugger_mode_ = true;
bool separate_debugger_mode_ = false;
};

View File

@@ -3,6 +3,7 @@
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
#include "app/emu/debug/log.h"
@@ -135,9 +136,21 @@ class Memory {
virtual uint8_t at(int i) const = 0;
};
enum class MemoryMapping { SNES_LOROM = 0, PC_ADDRESS = 1 };
class MemoryImpl : public Memory, public Loggable {
public:
void Initialize(const std::vector<uint8_t>& romData) {
void Initialize(const std::vector<uint8_t>& romData,
MemoryMapping mapping = MemoryMapping::SNES_LOROM) {
mapping_ = mapping;
if (mapping == MemoryMapping::PC_ADDRESS) {
memory_.resize(romData.size());
std::copy(romData.begin(), romData.end(), memory_.begin());
return;
}
memory_.reserve(0x1000000); // 16 MB
const size_t ROM_CHUNK_SIZE = 0x8000; // 32 KB
const size_t SRAM_SIZE = 0x10000; // 64 KB
const size_t SYSTEM_RAM_SIZE = 0x20000; // 128 KB
@@ -322,6 +335,7 @@ class MemoryImpl : public Memory, public Loggable {
auto size() const { return memory_.size(); }
auto begin() const { return memory_.begin(); }
auto end() const { return memory_.end(); }
auto data() const { return memory_.data(); }
// Define memory regions
std::vector<uint8_t> rom_;
@@ -334,6 +348,10 @@ class MemoryImpl : public Memory, public Loggable {
uint32_t bank = address >> 16;
uint32_t offset = address & 0xFFFF;
if (mapping_ == MemoryMapping::PC_ADDRESS) {
return address;
}
if (bank <= 0x3F) {
if (offset <= 0x1FFF) {
return offset; // Shadow RAM
@@ -364,10 +382,12 @@ class MemoryImpl : public Memory, public Loggable {
std::vector<Observer*> observers_;
// Memory (64KB)
std::array<uint8_t, 0x10000> memory_;
std::vector<uint8_t> memory_;
// Stack Pointer
uint16_t SP_ = 0x01FF;
MemoryMapping mapping_ = MemoryMapping::SNES_LOROM;
};
} // namespace emu

View File

@@ -108,22 +108,15 @@ ROMInfo SNES::ReadRomHeader(uint32_t offset) {
}
void SNES::Init(ROM& rom) {
// Setup observers for the memory space
memory_.AddObserver(&apu);
memory_.AddObserver(&ppu);
// Load the ROM into memory and set up the memory mapping
memory_.Initialize(rom.vector());
// Read the ROM header
auto header_offset = GetHeaderOffset(memory_);
rom_info_ = ReadRomHeader(header_offset);
// Perform a long jump into a FastROM bank (if the ROM speed is FastROM)
// Disable the emulation flag (switch to 65816 native mode)
// Initialize CPU
cpu.Init();
// Read the ROM header
auto header_offset = GetHeaderOffset(memory_);
rom_info_ = ReadRomHeader(header_offset);
cpu.PC = rom_info_.resetVector;
// Initialize PPU

View File

@@ -65,12 +65,22 @@ class SNES : public DMA {
auto Cpu() -> CPU& { return cpu; }
auto Ppu() -> PPU& { return ppu; }
auto Memory() -> MemoryImpl* { return &memory_; }
void SetCpuMode(int mode) { cpu_mode_ = mode; }
CPU::UpdateMode GetCpuMode() const {
return static_cast<CPU::UpdateMode>(cpu_mode_);
}
void SetupMemory(ROM& rom) {
// Setup observers for the memory space
memory_.AddObserver(&apu);
memory_.AddObserver(&ppu);
// Load the ROM into memory and set up the memory mapping
memory_.Initialize(rom.vector());
}
private:
void WriteToRegister(uint16_t address, uint8_t value) {
memory_.WriteByte(address, value);