Play audio in emulator class, update class references from the SNES
This commit is contained in:
@@ -59,8 +59,8 @@ void Emulator::Run() {
|
||||
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);
|
||||
wanted_frames_ = 1.0 / (snes_.Memory().pal_timing() ? 50.0 : 60.0);
|
||||
wanted_samples_ = 48000 / (snes_.Memory().pal_timing() ? 50 : 60);
|
||||
loaded = true;
|
||||
|
||||
countFreq = SDL_GetPerformanceFrequency();
|
||||
@@ -84,6 +84,12 @@ void Emulator::Run() {
|
||||
|
||||
if (loaded) {
|
||||
snes_.RunFrame();
|
||||
|
||||
snes_.SetSamples(audio_buffer_, wanted_samples_);
|
||||
if (SDL_GetQueuedAudioSize(audio_device_) <= wanted_samples_ * 4 * 6) {
|
||||
SDL_QueueAudio(audio_device_, audio_buffer_, wanted_samples_ * 4);
|
||||
}
|
||||
|
||||
void* ppu_pixels_;
|
||||
int ppu_pitch_;
|
||||
if (SDL_LockTexture(ppu_texture_, NULL, &ppu_pixels_, &ppu_pitch_) !=
|
||||
@@ -153,7 +159,7 @@ void Emulator::RenderNavBar() {
|
||||
|
||||
if (ImGui::Button(ICON_MD_SKIP_NEXT)) {
|
||||
// Step through Code logic
|
||||
snes_.cpu()->RunOpcode();
|
||||
snes_.cpu().RunOpcode();
|
||||
}
|
||||
if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip("Step Through Code");
|
||||
@@ -210,7 +216,7 @@ void Emulator::RenderNavBar() {
|
||||
}
|
||||
|
||||
SameLine();
|
||||
ImGui::Checkbox("Logging", snes_.cpu()->mutable_log_instructions());
|
||||
ImGui::Checkbox("Logging", snes_.cpu().mutable_log_instructions());
|
||||
|
||||
static bool show_memory_viewer = false;
|
||||
|
||||
@@ -257,28 +263,28 @@ void Emulator::RenderBreakpointList() {
|
||||
if (ImGui::InputText("##BreakpointInput", breakpoint_input, 10,
|
||||
ImGuiInputTextFlags_EnterReturnsTrue)) {
|
||||
int breakpoint = std::stoi(breakpoint_input, nullptr, 16);
|
||||
snes_.cpu()->SetBreakpoint(breakpoint);
|
||||
snes_.cpu().SetBreakpoint(breakpoint);
|
||||
memset(breakpoint_input, 0, sizeof(breakpoint_input));
|
||||
}
|
||||
SameLine();
|
||||
if (ImGui::Button("Add")) {
|
||||
int breakpoint = std::stoi(breakpoint_input, nullptr, 16);
|
||||
snes_.cpu()->SetBreakpoint(breakpoint);
|
||||
snes_.cpu().SetBreakpoint(breakpoint);
|
||||
memset(breakpoint_input, 0, sizeof(breakpoint_input));
|
||||
}
|
||||
SameLine();
|
||||
if (ImGui::Button("Clear")) {
|
||||
snes_.cpu()->ClearBreakpoints();
|
||||
snes_.cpu().ClearBreakpoints();
|
||||
}
|
||||
Separator();
|
||||
auto breakpoints = snes_.cpu()->GetBreakpoints();
|
||||
auto breakpoints = snes_.cpu().GetBreakpoints();
|
||||
if (!breakpoints.empty()) {
|
||||
Text("Breakpoints:");
|
||||
ImGui::BeginChild("BreakpointsList", ImVec2(0, 100), true);
|
||||
for (auto breakpoint : breakpoints) {
|
||||
if (ImGui::Selectable(absl::StrFormat("0x%04X", breakpoint).c_str())) {
|
||||
// Jump to breakpoint
|
||||
// snes_.cpu()->JumpToBreakpoint(breakpoint);
|
||||
// snes_.cpu().JumpToBreakpoint(breakpoint);
|
||||
}
|
||||
}
|
||||
ImGui::EndChild();
|
||||
@@ -287,8 +293,8 @@ void Emulator::RenderBreakpointList() {
|
||||
gui::InputHexByte("PB", &manual_pb_, 50.f);
|
||||
gui::InputHexWord("PC", &manual_pc_, 75.f);
|
||||
if (ImGui::Button("Set Current Address")) {
|
||||
snes_.cpu()->PC = manual_pc_;
|
||||
snes_.cpu()->PB = manual_pb_;
|
||||
snes_.cpu().PC = manual_pc_;
|
||||
snes_.cpu().PB = manual_pb_;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -342,8 +348,8 @@ void Emulator::RenderMemoryViewer() {
|
||||
}
|
||||
|
||||
TableNextColumn();
|
||||
mem_edit.DrawContents((void*)snes_.Memory()->rom_.data(),
|
||||
snes_.Memory()->rom_.size());
|
||||
mem_edit.DrawContents((void*)snes_.Memory().rom_.data(),
|
||||
snes_.Memory().rom_.size());
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
@@ -56,13 +56,13 @@ class Emulator : public SharedRom {
|
||||
}
|
||||
)";
|
||||
const std::map<std::string, void*> data_bindings = {
|
||||
{"cpu.A", &snes_.cpu()->A}, {"cpu.D", &snes_.cpu()->D},
|
||||
{"cpu.X", &snes_.cpu()->X}, {"cpu.DB", &snes_.cpu()->DB},
|
||||
{"cpu.Y", &snes_.cpu()->Y}, {"cpu.PB", &snes_.cpu()->PB},
|
||||
{"cpu.PC", &snes_.cpu()->PC}, {"cpu.E", &snes_.cpu()->E}};
|
||||
{"cpu.A", &snes_.cpu().A}, {"cpu.D", &snes_.cpu().D},
|
||||
{"cpu.X", &snes_.cpu().X}, {"cpu.DB", &snes_.cpu().DB},
|
||||
{"cpu.Y", &snes_.cpu().Y}, {"cpu.PB", &snes_.cpu().PB},
|
||||
{"cpu.PC", &snes_.cpu().PC}, {"cpu.E", &snes_.cpu().E}};
|
||||
emulator_node_ = gui::zeml::Parse(emulator_layout, data_bindings);
|
||||
Bind(emulator_node_.GetNode("CpuInstructionLog"),
|
||||
[&]() { RenderCpuInstructionLog(snes_.cpu()->instruction_log_); });
|
||||
[&]() { RenderCpuInstructionLog(snes_.cpu().instruction_log_); });
|
||||
Bind(emulator_node_.GetNode("SnesPpu"), [&]() { RenderSnesPpu(); });
|
||||
Bind(emulator_node_.GetNode("BreakpointList"),
|
||||
[&]() { RenderBreakpointList(); });
|
||||
@@ -72,6 +72,9 @@ class Emulator : public SharedRom {
|
||||
auto snes() -> SNES& { return snes_; }
|
||||
auto running() const -> bool { return running_; }
|
||||
void set_audio_buffer(int16_t* audio_buffer) { audio_buffer_ = audio_buffer; }
|
||||
auto set_audio_device_id(SDL_AudioDeviceID audio_device) {
|
||||
audio_device_ = audio_device;
|
||||
}
|
||||
auto wanted_samples() const -> int { return wanted_samples_; }
|
||||
|
||||
private:
|
||||
@@ -108,6 +111,7 @@ class Emulator : public SharedRom {
|
||||
float timeAdder = 0.0;
|
||||
|
||||
int16_t* audio_buffer_;
|
||||
SDL_AudioDeviceID audio_device_;
|
||||
|
||||
SNES snes_;
|
||||
SDL_Texture* ppu_texture_;
|
||||
|
||||
@@ -37,45 +37,6 @@ void SNES::Init(Rom& rom) {
|
||||
// rom_info_ = memory_.ReadRomHeader();
|
||||
Reset(true);
|
||||
|
||||
// Disable the emulation flag (switch to 65816 native mode)
|
||||
// cpu_.E = 0;
|
||||
// cpu_.PB = 0x00;
|
||||
// cpu_.PC = 0x8000;
|
||||
|
||||
// Disable interrupts and rendering
|
||||
memory_.WriteByte(0x4200, 0x00); // NMITIMEN
|
||||
memory_.WriteByte(0x420C, 0x00); // HDMAEN
|
||||
|
||||
// Disable screen
|
||||
memory_.WriteByte(0x2100, 0x8F); // INIDISP
|
||||
|
||||
// Reset PPU registers to a known good state
|
||||
memory_.WriteByte(0x4201, 0xFF); // WRIO
|
||||
|
||||
// Scroll Registers
|
||||
memory_.WriteByte(0x210D, 0x00); // BG1HOFS
|
||||
memory_.WriteByte(0x210E, 0xFF); // BG1VOFS
|
||||
|
||||
memory_.WriteByte(0x210F, 0x00); // BG2HOFS
|
||||
memory_.WriteByte(0x2110, 0xFF); // BG2VOFS
|
||||
|
||||
memory_.WriteByte(0x2111, 0x00); // BG3HOFS
|
||||
memory_.WriteByte(0x2112, 0xFF); // BG3VOFS
|
||||
|
||||
memory_.WriteByte(0x2113, 0x00); // BG4HOFS
|
||||
memory_.WriteByte(0x2114, 0xFF); // BG4VOFS
|
||||
|
||||
// VRAM Registers
|
||||
memory_.WriteByte(0x2115, 0x80); // VMAIN
|
||||
|
||||
// Color Math
|
||||
memory_.WriteByte(0x2130, 0x30); // CGWSEL
|
||||
memory_.WriteByte(0x2131, 0x00); // CGADSUB
|
||||
memory_.WriteByte(0x2132, 0xE0); // COLDATA
|
||||
|
||||
// Misc
|
||||
memory_.WriteByte(0x2133, 0x00); // SETINI
|
||||
|
||||
running_ = true;
|
||||
}
|
||||
|
||||
@@ -291,7 +252,7 @@ uint8_t SNES::ReadBBus(uint8_t adr) {
|
||||
}
|
||||
if (adr < 0x80) {
|
||||
CatchUpApu(); // catch up the apu before reading
|
||||
return apu_.outPorts[adr & 0x3];
|
||||
return apu_.out_ports_[adr & 0x3];
|
||||
}
|
||||
if (adr == 0x80) {
|
||||
uint8_t ret = ram[ram_adr_++];
|
||||
@@ -397,7 +358,7 @@ void SNES::WriteBBus(uint8_t adr, uint8_t val) {
|
||||
}
|
||||
if (adr < 0x80) {
|
||||
CatchUpApu(); // catch up the apu before writing
|
||||
apu_.inPorts[adr & 0x3] = val;
|
||||
apu_.in_ports_[adr & 0x3] = val;
|
||||
return;
|
||||
}
|
||||
switch (adr) {
|
||||
|
||||
@@ -67,9 +67,9 @@ class SNES {
|
||||
void SetPixels(uint8_t* pixel_data);
|
||||
|
||||
bool running() const { return running_; }
|
||||
auto cpu() -> Cpu* { return &cpu_; }
|
||||
auto ppu() -> video::Ppu* { return &ppu_; }
|
||||
auto Memory() -> memory::MemoryImpl* { return &memory_; }
|
||||
auto cpu() -> Cpu& { return cpu_; }
|
||||
auto ppu() -> video::Ppu& { return ppu_; }
|
||||
auto Memory() -> memory::MemoryImpl& { return memory_; }
|
||||
|
||||
private:
|
||||
// Components of the SNES
|
||||
@@ -77,7 +77,6 @@ class SNES {
|
||||
Debugger debugger;
|
||||
memory::RomInfo rom_info_;
|
||||
memory::MemoryImpl memory_;
|
||||
audio::AudioRamImpl audio_ram_;
|
||||
|
||||
memory::CpuCallbacks cpu_callbacks_ = {
|
||||
[&](uint32_t adr) { return CpuRead(adr); },
|
||||
@@ -86,7 +85,7 @@ class SNES {
|
||||
};
|
||||
Cpu cpu_{memory_, clock_, cpu_callbacks_};
|
||||
video::Ppu ppu_{memory_, clock_};
|
||||
audio::Apu apu_{memory_, audio_ram_, clock_};
|
||||
audio::Apu apu_{memory_, clock_};
|
||||
|
||||
// Currently loaded ROM
|
||||
std::vector<uint8_t> rom_data;
|
||||
|
||||
Reference in New Issue
Block a user