mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 07:35:41 +00:00
Misc: Post-refactor cleanups
This commit is contained in:
parent
82cdef45b3
commit
dc9c99438b
|
@ -16,8 +16,6 @@ add_library(core
|
|||
cheats.h
|
||||
controller.cpp
|
||||
controller.h
|
||||
common_host.cpp
|
||||
common_host.h
|
||||
cpu_code_cache.cpp
|
||||
cpu_code_cache.h
|
||||
cpu_core.cpp
|
||||
|
@ -62,8 +60,7 @@ add_library(core
|
|||
host.h
|
||||
host_interface_progress_callback.cpp
|
||||
host_interface_progress_callback.h
|
||||
host_settings.cpp
|
||||
host_settings.h
|
||||
hotkeys.cpp
|
||||
input_types.h
|
||||
imgui_overlays.cpp
|
||||
imgui_overlays.h
|
||||
|
@ -157,7 +154,6 @@ endif()
|
|||
if(ENABLE_CHEEVOS)
|
||||
target_sources(core PRIVATE
|
||||
achievements.cpp
|
||||
achievements_private.h
|
||||
)
|
||||
target_compile_definitions(core PUBLIC -DWITH_CHEEVOS=1)
|
||||
target_link_libraries(core PRIVATE rcheevos rapidjson)
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "achievements_private.h"
|
||||
#include "achievements.h"
|
||||
#include "bios.h"
|
||||
#include "bus.h"
|
||||
#include "cpu_core.h"
|
||||
#include "fullscreen_ui.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "system.h"
|
||||
|
||||
#include "scmversion/scmversion.h"
|
||||
|
@ -682,8 +681,7 @@ void Achievements::FrameUpdate()
|
|||
#ifdef WITH_RAINTEGRATION
|
||||
if (IsUsingRAIntegration())
|
||||
{
|
||||
if (!System::IsPaused())
|
||||
RA_DoAchievementsFrame();
|
||||
RA_DoAchievementsFrame();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
@ -693,17 +691,8 @@ void Achievements::FrameUpdate()
|
|||
if (HasActiveGame())
|
||||
{
|
||||
std::unique_lock lock(s_achievements_mutex);
|
||||
if (!System::IsPaused())
|
||||
rc_runtime_do_frame(&s_rcheevos_runtime, &CheevosEventHandler, &PeekMemory, nullptr, nullptr);
|
||||
rc_runtime_do_frame(&s_rcheevos_runtime, &CheevosEventHandler, &PeekMemory, nullptr, nullptr);
|
||||
UpdateRichPresence();
|
||||
|
||||
if (!IsTestModeActive())
|
||||
{
|
||||
const s32 ping_frequency =
|
||||
g_settings.achievements_rich_presence ? RICH_PRESENCE_PING_FREQUENCY : NO_RICH_PRESENCE_PING_FREQUENCY;
|
||||
if (static_cast<s32>(s_last_ping_time.GetTimeSeconds()) >= ping_frequency)
|
||||
SendPing();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -714,7 +703,18 @@ void Achievements::ProcessPendingHTTPRequests()
|
|||
return;
|
||||
#endif
|
||||
|
||||
if (!s_http_downloader)
|
||||
return;
|
||||
|
||||
s_http_downloader->PollRequests();
|
||||
|
||||
if (HasActiveGame() && !IsTestModeActive())
|
||||
{
|
||||
const s32 ping_frequency =
|
||||
g_settings.achievements_rich_presence ? RICH_PRESENCE_PING_FREQUENCY : NO_RICH_PRESENCE_PING_FREQUENCY;
|
||||
if (static_cast<s32>(s_last_ping_time.GetTimeSeconds()) >= ping_frequency)
|
||||
SendPing();
|
||||
}
|
||||
}
|
||||
|
||||
bool Achievements::DoState(StateWrapper& sw)
|
||||
|
@ -1029,7 +1029,7 @@ void Achievements::DisplayAchievementSummary()
|
|||
|
||||
// Technically not going through the resource API, but since we're passing this to something else, we can't.
|
||||
if (g_settings.achievements_sound_effects)
|
||||
FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, INFO_SOUND_NAME).c_str());
|
||||
PlatformMisc::PlaySoundAsync(Path::Combine(EmuFolders::Resources, INFO_SOUND_NAME).c_str());
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1773,7 +1773,7 @@ void Achievements::SubmitLeaderboardCallback(s32 status_code, std::string conten
|
|||
|
||||
// Technically not going through the resource API, but since we're passing this to something else, we can't.
|
||||
if (g_settings.achievements_sound_effects)
|
||||
FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, LBSUBMIT_SOUND_NAME).c_str());
|
||||
PlatformMisc::PlaySoundAsync(Path::Combine(EmuFolders::Resources, LBSUBMIT_SOUND_NAME).c_str());
|
||||
}
|
||||
|
||||
void Achievements::UnlockAchievement(u32 achievement_id, bool add_notification /* = true*/)
|
||||
|
@ -1818,7 +1818,7 @@ void Achievements::UnlockAchievement(u32 achievement_id, bool add_notification /
|
|||
GetAchievementBadgePath(*achievement));
|
||||
}
|
||||
if (g_settings.achievements_sound_effects)
|
||||
FrontendCommon::PlaySoundAsync(Path::Combine(EmuFolders::Resources, UNLOCK_SOUND_NAME).c_str());
|
||||
PlatformMisc::PlaySoundAsync(Path::Combine(EmuFolders::Resources, UNLOCK_SOUND_NAME).c_str());
|
||||
|
||||
if (IsMastered())
|
||||
DisplayMasteredNotification();
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "settings.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "common/string.h"
|
||||
#include "common/types.h"
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class StateWrapper;
|
||||
class CDImage;
|
||||
|
@ -13,23 +22,157 @@ namespace Achievements {
|
|||
|
||||
#ifdef WITH_CHEEVOS
|
||||
|
||||
// Implemented in Host.
|
||||
extern bool ConfirmSystemReset();
|
||||
extern void ResetRuntime();
|
||||
extern bool DoState(StateWrapper& sw);
|
||||
extern void GameChanged(const std::string& path, CDImage* image);
|
||||
enum class AchievementCategory : u8
|
||||
{
|
||||
Local = 0,
|
||||
Core = 3,
|
||||
Unofficial = 5
|
||||
};
|
||||
|
||||
struct Achievement
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
std::string memaddr;
|
||||
std::string badge_name;
|
||||
|
||||
// badge paths are mutable because they're resolved when they're needed.
|
||||
mutable std::string locked_badge_path;
|
||||
mutable std::string unlocked_badge_path;
|
||||
|
||||
u32 points;
|
||||
AchievementCategory category;
|
||||
bool locked;
|
||||
bool active;
|
||||
bool primed;
|
||||
};
|
||||
|
||||
struct Leaderboard
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
int format;
|
||||
};
|
||||
|
||||
struct LeaderboardEntry
|
||||
{
|
||||
std::string user;
|
||||
std::string formatted_score;
|
||||
time_t submitted;
|
||||
u32 rank;
|
||||
bool is_self;
|
||||
};
|
||||
|
||||
// RAIntegration only exists for Windows, so no point checking it on other platforms.
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
|
||||
bool IsUsingRAIntegration();
|
||||
|
||||
#else
|
||||
|
||||
static ALWAYS_INLINE bool IsUsingRAIntegration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool IsActive();
|
||||
bool IsLoggedIn();
|
||||
bool ChallengeModeActive();
|
||||
bool LeaderboardsActive();
|
||||
bool IsTestModeActive();
|
||||
bool IsUnofficialTestModeActive();
|
||||
bool IsRichPresenceEnabled();
|
||||
bool HasActiveGame();
|
||||
|
||||
u32 GetGameID();
|
||||
|
||||
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
|
||||
std::unique_lock<std::recursive_mutex> GetLock();
|
||||
|
||||
void Initialize();
|
||||
void UpdateSettings(const Settings& old_config);
|
||||
void ResetRuntime();
|
||||
|
||||
/// Called when the system is being reset. If it returns false, the reset should be aborted.
|
||||
bool ConfirmSystemReset();
|
||||
|
||||
/// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted.
|
||||
bool Shutdown();
|
||||
|
||||
/// Called when the system is being paused and resumed.
|
||||
void OnSystemPaused(bool paused);
|
||||
|
||||
/// Called once a frame at vsync time on the CPU thread.
|
||||
void FrameUpdate();
|
||||
|
||||
/// Called when the system is paused, because FrameUpdate() won't be getting called.
|
||||
void ProcessPendingHTTPRequests();
|
||||
|
||||
/// Saves/loads state.
|
||||
bool DoState(StateWrapper& sw);
|
||||
|
||||
/// Returns true if the current game has any achievements or leaderboards.
|
||||
/// Does not need to have the lock held.
|
||||
bool SafeHasAchievementsOrLeaderboards();
|
||||
|
||||
const std::string& GetUsername();
|
||||
const std::string& GetRichPresenceString();
|
||||
|
||||
bool LoginAsync(const char* username, const char* password);
|
||||
bool Login(const char* username, const char* password);
|
||||
void Logout();
|
||||
|
||||
void GameChanged(const std::string& path, CDImage* image);
|
||||
|
||||
/// Re-enables hardcode mode if it is enabled in the settings.
|
||||
extern bool ResetChallengeMode();
|
||||
bool ResetChallengeMode();
|
||||
|
||||
/// Forces hardcore mode off until next reset.
|
||||
extern void DisableChallengeMode();
|
||||
void DisableChallengeMode();
|
||||
|
||||
/// Prompts the user to disable hardcore mode, if they agree, returns true.
|
||||
extern bool ConfirmChallengeModeDisable(const char* trigger);
|
||||
bool ConfirmChallengeModeDisable(const char* trigger);
|
||||
|
||||
/// Returns true if features such as save states should be disabled.
|
||||
extern bool ChallengeModeActive();
|
||||
bool ChallengeModeActive();
|
||||
|
||||
const std::string& GetGameTitle();
|
||||
const std::string& GetGameIcon();
|
||||
|
||||
bool EnumerateAchievements(std::function<bool(const Achievement&)> callback);
|
||||
u32 GetUnlockedAchiementCount();
|
||||
u32 GetAchievementCount();
|
||||
u32 GetMaximumPointsForGame();
|
||||
u32 GetCurrentPointsForGame();
|
||||
|
||||
bool EnumerateLeaderboards(std::function<bool(const Leaderboard&)> callback);
|
||||
std::optional<bool> TryEnumerateLeaderboardEntries(u32 id, std::function<bool(const LeaderboardEntry&)> callback);
|
||||
const Leaderboard* GetLeaderboardByID(u32 id);
|
||||
u32 GetLeaderboardCount();
|
||||
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
|
||||
u32 GetPrimedAchievementCount();
|
||||
|
||||
const Achievement* GetAchievementByID(u32 id);
|
||||
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
|
||||
TinyString GetAchievementProgressText(const Achievement& achievement);
|
||||
const std::string& GetAchievementBadgePath(const Achievement& achievement, bool download_if_missing = true,
|
||||
bool force_unlocked_icon = false);
|
||||
std::string GetAchievementBadgeURL(const Achievement& achievement);
|
||||
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
void SwitchToRAIntegration();
|
||||
|
||||
namespace RAIntegration {
|
||||
void MainWindowChanged(void* new_handle);
|
||||
void GameChanged();
|
||||
std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
|
||||
void ActivateMenuItem(int item);
|
||||
} // namespace RAIntegration
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
|
@ -38,7 +181,9 @@ static inline bool ConfirmSystemReset()
|
|||
{
|
||||
return true;
|
||||
}
|
||||
static inline void ResetRuntime() {}
|
||||
static inline void ResetRuntime()
|
||||
{
|
||||
}
|
||||
static inline bool DoState(StateWrapper& sw)
|
||||
{
|
||||
return true;
|
||||
|
@ -53,7 +198,9 @@ static inline bool ResetChallengeMode()
|
|||
return false;
|
||||
}
|
||||
|
||||
static inline void DisableChallengeMode() {}
|
||||
static inline void DisableChallengeMode()
|
||||
{
|
||||
}
|
||||
|
||||
static inline bool ConfirmChallengeModeDisable(const char* trigger)
|
||||
{
|
||||
|
@ -63,3 +210,9 @@ static inline bool ConfirmChallengeModeDisable(const char* trigger)
|
|||
#endif
|
||||
|
||||
} // namespace Achievements
|
||||
|
||||
/// Functions implemented in the frontend.
|
||||
namespace Host {
|
||||
void OnAchievementsRefreshed();
|
||||
void OnAchievementsChallengeModeChanged();
|
||||
} // namespace Host
|
||||
|
|
|
@ -1,178 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "achievements.h"
|
||||
#include "settings.h"
|
||||
#include "types.h"
|
||||
|
||||
#include "common/string.h"
|
||||
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class CDImage;
|
||||
class StateWrapper;
|
||||
|
||||
namespace Achievements {
|
||||
enum class AchievementCategory : u8
|
||||
{
|
||||
Local = 0,
|
||||
Core = 3,
|
||||
Unofficial = 5
|
||||
};
|
||||
|
||||
struct Achievement
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
std::string memaddr;
|
||||
std::string badge_name;
|
||||
|
||||
// badge paths are mutable because they're resolved when they're needed.
|
||||
mutable std::string locked_badge_path;
|
||||
mutable std::string unlocked_badge_path;
|
||||
|
||||
u32 points;
|
||||
AchievementCategory category;
|
||||
bool locked;
|
||||
bool active;
|
||||
bool primed;
|
||||
};
|
||||
|
||||
struct Leaderboard
|
||||
{
|
||||
u32 id;
|
||||
std::string title;
|
||||
std::string description;
|
||||
int format;
|
||||
};
|
||||
|
||||
struct LeaderboardEntry
|
||||
{
|
||||
std::string user;
|
||||
std::string formatted_score;
|
||||
time_t submitted;
|
||||
u32 rank;
|
||||
bool is_self;
|
||||
};
|
||||
|
||||
// RAIntegration only exists for Windows, so no point checking it on other platforms.
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
|
||||
bool IsUsingRAIntegration();
|
||||
|
||||
#else
|
||||
|
||||
static ALWAYS_INLINE bool IsUsingRAIntegration()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool IsActive();
|
||||
bool IsLoggedIn();
|
||||
bool ChallengeModeActive();
|
||||
bool LeaderboardsActive();
|
||||
bool IsTestModeActive();
|
||||
bool IsUnofficialTestModeActive();
|
||||
bool IsRichPresenceEnabled();
|
||||
bool HasActiveGame();
|
||||
|
||||
u32 GetGameID();
|
||||
|
||||
/// Acquires the achievements lock. Must be held when accessing any achievement state from another thread.
|
||||
std::unique_lock<std::recursive_mutex> GetLock();
|
||||
|
||||
void Initialize();
|
||||
void UpdateSettings(const Settings& old_config);
|
||||
|
||||
/// Called when the system is being reset. If it returns false, the reset should be aborted.
|
||||
bool ConfirmSystemReset();
|
||||
|
||||
/// Called when the system is being shut down. If Shutdown() returns false, the shutdown should be aborted.
|
||||
bool Shutdown();
|
||||
|
||||
/// Called when the system is being paused and resumed.
|
||||
void OnSystemPaused(bool paused);
|
||||
|
||||
/// Called once a frame at vsync time on the CPU thread.
|
||||
void FrameUpdate();
|
||||
|
||||
/// Called when the system is paused, because FrameUpdate() won't be getting called.
|
||||
void ProcessPendingHTTPRequests();
|
||||
|
||||
/// Saves/loads state.
|
||||
bool DoState(StateWrapper& sw);
|
||||
|
||||
/// Returns true if the current game has any achievements or leaderboards.
|
||||
/// Does not need to have the lock held.
|
||||
bool SafeHasAchievementsOrLeaderboards();
|
||||
|
||||
const std::string& GetUsername();
|
||||
const std::string& GetRichPresenceString();
|
||||
|
||||
bool LoginAsync(const char* username, const char* password);
|
||||
bool Login(const char* username, const char* password);
|
||||
void Logout();
|
||||
|
||||
void GameChanged(const std::string& path, CDImage* image);
|
||||
|
||||
/// Re-enables hardcode mode if it is enabled in the settings.
|
||||
bool ResetChallengeMode();
|
||||
|
||||
/// Forces hardcore mode off until next reset.
|
||||
void DisableChallengeMode();
|
||||
|
||||
/// Prompts the user to disable hardcore mode, if they agree, returns true.
|
||||
bool ConfirmChallengeModeDisable(const char* trigger);
|
||||
|
||||
/// Returns true if features such as save states should be disabled.
|
||||
bool ChallengeModeActive();
|
||||
|
||||
const std::string& GetGameTitle();
|
||||
const std::string& GetGameIcon();
|
||||
|
||||
bool EnumerateAchievements(std::function<bool(const Achievement&)> callback);
|
||||
u32 GetUnlockedAchiementCount();
|
||||
u32 GetAchievementCount();
|
||||
u32 GetMaximumPointsForGame();
|
||||
u32 GetCurrentPointsForGame();
|
||||
|
||||
bool EnumerateLeaderboards(std::function<bool(const Leaderboard&)> callback);
|
||||
std::optional<bool> TryEnumerateLeaderboardEntries(u32 id, std::function<bool(const LeaderboardEntry&)> callback);
|
||||
const Leaderboard* GetLeaderboardByID(u32 id);
|
||||
u32 GetLeaderboardCount();
|
||||
bool IsLeaderboardTimeType(const Leaderboard& leaderboard);
|
||||
u32 GetPrimedAchievementCount();
|
||||
|
||||
const Achievement* GetAchievementByID(u32 id);
|
||||
std::pair<u32, u32> GetAchievementProgress(const Achievement& achievement);
|
||||
TinyString GetAchievementProgressText(const Achievement& achievement);
|
||||
const std::string& GetAchievementBadgePath(const Achievement& achievement, bool download_if_missing = true,
|
||||
bool force_unlocked_icon = false);
|
||||
std::string GetAchievementBadgeURL(const Achievement& achievement);
|
||||
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
void SwitchToRAIntegration();
|
||||
|
||||
namespace RAIntegration {
|
||||
void MainWindowChanged(void* new_handle);
|
||||
void GameChanged();
|
||||
std::vector<std::tuple<int, std::string, bool>> GetMenuItems();
|
||||
void ActivateMenuItem(int item);
|
||||
} // namespace RAIntegration
|
||||
#endif
|
||||
} // namespace Achievements
|
||||
|
||||
/// Functions implemented in the frontend.
|
||||
namespace Host {
|
||||
void OnAchievementsRefreshed();
|
||||
void OnAchievementsChallengeModeChanged();
|
||||
} // namespace Host
|
|
@ -8,6 +8,7 @@
|
|||
#include "host.h"
|
||||
#include "settings.h"
|
||||
#include "system.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "util/state_wrapper.h"
|
||||
#include <cmath>
|
||||
Log_SetChannel(AnalogController);
|
||||
|
@ -348,7 +349,7 @@ void AnalogController::UpdateHostVibration()
|
|||
hvalues[motor] = (state != 0) ? static_cast<float>(strength / 65535.0) : 0.0f;
|
||||
}
|
||||
|
||||
Host::SetPadVibrationIntensity(m_index, hvalues[0], hvalues[1]);
|
||||
InputManager::SetPadVibrationIntensity(m_index, hvalues[0], hvalues[1]);
|
||||
}
|
||||
|
||||
u8 AnalogController::GetExtraButtonMaskLSB() const
|
||||
|
@ -820,7 +821,7 @@ static const Controller::ControllerBindingInfo s_binding_info[] = {
|
|||
AXIS("RRight", TRANSLATE_NOOP("AnalogController", "Right Stick Right"), AnalogController::HalfAxis::RRight, GenericInputBinding::RightStickRight),
|
||||
AXIS("RDown", TRANSLATE_NOOP("AnalogController", "Right Stick Down"), AnalogController::HalfAxis::RDown, GenericInputBinding::RightStickDown),
|
||||
AXIS("RUp", TRANSLATE_NOOP("AnalogController", "Right Stick Up"), AnalogController::HalfAxis::RUp, GenericInputBinding::RightStickUp),
|
||||
// clang-format on
|
||||
// clang-format on
|
||||
|
||||
#undef AXIS
|
||||
#undef BUTTON
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "common/path.h"
|
||||
#include "cpu_disasm.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "settings.h"
|
||||
#include <cerrno>
|
||||
Log_SetChannel(BIOS);
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "system.h"
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
class SettingsInterface;
|
||||
|
||||
class AudioStream;
|
||||
enum class AudioStretchMode : u8;
|
||||
|
||||
namespace CommonHost {
|
||||
/// Initializes configuration.
|
||||
void UpdateLogSettings();
|
||||
|
||||
void Initialize();
|
||||
void Shutdown();
|
||||
|
||||
void SetDefaultSettings(SettingsInterface& si);
|
||||
void SetDefaultControllerSettings(SettingsInterface& si);
|
||||
void SetDefaultHotkeyBindings(SettingsInterface& si);
|
||||
void LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock);
|
||||
void CheckForSettingsChanges(const Settings& old_settings);
|
||||
void OnSystemStarting();
|
||||
void OnSystemStarted();
|
||||
void OnSystemDestroyed();
|
||||
void OnSystemPaused();
|
||||
void OnSystemResumed();
|
||||
void OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name);
|
||||
void PumpMessagesOnCPUThread();
|
||||
|
||||
/// Returns the time elapsed in the current play session.
|
||||
u64 GetSessionPlayedTime();
|
||||
|
||||
} // namespace CommonHost
|
||||
|
||||
namespace ImGuiManager {
|
||||
void RenderDebugWindows();
|
||||
}
|
|
@ -10,7 +10,6 @@
|
|||
<ClCompile Include="cdrom.cpp" />
|
||||
<ClCompile Include="cdrom_async_reader.cpp" />
|
||||
<ClCompile Include="cheats.cpp" />
|
||||
<ClCompile Include="common_host.cpp" />
|
||||
<ClCompile Include="cpu_core.cpp" />
|
||||
<ClCompile Include="cpu_disasm.cpp" />
|
||||
<ClCompile Include="cpu_code_cache.cpp" />
|
||||
|
@ -49,7 +48,7 @@
|
|||
<ClCompile Include="gpu_hw.cpp" />
|
||||
<ClCompile Include="host.cpp" />
|
||||
<ClCompile Include="host_interface_progress_callback.cpp" />
|
||||
<ClCompile Include="host_settings.cpp" />
|
||||
<ClCompile Include="hotkeys.cpp" />
|
||||
<ClCompile Include="imgui_overlays.cpp" />
|
||||
<ClCompile Include="interrupt_controller.cpp" />
|
||||
<ClCompile Include="mdec.cpp" />
|
||||
|
@ -74,7 +73,6 @@
|
|||
<ClCompile Include="timing_event.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="achievements_private.h" />
|
||||
<ClInclude Include="analog_controller.h" />
|
||||
<ClInclude Include="analog_joystick.h" />
|
||||
<ClInclude Include="bios.h" />
|
||||
|
@ -83,7 +81,6 @@
|
|||
<ClInclude Include="cdrom_async_reader.h" />
|
||||
<ClInclude Include="cheats.h" />
|
||||
<ClInclude Include="achievements.h" />
|
||||
<ClInclude Include="common_host.h" />
|
||||
<ClInclude Include="cpu_core.h" />
|
||||
<ClInclude Include="cpu_core_private.h" />
|
||||
<ClInclude Include="cpu_disasm.h" />
|
||||
|
@ -118,7 +115,6 @@
|
|||
<ClInclude Include="gte_types.h" />
|
||||
<ClInclude Include="host.h" />
|
||||
<ClInclude Include="host_interface_progress_callback.h" />
|
||||
<ClInclude Include="host_settings.h" />
|
||||
<ClInclude Include="imgui_overlays.h" />
|
||||
<ClInclude Include="input_types.h" />
|
||||
<ClInclude Include="interrupt_controller.h" />
|
||||
|
|
|
@ -54,11 +54,10 @@
|
|||
<ClCompile Include="game_database.cpp" />
|
||||
<ClCompile Include="pcdrv.cpp" />
|
||||
<ClCompile Include="game_list.cpp" />
|
||||
<ClCompile Include="host_settings.cpp" />
|
||||
<ClCompile Include="imgui_overlays.cpp" />
|
||||
<ClCompile Include="fullscreen_ui.cpp" />
|
||||
<ClCompile Include="common_host.cpp" />
|
||||
<ClCompile Include="achievements.cpp" />
|
||||
<ClCompile Include="hotkeys.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="types.h" />
|
||||
|
@ -113,7 +112,6 @@
|
|||
<ClInclude Include="multitap.h" />
|
||||
<ClInclude Include="gdb_protocol.h" />
|
||||
<ClInclude Include="host.h" />
|
||||
<ClInclude Include="host_settings.h" />
|
||||
<ClInclude Include="achievements.h" />
|
||||
<ClInclude Include="game_database.h" />
|
||||
<ClInclude Include="input_types.h" />
|
||||
|
@ -121,8 +119,6 @@
|
|||
<ClInclude Include="game_list.h" />
|
||||
<ClInclude Include="imgui_overlays.h" />
|
||||
<ClInclude Include="fullscreen_ui.h" />
|
||||
<ClInclude Include="common_host.h" />
|
||||
<ClInclude Include="achievements_private.h" />
|
||||
<ClInclude Include="shader_cache_version.h" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -7,14 +7,12 @@
|
|||
#include "achievements.h"
|
||||
#include "bios.h"
|
||||
#include "cheats.h"
|
||||
#include "common_host.h"
|
||||
#include "controller.h"
|
||||
#include "core/memory_card_image.h"
|
||||
#include "cpu_core.h"
|
||||
#include "game_list.h"
|
||||
#include "gpu.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "resources.h"
|
||||
#include "settings.h"
|
||||
#include "system.h"
|
||||
|
@ -53,10 +51,6 @@
|
|||
|
||||
Log_SetChannel(FullscreenUI);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#include "achievements_private.h"
|
||||
#endif
|
||||
|
||||
#define TR_CONTEXT "FullscreenUI"
|
||||
|
||||
namespace {
|
||||
|
@ -3170,7 +3164,7 @@ void FullscreenUI::ResetControllerSettings()
|
|||
{
|
||||
SettingsInterface* dsi = GetEditingSettingsInterface();
|
||||
|
||||
CommonHost::SetDefaultControllerSettings(*dsi);
|
||||
Settings::SetDefaultControllerConfig(*dsi);
|
||||
ShowToast(std::string(), FSUI_STR("Controller settings reset to default."));
|
||||
}
|
||||
|
||||
|
@ -4831,7 +4825,7 @@ void FullscreenUI::DrawPauseMenu(MainWindowType type)
|
|||
if (!serial.empty())
|
||||
{
|
||||
const std::time_t cached_played_time = GameList::GetCachedPlayedTimeForSerial(serial);
|
||||
const std::time_t session_time = static_cast<std::time_t>(CommonHost::GetSessionPlayedTime());
|
||||
const std::time_t session_time = static_cast<std::time_t>(System::GetSessionPlayedTime());
|
||||
|
||||
buffer.Fmt(FSUI_FSTR("Session: {}"), GameList::FormatTimespan(session_time, true).GetStringView());
|
||||
const ImVec2 session_size(g_medium_font->CalcTextSizeA(g_medium_font->FontSize, std::numeric_limits<float>::max(),
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include "game_list.h"
|
||||
#include "bios.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "psf_loader.h"
|
||||
#include "settings.h"
|
||||
#include "system.h"
|
||||
|
|
|
@ -4,17 +4,19 @@
|
|||
#include "gdb_protocol.h"
|
||||
#include "bus.h"
|
||||
#include "cpu_core_private.h"
|
||||
#include "cpu_core.h"
|
||||
#include "system.h"
|
||||
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "cpu_core.h"
|
||||
#include "common_host.h"
|
||||
#include "system.h"
|
||||
|
||||
#include <functional>
|
||||
#include <iomanip>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
Log_SetChannel(GDBProtocol);
|
||||
|
||||
namespace GDBProtocol
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "host.h"
|
||||
#include "common_host.h"
|
||||
#include "fullscreen_ui.h"
|
||||
#include "imgui_overlays.h"
|
||||
#include "shader_cache_version.h"
|
||||
#include "system.h"
|
||||
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/imgui_manager.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/heterogeneous_containers.h"
|
||||
#include "common/layered_settings_interface.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
|
@ -23,6 +25,9 @@ namespace Host {
|
|||
static std::pair<const char*, u32> LookupTranslationString(const std::string_view& context,
|
||||
const std::string_view& msg);
|
||||
|
||||
static std::mutex s_settings_mutex;
|
||||
static LayeredSettingsInterface s_layered_settings_interface;
|
||||
|
||||
static constexpr u32 TRANSLATION_STRING_CACHE_SIZE = 4 * 1024 * 1024;
|
||||
using TranslationStringMap = UnorderedStringMap<std::pair<u32, u32>>;
|
||||
using TranslationStringContextMap = UnorderedStringMap<TranslationStringMap>;
|
||||
|
@ -32,6 +37,196 @@ static std::vector<char> s_translation_string_cache;
|
|||
static u32 s_translation_string_cache_pos;
|
||||
} // namespace Host
|
||||
|
||||
std::unique_lock<std::mutex> Host::GetSettingsLock()
|
||||
{
|
||||
return std::unique_lock<std::mutex>(s_settings_mutex);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::GetSettingsInterface()
|
||||
{
|
||||
return &s_layered_settings_interface;
|
||||
}
|
||||
|
||||
SettingsInterface* Host::GetSettingsInterfaceForBindings()
|
||||
{
|
||||
SettingsInterface* input_layer = s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
|
||||
return input_layer ? input_layer : &s_layered_settings_interface;
|
||||
}
|
||||
|
||||
std::string Host::GetBaseStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool Host::GetBaseBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->GetBoolValue(section, key, default_value);
|
||||
}
|
||||
|
||||
s32 Host::GetBaseIntSettingValue(const char* section, const char* key, s32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
u32 Host::GetBaseUIntSettingValue(const char* section, const char* key, u32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->GetUIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
float Host::GetBaseFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
double Host::GetBaseDoubleSettingValue(const char* section, const char* key, double default_value /* = 0.0f */)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->GetDoubleValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::vector<std::string> Host::GetBaseStringListSetting(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetStringList(section, key);
|
||||
}
|
||||
|
||||
std::string Host::GetStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool Host::GetBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetBoolValue(section, key, default_value);
|
||||
}
|
||||
|
||||
s32 Host::GetIntSettingValue(const char* section, const char* key, s32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
u32 Host::GetUIntSettingValue(const char* section, const char* key, u32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetUIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
float Host::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
double Host::GetDoubleSettingValue(const char* section, const char* key, double default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetDoubleValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::vector<std::string> Host::GetStringListSetting(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetStringList(section, key);
|
||||
}
|
||||
|
||||
void Host::SetBaseBoolSettingValue(const char* section, const char* key, bool value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetBoolValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseIntSettingValue(const char* section, const char* key, int value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetIntValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseFloatSettingValue(const char* section, const char* key, float value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetFloatValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseStringSettingValue(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringList(section, key, values);
|
||||
}
|
||||
|
||||
bool Host::AddValueToBaseStringListSetting(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->AddToStringList(section, key, value);
|
||||
}
|
||||
|
||||
bool Host::RemoveValueFromBaseStringListSetting(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->RemoveFromStringList(section, key, value);
|
||||
}
|
||||
|
||||
void Host::DeleteBaseSettingValue(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->DeleteValue(section, key);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetBaseSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetGameSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_GAME);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetInputSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
|
||||
}
|
||||
|
||||
void Host::Internal::SetBaseSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
AssertMsg(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE) == nullptr,
|
||||
"Base layer has not been set");
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_BASE, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::SetGameSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_GAME, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::SetInputSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_INPUT, sif);
|
||||
}
|
||||
|
||||
std::pair<const char*, u32> Host::LookupTranslationString(const std::string_view& context, const std::string_view& msg)
|
||||
{
|
||||
// TODO: TranslatableString, compile-time hashing.
|
||||
|
@ -162,6 +357,118 @@ void Host::ReportFormattedDebuggerMessage(const char* format, ...)
|
|||
ReportDebuggerMessage(message);
|
||||
}
|
||||
|
||||
bool Host::CreateGPUDevice(RenderAPI api)
|
||||
{
|
||||
DebugAssert(!g_gpu_device);
|
||||
|
||||
Log_InfoPrintf("Trying to create a %s GPU device...", GPUDevice::RenderAPIToString(api));
|
||||
g_gpu_device = GPUDevice::CreateDeviceForAPI(api);
|
||||
|
||||
// TODO: FSUI should always use vsync..
|
||||
const bool vsync = System::IsValid() ? System::ShouldUseVSync() : g_settings.video_sync_enabled;
|
||||
if (!g_gpu_device || !g_gpu_device->Create(g_settings.gpu_adapter,
|
||||
g_settings.gpu_disable_shader_cache ? std::string_view() :
|
||||
std::string_view(EmuFolders::Cache),
|
||||
SHADER_CACHE_VERSION, g_settings.gpu_use_debug_device, vsync,
|
||||
g_settings.gpu_threaded_presentation))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to initialize GPU device.");
|
||||
if (g_gpu_device)
|
||||
g_gpu_device->Destroy();
|
||||
g_gpu_device.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ImGuiManager::Initialize())
|
||||
{
|
||||
Log_ErrorPrintf("Failed to initialize ImGuiManager.");
|
||||
g_gpu_device->Destroy();
|
||||
g_gpu_device.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Host::UpdateDisplayWindow()
|
||||
{
|
||||
if (!g_gpu_device)
|
||||
return;
|
||||
|
||||
if (!g_gpu_device->UpdateWindow())
|
||||
{
|
||||
Host::ReportErrorAsync("Error", "Failed to change window after update. The log may contain more information.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiManager::WindowResized();
|
||||
|
||||
// If we're paused, re-present the current frame at the new window size.
|
||||
if (System::IsValid() && System::IsPaused())
|
||||
RenderDisplay(false);
|
||||
}
|
||||
|
||||
void Host::ResizeDisplayWindow(s32 width, s32 height, float scale)
|
||||
{
|
||||
if (!g_gpu_device)
|
||||
return;
|
||||
|
||||
Log_DevPrintf("Display window resized to %dx%d", width, height);
|
||||
|
||||
g_gpu_device->ResizeWindow(width, height, scale);
|
||||
ImGuiManager::WindowResized();
|
||||
|
||||
// If we're paused, re-present the current frame at the new window size.
|
||||
if (System::IsValid())
|
||||
{
|
||||
if (System::IsPaused())
|
||||
RenderDisplay(false);
|
||||
|
||||
System::HostDisplayResized();
|
||||
}
|
||||
}
|
||||
|
||||
void Host::ReleaseGPUDevice()
|
||||
{
|
||||
if (!g_gpu_device)
|
||||
return;
|
||||
|
||||
SaveStateSelectorUI::DestroyTextures();
|
||||
FullscreenUI::Shutdown();
|
||||
ImGuiManager::Shutdown();
|
||||
|
||||
Log_InfoPrintf("Destroying %s GPU device...", GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI()));
|
||||
g_gpu_device->Destroy();
|
||||
g_gpu_device.reset();
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
|
||||
std::unique_ptr<AudioStream> Host::CreateAudioStream(AudioBackend backend, u32 sample_rate, u32 channels, u32 buffer_ms,
|
||||
u32 latency_ms, AudioStretchMode stretch)
|
||||
{
|
||||
switch (backend)
|
||||
{
|
||||
#ifdef WITH_CUBEB
|
||||
case AudioBackend::Cubeb:
|
||||
return AudioStream::CreateCubebAudioStream(sample_rate, channels, buffer_ms, latency_ms, stretch);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
case AudioBackend::XAudio2:
|
||||
return AudioStream::CreateXAudio2Stream(sample_rate, channels, buffer_ms, latency_ms, stretch);
|
||||
#endif
|
||||
|
||||
case AudioBackend::Null:
|
||||
return AudioStream::CreateNullStream(sample_rate, channels, buffer_ms);
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Host::RenderDisplay(bool skip_present)
|
||||
{
|
||||
Host::BeginPresentFrame();
|
||||
|
|
|
@ -9,14 +9,17 @@
|
|||
#include <ctime>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
class SettingsInterface;
|
||||
struct WindowInfo;
|
||||
enum class AudioBackend : u8;
|
||||
enum class AudioStretchMode : u8;
|
||||
enum class RenderAPI : u32;
|
||||
class AudioStream;
|
||||
class CDImage;
|
||||
|
||||
|
@ -38,6 +41,46 @@ std::optional<std::string> ReadResourceFileToString(const char* filename);
|
|||
/// Returns the modified time of a resource.
|
||||
std::optional<std::time_t> GetResourceFileTimestamp(const char* filename);
|
||||
|
||||
// Base setting retrieval, bypasses layers.
|
||||
std::string GetBaseStringSettingValue(const char* section, const char* key, const char* default_value = "");
|
||||
bool GetBaseBoolSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
s32 GetBaseIntSettingValue(const char* section, const char* key, s32 default_value = 0);
|
||||
u32 GetBaseUIntSettingValue(const char* section, const char* key, u32 default_value = 0);
|
||||
float GetBaseFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
double GetBaseDoubleSettingValue(const char* section, const char* key, double default_value = 0.0);
|
||||
std::vector<std::string> GetBaseStringListSetting(const char* section, const char* key);
|
||||
|
||||
// Allows the emucore to write settings back to the frontend. Use with care.
|
||||
// You should call CommitBaseSettingChanges() if you directly write to the layer (i.e. not these functions), or it may
|
||||
// not be written to disk.
|
||||
void SetBaseBoolSettingValue(const char* section, const char* key, bool value);
|
||||
void SetBaseIntSettingValue(const char* section, const char* key, s32 value);
|
||||
void SetBaseUIntSettingValue(const char* section, const char* key, u32 value);
|
||||
void SetBaseFloatSettingValue(const char* section, const char* key, float value);
|
||||
void SetBaseStringSettingValue(const char* section, const char* key, const char* value);
|
||||
void SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
|
||||
bool AddValueToBaseStringListSetting(const char* section, const char* key, const char* value);
|
||||
bool RemoveValueFromBaseStringListSetting(const char* section, const char* key, const char* value);
|
||||
void DeleteBaseSettingValue(const char* section, const char* key);
|
||||
void CommitBaseSettingChanges();
|
||||
|
||||
// Settings access, thread-safe.
|
||||
std::string GetStringSettingValue(const char* section, const char* key, const char* default_value = "");
|
||||
bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
int GetIntSettingValue(const char* section, const char* key, s32 default_value = 0);
|
||||
u32 GetUIntSettingValue(const char* section, const char* key, u32 default_value = 0);
|
||||
float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
double GetDoubleSettingValue(const char* section, const char* key, double default_value = 0.0);
|
||||
std::vector<std::string> GetStringListSetting(const char* section, const char* key);
|
||||
|
||||
/// Direct access to settings interface. Must hold the lock when calling GetSettingsInterface() and while using it.
|
||||
std::unique_lock<std::mutex> GetSettingsLock();
|
||||
SettingsInterface* GetSettingsInterface();
|
||||
|
||||
/// Returns the settings interface that controller bindings should be loaded from.
|
||||
/// If an input profile is being used, this will be the input layer, otherwise the layered interface.
|
||||
SettingsInterface* GetSettingsInterfaceForBindings();
|
||||
|
||||
/// Returns a localized version of the specified string within the specified context.
|
||||
/// The pointer is guaranteed to be valid until the next language change.
|
||||
const char* TranslateToCString(const std::string_view& context, const std::string_view& msg);
|
||||
|
@ -85,10 +128,6 @@ void ReportFormattedDebuggerMessage(const char* format, ...);
|
|||
/// such as compiling shaders when starting up.
|
||||
void DisplayLoadingScreen(const char* message, int progress_min = -1, int progress_max = -1, int progress_value = -1);
|
||||
|
||||
/// Internal method used by pads to dispatch vibration updates to input sources.
|
||||
/// Intensity is normalized from 0 to 1.
|
||||
void SetPadVibrationIntensity(u32 pad_index, float large_or_single_motor_intensity, float small_motor_intensity);
|
||||
|
||||
/// Enables "relative" mouse mode, locking the cursor position and returning relative coordinates.
|
||||
void SetMouseMode(bool relative, bool hide_cursor);
|
||||
|
||||
|
@ -105,6 +144,18 @@ bool CopyTextToClipboard(const std::string_view& text);
|
|||
/// if the user cancels the shutdown confirmation.
|
||||
void RequestExit(bool allow_confirm);
|
||||
|
||||
/// Attempts to create the rendering device backend.
|
||||
bool CreateGPUDevice(RenderAPI api);
|
||||
|
||||
/// Handles fullscreen transitions and such.
|
||||
void UpdateDisplayWindow();
|
||||
|
||||
/// Called when the window is resized.
|
||||
void ResizeDisplayWindow(s32 width, s32 height, float scale);
|
||||
|
||||
/// Destroys any active rendering device.
|
||||
void ReleaseGPUDevice();
|
||||
|
||||
/// Called before drawing the OSD and other display elements.
|
||||
void BeginPresentFrame();
|
||||
|
||||
|
@ -113,6 +164,24 @@ void RenderDisplay(bool skip_present);
|
|||
void InvalidateDisplay();
|
||||
|
||||
namespace Internal {
|
||||
/// Retrieves the base settings layer. Must call with lock held.
|
||||
SettingsInterface* GetBaseSettingsLayer();
|
||||
|
||||
/// Retrieves the game settings layer, if present. Must call with lock held.
|
||||
SettingsInterface* GetGameSettingsLayer();
|
||||
|
||||
/// Retrieves the input settings layer, if present. Must call with lock held.
|
||||
SettingsInterface* GetInputSettingsLayer();
|
||||
|
||||
/// Sets the base settings layer. Should be called by the host at initialization time.
|
||||
void SetBaseSettingsLayer(SettingsInterface* sif);
|
||||
|
||||
/// Sets the game settings layer. Called by VMManager when the game changes.
|
||||
void SetGameSettingsLayer(SettingsInterface* sif);
|
||||
|
||||
/// Sets the input profile settings layer. Called by VMManager when the game changes.
|
||||
void SetInputSettingsLayer(SettingsInterface* sif);
|
||||
|
||||
/// Implementation to retrieve a translated string.
|
||||
s32 GetTranslatedStringImpl(const std::string_view& context, const std::string_view& msg, char* tbuf,
|
||||
size_t tbuf_space);
|
||||
|
|
|
@ -1,192 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/layered_settings_interface.h"
|
||||
|
||||
static std::mutex s_settings_mutex;
|
||||
static LayeredSettingsInterface s_layered_settings_interface;
|
||||
|
||||
std::unique_lock<std::mutex> Host::GetSettingsLock()
|
||||
{
|
||||
return std::unique_lock<std::mutex>(s_settings_mutex);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::GetSettingsInterface()
|
||||
{
|
||||
return &s_layered_settings_interface;
|
||||
}
|
||||
|
||||
SettingsInterface* Host::GetSettingsInterfaceForBindings()
|
||||
{
|
||||
SettingsInterface* input_layer = s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
|
||||
return input_layer ? input_layer : &s_layered_settings_interface;
|
||||
}
|
||||
|
||||
std::string Host::GetBaseStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool Host::GetBaseBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetBoolValue(section, key, default_value);
|
||||
}
|
||||
|
||||
s32 Host::GetBaseIntSettingValue(const char* section, const char* key, s32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
u32 Host::GetBaseUIntSettingValue(const char* section, const char* key, u32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetUIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
float Host::GetBaseFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
double Host::GetBaseDoubleSettingValue(const char* section, const char* key, double default_value /* = 0.0f */)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetDoubleValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::vector<std::string> Host::GetBaseStringListSetting(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->GetStringList(section, key);
|
||||
}
|
||||
|
||||
std::string Host::GetStringSettingValue(const char* section, const char* key, const char* default_value /*= ""*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetStringValue(section, key, default_value);
|
||||
}
|
||||
|
||||
bool Host::GetBoolSettingValue(const char* section, const char* key, bool default_value /*= false*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetBoolValue(section, key, default_value);
|
||||
}
|
||||
|
||||
s32 Host::GetIntSettingValue(const char* section, const char* key, s32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
u32 Host::GetUIntSettingValue(const char* section, const char* key, u32 default_value /*= 0*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetUIntValue(section, key, default_value);
|
||||
}
|
||||
|
||||
float Host::GetFloatSettingValue(const char* section, const char* key, float default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetFloatValue(section, key, default_value);
|
||||
}
|
||||
|
||||
double Host::GetDoubleSettingValue(const char* section, const char* key, double default_value /*= 0.0f*/)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetDoubleValue(section, key, default_value);
|
||||
}
|
||||
|
||||
std::vector<std::string> Host::GetStringListSetting(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetStringList(section, key);
|
||||
}
|
||||
|
||||
void Host::SetBaseBoolSettingValue(const char* section, const char* key, bool value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetBoolValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseIntSettingValue(const char* section, const char* key, int value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetIntValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseFloatSettingValue(const char* section, const char* key, float value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetFloatValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseStringSettingValue(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringValue(section, key, value);
|
||||
}
|
||||
|
||||
void Host::SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->SetStringList(section, key, values);
|
||||
}
|
||||
|
||||
bool Host::AddValueToBaseStringListSetting(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->AddToStringList(section, key, value);
|
||||
}
|
||||
|
||||
bool Host::RemoveValueFromBaseStringListSetting(const char* section, const char* key, const char* value)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)
|
||||
->RemoveFromStringList(section, key, value);
|
||||
}
|
||||
|
||||
void Host::DeleteBaseSettingValue(const char* section, const char* key)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE)->DeleteValue(section, key);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetBaseSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetGameSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_GAME);
|
||||
}
|
||||
|
||||
SettingsInterface* Host::Internal::GetInputSettingsLayer()
|
||||
{
|
||||
return s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_INPUT);
|
||||
}
|
||||
|
||||
void Host::Internal::SetBaseSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
AssertMsg(s_layered_settings_interface.GetLayer(LayeredSettingsInterface::LAYER_BASE) == nullptr, "Base layer has not been set");
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_BASE, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::SetGameSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_GAME, sif);
|
||||
}
|
||||
|
||||
void Host::Internal::SetInputSettingsLayer(SettingsInterface* sif)
|
||||
{
|
||||
std::unique_lock lock(s_settings_mutex);
|
||||
s_layered_settings_interface.SetLayer(LayeredSettingsInterface::LAYER_INPUT, sif);
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class SettingsInterface;
|
||||
|
||||
namespace Host {
|
||||
// Base setting retrieval, bypasses layers.
|
||||
std::string GetBaseStringSettingValue(const char* section, const char* key, const char* default_value = "");
|
||||
bool GetBaseBoolSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
s32 GetBaseIntSettingValue(const char* section, const char* key, s32 default_value = 0);
|
||||
u32 GetBaseUIntSettingValue(const char* section, const char* key, u32 default_value = 0);
|
||||
float GetBaseFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
double GetBaseDoubleSettingValue(const char* section, const char* key, double default_value = 0.0);
|
||||
std::vector<std::string> GetBaseStringListSetting(const char* section, const char* key);
|
||||
|
||||
// Allows the emucore to write settings back to the frontend. Use with care.
|
||||
// You should call CommitBaseSettingChanges() if you directly write to the layer (i.e. not these functions), or it may
|
||||
// not be written to disk.
|
||||
void SetBaseBoolSettingValue(const char* section, const char* key, bool value);
|
||||
void SetBaseIntSettingValue(const char* section, const char* key, s32 value);
|
||||
void SetBaseUIntSettingValue(const char* section, const char* key, u32 value);
|
||||
void SetBaseFloatSettingValue(const char* section, const char* key, float value);
|
||||
void SetBaseStringSettingValue(const char* section, const char* key, const char* value);
|
||||
void SetBaseStringListSettingValue(const char* section, const char* key, const std::vector<std::string>& values);
|
||||
bool AddValueToBaseStringListSetting(const char* section, const char* key, const char* value);
|
||||
bool RemoveValueFromBaseStringListSetting(const char* section, const char* key, const char* value);
|
||||
void DeleteBaseSettingValue(const char* section, const char* key);
|
||||
void CommitBaseSettingChanges();
|
||||
|
||||
// Settings access, thread-safe.
|
||||
std::string GetStringSettingValue(const char* section, const char* key, const char* default_value = "");
|
||||
bool GetBoolSettingValue(const char* section, const char* key, bool default_value = false);
|
||||
int GetIntSettingValue(const char* section, const char* key, s32 default_value = 0);
|
||||
u32 GetUIntSettingValue(const char* section, const char* key, u32 default_value = 0);
|
||||
float GetFloatSettingValue(const char* section, const char* key, float default_value = 0.0f);
|
||||
double GetDoubleSettingValue(const char* section, const char* key, double default_value = 0.0);
|
||||
std::vector<std::string> GetStringListSetting(const char* section, const char* key);
|
||||
|
||||
/// Direct access to settings interface. Must hold the lock when calling GetSettingsInterface() and while using it.
|
||||
std::unique_lock<std::mutex> GetSettingsLock();
|
||||
SettingsInterface* GetSettingsInterface();
|
||||
|
||||
/// Returns the settings interface that controller bindings should be loaded from.
|
||||
/// If an input profile is being used, this will be the input layer, otherwise the layered interface.
|
||||
SettingsInterface* GetSettingsInterfaceForBindings();
|
||||
|
||||
namespace Internal {
|
||||
/// Retrieves the base settings layer. Must call with lock held.
|
||||
SettingsInterface* GetBaseSettingsLayer();
|
||||
|
||||
/// Retrieves the game settings layer, if present. Must call with lock held.
|
||||
SettingsInterface* GetGameSettingsLayer();
|
||||
|
||||
/// Retrieves the input settings layer, if present. Must call with lock held.
|
||||
SettingsInterface* GetInputSettingsLayer();
|
||||
|
||||
/// Sets the base settings layer. Should be called by the host at initialization time.
|
||||
void SetBaseSettingsLayer(SettingsInterface* sif);
|
||||
|
||||
/// Sets the game settings layer. Called by VMManager when the game changes.
|
||||
void SetGameSettingsLayer(SettingsInterface* sif);
|
||||
|
||||
/// Sets the input profile settings layer. Called by VMManager when the game changes.
|
||||
void SetInputSettingsLayer(SettingsInterface* sif);
|
||||
} // namespace Internal
|
||||
} // namespace Host
|
|
@ -1,375 +1,28 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "common_host.h"
|
||||
#include "cdrom.h"
|
||||
#include "cheats.h"
|
||||
#include "controller.h"
|
||||
#include "cpu_code_cache.h"
|
||||
#include "dma.h"
|
||||
#include "cpu_core.h"
|
||||
#include "fullscreen_ui.h"
|
||||
#include "game_list.h"
|
||||
#include "gpu.h"
|
||||
#include "gte.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "imgui_overlays.h"
|
||||
#include "mdec.h"
|
||||
#include "pgxp.h"
|
||||
#include "resources.h"
|
||||
#include "save_state_version.h"
|
||||
#include "settings.h"
|
||||
#include "shader_cache_version.h"
|
||||
#include "spu.h"
|
||||
#include "system.h"
|
||||
#include "texture_replacements.h"
|
||||
#include "timers.h"
|
||||
|
||||
#include "scmversion/scmversion.h"
|
||||
|
||||
#include "util/audio_stream.h"
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/imgui_fullscreen.h"
|
||||
#include "util/imgui_manager.h"
|
||||
#include "util/ini_settings_interface.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "util/platform_misc.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/byte_stream.h"
|
||||
#include "common/crash_handler.h"
|
||||
#include "common/file_system.h"
|
||||
#include "common/log.h"
|
||||
#include "common/path.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
#include "IconsFontAwesome5.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
#include "discord_rpc.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#include "achievements_private.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/windows_headers.h"
|
||||
#include <KnownFolders.h>
|
||||
#include <ShlObj.h>
|
||||
#include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
Log_SetChannel(CommonHostInterface);
|
||||
|
||||
namespace CommonHost {
|
||||
static void UpdateSessionTime(const std::string& new_serial);
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
static void SetDiscordPresenceEnabled(bool enabled);
|
||||
static void InitializeDiscordPresence();
|
||||
static void ShutdownDiscordPresence();
|
||||
static void UpdateDiscordPresence(bool rich_presence_only);
|
||||
static void PollDiscordPresence();
|
||||
#endif
|
||||
} // namespace CommonHost
|
||||
|
||||
// Used to track play time. We use a monotonic timer here, in case of clock changes.
|
||||
static u64 s_session_start_time = 0;
|
||||
static std::string s_session_serial;
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
// discord rich presence
|
||||
bool m_discord_presence_enabled = false;
|
||||
bool m_discord_presence_active = false;
|
||||
#ifdef WITH_CHEEVOS
|
||||
std::string m_discord_presence_cheevos_string;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void CommonHost::Initialize()
|
||||
{
|
||||
// This will call back to Host::LoadSettings() -> ReloadSources().
|
||||
System::LoadSettings(false);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
if (Host::GetBaseBoolSettingValue("Cheevos", "UseRAIntegration", false))
|
||||
Achievements::SwitchToRAIntegration();
|
||||
#endif
|
||||
if (g_settings.achievements_enabled)
|
||||
Achievements::Initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::Shutdown()
|
||||
{
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
CommonHost::ShutdownDiscordPresence();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::Shutdown();
|
||||
#endif
|
||||
|
||||
InputManager::CloseSources();
|
||||
}
|
||||
|
||||
void CommonHost::PumpMessagesOnCPUThread()
|
||||
{
|
||||
InputManager::PollSources();
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
PollDiscordPresence();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::IsActive())
|
||||
Achievements::FrameUpdate();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Host::CreateGPUDevice(RenderAPI api)
|
||||
{
|
||||
DebugAssert(!g_gpu_device);
|
||||
|
||||
Log_InfoPrintf("Trying to create a %s GPU device...", GPUDevice::RenderAPIToString(api));
|
||||
g_gpu_device = GPUDevice::CreateDeviceForAPI(api);
|
||||
|
||||
// TODO: FSUI should always use vsync..
|
||||
const bool vsync = System::IsValid() ? System::ShouldUseVSync() : g_settings.video_sync_enabled;
|
||||
if (!g_gpu_device || !g_gpu_device->Create(g_settings.gpu_adapter,
|
||||
g_settings.gpu_disable_shader_cache ? std::string_view() :
|
||||
std::string_view(EmuFolders::Cache),
|
||||
SHADER_CACHE_VERSION, g_settings.gpu_use_debug_device, vsync,
|
||||
g_settings.gpu_threaded_presentation))
|
||||
{
|
||||
Log_ErrorPrintf("Failed to initialize GPU device.");
|
||||
if (g_gpu_device)
|
||||
g_gpu_device->Destroy();
|
||||
g_gpu_device.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!ImGuiManager::Initialize())
|
||||
{
|
||||
Log_ErrorPrintf("Failed to initialize ImGuiManager.");
|
||||
g_gpu_device->Destroy();
|
||||
g_gpu_device.reset();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Host::UpdateDisplayWindow()
|
||||
{
|
||||
if (!g_gpu_device)
|
||||
return;
|
||||
|
||||
if (!g_gpu_device->UpdateWindow())
|
||||
{
|
||||
Host::ReportErrorAsync("Error", "Failed to change window after update. The log may contain more information.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiManager::WindowResized();
|
||||
|
||||
// If we're paused, re-present the current frame at the new window size.
|
||||
if (System::IsValid() && System::IsPaused())
|
||||
RenderDisplay(false);
|
||||
}
|
||||
|
||||
void Host::ResizeDisplayWindow(s32 width, s32 height, float scale)
|
||||
{
|
||||
if (!g_gpu_device)
|
||||
return;
|
||||
|
||||
Log_DevPrintf("Display window resized to %dx%d", width, height);
|
||||
|
||||
g_gpu_device->ResizeWindow(width, height, scale);
|
||||
ImGuiManager::WindowResized();
|
||||
|
||||
// If we're paused, re-present the current frame at the new window size.
|
||||
if (System::IsValid())
|
||||
{
|
||||
if (System::IsPaused())
|
||||
RenderDisplay(false);
|
||||
|
||||
System::HostDisplayResized();
|
||||
}
|
||||
}
|
||||
|
||||
void Host::ReleaseGPUDevice()
|
||||
{
|
||||
if (!g_gpu_device)
|
||||
return;
|
||||
|
||||
SaveStateSelectorUI::DestroyTextures();
|
||||
FullscreenUI::Shutdown();
|
||||
ImGuiManager::Shutdown();
|
||||
|
||||
Log_InfoPrintf("Destroying %s GPU device...", GPUDevice::RenderAPIToString(g_gpu_device->GetRenderAPI()));
|
||||
g_gpu_device->Destroy();
|
||||
g_gpu_device.reset();
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
|
||||
std::unique_ptr<AudioStream> Host::CreateAudioStream(AudioBackend backend, u32 sample_rate, u32 channels, u32 buffer_ms,
|
||||
u32 latency_ms, AudioStretchMode stretch)
|
||||
{
|
||||
switch (backend)
|
||||
{
|
||||
#ifdef WITH_CUBEB
|
||||
case AudioBackend::Cubeb:
|
||||
return AudioStream::CreateCubebAudioStream(sample_rate, channels, buffer_ms, latency_ms, stretch);
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
case AudioBackend::XAudio2:
|
||||
return AudioStream::CreateXAudio2Stream(sample_rate, channels, buffer_ms, latency_ms, stretch);
|
||||
#endif
|
||||
|
||||
case AudioBackend::Null:
|
||||
return AudioStream::CreateNullStream(sample_rate, channels, buffer_ms);
|
||||
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void CommonHost::UpdateLogSettings()
|
||||
{
|
||||
Log::SetFilterLevel(g_settings.log_level);
|
||||
Log::SetConsoleOutputParams(g_settings.log_to_console,
|
||||
g_settings.log_filter.empty() ? nullptr : g_settings.log_filter.c_str(),
|
||||
g_settings.log_level);
|
||||
Log::SetDebugOutputParams(g_settings.log_to_debug,
|
||||
g_settings.log_filter.empty() ? nullptr : g_settings.log_filter.c_str(),
|
||||
g_settings.log_level);
|
||||
|
||||
if (g_settings.log_to_file)
|
||||
{
|
||||
Log::SetFileOutputParams(g_settings.log_to_file, Path::Combine(EmuFolders::DataRoot, "duckstation.log").c_str(),
|
||||
true, g_settings.log_filter.empty() ? nullptr : g_settings.log_filter.c_str(),
|
||||
g_settings.log_level);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::SetFileOutputParams(false, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void CommonHost::OnSystemStarting()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
void CommonHost::OnSystemStarted()
|
||||
{
|
||||
FullscreenUI::OnSystemStarted();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
FrontendCommon::SuspendScreensaver();
|
||||
}
|
||||
|
||||
void CommonHost::OnSystemPaused()
|
||||
{
|
||||
FullscreenUI::OnSystemPaused();
|
||||
|
||||
InputManager::PauseVibration();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::OnSystemPaused(true);
|
||||
#endif
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
FrontendCommon::ResumeScreensaver();
|
||||
}
|
||||
|
||||
void CommonHost::OnSystemResumed()
|
||||
{
|
||||
FullscreenUI::OnSystemResumed();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::OnSystemPaused(false);
|
||||
#endif
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
FrontendCommon::SuspendScreensaver();
|
||||
}
|
||||
|
||||
void CommonHost::OnSystemDestroyed()
|
||||
{
|
||||
Host::ClearOSDMessages();
|
||||
|
||||
SaveStateSelectorUI::Close(true);
|
||||
FullscreenUI::OnSystemDestroyed();
|
||||
|
||||
InputManager::PauseVibration();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
FrontendCommon::ResumeScreensaver();
|
||||
}
|
||||
|
||||
void CommonHost::OnGameChanged(const std::string& disc_path, const std::string& game_serial,
|
||||
const std::string& game_name)
|
||||
{
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
UpdateDiscordPresence(false);
|
||||
#endif
|
||||
|
||||
UpdateSessionTime(game_serial);
|
||||
|
||||
SaveStateSelectorUI::RefreshList();
|
||||
}
|
||||
|
||||
void CommonHost::SetDefaultSettings(SettingsInterface& si)
|
||||
{
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
si.SetBoolValue("Main", "EnableDiscordPresence", false);
|
||||
#endif
|
||||
|
||||
#if defined(WITH_CHEEVOS) && defined(WITH_RAINTEGRATION)
|
||||
si.SetBoolValue("Cheevos", "UseRAIntegration", false);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::SetDefaultControllerSettings(SettingsInterface& si)
|
||||
{
|
||||
InputManager::SetDefaultConfig(si);
|
||||
|
||||
// Global Settings
|
||||
si.SetStringValue("ControllerPorts", "MultitapMode", Settings::GetMultitapModeName(Settings::DEFAULT_MULTITAP_MODE));
|
||||
si.SetFloatValue("ControllerPorts", "PointerXScale", 8.0f);
|
||||
si.SetFloatValue("ControllerPorts", "PointerYScale", 8.0f);
|
||||
si.SetBoolValue("ControllerPorts", "PointerXInvert", false);
|
||||
si.SetBoolValue("ControllerPorts", "PointerYInvert", false);
|
||||
|
||||
// Default pad types and parameters.
|
||||
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
||||
{
|
||||
const std::string section(Controller::GetSettingsSection(i));
|
||||
si.ClearSection(section.c_str());
|
||||
si.SetStringValue(section.c_str(), "Type", Controller::GetDefaultPadType(i));
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
// Use the automapper to set this up.
|
||||
InputManager::MapController(si, 0, InputManager::GetGenericBindingMapping("Keyboard"));
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::SetDefaultHotkeyBindings(SettingsInterface& si)
|
||||
void Settings::SetDefaultHotkeyConfig(SettingsInterface& si)
|
||||
{
|
||||
si.ClearSection("Hotkeys");
|
||||
|
||||
|
@ -387,276 +40,6 @@ void CommonHost::SetDefaultHotkeyBindings(SettingsInterface& si)
|
|||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
UpdateLogSettings();
|
||||
InputManager::ReloadSources(si, lock);
|
||||
InputManager::ReloadBindings(si, *Host::GetSettingsInterfaceForBindings());
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
SetDiscordPresenceEnabled(si.GetBoolValue("Main", "EnableDiscordPresence", false));
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::CheckForSettingsChanges(const Settings& old_settings)
|
||||
{
|
||||
if (System::IsValid())
|
||||
{
|
||||
if (g_settings.inhibit_screensaver != old_settings.inhibit_screensaver)
|
||||
{
|
||||
if (g_settings.inhibit_screensaver)
|
||||
FrontendCommon::SuspendScreensaver();
|
||||
else
|
||||
FrontendCommon::ResumeScreensaver();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::UpdateSettings(old_settings);
|
||||
#endif
|
||||
|
||||
FullscreenUI::CheckForConfigChanges(old_settings);
|
||||
|
||||
if (g_settings.log_level != old_settings.log_level || g_settings.log_filter != old_settings.log_filter ||
|
||||
g_settings.log_to_console != old_settings.log_to_console ||
|
||||
g_settings.log_to_debug != old_settings.log_to_debug || g_settings.log_to_window != old_settings.log_to_window ||
|
||||
g_settings.log_to_file != old_settings.log_to_file)
|
||||
{
|
||||
UpdateLogSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void CommonHost::UpdateSessionTime(const std::string& new_serial)
|
||||
{
|
||||
if (s_session_serial == new_serial)
|
||||
return;
|
||||
|
||||
const u64 ctime = Common::Timer::GetCurrentValue();
|
||||
if (!s_session_serial.empty())
|
||||
{
|
||||
// round up to seconds
|
||||
const std::time_t etime =
|
||||
static_cast<std::time_t>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
|
||||
const std::time_t wtime = std::time(nullptr);
|
||||
GameList::AddPlayedTimeForSerial(s_session_serial, wtime, etime);
|
||||
}
|
||||
|
||||
s_session_serial = new_serial;
|
||||
s_session_start_time = ctime;
|
||||
}
|
||||
|
||||
u64 CommonHost::GetSessionPlayedTime()
|
||||
{
|
||||
const u64 ctime = Common::Timer::GetCurrentValue();
|
||||
return static_cast<u64>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
|
||||
}
|
||||
|
||||
void Host::SetPadVibrationIntensity(u32 pad_index, float large_or_single_motor_intensity, float small_motor_intensity)
|
||||
{
|
||||
InputManager::SetPadVibrationIntensity(pad_index, large_or_single_motor_intensity, small_motor_intensity);
|
||||
}
|
||||
|
||||
void Host::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/, int progress_max /*= -1*/,
|
||||
int progress_value /*= -1*/)
|
||||
{
|
||||
const auto& io = ImGui::GetIO();
|
||||
const float scale = ImGuiManager::GetGlobalScale();
|
||||
const float width = (400.0f * scale);
|
||||
const bool has_progress = (progress_min < progress_max);
|
||||
|
||||
// eat the last imgui frame, it might've been partially rendered by the caller.
|
||||
ImGui::EndFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
const float logo_width = 260.0f * scale;
|
||||
const float logo_height = 260.0f * scale;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(logo_width, logo_height), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, (io.DisplaySize.y * 0.5f) - (50.0f * scale)),
|
||||
ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
if (ImGui::Begin("LoadingScreenLogo", nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoBackground))
|
||||
{
|
||||
GPUTexture* tex = ImGuiFullscreen::GetCachedTexture("images/duck.png");
|
||||
if (tex)
|
||||
ImGui::Image(tex, ImVec2(logo_width, logo_height));
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
const float padding_and_rounding = 15.0f * scale;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, padding_and_rounding);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(padding_and_rounding, padding_and_rounding));
|
||||
ImGui::SetNextWindowSize(ImVec2(width, (has_progress ? 80.0f : 50.0f) * scale), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, (io.DisplaySize.y * 0.5f) + (100.0f * scale)),
|
||||
ImGuiCond_Always, ImVec2(0.5f, 0.0f));
|
||||
if (ImGui::Begin("LoadingScreen", nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing))
|
||||
{
|
||||
if (has_progress)
|
||||
{
|
||||
ImGui::TextUnformatted(message);
|
||||
|
||||
TinyString buf;
|
||||
buf.Fmt("{}/{}", progress_value, progress_max);
|
||||
|
||||
const ImVec2 prog_size = ImGui::CalcTextSize(buf.GetCharArray(), buf.GetCharArray() + buf.GetLength());
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(width - padding_and_rounding - prog_size.x);
|
||||
ImGui::TextUnformatted(buf.GetCharArray(), buf.GetCharArray() + buf.GetLength());
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5.0f);
|
||||
|
||||
ImGui::ProgressBar(static_cast<float>(progress_value) / static_cast<float>(progress_max - progress_min),
|
||||
ImVec2(-1.0f, 0.0f), "");
|
||||
Log_InfoPrintf("%s: %d/%d", message, progress_value, progress_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
const ImVec2 text_size(ImGui::CalcTextSize(message));
|
||||
ImGui::SetCursorPosX((width - text_size.x) / 2.0f);
|
||||
ImGui::TextUnformatted(message);
|
||||
Log_InfoPrintf("%s", message);
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
ImGui::EndFrame();
|
||||
g_gpu_device->Render(false);
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void ImGuiManager::RenderDebugWindows()
|
||||
{
|
||||
if (System::IsValid())
|
||||
{
|
||||
if (g_settings.debugging.show_gpu_state)
|
||||
g_gpu->DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_cdrom_state)
|
||||
CDROM::DrawDebugWindow();
|
||||
if (g_settings.debugging.show_timers_state)
|
||||
Timers::DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_spu_state)
|
||||
SPU::DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_mdec_state)
|
||||
MDEC::DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_dma_state)
|
||||
DMA::DrawDebugStateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
|
||||
void CommonHost::SetDiscordPresenceEnabled(bool enabled)
|
||||
{
|
||||
if (m_discord_presence_enabled == enabled)
|
||||
return;
|
||||
|
||||
m_discord_presence_enabled = enabled;
|
||||
if (enabled)
|
||||
InitializeDiscordPresence();
|
||||
else
|
||||
ShutdownDiscordPresence();
|
||||
}
|
||||
|
||||
void CommonHost::InitializeDiscordPresence()
|
||||
{
|
||||
if (m_discord_presence_active)
|
||||
return;
|
||||
|
||||
DiscordEventHandlers handlers = {};
|
||||
Discord_Initialize("705325712680288296", &handlers, 0, nullptr);
|
||||
m_discord_presence_active = true;
|
||||
|
||||
UpdateDiscordPresence(false);
|
||||
}
|
||||
|
||||
void CommonHost::ShutdownDiscordPresence()
|
||||
{
|
||||
if (!m_discord_presence_active)
|
||||
return;
|
||||
|
||||
Discord_ClearPresence();
|
||||
Discord_Shutdown();
|
||||
m_discord_presence_active = false;
|
||||
#ifdef WITH_CHEEVOS
|
||||
m_discord_presence_cheevos_string.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CommonHost::UpdateDiscordPresence(bool rich_presence_only)
|
||||
{
|
||||
if (!m_discord_presence_active)
|
||||
return;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
// Update only if RetroAchievements rich presence has changed
|
||||
const std::string& new_rich_presence = Achievements::GetRichPresenceString();
|
||||
if (new_rich_presence == m_discord_presence_cheevos_string && rich_presence_only)
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_discord_presence_cheevos_string = new_rich_presence;
|
||||
#else
|
||||
if (rich_presence_only)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields
|
||||
DiscordRichPresence rp = {};
|
||||
rp.largeImageKey = "duckstation_logo";
|
||||
rp.largeImageText = "DuckStation PS1/PSX Emulator";
|
||||
rp.startTimestamp = std::time(nullptr);
|
||||
|
||||
SmallString details_string;
|
||||
if (!System::IsShutdown())
|
||||
{
|
||||
details_string.AppendFormattedString("%s (%s)", System::GetGameTitle().c_str(), System::GetGameSerial().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
details_string.AppendString("No Game Running");
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
SmallString state_string;
|
||||
// Trim to 128 bytes as per Discord-RPC requirements
|
||||
if (m_discord_presence_cheevos_string.length() >= 128)
|
||||
{
|
||||
// 124 characters + 3 dots + null terminator
|
||||
state_string = m_discord_presence_cheevos_string.substr(0, 124);
|
||||
state_string.AppendString("...");
|
||||
}
|
||||
else
|
||||
{
|
||||
state_string = m_discord_presence_cheevos_string;
|
||||
}
|
||||
|
||||
rp.state = state_string;
|
||||
#endif
|
||||
rp.details = details_string;
|
||||
|
||||
Discord_UpdatePresence(&rp);
|
||||
}
|
||||
|
||||
void CommonHost::PollDiscordPresence()
|
||||
{
|
||||
if (!m_discord_presence_active)
|
||||
return;
|
||||
|
||||
UpdateDiscordPresence(true);
|
||||
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void HotkeyModifyResolutionScale(s32 increment)
|
||||
{
|
||||
const u32 new_resolution_scale = std::clamp<u32>(
|
|
@ -1,12 +1,14 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "imgui_overlays.h"
|
||||
#include "cdrom.h"
|
||||
#include "controller.h"
|
||||
#include "dma.h"
|
||||
#include "fullscreen_ui.h"
|
||||
#include "gpu.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "mdec.h"
|
||||
#include "resources.h"
|
||||
#include "settings.h"
|
||||
#include "spu.h"
|
||||
|
@ -131,6 +133,99 @@ static std::tuple<float, float> GetMinMax(gsl::span<const float> values)
|
|||
|
||||
static bool s_save_state_selector_ui_open = false;
|
||||
|
||||
void Host::DisplayLoadingScreen(const char* message, int progress_min /*= -1*/, int progress_max /*= -1*/,
|
||||
int progress_value /*= -1*/)
|
||||
{
|
||||
const auto& io = ImGui::GetIO();
|
||||
const float scale = ImGuiManager::GetGlobalScale();
|
||||
const float width = (400.0f * scale);
|
||||
const bool has_progress = (progress_min < progress_max);
|
||||
|
||||
// eat the last imgui frame, it might've been partially rendered by the caller.
|
||||
ImGui::EndFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
const float logo_width = 260.0f * scale;
|
||||
const float logo_height = 260.0f * scale;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(logo_width, logo_height), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, (io.DisplaySize.y * 0.5f) - (50.0f * scale)),
|
||||
ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
if (ImGui::Begin("LoadingScreenLogo", nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing |
|
||||
ImGuiWindowFlags_NoBackground))
|
||||
{
|
||||
GPUTexture* tex = ImGuiFullscreen::GetCachedTexture("images/duck.png");
|
||||
if (tex)
|
||||
ImGui::Image(tex, ImVec2(logo_width, logo_height));
|
||||
}
|
||||
ImGui::End();
|
||||
|
||||
const float padding_and_rounding = 15.0f * scale;
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, padding_and_rounding);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(padding_and_rounding, padding_and_rounding));
|
||||
ImGui::SetNextWindowSize(ImVec2(width, (has_progress ? 80.0f : 50.0f) * scale), ImGuiCond_Always);
|
||||
ImGui::SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, (io.DisplaySize.y * 0.5f) + (100.0f * scale)),
|
||||
ImGuiCond_Always, ImVec2(0.5f, 0.0f));
|
||||
if (ImGui::Begin("LoadingScreen", nullptr,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoNav |
|
||||
ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoFocusOnAppearing))
|
||||
{
|
||||
if (has_progress)
|
||||
{
|
||||
ImGui::TextUnformatted(message);
|
||||
|
||||
TinyString buf;
|
||||
buf.Fmt("{}/{}", progress_value, progress_max);
|
||||
|
||||
const ImVec2 prog_size = ImGui::CalcTextSize(buf.GetCharArray(), buf.GetCharArray() + buf.GetLength());
|
||||
ImGui::SameLine();
|
||||
ImGui::SetCursorPosX(width - padding_and_rounding - prog_size.x);
|
||||
ImGui::TextUnformatted(buf.GetCharArray(), buf.GetCharArray() + buf.GetLength());
|
||||
ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 5.0f);
|
||||
|
||||
ImGui::ProgressBar(static_cast<float>(progress_value) / static_cast<float>(progress_max - progress_min),
|
||||
ImVec2(-1.0f, 0.0f), "");
|
||||
Log_InfoPrintf("%s: %d/%d", message, progress_value, progress_max);
|
||||
}
|
||||
else
|
||||
{
|
||||
const ImVec2 text_size(ImGui::CalcTextSize(message));
|
||||
ImGui::SetCursorPosX((width - text_size.x) / 2.0f);
|
||||
ImGui::TextUnformatted(message);
|
||||
Log_InfoPrintf("%s", message);
|
||||
}
|
||||
}
|
||||
ImGui::End();
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
ImGui::EndFrame();
|
||||
g_gpu_device->Render(false);
|
||||
ImGui::NewFrame();
|
||||
}
|
||||
|
||||
void ImGuiManager::RenderDebugWindows()
|
||||
{
|
||||
if (System::IsValid())
|
||||
{
|
||||
if (g_settings.debugging.show_gpu_state)
|
||||
g_gpu->DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_cdrom_state)
|
||||
CDROM::DrawDebugWindow();
|
||||
if (g_settings.debugging.show_timers_state)
|
||||
Timers::DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_spu_state)
|
||||
SPU::DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_mdec_state)
|
||||
MDEC::DrawDebugStateWindow();
|
||||
if (g_settings.debugging.show_dma_state)
|
||||
DMA::DrawDebugStateWindow();
|
||||
}
|
||||
}
|
||||
|
||||
void ImGuiManager::RenderTextOverlays()
|
||||
{
|
||||
const System::State state = System::GetState();
|
||||
|
|
|
@ -7,8 +7,9 @@
|
|||
|
||||
namespace ImGuiManager {
|
||||
void RenderTextOverlays();
|
||||
void RenderDebugWindows();
|
||||
void RenderOverlayWindows();
|
||||
}
|
||||
} // namespace ImGuiManager
|
||||
|
||||
namespace SaveStateSelectorUI {
|
||||
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#include "achievements.h"
|
||||
#include "controller.h"
|
||||
#include "host.h"
|
||||
#include "host_settings.h"
|
||||
#include "system.h"
|
||||
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/input_manager.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/file_system.h"
|
||||
|
@ -182,6 +182,7 @@ void Settings::Load(SettingsInterface& si)
|
|||
apply_game_settings = si.GetBoolValue("Main", "ApplyGameSettings", true);
|
||||
auto_load_cheats = si.GetBoolValue("Main", "AutoLoadCheats", true);
|
||||
disable_all_enhancements = si.GetBoolValue("Main", "DisableAllEnhancements", false);
|
||||
enable_discord_presence = si.GetBoolValue("Main", "EnableDiscordPresence", false);
|
||||
rewind_enable = si.GetBoolValue("Main", "RewindEnable", false);
|
||||
rewind_save_frequency = si.GetFloatValue("Main", "RewindFrequency", 10.0f);
|
||||
rewind_save_slots = static_cast<u32>(si.GetIntValue("Main", "RewindSaveSlots", 10));
|
||||
|
@ -369,6 +370,7 @@ void Settings::Load(SettingsInterface& si)
|
|||
achievements_notifications = si.GetBoolValue("Cheevos", "Notifications", true);
|
||||
achievements_sound_effects = si.GetBoolValue("Cheevos", "SoundEffects", true);
|
||||
achievements_primed_indicators = si.GetBoolValue("Cheevos", "PrimedIndicators", true);
|
||||
achievements_use_raintegration = si.GetBoolValue("Cheevos", "UseRAIntegration", false);
|
||||
|
||||
log_level = ParseLogLevelName(si.GetStringValue("Logging", "LogLevel", GetLogLevelName(DEFAULT_LOG_LEVEL)).c_str())
|
||||
.value_or(DEFAULT_LOG_LEVEL);
|
||||
|
@ -426,6 +428,7 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetBoolValue("Main", "ApplyGameSettings", apply_game_settings);
|
||||
si.SetBoolValue("Main", "AutoLoadCheats", auto_load_cheats);
|
||||
si.SetBoolValue("Main", "DisableAllEnhancements", disable_all_enhancements);
|
||||
si.SetBoolValue("Main", "EnableDiscordPresence", enable_discord_presence);
|
||||
si.SetBoolValue("Main", "RewindEnable", rewind_enable);
|
||||
si.SetFloatValue("Main", "RewindFrequency", rewind_save_frequency);
|
||||
si.SetIntValue("Main", "RewindSaveSlots", rewind_save_slots);
|
||||
|
@ -565,6 +568,7 @@ void Settings::Save(SettingsInterface& si) const
|
|||
si.SetBoolValue("Cheevos", "Notifications", achievements_notifications);
|
||||
si.SetBoolValue("Cheevos", "SoundEffects", achievements_sound_effects);
|
||||
si.SetBoolValue("Cheevos", "PrimedIndicators", achievements_primed_indicators);
|
||||
si.SetBoolValue("Cheevos", "UseRAIntegration", achievements_use_raintegration);
|
||||
|
||||
si.SetStringValue("Logging", "LogLevel", GetLogLevelName(log_level));
|
||||
si.SetStringValue("Logging", "LogFilter", log_filter.c_str());
|
||||
|
@ -726,6 +730,46 @@ void Settings::FixIncompatibleSettings(bool display_osd_messages)
|
|||
}
|
||||
}
|
||||
|
||||
void Settings::UpdateLogSettings()
|
||||
{
|
||||
Log::SetFilterLevel(log_level);
|
||||
Log::SetConsoleOutputParams(log_to_console, log_filter.empty() ? nullptr : log_filter.c_str(), log_level);
|
||||
Log::SetDebugOutputParams(log_to_debug, log_filter.empty() ? nullptr : log_filter.c_str(), log_level);
|
||||
|
||||
if (log_to_file)
|
||||
{
|
||||
Log::SetFileOutputParams(log_to_file, Path::Combine(EmuFolders::DataRoot, "duckstation.log").c_str(), true,
|
||||
log_filter.empty() ? nullptr : log_filter.c_str(), log_level);
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::SetFileOutputParams(false, nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
void Settings::SetDefaultControllerConfig(SettingsInterface& si)
|
||||
{
|
||||
// Global Settings
|
||||
si.SetStringValue("ControllerPorts", "MultitapMode", GetMultitapModeName(Settings::DEFAULT_MULTITAP_MODE));
|
||||
si.SetFloatValue("ControllerPorts", "PointerXScale", 8.0f);
|
||||
si.SetFloatValue("ControllerPorts", "PointerYScale", 8.0f);
|
||||
si.SetBoolValue("ControllerPorts", "PointerXInvert", false);
|
||||
si.SetBoolValue("ControllerPorts", "PointerYInvert", false);
|
||||
|
||||
// Default pad types and parameters.
|
||||
for (u32 i = 0; i < NUM_CONTROLLER_AND_CARD_PORTS; i++)
|
||||
{
|
||||
const std::string section(Controller::GetSettingsSection(i));
|
||||
si.ClearSection(section.c_str());
|
||||
si.SetStringValue(section.c_str(), "Type", Controller::GetDefaultPadType(i));
|
||||
}
|
||||
|
||||
#ifndef __ANDROID__
|
||||
// Use the automapper to set this up.
|
||||
InputManager::MapController(si, 0, InputManager::GetGenericBindingMapping("Keyboard"));
|
||||
#endif
|
||||
}
|
||||
|
||||
static std::array<const char*, LOGLEVEL_COUNT> s_log_level_names = {
|
||||
{"None", "Error", "Warning", "Perf", "Info", "Verbose", "Dev", "Profile", "Debug", "Trace"}};
|
||||
static std::array<const char*, LOGLEVEL_COUNT> s_log_level_display_names = {
|
||||
|
|
|
@ -85,6 +85,7 @@ struct Settings
|
|||
bool apply_game_settings = true;
|
||||
bool auto_load_cheats = true;
|
||||
bool disable_all_enhancements = false;
|
||||
bool enable_discord_presence = false;
|
||||
|
||||
bool rewind_enable = false;
|
||||
float rewind_save_frequency = 10.0f;
|
||||
|
@ -190,6 +191,7 @@ struct Settings
|
|||
bool achievements_notifications = true;
|
||||
bool achievements_sound_effects = true;
|
||||
bool achievements_primed_indicators = true;
|
||||
bool achievements_use_raintegration = false;
|
||||
|
||||
struct DebugSettings
|
||||
{
|
||||
|
@ -336,6 +338,12 @@ struct Settings
|
|||
|
||||
void FixIncompatibleSettings(bool display_osd_messages);
|
||||
|
||||
/// Initializes configuration.
|
||||
void UpdateLogSettings();
|
||||
|
||||
static void SetDefaultControllerConfig(SettingsInterface& si);
|
||||
static void SetDefaultHotkeyConfig(SettingsInterface& si);
|
||||
|
||||
static std::optional<LOGLEVEL> ParseLogLevelName(const char* str);
|
||||
static const char* GetLogLevelName(LOGLEVEL level);
|
||||
static const char* GetLogLevelDisplayName(LOGLEVEL level);
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
#include "cpu_code_cache.h"
|
||||
#include "cpu_core.h"
|
||||
#include "dma.h"
|
||||
#include "fmt/chrono.h"
|
||||
#include "fmt/format.h"
|
||||
#include "fullscreen_ui.h"
|
||||
#include "game_database.h"
|
||||
#include "game_list.h"
|
||||
#include "gpu.h"
|
||||
#include "gte.h"
|
||||
#include "host.h"
|
||||
#include "host_interface_progress_callback.h"
|
||||
#include "host_settings.h"
|
||||
#include "imgui_overlays.h"
|
||||
#include "interrupt_controller.h"
|
||||
#include "mdec.h"
|
||||
#include "memory_card.h"
|
||||
|
@ -38,7 +38,9 @@
|
|||
#include "util/cd_image.h"
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/ini_settings_interface.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "util/iso_reader.h"
|
||||
#include "util/platform_misc.h"
|
||||
#include "util/state_wrapper.h"
|
||||
|
||||
#include "common/error.h"
|
||||
|
@ -49,6 +51,8 @@
|
|||
#include "common/string_util.h"
|
||||
#include "common/threading.h"
|
||||
|
||||
#include "fmt/chrono.h"
|
||||
#include "fmt/format.h"
|
||||
#include "xxhash.h"
|
||||
|
||||
#include <cctype>
|
||||
|
@ -67,6 +71,10 @@ Log_SetChannel(System);
|
|||
#include <mmsystem.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
#include "discord_rpc.h"
|
||||
#endif
|
||||
|
||||
// #define PROFILE_MEMORY_SAVE_STATES 1
|
||||
|
||||
SystemBootParameters::SystemBootParameters() = default;
|
||||
|
@ -130,7 +138,16 @@ static void UpdateRunningGame(const char* path, CDImage* image, bool booting);
|
|||
static bool CheckForSBIFile(CDImage* image);
|
||||
static std::unique_ptr<MemoryCard> GetMemoryCardForSlot(u32 slot, MemoryCardType type);
|
||||
|
||||
static void UpdateSessionTime(const std::string& prev_serial);
|
||||
|
||||
static void SetTimerResolutionIncreased(bool enabled);
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
static void InitializeDiscordPresence();
|
||||
static void ShutdownDiscordPresence();
|
||||
static void UpdateDiscordPresence(bool rich_presence_only);
|
||||
static void PollDiscordPresence();
|
||||
#endif
|
||||
} // namespace System
|
||||
|
||||
static constexpr const float PERFORMANCE_COUNTER_UPDATE_INTERVAL = 1.0f;
|
||||
|
@ -222,11 +239,63 @@ static bool s_runahead_replay_pending = false;
|
|||
static u32 s_runahead_frames = 0;
|
||||
static u32 s_runahead_replay_frames = 0;
|
||||
|
||||
// Used to track play time. We use a monotonic timer here, in case of clock changes.
|
||||
static u64 s_session_start_time = 0;
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
// discord rich presence
|
||||
static bool s_discord_presence_active = false;
|
||||
#ifdef WITH_CHEEVOS
|
||||
static std::string s_discord_presence_cheevos_string;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static TinyString GetTimestampStringForFileName()
|
||||
{
|
||||
return TinyString::FromFmt("{:%Y-%m-%d_%H-%M-%S}", fmt::localtime(std::time(nullptr)));
|
||||
}
|
||||
|
||||
void System::Internal::ProcessStartup()
|
||||
{
|
||||
// This will call back to Host::LoadSettings() -> ReloadSources().
|
||||
LoadSettings(false);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#ifdef WITH_RAINTEGRATION
|
||||
if (Host::GetBaseBoolSettingValue("Cheevos", "UseRAIntegration", false))
|
||||
Achievements::SwitchToRAIntegration();
|
||||
#endif
|
||||
if (g_settings.achievements_enabled)
|
||||
Achievements::Initialize();
|
||||
#endif
|
||||
}
|
||||
|
||||
void System::Internal::ProcessShutdown()
|
||||
{
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
ShutdownDiscordPresence();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::Shutdown();
|
||||
#endif
|
||||
|
||||
InputManager::CloseSources();
|
||||
}
|
||||
|
||||
void System::Internal::IdlePollUpdate()
|
||||
{
|
||||
InputManager::PollSources();
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
PollDiscordPresence();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::ProcessPendingHTTPRequests();
|
||||
#endif
|
||||
}
|
||||
|
||||
System::State System::GetState()
|
||||
{
|
||||
return s_state;
|
||||
|
@ -845,7 +914,11 @@ void System::LoadSettings(bool display_osd_messages)
|
|||
std::unique_lock<std::mutex> lock = Host::GetSettingsLock();
|
||||
SettingsInterface& si = *Host::GetSettingsInterface();
|
||||
g_settings.Load(si);
|
||||
g_settings.UpdateLogSettings();
|
||||
|
||||
Host::LoadSettings(si, lock);
|
||||
InputManager::ReloadSources(si, lock);
|
||||
InputManager::ReloadBindings(si, *Host::GetSettingsInterfaceForBindings());
|
||||
|
||||
// apply compatibility settings
|
||||
if (g_settings.apply_compatibility_settings && !s_running_game_serial.empty())
|
||||
|
@ -1017,12 +1090,34 @@ void System::PauseSystem(bool paused)
|
|||
|
||||
if (paused)
|
||||
{
|
||||
FullscreenUI::OnSystemPaused();
|
||||
|
||||
InputManager::PauseVibration();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::OnSystemPaused(true);
|
||||
#endif
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::ResumeScreensaver();
|
||||
|
||||
Host::OnSystemPaused();
|
||||
}
|
||||
else
|
||||
{
|
||||
Host::OnSystemResumed();
|
||||
FullscreenUI::OnSystemResumed();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::OnSystemPaused(false);
|
||||
#endif
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::SuspendScreensaver();
|
||||
|
||||
UpdateDisplaySync();
|
||||
|
||||
Host::OnSystemResumed();
|
||||
|
||||
ResetPerformanceCounters();
|
||||
ResetThrottler();
|
||||
}
|
||||
|
@ -1330,16 +1425,16 @@ bool System::BootSystem(SystemBootParameters parameters)
|
|||
}
|
||||
|
||||
// Good to go.
|
||||
s_state =
|
||||
(g_settings.start_paused || parameters.override_start_paused.value_or(false)) ? State::Paused : State::Running;
|
||||
s_state = State::Running;
|
||||
UpdateSoftwareCursor();
|
||||
SPU::GetOutputStream()->SetPaused(false);
|
||||
Host::OnSystemStarted();
|
||||
|
||||
if (s_state == State::Paused)
|
||||
Host::OnSystemPaused();
|
||||
else
|
||||
Host::OnSystemResumed();
|
||||
FullscreenUI::OnSystemStarted();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::SuspendScreensaver();
|
||||
|
||||
Host::OnSystemStarted();
|
||||
|
||||
// try to load the state, if it fails, bail out
|
||||
if (!parameters.save_state.empty())
|
||||
|
@ -1371,6 +1466,9 @@ bool System::BootSystem(SystemBootParameters parameters)
|
|||
if (g_settings.audio_dump_on_boot)
|
||||
StartDumpingAudio();
|
||||
|
||||
if (g_settings.start_paused || parameters.override_start_paused.value_or(false))
|
||||
PauseSystem(true);
|
||||
|
||||
ResetPerformanceCounters();
|
||||
if (IsRunning())
|
||||
UpdateSpeedLimiterState();
|
||||
|
@ -1520,6 +1618,16 @@ void System::DestroySystem()
|
|||
if (s_state == State::Shutdown)
|
||||
return;
|
||||
|
||||
Host::ClearOSDMessages();
|
||||
|
||||
SaveStateSelectorUI::Close(true);
|
||||
FullscreenUI::OnSystemDestroyed();
|
||||
|
||||
InputManager::PauseVibration();
|
||||
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::ResumeScreensaver();
|
||||
|
||||
SetTimerResolutionIncreased(false);
|
||||
|
||||
s_cpu_thread_usage = {};
|
||||
|
@ -1569,6 +1677,8 @@ void System::DestroySystem()
|
|||
|
||||
void System::ClearRunningGame()
|
||||
{
|
||||
UpdateSessionTime(s_running_game_serial);
|
||||
|
||||
s_running_game_serial.clear();
|
||||
s_running_game_path.clear();
|
||||
s_running_game_title.clear();
|
||||
|
@ -1580,6 +1690,10 @@ void System::ClearRunningGame()
|
|||
#ifdef WITH_CHEEVOS
|
||||
Achievements::GameChanged(s_running_game_path, nullptr);
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
UpdateDiscordPresence(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool System::FastForwardToFirstFrame()
|
||||
|
@ -1644,6 +1758,7 @@ void System::FrameDone()
|
|||
g_gpu->FlushRender();
|
||||
|
||||
// Generate any pending samples from the SPU before sleeping, this way we reduce the chances of underruns.
|
||||
// TODO: when running ahead, we can skip this (and the flush above)
|
||||
SPU::GeneratePendingSamples();
|
||||
|
||||
if (s_cheat_list)
|
||||
|
@ -1677,6 +1792,8 @@ void System::FrameDone()
|
|||
// *technically* this means higher input latency (by less than a frame), but runahead itself
|
||||
// counter-acts that.
|
||||
Host::PumpMessagesOnCPUThread();
|
||||
InputManager::PollSources();
|
||||
|
||||
if (IsExecutionInterrupted())
|
||||
{
|
||||
s_system_interrupted = false;
|
||||
|
@ -1694,6 +1811,15 @@ void System::FrameDone()
|
|||
SaveRunaheadState();
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
if (Achievements::IsActive())
|
||||
Achievements::FrameUpdate();
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
PollDiscordPresence();
|
||||
#endif
|
||||
|
||||
const Common::Timer::Value current_time = Common::Timer::GetCurrentValue();
|
||||
if (current_time < s_next_frame_time || s_display_all_frames || s_last_frame_skipped)
|
||||
{
|
||||
|
@ -1722,6 +1848,7 @@ void System::FrameDone()
|
|||
if (s_runahead_frames == 0)
|
||||
{
|
||||
Host::PumpMessagesOnCPUThread();
|
||||
InputManager::PollSources();
|
||||
|
||||
if (IsExecutionInterrupted())
|
||||
{
|
||||
|
@ -3150,8 +3277,10 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting)
|
|||
if (!booting && s_running_game_path == path)
|
||||
return;
|
||||
|
||||
const std::string prev_serial = std::move(s_running_game_serial);
|
||||
|
||||
s_running_game_path.clear();
|
||||
s_running_game_serial.clear();
|
||||
s_running_game_serial = {};
|
||||
s_running_game_title.clear();
|
||||
s_running_game_entry = nullptr;
|
||||
s_running_game_hash = 0;
|
||||
|
@ -3207,6 +3336,15 @@ void System::UpdateRunningGame(const char* path, CDImage* image, bool booting)
|
|||
if (g_settings.auto_load_cheats && !Achievements::ChallengeModeActive())
|
||||
LoadCheatListFromGameTitle();
|
||||
|
||||
if (s_running_game_serial != prev_serial)
|
||||
UpdateSessionTime(prev_serial);
|
||||
|
||||
SaveStateSelectorUI::RefreshList();
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
UpdateDiscordPresence(false);
|
||||
#endif
|
||||
|
||||
Host::OnGameChanged(s_running_game_path, s_running_game_serial, s_running_game_title);
|
||||
}
|
||||
|
||||
|
@ -3541,6 +3679,14 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
g_gpu_device->SetPostProcessingChain({});
|
||||
}
|
||||
}
|
||||
|
||||
if (g_settings.inhibit_screensaver != old_settings.inhibit_screensaver)
|
||||
{
|
||||
if (g_settings.inhibit_screensaver)
|
||||
PlatformMisc::SuspendScreensaver();
|
||||
else
|
||||
PlatformMisc::ResumeScreensaver();
|
||||
}
|
||||
}
|
||||
|
||||
bool controllers_updated = false;
|
||||
|
@ -3566,6 +3712,28 @@ void System::CheckForSettingsChanges(const Settings& old_settings)
|
|||
|
||||
if (g_settings.multitap_mode != old_settings.multitap_mode)
|
||||
UpdateMultitaps();
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
Achievements::UpdateSettings(old_settings);
|
||||
#endif
|
||||
|
||||
FullscreenUI::CheckForConfigChanges(old_settings);
|
||||
|
||||
if (g_settings.enable_discord_presence != old_settings.enable_discord_presence)
|
||||
{
|
||||
if (g_settings.enable_discord_presence)
|
||||
InitializeDiscordPresence();
|
||||
else
|
||||
ShutdownDiscordPresence();
|
||||
}
|
||||
|
||||
if (g_settings.log_level != old_settings.log_level || g_settings.log_filter != old_settings.log_filter ||
|
||||
g_settings.log_to_console != old_settings.log_to_console ||
|
||||
g_settings.log_to_debug != old_settings.log_to_debug || g_settings.log_to_window != old_settings.log_to_window ||
|
||||
g_settings.log_to_file != old_settings.log_to_file)
|
||||
{
|
||||
g_settings.UpdateLogSettings();
|
||||
}
|
||||
}
|
||||
|
||||
void System::CalculateRewindMemoryUsage(u32 num_saves, u64* ram_usage, u64* vram_usage)
|
||||
|
@ -4538,3 +4706,120 @@ void System::SetTimerResolutionIncreased(bool enabled)
|
|||
timeEndPeriod(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void System::UpdateSessionTime(const std::string& prev_serial)
|
||||
{
|
||||
const u64 ctime = Common::Timer::GetCurrentValue();
|
||||
if (!prev_serial.empty())
|
||||
{
|
||||
// round up to seconds
|
||||
const std::time_t etime =
|
||||
static_cast<std::time_t>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
|
||||
const std::time_t wtime = std::time(nullptr);
|
||||
GameList::AddPlayedTimeForSerial(prev_serial, wtime, etime);
|
||||
}
|
||||
|
||||
s_session_start_time = ctime;
|
||||
}
|
||||
|
||||
u64 System::GetSessionPlayedTime()
|
||||
{
|
||||
const u64 ctime = Common::Timer::GetCurrentValue();
|
||||
return static_cast<u64>(std::round(Common::Timer::ConvertValueToSeconds(ctime - s_session_start_time)));
|
||||
}
|
||||
|
||||
#ifdef WITH_DISCORD_PRESENCE
|
||||
|
||||
void System::InitializeDiscordPresence()
|
||||
{
|
||||
if (s_discord_presence_active)
|
||||
return;
|
||||
|
||||
DiscordEventHandlers handlers = {};
|
||||
Discord_Initialize("705325712680288296", &handlers, 0, nullptr);
|
||||
s_discord_presence_active = true;
|
||||
|
||||
UpdateDiscordPresence(false);
|
||||
}
|
||||
|
||||
void System::ShutdownDiscordPresence()
|
||||
{
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
Discord_ClearPresence();
|
||||
Discord_Shutdown();
|
||||
s_discord_presence_active = false;
|
||||
#ifdef WITH_CHEEVOS
|
||||
s_discord_presence_cheevos_string.clear();
|
||||
#endif
|
||||
}
|
||||
|
||||
void System::UpdateDiscordPresence(bool rich_presence_only)
|
||||
{
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
// Update only if RetroAchievements rich presence has changed
|
||||
const std::string& new_rich_presence = Achievements::GetRichPresenceString();
|
||||
if (new_rich_presence == s_discord_presence_cheevos_string && rich_presence_only)
|
||||
{
|
||||
return;
|
||||
}
|
||||
s_discord_presence_cheevos_string = new_rich_presence;
|
||||
#else
|
||||
if (rich_presence_only)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
// https://discord.com/developers/docs/rich-presence/how-to#updating-presence-update-presence-payload-fields
|
||||
DiscordRichPresence rp = {};
|
||||
rp.largeImageKey = "duckstation_logo";
|
||||
rp.largeImageText = "DuckStation PS1/PSX Emulator";
|
||||
rp.startTimestamp = std::time(nullptr);
|
||||
|
||||
SmallString details_string;
|
||||
if (!System::IsShutdown())
|
||||
{
|
||||
details_string.AppendFormattedString("%s (%s)", System::GetGameTitle().c_str(), System::GetGameSerial().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
details_string.AppendString("No Game Running");
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
SmallString state_string;
|
||||
// Trim to 128 bytes as per Discord-RPC requirements
|
||||
if (s_discord_presence_cheevos_string.length() >= 128)
|
||||
{
|
||||
// 124 characters + 3 dots + null terminator
|
||||
state_string = s_discord_presence_cheevos_string.substr(0, 124);
|
||||
state_string.AppendString("...");
|
||||
}
|
||||
else
|
||||
{
|
||||
state_string = s_discord_presence_cheevos_string;
|
||||
}
|
||||
|
||||
rp.state = state_string;
|
||||
#endif
|
||||
rp.details = details_string;
|
||||
|
||||
Discord_UpdatePresence(&rp);
|
||||
}
|
||||
|
||||
void System::PollDiscordPresence()
|
||||
{
|
||||
if (!s_discord_presence_active)
|
||||
return;
|
||||
|
||||
UpdateDiscordPresence(true);
|
||||
|
||||
Discord_RunCallbacks();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -194,6 +194,9 @@ GameHash GetGameHash();
|
|||
bool IsRunningUnknownGame();
|
||||
bool WasFastBooted();
|
||||
|
||||
/// Returns the time elapsed in the current play session.
|
||||
u64 GetSessionPlayedTime();
|
||||
|
||||
const BIOS::ImageInfo* GetBIOSImageInfo();
|
||||
const BIOS::Hash& GetBIOSHash();
|
||||
|
||||
|
@ -459,6 +462,18 @@ void UpdateMemorySaveStateSettings();
|
|||
bool LoadRewindState(u32 skip_saves = 0, bool consume_state = true);
|
||||
void SetRunaheadReplayFlag();
|
||||
|
||||
namespace Internal
|
||||
{
|
||||
/// Called on process startup.
|
||||
void ProcessStartup();
|
||||
|
||||
/// Called on process shutdown.
|
||||
void ProcessShutdown();
|
||||
|
||||
/// Polls input, updates subsystems which are present while paused/inactive.
|
||||
void IdlePollUpdate();
|
||||
}
|
||||
|
||||
} // namespace System
|
||||
|
||||
namespace Host {
|
||||
|
@ -497,16 +512,4 @@ void RequestResizeHostDisplay(s32 width, s32 height);
|
|||
|
||||
/// Requests shut down of the current virtual machine.
|
||||
void RequestSystemShutdown(bool allow_confirm, bool save_state);
|
||||
|
||||
/// Attempts to create the rendering device backend.
|
||||
bool CreateGPUDevice(RenderAPI api);
|
||||
|
||||
/// Handles fullscreen transitions and such.
|
||||
void UpdateDisplayWindow();
|
||||
|
||||
/// Called when the window is resized.
|
||||
void ResizeDisplayWindow(s32 width, s32 height, float scale);
|
||||
|
||||
/// Destroys any active rendering device.
|
||||
void ReleaseGPUDevice();
|
||||
} // namespace Host
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
#include "nogui_host.h"
|
||||
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
|
||||
#include "util/cocoa_tools.h"
|
||||
#include "util/imgui_manager.h"
|
||||
|
@ -28,9 +27,6 @@ constexpr NSWindowStyleMask WINDOWED_STYLE = NSWindowStyleMaskTitled | NSWindowS
|
|||
- (BOOL)canBecomeKeyView {
|
||||
return YES;
|
||||
}
|
||||
- (void)viewDidEndLiveResize:(NSEvent *)event {
|
||||
[super viewDidEndLiveResize:event];
|
||||
}
|
||||
- (void)mouseDown:(NSEvent *)event {
|
||||
NoGUIHost::ProcessPlatformMouseButtonEvent(0, true);
|
||||
}
|
||||
|
|
|
@ -6,13 +6,12 @@
|
|||
|
||||
#include "scmversion/scmversion.h"
|
||||
|
||||
#include "core/common_host.h"
|
||||
#include "core/achievements.h"
|
||||
#include "core/controller.h"
|
||||
#include "core/fullscreen_ui.h"
|
||||
#include "core/game_list.h"
|
||||
#include "core/gpu.h"
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "core/imgui_overlays.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/system.h"
|
||||
|
@ -21,6 +20,7 @@
|
|||
#include "util/imgui_manager.h"
|
||||
#include "util/ini_settings_interface.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "util/platform_misc.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_internal.h"
|
||||
|
@ -43,10 +43,6 @@
|
|||
|
||||
Log_SetChannel(NoGUIHost);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#include "core/achievements_private.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/windows_headers.h"
|
||||
#include <ShlObj.h>
|
||||
|
@ -278,15 +274,15 @@ void NoGUIHost::SetDefaultSettings(SettingsInterface& si, bool system, bool cont
|
|||
if (system)
|
||||
{
|
||||
System::SetDefaultSettings(si);
|
||||
CommonHost::SetDefaultSettings(si);
|
||||
EmuFolders::SetDefaults();
|
||||
EmuFolders::Save(si);
|
||||
}
|
||||
|
||||
if (controller)
|
||||
{
|
||||
CommonHost::SetDefaultControllerSettings(si);
|
||||
CommonHost::SetDefaultHotkeyBindings(si);
|
||||
InputManager::SetDefaultSourceConfig(si);
|
||||
Settings::SetDefaultControllerConfig(si);
|
||||
Settings::SetDefaultHotkeyConfig(si);
|
||||
}
|
||||
|
||||
g_nogui_window->SetDefaultConfig(si);
|
||||
|
@ -384,12 +380,10 @@ std::optional<std::time_t> Host::GetResourceFileTimestamp(const char* filename)
|
|||
|
||||
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
CommonHost::LoadSettings(si, lock);
|
||||
}
|
||||
|
||||
void Host::CheckForSettingsChanges(const Settings& old_settings)
|
||||
{
|
||||
CommonHost::CheckForSettingsChanges(old_settings);
|
||||
}
|
||||
|
||||
void Host::CommitBaseSettingChanges()
|
||||
|
@ -614,7 +608,7 @@ void NoGUIHost::CPUThreadEntryPoint()
|
|||
Threading::SetNameOfCurrentThread("CPU Thread");
|
||||
|
||||
// input source setup must happen on emu thread
|
||||
CommonHost::Initialize();
|
||||
System::Internal::ProcessStartup();
|
||||
|
||||
// start the fullscreen UI and get it going
|
||||
if (Host::CreateGPUDevice(Settings::GetRenderAPIForRenderer(g_settings.gpu_renderer)) && FullscreenUI::Initialize())
|
||||
|
@ -640,7 +634,7 @@ void NoGUIHost::CPUThreadEntryPoint()
|
|||
Host::ReleaseGPUDevice();
|
||||
Host::ReleaseRenderWindow();
|
||||
|
||||
CommonHost::Shutdown();
|
||||
System::Internal::ProcessShutdown();
|
||||
g_nogui_window->QuitMessageLoop();
|
||||
}
|
||||
|
||||
|
@ -655,6 +649,7 @@ void NoGUIHost::CPUThreadMainLoop()
|
|||
}
|
||||
|
||||
Host::PumpMessagesOnCPUThread();
|
||||
System::Internal::IdlePollUpdate();
|
||||
Host::RenderDisplay(false);
|
||||
if (!g_gpu_device->IsVsyncEnabled())
|
||||
g_gpu_device->ThrottlePresentation();
|
||||
|
@ -708,34 +703,24 @@ void Host::ReleaseRenderWindow()
|
|||
|
||||
void Host::OnSystemStarting()
|
||||
{
|
||||
CommonHost::OnSystemStarting();
|
||||
Log_VerbosePrintf("Host::OnSystemStarting()");
|
||||
s_save_state_on_shutdown = false;
|
||||
s_was_paused_by_focus_loss = false;
|
||||
}
|
||||
|
||||
void Host::OnSystemStarted()
|
||||
{
|
||||
CommonHost::OnSystemStarted();
|
||||
Log_VerbosePrintf("Host::OnSystemStarted()");
|
||||
}
|
||||
|
||||
void Host::OnSystemPaused()
|
||||
{
|
||||
CommonHost::OnSystemPaused();
|
||||
Log_VerbosePrintf("Host::OnSystemPaused()");
|
||||
}
|
||||
|
||||
void Host::OnSystemResumed()
|
||||
{
|
||||
CommonHost::OnSystemResumed();
|
||||
Log_VerbosePrintf("Host::OnSystemResumed()");
|
||||
}
|
||||
|
||||
void Host::OnSystemDestroyed()
|
||||
{
|
||||
CommonHost::OnSystemDestroyed();
|
||||
Log_VerbosePrintf("Host::OnSystemDestroyed()");
|
||||
}
|
||||
|
||||
void Host::BeginPresentFrame()
|
||||
|
@ -764,18 +749,15 @@ void Host::OnPerformanceCountersUpdated()
|
|||
|
||||
void Host::OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name)
|
||||
{
|
||||
CommonHost::OnGameChanged(disc_path, game_serial, game_name);
|
||||
Log_VerbosePrintf("Host::OnGameChanged(\"%s\", \"%s\", \"%s\")", disc_path.c_str(), game_serial.c_str(),
|
||||
game_name.c_str());
|
||||
NoGUIHost::UpdateWindowTitle(game_name);
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
void Host::OnAchievementsRefreshed()
|
||||
{
|
||||
// noop
|
||||
}
|
||||
#endif
|
||||
|
||||
void Host::SetMouseMode(bool relative, bool hide_cursor)
|
||||
{
|
||||
|
@ -793,7 +775,6 @@ void Host::PumpMessagesOnCPUThread()
|
|||
{
|
||||
NoGUIHost::ProcessCPUThreadPlatformMessages();
|
||||
NoGUIHost::ProcessCPUThreadEvents(false);
|
||||
CommonHost::PumpMessagesOnCPUThread(); // calls InputManager::PollSources()
|
||||
}
|
||||
|
||||
std::unique_ptr<NoGUIPlatform> NoGUIHost::CreatePlatform()
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "common/string_util.h"
|
||||
#include "common/threading.h"
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "util/imgui_manager.h"
|
||||
#include "nogui_host.h"
|
||||
#include "resource.h"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "achievementlogindialog.h"
|
||||
#include "core/achievements_private.h"
|
||||
#include "core/achievements.h"
|
||||
#include "qthost.h"
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
|
||||
#include "core/achievements_private.h"
|
||||
#include "core/achievements.h"
|
||||
#include "core/system.h"
|
||||
|
||||
#include "common/string_util.h"
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
|
||||
#include "core/common_host.h"
|
||||
#include "core/spu.h"
|
||||
|
||||
#include "util/audio_stream.h"
|
||||
|
|
|
@ -2,17 +2,21 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "controllerbindingwidgets.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "controllersettingsdialog.h"
|
||||
#include "controllersettingwidgetbinder.h"
|
||||
#include "core/controller.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "qthost.h"
|
||||
#include "qtutils.h"
|
||||
#include "settingsdialog.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
|
||||
#include "core/controller.h"
|
||||
#include "core/host.h"
|
||||
|
||||
#include "util/input_manager.h"
|
||||
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
#include <QtWidgets/QCheckBox>
|
||||
#include <QtWidgets/QDoubleSpinBox>
|
||||
#include <QtWidgets/QInputDialog>
|
||||
|
@ -519,7 +523,9 @@ ControllerCustomSettingsWidget::ControllerCustomSettingsWidget(ControllerBinding
|
|||
layout->addStretch(1);
|
||||
}
|
||||
|
||||
ControllerCustomSettingsWidget::~ControllerCustomSettingsWidget() {}
|
||||
ControllerCustomSettingsWidget::~ControllerCustomSettingsWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidget* parent, QWidget* parent_widget,
|
||||
QGridLayout* layout, const Controller::ControllerInfo* cinfo)
|
||||
|
@ -720,9 +726,13 @@ void ControllerCustomSettingsWidget::restoreDefaults()
|
|||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ControllerBindingWidget_Base::ControllerBindingWidget_Base(ControllerBindingWidget* parent) : QWidget(parent) {}
|
||||
ControllerBindingWidget_Base::ControllerBindingWidget_Base(ControllerBindingWidget* parent) : QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
ControllerBindingWidget_Base::~ControllerBindingWidget_Base() {}
|
||||
ControllerBindingWidget_Base::~ControllerBindingWidget_Base()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_Base::getIcon() const
|
||||
{
|
||||
|
@ -792,7 +802,9 @@ ControllerBindingWidget_DigitalController::ControllerBindingWidget_DigitalContro
|
|||
initBindingWidgets();
|
||||
}
|
||||
|
||||
ControllerBindingWidget_DigitalController::~ControllerBindingWidget_DigitalController() {}
|
||||
ControllerBindingWidget_DigitalController::~ControllerBindingWidget_DigitalController()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_DigitalController::getIcon() const
|
||||
{
|
||||
|
@ -813,7 +825,9 @@ ControllerBindingWidget_AnalogController::ControllerBindingWidget_AnalogControll
|
|||
initBindingWidgets();
|
||||
}
|
||||
|
||||
ControllerBindingWidget_AnalogController::~ControllerBindingWidget_AnalogController() {}
|
||||
ControllerBindingWidget_AnalogController::~ControllerBindingWidget_AnalogController()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_AnalogController::getIcon() const
|
||||
{
|
||||
|
@ -834,7 +848,9 @@ ControllerBindingWidget_AnalogJoystick::ControllerBindingWidget_AnalogJoystick(C
|
|||
initBindingWidgets();
|
||||
}
|
||||
|
||||
ControllerBindingWidget_AnalogJoystick::~ControllerBindingWidget_AnalogJoystick() {}
|
||||
ControllerBindingWidget_AnalogJoystick::~ControllerBindingWidget_AnalogJoystick()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_AnalogJoystick::getIcon() const
|
||||
{
|
||||
|
@ -872,7 +888,9 @@ ControllerBindingWidget_NeGcon::ControllerBindingWidget_NeGcon(ControllerBinding
|
|||
}
|
||||
}
|
||||
|
||||
ControllerBindingWidget_NeGcon::~ControllerBindingWidget_NeGcon() {}
|
||||
ControllerBindingWidget_NeGcon::~ControllerBindingWidget_NeGcon()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_NeGcon::getIcon() const
|
||||
{
|
||||
|
@ -893,7 +911,9 @@ ControllerBindingWidget_GunCon::ControllerBindingWidget_GunCon(ControllerBinding
|
|||
initBindingWidgets();
|
||||
}
|
||||
|
||||
ControllerBindingWidget_GunCon::~ControllerBindingWidget_GunCon() {}
|
||||
ControllerBindingWidget_GunCon::~ControllerBindingWidget_GunCon()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_GunCon::getIcon() const
|
||||
{
|
||||
|
@ -914,7 +934,9 @@ ControllerBindingWidget_Mouse::ControllerBindingWidget_Mouse(ControllerBindingWi
|
|||
initBindingWidgets();
|
||||
}
|
||||
|
||||
ControllerBindingWidget_Mouse::~ControllerBindingWidget_Mouse() {}
|
||||
ControllerBindingWidget_Mouse::~ControllerBindingWidget_Mouse()
|
||||
{
|
||||
}
|
||||
|
||||
QIcon ControllerBindingWidget_Mouse::getIcon() const
|
||||
{
|
||||
|
|
|
@ -2,16 +2,19 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "controllersettingsdialog.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/file_system.h"
|
||||
#include "controllerbindingwidgets.h"
|
||||
#include "controllerglobalsettingswidget.h"
|
||||
#include "core/controller.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "hotkeysettingswidget.h"
|
||||
#include "qthost.h"
|
||||
|
||||
#include "core/controller.h"
|
||||
#include "core/host.h"
|
||||
|
||||
#include "util/ini_settings_interface.h"
|
||||
#include "util/input_manager.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/file_system.h"
|
||||
|
||||
#include <QtWidgets/QInputDialog>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include "qthost.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
|
||||
#include "core/host.h"
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtGui/QAction>
|
||||
|
@ -11,10 +16,8 @@
|
|||
#include <QtWidgets/QLineEdit>
|
||||
#include <QtWidgets/QSlider>
|
||||
#include <QtWidgets/QSpinBox>
|
||||
|
||||
#include "core/host_settings.h"
|
||||
#include "qthost.h"
|
||||
#include "settingwidgetbinder.h"
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
/// This nastyness is required because input profiles aren't overlaid settings like the rest of them, it's
|
||||
/// input profile *or* global, not both.
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "qtutils.h"
|
||||
|
||||
#include "core/game_list.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "core/host.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
|
@ -83,7 +83,9 @@ private:
|
|||
QString m_filter_name;
|
||||
};
|
||||
|
||||
GameListWidget::GameListWidget(QWidget* parent /* = nullptr */) : QWidget(parent) {}
|
||||
GameListWidget::GameListWidget(QWidget* parent /* = nullptr */) : QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
GameListWidget::~GameListWidget() = default;
|
||||
|
||||
|
@ -585,7 +587,9 @@ const GameList::Entry* GameListWidget::getSelectedEntry() const
|
|||
}
|
||||
}
|
||||
|
||||
GameListGridListView::GameListGridListView(QWidget* parent /*= nullptr*/) : QListView(parent) {}
|
||||
GameListGridListView::GameListGridListView(QWidget* parent /*= nullptr*/) : QListView(parent)
|
||||
{
|
||||
}
|
||||
|
||||
void GameListGridListView::wheelEvent(QWheelEvent* e)
|
||||
{
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "inputbindingwidgets.h"
|
||||
#include "common/bitutils.h"
|
||||
#include "controllersettingsdialog.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "inputbindingdialog.h"
|
||||
#include "qthost.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
#include "core/host.h"
|
||||
|
||||
#include "common/bitutils.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
#include <QtGui/QKeyEvent>
|
||||
#include <QtGui/QMouseEvent>
|
||||
|
@ -408,7 +411,9 @@ InputVibrationBindingWidget::InputVibrationBindingWidget(QWidget* parent, Contro
|
|||
setKey(dialog, std::move(section_name), std::move(key_name));
|
||||
}
|
||||
|
||||
InputVibrationBindingWidget::~InputVibrationBindingWidget() {}
|
||||
InputVibrationBindingWidget::~InputVibrationBindingWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void InputVibrationBindingWidget::setKey(ControllerSettingsDialog* dialog, std::string section_name,
|
||||
std::string key_name)
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include "util/cd_image.h"
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/platform_misc.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/file_system.h"
|
||||
|
@ -46,15 +45,15 @@
|
|||
#include <QtWidgets/QStyleFactory>
|
||||
#include <cmath>
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#include "core/achievements_private.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "common/windows_headers.h"
|
||||
#include <Dbt.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "util/cocoa_tools.h"
|
||||
#endif
|
||||
|
||||
Log_SetChannel(MainWindow);
|
||||
|
||||
static constexpr char DISC_IMAGE_FILTER[] = QT_TRANSLATE_NOOP(
|
||||
|
@ -65,11 +64,7 @@ static constexpr char DISC_IMAGE_FILTER[] = QT_TRANSLATE_NOOP(
|
|||
"(*.ecm);;Media Descriptor Sidecar Images (*.mds);;PlayStation EBOOTs (*.pbp *.PBP);;PlayStation Executables (*.exe "
|
||||
"*.psexe *.ps-exe);;Portable Sound Format Files (*.psf *.minipsf);;Playlists (*.m3u)");
|
||||
|
||||
#ifdef __APPLE__
|
||||
const char* DEFAULT_THEME_NAME = "";
|
||||
#else
|
||||
const char* DEFAULT_THEME_NAME = "darkfusion";
|
||||
#endif
|
||||
|
||||
MainWindow* g_main_window = nullptr;
|
||||
static QString s_unthemed_style_name;
|
||||
|
@ -123,7 +118,7 @@ MainWindow::~MainWindow()
|
|||
unregisterForDeviceNotifications();
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
FrontendCommon::RemoveThemeChangeHandler(this);
|
||||
CocoaTools::RemoveThemeChangeHandler(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -159,8 +154,8 @@ void MainWindow::initialize()
|
|||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
FrontendCommon::AddThemeChangeHandler(this,
|
||||
[](void* ctx) { QtHost::RunOnUIThread([] { g_main_window->updateTheme(); }); });
|
||||
CocoaTools::AddThemeChangeHandler(this,
|
||||
[](void* ctx) { QtHost::RunOnUIThread([] { g_main_window->updateTheme(); }); });
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
namespace FrontendCommon {
|
||||
namespace PlatformMisc {
|
||||
class PostProcessingChain;
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "qtprogresscallback.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
#include "core/achievements.h"
|
||||
#include "core/cheats.h"
|
||||
#include "core/controller.h"
|
||||
#include "core/fullscreen_ui.h"
|
||||
|
@ -14,7 +15,6 @@
|
|||
#include "core/game_list.h"
|
||||
#include "core/gpu.h"
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "core/imgui_overlays.h"
|
||||
#include "core/memory_card.h"
|
||||
#include "core/spu.h"
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include "util/imgui_manager.h"
|
||||
#include "util/ini_settings_interface.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "util/platform_misc.h"
|
||||
|
||||
#include "scmversion/scmversion.h"
|
||||
|
||||
|
@ -62,10 +63,6 @@ Log_SetChannel(QtHost);
|
|||
#include <ShlObj.h>
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#include "core/achievements_private.h"
|
||||
#endif
|
||||
|
||||
static constexpr u32 SETTINGS_VERSION = 3;
|
||||
static constexpr u32 SETTINGS_SAVE_DELAY = 1000;
|
||||
|
||||
|
@ -321,7 +318,6 @@ void QtHost::SetDataDirectory()
|
|||
|
||||
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
CommonHost::LoadSettings(si, lock);
|
||||
g_emu_thread->loadSettings(si);
|
||||
}
|
||||
|
||||
|
@ -358,7 +354,6 @@ void EmuThread::checkForSettingsChanges(const Settings& old_settings)
|
|||
|
||||
void Host::CheckForSettingsChanges(const Settings& old_settings)
|
||||
{
|
||||
CommonHost::CheckForSettingsChanges(old_settings);
|
||||
g_emu_thread->checkForSettingsChanges(old_settings);
|
||||
}
|
||||
|
||||
|
@ -385,15 +380,15 @@ void QtHost::SetDefaultSettings(SettingsInterface& si, bool system, bool control
|
|||
if (system)
|
||||
{
|
||||
System::SetDefaultSettings(si);
|
||||
CommonHost::SetDefaultSettings(si);
|
||||
EmuFolders::SetDefaults();
|
||||
EmuFolders::Save(si);
|
||||
}
|
||||
|
||||
if (controller)
|
||||
{
|
||||
CommonHost::SetDefaultControllerSettings(si);
|
||||
CommonHost::SetDefaultHotkeyBindings(si);
|
||||
InputManager::SetDefaultSourceConfig(si);
|
||||
Settings::SetDefaultControllerConfig(si);
|
||||
Settings::SetDefaultHotkeyConfig(si);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -745,15 +740,11 @@ void EmuThread::connectDisplaySignals(DisplayWidget* widget)
|
|||
|
||||
void Host::OnSystemStarting()
|
||||
{
|
||||
CommonHost::OnSystemStarting();
|
||||
|
||||
emit g_emu_thread->systemStarting();
|
||||
}
|
||||
|
||||
void Host::OnSystemStarted()
|
||||
{
|
||||
CommonHost::OnSystemStarted();
|
||||
|
||||
g_emu_thread->wakeThread();
|
||||
g_emu_thread->stopBackgroundControllerPollTimer();
|
||||
|
||||
|
@ -762,8 +753,6 @@ void Host::OnSystemStarted()
|
|||
|
||||
void Host::OnSystemPaused()
|
||||
{
|
||||
CommonHost::OnSystemPaused();
|
||||
|
||||
emit g_emu_thread->systemPaused();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
Host::InvalidateDisplay();
|
||||
|
@ -771,8 +760,6 @@ void Host::OnSystemPaused()
|
|||
|
||||
void Host::OnSystemResumed()
|
||||
{
|
||||
CommonHost::OnSystemResumed();
|
||||
|
||||
// if we were surfaceless (view->game list, system->unpause), get our display widget back
|
||||
if (g_emu_thread->isSurfaceless())
|
||||
g_emu_thread->setSurfaceless(false);
|
||||
|
@ -785,8 +772,6 @@ void Host::OnSystemResumed()
|
|||
|
||||
void Host::OnSystemDestroyed()
|
||||
{
|
||||
CommonHost::OnSystemDestroyed();
|
||||
|
||||
g_emu_thread->resetPerformanceCounters();
|
||||
g_emu_thread->startBackgroundControllerPollTimer();
|
||||
emit g_emu_thread->systemDestroyed();
|
||||
|
@ -1227,10 +1212,9 @@ void EmuThread::saveScreenshot()
|
|||
System::SaveScreenshot(nullptr, true, true);
|
||||
}
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
|
||||
void Host::OnAchievementsRefreshed()
|
||||
{
|
||||
#ifdef WITH_CHEEVOS
|
||||
u32 game_id = 0;
|
||||
u32 achievement_count = 0;
|
||||
u32 max_points = 0;
|
||||
|
@ -1264,18 +1248,19 @@ void Host::OnAchievementsRefreshed()
|
|||
}
|
||||
|
||||
emit g_emu_thread->achievementsRefreshed(game_id, game_info, achievement_count, max_points);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Host::OnAchievementsChallengeModeChanged()
|
||||
{
|
||||
#ifdef WITH_CHEEVOS
|
||||
emit g_emu_thread->achievementsChallengeModeChanged();
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void EmuThread::doBackgroundControllerPoll()
|
||||
{
|
||||
InputManager::PollSources();
|
||||
System::Internal::IdlePollUpdate();
|
||||
}
|
||||
|
||||
void EmuThread::createBackgroundControllerPollTimer()
|
||||
|
@ -1346,7 +1331,7 @@ void EmuThread::run()
|
|||
m_started_semaphore.release();
|
||||
|
||||
// input source setup must happen on emu thread
|
||||
CommonHost::Initialize();
|
||||
System::Internal::ProcessStartup();
|
||||
|
||||
// bind buttons/axises
|
||||
createBackgroundControllerPollTimer();
|
||||
|
@ -1370,7 +1355,7 @@ void EmuThread::run()
|
|||
}
|
||||
|
||||
m_event_loop->processEvents(QEventLoop::AllEvents);
|
||||
CommonHost::PumpMessagesOnCPUThread();
|
||||
System::Internal::IdlePollUpdate();
|
||||
if (g_gpu_device)
|
||||
{
|
||||
Host::RenderDisplay(false);
|
||||
|
@ -1384,7 +1369,7 @@ void EmuThread::run()
|
|||
System::ShutdownSystem(false);
|
||||
|
||||
destroyBackgroundControllerPollTimer();
|
||||
CommonHost::Shutdown();
|
||||
System::Internal::ProcessShutdown();
|
||||
|
||||
// move back to UI thread
|
||||
moveToThread(m_ui_thread);
|
||||
|
@ -1585,8 +1570,6 @@ void Host::OnPerformanceCountersUpdated()
|
|||
|
||||
void Host::OnGameChanged(const std::string& disc_path, const std::string& game_serial, const std::string& game_name)
|
||||
{
|
||||
CommonHost::OnGameChanged(disc_path, game_serial, game_name);
|
||||
|
||||
emit g_emu_thread->runningGameChanged(QString::fromStdString(disc_path), QString::fromStdString(game_serial),
|
||||
QString::fromStdString(game_name));
|
||||
}
|
||||
|
@ -1606,7 +1589,6 @@ void Host::SetMouseMode(bool relative, bool hide_cursor)
|
|||
void Host::PumpMessagesOnCPUThread()
|
||||
{
|
||||
g_emu_thread->getEventLoop()->processEvents(QEventLoop::AllEvents);
|
||||
CommonHost::PumpMessagesOnCPUThread(); // calls InputManager::PollSources()
|
||||
}
|
||||
|
||||
void QtHost::SaveSettings()
|
||||
|
|
|
@ -6,12 +6,10 @@
|
|||
#include "gdbserver.h"
|
||||
#include "qtutils.h"
|
||||
|
||||
#include "core/game_list.h"
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "core/system.h"
|
||||
#include "core/types.h"
|
||||
#include "core/common_host.h"
|
||||
#include "core/game_list.h"
|
||||
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/input_manager.h"
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "qthost.h"
|
||||
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
|
||||
#include "util/ini_settings_interface.h"
|
||||
|
||||
|
@ -32,7 +31,7 @@
|
|||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#include "achievementsettingswidget.h"
|
||||
#include "core/achievements_private.h"
|
||||
#include "core/achievements.h"
|
||||
#endif
|
||||
|
||||
static QList<SettingsDialog*> s_open_game_properties_dialogs;
|
||||
|
|
|
@ -1,10 +1,17 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-FileCopyrightText: 2019-2023 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include "qthost.h"
|
||||
#include "qtutils.h"
|
||||
#include "settingsdialog.h"
|
||||
|
||||
#include "core/host.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/path.h"
|
||||
|
||||
#include <QtCore/QtCore>
|
||||
#include <QtGui/QAction>
|
||||
|
@ -17,15 +24,8 @@
|
|||
#include <QtWidgets/QMenu>
|
||||
#include <QtWidgets/QSlider>
|
||||
#include <QtWidgets/QSpinBox>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/path.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "core/settings.h"
|
||||
|
||||
#include "qthost.h"
|
||||
#include "qtutils.h"
|
||||
#include "settingsdialog.h"
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
|
||||
namespace SettingWidgetBinder {
|
||||
static constexpr const char* NULLABLE_PROPERTY = "SettingWidgetBinder_isNullable";
|
||||
|
|
|
@ -1,6 +1,18 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "core/achievements.h"
|
||||
#include "core/game_list.h"
|
||||
#include "core/host.h"
|
||||
#include "core/system.h"
|
||||
|
||||
#include "scmversion/scmversion.h"
|
||||
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/imgui_manager.h"
|
||||
#include "util/input_manager.h"
|
||||
#include "util/platform_misc.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/crash_handler.h"
|
||||
#include "common/file_system.h"
|
||||
|
@ -8,22 +20,11 @@
|
|||
#include "common/memory_settings_interface.h"
|
||||
#include "common/path.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/common_host.h"
|
||||
#include "core/game_list.h"
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "core/system.h"
|
||||
#include "scmversion/scmversion.h"
|
||||
#include "util/gpu_device.h"
|
||||
#include "util/imgui_manager.h"
|
||||
#include "util/input_manager.h"
|
||||
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
Log_SetChannel(RegTestHost);
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
#include "core/achievements_private.h"
|
||||
#endif
|
||||
Log_SetChannel(RegTestHost);
|
||||
|
||||
namespace RegTestHost {
|
||||
static bool ParseCommandLineParameters(int argc, char* argv[], std::optional<SystemBootParameters>& autoboot);
|
||||
|
@ -157,12 +158,10 @@ s32 Host::Internal::GetTranslatedStringImpl(const std::string_view& context, con
|
|||
|
||||
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
|
||||
{
|
||||
CommonHost::LoadSettings(si, lock);
|
||||
}
|
||||
|
||||
void Host::CheckForSettingsChanges(const Settings& old_settings)
|
||||
{
|
||||
CommonHost::CheckForSettingsChanges(old_settings);
|
||||
}
|
||||
|
||||
void Host::CommitBaseSettingChanges()
|
||||
|
|
|
@ -232,7 +232,6 @@ if(WIN32)
|
|||
elseif(APPLE)
|
||||
target_sources(util PRIVATE
|
||||
cocoa_tools.h
|
||||
cocoa_tools.mm
|
||||
metal_device.h
|
||||
metal_device.mm
|
||||
metal_stream_buffer.h
|
||||
|
|
|
@ -3,9 +3,23 @@
|
|||
|
||||
#include <string_view>
|
||||
|
||||
#include <Cocoa/Cocoa.h>
|
||||
struct WindowInfo;
|
||||
|
||||
#ifdef __OBJC__
|
||||
#import <AppKit/AppKit.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
namespace CocoaTools {
|
||||
NSString* StringViewToNSString(const std::string_view& str);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace CocoaTools {
|
||||
/// Add a handler to be run when macOS changes between dark and light themes
|
||||
void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx));
|
||||
|
||||
/// Remove a handler previously added using AddThemeChangeHandler with the given context
|
||||
void RemoveThemeChangeHandler(void* ctx);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "cocoa_tools.h"
|
||||
|
||||
NSString* CocoaTools::StringViewToNSString(const std::string_view& str)
|
||||
{
|
||||
if (str.empty())
|
||||
return nil;
|
||||
|
||||
return [[[NSString alloc] initWithBytes:str.data()
|
||||
length:static_cast<NSUInteger>(str.length())
|
||||
encoding:NSUTF8StringEncoding] autorelease];
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "d3d11_device.h"
|
||||
#include "core/host_settings.h" // TODO: Remove me
|
||||
#include "core/host.h" // TODO: Remove me
|
||||
#include "d3d11_pipeline.h"
|
||||
#include "d3d11_texture.h"
|
||||
#include "d3d_common.h"
|
||||
|
|
|
@ -4,13 +4,16 @@
|
|||
#define INITGUID
|
||||
|
||||
#include "dinput_source.h"
|
||||
#include "input_manager.h"
|
||||
#include "platform_misc.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/log.h"
|
||||
#include "common/make_array.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/host.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "input_manager.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
Log_SetChannel(DInputSource);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "gpu_device.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "core/host.h"
|
||||
#include "core/settings.h"
|
||||
#include "core/system.h"
|
||||
#include "postprocessing_chain.h"
|
||||
|
|
|
@ -1071,7 +1071,7 @@ bool InputManager::HasPointerAxisBinds()
|
|||
return false;
|
||||
}
|
||||
|
||||
void InputManager::SetDefaultConfig(SettingsInterface& si)
|
||||
void InputManager::SetDefaultSourceConfig(SettingsInterface& si)
|
||||
{
|
||||
si.ClearSection("InputSources");
|
||||
si.SetBoolValue("InputSources", "SDL", true);
|
||||
|
|
|
@ -319,7 +319,7 @@ bool IsUsingRawInput();
|
|||
bool HasPointerAxisBinds();
|
||||
|
||||
/// Restores default configuration.
|
||||
void SetDefaultConfig(SettingsInterface& si);
|
||||
void SetDefaultSourceConfig(SettingsInterface& si);
|
||||
|
||||
/// Clears all bindings for a given port.
|
||||
void ClearPortBindings(SettingsInterface& si, u32 port);
|
||||
|
@ -343,9 +343,6 @@ void OnInputDeviceDisconnected(const std::string_view& identifier);
|
|||
} // namespace InputManager
|
||||
|
||||
namespace Host {
|
||||
/// Return the current window handle. Needed for DInput.
|
||||
std::optional<WindowInfo> GetTopLevelWindowInfo();
|
||||
|
||||
/// Called when a new input device is connected.
|
||||
void OnInputDeviceConnected(const std::string_view& identifier, const std::string_view& device_name);
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "metal_device.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "spirv_compiler.h"
|
||||
|
||||
#include "common/align.h"
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
|
||||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
namespace FrontendCommon {
|
||||
#include "window_info.h"
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace PlatformMisc {
|
||||
void SuspendScreensaver();
|
||||
void ResumeScreensaver();
|
||||
|
||||
/// Abstracts platform-specific code for asynchronously playing a sound.
|
||||
/// On Windows, this will use PlaySound(). On Linux, it will shell out to aplay. On MacOS, it uses NSSound.
|
||||
bool PlaySoundAsync(const char* path);
|
||||
} // namespace PlatformMisc
|
||||
|
||||
#ifdef __APPLE__
|
||||
/// Add a handler to be run when macOS changes between dark and light themes
|
||||
void AddThemeChangeHandler(void* ctx, void(handler)(void* ctx));
|
||||
/// Remove a handler previously added using AddThemeChangeHandler with the given context
|
||||
void RemoveThemeChangeHandler(void* ctx);
|
||||
#endif
|
||||
} // namespace FrontendCommon
|
||||
namespace Host {
|
||||
/// Return the current window handle. Needed for DInput.
|
||||
std::optional<WindowInfo> GetTopLevelWindowInfo();
|
||||
} // namespace Host
|
|
@ -2,16 +2,23 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "platform_misc.h"
|
||||
#include "window_info.h"
|
||||
#include "cocoa_tools.h"
|
||||
|
||||
#include "common/log.h"
|
||||
#include "common/string.h"
|
||||
|
||||
#include <IOKit/pwr_mgt/IOPMLib.h>
|
||||
#include <Cocoa/Cocoa.h>
|
||||
#include <QuartzCore/QuartzCore.h>
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
Log_SetChannel(FrontendCommon);
|
||||
|
||||
#import <AppKit/AppKit.h>
|
||||
Log_SetChannel(PlatformMisc);
|
||||
|
||||
#if __has_feature(objc_arc)
|
||||
#error ARC should not be enabled.
|
||||
#endif
|
||||
|
||||
static IOPMAssertionID s_prevent_idle_assertion = kIOPMNullAssertionID;
|
||||
|
||||
|
@ -39,7 +46,7 @@ static bool SetScreensaverInhibitMacOS(bool inhibit)
|
|||
|
||||
static bool s_screensaver_suspended;
|
||||
|
||||
void FrontendCommon::SuspendScreensaver()
|
||||
void PlatformMisc::SuspendScreensaver()
|
||||
{
|
||||
if (s_screensaver_suspended)
|
||||
|
||||
|
@ -52,7 +59,7 @@ void FrontendCommon::SuspendScreensaver()
|
|||
s_screensaver_suspended = true;
|
||||
}
|
||||
|
||||
void FrontendCommon::ResumeScreensaver()
|
||||
void PlatformMisc::ResumeScreensaver()
|
||||
{
|
||||
if (!s_screensaver_suspended)
|
||||
return;
|
||||
|
@ -63,7 +70,7 @@ void FrontendCommon::ResumeScreensaver()
|
|||
s_screensaver_suspended = false;
|
||||
}
|
||||
|
||||
bool FrontendCommon::PlaySoundAsync(const char* path)
|
||||
bool PlatformMisc::PlaySoundAsync(const char* path)
|
||||
{
|
||||
NSString* nspath = [[NSString alloc] initWithUTF8String:path];
|
||||
NSSound* sound = [[NSSound alloc] initWithContentsOfFile:nspath byReference:YES];
|
||||
|
@ -73,6 +80,16 @@ bool FrontendCommon::PlaySoundAsync(const char* path)
|
|||
return result;
|
||||
}
|
||||
|
||||
NSString* CocoaTools::StringViewToNSString(const std::string_view& str)
|
||||
{
|
||||
if (str.empty())
|
||||
return nil;
|
||||
|
||||
return [[[NSString alloc] initWithBytes:str.data()
|
||||
length:static_cast<NSUInteger>(str.length())
|
||||
encoding:NSUTF8StringEncoding] autorelease];
|
||||
}
|
||||
|
||||
// From https://github.com/PCSX2/pcsx2/blob/1b673d9dd0829a48f5f0b6604c1de2108e981399/common/CocoaTools.mm
|
||||
|
||||
@interface PCSX2KVOHelper : NSObject
|
||||
|
@ -110,7 +127,7 @@ bool FrontendCommon::PlaySoundAsync(const char* path)
|
|||
|
||||
static PCSX2KVOHelper* s_themeChangeHandler;
|
||||
|
||||
void FrontendCommon::AddThemeChangeHandler(void* ctx, void(handler)(void* ctx))
|
||||
void CocoaTools::AddThemeChangeHandler(void* ctx, void(handler)(void* ctx))
|
||||
{
|
||||
assert([NSThread isMainThread]);
|
||||
if (!s_themeChangeHandler)
|
||||
|
@ -125,7 +142,7 @@ void FrontendCommon::AddThemeChangeHandler(void* ctx, void(handler)(void* ctx))
|
|||
[s_themeChangeHandler addCallback:ctx run:handler];
|
||||
}
|
||||
|
||||
void FrontendCommon::RemoveThemeChangeHandler(void* ctx)
|
||||
void CocoaTools::RemoveThemeChangeHandler(void* ctx)
|
||||
{
|
||||
assert([NSThread isMainThread]);
|
||||
[s_themeChangeHandler removeCallback:ctx];
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "input_manager.h"
|
||||
#include "platform_misc.h"
|
||||
#include <cinttypes>
|
||||
Log_SetChannel(FrontendCommon);
|
||||
Log_SetChannel(PlatformMisc);
|
||||
|
||||
#include <spawn.h>
|
||||
#include <unistd.h>
|
||||
|
@ -146,7 +146,7 @@ static bool SetScreensaverInhibit(bool inhibit)
|
|||
|
||||
static bool s_screensaver_suspended;
|
||||
|
||||
void FrontendCommon::SuspendScreensaver()
|
||||
void PlatformMisc::SuspendScreensaver()
|
||||
{
|
||||
if (s_screensaver_suspended)
|
||||
return;
|
||||
|
@ -160,7 +160,7 @@ void FrontendCommon::SuspendScreensaver()
|
|||
s_screensaver_suspended = true;
|
||||
}
|
||||
|
||||
void FrontendCommon::ResumeScreensaver()
|
||||
void PlatformMisc::ResumeScreensaver()
|
||||
{
|
||||
if (!s_screensaver_suspended)
|
||||
return;
|
||||
|
@ -171,7 +171,7 @@ void FrontendCommon::ResumeScreensaver()
|
|||
s_screensaver_suspended = false;
|
||||
}
|
||||
|
||||
bool FrontendCommon::PlaySoundAsync(const char* path)
|
||||
bool PlatformMisc::PlaySoundAsync(const char* path)
|
||||
{
|
||||
#ifdef __linux__
|
||||
// This is... pretty awful. But I can't think of a better way without linking to e.g. gstreamer.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "common/string_util.h"
|
||||
#include "platform_misc.h"
|
||||
#include <cinttypes>
|
||||
Log_SetChannel(FrontendCommon);
|
||||
Log_SetChannel(PlatformMisc);
|
||||
|
||||
#include "common/windows_headers.h"
|
||||
#include <mmsystem.h>
|
||||
|
@ -24,7 +24,7 @@ static bool SetScreensaverInhibitWin32(bool inhibit)
|
|||
|
||||
static bool s_screensaver_suspended;
|
||||
|
||||
void FrontendCommon::SuspendScreensaver()
|
||||
void PlatformMisc::SuspendScreensaver()
|
||||
{
|
||||
if (s_screensaver_suspended)
|
||||
return;
|
||||
|
@ -38,7 +38,7 @@ void FrontendCommon::SuspendScreensaver()
|
|||
s_screensaver_suspended = true;
|
||||
}
|
||||
|
||||
void FrontendCommon::ResumeScreensaver()
|
||||
void PlatformMisc::ResumeScreensaver()
|
||||
{
|
||||
if (!s_screensaver_suspended)
|
||||
return;
|
||||
|
@ -49,7 +49,7 @@ void FrontendCommon::ResumeScreensaver()
|
|||
s_screensaver_suspended = false;
|
||||
}
|
||||
|
||||
bool FrontendCommon::PlaySoundAsync(const char* path)
|
||||
bool PlatformMisc::PlaySoundAsync(const char* path)
|
||||
{
|
||||
const std::wstring wpath(StringUtil::UTF8StringToWideString(path));
|
||||
return PlaySoundW(wpath.c_str(), NULL, SND_ASYNC | SND_NODEFAULT);
|
||||
|
|
|
@ -2,17 +2,21 @@
|
|||
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
|
||||
|
||||
#include "sdl_input_source.h"
|
||||
#include "input_manager.h"
|
||||
|
||||
#include "core/host.h"
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/bitutils.h"
|
||||
#include "common/log.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/host.h"
|
||||
#include "core/host_settings.h"
|
||||
#include "input_manager.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif
|
||||
|
||||
Log_SetChannel(SDLInputSource);
|
||||
|
||||
static constexpr const char* s_sdl_axis_names[] = {
|
||||
|
|
Loading…
Reference in a new issue