CDROM: Special case immediate GetlocP after play/read before int

Fixes CDDA in Mad Panic Coaster.
This commit is contained in:
Connor McLaughlin 2021-10-27 20:03:55 +10:00
parent 58f05498e5
commit 25f69e7f8c
15 changed files with 68 additions and 60 deletions

View File

@ -1913,7 +1913,18 @@ void CDROM::UpdatePhysicalPosition(bool update_logical)
const u32 ticks = TimingEvents::GetGlobalTickCounter(); const u32 ticks = TimingEvents::GetGlobalTickCounter();
if (IsSeeking() || IsReadingOrPlaying() || !m_secondary_status.motor_on) if (IsSeeking() || IsReadingOrPlaying() || !m_secondary_status.motor_on)
{ {
// set by the event // If we're seeking+reading the first sector (no stat bits set), we need to return the set/current lba, not the last
// physical LBA. Failing to do so may result in a track-jumped position getting returned in GetlocP, which causes
// Mad Panic Coaster to go into a seek+play loop.
if ((m_secondary_status.bits & (STAT_READING | STAT_PLAYING_CDDA | STAT_MOTOR_ON)) == STAT_MOTOR_ON &&
m_current_lba != m_physical_lba)
{
Log_WarningPrintf("Jumping to hold position [%u->%u] while %s first sector", m_physical_lba, m_current_lba,
(m_drive_state == DriveState::Reading) ? "reading" : "playing");
SetHoldPosition(m_current_lba, true);
}
// Otherwise, this gets updated by the read event.
return; return;
} }

View File

@ -456,25 +456,6 @@ bool HostInterface::SaveState(const char* filename)
return result; return result;
} }
void HostInterface::OnSystemCreated() {}
void HostInterface::OnSystemPaused(bool paused) {}
void HostInterface::OnSystemDestroyed() {}
void HostInterface::OnSystemPerformanceCountersUpdated() {}
void HostInterface::OnDisplayInvalidated() {}
void HostInterface::OnSystemStateSaved(bool global, s32 slot) {}
void HostInterface::OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
const std::string& game_title)
{
}
void HostInterface::OnControllerTypeChanged(u32 slot) {}
std::string HostInterface::GetShaderCacheBasePath() const std::string HostInterface::GetShaderCacheBasePath() const
{ {
return GetUserDirectoryRelativePath("cache/"); return GetUserDirectoryRelativePath("cache/");
@ -1197,13 +1178,3 @@ void HostInterface::RecreateSystem()
System::ResetThrottler(); System::ResetThrottler();
OnDisplayInvalidated(); OnDisplayInvalidated();
} }
void HostInterface::SetMouseMode(bool relative, bool hide_cursor) {}
void HostInterface::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/, int progress_max /*= -1*/,
int progress_value /*= -1*/)
{
Log_InfoPrintf("Loading: %s %d of %d-%d", message, progress_value, progress_min, progress_max);
}
void HostInterface::GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title) {}

View File

@ -88,10 +88,10 @@ public:
/// Displays a loading screen with the logo, rendered with ImGui. Use when executing possibly-time-consuming tasks /// Displays a loading screen with the logo, rendered with ImGui. Use when executing possibly-time-consuming tasks
/// such as compiling shaders when starting up. /// such as compiling shaders when starting up.
virtual void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1, virtual void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1,
int progress_value = -1); int progress_value = -1) = 0;
/// Retrieves information about specified game from game list. /// Retrieves information about specified game from game list.
virtual void GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title); virtual void GetGameInfo(const char* path, CDImage* image, std::string* code, std::string* title) = 0;
/// Returns the directory where per-game memory cards will be saved. /// Returns the directory where per-game memory cards will be saved.
virtual std::string GetMemoryCardDirectory() const; virtual std::string GetMemoryCardDirectory() const;
@ -147,11 +147,11 @@ public:
virtual std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) = 0; virtual std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) = 0;
virtual void OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code, virtual void OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
const std::string& game_title); const std::string& game_title) = 0;
virtual void OnSystemPerformanceCountersUpdated(); virtual void OnSystemPerformanceCountersUpdated() = 0;
/// Called when the display is invalidated (e.g. a state is loaded). /// Called when the display is invalidated (e.g. a state is loaded).
virtual void OnDisplayInvalidated(); virtual void OnDisplayInvalidated() = 0;
protected: protected:
virtual bool AcquireHostDisplay() = 0; virtual bool AcquireHostDisplay() = 0;
@ -159,11 +159,10 @@ protected:
virtual std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend) = 0; virtual std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend) = 0;
virtual s32 GetAudioOutputVolume() const; virtual s32 GetAudioOutputVolume() const;
virtual void OnSystemCreated(); virtual void OnSystemCreated() = 0;
virtual void OnSystemPaused(bool paused); virtual void OnSystemPaused(bool paused) = 0;
virtual void OnSystemDestroyed(); virtual void OnSystemDestroyed() = 0;
virtual void OnSystemStateSaved(bool global, s32 slot); virtual void OnControllerTypeChanged(u32 slot) = 0;
virtual void OnControllerTypeChanged(u32 slot);
/// Restores all settings to defaults. /// Restores all settings to defaults.
virtual void SetDefaultSettings(SettingsInterface& si); virtual void SetDefaultSettings(SettingsInterface& si);
@ -184,7 +183,7 @@ protected:
virtual void RecreateSystem(); virtual void RecreateSystem();
/// Enables "relative" mouse mode, locking the cursor position and returning relative coordinates. /// Enables "relative" mouse mode, locking the cursor position and returning relative coordinates.
virtual void SetMouseMode(bool relative, bool hide_cursor); virtual void SetMouseMode(bool relative, bool hide_cursor) = 0;
/// Call when host display size changes, use with "match display" aspect ratio setting. /// Call when host display size changes, use with "match display" aspect ratio setting.
virtual void OnHostDisplayResized(); virtual void OnHostDisplayResized();

View File

@ -89,6 +89,10 @@ void NoGUIHostInterface::SetDefaultSettings(SettingsInterface& si)
si.SetStringValue("Hotkeys", "OpenQuickMenu", "Keyboard/Escape"); si.SetStringValue("Hotkeys", "OpenQuickMenu", "Keyboard/Escape");
} }
void NoGUIHostInterface::OnDisplayInvalidated() {}
void NoGUIHostInterface::OnSystemPerformanceCountersUpdated() {}
bool NoGUIHostInterface::CreateDisplay(bool fullscreen) bool NoGUIHostInterface::CreateDisplay(bool fullscreen)
{ {
std::optional<WindowInfo> wi = GetPlatformWindowInfo(); std::optional<WindowInfo> wi = GetPlatformWindowInfo();

View File

@ -31,6 +31,9 @@ public:
void RunLater(std::function<void()> callback) override; void RunLater(std::function<void()> callback) override;
virtual void OnDisplayInvalidated() override;
virtual void OnSystemPerformanceCountersUpdated() override;
protected: protected:
enum : u32 enum : u32
{ {

View File

@ -260,6 +260,8 @@ std::optional<CommonHostInterface::HostKeyCode> SDLHostInterface::GetHostKeyCode
return static_cast<HostKeyCode>(*code); return static_cast<HostKeyCode>(*code);
} }
void SDLHostInterface::SetMouseMode(bool relative, bool hide_cursor) {}
void SDLHostInterface::PollAndUpdate() void SDLHostInterface::PollAndUpdate()
{ {
// Process SDL events before the controller interface can steal them. // Process SDL events before the controller interface can steal them.

View File

@ -21,6 +21,8 @@ public:
bool SetFullscreen(bool enabled) override; bool SetFullscreen(bool enabled) override;
protected: protected:
void SetMouseMode(bool relative, bool hide_cursor) override;
void PollAndUpdate() override; void PollAndUpdate() override;
std::optional<HostKeyCode> GetHostKeyCode(const std::string_view key_code) const override; std::optional<HostKeyCode> GetHostKeyCode(const std::string_view key_code) const override;

View File

@ -111,6 +111,8 @@ void VTYHostInterface::PollAndUpdate()
NoGUIHostInterface::PollAndUpdate(); NoGUIHostInterface::PollAndUpdate();
} }
void VTYHostInterface::SetMouseMode(bool relative, bool hide_cursor) {}
void VTYHostInterface::OpenEVDevFDs() void VTYHostInterface::OpenEVDevFDs()
{ {
for (int i = 0; i < 1000; i++) for (int i = 0; i < 1000; i++)

View File

@ -29,6 +29,8 @@ protected:
void PollAndUpdate() override; void PollAndUpdate() override;
void SetMouseMode(bool relative, bool hide_cursor) override;
private: private:
static void SIGTERMHandler(int sig); static void SIGTERMHandler(int sig);

View File

@ -57,6 +57,8 @@ bool Win32HostInterface::RegisterWindowClass()
return true; return true;
} }
void Win32HostInterface::SetMouseMode(bool relative, bool hide_cursor) {}
bool Win32HostInterface::CreatePlatformWindow() bool Win32HostInterface::CreatePlatformWindow()
{ {
m_hwnd = CreateWindowExW(WS_EX_CLIENTEDGE, WINDOW_CLASS_NAME, L"DuckStation", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, m_hwnd = CreateWindowExW(WS_EX_CLIENTEDGE, WINDOW_CLASS_NAME, L"DuckStation", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,

View File

@ -16,6 +16,8 @@ public:
static std::unique_ptr<NoGUIHostInterface> Create(); static std::unique_ptr<NoGUIHostInterface> Create();
protected: protected:
void SetMouseMode(bool relative, bool hide_cursor) override;
bool CreatePlatformWindow() override; bool CreatePlatformWindow() override;
void DestroyPlatformWindow() override; void DestroyPlatformWindow() override;
std::optional<WindowInfo> GetPlatformWindowInfo() override; std::optional<WindowInfo> GetPlatformWindowInfo() override;

View File

@ -784,8 +784,6 @@ void QtHostInterface::OnSystemDestroyed()
void QtHostInterface::OnSystemPerformanceCountersUpdated() void QtHostInterface::OnSystemPerformanceCountersUpdated()
{ {
HostInterface::OnSystemPerformanceCountersUpdated();
GPURenderer renderer = GPURenderer::Count; GPURenderer renderer = GPURenderer::Count;
u32 render_width = 0; u32 render_width = 0;
u32 render_height = 0; u32 render_height = 0;

View File

@ -104,8 +104,6 @@ void RegTestHostInterface::GetGameInfo(const char* path, CDImage* image, std::st
void RegTestHostInterface::OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code, void RegTestHostInterface::OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
const std::string& game_title) const std::string& game_title)
{ {
HostInterface::OnRunningGameChanged(path, image, game_code, game_title);
Log_InfoPrintf("Game Path: %s", path.c_str()); Log_InfoPrintf("Game Path: %s", path.c_str());
Log_InfoPrintf("Game Code: %s", game_code.c_str()); Log_InfoPrintf("Game Code: %s", game_code.c_str());
Log_InfoPrintf("Game Title: %s", game_title.c_str()); Log_InfoPrintf("Game Title: %s", game_title.c_str());
@ -128,6 +126,10 @@ void RegTestHostInterface::OnRunningGameChanged(const std::string& path, CDImage
UpdateSettings(); UpdateSettings();
} }
void RegTestHostInterface::OnSystemPerformanceCountersUpdated() {}
void RegTestHostInterface::OnDisplayInvalidated() {}
std::string RegTestHostInterface::GetStringSettingValue(const char* section, const char* key, std::string RegTestHostInterface::GetStringSettingValue(const char* section, const char* key,
const char* default_value /*= ""*/) const char* default_value /*= ""*/)
{ {
@ -284,6 +286,16 @@ std::unique_ptr<AudioStream> RegTestHostInterface::CreateAudioStream(AudioBacken
return AudioStream::CreateNullAudioStream(); return AudioStream::CreateNullAudioStream();
} }
void RegTestHostInterface::OnSystemCreated() {}
void RegTestHostInterface::OnSystemPaused(bool paused) {}
void RegTestHostInterface::OnSystemDestroyed() {}
void RegTestHostInterface::OnControllerTypeChanged(u32 slot) {}
void RegTestHostInterface::SetMouseMode(bool relative, bool hide_cursor) {}
static void PrintCommandLineVersion() static void PrintCommandLineVersion()
{ {
const bool was_console_enabled = Log::IsConsoleOutputEnabled(); const bool was_console_enabled = Log::IsConsoleOutputEnabled();

View File

@ -2,7 +2,7 @@
#include "core/host_interface.h" #include "core/host_interface.h"
#include "regtest_settings_interface.h" #include "regtest_settings_interface.h"
class RegTestHostInterface : public HostInterface class RegTestHostInterface final : public HostInterface
{ {
public: public:
RegTestHostInterface(); RegTestHostInterface();
@ -34,12 +34,22 @@ public:
std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) override; std::unique_ptr<ByteStream> OpenPackageFile(const char* path, u32 flags) override;
void OnSystemPerformanceCountersUpdated() override;
void OnDisplayInvalidated() override;
protected: protected:
bool AcquireHostDisplay() override; bool AcquireHostDisplay() override;
void ReleaseHostDisplay() override; void ReleaseHostDisplay() override;
std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend) override; std::unique_ptr<AudioStream> CreateAudioStream(AudioBackend backend) override;
void OnSystemCreated() override;
void OnSystemPaused(bool paused) override;
void OnSystemDestroyed() override;
void OnControllerTypeChanged(u32 slot) override;
void SetMouseMode(bool relative, bool hide_cursor) override;
private: private:
void LoadGameSettingsDatabase(); void LoadGameSettingsDatabase();
void InitializeSettings(); void InitializeSettings();

View File

@ -840,11 +840,7 @@ bool CommonHostInterface::SaveState(bool global, s32 slot)
std::string save_path = global ? GetGlobalSaveStateFileName(slot) : GetGameSaveStateFileName(code.c_str(), slot); std::string save_path = global ? GetGlobalSaveStateFileName(slot) : GetGameSaveStateFileName(code.c_str(), slot);
RenameCurrentSaveStateToBackup(save_path.c_str()); RenameCurrentSaveStateToBackup(save_path.c_str());
if (!SaveState(save_path.c_str())) return SaveState(save_path.c_str());
return false;
OnSystemStateSaved(global, slot);
return true;
} }
bool CommonHostInterface::CanResumeSystemFromFile(const char* filename) bool CommonHostInterface::CanResumeSystemFromFile(const char* filename)
@ -1090,8 +1086,6 @@ void CommonHostInterface::SetUserDirectory()
void CommonHostInterface::OnSystemCreated() void CommonHostInterface::OnSystemCreated()
{ {
HostInterface::OnSystemCreated();
if (m_fullscreen_ui_enabled) if (m_fullscreen_ui_enabled)
FullscreenUI::SystemCreated(); FullscreenUI::SystemCreated();
@ -1127,8 +1121,6 @@ void CommonHostInterface::OnSystemDestroyed()
if (m_display) if (m_display)
m_display->SetDisplayMaxFPS(0.0f); m_display->SetDisplayMaxFPS(0.0f);
HostInterface::OnSystemDestroyed();
if (m_fullscreen_ui_enabled) if (m_fullscreen_ui_enabled)
FullscreenUI::SystemDestroyed(); FullscreenUI::SystemDestroyed();
@ -1139,8 +1131,6 @@ void CommonHostInterface::OnSystemDestroyed()
void CommonHostInterface::OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code, void CommonHostInterface::OnRunningGameChanged(const std::string& path, CDImage* image, const std::string& game_code,
const std::string& game_title) const std::string& game_title)
{ {
HostInterface::OnRunningGameChanged(path, image, game_code, game_title);
if (g_settings.apply_game_settings) if (g_settings.apply_game_settings)
ApplySettings(true); ApplySettings(true);
@ -1166,8 +1156,6 @@ void CommonHostInterface::OnRunningGameChanged(const std::string& path, CDImage*
void CommonHostInterface::OnControllerTypeChanged(u32 slot) void CommonHostInterface::OnControllerTypeChanged(u32 slot)
{ {
HostInterface::OnControllerTypeChanged(slot);
UpdateInputMap(); UpdateInputMap();
} }
@ -2821,8 +2809,8 @@ bool CommonHostInterface::ApplyInputProfile(const char* profile_path)
continue; continue;
} }
// We don't need to call ControllerTypeChanged here because we're already updating the input map.
g_settings.controller_types[controller_index - 1] = *ctype; g_settings.controller_types[controller_index - 1] = *ctype;
HostInterface::OnControllerTypeChanged(controller_index - 1);
m_settings_interface->SetStringValue(section_name, "Type", Settings::GetControllerTypeName(*ctype)); m_settings_interface->SetStringValue(section_name, "Type", Settings::GetControllerTypeName(*ctype));