diff --git a/src/common/cd_image.cpp b/src/common/cd_image.cpp index b3cc635ea..bf81991ef 100644 --- a/src/common/cd_image.cpp +++ b/src/common/cd_image.cpp @@ -11,20 +11,6 @@ CDImage::~CDImage() m_data_file->Release(); } -constexpr u64 CDImage::MSFToLBA(u32 pregap_seconds, u32 minute, u32 second, u32 frame) -{ - return ZeroExtend64(minute) * FRAMES_PER_MINUTE + ZeroExtend64(second) * FRAMES_PER_SECOND + ZeroExtend64(frame) - - ZeroExtend64(pregap_seconds) * FRAMES_PER_SECOND; -} - -constexpr void CDImage::LBAToMSF(u32 pregap_seconds, u64 lba, u32* minute, u32* second, u32* frame) -{ - const u64 offset = (lba + (pregap_seconds * FRAMES_PER_SECOND) % FRAMES_PER_MINUTE); - *minute = Truncate32(lba / FRAMES_PER_MINUTE); - *second = Truncate32(offset / FRAMES_PER_SECOND); - *frame = Truncate32(offset % FRAMES_PER_SECOND); -} - bool CDImage::Open(const char* path) { Assert(!m_data_file); @@ -35,6 +21,7 @@ bool CDImage::Open(const char* path) return false; } + m_filename = path; m_lba_count = m_data_file->GetSize() / RAW_SECTOR_SIZE; return true; } diff --git a/src/common/cd_image.h b/src/common/cd_image.h index b8f9f57ac..708f8ad7a 100644 --- a/src/common/cd_image.h +++ b/src/common/cd_image.h @@ -1,6 +1,7 @@ #pragma once #include "bitfield.h" #include "types.h" +#include class ByteStream; @@ -37,11 +38,25 @@ public: }; // Conversion helpers. - static constexpr u64 MSFToLBA(u32 pregap_seconds, u32 minute, u32 second, u32 frame); - static constexpr void LBAToMSF(u32 pregap_seconds, u64 lba, u32* minute, u32* second, u32* frame); + static constexpr u64 MSFToLBA(u32 pregap_seconds, u32 minute, u32 second, u32 frame) + { + return ZeroExtend64(minute) * FRAMES_PER_MINUTE + ZeroExtend64(second) * FRAMES_PER_SECOND + ZeroExtend64(frame) - + ZeroExtend64(pregap_seconds) * FRAMES_PER_SECOND; + } + static constexpr std::tuple LBAToMSF(u32 pregap_seconds, u64 lba) + { + const u64 offset = (lba + (pregap_seconds * FRAMES_PER_SECOND) % FRAMES_PER_MINUTE); + const u32 minute = Truncate32(lba / FRAMES_PER_MINUTE); + const u32 second = Truncate32(offset / FRAMES_PER_SECOND); + const u32 frame = Truncate32(offset % FRAMES_PER_SECOND); + return std::make_tuple(minute, second, frame); + } // Accessors. + const std::string& GetFileName() const { return m_filename; } + u32 GetPregapSeconds() const { return m_pregap_seconds; } u64 GetCurrentLBA() const { return m_current_lba; } + std::tuple GetPositionMSF() const { return LBAToMSF(m_pregap_seconds, m_current_lba); } u64 GetLBACount() const { return m_lba_count; } bool Open(const char* path); @@ -60,6 +75,8 @@ public: u32 Read(ReadMode read_mode, u32 sector_count, void* buffer); private: + std::string m_filename; + // TODO: Multiple data files from cue sheet ByteStream* m_data_file = nullptr; diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index ec2f412d3..6f91a83fd 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -3,6 +3,7 @@ #include "common/cd_image.h" #include "common/state_wrapper.h" #include "dma.h" +#include "imgui.h" #include "interrupt_controller.h" #include "spu.h" #include "system.h" @@ -108,7 +109,8 @@ bool CDROM::DoState(StateWrapper& sw) sw.Do(&m_sector_buffer); u64 media_lba = m_media ? m_media->GetCurrentLBA() : 0; - sw.Do(&m_media_filename); + std::string media_filename = m_media ? m_media->GetFileName() : std::string(); + sw.Do(&media_filename); sw.Do(&media_lba); if (sw.IsReading()) @@ -120,12 +122,12 @@ bool CDROM::DoState(StateWrapper& sw) // load up media if we had something in there before m_media.reset(); - if (!m_media_filename.empty()) + if (!media_filename.empty()) { m_media = std::make_unique(); - if (!m_media->Open(m_media_filename.c_str()) || !m_media->Seek(media_lba)) + if (!m_media->Open(media_filename.c_str()) || !m_media->Seek(media_lba)) { - Log_ErrorPrintf("Failed to re-insert CD media from save state: '%s'. Ejecting.", m_media_filename.c_str()); + Log_ErrorPrintf("Failed to re-insert CD media from save state: '%s'. Ejecting.", media_filename.c_str()); RemoveMedia(); } } @@ -147,7 +149,6 @@ bool CDROM::InsertMedia(const char* filename) RemoveMedia(); m_media = std::move(media); - m_media_filename = filename; // m_secondary_status.shell_open = false; return true; } @@ -160,7 +161,6 @@ void CDROM::RemoveMedia() // TODO: Error while reading? Log_InfoPrintf("Removing CD..."); m_media.reset(); - m_media_filename.clear(); // m_secondary_status.shell_open = true; } @@ -1031,3 +1031,109 @@ void CDROM::LoadDataFIFO() Log_DebugPrintf("Loaded %u bytes to data FIFO", m_data_fifo.GetSize()); m_sector_buffer.clear(); } + +void CDROM::DrawDebugWindow() +{ + if (!m_show_cdrom_state) + return; + + ImGui::SetNextWindowSize(ImVec2(800, 400), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("CDROM State", &m_show_cdrom_state)) + { + ImGui::End(); + return; + } + + // draw voice states + if (ImGui::CollapsingHeader("Media", ImGuiTreeNodeFlags_DefaultOpen)) + { + if (m_media) + { + const auto [pos_minute, pos_second, pos_frame] = m_media->GetPositionMSF(); + + ImGui::Text("Filename: %s", m_media->GetFileName().c_str()); + ImGui::Text("Position (MSF): %02u:%02u:%02u", pos_minute, pos_second, pos_frame); + ImGui::Text("Position (LBA): %llu", m_media->GetCurrentLBA()); + } + else + { + ImGui::Text("No media inserted."); + } + } + + if (ImGui::CollapsingHeader("Status/Mode", ImGuiTreeNodeFlags_DefaultOpen)) + { + ImGui::Columns(3); + + ImGui::Text("Status"); + ImGui::NextColumn(); + ImGui::Text("Secondary Status"); + ImGui::NextColumn(); + ImGui::Text("Mode Status"); + ImGui::NextColumn(); + + ImGui::Text("ADPBUSY: %s", m_status.ADPBUSY ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Error: %s", m_secondary_status.error ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("CDDA: %s", m_mode.cdda ? "Yes" : "No"); + ImGui::NextColumn(); + + ImGui::Text("PRMEMPTY: %s", m_status.PRMEMPTY ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Motor On: %s", m_secondary_status.motor_on ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Auto Pause: %s", m_mode.auto_pause ? "Yes" : "No"); + ImGui::NextColumn(); + + ImGui::Text("PRMWRDY: %s", m_status.PRMWRDY ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Seek Error: %s", m_secondary_status.seek_error ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Report Audio: %s", m_mode.report_audio ? "Yes" : "No"); + ImGui::NextColumn(); + + ImGui::Text("RSLRRDY: %s", m_status.RSLRRDY ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("ID Error: %s", m_secondary_status.id_error ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("XA Filter: %s (File %u Channel %u)", m_mode.xa_filter ? "Yes" : "No", m_filter_file_number, + m_filter_channel_number); + ImGui::NextColumn(); + + ImGui::Text("DRQSTS: %s", m_status.DRQSTS ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Shell Open: %s", m_secondary_status.shell_open ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Ignore Bit: %s", m_mode.ignore_bit ? "Yes" : "No"); + ImGui::NextColumn(); + + ImGui::Text("BUSYSTS: %s", m_status.BUSYSTS ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Reading: %s", m_secondary_status.reading ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Read Raw Sectors: %s", m_mode.read_raw_sector ? "Yes" : "No"); + ImGui::NextColumn(); + + ImGui::NextColumn(); + ImGui::Text("Seeking: %s", m_secondary_status.seeking ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("XA Enable: %s", m_mode.xa_enable ? "Yes" : "No"); + ImGui::NextColumn(); + + ImGui::NextColumn(); + ImGui::Text("Playing CDDA: %s", m_secondary_status.playing_cdda ? "Yes" : "No"); + ImGui::NextColumn(); + ImGui::Text("Double Speed: %s", m_mode.double_speed ? "Yes" : "No"); + ImGui::NextColumn(); + + ImGui::Columns(1); + } + + ImGui::End(); +} + +void CDROM::DrawDebugMenu() +{ + ImGui::MenuItem("CDROM", nullptr, &m_show_cdrom_state); +} diff --git a/src/core/cdrom.h b/src/core/cdrom.h index 83062456e..ff4a869c7 100644 --- a/src/core/cdrom.h +++ b/src/core/cdrom.h @@ -46,6 +46,12 @@ public: void Execute(TickCount ticks); + // Render statistics debug window. + void DrawDebugWindow(); + + // Manipulating debug options. + void DrawDebugMenu(); + private: static constexpr u32 PARAM_FIFO_SIZE = 16; static constexpr u32 RESPONSE_FIFO_SIZE = 16; @@ -184,7 +190,6 @@ private: InterruptController* m_interrupt_controller = nullptr; SPU* m_spu = nullptr; std::unique_ptr m_media; - std::string m_media_filename; CommandState m_command_state = CommandState::Idle; Command m_command = Command::Sync; @@ -223,4 +228,6 @@ private: InlineFIFOQueue m_response_fifo; HeapFIFOQueue m_data_fifo; std::vector m_sector_buffer; + + bool m_show_cdrom_state = false; }; diff --git a/src/core/system.cpp b/src/core/system.cpp index 3afa32a5e..4a1863570 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -326,6 +326,7 @@ void System::DrawDebugMenus() m_gpu->DrawDebugMenu(); m_spu->DrawDebugMenu(); m_timers->DrawDebugMenu(); + m_cdrom->DrawDebugMenu(); m_mdec->DrawDebugMenu(); } @@ -334,5 +335,6 @@ void System::DrawDebugWindows() m_gpu->DrawDebugWindows(); m_spu->DrawDebugWindow(); m_timers->DrawDebugWindow(); + m_cdrom->DrawDebugWindow(); m_mdec->DrawDebugWindow(); }