Add SNES BBus, registers, input, nmi/irq, joypad handling, frame timing, cpu callbacks, etc

This commit is contained in:
scawful
2024-04-22 15:53:17 -04:00
parent 541e045c46
commit 917cd26a6e
6 changed files with 652 additions and 329 deletions

View File

@@ -50,19 +50,74 @@ using ImGui::Text;
void Emulator::Run() {
if (!snes_.running() && rom()->is_loaded()) {
ppu_texture_ =
SDL_CreateTexture(rom()->renderer().get(), SDL_PIXELFORMAT_RGBX8888,
SDL_TEXTUREACCESS_STREAMING, 512, 480);
if (ppu_texture_ == NULL) {
printf("Failed to create texture: %s\n", SDL_GetError());
return;
}
snes_.Init(*rom());
wanted_frames_ = 1.0 / (snes_.Memory()->pal_timing() ? 50.0 : 60.0);
wanted_samples_ = 48000 / (snes_.Memory()->pal_timing() ? 50 : 60);
countFreq = SDL_GetPerformanceFrequency();
lastCount = SDL_GetPerformanceCounter();
timeAdder = 0.0;
}
RenderNavBar();
if (running_) {
HandleEvents();
snes_.Run();
uint64_t curCount = SDL_GetPerformanceCounter();
uint64_t delta = curCount - lastCount;
lastCount = curCount;
float seconds = delta / (float)countFreq;
timeAdder += seconds;
// allow 2 ms earlier, to prevent skipping due to being just below wanted
while (timeAdder >= wanted_frames_ - 0.002) {
timeAdder -= wanted_frames_;
snes_.RunFrame();
void* ppu_pixels_;
int ppu_pitch_;
if (SDL_LockTexture(ppu_texture_, NULL, &ppu_pixels_, &ppu_pitch_) != 0) {
printf("Failed to lock texture: %s\n", SDL_GetError());
return;
}
snes_.SetPixels(static_cast<uint8_t*>(ppu_pixels_));
SDL_UnlockTexture(ppu_texture_);
}
}
gui::zeml::Render(emulator_node_);
}
void Emulator::RenderSnesPpu() {
ImVec2 size = ImVec2(320, 480);
if (snes_.running()) {
ImGui::BeginChild("EmulatorOutput", ImVec2(0, 240), true,
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar);
ImGui::SetCursorPosX((ImGui::GetWindowSize().x - size.x) * 0.5f);
ImGui::SetCursorPosY((ImGui::GetWindowSize().y - size.y) * 0.5f);
ImGui::Image((void*)ppu_texture_, size, ImVec2(0, 0), ImVec2(1, 1));
ImGui::EndChild();
} else {
ImGui::Text("Emulator output not available.");
ImGui::BeginChild("EmulatorOutput", ImVec2(0, 240), true,
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar);
ImGui::SetCursorPosX(((ImGui::GetWindowSize().x * 0.5f) - size.x) * 0.5f);
ImGui::SetCursorPosY(((ImGui::GetWindowSize().y * 0.5f) - size.y) * 0.5f);
ImGui::Dummy(size);
ImGui::EndChild();
}
ImGui::Separator();
}
void Emulator::RenderNavBar() {
std::string navbar_layout = R"(
BeginMenuBar {
@@ -94,7 +149,7 @@ void Emulator::RenderNavBar() {
if (ImGui::Button(ICON_MD_SKIP_NEXT)) {
// Step through Code logic
snes_.StepRun();
// snes_.StepRun();
}
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Step Through Code");
@@ -148,6 +203,10 @@ void Emulator::RenderNavBar() {
}
// About Debugger logic
}
SameLine();
ImGui::Checkbox("Logging", snes_.cpu().mutable_log_instructions());
static bool show_memory_viewer = false;
SameLine();
@@ -170,29 +229,6 @@ void Emulator::HandleEvents() {
// ...
}
void Emulator::RenderSnesPpu() {
ImVec2 size = ImVec2(320, 240);
if (snes_.running()) {
ImGui::BeginChild("EmulatorOutput", ImVec2(0, 240), true,
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar);
ImGui::SetCursorPosX((ImGui::GetWindowSize().x - size.x) * 0.5f);
ImGui::SetCursorPosY((ImGui::GetWindowSize().y - size.y) * 0.5f);
ImGui::Image((void*)snes_.ppu().GetScreen()->texture(), size, ImVec2(0, 0),
ImVec2(1, 1));
ImGui::EndChild();
} else {
ImGui::Text("Emulator output not available.");
ImGui::BeginChild("EmulatorOutput", ImVec2(0, 240), true,
ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar);
ImGui::SetCursorPosX(((ImGui::GetWindowSize().x * 0.5f) - size.x) * 0.5f);
ImGui::SetCursorPosY(((ImGui::GetWindowSize().y * 0.5f) - size.y) * 0.5f);
ImGui::Dummy(size);
ImGui::EndChild();
}
ImGui::Separator();
}
void Emulator::RenderBreakpointList() {
Text("Breakpoints");
Separator();